| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 return true; | 259 return true; |
| 260 if (value->IsArray() && name == "length") | 260 if (value->IsArray() && name == "length") |
| 261 return true; | 261 return true; |
| 262 if (V8Blob::hasInstance(value, isolate)) | 262 if (V8Blob::hasInstance(value, isolate)) |
| 263 return name == "size" || name == "type"; | 263 return name == "size" || name == "type"; |
| 264 if (V8File::hasInstance(value, isolate)) | 264 if (V8File::hasInstance(value, isolate)) |
| 265 return name == "name" || name == "lastModified" || name =="lastModifiedD
ate"; | 265 return name == "name" || name == "lastModified" || name =="lastModifiedD
ate"; |
| 266 return false; | 266 return false; |
| 267 } | 267 } |
| 268 | 268 |
| 269 // Get an object's property ("own" or via prototype chain) of the given name. | |
| 270 // Has a special case for String's length property and otherwise fails for | |
| 271 // non-objects since it casts to object to call Has() and Get(). | |
| 272 static bool get(v8::Isolate* isolate, v8::Local<v8::Value> value, const String&
name, v8::Local<v8::Value>& result) | |
| 273 { | |
| 274 if (value->IsString() && name == "length") { | |
| 275 int32_t length = value.As<v8::String>()->Length(); | |
| 276 result = v8::Number::New(isolate, length); | |
| 277 return true; | |
| 278 } | |
| 279 if (!value->IsObject()) | |
| 280 return false; | |
| 281 v8::Local<v8::Object> object = value.As<v8::Object>(); | |
| 282 v8::Local<v8::String> key = v8String(isolate, name); | |
| 283 v8::Local<v8::Context> context = isolate->GetCurrentContext(); | |
| 284 if (!v8CallBoolean(object->Has(context, key))) | |
| 285 return false; | |
| 286 if (!object->Get(context, key).ToLocal(&result)) | |
| 287 return false; | |
| 288 return true; | |
| 289 } | |
| 290 | |
| 291 // Assumes a valid key path. | 269 // Assumes a valid key path. |
| 292 static Vector<String> parseKeyPath(const String& keyPath) | 270 static Vector<String> parseKeyPath(const String& keyPath) |
| 293 { | 271 { |
| 294 Vector<String> elements; | 272 Vector<String> elements; |
| 295 IDBKeyPathParseError error; | 273 IDBKeyPathParseError error; |
| 296 IDBParseKeyPath(keyPath, elements, error); | 274 IDBParseKeyPath(keyPath, elements, error); |
| 297 ASSERT(error == IDBKeyPathParseErrorNone); | 275 ASSERT(error == IDBKeyPathParseErrorNone); |
| 298 return elements; | 276 return elements; |
| 299 } | 277 } |
| 300 | 278 |
| 301 static IDBKey* createIDBKeyFromValueAndKeyPath(v8::Isolate* isolate, v8::Local<v
8::Value> v8Value, const String& keyPath, ExceptionState& exceptionState, bool a
llowExperimentalTypes) | 279 static IDBKey* createIDBKeyFromValueAndKeyPath(v8::Isolate* isolate, v8::Local<v
8::Value> v8Value, const String& keyPath, ExceptionState& exceptionState, bool a
llowExperimentalTypes) |
| 302 { | 280 { |
| 303 Vector<String> keyPathElements = parseKeyPath(keyPath); | 281 Vector<String> keyPathElements = parseKeyPath(keyPath); |
| 304 ASSERT(isolate->InContext()); | 282 ASSERT(isolate->InContext()); |
| 305 | 283 |
| 306 v8::HandleScope handleScope(isolate); | 284 v8::HandleScope handleScope(isolate); |
| 307 v8::Local<v8::Value> currentValue(v8Value); | 285 v8::Local<v8::Context> context = isolate->GetCurrentContext(); |
| 286 v8::TryCatch block; |
| 308 for (size_t i = 0; i < keyPathElements.size(); ++i) { | 287 for (size_t i = 0; i < keyPathElements.size(); ++i) { |
| 309 v8::Local<v8::Value> parentValue(currentValue); | 288 if (v8Value->IsString() && keyPathElements[i] == "length") { |
| 310 if (!get(isolate, parentValue, keyPathElements[i], currentValue)) | 289 int32_t length = v8Value.As<v8::String>()->Length(); |
| 290 v8Value = v8::Number::New(isolate, length); |
| 291 } else if (!v8Value->IsObject()) { |
| 311 return nullptr; | 292 return nullptr; |
| 293 } else { |
| 294 v8::Local<v8::Object> object = v8Value.As<v8::Object>(); |
| 295 v8::Local<v8::String> key = v8String(isolate, keyPathElements[i]); |
| 296 if (!v8CallBoolean(object->Has(context, key))) |
| 297 return nullptr; |
| 298 if (!v8Call(object->Get(context, key), v8Value, block)) { |
| 299 exceptionState.rethrowV8Exception(block.Exception()); |
| 300 return nullptr; |
| 301 } |
| 302 } |
| 312 } | 303 } |
| 313 return createIDBKeyFromValue(isolate, currentValue, exceptionState, allowExp
erimentalTypes); | 304 return createIDBKeyFromValue(isolate, v8Value, exceptionState, allowExperime
ntalTypes); |
| 314 } | 305 } |
| 315 | 306 |
| 316 static IDBKey* createIDBKeyFromValueAndKeyPath(v8::Isolate* isolate, v8::Local<v
8::Value> value, const IDBKeyPath& keyPath, ExceptionState& exceptionState, bool
allowExperimentalTypes = false) | 307 static IDBKey* createIDBKeyFromValueAndKeyPath(v8::Isolate* isolate, v8::Local<v
8::Value> value, const IDBKeyPath& keyPath, ExceptionState& exceptionState, bool
allowExperimentalTypes = false) |
| 317 { | 308 { |
| 318 ASSERT(!keyPath.isNull()); | 309 ASSERT(!keyPath.isNull()); |
| 319 v8::HandleScope handleScope(isolate); | 310 v8::HandleScope handleScope(isolate); |
| 320 if (keyPath.type() == IDBKeyPath::ArrayType) { | 311 if (keyPath.type() == IDBKeyPath::ArrayType) { |
| 321 IDBKey::KeyArray result; | 312 IDBKey::KeyArray result; |
| 322 const Vector<String>& array = keyPath.array(); | 313 const Vector<String>& array = keyPath.array(); |
| 323 for (size_t i = 0; i < array.size(); ++i) { | 314 for (size_t i = 0; i < array.size(); ++i) { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 ASSERT_NOT_REACHED(); | 389 ASSERT_NOT_REACHED(); |
| 399 return false; | 390 return false; |
| 400 } | 391 } |
| 401 | 392 |
| 402 v8::HandleScope handleScope(isolate); | 393 v8::HandleScope handleScope(isolate); |
| 403 v8::Local<v8::Context> context = isolate->GetCurrentContext(); | 394 v8::Local<v8::Context> context = isolate->GetCurrentContext(); |
| 404 | 395 |
| 405 // For an object o = {} which should have keypath 'a.b.c' and key k, this | 396 // For an object o = {} which should have keypath 'a.b.c' and key k, this |
| 406 // populates o to be {a:{b:{}}}. This is only applied to deserialized | 397 // populates o to be {a:{b:{}}}. This is only applied to deserialized |
| 407 // values which were validated before serialization, so various | 398 // values which were validated before serialization, so various |
| 408 // assumptions can be made. | 399 // assumptions can be made, e.g. there are no getters/setters on the |
| 400 // object itself (though there might be on the prototype chain). |
| 409 for (size_t i = 0; i < keyPathElements.size() - 1; ++i) { | 401 for (size_t i = 0; i < keyPathElements.size() - 1; ++i) { |
| 410 const String& keyPathElement = keyPathElements[i]; | 402 const String& keyPathElement = keyPathElements[i]; |
| 411 ASSERT(value->IsObject()); | 403 ASSERT(value->IsObject()); |
| 412 ASSERT(!isImplicitProperty(isolate, value, keyPathElement)); | 404 ASSERT(!isImplicitProperty(isolate, value, keyPathElement)); |
| 413 v8::Local<v8::Object> object = value.As<v8::Object>(); | 405 v8::Local<v8::Object> object = value.As<v8::Object>(); |
| 414 v8::Local<v8::String> property = v8String(isolate, keyPathElement); | 406 v8::Local<v8::String> property = v8String(isolate, keyPathElement); |
| 415 bool hasOwnProperty; | 407 bool hasOwnProperty; |
| 416 if (!v8Call(object->HasOwnProperty(context, property), hasOwnProperty)) | 408 if (!v8Call(object->HasOwnProperty(context, property), hasOwnProperty)) |
| 417 return false; | 409 return false; |
| 418 if (hasOwnProperty) { | 410 if (hasOwnProperty) { |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 ASSERT(!exceptionState.hadException()); | 531 ASSERT(!exceptionState.hadException()); |
| 540 if (expectedKey && expectedKey->isEqual(value->primaryKey())) | 532 if (expectedKey && expectedKey->isEqual(value->primaryKey())) |
| 541 return; | 533 return; |
| 542 | 534 |
| 543 bool injected = injectV8KeyIntoV8Value(isolate, keyValue.v8Value(), scriptVa
lue.v8Value(), value->keyPath()); | 535 bool injected = injectV8KeyIntoV8Value(isolate, keyValue.v8Value(), scriptVa
lue.v8Value(), value->keyPath()); |
| 544 ASSERT_UNUSED(injected, injected); | 536 ASSERT_UNUSED(injected, injected); |
| 545 } | 537 } |
| 546 #endif | 538 #endif |
| 547 | 539 |
| 548 } // namespace blink | 540 } // namespace blink |
| OLD | NEW |