OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 js_object); | 221 js_object); |
222 if (!maybe_result->ToObject(&result)) return maybe_result; | 222 if (!maybe_result->ToObject(&result)) return maybe_result; |
223 } | 223 } |
224 elements->set(i, result); | 224 elements->set(i, result); |
225 } | 225 } |
226 } | 226 } |
227 } | 227 } |
228 break; | 228 break; |
229 } | 229 } |
230 case DICTIONARY_ELEMENTS: { | 230 case DICTIONARY_ELEMENTS: { |
231 NumberDictionary* element_dictionary = copy->element_dictionary(); | 231 SeededNumberDictionary* element_dictionary = copy->element_dictionary(); |
232 int capacity = element_dictionary->Capacity(); | 232 int capacity = element_dictionary->Capacity(); |
233 for (int i = 0; i < capacity; i++) { | 233 for (int i = 0; i < capacity; i++) { |
234 Object* k = element_dictionary->KeyAt(i); | 234 Object* k = element_dictionary->KeyAt(i); |
235 if (element_dictionary->IsKey(k)) { | 235 if (element_dictionary->IsKey(k)) { |
236 Object* value = element_dictionary->ValueAt(i); | 236 Object* value = element_dictionary->ValueAt(i); |
237 if (value->IsJSObject()) { | 237 if (value->IsJSObject()) { |
238 JSObject* js_object = JSObject::cast(value); | 238 JSObject* js_object = JSObject::cast(value); |
239 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, | 239 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, |
240 js_object); | 240 js_object); |
241 if (!maybe_result->ToObject(&result)) return maybe_result; | 241 if (!maybe_result->ToObject(&result)) return maybe_result; |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 bool is_result_from_cache = false; | 348 bool is_result_from_cache = false; |
349 Handle<Map> map = has_function_literal | 349 Handle<Map> map = has_function_literal |
350 ? Handle<Map>(context->object_function()->initial_map()) | 350 ? Handle<Map>(context->object_function()->initial_map()) |
351 : ComputeObjectLiteralMap(context, | 351 : ComputeObjectLiteralMap(context, |
352 constant_properties, | 352 constant_properties, |
353 &is_result_from_cache); | 353 &is_result_from_cache); |
354 | 354 |
355 Handle<JSObject> boilerplate = isolate->factory()->NewJSObjectFromMap(map); | 355 Handle<JSObject> boilerplate = isolate->factory()->NewJSObjectFromMap(map); |
356 | 356 |
357 // Normalize the elements of the boilerplate to save space if needed. | 357 // Normalize the elements of the boilerplate to save space if needed. |
358 if (!should_have_fast_elements) NormalizeElements(boilerplate); | 358 if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate); |
359 | 359 |
360 // Add the constant properties to the boilerplate. | 360 // Add the constant properties to the boilerplate. |
361 int length = constant_properties->length(); | 361 int length = constant_properties->length(); |
362 bool should_transform = | 362 bool should_transform = |
363 !is_result_from_cache && boilerplate->HasFastProperties(); | 363 !is_result_from_cache && boilerplate->HasFastProperties(); |
364 if (should_transform || has_function_literal) { | 364 if (should_transform || has_function_literal) { |
365 // Normalize the properties of object to avoid n^2 behavior | 365 // Normalize the properties of object to avoid n^2 behavior |
366 // when extending the object multiple properties. Indicate the number of | 366 // when extending the object multiple properties. Indicate the number of |
367 // properties to be added. | 367 // properties to be added. |
368 NormalizeProperties(boilerplate, KEEP_INOBJECT_PROPERTIES, length / 2); | 368 JSObject::NormalizeProperties( |
| 369 boilerplate, KEEP_INOBJECT_PROPERTIES, length / 2); |
369 } | 370 } |
370 | 371 |
371 for (int index = 0; index < length; index +=2) { | 372 for (int index = 0; index < length; index +=2) { |
372 Handle<Object> key(constant_properties->get(index+0), isolate); | 373 Handle<Object> key(constant_properties->get(index+0), isolate); |
373 Handle<Object> value(constant_properties->get(index+1), isolate); | 374 Handle<Object> value(constant_properties->get(index+1), isolate); |
374 if (value->IsFixedArray()) { | 375 if (value->IsFixedArray()) { |
375 // The value contains the constant_properties of a | 376 // The value contains the constant_properties of a |
376 // simple object or array literal. | 377 // simple object or array literal. |
377 Handle<FixedArray> array = Handle<FixedArray>::cast(value); | 378 Handle<FixedArray> array = Handle<FixedArray>::cast(value); |
378 value = CreateLiteralBoilerplate(isolate, literals, array); | 379 value = CreateLiteralBoilerplate(isolate, literals, array); |
379 if (value.is_null()) return value; | 380 if (value.is_null()) return value; |
380 } | 381 } |
381 Handle<Object> result; | 382 Handle<Object> result; |
382 uint32_t element_index = 0; | 383 uint32_t element_index = 0; |
383 if (key->IsSymbol()) { | 384 if (key->IsSymbol()) { |
384 if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) { | 385 if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) { |
385 // Array index as string (uint32). | 386 // Array index as string (uint32). |
386 result = SetOwnElement(boilerplate, | 387 result = JSObject::SetOwnElement( |
387 element_index, | 388 boilerplate, element_index, value, kNonStrictMode); |
388 value, | |
389 kNonStrictMode); | |
390 } else { | 389 } else { |
391 Handle<String> name(String::cast(*key)); | 390 Handle<String> name(String::cast(*key)); |
392 ASSERT(!name->AsArrayIndex(&element_index)); | 391 ASSERT(!name->AsArrayIndex(&element_index)); |
393 result = SetLocalPropertyIgnoreAttributes(boilerplate, name, | 392 result = JSObject::SetLocalPropertyIgnoreAttributes( |
394 value, NONE); | 393 boilerplate, name, value, NONE); |
395 } | 394 } |
396 } else if (key->ToArrayIndex(&element_index)) { | 395 } else if (key->ToArrayIndex(&element_index)) { |
397 // Array index (uint32). | 396 // Array index (uint32). |
398 result = SetOwnElement(boilerplate, | 397 result = JSObject::SetOwnElement( |
399 element_index, | 398 boilerplate, element_index, value, kNonStrictMode); |
400 value, | |
401 kNonStrictMode); | |
402 } else { | 399 } else { |
403 // Non-uint32 number. | 400 // Non-uint32 number. |
404 ASSERT(key->IsNumber()); | 401 ASSERT(key->IsNumber()); |
405 double num = key->Number(); | 402 double num = key->Number(); |
406 char arr[100]; | 403 char arr[100]; |
407 Vector<char> buffer(arr, ARRAY_SIZE(arr)); | 404 Vector<char> buffer(arr, ARRAY_SIZE(arr)); |
408 const char* str = DoubleToCString(num, buffer); | 405 const char* str = DoubleToCString(num, buffer); |
409 Handle<String> name = | 406 Handle<String> name = |
410 isolate->factory()->NewStringFromAscii(CStrVector(str)); | 407 isolate->factory()->NewStringFromAscii(CStrVector(str)); |
411 result = SetLocalPropertyIgnoreAttributes(boilerplate, name, | 408 result = JSObject::SetLocalPropertyIgnoreAttributes( |
412 value, NONE); | 409 boilerplate, name, value, NONE); |
413 } | 410 } |
414 // If setting the property on the boilerplate throws an | 411 // If setting the property on the boilerplate throws an |
415 // exception, the exception is converted to an empty handle in | 412 // exception, the exception is converted to an empty handle in |
416 // the handle based operations. In that case, we need to | 413 // the handle based operations. In that case, we need to |
417 // convert back to an exception. | 414 // convert back to an exception. |
418 if (result.is_null()) return result; | 415 if (result.is_null()) return result; |
419 } | 416 } |
420 | 417 |
421 // Transform to fast properties if necessary. For object literals with | 418 // Transform to fast properties if necessary. For object literals with |
422 // containing function literals we defer this operation until after all | 419 // containing function literals we defer this operation until after all |
423 // computed properties have been assigned so that we can generate | 420 // computed properties have been assigned so that we can generate |
424 // constant function properties. | 421 // constant function properties. |
425 if (should_transform && !has_function_literal) { | 422 if (should_transform && !has_function_literal) { |
426 TransformToFastProperties(boilerplate, | 423 JSObject::TransformToFastProperties( |
427 boilerplate->map()->unused_property_fields()); | 424 boilerplate, boilerplate->map()->unused_property_fields()); |
428 } | 425 } |
429 | 426 |
430 return boilerplate; | 427 return boilerplate; |
431 } | 428 } |
432 | 429 |
433 | 430 |
434 static const int kSmiOnlyLiteralMinimumLength = 1024; | 431 static const int kSmiOnlyLiteralMinimumLength = 1024; |
435 | 432 |
436 | 433 |
437 // static | |
438 Handle<Object> Runtime::CreateArrayLiteralBoilerplate( | 434 Handle<Object> Runtime::CreateArrayLiteralBoilerplate( |
439 Isolate* isolate, | 435 Isolate* isolate, |
440 Handle<FixedArray> literals, | 436 Handle<FixedArray> literals, |
441 Handle<FixedArray> elements) { | 437 Handle<FixedArray> elements) { |
442 // Create the JSArray. | 438 // Create the JSArray. |
443 Handle<JSFunction> constructor( | 439 Handle<JSFunction> constructor( |
444 JSFunction::GlobalContextFromLiterals(*literals)->array_function()); | 440 JSFunction::GlobalContextFromLiterals(*literals)->array_function()); |
445 Handle<JSArray> object = | 441 Handle<JSArray> object = |
446 Handle<JSArray>::cast(isolate->factory()->NewJSObject(constructor)); | 442 Handle<JSArray>::cast(isolate->factory()->NewJSObject(constructor)); |
447 | 443 |
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1041 | 1037 |
1042 case JSObject::DICTIONARY_ELEMENT: { | 1038 case JSObject::DICTIONARY_ELEMENT: { |
1043 Handle<JSObject> holder = obj; | 1039 Handle<JSObject> holder = obj; |
1044 if (obj->IsJSGlobalProxy()) { | 1040 if (obj->IsJSGlobalProxy()) { |
1045 Object* proto = obj->GetPrototype(); | 1041 Object* proto = obj->GetPrototype(); |
1046 if (proto->IsNull()) return heap->undefined_value(); | 1042 if (proto->IsNull()) return heap->undefined_value(); |
1047 ASSERT(proto->IsJSGlobalObject()); | 1043 ASSERT(proto->IsJSGlobalObject()); |
1048 holder = Handle<JSObject>(JSObject::cast(proto)); | 1044 holder = Handle<JSObject>(JSObject::cast(proto)); |
1049 } | 1045 } |
1050 FixedArray* elements = FixedArray::cast(holder->elements()); | 1046 FixedArray* elements = FixedArray::cast(holder->elements()); |
1051 NumberDictionary* dictionary = NULL; | 1047 SeededNumberDictionary* dictionary = NULL; |
1052 if (elements->map() == heap->non_strict_arguments_elements_map()) { | 1048 if (elements->map() == heap->non_strict_arguments_elements_map()) { |
1053 dictionary = NumberDictionary::cast(elements->get(1)); | 1049 dictionary = SeededNumberDictionary::cast(elements->get(1)); |
1054 } else { | 1050 } else { |
1055 dictionary = NumberDictionary::cast(elements); | 1051 dictionary = SeededNumberDictionary::cast(elements); |
1056 } | 1052 } |
1057 int entry = dictionary->FindEntry(index); | 1053 int entry = dictionary->FindEntry(index); |
1058 ASSERT(entry != NumberDictionary::kNotFound); | 1054 ASSERT(entry != SeededNumberDictionary::kNotFound); |
1059 PropertyDetails details = dictionary->DetailsAt(entry); | 1055 PropertyDetails details = dictionary->DetailsAt(entry); |
1060 switch (details.type()) { | 1056 switch (details.type()) { |
1061 case CALLBACKS: { | 1057 case CALLBACKS: { |
1062 // This is an accessor property with getter and/or setter. | 1058 // This is an accessor property with getter and/or setter. |
1063 FixedArray* callbacks = | 1059 AccessorPair* accessors = |
1064 FixedArray::cast(dictionary->ValueAt(entry)); | 1060 AccessorPair::cast(dictionary->ValueAt(entry)); |
1065 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); | 1061 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); |
1066 if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) { | 1062 if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) { |
1067 elms->set(GETTER_INDEX, callbacks->get(0)); | 1063 elms->set(GETTER_INDEX, accessors->getter()); |
1068 } | 1064 } |
1069 if (CheckElementAccess(*obj, index, v8::ACCESS_SET)) { | 1065 if (CheckElementAccess(*obj, index, v8::ACCESS_SET)) { |
1070 elms->set(SETTER_INDEX, callbacks->get(1)); | 1066 elms->set(SETTER_INDEX, accessors->setter()); |
1071 } | 1067 } |
1072 break; | 1068 break; |
1073 } | 1069 } |
1074 case NORMAL: { | 1070 case NORMAL: { |
1075 // This is a data property. | 1071 // This is a data property. |
1076 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); | 1072 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); |
1077 Handle<Object> value = Object::GetElement(obj, index); | 1073 Handle<Object> value = Object::GetElement(obj, index); |
1078 ASSERT(!value.is_null()); | 1074 ASSERT(!value.is_null()); |
1079 elms->set(VALUE_INDEX, *value); | 1075 elms->set(VALUE_INDEX, *value); |
1080 elms->set(WRITABLE_INDEX, heap->ToBoolean(!details.IsReadOnly())); | 1076 elms->set(WRITABLE_INDEX, heap->ToBoolean(!details.IsReadOnly())); |
(...skipping 18 matching lines...) Expand all Loading... |
1099 } | 1095 } |
1100 | 1096 |
1101 if (!CheckAccess(*obj, *name, &result, v8::ACCESS_HAS)) { | 1097 if (!CheckAccess(*obj, *name, &result, v8::ACCESS_HAS)) { |
1102 return heap->false_value(); | 1098 return heap->false_value(); |
1103 } | 1099 } |
1104 | 1100 |
1105 elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!result.IsDontEnum())); | 1101 elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!result.IsDontEnum())); |
1106 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!result.IsDontDelete())); | 1102 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!result.IsDontDelete())); |
1107 | 1103 |
1108 bool is_js_accessor = (result.type() == CALLBACKS) && | 1104 bool is_js_accessor = (result.type() == CALLBACKS) && |
1109 (result.GetCallbackObject()->IsFixedArray()); | 1105 (result.GetCallbackObject()->IsAccessorPair()); |
1110 | 1106 |
1111 if (is_js_accessor) { | 1107 if (is_js_accessor) { |
1112 // __defineGetter__/__defineSetter__ callback. | 1108 // __defineGetter__/__defineSetter__ callback. |
1113 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); | 1109 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); |
1114 | 1110 |
1115 FixedArray* structure = FixedArray::cast(result.GetCallbackObject()); | 1111 AccessorPair* accessors = AccessorPair::cast(result.GetCallbackObject()); |
1116 if (CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) { | 1112 if (CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) { |
1117 elms->set(GETTER_INDEX, structure->get(0)); | 1113 elms->set(GETTER_INDEX, accessors->getter()); |
1118 } | 1114 } |
1119 if (CheckAccess(*obj, *name, &result, v8::ACCESS_SET)) { | 1115 if (CheckAccess(*obj, *name, &result, v8::ACCESS_SET)) { |
1120 elms->set(SETTER_INDEX, structure->get(1)); | 1116 elms->set(SETTER_INDEX, accessors->setter()); |
1121 } | 1117 } |
1122 } else { | 1118 } else { |
1123 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); | 1119 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); |
1124 elms->set(WRITABLE_INDEX, heap->ToBoolean(!result.IsReadOnly())); | 1120 elms->set(WRITABLE_INDEX, heap->ToBoolean(!result.IsReadOnly())); |
1125 | 1121 |
1126 PropertyAttributes attrs; | 1122 PropertyAttributes attrs; |
1127 Object* value; | 1123 Object* value; |
1128 // GetProperty will check access and report any violations. | 1124 // GetProperty will check access and report any violations. |
1129 { MaybeObject* maybe_value = obj->GetProperty(*obj, &result, *name, &attrs); | 1125 { MaybeObject* maybe_value = obj->GetProperty(*obj, &result, *name, &attrs); |
1130 if (!maybe_value->ToObject(&value)) return maybe_value; | 1126 if (!maybe_value->ToObject(&value)) return maybe_value; |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1328 // handlers such as "function onload() {}". Firefox does call the | 1324 // handlers such as "function onload() {}". Firefox does call the |
1329 // onload setter in those case and Safari does not. We follow | 1325 // onload setter in those case and Safari does not. We follow |
1330 // Safari for compatibility. | 1326 // Safari for compatibility. |
1331 if (value->IsJSFunction()) { | 1327 if (value->IsJSFunction()) { |
1332 // Do not change DONT_DELETE to false from true. | 1328 // Do not change DONT_DELETE to false from true. |
1333 if (lookup.IsProperty() && (lookup.type() != INTERCEPTOR)) { | 1329 if (lookup.IsProperty() && (lookup.type() != INTERCEPTOR)) { |
1334 attr |= lookup.GetAttributes() & DONT_DELETE; | 1330 attr |= lookup.GetAttributes() & DONT_DELETE; |
1335 } | 1331 } |
1336 PropertyAttributes attributes = static_cast<PropertyAttributes>(attr); | 1332 PropertyAttributes attributes = static_cast<PropertyAttributes>(attr); |
1337 | 1333 |
1338 RETURN_IF_EMPTY_HANDLE(isolate, | 1334 RETURN_IF_EMPTY_HANDLE( |
1339 SetLocalPropertyIgnoreAttributes(global, | 1335 isolate, |
1340 name, | 1336 JSObject::SetLocalPropertyIgnoreAttributes(global, name, value, |
1341 value, | 1337 attributes)); |
1342 attributes)); | |
1343 } else { | 1338 } else { |
1344 LanguageMode language_mode = DeclareGlobalsLanguageMode::decode(flags); | 1339 LanguageMode language_mode = DeclareGlobalsLanguageMode::decode(flags); |
1345 StrictModeFlag strict_mode_flag = (language_mode == CLASSIC_MODE) | 1340 StrictModeFlag strict_mode_flag = (language_mode == CLASSIC_MODE) |
1346 ? kNonStrictMode : kStrictMode; | 1341 ? kNonStrictMode : kStrictMode; |
1347 RETURN_IF_EMPTY_HANDLE(isolate, | 1342 RETURN_IF_EMPTY_HANDLE( |
1348 SetProperty(global, | 1343 isolate, |
1349 name, | 1344 JSReceiver::SetProperty(global, name, value, |
1350 value, | 1345 static_cast<PropertyAttributes>(attr), |
1351 static_cast<PropertyAttributes>(attr), | 1346 strict_mode_flag)); |
1352 strict_mode_flag)); | |
1353 } | 1347 } |
1354 } | 1348 } |
1355 | 1349 |
1356 ASSERT(!isolate->has_pending_exception()); | 1350 ASSERT(!isolate->has_pending_exception()); |
1357 return isolate->heap()->undefined_value(); | 1351 return isolate->heap()->undefined_value(); |
1358 } | 1352 } |
1359 | 1353 |
1360 | 1354 |
1361 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) { | 1355 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) { |
1362 HandleScope scope(isolate); | 1356 HandleScope scope(isolate); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1396 if (((attributes & READ_ONLY) == 0) || | 1390 if (((attributes & READ_ONLY) == 0) || |
1397 context->get(index)->IsTheHole()) { | 1391 context->get(index)->IsTheHole()) { |
1398 context->set(index, *initial_value); | 1392 context->set(index, *initial_value); |
1399 } | 1393 } |
1400 } else { | 1394 } else { |
1401 // Slow case: The property is in the context extension object of a | 1395 // Slow case: The property is in the context extension object of a |
1402 // function context or the global object of a global context. | 1396 // function context or the global object of a global context. |
1403 Handle<JSObject> object = Handle<JSObject>::cast(holder); | 1397 Handle<JSObject> object = Handle<JSObject>::cast(holder); |
1404 RETURN_IF_EMPTY_HANDLE( | 1398 RETURN_IF_EMPTY_HANDLE( |
1405 isolate, | 1399 isolate, |
1406 SetProperty(object, name, initial_value, mode, kNonStrictMode)); | 1400 JSReceiver::SetProperty(object, name, initial_value, mode, |
| 1401 kNonStrictMode)); |
1407 } | 1402 } |
1408 } | 1403 } |
1409 | 1404 |
1410 } else { | 1405 } else { |
1411 // The property is not in the function context. It needs to be | 1406 // The property is not in the function context. It needs to be |
1412 // "declared" in the function context's extension context or as a | 1407 // "declared" in the function context's extension context or as a |
1413 // property of the the global object. | 1408 // property of the the global object. |
1414 Handle<JSObject> object; | 1409 Handle<JSObject> object; |
1415 if (context->has_extension()) { | 1410 if (context->has_extension()) { |
1416 object = Handle<JSObject>(JSObject::cast(context->extension())); | 1411 object = Handle<JSObject>(JSObject::cast(context->extension())); |
(...skipping 19 matching lines...) Expand all Loading... |
1436 // SetProperty and no setters are invoked for those since they are | 1431 // SetProperty and no setters are invoked for those since they are |
1437 // not real JSObjects. | 1432 // not real JSObjects. |
1438 if (initial_value->IsTheHole() && | 1433 if (initial_value->IsTheHole() && |
1439 !object->IsJSContextExtensionObject()) { | 1434 !object->IsJSContextExtensionObject()) { |
1440 LookupResult lookup(isolate); | 1435 LookupResult lookup(isolate); |
1441 object->Lookup(*name, &lookup); | 1436 object->Lookup(*name, &lookup); |
1442 if (lookup.IsProperty() && (lookup.type() == CALLBACKS)) { | 1437 if (lookup.IsProperty() && (lookup.type() == CALLBACKS)) { |
1443 return ThrowRedeclarationError(isolate, "const", name); | 1438 return ThrowRedeclarationError(isolate, "const", name); |
1444 } | 1439 } |
1445 } | 1440 } |
1446 RETURN_IF_EMPTY_HANDLE(isolate, | 1441 RETURN_IF_EMPTY_HANDLE( |
1447 SetProperty(object, name, value, mode, | 1442 isolate, |
1448 kNonStrictMode)); | 1443 JSReceiver::SetProperty(object, name, value, mode, kNonStrictMode)); |
1449 } | 1444 } |
1450 | 1445 |
1451 return isolate->heap()->undefined_value(); | 1446 return isolate->heap()->undefined_value(); |
1452 } | 1447 } |
1453 | 1448 |
1454 | 1449 |
1455 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) { | 1450 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) { |
1456 NoHandleAllocation nha; | 1451 NoHandleAllocation nha; |
1457 // args[0] == name | 1452 // args[0] == name |
1458 // args[1] == language_mode | 1453 // args[1] == language_mode |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1547 if (!lookup.IsReadOnly()) { | 1542 if (!lookup.IsReadOnly()) { |
1548 // Restore global object from context (in case of GC) and continue | 1543 // Restore global object from context (in case of GC) and continue |
1549 // with setting the value. | 1544 // with setting the value. |
1550 HandleScope handle_scope(isolate); | 1545 HandleScope handle_scope(isolate); |
1551 Handle<GlobalObject> global(isolate->context()->global()); | 1546 Handle<GlobalObject> global(isolate->context()->global()); |
1552 | 1547 |
1553 // BUG 1213575: Handle the case where we have to set a read-only | 1548 // BUG 1213575: Handle the case where we have to set a read-only |
1554 // property through an interceptor and only do it if it's | 1549 // property through an interceptor and only do it if it's |
1555 // uninitialized, e.g. the hole. Nirk... | 1550 // uninitialized, e.g. the hole. Nirk... |
1556 // Passing non-strict mode because the property is writable. | 1551 // Passing non-strict mode because the property is writable. |
1557 RETURN_IF_EMPTY_HANDLE(isolate, | 1552 RETURN_IF_EMPTY_HANDLE( |
1558 SetProperty(global, | 1553 isolate, |
1559 name, | 1554 JSReceiver::SetProperty(global, name, value, attributes, |
1560 value, | 1555 kNonStrictMode)); |
1561 attributes, | |
1562 kNonStrictMode)); | |
1563 return *value; | 1556 return *value; |
1564 } | 1557 } |
1565 | 1558 |
1566 // Set the value, but only if we're assigning the initial value to a | 1559 // Set the value, but only if we're assigning the initial value to a |
1567 // constant. For now, we determine this by checking if the | 1560 // constant. For now, we determine this by checking if the |
1568 // current value is the hole. | 1561 // current value is the hole. |
1569 // Strict mode handling not needed (const is disallowed in strict mode). | 1562 // Strict mode handling not needed (const is disallowed in strict mode). |
1570 PropertyType type = lookup.type(); | 1563 PropertyType type = lookup.type(); |
1571 if (type == FIELD) { | 1564 if (type == FIELD) { |
1572 FixedArray* properties = global->properties(); | 1565 FixedArray* properties = global->properties(); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1622 } | 1615 } |
1623 | 1616 |
1624 // The property could not be found, we introduce it as a property of the | 1617 // The property could not be found, we introduce it as a property of the |
1625 // global object. | 1618 // global object. |
1626 if (attributes == ABSENT) { | 1619 if (attributes == ABSENT) { |
1627 Handle<JSObject> global = Handle<JSObject>( | 1620 Handle<JSObject> global = Handle<JSObject>( |
1628 isolate->context()->global()); | 1621 isolate->context()->global()); |
1629 // Strict mode not needed (const disallowed in strict mode). | 1622 // Strict mode not needed (const disallowed in strict mode). |
1630 RETURN_IF_EMPTY_HANDLE( | 1623 RETURN_IF_EMPTY_HANDLE( |
1631 isolate, | 1624 isolate, |
1632 SetProperty(global, name, value, NONE, kNonStrictMode)); | 1625 JSReceiver::SetProperty(global, name, value, NONE, kNonStrictMode)); |
1633 return *value; | 1626 return *value; |
1634 } | 1627 } |
1635 | 1628 |
1636 // The property was present in some function's context extension object, | 1629 // The property was present in some function's context extension object, |
1637 // as a property on the subject of a with, or as a property of the global | 1630 // as a property on the subject of a with, or as a property of the global |
1638 // object. | 1631 // object. |
1639 // | 1632 // |
1640 // In most situations, eval-introduced consts should still be present in | 1633 // In most situations, eval-introduced consts should still be present in |
1641 // the context extension object. However, because declaration and | 1634 // the context extension object. However, because declaration and |
1642 // initialization are separate, the property might have been deleted | 1635 // initialization are separate, the property might have been deleted |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1674 // either a field or a dictionary slot. | 1667 // either a field or a dictionary slot. |
1675 UNREACHABLE(); | 1668 UNREACHABLE(); |
1676 } | 1669 } |
1677 } else { | 1670 } else { |
1678 // The property was found on some other object. Set it if it is not a | 1671 // The property was found on some other object. Set it if it is not a |
1679 // read-only property. | 1672 // read-only property. |
1680 if ((attributes & READ_ONLY) == 0) { | 1673 if ((attributes & READ_ONLY) == 0) { |
1681 // Strict mode not needed (const disallowed in strict mode). | 1674 // Strict mode not needed (const disallowed in strict mode). |
1682 RETURN_IF_EMPTY_HANDLE( | 1675 RETURN_IF_EMPTY_HANDLE( |
1683 isolate, | 1676 isolate, |
1684 SetProperty(object, name, value, attributes, kNonStrictMode)); | 1677 JSReceiver::SetProperty(object, name, value, attributes, |
| 1678 kNonStrictMode)); |
1685 } | 1679 } |
1686 } | 1680 } |
1687 | 1681 |
1688 return *value; | 1682 return *value; |
1689 } | 1683 } |
1690 | 1684 |
1691 | 1685 |
1692 RUNTIME_FUNCTION(MaybeObject*, | 1686 RUNTIME_FUNCTION(MaybeObject*, |
1693 Runtime_OptimizeObjectForAddingMultipleProperties) { | 1687 Runtime_OptimizeObjectForAddingMultipleProperties) { |
1694 HandleScope scope(isolate); | 1688 HandleScope scope(isolate); |
1695 ASSERT(args.length() == 2); | 1689 ASSERT(args.length() == 2); |
1696 CONVERT_ARG_CHECKED(JSObject, object, 0); | 1690 CONVERT_ARG_CHECKED(JSObject, object, 0); |
1697 CONVERT_SMI_ARG_CHECKED(properties, 1); | 1691 CONVERT_SMI_ARG_CHECKED(properties, 1); |
1698 if (object->HasFastProperties()) { | 1692 if (object->HasFastProperties()) { |
1699 NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties); | 1693 JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties); |
1700 } | 1694 } |
1701 return *object; | 1695 return *object; |
1702 } | 1696 } |
1703 | 1697 |
1704 | 1698 |
1705 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) { | 1699 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) { |
1706 HandleScope scope(isolate); | 1700 HandleScope scope(isolate); |
1707 ASSERT(args.length() == 4); | 1701 ASSERT(args.length() == 4); |
1708 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0); | 1702 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0); |
1709 CONVERT_ARG_CHECKED(String, subject, 1); | 1703 CONVERT_ARG_CHECKED(String, subject, 1); |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1845 Builtins::Name builtin_name) { | 1839 Builtins::Name builtin_name) { |
1846 Handle<String> key = isolate->factory()->LookupAsciiSymbol(name); | 1840 Handle<String> key = isolate->factory()->LookupAsciiSymbol(name); |
1847 Handle<Code> code(isolate->builtins()->builtin(builtin_name)); | 1841 Handle<Code> code(isolate->builtins()->builtin(builtin_name)); |
1848 Handle<JSFunction> optimized = | 1842 Handle<JSFunction> optimized = |
1849 isolate->factory()->NewFunction(key, | 1843 isolate->factory()->NewFunction(key, |
1850 JS_OBJECT_TYPE, | 1844 JS_OBJECT_TYPE, |
1851 JSObject::kHeaderSize, | 1845 JSObject::kHeaderSize, |
1852 code, | 1846 code, |
1853 false); | 1847 false); |
1854 optimized->shared()->DontAdaptArguments(); | 1848 optimized->shared()->DontAdaptArguments(); |
1855 SetProperty(holder, key, optimized, NONE, kStrictMode); | 1849 JSReceiver::SetProperty(holder, key, optimized, NONE, kStrictMode); |
1856 return optimized; | 1850 return optimized; |
1857 } | 1851 } |
1858 | 1852 |
1859 | 1853 |
1860 RUNTIME_FUNCTION(MaybeObject*, Runtime_SpecialArrayFunctions) { | 1854 RUNTIME_FUNCTION(MaybeObject*, Runtime_SpecialArrayFunctions) { |
1861 HandleScope scope(isolate); | 1855 HandleScope scope(isolate); |
1862 ASSERT(args.length() == 1); | 1856 ASSERT(args.length() == 1); |
1863 CONVERT_ARG_CHECKED(JSObject, holder, 0); | 1857 CONVERT_ARG_CHECKED(JSObject, holder, 0); |
1864 | 1858 |
1865 InstallBuiltin(isolate, holder, "pop", Builtins::kArrayPop); | 1859 InstallBuiltin(isolate, holder, "pop", Builtins::kArrayPop); |
(...skipping 2193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4059 | 4053 |
4060 // Handle [] indexing on String objects | 4054 // Handle [] indexing on String objects |
4061 if (object->IsStringObjectWithCharacterAt(index)) { | 4055 if (object->IsStringObjectWithCharacterAt(index)) { |
4062 Handle<JSValue> js_value = Handle<JSValue>::cast(object); | 4056 Handle<JSValue> js_value = Handle<JSValue>::cast(object); |
4063 Handle<Object> result = | 4057 Handle<Object> result = |
4064 GetCharAt(Handle<String>(String::cast(js_value->value())), index); | 4058 GetCharAt(Handle<String>(String::cast(js_value->value())), index); |
4065 if (!result->IsUndefined()) return *result; | 4059 if (!result->IsUndefined()) return *result; |
4066 } | 4060 } |
4067 | 4061 |
4068 if (object->IsString() || object->IsNumber() || object->IsBoolean()) { | 4062 if (object->IsString() || object->IsNumber() || object->IsBoolean()) { |
4069 Handle<Object> prototype = GetPrototype(object); | 4063 return object->GetPrototype()->GetElement(index); |
4070 return prototype->GetElement(index); | |
4071 } | 4064 } |
4072 | 4065 |
4073 return object->GetElement(index); | 4066 return object->GetElement(index); |
4074 } | 4067 } |
4075 | 4068 |
4076 | 4069 |
4077 MaybeObject* Runtime::GetObjectProperty(Isolate* isolate, | 4070 MaybeObject* Runtime::GetObjectProperty(Isolate* isolate, |
4078 Handle<Object> object, | 4071 Handle<Object> object, |
4079 Handle<Object> key) { | 4072 Handle<Object> key) { |
4080 HandleScope scope(isolate); | 4073 HandleScope scope(isolate); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4127 | 4120 |
4128 | 4121 |
4129 MaybeObject* TransitionElements(Handle<Object> object, | 4122 MaybeObject* TransitionElements(Handle<Object> object, |
4130 ElementsKind to_kind, | 4123 ElementsKind to_kind, |
4131 Isolate* isolate) { | 4124 Isolate* isolate) { |
4132 HandleScope scope(isolate); | 4125 HandleScope scope(isolate); |
4133 if (!object->IsJSObject()) return isolate->ThrowIllegalOperation(); | 4126 if (!object->IsJSObject()) return isolate->ThrowIllegalOperation(); |
4134 ElementsKind from_kind = | 4127 ElementsKind from_kind = |
4135 Handle<JSObject>::cast(object)->map()->elements_kind(); | 4128 Handle<JSObject>::cast(object)->map()->elements_kind(); |
4136 if (Map::IsValidElementsTransition(from_kind, to_kind)) { | 4129 if (Map::IsValidElementsTransition(from_kind, to_kind)) { |
4137 Handle<Object> result = | 4130 Handle<Object> result = JSObject::TransitionElementsKind( |
4138 TransitionElementsKind(Handle<JSObject>::cast(object), to_kind); | 4131 Handle<JSObject>::cast(object), to_kind); |
4139 if (result.is_null()) return isolate->ThrowIllegalOperation(); | 4132 if (result.is_null()) return isolate->ThrowIllegalOperation(); |
4140 return *result; | 4133 return *result; |
4141 } | 4134 } |
4142 return isolate->ThrowIllegalOperation(); | 4135 return isolate->ThrowIllegalOperation(); |
4143 } | 4136 } |
4144 | 4137 |
4145 | 4138 |
4146 // KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric. | 4139 // KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric. |
4147 RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) { | 4140 RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) { |
4148 NoHandleAllocation ha; | 4141 NoHandleAllocation ha; |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4300 // Don't allow element properties to be redefined on objects with external | 4293 // Don't allow element properties to be redefined on objects with external |
4301 // array elements. | 4294 // array elements. |
4302 if (js_object->HasExternalArrayElements()) { | 4295 if (js_object->HasExternalArrayElements()) { |
4303 Handle<Object> args[2] = { js_object, name }; | 4296 Handle<Object> args[2] = { js_object, name }; |
4304 Handle<Object> error = | 4297 Handle<Object> error = |
4305 isolate->factory()->NewTypeError("redef_external_array_element", | 4298 isolate->factory()->NewTypeError("redef_external_array_element", |
4306 HandleVector(args, 2)); | 4299 HandleVector(args, 2)); |
4307 return isolate->Throw(*error); | 4300 return isolate->Throw(*error); |
4308 } | 4301 } |
4309 | 4302 |
4310 Handle<NumberDictionary> dictionary = NormalizeElements(js_object); | 4303 Handle<SeededNumberDictionary> dictionary = |
| 4304 JSObject::NormalizeElements(js_object); |
4311 // Make sure that we never go back to fast case. | 4305 // Make sure that we never go back to fast case. |
4312 dictionary->set_requires_slow_elements(); | 4306 dictionary->set_requires_slow_elements(); |
4313 PropertyDetails details = PropertyDetails(attr, NORMAL); | 4307 PropertyDetails details = PropertyDetails(attr, NORMAL); |
4314 Handle<NumberDictionary> extended_dictionary = | 4308 Handle<SeededNumberDictionary> extended_dictionary = |
4315 NumberDictionarySet(dictionary, index, obj_value, details); | 4309 SeededNumberDictionary::Set(dictionary, index, obj_value, details); |
4316 if (*extended_dictionary != *dictionary) { | 4310 if (*extended_dictionary != *dictionary) { |
4317 if (js_object->GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS) { | 4311 if (js_object->GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS) { |
4318 FixedArray::cast(js_object->elements())->set(1, *extended_dictionary); | 4312 FixedArray::cast(js_object->elements())->set(1, *extended_dictionary); |
4319 } else { | 4313 } else { |
4320 js_object->set_elements(*extended_dictionary); | 4314 js_object->set_elements(*extended_dictionary); |
4321 } | 4315 } |
4322 } | 4316 } |
4323 return *obj_value; | 4317 return *obj_value; |
4324 } | 4318 } |
4325 | 4319 |
(...skipping 29 matching lines...) Expand all Loading... |
4355 // correctly in the case where a property is a field and is reset with | 4349 // correctly in the case where a property is a field and is reset with |
4356 // new attributes. | 4350 // new attributes. |
4357 if (result.IsProperty() && | 4351 if (result.IsProperty() && |
4358 (attr != result.GetAttributes() || result.type() == CALLBACKS)) { | 4352 (attr != result.GetAttributes() || result.type() == CALLBACKS)) { |
4359 // New attributes - normalize to avoid writing to instance descriptor | 4353 // New attributes - normalize to avoid writing to instance descriptor |
4360 if (js_object->IsJSGlobalProxy()) { | 4354 if (js_object->IsJSGlobalProxy()) { |
4361 // Since the result is a property, the prototype will exist so | 4355 // Since the result is a property, the prototype will exist so |
4362 // we don't have to check for null. | 4356 // we don't have to check for null. |
4363 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype())); | 4357 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype())); |
4364 } | 4358 } |
4365 NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); | 4359 JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); |
4366 // Use IgnoreAttributes version since a readonly property may be | 4360 // Use IgnoreAttributes version since a readonly property may be |
4367 // overridden and SetProperty does not allow this. | 4361 // overridden and SetProperty does not allow this. |
4368 return js_object->SetLocalPropertyIgnoreAttributes(*name, | 4362 return js_object->SetLocalPropertyIgnoreAttributes(*name, |
4369 *obj_value, | 4363 *obj_value, |
4370 attr); | 4364 attr); |
4371 } | 4365 } |
4372 | 4366 |
4373 return Runtime::ForceSetObjectProperty(isolate, | 4367 return Runtime::ForceSetObjectProperty(isolate, |
4374 js_object, | 4368 js_object, |
4375 name, | 4369 name, |
4376 obj_value, | 4370 obj_value, |
4377 attr); | 4371 attr); |
4378 } | 4372 } |
4379 | 4373 |
4380 | 4374 |
4381 // Special case for elements if any of the flags are true. | 4375 // Special case for elements if any of the flags are true. |
4382 // If elements are in fast case we always implicitly assume that: | 4376 // If elements are in fast case we always implicitly assume that: |
4383 // DONT_DELETE: false, DONT_ENUM: false, READ_ONLY: false. | 4377 // DONT_DELETE: false, DONT_ENUM: false, READ_ONLY: false. |
4384 static MaybeObject* NormalizeObjectSetElement(Isolate* isolate, | 4378 static MaybeObject* NormalizeObjectSetElement(Isolate* isolate, |
4385 Handle<JSObject> js_object, | 4379 Handle<JSObject> js_object, |
4386 uint32_t index, | 4380 uint32_t index, |
4387 Handle<Object> value, | 4381 Handle<Object> value, |
4388 PropertyAttributes attr) { | 4382 PropertyAttributes attr) { |
4389 // Normalize the elements to enable attributes on the property. | 4383 // Normalize the elements to enable attributes on the property. |
4390 Handle<NumberDictionary> dictionary = NormalizeElements(js_object); | 4384 Handle<SeededNumberDictionary> dictionary = |
| 4385 JSObject::NormalizeElements(js_object); |
4391 // Make sure that we never go back to fast case. | 4386 // Make sure that we never go back to fast case. |
4392 dictionary->set_requires_slow_elements(); | 4387 dictionary->set_requires_slow_elements(); |
4393 PropertyDetails details = PropertyDetails(attr, NORMAL); | 4388 PropertyDetails details = PropertyDetails(attr, NORMAL); |
4394 Handle<NumberDictionary> extended_dictionary = | 4389 Handle<SeededNumberDictionary> extended_dictionary = |
4395 NumberDictionarySet(dictionary, index, value, details); | 4390 SeededNumberDictionary::Set(dictionary, index, value, details); |
4396 if (*extended_dictionary != *dictionary) { | 4391 if (*extended_dictionary != *dictionary) { |
4397 js_object->set_elements(*extended_dictionary); | 4392 js_object->set_elements(*extended_dictionary); |
4398 } | 4393 } |
4399 return *value; | 4394 return *value; |
4400 } | 4395 } |
4401 | 4396 |
4402 | 4397 |
4403 MaybeObject* Runtime::SetObjectProperty(Isolate* isolate, | 4398 MaybeObject* Runtime::SetObjectProperty(Isolate* isolate, |
4404 Handle<Object> object, | 4399 Handle<Object> object, |
4405 Handle<Object> key, | 4400 Handle<Object> key, |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4440 // string does nothing with the assignment then we can ignore such | 4435 // string does nothing with the assignment then we can ignore such |
4441 // assignments. | 4436 // assignments. |
4442 if (js_object->IsStringObjectWithCharacterAt(index)) { | 4437 if (js_object->IsStringObjectWithCharacterAt(index)) { |
4443 return *value; | 4438 return *value; |
4444 } | 4439 } |
4445 | 4440 |
4446 if (((attr & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0)) { | 4441 if (((attr & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0)) { |
4447 return NormalizeObjectSetElement(isolate, js_object, index, value, attr); | 4442 return NormalizeObjectSetElement(isolate, js_object, index, value, attr); |
4448 } | 4443 } |
4449 | 4444 |
4450 Handle<Object> result = SetElement(js_object, index, value, strict_mode); | 4445 Handle<Object> result = |
| 4446 JSObject::SetElement(js_object, index, value, strict_mode); |
4451 if (result.is_null()) return Failure::Exception(); | 4447 if (result.is_null()) return Failure::Exception(); |
4452 return *value; | 4448 return *value; |
4453 } | 4449 } |
4454 | 4450 |
4455 if (key->IsString()) { | 4451 if (key->IsString()) { |
4456 Handle<Object> result; | 4452 Handle<Object> result; |
4457 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { | 4453 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { |
4458 if (((attr & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0)) { | 4454 if (((attr & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0)) { |
4459 return NormalizeObjectSetElement(isolate, | 4455 return NormalizeObjectSetElement(isolate, |
4460 js_object, | 4456 js_object, |
4461 index, | 4457 index, |
4462 value, | 4458 value, |
4463 attr); | 4459 attr); |
4464 } | 4460 } |
4465 result = SetElement(js_object, index, value, strict_mode); | 4461 result = |
| 4462 JSObject::SetElement(js_object, index, value, strict_mode); |
4466 } else { | 4463 } else { |
4467 Handle<String> key_string = Handle<String>::cast(key); | 4464 Handle<String> key_string = Handle<String>::cast(key); |
4468 key_string->TryFlatten(); | 4465 key_string->TryFlatten(); |
4469 result = SetProperty(js_object, key_string, value, attr, strict_mode); | 4466 result = JSReceiver::SetProperty( |
| 4467 js_object, key_string, value, attr, strict_mode); |
4470 } | 4468 } |
4471 if (result.is_null()) return Failure::Exception(); | 4469 if (result.is_null()) return Failure::Exception(); |
4472 return *value; | 4470 return *value; |
4473 } | 4471 } |
4474 | 4472 |
4475 // Call-back into JavaScript to convert the key to a string. | 4473 // Call-back into JavaScript to convert the key to a string. |
4476 bool has_pending_exception = false; | 4474 bool has_pending_exception = false; |
4477 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); | 4475 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); |
4478 if (has_pending_exception) return Failure::Exception(); | 4476 if (has_pending_exception) return Failure::Exception(); |
4479 Handle<String> name = Handle<String>::cast(converted); | 4477 Handle<String> name = Handle<String>::cast(converted); |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4648 Handle<JSArray> boilerplate_object(JSArray::cast(raw_boilerplate_object)); | 4646 Handle<JSArray> boilerplate_object(JSArray::cast(raw_boilerplate_object)); |
4649 #if DEBUG | 4647 #if DEBUG |
4650 ElementsKind elements_kind = object->GetElementsKind(); | 4648 ElementsKind elements_kind = object->GetElementsKind(); |
4651 #endif | 4649 #endif |
4652 ASSERT(elements_kind <= FAST_DOUBLE_ELEMENTS); | 4650 ASSERT(elements_kind <= FAST_DOUBLE_ELEMENTS); |
4653 // Smis should never trigger transitions. | 4651 // Smis should never trigger transitions. |
4654 ASSERT(!value->IsSmi()); | 4652 ASSERT(!value->IsSmi()); |
4655 | 4653 |
4656 if (value->IsNumber()) { | 4654 if (value->IsNumber()) { |
4657 ASSERT(elements_kind == FAST_SMI_ONLY_ELEMENTS); | 4655 ASSERT(elements_kind == FAST_SMI_ONLY_ELEMENTS); |
4658 TransitionElementsKind(object, FAST_DOUBLE_ELEMENTS); | 4656 JSObject::TransitionElementsKind(object, FAST_DOUBLE_ELEMENTS); |
4659 TransitionElementsKind(boilerplate_object, FAST_DOUBLE_ELEMENTS); | 4657 JSObject::TransitionElementsKind(boilerplate_object, FAST_DOUBLE_ELEMENTS); |
4660 ASSERT(object->GetElementsKind() == FAST_DOUBLE_ELEMENTS); | 4658 ASSERT(object->GetElementsKind() == FAST_DOUBLE_ELEMENTS); |
4661 FixedDoubleArray* double_array = | 4659 FixedDoubleArray* double_array = |
4662 FixedDoubleArray::cast(object->elements()); | 4660 FixedDoubleArray::cast(object->elements()); |
4663 HeapNumber* number = HeapNumber::cast(*value); | 4661 HeapNumber* number = HeapNumber::cast(*value); |
4664 double_array->set(store_index, number->Number()); | 4662 double_array->set(store_index, number->Number()); |
4665 } else { | 4663 } else { |
4666 ASSERT(elements_kind == FAST_SMI_ONLY_ELEMENTS || | 4664 ASSERT(elements_kind == FAST_SMI_ONLY_ELEMENTS || |
4667 elements_kind == FAST_DOUBLE_ELEMENTS); | 4665 elements_kind == FAST_DOUBLE_ELEMENTS); |
4668 TransitionElementsKind(object, FAST_ELEMENTS); | 4666 JSObject::TransitionElementsKind(object, FAST_ELEMENTS); |
4669 TransitionElementsKind(boilerplate_object, FAST_ELEMENTS); | 4667 JSObject::TransitionElementsKind(boilerplate_object, FAST_ELEMENTS); |
4670 FixedArray* object_array = | 4668 FixedArray* object_array = |
4671 FixedArray::cast(object->elements()); | 4669 FixedArray::cast(object->elements()); |
4672 object_array->set(store_index, *value); | 4670 object_array->set(store_index, *value); |
4673 } | 4671 } |
4674 return *object; | 4672 return *object; |
4675 } | 4673 } |
4676 | 4674 |
4677 | 4675 |
4678 // Set a local property, even if it is READ_ONLY. If the property does not | 4676 // Set a local property, even if it is READ_ONLY. If the property does not |
4679 // exist, it will be added with attributes NONE. | 4677 // exist, it will be added with attributes NONE. |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4811 case JSObject::DICTIONARY_ELEMENT: { | 4809 case JSObject::DICTIONARY_ELEMENT: { |
4812 if (object->IsJSGlobalProxy()) { | 4810 if (object->IsJSGlobalProxy()) { |
4813 Object* proto = object->GetPrototype(); | 4811 Object* proto = object->GetPrototype(); |
4814 if (proto->IsNull()) { | 4812 if (proto->IsNull()) { |
4815 return isolate->heap()->false_value(); | 4813 return isolate->heap()->false_value(); |
4816 } | 4814 } |
4817 ASSERT(proto->IsJSGlobalObject()); | 4815 ASSERT(proto->IsJSGlobalObject()); |
4818 object = JSObject::cast(proto); | 4816 object = JSObject::cast(proto); |
4819 } | 4817 } |
4820 FixedArray* elements = FixedArray::cast(object->elements()); | 4818 FixedArray* elements = FixedArray::cast(object->elements()); |
4821 NumberDictionary* dictionary = NULL; | 4819 SeededNumberDictionary* dictionary = NULL; |
4822 if (elements->map() == | 4820 if (elements->map() == |
4823 isolate->heap()->non_strict_arguments_elements_map()) { | 4821 isolate->heap()->non_strict_arguments_elements_map()) { |
4824 dictionary = NumberDictionary::cast(elements->get(1)); | 4822 dictionary = SeededNumberDictionary::cast(elements->get(1)); |
4825 } else { | 4823 } else { |
4826 dictionary = NumberDictionary::cast(elements); | 4824 dictionary = SeededNumberDictionary::cast(elements); |
4827 } | 4825 } |
4828 int entry = dictionary->FindEntry(index); | 4826 int entry = dictionary->FindEntry(index); |
4829 ASSERT(entry != NumberDictionary::kNotFound); | 4827 ASSERT(entry != SeededNumberDictionary::kNotFound); |
4830 PropertyDetails details = dictionary->DetailsAt(entry); | 4828 PropertyDetails details = dictionary->DetailsAt(entry); |
4831 return isolate->heap()->ToBoolean(!details.IsDontEnum()); | 4829 return isolate->heap()->ToBoolean(!details.IsDontEnum()); |
4832 } | 4830 } |
4833 } | 4831 } |
4834 } | 4832 } |
4835 | 4833 |
4836 PropertyAttributes att = object->GetLocalPropertyAttribute(key); | 4834 PropertyAttributes att = object->GetLocalPropertyAttribute(key); |
4837 return isolate->heap()->ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0); | 4835 return isolate->heap()->ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0); |
4838 } | 4836 } |
4839 | 4837 |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5137 } | 5135 } |
5138 return function; | 5136 return function; |
5139 } | 5137 } |
5140 | 5138 |
5141 // Lookup in the initial Object.prototype object. | 5139 // Lookup in the initial Object.prototype object. |
5142 return isolate->initial_object_prototype()->GetProperty(*key); | 5140 return isolate->initial_object_prototype()->GetProperty(*key); |
5143 } | 5141 } |
5144 | 5142 |
5145 | 5143 |
5146 RUNTIME_FUNCTION(MaybeObject*, Runtime_ToFastProperties) { | 5144 RUNTIME_FUNCTION(MaybeObject*, Runtime_ToFastProperties) { |
5147 HandleScope scope(isolate); | |
5148 | |
5149 ASSERT(args.length() == 1); | 5145 ASSERT(args.length() == 1); |
5150 Handle<Object> object = args.at<Object>(0); | 5146 Object* object = args[0]; |
5151 if (object->IsJSObject()) { | 5147 return (object->IsJSObject() && !object->IsGlobalObject()) |
5152 Handle<JSObject> js_object = Handle<JSObject>::cast(object); | 5148 ? JSObject::cast(object)->TransformToFastProperties(0) |
5153 if (!js_object->HasFastProperties() && !js_object->IsGlobalObject()) { | 5149 : object; |
5154 MaybeObject* ok = js_object->TransformToFastProperties(0); | |
5155 if (ok->IsRetryAfterGC()) return ok; | |
5156 } | |
5157 } | |
5158 return *object; | |
5159 } | 5150 } |
5160 | 5151 |
5161 | 5152 |
5162 RUNTIME_FUNCTION(MaybeObject*, Runtime_ToSlowProperties) { | 5153 RUNTIME_FUNCTION(MaybeObject*, Runtime_ToSlowProperties) { |
5163 HandleScope scope(isolate); | |
5164 | |
5165 ASSERT(args.length() == 1); | 5154 ASSERT(args.length() == 1); |
5166 Handle<Object> object = args.at<Object>(0); | 5155 Object* obj = args[0]; |
5167 if (object->IsJSObject() && !object->IsJSGlobalProxy()) { | 5156 return (obj->IsJSObject() && !obj->IsJSGlobalProxy()) |
5168 Handle<JSObject> js_object = Handle<JSObject>::cast(object); | 5157 ? JSObject::cast(obj)->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0) |
5169 NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); | 5158 : obj; |
5170 } | |
5171 return *object; | |
5172 } | 5159 } |
5173 | 5160 |
5174 | 5161 |
5175 RUNTIME_FUNCTION(MaybeObject*, Runtime_ToBool) { | 5162 RUNTIME_FUNCTION(MaybeObject*, Runtime_ToBool) { |
5176 NoHandleAllocation ha; | 5163 NoHandleAllocation ha; |
5177 ASSERT(args.length() == 1); | 5164 ASSERT(args.length() == 1); |
5178 | 5165 |
5179 return args[0]->ToBoolean(); | 5166 return args[0]->ToBoolean(); |
5180 } | 5167 } |
5181 | 5168 |
(...skipping 3944 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9126 // In non-strict mode, the property is added to the global object. | 9113 // In non-strict mode, the property is added to the global object. |
9127 attributes = NONE; | 9114 attributes = NONE; |
9128 object = Handle<JSObject>(isolate->context()->global()); | 9115 object = Handle<JSObject>(isolate->context()->global()); |
9129 } | 9116 } |
9130 | 9117 |
9131 // Set the property if it's not read only or doesn't yet exist. | 9118 // Set the property if it's not read only or doesn't yet exist. |
9132 if ((attributes & READ_ONLY) == 0 || | 9119 if ((attributes & READ_ONLY) == 0 || |
9133 (object->GetLocalPropertyAttribute(*name) == ABSENT)) { | 9120 (object->GetLocalPropertyAttribute(*name) == ABSENT)) { |
9134 RETURN_IF_EMPTY_HANDLE( | 9121 RETURN_IF_EMPTY_HANDLE( |
9135 isolate, | 9122 isolate, |
9136 SetProperty(object, name, value, NONE, strict_mode)); | 9123 JSReceiver::SetProperty(object, name, value, NONE, strict_mode)); |
9137 } else if (strict_mode == kStrictMode && (attributes & READ_ONLY) != 0) { | 9124 } else if (strict_mode == kStrictMode && (attributes & READ_ONLY) != 0) { |
9138 // Setting read only property in strict mode. | 9125 // Setting read only property in strict mode. |
9139 Handle<Object> error = | 9126 Handle<Object> error = |
9140 isolate->factory()->NewTypeError( | 9127 isolate->factory()->NewTypeError( |
9141 "strict_cannot_assign", HandleVector(&name, 1)); | 9128 "strict_cannot_assign", HandleVector(&name, 1)); |
9142 return isolate->Throw(*error); | 9129 return isolate->Throw(*error); |
9143 } | 9130 } |
9144 return *value; | 9131 return *value; |
9145 } | 9132 } |
9146 | 9133 |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9379 // Syntax error or stack overflow in scanner. | 9366 // Syntax error or stack overflow in scanner. |
9380 ASSERT(isolate->has_pending_exception()); | 9367 ASSERT(isolate->has_pending_exception()); |
9381 return Failure::Exception(); | 9368 return Failure::Exception(); |
9382 } | 9369 } |
9383 return *result; | 9370 return *result; |
9384 } | 9371 } |
9385 | 9372 |
9386 | 9373 |
9387 bool CodeGenerationFromStringsAllowed(Isolate* isolate, | 9374 bool CodeGenerationFromStringsAllowed(Isolate* isolate, |
9388 Handle<Context> context) { | 9375 Handle<Context> context) { |
9389 if (context->allow_code_gen_from_strings()->IsFalse()) { | 9376 ASSERT(context->allow_code_gen_from_strings()->IsFalse()); |
9390 // Check with callback if set. | 9377 // Check with callback if set. |
9391 AllowCodeGenerationFromStringsCallback callback = | 9378 AllowCodeGenerationFromStringsCallback callback = |
9392 isolate->allow_code_gen_callback(); | 9379 isolate->allow_code_gen_callback(); |
9393 if (callback == NULL) { | 9380 if (callback == NULL) { |
9394 // No callback set and code generation disallowed. | 9381 // No callback set and code generation disallowed. |
9395 return false; | 9382 return false; |
9396 } else { | 9383 } else { |
9397 // Callback set. Let it decide if code generation is allowed. | 9384 // Callback set. Let it decide if code generation is allowed. |
9398 VMState state(isolate, EXTERNAL); | 9385 VMState state(isolate, EXTERNAL); |
9399 return callback(v8::Utils::ToLocal(context)); | 9386 return callback(v8::Utils::ToLocal(context)); |
9400 } | |
9401 } | 9387 } |
9402 return true; | |
9403 } | 9388 } |
9404 | 9389 |
9405 | 9390 |
9406 RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileString) { | 9391 RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileString) { |
9407 HandleScope scope(isolate); | 9392 HandleScope scope(isolate); |
9408 ASSERT_EQ(1, args.length()); | 9393 ASSERT_EQ(1, args.length()); |
9409 CONVERT_ARG_CHECKED(String, source, 0); | 9394 CONVERT_ARG_CHECKED(String, source, 0); |
9410 | 9395 |
9411 // Extract global context. | 9396 // Extract global context. |
9412 Handle<Context> context(isolate->context()->global_context()); | 9397 Handle<Context> context(isolate->context()->global_context()); |
9413 | 9398 |
9414 // Check if global context allows code generation from | 9399 // Check if global context allows code generation from |
9415 // strings. Throw an exception if it doesn't. | 9400 // strings. Throw an exception if it doesn't. |
9416 if (!CodeGenerationFromStringsAllowed(isolate, context)) { | 9401 if (context->allow_code_gen_from_strings()->IsFalse() && |
| 9402 !CodeGenerationFromStringsAllowed(isolate, context)) { |
9417 return isolate->Throw(*isolate->factory()->NewError( | 9403 return isolate->Throw(*isolate->factory()->NewError( |
9418 "code_gen_from_strings", HandleVector<Object>(NULL, 0))); | 9404 "code_gen_from_strings", HandleVector<Object>(NULL, 0))); |
9419 } | 9405 } |
9420 | 9406 |
9421 // Compile source string in the global context. | 9407 // Compile source string in the global context. |
9422 Handle<SharedFunctionInfo> shared = Compiler::CompileEval( | 9408 Handle<SharedFunctionInfo> shared = Compiler::CompileEval( |
9423 source, context, true, CLASSIC_MODE, RelocInfo::kNoPosition); | 9409 source, context, true, CLASSIC_MODE, RelocInfo::kNoPosition); |
9424 if (shared.is_null()) return Failure::Exception(); | 9410 if (shared.is_null()) return Failure::Exception(); |
9425 Handle<JSFunction> fun = | 9411 Handle<JSFunction> fun = |
9426 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, | 9412 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, |
9427 context, | 9413 context, |
9428 NOT_TENURED); | 9414 NOT_TENURED); |
9429 return *fun; | 9415 return *fun; |
9430 } | 9416 } |
9431 | 9417 |
9432 | 9418 |
9433 static ObjectPair CompileGlobalEval(Isolate* isolate, | 9419 static ObjectPair CompileGlobalEval(Isolate* isolate, |
9434 Handle<String> source, | 9420 Handle<String> source, |
9435 Handle<Object> receiver, | 9421 Handle<Object> receiver, |
9436 LanguageMode language_mode, | 9422 LanguageMode language_mode, |
9437 int scope_position) { | 9423 int scope_position) { |
9438 Handle<Context> context = Handle<Context>(isolate->context()); | 9424 Handle<Context> context = Handle<Context>(isolate->context()); |
9439 Handle<Context> global_context = Handle<Context>(context->global_context()); | 9425 Handle<Context> global_context = Handle<Context>(context->global_context()); |
9440 | 9426 |
9441 // Check if global context allows code generation from | 9427 // Check if global context allows code generation from |
9442 // strings. Throw an exception if it doesn't. | 9428 // strings. Throw an exception if it doesn't. |
9443 if (!CodeGenerationFromStringsAllowed(isolate, global_context)) { | 9429 if (global_context->allow_code_gen_from_strings()->IsFalse() && |
| 9430 !CodeGenerationFromStringsAllowed(isolate, global_context)) { |
9444 isolate->Throw(*isolate->factory()->NewError( | 9431 isolate->Throw(*isolate->factory()->NewError( |
9445 "code_gen_from_strings", HandleVector<Object>(NULL, 0))); | 9432 "code_gen_from_strings", HandleVector<Object>(NULL, 0))); |
9446 return MakePair(Failure::Exception(), NULL); | 9433 return MakePair(Failure::Exception(), NULL); |
9447 } | 9434 } |
9448 | 9435 |
9449 // Deal with a normal eval call with a string argument. Compile it | 9436 // Deal with a normal eval call with a string argument. Compile it |
9450 // and return the compiled function bound in the local context. | 9437 // and return the compiled function bound in the local context. |
9451 Handle<SharedFunctionInfo> shared = Compiler::CompileEval( | 9438 Handle<SharedFunctionInfo> shared = Compiler::CompileEval( |
9452 source, | 9439 source, |
9453 Handle<Context>(isolate->context()), | 9440 Handle<Context>(isolate->context()), |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9589 return; | 9576 return; |
9590 } | 9577 } |
9591 // Our initial estimate of length was foiled, possibly by | 9578 // Our initial estimate of length was foiled, possibly by |
9592 // getters on the arrays increasing the length of later arrays | 9579 // getters on the arrays increasing the length of later arrays |
9593 // during iteration. | 9580 // during iteration. |
9594 // This shouldn't happen in anything but pathological cases. | 9581 // This shouldn't happen in anything but pathological cases. |
9595 SetDictionaryMode(index); | 9582 SetDictionaryMode(index); |
9596 // Fall-through to dictionary mode. | 9583 // Fall-through to dictionary mode. |
9597 } | 9584 } |
9598 ASSERT(!fast_elements_); | 9585 ASSERT(!fast_elements_); |
9599 Handle<NumberDictionary> dict(NumberDictionary::cast(*storage_)); | 9586 Handle<SeededNumberDictionary> dict( |
9600 Handle<NumberDictionary> result = | 9587 SeededNumberDictionary::cast(*storage_)); |
| 9588 Handle<SeededNumberDictionary> result = |
9601 isolate_->factory()->DictionaryAtNumberPut(dict, index, elm); | 9589 isolate_->factory()->DictionaryAtNumberPut(dict, index, elm); |
9602 if (!result.is_identical_to(dict)) { | 9590 if (!result.is_identical_to(dict)) { |
9603 // Dictionary needed to grow. | 9591 // Dictionary needed to grow. |
9604 clear_storage(); | 9592 clear_storage(); |
9605 set_storage(*result); | 9593 set_storage(*result); |
9606 } | 9594 } |
9607 } | 9595 } |
9608 | 9596 |
9609 void increase_index_offset(uint32_t delta) { | 9597 void increase_index_offset(uint32_t delta) { |
9610 if (JSObject::kMaxElementCount - index_offset_ < delta) { | 9598 if (JSObject::kMaxElementCount - index_offset_ < delta) { |
(...skipping 19 matching lines...) Expand all Loading... |
9630 array->set_length(*length); | 9618 array->set_length(*length); |
9631 array->set_elements(*storage_); | 9619 array->set_elements(*storage_); |
9632 return array; | 9620 return array; |
9633 } | 9621 } |
9634 | 9622 |
9635 private: | 9623 private: |
9636 // Convert storage to dictionary mode. | 9624 // Convert storage to dictionary mode. |
9637 void SetDictionaryMode(uint32_t index) { | 9625 void SetDictionaryMode(uint32_t index) { |
9638 ASSERT(fast_elements_); | 9626 ASSERT(fast_elements_); |
9639 Handle<FixedArray> current_storage(*storage_); | 9627 Handle<FixedArray> current_storage(*storage_); |
9640 Handle<NumberDictionary> slow_storage( | 9628 Handle<SeededNumberDictionary> slow_storage( |
9641 isolate_->factory()->NewNumberDictionary(current_storage->length())); | 9629 isolate_->factory()->NewSeededNumberDictionary( |
| 9630 current_storage->length())); |
9642 uint32_t current_length = static_cast<uint32_t>(current_storage->length()); | 9631 uint32_t current_length = static_cast<uint32_t>(current_storage->length()); |
9643 for (uint32_t i = 0; i < current_length; i++) { | 9632 for (uint32_t i = 0; i < current_length; i++) { |
9644 HandleScope loop_scope; | 9633 HandleScope loop_scope; |
9645 Handle<Object> element(current_storage->get(i)); | 9634 Handle<Object> element(current_storage->get(i)); |
9646 if (!element->IsTheHole()) { | 9635 if (!element->IsTheHole()) { |
9647 Handle<NumberDictionary> new_storage = | 9636 Handle<SeededNumberDictionary> new_storage = |
9648 isolate_->factory()->DictionaryAtNumberPut(slow_storage, i, element); | 9637 isolate_->factory()->DictionaryAtNumberPut(slow_storage, i, element); |
9649 if (!new_storage.is_identical_to(slow_storage)) { | 9638 if (!new_storage.is_identical_to(slow_storage)) { |
9650 slow_storage = loop_scope.CloseAndEscape(new_storage); | 9639 slow_storage = loop_scope.CloseAndEscape(new_storage); |
9651 } | 9640 } |
9652 } | 9641 } |
9653 } | 9642 } |
9654 clear_storage(); | 9643 clear_storage(); |
9655 set_storage(*slow_storage); | 9644 set_storage(*slow_storage); |
9656 fast_elements_ = false; | 9645 fast_elements_ = false; |
9657 } | 9646 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9689 for (int i = 0; i < fast_length; i++) { | 9678 for (int i = 0; i < fast_length; i++) { |
9690 if (!elements->get(i)->IsTheHole()) element_count++; | 9679 if (!elements->get(i)->IsTheHole()) element_count++; |
9691 } | 9680 } |
9692 break; | 9681 break; |
9693 } | 9682 } |
9694 case FAST_DOUBLE_ELEMENTS: | 9683 case FAST_DOUBLE_ELEMENTS: |
9695 // TODO(1810): Decide if it's worthwhile to implement this. | 9684 // TODO(1810): Decide if it's worthwhile to implement this. |
9696 UNREACHABLE(); | 9685 UNREACHABLE(); |
9697 break; | 9686 break; |
9698 case DICTIONARY_ELEMENTS: { | 9687 case DICTIONARY_ELEMENTS: { |
9699 Handle<NumberDictionary> dictionary( | 9688 Handle<SeededNumberDictionary> dictionary( |
9700 NumberDictionary::cast(array->elements())); | 9689 SeededNumberDictionary::cast(array->elements())); |
9701 int capacity = dictionary->Capacity(); | 9690 int capacity = dictionary->Capacity(); |
9702 for (int i = 0; i < capacity; i++) { | 9691 for (int i = 0; i < capacity; i++) { |
9703 Handle<Object> key(dictionary->KeyAt(i)); | 9692 Handle<Object> key(dictionary->KeyAt(i)); |
9704 if (dictionary->IsKey(*key)) { | 9693 if (dictionary->IsKey(*key)) { |
9705 element_count++; | 9694 element_count++; |
9706 } | 9695 } |
9707 } | 9696 } |
9708 break; | 9697 break; |
9709 } | 9698 } |
9710 case NON_STRICT_ARGUMENTS_ELEMENTS: | 9699 case NON_STRICT_ARGUMENTS_ELEMENTS: |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9793 } | 9782 } |
9794 } | 9783 } |
9795 break; | 9784 break; |
9796 } | 9785 } |
9797 case FAST_DOUBLE_ELEMENTS: { | 9786 case FAST_DOUBLE_ELEMENTS: { |
9798 // TODO(1810): Decide if it's worthwhile to implement this. | 9787 // TODO(1810): Decide if it's worthwhile to implement this. |
9799 UNREACHABLE(); | 9788 UNREACHABLE(); |
9800 break; | 9789 break; |
9801 } | 9790 } |
9802 case DICTIONARY_ELEMENTS: { | 9791 case DICTIONARY_ELEMENTS: { |
9803 Handle<NumberDictionary> dict(NumberDictionary::cast(object->elements())); | 9792 Handle<SeededNumberDictionary> dict( |
| 9793 SeededNumberDictionary::cast(object->elements())); |
9804 uint32_t capacity = dict->Capacity(); | 9794 uint32_t capacity = dict->Capacity(); |
9805 for (uint32_t j = 0; j < capacity; j++) { | 9795 for (uint32_t j = 0; j < capacity; j++) { |
9806 HandleScope loop_scope; | 9796 HandleScope loop_scope; |
9807 Handle<Object> k(dict->KeyAt(j)); | 9797 Handle<Object> k(dict->KeyAt(j)); |
9808 if (dict->IsKey(*k)) { | 9798 if (dict->IsKey(*k)) { |
9809 ASSERT(k->IsNumber()); | 9799 ASSERT(k->IsNumber()); |
9810 uint32_t index = static_cast<uint32_t>(k->Number()); | 9800 uint32_t index = static_cast<uint32_t>(k->Number()); |
9811 if (index < range) { | 9801 if (index < range) { |
9812 indices->Add(index); | 9802 indices->Add(index); |
9813 } | 9803 } |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9928 } | 9918 } |
9929 } | 9919 } |
9930 break; | 9920 break; |
9931 } | 9921 } |
9932 case FAST_DOUBLE_ELEMENTS: { | 9922 case FAST_DOUBLE_ELEMENTS: { |
9933 // TODO(1810): Decide if it's worthwhile to implement this. | 9923 // TODO(1810): Decide if it's worthwhile to implement this. |
9934 UNREACHABLE(); | 9924 UNREACHABLE(); |
9935 break; | 9925 break; |
9936 } | 9926 } |
9937 case DICTIONARY_ELEMENTS: { | 9927 case DICTIONARY_ELEMENTS: { |
9938 Handle<NumberDictionary> dict(receiver->element_dictionary()); | 9928 Handle<SeededNumberDictionary> dict(receiver->element_dictionary()); |
9939 List<uint32_t> indices(dict->Capacity() / 2); | 9929 List<uint32_t> indices(dict->Capacity() / 2); |
9940 // Collect all indices in the object and the prototypes less | 9930 // Collect all indices in the object and the prototypes less |
9941 // than length. This might introduce duplicates in the indices list. | 9931 // than length. This might introduce duplicates in the indices list. |
9942 CollectElementIndices(receiver, length, &indices); | 9932 CollectElementIndices(receiver, length, &indices); |
9943 indices.Sort(&compareUInt32); | 9933 indices.Sort(&compareUInt32); |
9944 int j = 0; | 9934 int j = 0; |
9945 int n = indices.length(); | 9935 int n = indices.length(); |
9946 while (j < n) { | 9936 while (j < n) { |
9947 HandleScope loop_scope; | 9937 HandleScope loop_scope; |
9948 uint32_t index = indices[j]; | 9938 uint32_t index = indices[j]; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10042 Handle<Object> obj(elements->get(i)); | 10032 Handle<Object> obj(elements->get(i)); |
10043 uint32_t length_estimate; | 10033 uint32_t length_estimate; |
10044 uint32_t element_estimate; | 10034 uint32_t element_estimate; |
10045 if (obj->IsJSArray()) { | 10035 if (obj->IsJSArray()) { |
10046 Handle<JSArray> array(Handle<JSArray>::cast(obj)); | 10036 Handle<JSArray> array(Handle<JSArray>::cast(obj)); |
10047 // TODO(1810): Find out if it's worthwhile to properly support | 10037 // TODO(1810): Find out if it's worthwhile to properly support |
10048 // arbitrary ElementsKinds. For now, pessimistically transition to | 10038 // arbitrary ElementsKinds. For now, pessimistically transition to |
10049 // FAST_ELEMENTS. | 10039 // FAST_ELEMENTS. |
10050 if (array->HasFastDoubleElements()) { | 10040 if (array->HasFastDoubleElements()) { |
10051 array = Handle<JSArray>::cast( | 10041 array = Handle<JSArray>::cast( |
10052 TransitionElementsKind(array, FAST_ELEMENTS)); | 10042 JSObject::TransitionElementsKind(array, FAST_ELEMENTS)); |
10053 } | 10043 } |
10054 length_estimate = | 10044 length_estimate = |
10055 static_cast<uint32_t>(array->length()->Number()); | 10045 static_cast<uint32_t>(array->length()->Number()); |
10056 element_estimate = | 10046 element_estimate = |
10057 EstimateElementCount(array); | 10047 EstimateElementCount(array); |
10058 } else { | 10048 } else { |
10059 length_estimate = 1; | 10049 length_estimate = 1; |
10060 element_estimate = 1; | 10050 element_estimate = 1; |
10061 } | 10051 } |
10062 // Avoid overflows by capping at kMaxElementCount. | 10052 // Avoid overflows by capping at kMaxElementCount. |
(...skipping 21 matching lines...) Expand all Loading... |
10084 if (fast_case) { | 10074 if (fast_case) { |
10085 // The backing storage array must have non-existing elements to | 10075 // The backing storage array must have non-existing elements to |
10086 // preserve holes across concat operations. | 10076 // preserve holes across concat operations. |
10087 storage = isolate->factory()->NewFixedArrayWithHoles( | 10077 storage = isolate->factory()->NewFixedArrayWithHoles( |
10088 estimate_result_length); | 10078 estimate_result_length); |
10089 } else { | 10079 } else { |
10090 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate | 10080 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate |
10091 uint32_t at_least_space_for = estimate_nof_elements + | 10081 uint32_t at_least_space_for = estimate_nof_elements + |
10092 (estimate_nof_elements >> 2); | 10082 (estimate_nof_elements >> 2); |
10093 storage = Handle<FixedArray>::cast( | 10083 storage = Handle<FixedArray>::cast( |
10094 isolate->factory()->NewNumberDictionary(at_least_space_for)); | 10084 isolate->factory()->NewSeededNumberDictionary(at_least_space_for)); |
10095 } | 10085 } |
10096 | 10086 |
10097 ArrayConcatVisitor visitor(isolate, storage, fast_case); | 10087 ArrayConcatVisitor visitor(isolate, storage, fast_case); |
10098 | 10088 |
10099 for (int i = 0; i < argument_count; i++) { | 10089 for (int i = 0; i < argument_count; i++) { |
10100 Handle<Object> obj(elements->get(i)); | 10090 Handle<Object> obj(elements->get(i)); |
10101 if (obj->IsJSArray()) { | 10091 if (obj->IsJSArray()) { |
10102 Handle<JSArray> array = Handle<JSArray>::cast(obj); | 10092 Handle<JSArray> array = Handle<JSArray>::cast(obj); |
10103 if (!IterateElements(isolate, array, &visitor)) { | 10093 if (!IterateElements(isolate, array, &visitor)) { |
10104 return Failure::Exception(); | 10094 return Failure::Exception(); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10172 return to; | 10162 return to; |
10173 } | 10163 } |
10174 | 10164 |
10175 | 10165 |
10176 // How many elements does this object/array have? | 10166 // How many elements does this object/array have? |
10177 RUNTIME_FUNCTION(MaybeObject*, Runtime_EstimateNumberOfElements) { | 10167 RUNTIME_FUNCTION(MaybeObject*, Runtime_EstimateNumberOfElements) { |
10178 ASSERT(args.length() == 1); | 10168 ASSERT(args.length() == 1); |
10179 CONVERT_CHECKED(JSObject, object, args[0]); | 10169 CONVERT_CHECKED(JSObject, object, args[0]); |
10180 HeapObject* elements = object->elements(); | 10170 HeapObject* elements = object->elements(); |
10181 if (elements->IsDictionary()) { | 10171 if (elements->IsDictionary()) { |
10182 return Smi::FromInt(NumberDictionary::cast(elements)->NumberOfElements()); | 10172 int result = SeededNumberDictionary::cast(elements)->NumberOfElements(); |
| 10173 return Smi::FromInt(result); |
10183 } else if (object->IsJSArray()) { | 10174 } else if (object->IsJSArray()) { |
10184 return JSArray::cast(object)->length(); | 10175 return JSArray::cast(object)->length(); |
10185 } else { | 10176 } else { |
10186 return Smi::FromInt(FixedArray::cast(elements)->length()); | 10177 return Smi::FromInt(FixedArray::cast(elements)->length()); |
10187 } | 10178 } |
10188 } | 10179 } |
10189 | 10180 |
10190 | 10181 |
10191 RUNTIME_FUNCTION(MaybeObject*, Runtime_SwapElements) { | 10182 RUNTIME_FUNCTION(MaybeObject*, Runtime_SwapElements) { |
10192 HandleScope handle_scope(isolate); | 10183 HandleScope handle_scope(isolate); |
10193 | 10184 |
10194 ASSERT_EQ(3, args.length()); | 10185 ASSERT_EQ(3, args.length()); |
10195 | 10186 |
10196 CONVERT_ARG_CHECKED(JSObject, object, 0); | 10187 CONVERT_ARG_CHECKED(JSObject, object, 0); |
10197 Handle<Object> key1 = args.at<Object>(1); | 10188 Handle<Object> key1 = args.at<Object>(1); |
10198 Handle<Object> key2 = args.at<Object>(2); | 10189 Handle<Object> key2 = args.at<Object>(2); |
10199 | 10190 |
10200 uint32_t index1, index2; | 10191 uint32_t index1, index2; |
10201 if (!key1->ToArrayIndex(&index1) | 10192 if (!key1->ToArrayIndex(&index1) |
10202 || !key2->ToArrayIndex(&index2)) { | 10193 || !key2->ToArrayIndex(&index2)) { |
10203 return isolate->ThrowIllegalOperation(); | 10194 return isolate->ThrowIllegalOperation(); |
10204 } | 10195 } |
10205 | 10196 |
10206 Handle<JSObject> jsobject = Handle<JSObject>::cast(object); | 10197 Handle<JSObject> jsobject = Handle<JSObject>::cast(object); |
10207 Handle<Object> tmp1 = Object::GetElement(jsobject, index1); | 10198 Handle<Object> tmp1 = Object::GetElement(jsobject, index1); |
10208 RETURN_IF_EMPTY_HANDLE(isolate, tmp1); | 10199 RETURN_IF_EMPTY_HANDLE(isolate, tmp1); |
10209 Handle<Object> tmp2 = Object::GetElement(jsobject, index2); | 10200 Handle<Object> tmp2 = Object::GetElement(jsobject, index2); |
10210 RETURN_IF_EMPTY_HANDLE(isolate, tmp2); | 10201 RETURN_IF_EMPTY_HANDLE(isolate, tmp2); |
10211 | 10202 |
10212 RETURN_IF_EMPTY_HANDLE(isolate, | 10203 RETURN_IF_EMPTY_HANDLE( |
10213 SetElement(jsobject, index1, tmp2, kStrictMode)); | 10204 isolate, JSObject::SetElement(jsobject, index1, tmp2, kStrictMode)); |
10214 RETURN_IF_EMPTY_HANDLE(isolate, | 10205 RETURN_IF_EMPTY_HANDLE( |
10215 SetElement(jsobject, index2, tmp1, kStrictMode)); | 10206 isolate, JSObject::SetElement(jsobject, index2, tmp1, kStrictMode)); |
10216 | 10207 |
10217 return isolate->heap()->undefined_value(); | 10208 return isolate->heap()->undefined_value(); |
10218 } | 10209 } |
10219 | 10210 |
10220 | 10211 |
10221 // Returns an array that tells you where in the [0, length) interval an array | 10212 // Returns an array that tells you where in the [0, length) interval an array |
10222 // might have elements. Can either return keys (positive integers) or | 10213 // might have elements. Can either return keys (positive integers) or |
10223 // intervals (pair of a negative integer (-start-1) followed by a | 10214 // intervals (pair of a negative integer (-start-1) followed by a |
10224 // positive (length)) or undefined values. | 10215 // positive (length)) or undefined values. |
10225 // Intervals can span over some keys that are not in the object. | 10216 // Intervals can span over some keys that are not in the object. |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10481 { MaybeObject* maybe_raw_value = | 10472 { MaybeObject* maybe_raw_value = |
10482 DebugLookupResultValue(isolate->heap(), *obj, *name, | 10473 DebugLookupResultValue(isolate->heap(), *obj, *name, |
10483 &result, &caught_exception); | 10474 &result, &caught_exception); |
10484 if (!maybe_raw_value->ToObject(&raw_value)) return maybe_raw_value; | 10475 if (!maybe_raw_value->ToObject(&raw_value)) return maybe_raw_value; |
10485 } | 10476 } |
10486 Handle<Object> value(raw_value, isolate); | 10477 Handle<Object> value(raw_value, isolate); |
10487 | 10478 |
10488 // If the callback object is a fixed array then it contains JavaScript | 10479 // If the callback object is a fixed array then it contains JavaScript |
10489 // getter and/or setter. | 10480 // getter and/or setter. |
10490 bool hasJavaScriptAccessors = result_type == CALLBACKS && | 10481 bool hasJavaScriptAccessors = result_type == CALLBACKS && |
10491 result_callback_obj->IsFixedArray(); | 10482 result_callback_obj->IsAccessorPair(); |
10492 Handle<FixedArray> details = | 10483 Handle<FixedArray> details = |
10493 isolate->factory()->NewFixedArray(hasJavaScriptAccessors ? 5 : 2); | 10484 isolate->factory()->NewFixedArray(hasJavaScriptAccessors ? 5 : 2); |
10494 details->set(0, *value); | 10485 details->set(0, *value); |
10495 details->set(1, property_details); | 10486 details->set(1, property_details); |
10496 if (hasJavaScriptAccessors) { | 10487 if (hasJavaScriptAccessors) { |
10497 details->set(2, isolate->heap()->ToBoolean(caught_exception)); | 10488 details->set(2, isolate->heap()->ToBoolean(caught_exception)); |
10498 details->set(3, FixedArray::cast(*result_callback_obj)->get(0)); | 10489 details->set(3, AccessorPair::cast(*result_callback_obj)->getter()); |
10499 details->set(4, FixedArray::cast(*result_callback_obj)->get(1)); | 10490 details->set(4, AccessorPair::cast(*result_callback_obj)->setter()); |
10500 } | 10491 } |
10501 | 10492 |
10502 return *isolate->factory()->NewJSArrayWithElements(details); | 10493 return *isolate->factory()->NewJSArrayWithElements(details); |
10503 } | 10494 } |
10504 if (i < length - 1) { | 10495 if (i < length - 1) { |
10505 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); | 10496 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); |
10506 } | 10497 } |
10507 } | 10498 } |
10508 | 10499 |
10509 return isolate->heap()->undefined_value(); | 10500 return isolate->heap()->undefined_value(); |
(...skipping 3051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13561 } else { | 13552 } else { |
13562 // Handle last resort GC and make sure to allow future allocations | 13553 // Handle last resort GC and make sure to allow future allocations |
13563 // to grow the heap without causing GCs (if possible). | 13554 // to grow the heap without causing GCs (if possible). |
13564 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13555 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13565 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); | 13556 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); |
13566 } | 13557 } |
13567 } | 13558 } |
13568 | 13559 |
13569 | 13560 |
13570 } } // namespace v8::internal | 13561 } } // namespace v8::internal |
OLD | NEW |