Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 4ca3d57de2c4b560384e2f8649e481ffd6953202..f329c274dc643592bf8621ce4c2a3e2be03d6648 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -1900,20 +1900,6 @@ MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map, |
} |
-void JSObject::AddFastProperty(Handle<JSObject> object, |
- Handle<Name> name, |
- Handle<Object> value, |
- PropertyAttributes attributes, |
- StoreFromKeyed store_mode, |
- ValueType value_type, |
- TransitionFlag flag) { |
- CALL_HEAP_FUNCTION_VOID( |
- object->GetIsolate(), |
- object->AddFastProperty( |
- *name, *value, attributes, store_mode, value_type, flag)); |
-} |
- |
- |
MaybeObject* JSObject::AddFastProperty(Name* name, |
Object* value, |
PropertyAttributes attributes, |
@@ -1959,17 +1945,6 @@ MaybeObject* JSObject::AddFastProperty(Name* name, |
} |
-void JSObject::AddConstantProperty(Handle<JSObject> object, |
- Handle<Name> name, |
- Handle<Object> constant, |
- PropertyAttributes attributes, |
- TransitionFlag flag) { |
- CALL_HEAP_FUNCTION_VOID( |
- object->GetIsolate(), |
- object->AddConstantProperty(*name, *constant, attributes, flag)); |
-} |
- |
- |
MaybeObject* JSObject::AddConstantProperty( |
Name* name, |
Object* constant, |
@@ -1996,15 +1971,7 @@ MaybeObject* JSObject::AddConstantProperty( |
} |
-void JSObject::AddSlowProperty(Handle<JSObject> object, |
- Handle<Name> name, |
- Handle<Object> value, |
- PropertyAttributes attributes) { |
- CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), |
- object->AddSlowProperty(*name, *value, attributes)); |
-} |
- |
- |
+// Add property in slow mode |
MaybeObject* JSObject::AddSlowProperty(Name* name, |
Object* value, |
PropertyAttributes attributes) { |
@@ -2046,61 +2013,69 @@ MaybeObject* JSObject::AddSlowProperty(Name* name, |
} |
-Handle<Object> JSObject::AddProperty(Handle<JSObject> object, |
- Handle<Name> name, |
- Handle<Object> value, |
- PropertyAttributes attributes, |
- StrictModeFlag strict_mode, |
- JSReceiver::StoreFromKeyed store_mode, |
- ExtensibilityCheck extensibility_check, |
- ValueType value_type, |
- StoreMode mode, |
- TransitionFlag transition_flag) { |
- ASSERT(!object->IsJSGlobalProxy()); |
- Isolate* isolate = object->GetIsolate(); |
+MaybeObject* JSObject::AddProperty(Name* name, |
+ Object* value, |
+ PropertyAttributes attributes, |
+ StrictModeFlag strict_mode, |
+ JSReceiver::StoreFromKeyed store_mode, |
+ ExtensibilityCheck extensibility_check, |
+ ValueType value_type, |
+ StoreMode mode, |
+ TransitionFlag transition_flag) { |
+ ASSERT(!IsJSGlobalProxy()); |
+ Map* map_of_this = map(); |
+ Heap* heap = GetHeap(); |
+ Isolate* isolate = heap->isolate(); |
+ MaybeObject* result; |
if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && |
- !object->map()->is_extensible()) { |
+ !map_of_this->is_extensible()) { |
if (strict_mode == kNonStrictMode) { |
return value; |
} else { |
- Handle<Object> args[1] = { name }; |
- Handle<Object> error = isolate->factory()->NewTypeError( |
- "object_not_extensible", HandleVector(args, ARRAY_SIZE(args))); |
- isolate->Throw(*error); |
- return Handle<Object>(); |
+ Handle<Object> args[1] = {Handle<Name>(name)}; |
+ return isolate->Throw( |
+ *isolate->factory()->NewTypeError("object_not_extensible", |
+ HandleVector(args, 1))); |
} |
} |
- if (object->HasFastProperties()) { |
+ if (HasFastProperties()) { |
// Ensure the descriptor array does not get too big. |
- if (object->map()->NumberOfOwnDescriptors() < |
+ if (map_of_this->NumberOfOwnDescriptors() < |
DescriptorArray::kMaxNumberOfDescriptors) { |
// TODO(verwaest): Support other constants. |
// if (mode == ALLOW_AS_CONSTANT && |
// !value->IsTheHole() && |
// !value->IsConsString()) { |
if (value->IsJSFunction()) { |
- AddConstantProperty(object, name, value, attributes, transition_flag); |
+ result = AddConstantProperty(name, value, attributes, transition_flag); |
} else { |
- AddFastProperty(object, name, value, attributes, store_mode, |
- value_type, transition_flag); |
+ result = AddFastProperty( |
+ name, value, attributes, store_mode, value_type, transition_flag); |
} |
} else { |
// Normalize the object to prevent very large instance descriptors. |
// This eliminates unwanted N^2 allocation and lookup behavior. |
- NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
- AddSlowProperty(object, name, value, attributes); |
+ Object* obj; |
+ MaybeObject* maybe = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
+ if (!maybe->To(&obj)) return maybe; |
+ result = AddSlowProperty(name, value, attributes); |
} |
} else { |
- AddSlowProperty(object, name, value, attributes); |
+ result = AddSlowProperty(name, value, attributes); |
} |
- if (FLAG_harmony_observation && object->map()->is_observed()) { |
- Handle<Object> old_value = isolate->factory()->the_hole_value(); |
- EnqueueChangeRecord(object, "new", name, old_value); |
+ Handle<Object> hresult; |
+ if (!result->ToHandle(&hresult, isolate)) return result; |
+ |
+ if (FLAG_harmony_observation && map()->is_observed()) { |
+ EnqueueChangeRecord(handle(this, isolate), |
+ "new", |
+ handle(name, isolate), |
+ handle(heap->the_hole_value(), isolate)); |
} |
- return value; |
+ return *hresult; |
} |
@@ -2140,32 +2115,29 @@ void JSObject::DeliverChangeRecords(Isolate* isolate) { |
} |
-Handle<Object> JSObject::SetPropertyPostInterceptor( |
- Handle<JSObject> object, |
- Handle<Name> name, |
- Handle<Object> value, |
+MaybeObject* JSObject::SetPropertyPostInterceptor( |
+ Name* name, |
+ Object* value, |
PropertyAttributes attributes, |
- StrictModeFlag strict_mode) { |
+ StrictModeFlag strict_mode, |
+ StoreMode mode) { |
// Check local property, ignore interceptor. |
- LookupResult result(object->GetIsolate()); |
- object->LocalLookupRealNamedProperty(*name, &result); |
- if (!result.IsFound()) { |
- object->map()->LookupTransition(*object, *name, &result); |
- } |
+ LookupResult result(GetIsolate()); |
+ LocalLookupRealNamedProperty(name, &result); |
+ if (!result.IsFound()) map()->LookupTransition(this, name, &result); |
if (result.IsFound()) { |
// An existing property or a map transition was found. Use set property to |
// handle all these cases. |
- CALL_HEAP_FUNCTION(object->GetIsolate(), |
- object->SetProperty( |
- &result, *name, *value, attributes, strict_mode), |
- Object); |
+ return SetProperty(&result, name, value, attributes, strict_mode); |
} |
bool done = false; |
- Handle<Object> result_object = SetPropertyViaPrototypes( |
- object, name, value, attributes, strict_mode, &done); |
+ MaybeObject* result_object = |
+ SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done); |
if (done) return result_object; |
// Add a new real property. |
- return AddProperty(object, name, value, attributes, strict_mode); |
+ return AddProperty(name, value, attributes, strict_mode, |
+ MAY_BE_STORE_FROM_KEYED, PERFORM_EXTENSIBILITY_CHECK, |
+ OPTIMAL_REPRESENTATION, mode); |
} |
@@ -2731,36 +2703,41 @@ Map* Map::CurrentMapForDeprecated() { |
} |
-Handle<Object> JSObject::SetPropertyWithInterceptor( |
- Handle<JSObject> object, |
- Handle<Name> name, |
- Handle<Object> value, |
+MaybeObject* JSObject::SetPropertyWithInterceptor( |
+ Name* name, |
+ Object* value, |
PropertyAttributes attributes, |
StrictModeFlag strict_mode) { |
// TODO(rossberg): Support symbols in the API. |
if (name->IsSymbol()) return value; |
- Isolate* isolate = object->GetIsolate(); |
- Handle<String> name_string = Handle<String>::cast(name); |
- Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor()); |
+ Isolate* isolate = GetIsolate(); |
+ HandleScope scope(isolate); |
+ Handle<JSObject> this_handle(this); |
+ Handle<String> name_handle(String::cast(name)); |
+ Handle<Object> value_handle(value, isolate); |
+ Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); |
if (!interceptor->setter()->IsUndefined()) { |
- LOG(isolate, |
- ApiNamedPropertyAccess("interceptor-named-set", *object, *name)); |
- PropertyCallbackArguments args( |
- isolate, interceptor->data(), *object, *object); |
+ LOG(isolate, ApiNamedPropertyAccess("interceptor-named-set", this, name)); |
+ PropertyCallbackArguments args(isolate, interceptor->data(), this, this); |
v8::NamedPropertySetterCallback setter = |
v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter()); |
- Handle<Object> value_unhole = value->IsTheHole() |
- ? Handle<Object>(isolate->factory()->undefined_value()) : value; |
+ Handle<Object> value_unhole(value->IsTheHole() ? |
+ isolate->heap()->undefined_value() : |
+ value, |
+ isolate); |
v8::Handle<v8::Value> result = args.Call(setter, |
- v8::Utils::ToLocal(name_string), |
+ v8::Utils::ToLocal(name_handle), |
v8::Utils::ToLocal(value_unhole)); |
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); |
- if (!result.IsEmpty()) return value; |
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
+ if (!result.IsEmpty()) return *value_handle; |
} |
- Handle<Object> result = |
- SetPropertyPostInterceptor(object, name, value, attributes, strict_mode); |
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); |
- return result; |
+ MaybeObject* raw_result = |
+ this_handle->SetPropertyPostInterceptor(*name_handle, |
+ *value_handle, |
+ attributes, |
+ strict_mode); |
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
+ return raw_result; |
} |
@@ -2953,20 +2930,21 @@ MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( |
return heap->the_hole_value(); |
} |
-Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object, |
- Handle<Name> name, |
- Handle<Object> value, |
- PropertyAttributes attributes, |
- StrictModeFlag strict_mode, |
- bool* done) { |
- Isolate* isolate = object->GetIsolate(); |
+MaybeObject* JSObject::SetPropertyViaPrototypes( |
+ Name* name, |
+ Object* value, |
+ PropertyAttributes attributes, |
+ StrictModeFlag strict_mode, |
+ bool* done) { |
+ Heap* heap = GetHeap(); |
+ Isolate* isolate = heap->isolate(); |
*done = false; |
// We could not find a local property so let's check whether there is an |
// accessor that wants to handle the property, or whether the property is |
// read-only on the prototype chain. |
LookupResult result(isolate); |
- object->LookupRealNamedPropertyInPrototypes(*name, &result); |
+ LookupRealNamedPropertyInPrototypes(name, &result); |
if (result.IsFound()) { |
switch (result.type()) { |
case NORMAL: |
@@ -2977,25 +2955,19 @@ Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object, |
case INTERCEPTOR: { |
PropertyAttributes attr = |
result.holder()->GetPropertyAttributeWithInterceptor( |
- *object, *name, true); |
+ this, name, true); |
*done = !!(attr & READ_ONLY); |
break; |
} |
case CALLBACKS: { |
if (!FLAG_es5_readonly && result.IsReadOnly()) break; |
*done = true; |
- CALL_HEAP_FUNCTION(isolate, |
- object->SetPropertyWithCallback( |
- result.GetCallbackObject(), |
- *name, *value, result.holder(), strict_mode), |
- Object); |
+ return SetPropertyWithCallback(result.GetCallbackObject(), |
+ name, value, result.holder(), strict_mode); |
} |
case HANDLER: { |
- CALL_HEAP_FUNCTION(isolate, |
- result.proxy()->SetPropertyViaPrototypesWithHandler( |
- *object, *name, *value, attributes, strict_mode, |
- done), |
- Object); |
+ return result.proxy()->SetPropertyViaPrototypesWithHandler( |
+ this, name, value, attributes, strict_mode, done); |
} |
case TRANSITION: |
case NONEXISTENT: |
@@ -3008,13 +2980,12 @@ Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object, |
if (!FLAG_es5_readonly) *done = false; |
if (*done) { |
if (strict_mode == kNonStrictMode) return value; |
- Handle<Object> args[] = { name, object }; |
- Handle<Object> error = isolate->factory()->NewTypeError( |
- "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); |
- isolate->Throw(*error); |
- return Handle<Object>(); |
+ Handle<Object> args[] = { Handle<Object>(name, isolate), |
+ Handle<Object>(this, isolate)}; |
+ return isolate->Throw(*isolate->factory()->NewTypeError( |
+ "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)))); |
} |
- return isolate->factory()->the_hole_value(); |
+ return heap->the_hole_value(); |
} |
@@ -3802,14 +3773,11 @@ static MaybeObject* SetPropertyUsingTransition(LookupResult* lookup, |
// AddProperty will either normalize the object, or create a new fast copy |
// of the map. If we get a fast copy of the map, all field representations |
// will be tagged since the transition is omitted. |
- Handle<JSObject> holder(lookup->holder()); |
- Handle<Object> result = JSObject::AddProperty( |
- holder, name, value, attributes, kNonStrictMode, |
+ return lookup->holder()->AddProperty( |
+ *name, *value, attributes, kNonStrictMode, |
JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, |
JSReceiver::OMIT_EXTENSIBILITY_CHECK, |
JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION); |
- RETURN_IF_EMPTY_HANDLE(holder->GetIsolate(), result); |
- return *result; |
} |
// Keep the target CONSTANT if the same value is stored. |
@@ -3979,18 +3947,15 @@ MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup, |
if (!lookup->IsProperty() && !self->IsJSContextExtensionObject()) { |
bool done = false; |
- Handle<Object> result_object = SetPropertyViaPrototypes( |
- self, name, value, attributes, strict_mode, &done); |
- RETURN_IF_EMPTY_HANDLE(isolate, result_object); |
- if (done) return *result_object; |
+ MaybeObject* result_object = self->SetPropertyViaPrototypes( |
+ *name, *value, attributes, strict_mode, &done); |
+ if (done) return result_object; |
} |
if (!lookup->IsFound()) { |
// Neither properties nor transitions found. |
- Handle<Object> result_object = AddProperty( |
- self, name, value, attributes, strict_mode, store_mode); |
- RETURN_IF_EMPTY_HANDLE(isolate, result_object); |
- return *result_object; |
+ return self->AddProperty( |
+ *name, *value, attributes, strict_mode, store_mode); |
} |
if (lookup->IsProperty() && lookup->IsReadOnly()) { |
@@ -4029,14 +3994,10 @@ MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup, |
return self->SetPropertyWithCallback( |
callback_object, *name, *value, lookup->holder(), strict_mode); |
} |
- case INTERCEPTOR: { |
- Handle<JSObject> holder(lookup->holder()); |
- Handle<Object> hresult = SetPropertyWithInterceptor( |
- holder, name, value, attributes, strict_mode); |
- RETURN_IF_EMPTY_HANDLE(isolate, hresult); |
- result = *hresult; |
+ case INTERCEPTOR: |
+ result = lookup->holder()->SetPropertyWithInterceptor( |
+ *name, *value, attributes, strict_mode); |
break; |
- } |
case TRANSITION: { |
result = SetPropertyUsingTransition(lookup, name, value, attributes); |
break; |
@@ -4159,23 +4120,21 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( |
LocalLookupRealNamedProperty(name_raw, &lookup); |
} |
- // From this point on everything needs to be handlified. |
- HandleScope scope(isolate); |
- Handle<JSObject> self(this); |
- Handle<Name> name(name_raw); |
- Handle<Object> value(value_raw, isolate); |
- |
// Check for accessor in prototype chain removed here in clone. |
if (!lookup.IsFound()) { |
// Neither properties nor transitions found. |
- Handle<Object> result = AddProperty( |
- self, name, value, attributes, kNonStrictMode, |
+ return AddProperty( |
+ name_raw, value_raw, attributes, kNonStrictMode, |
MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode); |
- RETURN_IF_EMPTY_HANDLE(isolate, result); |
- return *result; |
} |
- Handle<Object> old_value = isolate->factory()->the_hole_value(); |
+ // From this point on everything needs to be handlified. |
+ HandleScope scope(isolate); |
+ Handle<JSObject> self(this); |
+ Handle<Name> name(name_raw); |
+ Handle<Object> value(value_raw, isolate); |
+ |
+ Handle<Object> old_value(isolate->heap()->the_hole_value(), isolate); |
PropertyAttributes old_attributes = ABSENT; |
bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); |
if (is_observed && lookup.IsProperty()) { |