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 1416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1427 // Declaring a const context slot is a conflicting declaration if | 1427 // Declaring a const context slot is a conflicting declaration if |
1428 // there is a callback with that name in a prototype. It is | 1428 // there is a callback with that name in a prototype. It is |
1429 // allowed to introduce const variables in | 1429 // allowed to introduce const variables in |
1430 // JSContextExtensionObjects. They are treated specially in | 1430 // JSContextExtensionObjects. They are treated specially in |
1431 // SetProperty and no setters are invoked for those since they are | 1431 // SetProperty and no setters are invoked for those since they are |
1432 // not real JSObjects. | 1432 // not real JSObjects. |
1433 if (initial_value->IsTheHole() && | 1433 if (initial_value->IsTheHole() && |
1434 !object->IsJSContextExtensionObject()) { | 1434 !object->IsJSContextExtensionObject()) { |
1435 LookupResult lookup(isolate); | 1435 LookupResult lookup(isolate); |
1436 object->Lookup(*name, &lookup); | 1436 object->Lookup(*name, &lookup); |
1437 if (lookup.IsProperty() && (lookup.type() == CALLBACKS)) { | 1437 if (lookup.IsFound() && (lookup.type() == CALLBACKS)) { |
1438 return ThrowRedeclarationError(isolate, "const", name); | 1438 return ThrowRedeclarationError(isolate, "const", name); |
1439 } | 1439 } |
1440 } | 1440 } |
1441 RETURN_IF_EMPTY_HANDLE( | 1441 RETURN_IF_EMPTY_HANDLE( |
1442 isolate, | 1442 isolate, |
1443 JSReceiver::SetProperty(object, name, value, mode, kNonStrictMode)); | 1443 JSReceiver::SetProperty(object, name, value, mode, kNonStrictMode)); |
1444 } | 1444 } |
1445 | 1445 |
1446 return isolate->heap()->undefined_value(); | 1446 return isolate->heap()->undefined_value(); |
1447 } | 1447 } |
(...skipping 27 matching lines...) Expand all Loading... |
1475 // locally if there is an explicit initialization value that we have | 1475 // locally if there is an explicit initialization value that we have |
1476 // to assign to the property. | 1476 // to assign to the property. |
1477 // Note that objects can have hidden prototypes, so we need to traverse | 1477 // Note that objects can have hidden prototypes, so we need to traverse |
1478 // the whole chain of hidden prototypes to do a 'local' lookup. | 1478 // the whole chain of hidden prototypes to do a 'local' lookup. |
1479 Object* object = global; | 1479 Object* object = global; |
1480 LookupResult lookup(isolate); | 1480 LookupResult lookup(isolate); |
1481 while (object->IsJSObject() && | 1481 while (object->IsJSObject() && |
1482 JSObject::cast(object)->map()->is_hidden_prototype()) { | 1482 JSObject::cast(object)->map()->is_hidden_prototype()) { |
1483 JSObject* raw_holder = JSObject::cast(object); | 1483 JSObject* raw_holder = JSObject::cast(object); |
1484 raw_holder->LocalLookup(*name, &lookup); | 1484 raw_holder->LocalLookup(*name, &lookup); |
1485 if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) { | 1485 if (lookup.IsFound() && lookup.type() == INTERCEPTOR) { |
1486 HandleScope handle_scope(isolate); | 1486 HandleScope handle_scope(isolate); |
1487 Handle<JSObject> holder(raw_holder); | 1487 Handle<JSObject> holder(raw_holder); |
1488 PropertyAttributes intercepted = holder->GetPropertyAttribute(*name); | 1488 PropertyAttributes intercepted = holder->GetPropertyAttribute(*name); |
1489 // Update the raw pointer in case it's changed due to GC. | 1489 // Update the raw pointer in case it's changed due to GC. |
1490 raw_holder = *holder; | 1490 raw_holder = *holder; |
1491 if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) { | 1491 if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) { |
1492 // Found an interceptor that's not read only. | 1492 // Found an interceptor that's not read only. |
1493 if (assign) { | 1493 if (assign) { |
1494 return raw_holder->SetProperty( | 1494 return raw_holder->SetProperty( |
1495 &lookup, *name, args[2], attributes, strict_mode_flag); | 1495 &lookup, *name, args[2], attributes, strict_mode_flag); |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1641 // | 1641 // |
1642 // In that case, the initialization behaves like a normal assignment. | 1642 // In that case, the initialization behaves like a normal assignment. |
1643 Handle<JSObject> object = Handle<JSObject>::cast(holder); | 1643 Handle<JSObject> object = Handle<JSObject>::cast(holder); |
1644 | 1644 |
1645 if (*object == context->extension()) { | 1645 if (*object == context->extension()) { |
1646 // This is the property that was introduced by the const declaration. | 1646 // This is the property that was introduced by the const declaration. |
1647 // Set it if it hasn't been set before. NOTE: We cannot use | 1647 // Set it if it hasn't been set before. NOTE: We cannot use |
1648 // GetProperty() to get the current value as it 'unholes' the value. | 1648 // GetProperty() to get the current value as it 'unholes' the value. |
1649 LookupResult lookup(isolate); | 1649 LookupResult lookup(isolate); |
1650 object->LocalLookupRealNamedProperty(*name, &lookup); | 1650 object->LocalLookupRealNamedProperty(*name, &lookup); |
1651 ASSERT(lookup.IsProperty()); // the property was declared | 1651 ASSERT(lookup.IsFound()); // the property was declared |
1652 ASSERT(lookup.IsReadOnly()); // and it was declared as read-only | 1652 ASSERT(lookup.IsReadOnly()); // and it was declared as read-only |
1653 | 1653 |
1654 PropertyType type = lookup.type(); | 1654 PropertyType type = lookup.type(); |
1655 if (type == FIELD) { | 1655 if (type == FIELD) { |
1656 FixedArray* properties = object->properties(); | 1656 FixedArray* properties = object->properties(); |
1657 int index = lookup.GetFieldIndex(); | 1657 int index = lookup.GetFieldIndex(); |
1658 if (properties->get(index)->IsTheHole()) { | 1658 if (properties->get(index)->IsTheHole()) { |
1659 properties->set(index, *value); | 1659 properties->set(index, *value); |
1660 } | 1660 } |
1661 } else if (type == NORMAL) { | 1661 } else if (type == NORMAL) { |
(...skipping 2587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4249 if (offset != -1) { | 4249 if (offset != -1) { |
4250 Object* value = receiver->FastPropertyAt(offset); | 4250 Object* value = receiver->FastPropertyAt(offset); |
4251 return value->IsTheHole() | 4251 return value->IsTheHole() |
4252 ? isolate->heap()->undefined_value() | 4252 ? isolate->heap()->undefined_value() |
4253 : value; | 4253 : value; |
4254 } | 4254 } |
4255 // Lookup cache miss. Perform lookup and update the cache if | 4255 // Lookup cache miss. Perform lookup and update the cache if |
4256 // appropriate. | 4256 // appropriate. |
4257 LookupResult result(isolate); | 4257 LookupResult result(isolate); |
4258 receiver->LocalLookup(key, &result); | 4258 receiver->LocalLookup(key, &result); |
4259 if (result.IsProperty() && result.type() == FIELD) { | 4259 if (result.IsFound() && result.type() == FIELD) { |
4260 int offset = result.GetFieldIndex(); | 4260 int offset = result.GetFieldIndex(); |
4261 keyed_lookup_cache->Update(receiver_map, key, offset); | 4261 keyed_lookup_cache->Update(receiver_map, key, offset); |
4262 return receiver->FastPropertyAt(offset); | 4262 return receiver->FastPropertyAt(offset); |
4263 } | 4263 } |
4264 } else { | 4264 } else { |
4265 // Attempt dictionary lookup. | 4265 // Attempt dictionary lookup. |
4266 StringDictionary* dictionary = receiver->property_dictionary(); | 4266 StringDictionary* dictionary = receiver->property_dictionary(); |
4267 int entry = dictionary->FindEntry(key); | 4267 int entry = dictionary->FindEntry(key); |
4268 if ((entry != StringDictionary::kNotFound) && | 4268 if ((entry != StringDictionary::kNotFound) && |
4269 (dictionary->DetailsAt(entry).type() == NORMAL)) { | 4269 (dictionary->DetailsAt(entry).type() == NORMAL)) { |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4397 js_object->set_elements(*extended_dictionary); | 4397 js_object->set_elements(*extended_dictionary); |
4398 } | 4398 } |
4399 } | 4399 } |
4400 return *obj_value; | 4400 return *obj_value; |
4401 } | 4401 } |
4402 | 4402 |
4403 LookupResult result(isolate); | 4403 LookupResult result(isolate); |
4404 js_object->LocalLookupRealNamedProperty(*name, &result); | 4404 js_object->LocalLookupRealNamedProperty(*name, &result); |
4405 | 4405 |
4406 // Special case for callback properties. | 4406 // Special case for callback properties. |
4407 if (result.IsProperty() && result.type() == CALLBACKS) { | 4407 if (result.IsFound() && result.type() == CALLBACKS) { |
4408 Object* callback = result.GetCallbackObject(); | 4408 Object* callback = result.GetCallbackObject(); |
4409 // To be compatible with Safari we do not change the value on API objects | 4409 // To be compatible with Safari we do not change the value on API objects |
4410 // in Object.defineProperty(). Firefox disagrees here, and actually changes | 4410 // in Object.defineProperty(). Firefox disagrees here, and actually changes |
4411 // the value. | 4411 // the value. |
4412 if (callback->IsAccessorInfo()) { | 4412 if (callback->IsAccessorInfo()) { |
4413 return isolate->heap()->undefined_value(); | 4413 return isolate->heap()->undefined_value(); |
4414 } | 4414 } |
4415 // Avoid redefining foreign callback as data property, just use the stored | 4415 // Avoid redefining foreign callback as data property, just use the stored |
4416 // setter to update the value instead. | 4416 // setter to update the value instead. |
4417 // TODO(mstarzinger): So far this only works if property attributes don't | 4417 // TODO(mstarzinger): So far this only works if property attributes don't |
(...skipping 9217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13635 } else { | 13635 } else { |
13636 // Handle last resort GC and make sure to allow future allocations | 13636 // Handle last resort GC and make sure to allow future allocations |
13637 // to grow the heap without causing GCs (if possible). | 13637 // to grow the heap without causing GCs (if possible). |
13638 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13638 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13639 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); | 13639 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); |
13640 } | 13640 } |
13641 } | 13641 } |
13642 | 13642 |
13643 | 13643 |
13644 } } // namespace v8::internal | 13644 } } // namespace v8::internal |
OLD | NEW |