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 1097 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1108 return heap->undefined_value(); | 1108 return heap->undefined_value(); |
1109 } | 1109 } |
1110 | 1110 |
1111 if (!CheckAccess(*obj, *name, &result, v8::ACCESS_HAS)) { | 1111 if (!CheckAccess(*obj, *name, &result, v8::ACCESS_HAS)) { |
1112 return heap->false_value(); | 1112 return heap->false_value(); |
1113 } | 1113 } |
1114 | 1114 |
1115 elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!result.IsDontEnum())); | 1115 elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!result.IsDontEnum())); |
1116 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!result.IsDontDelete())); | 1116 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!result.IsDontDelete())); |
1117 | 1117 |
1118 bool is_js_accessor = (result.type() == CALLBACKS) && | 1118 bool is_js_accessor = result.IsCallbacks() && |
1119 (result.GetCallbackObject()->IsAccessorPair()); | 1119 (result.GetCallbackObject()->IsAccessorPair()); |
1120 | 1120 |
1121 if (is_js_accessor) { | 1121 if (is_js_accessor) { |
1122 // __defineGetter__/__defineSetter__ callback. | 1122 // __defineGetter__/__defineSetter__ callback. |
1123 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); | 1123 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); |
1124 | 1124 |
1125 AccessorPair* accessors = AccessorPair::cast(result.GetCallbackObject()); | 1125 AccessorPair* accessors = AccessorPair::cast(result.GetCallbackObject()); |
1126 Object* getter = accessors->GetComponent(ACCESSOR_GETTER); | 1126 Object* getter = accessors->GetComponent(ACCESSOR_GETTER); |
1127 if (!getter->IsMap() && CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) { | 1127 if (!getter->IsMap() && CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) { |
1128 elms->set(GETTER_INDEX, getter); | 1128 elms->set(GETTER_INDEX, getter); |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1320 JSObject::cast(obj)->LocalLookup(*name, &lookup); | 1320 JSObject::cast(obj)->LocalLookup(*name, &lookup); |
1321 obj = obj->GetPrototype(); | 1321 obj = obj->GetPrototype(); |
1322 } while (!lookup.IsFound() && obj->IsJSObject() && | 1322 } while (!lookup.IsFound() && obj->IsJSObject() && |
1323 JSObject::cast(obj)->map()->is_hidden_prototype()); | 1323 JSObject::cast(obj)->map()->is_hidden_prototype()); |
1324 } else { | 1324 } else { |
1325 global->Lookup(*name, &lookup); | 1325 global->Lookup(*name, &lookup); |
1326 } | 1326 } |
1327 if (lookup.IsProperty()) { | 1327 if (lookup.IsProperty()) { |
1328 // We found an existing property. Unless it was an interceptor | 1328 // We found an existing property. Unless it was an interceptor |
1329 // that claims the property is absent, skip this declaration. | 1329 // that claims the property is absent, skip this declaration. |
1330 if (lookup.type() != INTERCEPTOR) continue; | 1330 if (!lookup.IsInterceptor()) continue; |
1331 PropertyAttributes attributes = global->GetPropertyAttribute(*name); | 1331 PropertyAttributes attributes = global->GetPropertyAttribute(*name); |
1332 if (attributes != ABSENT) continue; | 1332 if (attributes != ABSENT) continue; |
1333 // Fall-through and introduce the absent property by using | 1333 // Fall-through and introduce the absent property by using |
1334 // SetProperty. | 1334 // SetProperty. |
1335 } | 1335 } |
1336 } else if (is_function) { | 1336 } else if (is_function) { |
1337 // Copy the function and update its context. Use it as value. | 1337 // Copy the function and update its context. Use it as value. |
1338 Handle<SharedFunctionInfo> shared = | 1338 Handle<SharedFunctionInfo> shared = |
1339 Handle<SharedFunctionInfo>::cast(value); | 1339 Handle<SharedFunctionInfo>::cast(value); |
1340 Handle<JSFunction> function = | 1340 Handle<JSFunction> function = |
(...skipping 17 matching lines...) Expand all Loading... |
1358 attr |= READ_ONLY; | 1358 attr |= READ_ONLY; |
1359 } | 1359 } |
1360 | 1360 |
1361 LanguageMode language_mode = DeclareGlobalsLanguageMode::decode(flags); | 1361 LanguageMode language_mode = DeclareGlobalsLanguageMode::decode(flags); |
1362 | 1362 |
1363 if (!lookup.IsProperty() || is_function || is_module) { | 1363 if (!lookup.IsProperty() || is_function || is_module) { |
1364 // If the local property exists, check that we can reconfigure it | 1364 // If the local property exists, check that we can reconfigure it |
1365 // as required for function declarations. | 1365 // as required for function declarations. |
1366 if (lookup.IsProperty() && lookup.IsDontDelete()) { | 1366 if (lookup.IsProperty() && lookup.IsDontDelete()) { |
1367 if (lookup.IsReadOnly() || lookup.IsDontEnum() || | 1367 if (lookup.IsReadOnly() || lookup.IsDontEnum() || |
1368 lookup.type() == CALLBACKS) { | 1368 lookup.IsCallbacks()) { |
1369 return ThrowRedeclarationError( | 1369 return ThrowRedeclarationError( |
1370 isolate, is_function ? "function" : "module", name); | 1370 isolate, is_function ? "function" : "module", name); |
1371 } | 1371 } |
1372 // If the existing property is not configurable, keep its attributes. | 1372 // If the existing property is not configurable, keep its attributes. |
1373 attr = lookup.GetAttributes(); | 1373 attr = lookup.GetAttributes(); |
1374 } | 1374 } |
1375 // Define or redefine own property. | 1375 // Define or redefine own property. |
1376 RETURN_IF_EMPTY_HANDLE(isolate, | 1376 RETURN_IF_EMPTY_HANDLE(isolate, |
1377 JSObject::SetLocalPropertyIgnoreAttributes( | 1377 JSObject::SetLocalPropertyIgnoreAttributes( |
1378 global, name, value, static_cast<PropertyAttributes>(attr))); | 1378 global, name, value, static_cast<PropertyAttributes>(attr))); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1467 // Declaring a const context slot is a conflicting declaration if | 1467 // Declaring a const context slot is a conflicting declaration if |
1468 // there is a callback with that name in a prototype. It is | 1468 // there is a callback with that name in a prototype. It is |
1469 // allowed to introduce const variables in | 1469 // allowed to introduce const variables in |
1470 // JSContextExtensionObjects. They are treated specially in | 1470 // JSContextExtensionObjects. They are treated specially in |
1471 // SetProperty and no setters are invoked for those since they are | 1471 // SetProperty and no setters are invoked for those since they are |
1472 // not real JSObjects. | 1472 // not real JSObjects. |
1473 if (initial_value->IsTheHole() && | 1473 if (initial_value->IsTheHole() && |
1474 !object->IsJSContextExtensionObject()) { | 1474 !object->IsJSContextExtensionObject()) { |
1475 LookupResult lookup(isolate); | 1475 LookupResult lookup(isolate); |
1476 object->Lookup(*name, &lookup); | 1476 object->Lookup(*name, &lookup); |
1477 if (lookup.IsFound() && (lookup.type() == CALLBACKS)) { | 1477 if (lookup.IsCallbacks()) { |
1478 return ThrowRedeclarationError(isolate, "const", name); | 1478 return ThrowRedeclarationError(isolate, "const", name); |
1479 } | 1479 } |
1480 } | 1480 } |
1481 if (object->IsJSGlobalObject()) { | 1481 if (object->IsJSGlobalObject()) { |
1482 // Define own property on the global object. | 1482 // Define own property on the global object. |
1483 RETURN_IF_EMPTY_HANDLE(isolate, | 1483 RETURN_IF_EMPTY_HANDLE(isolate, |
1484 JSObject::SetLocalPropertyIgnoreAttributes(object, name, value, mode)); | 1484 JSObject::SetLocalPropertyIgnoreAttributes(object, name, value, mode)); |
1485 } else { | 1485 } else { |
1486 RETURN_IF_EMPTY_HANDLE(isolate, | 1486 RETURN_IF_EMPTY_HANDLE(isolate, |
1487 JSReceiver::SetProperty(object, name, value, mode, kNonStrictMode)); | 1487 JSReceiver::SetProperty(object, name, value, mode, kNonStrictMode)); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1520 // locally if there is an explicit initialization value that we have | 1520 // locally if there is an explicit initialization value that we have |
1521 // to assign to the property. | 1521 // to assign to the property. |
1522 // Note that objects can have hidden prototypes, so we need to traverse | 1522 // Note that objects can have hidden prototypes, so we need to traverse |
1523 // the whole chain of hidden prototypes to do a 'local' lookup. | 1523 // the whole chain of hidden prototypes to do a 'local' lookup. |
1524 Object* object = global; | 1524 Object* object = global; |
1525 LookupResult lookup(isolate); | 1525 LookupResult lookup(isolate); |
1526 while (object->IsJSObject() && | 1526 while (object->IsJSObject() && |
1527 JSObject::cast(object)->map()->is_hidden_prototype()) { | 1527 JSObject::cast(object)->map()->is_hidden_prototype()) { |
1528 JSObject* raw_holder = JSObject::cast(object); | 1528 JSObject* raw_holder = JSObject::cast(object); |
1529 raw_holder->LocalLookup(*name, &lookup); | 1529 raw_holder->LocalLookup(*name, &lookup); |
1530 if (lookup.IsFound() && lookup.type() == INTERCEPTOR) { | 1530 if (lookup.IsInterceptor()) { |
1531 HandleScope handle_scope(isolate); | 1531 HandleScope handle_scope(isolate); |
1532 Handle<JSObject> holder(raw_holder); | 1532 Handle<JSObject> holder(raw_holder); |
1533 PropertyAttributes intercepted = holder->GetPropertyAttribute(*name); | 1533 PropertyAttributes intercepted = holder->GetPropertyAttribute(*name); |
1534 // Update the raw pointer in case it's changed due to GC. | 1534 // Update the raw pointer in case it's changed due to GC. |
1535 raw_holder = *holder; | 1535 raw_holder = *holder; |
1536 if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) { | 1536 if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) { |
1537 // Found an interceptor that's not read only. | 1537 // Found an interceptor that's not read only. |
1538 if (assign) { | 1538 if (assign) { |
1539 return raw_holder->SetProperty( | 1539 return raw_holder->SetProperty( |
1540 &lookup, *name, args[2], attributes, strict_mode_flag); | 1540 &lookup, *name, args[2], attributes, strict_mode_flag); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1598 isolate, | 1598 isolate, |
1599 JSReceiver::SetProperty(global, name, value, attributes, | 1599 JSReceiver::SetProperty(global, name, value, attributes, |
1600 kNonStrictMode)); | 1600 kNonStrictMode)); |
1601 return *value; | 1601 return *value; |
1602 } | 1602 } |
1603 | 1603 |
1604 // Set the value, but only if we're assigning the initial value to a | 1604 // Set the value, but only if we're assigning the initial value to a |
1605 // constant. For now, we determine this by checking if the | 1605 // constant. For now, we determine this by checking if the |
1606 // current value is the hole. | 1606 // current value is the hole. |
1607 // Strict mode handling not needed (const is disallowed in strict mode). | 1607 // Strict mode handling not needed (const is disallowed in strict mode). |
1608 PropertyType type = lookup.type(); | 1608 if (lookup.IsField()) { |
1609 if (type == FIELD) { | |
1610 FixedArray* properties = global->properties(); | 1609 FixedArray* properties = global->properties(); |
1611 int index = lookup.GetFieldIndex(); | 1610 int index = lookup.GetFieldIndex(); |
1612 if (properties->get(index)->IsTheHole() || !lookup.IsReadOnly()) { | 1611 if (properties->get(index)->IsTheHole() || !lookup.IsReadOnly()) { |
1613 properties->set(index, *value); | 1612 properties->set(index, *value); |
1614 } | 1613 } |
1615 } else if (type == NORMAL) { | 1614 } else if (lookup.IsNormal()) { |
1616 if (global->GetNormalizedProperty(&lookup)->IsTheHole() || | 1615 if (global->GetNormalizedProperty(&lookup)->IsTheHole() || |
1617 !lookup.IsReadOnly()) { | 1616 !lookup.IsReadOnly()) { |
1618 global->SetNormalizedProperty(&lookup, *value); | 1617 global->SetNormalizedProperty(&lookup, *value); |
1619 } | 1618 } |
1620 } else { | 1619 } else { |
1621 // Ignore re-initialization of constants that have already been | 1620 // Ignore re-initialization of constants that have already been |
1622 // assigned a function value. | 1621 // assigned a function value. |
1623 ASSERT(lookup.IsReadOnly() && type == CONSTANT_FUNCTION); | 1622 ASSERT(lookup.IsReadOnly() && lookup.IsConstantFunction()); |
1624 } | 1623 } |
1625 | 1624 |
1626 // Use the set value as the result of the operation. | 1625 // Use the set value as the result of the operation. |
1627 return *value; | 1626 return *value; |
1628 } | 1627 } |
1629 | 1628 |
1630 | 1629 |
1631 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) { | 1630 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) { |
1632 HandleScope scope(isolate); | 1631 HandleScope scope(isolate); |
1633 ASSERT(args.length() == 3); | 1632 ASSERT(args.length() == 3); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1689 | 1688 |
1690 if (*object == context->extension()) { | 1689 if (*object == context->extension()) { |
1691 // This is the property that was introduced by the const declaration. | 1690 // This is the property that was introduced by the const declaration. |
1692 // Set it if it hasn't been set before. NOTE: We cannot use | 1691 // Set it if it hasn't been set before. NOTE: We cannot use |
1693 // GetProperty() to get the current value as it 'unholes' the value. | 1692 // GetProperty() to get the current value as it 'unholes' the value. |
1694 LookupResult lookup(isolate); | 1693 LookupResult lookup(isolate); |
1695 object->LocalLookupRealNamedProperty(*name, &lookup); | 1694 object->LocalLookupRealNamedProperty(*name, &lookup); |
1696 ASSERT(lookup.IsFound()); // the property was declared | 1695 ASSERT(lookup.IsFound()); // the property was declared |
1697 ASSERT(lookup.IsReadOnly()); // and it was declared as read-only | 1696 ASSERT(lookup.IsReadOnly()); // and it was declared as read-only |
1698 | 1697 |
1699 PropertyType type = lookup.type(); | 1698 if (lookup.IsField()) { |
1700 if (type == FIELD) { | |
1701 FixedArray* properties = object->properties(); | 1699 FixedArray* properties = object->properties(); |
1702 int index = lookup.GetFieldIndex(); | 1700 int index = lookup.GetFieldIndex(); |
1703 if (properties->get(index)->IsTheHole()) { | 1701 if (properties->get(index)->IsTheHole()) { |
1704 properties->set(index, *value); | 1702 properties->set(index, *value); |
1705 } | 1703 } |
1706 } else if (type == NORMAL) { | 1704 } else if (lookup.IsNormal()) { |
1707 if (object->GetNormalizedProperty(&lookup)->IsTheHole()) { | 1705 if (object->GetNormalizedProperty(&lookup)->IsTheHole()) { |
1708 object->SetNormalizedProperty(&lookup, *value); | 1706 object->SetNormalizedProperty(&lookup, *value); |
1709 } | 1707 } |
1710 } else { | 1708 } else { |
1711 // We should not reach here. Any real, named property should be | 1709 // We should not reach here. Any real, named property should be |
1712 // either a field or a dictionary slot. | 1710 // either a field or a dictionary slot. |
1713 UNREACHABLE(); | 1711 UNREACHABLE(); |
1714 } | 1712 } |
1715 } else { | 1713 } else { |
1716 // The property was found on some other object. Set it if it is not a | 1714 // The property was found on some other object. Set it if it is not a |
(...skipping 2648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4365 if (offset != -1) { | 4363 if (offset != -1) { |
4366 Object* value = receiver->FastPropertyAt(offset); | 4364 Object* value = receiver->FastPropertyAt(offset); |
4367 return value->IsTheHole() | 4365 return value->IsTheHole() |
4368 ? isolate->heap()->undefined_value() | 4366 ? isolate->heap()->undefined_value() |
4369 : value; | 4367 : value; |
4370 } | 4368 } |
4371 // Lookup cache miss. Perform lookup and update the cache if | 4369 // Lookup cache miss. Perform lookup and update the cache if |
4372 // appropriate. | 4370 // appropriate. |
4373 LookupResult result(isolate); | 4371 LookupResult result(isolate); |
4374 receiver->LocalLookup(key, &result); | 4372 receiver->LocalLookup(key, &result); |
4375 if (result.IsFound() && result.type() == FIELD) { | 4373 if (result.IsField()) { |
4376 int offset = result.GetFieldIndex(); | 4374 int offset = result.GetFieldIndex(); |
4377 keyed_lookup_cache->Update(receiver_map, key, offset); | 4375 keyed_lookup_cache->Update(receiver_map, key, offset); |
4378 return receiver->FastPropertyAt(offset); | 4376 return receiver->FastPropertyAt(offset); |
4379 } | 4377 } |
4380 } else { | 4378 } else { |
4381 // Attempt dictionary lookup. | 4379 // Attempt dictionary lookup. |
4382 StringDictionary* dictionary = receiver->property_dictionary(); | 4380 StringDictionary* dictionary = receiver->property_dictionary(); |
4383 int entry = dictionary->FindEntry(key); | 4381 int entry = dictionary->FindEntry(key); |
4384 if ((entry != StringDictionary::kNotFound) && | 4382 if ((entry != StringDictionary::kNotFound) && |
4385 (dictionary->DetailsAt(entry).type() == NORMAL)) { | 4383 (dictionary->DetailsAt(entry).type() == NORMAL)) { |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4477 CONVERT_ARG_HANDLE_CHECKED(String, name, 1); | 4475 CONVERT_ARG_HANDLE_CHECKED(String, name, 1); |
4478 CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2); | 4476 CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2); |
4479 CONVERT_SMI_ARG_CHECKED(unchecked, 3); | 4477 CONVERT_SMI_ARG_CHECKED(unchecked, 3); |
4480 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 4478 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
4481 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); | 4479 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); |
4482 | 4480 |
4483 LookupResult result(isolate); | 4481 LookupResult result(isolate); |
4484 js_object->LocalLookupRealNamedProperty(*name, &result); | 4482 js_object->LocalLookupRealNamedProperty(*name, &result); |
4485 | 4483 |
4486 // Special case for callback properties. | 4484 // Special case for callback properties. |
4487 if (result.IsFound() && result.type() == CALLBACKS) { | 4485 if (result.IsCallbacks()) { |
4488 Object* callback = result.GetCallbackObject(); | 4486 Object* callback = result.GetCallbackObject(); |
4489 // To be compatible with Safari we do not change the value on API objects | 4487 // To be compatible with Safari we do not change the value on API objects |
4490 // in Object.defineProperty(). Firefox disagrees here, and actually changes | 4488 // in Object.defineProperty(). Firefox disagrees here, and actually changes |
4491 // the value. | 4489 // the value. |
4492 if (callback->IsAccessorInfo()) { | 4490 if (callback->IsAccessorInfo()) { |
4493 return isolate->heap()->undefined_value(); | 4491 return isolate->heap()->undefined_value(); |
4494 } | 4492 } |
4495 // Avoid redefining foreign callback as data property, just use the stored | 4493 // Avoid redefining foreign callback as data property, just use the stored |
4496 // setter to update the value instead. | 4494 // setter to update the value instead. |
4497 // TODO(mstarzinger): So far this only works if property attributes don't | 4495 // TODO(mstarzinger): So far this only works if property attributes don't |
4498 // change, this should be fixed once we cleanup the underlying code. | 4496 // change, this should be fixed once we cleanup the underlying code. |
4499 if (callback->IsForeign() && result.GetAttributes() == attr) { | 4497 if (callback->IsForeign() && result.GetAttributes() == attr) { |
4500 return js_object->SetPropertyWithCallback(callback, | 4498 return js_object->SetPropertyWithCallback(callback, |
4501 *name, | 4499 *name, |
4502 *obj_value, | 4500 *obj_value, |
4503 result.holder(), | 4501 result.holder(), |
4504 kStrictMode); | 4502 kStrictMode); |
4505 } | 4503 } |
4506 } | 4504 } |
4507 | 4505 |
4508 // Take special care when attributes are different and there is already | 4506 // Take special care when attributes are different and there is already |
4509 // a property. For simplicity we normalize the property which enables us | 4507 // a property. For simplicity we normalize the property which enables us |
4510 // to not worry about changing the instance_descriptor and creating a new | 4508 // to not worry about changing the instance_descriptor and creating a new |
4511 // map. The current version of SetObjectProperty does not handle attributes | 4509 // map. The current version of SetObjectProperty does not handle attributes |
4512 // correctly in the case where a property is a field and is reset with | 4510 // correctly in the case where a property is a field and is reset with |
4513 // new attributes. | 4511 // new attributes. |
4514 if (result.IsProperty() && | 4512 if (result.IsProperty() && |
4515 (attr != result.GetAttributes() || result.type() == CALLBACKS)) { | 4513 (attr != result.GetAttributes() || result.IsCallbacks())) { |
4516 // New attributes - normalize to avoid writing to instance descriptor | 4514 // New attributes - normalize to avoid writing to instance descriptor |
4517 if (js_object->IsJSGlobalProxy()) { | 4515 if (js_object->IsJSGlobalProxy()) { |
4518 // Since the result is a property, the prototype will exist so | 4516 // Since the result is a property, the prototype will exist so |
4519 // we don't have to check for null. | 4517 // we don't have to check for null. |
4520 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype())); | 4518 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype())); |
4521 } | 4519 } |
4522 JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); | 4520 JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); |
4523 // Use IgnoreAttributes version since a readonly property may be | 4521 // Use IgnoreAttributes version since a readonly property may be |
4524 // overridden and SetProperty does not allow this. | 4522 // overridden and SetProperty does not allow this. |
4525 return js_object->SetLocalPropertyIgnoreAttributes(*name, | 4523 return js_object->SetLocalPropertyIgnoreAttributes(*name, |
(...skipping 5831 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10357 | 10355 |
10358 // Try local lookup on each of the objects. | 10356 // Try local lookup on each of the objects. |
10359 Handle<JSObject> jsproto = obj; | 10357 Handle<JSObject> jsproto = obj; |
10360 for (int i = 0; i < length; i++) { | 10358 for (int i = 0; i < length; i++) { |
10361 LookupResult result(isolate); | 10359 LookupResult result(isolate); |
10362 jsproto->LocalLookup(*name, &result); | 10360 jsproto->LocalLookup(*name, &result); |
10363 if (result.IsProperty()) { | 10361 if (result.IsProperty()) { |
10364 // LookupResult is not GC safe as it holds raw object pointers. | 10362 // LookupResult is not GC safe as it holds raw object pointers. |
10365 // GC can happen later in this code so put the required fields into | 10363 // GC can happen later in this code so put the required fields into |
10366 // local variables using handles when required for later use. | 10364 // local variables using handles when required for later use. |
10367 PropertyType result_type = result.type(); | |
10368 Handle<Object> result_callback_obj; | 10365 Handle<Object> result_callback_obj; |
10369 if (result_type == CALLBACKS) { | 10366 if (result.IsCallbacks()) { |
10370 result_callback_obj = Handle<Object>(result.GetCallbackObject(), | 10367 result_callback_obj = Handle<Object>(result.GetCallbackObject(), |
10371 isolate); | 10368 isolate); |
10372 } | 10369 } |
10373 Smi* property_details = result.GetPropertyDetails().AsSmi(); | 10370 Smi* property_details = result.GetPropertyDetails().AsSmi(); |
10374 // DebugLookupResultValue can cause GC so details from LookupResult needs | 10371 // DebugLookupResultValue can cause GC so details from LookupResult needs |
10375 // to be copied to handles before this. | 10372 // to be copied to handles before this. |
10376 bool caught_exception = false; | 10373 bool caught_exception = false; |
10377 Object* raw_value; | 10374 Object* raw_value; |
10378 { MaybeObject* maybe_raw_value = | 10375 { MaybeObject* maybe_raw_value = |
10379 DebugLookupResultValue(isolate->heap(), *obj, *name, | 10376 DebugLookupResultValue(isolate->heap(), *obj, *name, |
10380 &result, &caught_exception); | 10377 &result, &caught_exception); |
10381 if (!maybe_raw_value->ToObject(&raw_value)) return maybe_raw_value; | 10378 if (!maybe_raw_value->ToObject(&raw_value)) return maybe_raw_value; |
10382 } | 10379 } |
10383 Handle<Object> value(raw_value, isolate); | 10380 Handle<Object> value(raw_value, isolate); |
10384 | 10381 |
10385 // If the callback object is a fixed array then it contains JavaScript | 10382 // If the callback object is a fixed array then it contains JavaScript |
10386 // getter and/or setter. | 10383 // getter and/or setter. |
10387 bool hasJavaScriptAccessors = result_type == CALLBACKS && | 10384 bool hasJavaScriptAccessors = result.IsCallbacks() && |
10388 result_callback_obj->IsAccessorPair(); | 10385 result_callback_obj->IsAccessorPair(); |
10389 Handle<FixedArray> details = | 10386 Handle<FixedArray> details = |
10390 isolate->factory()->NewFixedArray(hasJavaScriptAccessors ? 5 : 2); | 10387 isolate->factory()->NewFixedArray(hasJavaScriptAccessors ? 5 : 2); |
10391 details->set(0, *value); | 10388 details->set(0, *value); |
10392 details->set(1, property_details); | 10389 details->set(1, property_details); |
10393 if (hasJavaScriptAccessors) { | 10390 if (hasJavaScriptAccessors) { |
10394 AccessorPair* accessors = AccessorPair::cast(*result_callback_obj); | 10391 AccessorPair* accessors = AccessorPair::cast(*result_callback_obj); |
10395 details->set(2, isolate->heap()->ToBoolean(caught_exception)); | 10392 details->set(2, isolate->heap()->ToBoolean(caught_exception)); |
10396 details->set(3, accessors->GetComponent(ACCESSOR_GETTER)); | 10393 details->set(3, accessors->GetComponent(ACCESSOR_GETTER)); |
10397 details->set(4, accessors->GetComponent(ACCESSOR_SETTER)); | 10394 details->set(4, accessors->GetComponent(ACCESSOR_SETTER)); |
(...skipping 3254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13652 // Handle last resort GC and make sure to allow future allocations | 13649 // Handle last resort GC and make sure to allow future allocations |
13653 // to grow the heap without causing GCs (if possible). | 13650 // to grow the heap without causing GCs (if possible). |
13654 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13651 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13655 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13652 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13656 "Runtime::PerformGC"); | 13653 "Runtime::PerformGC"); |
13657 } | 13654 } |
13658 } | 13655 } |
13659 | 13656 |
13660 | 13657 |
13661 } } // namespace v8::internal | 13658 } } // namespace v8::internal |
OLD | NEW |