Chromium Code Reviews| Index: src/objects.cc |
| diff --git a/src/objects.cc b/src/objects.cc |
| index 719ca3b201b0cc05f50efccb649ee8d955ede2d1..86f13f129ac3dd690dafed8d0dd5864d5f153493 100644 |
| --- a/src/objects.cc |
| +++ b/src/objects.cc |
| @@ -5838,11 +5838,12 @@ static bool UpdateGetterSetterInDictionary( |
| } |
| -MaybeObject* JSObject::DefineElementAccessor(uint32_t index, |
| - Object* getter, |
| - Object* setter, |
| - PropertyAttributes attributes) { |
| - switch (GetElementsKind()) { |
| +void JSObject::DefineElementAccessor(Handle<JSObject> object, |
| + uint32_t index, |
| + Handle<Object> getter, |
| + Handle<Object> setter, |
| + PropertyAttributes attributes) { |
| + switch (object->GetElementsKind()) { |
| case FAST_SMI_ELEMENTS: |
| case FAST_ELEMENTS: |
| case FAST_DOUBLE_ELEMENTS: |
| @@ -5860,21 +5861,21 @@ MaybeObject* JSObject::DefineElementAccessor(uint32_t index, |
| case EXTERNAL_FLOAT_ELEMENTS: |
| case EXTERNAL_DOUBLE_ELEMENTS: |
| // Ignore getters and setters on pixel and external array elements. |
| - return GetHeap()->undefined_value(); |
| + return; |
| case DICTIONARY_ELEMENTS: |
| - if (UpdateGetterSetterInDictionary(element_dictionary(), |
| + if (UpdateGetterSetterInDictionary(object->element_dictionary(), |
| index, |
| - getter, |
| - setter, |
| + *getter, |
| + *setter, |
| attributes)) { |
| - return GetHeap()->undefined_value(); |
| + return; |
| } |
| break; |
| case NON_STRICT_ARGUMENTS_ELEMENTS: { |
| // Ascertain whether we have read-only properties or an existing |
| // getter/setter pair in an arguments elements dictionary backing |
| // store. |
| - FixedArray* parameter_map = FixedArray::cast(elements()); |
| + FixedArray* parameter_map = FixedArray::cast(object->elements()); |
| uint32_t length = parameter_map->length(); |
| Object* probe = |
| index < (length - 2) ? parameter_map->get(index + 2) : NULL; |
| @@ -5885,10 +5886,10 @@ MaybeObject* JSObject::DefineElementAccessor(uint32_t index, |
| SeededNumberDictionary::cast(arguments); |
| if (UpdateGetterSetterInDictionary(dictionary, |
| index, |
| - getter, |
| - setter, |
| + *getter, |
| + *setter, |
| attributes)) { |
| - return GetHeap()->undefined_value(); |
| + return; |
| } |
| } |
| } |
| @@ -5896,19 +5897,20 @@ MaybeObject* JSObject::DefineElementAccessor(uint32_t index, |
| } |
| } |
| - AccessorPair* accessors; |
| - { MaybeObject* maybe_accessors = GetHeap()->AllocateAccessorPair(); |
| - if (!maybe_accessors->To(&accessors)) return maybe_accessors; |
| - } |
| - accessors->SetComponents(getter, setter); |
| + Isolate* isolate = object->GetIsolate(); |
| + Handle<AccessorPair> accessors = isolate->factory()->NewAccessorPair(); |
| + accessors->SetComponents(*getter, *setter); |
| - return SetElementCallback(index, accessors, attributes); |
| + CALL_HEAP_FUNCTION_VOID( |
| + isolate, object->SetElementCallback(index, *accessors, attributes)); |
| } |
| -MaybeObject* JSObject::CreateAccessorPairFor(Name* name) { |
| - LookupResult result(GetHeap()->isolate()); |
| - LocalLookupRealNamedProperty(name, &result); |
| +Handle<AccessorPair> JSObject::CreateAccessorPairFor(Handle<JSObject> object, |
| + Handle<Name> name) { |
| + Isolate* isolate = object->GetIsolate(); |
| + LookupResult result(isolate); |
| + object->LocalLookupRealNamedProperty(*name, &result); |
| if (result.IsPropertyCallbacks()) { |
| // Note that the result can actually have IsDontDelete() == true when we |
| // e.g. have to fall back to the slow case while adding a setter after |
| @@ -5918,47 +5920,44 @@ MaybeObject* JSObject::CreateAccessorPairFor(Name* name) { |
| // DefinePropertyAccessor below. |
| Object* obj = result.GetCallbackObject(); |
| if (obj->IsAccessorPair()) { |
| - return AccessorPair::cast(obj)->Copy(); |
| + return AccessorPair::Copy(Handle<AccessorPair>(AccessorPair::cast(obj))); |
|
rossberg
2013/07/02 12:20:47
Use handle() and pass isolate.
Michael Starzinger
2013/07/02 15:50:23
Done.
|
| } |
| } |
| - return GetHeap()->AllocateAccessorPair(); |
| + return isolate->factory()->NewAccessorPair(); |
| } |
| -MaybeObject* JSObject::DefinePropertyAccessor(Name* name, |
| - Object* getter, |
| - Object* setter, |
| - PropertyAttributes attributes) { |
| +void JSObject::DefinePropertyAccessor(Handle<JSObject> object, |
| + Handle<Name> name, |
| + Handle<Object> getter, |
| + Handle<Object> setter, |
| + PropertyAttributes attributes) { |
| // We could assert that the property is configurable here, but we would need |
| // to do a lookup, which seems to be a bit of overkill. |
| - Heap* heap = GetHeap(); |
| + Factory* factory = object->GetIsolate()->factory(); |
| bool only_attribute_changes = getter->IsNull() && setter->IsNull(); |
| - if (HasFastProperties() && !only_attribute_changes && |
| - (map()->NumberOfOwnDescriptors() < |
| + if (object->HasFastProperties() && !only_attribute_changes && |
| + (object->map()->NumberOfOwnDescriptors() < |
| DescriptorArray::kMaxNumberOfDescriptors)) { |
| - MaybeObject* getterOk = heap->undefined_value(); |
| - if (!getter->IsNull()) { |
| - getterOk = DefineFastAccessor(name, ACCESSOR_GETTER, getter, attributes); |
| - if (getterOk->IsFailure()) return getterOk; |
| - } |
| + Handle<Object> getterOk = getter->IsNull() |
| + ? Handle<Object>(factory->undefined_value()) |
|
rossberg
2013/07/02 12:20:47
Pass isolate. Though actually, isn't the construct
Michael Starzinger
2013/07/02 15:50:23
Done. As discussed offline: Returning an object he
|
| + : DefineFastAccessor(object, name, ACCESSOR_GETTER, getter, attributes); |
| - MaybeObject* setterOk = heap->undefined_value(); |
| - if (getterOk != heap->null_value() && !setter->IsNull()) { |
| - setterOk = DefineFastAccessor(name, ACCESSOR_SETTER, setter, attributes); |
| - if (setterOk->IsFailure()) return setterOk; |
| - } |
| + Handle<Object> setterOk = getterOk->IsNull() || setter->IsNull() |
| + ? Handle<Object>(factory->undefined_value()) |
|
rossberg
2013/07/02 12:20:47
Same here
Michael Starzinger
2013/07/02 15:50:23
Likewise.
|
| + : DefineFastAccessor(object, name, ACCESSOR_SETTER, setter, attributes); |
| - if (getterOk != heap->null_value() && setterOk != heap->null_value()) { |
| - return heap->undefined_value(); |
| + if (!getterOk->IsNull() && !setterOk->IsNull()) { |
| + return; |
| } |
| } |
| - AccessorPair* accessors; |
| - MaybeObject* maybe_accessors = CreateAccessorPairFor(name); |
| - if (!maybe_accessors->To(&accessors)) return maybe_accessors; |
| + Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name); |
| + accessors->SetComponents(*getter, *setter); |
| - accessors->SetComponents(getter, setter); |
| - return SetPropertyCallback(name, accessors, attributes); |
| + CALL_HEAP_FUNCTION_VOID( |
| + object->GetIsolate(), |
| + object->SetPropertyCallback(*name, *accessors, attributes)); |
| } |
| @@ -6060,29 +6059,21 @@ void JSObject::DefineAccessor(Handle<JSObject> object, |
| Handle<Object> getter, |
| Handle<Object> setter, |
| PropertyAttributes attributes) { |
| - CALL_HEAP_FUNCTION_VOID( |
| - object->GetIsolate(), |
| - object->DefineAccessor(*name, *getter, *setter, attributes)); |
| -} |
| - |
| -MaybeObject* JSObject::DefineAccessor(Name* name_raw, |
| - Object* getter_raw, |
| - Object* setter_raw, |
| - PropertyAttributes attributes) { |
| - Isolate* isolate = GetIsolate(); |
| + Isolate* isolate = object->GetIsolate(); |
| // Check access rights if needed. |
| - if (IsAccessCheckNeeded() && |
| - !isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { |
| - isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
| - return isolate->heap()->undefined_value(); |
| + if (object->IsAccessCheckNeeded() && |
| + !isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) { |
| + isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET); |
| + return; |
| } |
| - if (IsJSGlobalProxy()) { |
| - Object* proto = GetPrototype(); |
| - if (proto->IsNull()) return this; |
| + if (object->IsJSGlobalProxy()) { |
| + Handle<Object> proto(object->GetPrototype(), isolate); |
| + if (proto->IsNull()) return; |
| ASSERT(proto->IsJSGlobalObject()); |
| - return JSObject::cast(proto)->DefineAccessor( |
| - name_raw, getter_raw, setter_raw, attributes); |
| + DefineAccessor( |
| + Handle<JSObject>::cast(proto), name, getter, setter, attributes); |
| + return; |
| } |
| // Make sure that the top context does not change when doing callbacks or |
| @@ -6090,52 +6081,42 @@ MaybeObject* JSObject::DefineAccessor(Name* name_raw, |
| AssertNoContextChange ncc; |
| // Try to flatten before operating on the string. |
| - if (name_raw->IsString()) String::cast(name_raw)->TryFlatten(); |
| + if (name->IsString()) String::cast(*name)->TryFlatten(); |
| - if (!CanSetCallback(name_raw)) return isolate->heap()->undefined_value(); |
| - |
| - // From this point on everything needs to be handlified. |
|
rossberg
2013/07/02 12:20:47
Glad this goes away...
|
| - HandleScope scope(isolate); |
| - Handle<JSObject> self(this); |
| - Handle<Name> name(name_raw); |
| - Handle<Object> getter(getter_raw, isolate); |
| - Handle<Object> setter(setter_raw, isolate); |
| + if (!object->CanSetCallback(*name)) return; |
| uint32_t index = 0; |
| bool is_element = name->AsArrayIndex(&index); |
| Handle<Object> old_value = isolate->factory()->the_hole_value(); |
| - bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); |
| + bool is_observed = FLAG_harmony_observation && object->map()->is_observed(); |
| bool preexists = false; |
| if (is_observed) { |
| if (is_element) { |
| - preexists = HasLocalElement(index); |
| - if (preexists && self->GetLocalElementAccessorPair(index) == NULL) { |
| - old_value = Object::GetElement(self, index); |
| + preexists = object->HasLocalElement(index); |
| + if (preexists && object->GetLocalElementAccessorPair(index) == NULL) { |
| + old_value = Object::GetElement(object, index); |
| } |
| } else { |
| LookupResult lookup(isolate); |
| - LocalLookup(*name, &lookup, true); |
| + object->LocalLookup(*name, &lookup, true); |
| preexists = lookup.IsProperty(); |
| if (preexists && lookup.IsDataProperty()) { |
| - old_value = Object::GetProperty(self, name); |
| + old_value = Object::GetProperty(object, name); |
| } |
| } |
| } |
| - MaybeObject* result = is_element ? |
| - self->DefineElementAccessor(index, *getter, *setter, attributes) : |
| - self->DefinePropertyAccessor(*name, *getter, *setter, attributes); |
| - |
| - Handle<Object> hresult; |
| - if (!result->ToHandle(&hresult, isolate)) return result; |
| + if (is_element) { |
| + DefineElementAccessor(object, index, getter, setter, attributes); |
| + } else { |
| + DefinePropertyAccessor(object, name, getter, setter, attributes); |
| + } |
| if (is_observed) { |
| const char* type = preexists ? "reconfigured" : "new"; |
| - EnqueueChangeRecord(self, type, name, old_value); |
| + EnqueueChangeRecord(object, type, name, old_value); |
| } |
| - |
| - return *hresult; |
| } |
| @@ -6168,16 +6149,37 @@ static MaybeObject* TryAccessorTransition(JSObject* self, |
| } |
| -MaybeObject* JSObject::DefineFastAccessor(Name* name, |
| - AccessorComponent component, |
| - Object* accessor, |
| - PropertyAttributes attributes) { |
| +static MaybeObject* CopyInsertDescriptor(Map* map, |
| + Name* name, |
| + AccessorPair* accessors, |
| + PropertyAttributes attributes) { |
| + CallbacksDescriptor new_accessors_desc(name, accessors, attributes); |
| + return map->CopyInsertDescriptor(&new_accessors_desc, INSERT_TRANSITION); |
| +} |
| + |
| + |
| +static Handle<Map> CopyInsertDescriptor(Handle<Map> map, |
| + Handle<Name> name, |
| + Handle<AccessorPair> accessors, |
| + PropertyAttributes attributes) { |
| + CALL_HEAP_FUNCTION(map->GetIsolate(), |
| + CopyInsertDescriptor(*map, *name, *accessors, attributes), |
| + Map); |
| +} |
| + |
| + |
| +Handle<Object> JSObject::DefineFastAccessor(Handle<JSObject> object, |
| + Handle<Name> name, |
| + AccessorComponent component, |
| + Handle<Object> accessor, |
| + PropertyAttributes attributes) { |
| ASSERT(accessor->IsSpecFunction() || accessor->IsUndefined()); |
| - LookupResult result(GetIsolate()); |
| - LocalLookup(name, &result); |
| + Isolate* isolate = object->GetIsolate(); |
| + LookupResult result(isolate); |
| + object->LocalLookup(*name, &result); |
| if (result.IsFound() && !result.IsPropertyCallbacks()) { |
| - return GetHeap()->null_value(); |
| + return isolate->factory()->null_value(); |
| } |
| // Return success if the same accessor with the same attributes already exist. |
| @@ -6187,65 +6189,59 @@ MaybeObject* JSObject::DefineFastAccessor(Name* name, |
| if (callback_value->IsAccessorPair()) { |
| source_accessors = AccessorPair::cast(callback_value); |
| Object* entry = source_accessors->get(component); |
| - if (entry == accessor && result.GetAttributes() == attributes) { |
| - return this; |
| + if (entry == *accessor && result.GetAttributes() == attributes) { |
| + return object; |
| } |
| } else { |
| - return GetHeap()->null_value(); |
| + return isolate->factory()->null_value(); |
| } |
| int descriptor_number = result.GetDescriptorIndex(); |
| - map()->LookupTransition(this, name, &result); |
| + object->map()->LookupTransition(*object, *name, &result); |
| if (result.IsFound()) { |
| Map* target = result.GetTransitionTarget(); |
| ASSERT(target->NumberOfOwnDescriptors() == |
| - map()->NumberOfOwnDescriptors()); |
| + object->map()->NumberOfOwnDescriptors()); |
| // This works since descriptors are sorted in order of addition. |
| - ASSERT(map()->instance_descriptors()->GetKey(descriptor_number) == name); |
| - return TryAccessorTransition( |
| - this, target, descriptor_number, component, accessor, attributes); |
| + ASSERT(object->map()->instance_descriptors()-> |
| + GetKey(descriptor_number) == *name); |
| + CALL_HEAP_FUNCTION( |
| + isolate, |
| + TryAccessorTransition(*object, target, descriptor_number, |
| + component, *accessor, attributes), |
| + Object); |
| } |
| } else { |
| // If not, lookup a transition. |
| - map()->LookupTransition(this, name, &result); |
| + object->map()->LookupTransition(*object, *name, &result); |
| // If there is a transition, try to follow it. |
| if (result.IsFound()) { |
| Map* target = result.GetTransitionTarget(); |
| int descriptor_number = target->LastAdded(); |
| ASSERT(target->instance_descriptors()->GetKey(descriptor_number) |
| - ->Equals(name)); |
| - return TryAccessorTransition( |
| - this, target, descriptor_number, component, accessor, attributes); |
| + ->Equals(*name)); |
| + CALL_HEAP_FUNCTION( |
| + isolate, |
| + TryAccessorTransition(*object, target, descriptor_number, |
| + component, *accessor, attributes), |
| + Object); |
| } |
| } |
| // If there is no transition yet, add a transition to the a new accessor pair |
| - // containing the accessor. |
| - AccessorPair* accessors; |
| - MaybeObject* maybe_accessors; |
| - |
| - // Allocate a new pair if there were no source accessors. Otherwise, copy the |
| - // pair and modify the accessor. |
| - if (source_accessors != NULL) { |
| - maybe_accessors = source_accessors->Copy(); |
| - } else { |
| - maybe_accessors = GetHeap()->AllocateAccessorPair(); |
| - } |
| - if (!maybe_accessors->To(&accessors)) return maybe_accessors; |
| - accessors->set(component, accessor); |
| - |
| - CallbacksDescriptor new_accessors_desc(name, accessors, attributes); |
| - |
| - Map* new_map; |
| - MaybeObject* maybe_new_map = |
| - map()->CopyInsertDescriptor(&new_accessors_desc, INSERT_TRANSITION); |
| - if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
| - |
| - set_map(new_map); |
| - return this; |
| + // containing the accessor. Allocate a new pair if there were no source |
| + // accessors. Otherwise, copy the pair and modify the accessor. |
| + Handle<AccessorPair> accessors = source_accessors != NULL |
| + ? AccessorPair::Copy(Handle<AccessorPair>(source_accessors)) |
|
rossberg
2013/07/02 12:20:47
Pass isolate
Michael Starzinger
2013/07/02 15:50:23
As discussed offline: Not needed here.
|
| + : isolate->factory()->NewAccessorPair(); |
| + accessors->set(component, *accessor); |
| + Handle<Map> new_map = CopyInsertDescriptor(Handle<Map>(object->map()), |
| + name, accessors, attributes); |
| + object->set_map(*new_map); |
| + return object; |
| } |
| @@ -7825,14 +7821,10 @@ void DescriptorArray::Sort() { |
| } |
| -MaybeObject* AccessorPair::Copy() { |
| - Heap* heap = GetHeap(); |
| - AccessorPair* copy; |
| - MaybeObject* maybe_copy = heap->AllocateAccessorPair(); |
| - if (!maybe_copy->To(©)) return maybe_copy; |
| - |
| - copy->set_getter(getter()); |
| - copy->set_setter(setter()); |
| +Handle<AccessorPair> AccessorPair::Copy(Handle<AccessorPair> pair) { |
| + Handle<AccessorPair> copy = pair->GetIsolate()->factory()->NewAccessorPair(); |
| + copy->set_getter(pair->getter()); |
| + copy->set_setter(pair->setter()); |
| return copy; |
| } |