Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index bb78a8e72426e73df043a1a1f90fd8d0bffc08f6..efd18e2ddeafbe49f02ee3f5b04e8cfc06a505cd 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -455,10 +455,8 @@ Handle<Object> JSProxy::SetElementWithHandler(Handle<JSProxy> proxy, |
StrictModeFlag strict_mode) { |
Isolate* isolate = proxy->GetIsolate(); |
Handle<String> name = isolate->factory()->Uint32ToString(index); |
- CALL_HEAP_FUNCTION(isolate, |
- proxy->SetPropertyWithHandler( |
- *receiver, *name, *value, NONE, strict_mode), |
- Object); |
+ return SetPropertyWithHandler( |
+ proxy, receiver, name, value, NONE, strict_mode); |
} |
@@ -1871,6 +1869,20 @@ String* JSReceiver::constructor_name() { |
} |
+Handle<Object> JSObject::AddFastPropertyUsingMap( |
+ Handle<JSObject> object, |
+ Handle<Map> new_map, |
+ Handle<Name> name, |
+ Handle<Object> value, |
+ int field_index, |
+ Representation representation) { |
+ CALL_HEAP_FUNCTION(object->GetIsolate(), |
+ object->AddFastPropertyUsingMap( |
+ *new_map, *name, *value, field_index, representation), |
+ Object); |
+} |
+ |
+ |
MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map, |
Name* name, |
Object* value, |
@@ -1900,182 +1912,215 @@ MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map, |
} |
-MaybeObject* JSObject::AddFastProperty(Name* name, |
- Object* value, |
- PropertyAttributes attributes, |
- StoreFromKeyed store_mode, |
- ValueType value_type, |
- TransitionFlag flag) { |
- ASSERT(!IsJSGlobalProxy()); |
+static MaybeObject* CopyAddFieldDescriptor(Map* map, |
+ Name* name, |
+ int index, |
+ PropertyAttributes attributes, |
+ Representation representation, |
+ TransitionFlag flag) { |
+ Map* new_map; |
+ FieldDescriptor new_field_desc(name, index, attributes, representation); |
+ MaybeObject* maybe_map = map->CopyAddDescriptor(&new_field_desc, flag); |
+ if (!maybe_map->To(&new_map)) return maybe_map; |
+ int unused_property_fields = map->unused_property_fields() - 1; |
+ if (unused_property_fields < 0) { |
+ unused_property_fields += JSObject::kFieldsAdded; |
+ } |
+ new_map->set_unused_property_fields(unused_property_fields); |
+ return new_map; |
+} |
+ |
+ |
+static Handle<Map> CopyAddFieldDescriptor(Handle<Map> map, |
+ Handle<Name> name, |
+ int index, |
+ PropertyAttributes attributes, |
+ Representation representation, |
+ TransitionFlag flag) { |
+ CALL_HEAP_FUNCTION(map->GetIsolate(), |
+ CopyAddFieldDescriptor( |
+ *map, *name, index, attributes, representation, flag), |
+ Map); |
+} |
+ |
+ |
+void JSObject::AddFastProperty(Handle<JSObject> object, |
+ Handle<Name> name, |
+ Handle<Object> value, |
+ PropertyAttributes attributes, |
+ StoreFromKeyed store_mode, |
+ ValueType value_type, |
+ TransitionFlag flag) { |
+ ASSERT(!object->IsJSGlobalProxy()); |
ASSERT(DescriptorArray::kNotFound == |
- map()->instance_descriptors()->Search( |
- name, map()->NumberOfOwnDescriptors())); |
+ object->map()->instance_descriptors()->Search( |
+ *name, object->map()->NumberOfOwnDescriptors())); |
// Normalize the object if the name is an actual name (not the |
// hidden strings) and is not a real identifier. |
// Normalize the object if it will have too many fast properties. |
- Isolate* isolate = GetHeap()->isolate(); |
- if (!name->IsCacheable(isolate) || TooManyFastProperties(store_mode)) { |
- MaybeObject* maybe_failure = |
- NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
- if (maybe_failure->IsFailure()) return maybe_failure; |
- return AddSlowProperty(name, value, attributes); |
+ Isolate* isolate = object->GetIsolate(); |
+ if (!name->IsCacheable(isolate) || |
+ object->TooManyFastProperties(store_mode)) { |
+ NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
+ AddSlowProperty(object, name, value, attributes); |
+ return; |
} |
// Compute the new index for new field. |
- int index = map()->NextFreePropertyIndex(); |
+ int index = object->map()->NextFreePropertyIndex(); |
// Allocate new instance descriptors with (name, index) added |
- if (IsJSContextExtensionObject()) value_type = FORCE_TAGGED; |
+ if (object->IsJSContextExtensionObject()) value_type = FORCE_TAGGED; |
Representation representation = value->OptimalRepresentation(value_type); |
+ Handle<Map> new_map = CopyAddFieldDescriptor( |
+ handle(object->map()), name, index, attributes, representation, flag); |
- FieldDescriptor new_field(name, index, attributes, representation); |
+ AddFastPropertyUsingMap(object, new_map, name, value, index, representation); |
+} |
- Map* new_map; |
- MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&new_field, flag); |
- if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
- int unused_property_fields = map()->unused_property_fields() - 1; |
- if (unused_property_fields < 0) { |
- unused_property_fields += kFieldsAdded; |
- } |
- new_map->set_unused_property_fields(unused_property_fields); |
- |
- return AddFastPropertyUsingMap(new_map, name, value, index, representation); |
+static MaybeObject* CopyAddConstantDescriptor(Map* map, |
+ Name* name, |
+ Object* value, |
+ PropertyAttributes attributes, |
+ TransitionFlag flag) { |
+ ConstantDescriptor new_constant_desc(name, value, attributes); |
+ return map->CopyAddDescriptor(&new_constant_desc, flag); |
} |
-MaybeObject* JSObject::AddConstantProperty( |
- Name* name, |
- Object* constant, |
- PropertyAttributes attributes, |
- TransitionFlag initial_flag) { |
- // Allocate new instance descriptors with (name, constant) added |
- ConstantDescriptor d(name, constant, attributes); |
+static Handle<Map> CopyAddConstantDescriptor(Handle<Map> map, |
+ Handle<Name> name, |
+ Handle<Object> value, |
+ PropertyAttributes attributes, |
+ TransitionFlag flag) { |
+ CALL_HEAP_FUNCTION(map->GetIsolate(), |
+ CopyAddConstantDescriptor( |
+ *map, *name, *value, attributes, flag), |
+ Map); |
+} |
+ |
+void JSObject::AddConstantProperty(Handle<JSObject> object, |
+ Handle<Name> name, |
+ Handle<Object> constant, |
+ PropertyAttributes attributes, |
+ TransitionFlag initial_flag) { |
TransitionFlag flag = |
// Do not add transitions to global objects. |
- (IsGlobalObject() || |
+ (object->IsGlobalObject() || |
// Don't add transitions to special properties with non-trivial |
// attributes. |
attributes != NONE) |
? OMIT_TRANSITION |
: initial_flag; |
- Map* new_map; |
- MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&d, flag); |
- if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
+ // Allocate new instance descriptors with (name, constant) added. |
+ Handle<Map> new_map = CopyAddConstantDescriptor( |
+ handle(object->map()), name, constant, attributes, flag); |
- set_map(new_map); |
- return constant; |
+ object->set_map(*new_map); |
} |
-// Add property in slow mode |
-MaybeObject* JSObject::AddSlowProperty(Name* name, |
- Object* value, |
- PropertyAttributes attributes) { |
- ASSERT(!HasFastProperties()); |
- NameDictionary* dict = property_dictionary(); |
- Object* store_value = value; |
- if (IsGlobalObject()) { |
+// TODO(mstarzinger): Temporary wrapper until handlified. |
+static Handle<NameDictionary> NameDictionaryAdd(Handle<NameDictionary> dict, |
+ Handle<Name> name, |
+ Handle<Object> value, |
+ PropertyDetails details) { |
+ CALL_HEAP_FUNCTION(dict->GetIsolate(), |
+ dict->Add(*name, *value, details), |
+ NameDictionary); |
+} |
+ |
+ |
+void JSObject::AddSlowProperty(Handle<JSObject> object, |
+ Handle<Name> name, |
+ Handle<Object> value, |
+ PropertyAttributes attributes) { |
+ ASSERT(!object->HasFastProperties()); |
+ Isolate* isolate = object->GetIsolate(); |
+ Handle<NameDictionary> dict(object->property_dictionary()); |
+ if (object->IsGlobalObject()) { |
// In case name is an orphaned property reuse the cell. |
- int entry = dict->FindEntry(name); |
+ int entry = dict->FindEntry(*name); |
if (entry != NameDictionary::kNotFound) { |
- store_value = dict->ValueAt(entry); |
- MaybeObject* maybe_type = |
- PropertyCell::cast(store_value)->SetValueInferType(value); |
- if (maybe_type->IsFailure()) return maybe_type; |
+ Handle<PropertyCell> cell(PropertyCell::cast(dict->ValueAt(entry))); |
+ PropertyCell::SetValueInferType(cell, value); |
// Assign an enumeration index to the property and update |
// SetNextEnumerationIndex. |
int index = dict->NextEnumerationIndex(); |
PropertyDetails details = PropertyDetails(attributes, NORMAL, index); |
dict->SetNextEnumerationIndex(index + 1); |
- dict->SetEntry(entry, name, store_value, details); |
- return value; |
- } |
- Heap* heap = GetHeap(); |
- { MaybeObject* maybe_store_value = |
- heap->AllocatePropertyCell(value); |
- if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value; |
+ dict->SetEntry(entry, *name, *cell, details); |
+ return; |
} |
- MaybeObject* maybe_type = |
- PropertyCell::cast(store_value)->SetValueInferType(value); |
- if (maybe_type->IsFailure()) return maybe_type; |
+ Handle<PropertyCell> cell = isolate->factory()->NewPropertyCell(value); |
+ PropertyCell::SetValueInferType(cell, value); |
+ value = cell; |
} |
PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); |
- Object* result; |
- { MaybeObject* maybe_result = dict->Add(name, store_value, details); |
- if (!maybe_result->ToObject(&result)) return maybe_result; |
- } |
- if (dict != result) set_properties(NameDictionary::cast(result)); |
- return value; |
+ Handle<NameDictionary> result = NameDictionaryAdd(dict, name, value, details); |
+ if (*dict != *result) object->set_properties(*result); |
} |
-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; |
+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(); |
if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && |
- !map_of_this->is_extensible()) { |
+ !object->map()->is_extensible()) { |
if (strict_mode == kNonStrictMode) { |
return value; |
} else { |
- Handle<Object> args[1] = {Handle<Name>(name)}; |
- return isolate->Throw( |
- *isolate->factory()->NewTypeError("object_not_extensible", |
- HandleVector(args, 1))); |
+ 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>(); |
} |
} |
- if (HasFastProperties()) { |
+ if (object->HasFastProperties()) { |
// Ensure the descriptor array does not get too big. |
- if (map_of_this->NumberOfOwnDescriptors() < |
+ if (object->map()->NumberOfOwnDescriptors() < |
DescriptorArray::kMaxNumberOfDescriptors) { |
// TODO(verwaest): Support other constants. |
// if (mode == ALLOW_AS_CONSTANT && |
// !value->IsTheHole() && |
// !value->IsConsString()) { |
if (value->IsJSFunction()) { |
- result = AddConstantProperty(name, value, attributes, transition_flag); |
+ AddConstantProperty(object, name, value, attributes, transition_flag); |
} else { |
- result = AddFastProperty( |
- name, value, attributes, store_mode, value_type, transition_flag); |
+ AddFastProperty(object, 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. |
- Object* obj; |
- MaybeObject* maybe = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
- if (!maybe->To(&obj)) return maybe; |
- result = AddSlowProperty(name, value, attributes); |
+ NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
+ AddSlowProperty(object, name, value, attributes); |
} |
} else { |
- result = AddSlowProperty(name, value, attributes); |
+ AddSlowProperty(object, name, value, attributes); |
} |
- 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)); |
+ if (FLAG_harmony_observation && object->map()->is_observed()) { |
+ Handle<Object> old_value = isolate->factory()->the_hole_value(); |
+ EnqueueChangeRecord(object, "new", name, old_value); |
} |
- return *hresult; |
+ return value; |
} |
@@ -2115,37 +2160,39 @@ void JSObject::DeliverChangeRecords(Isolate* isolate) { |
} |
-MaybeObject* JSObject::SetPropertyPostInterceptor( |
- Name* name, |
- Object* value, |
+Handle<Object> JSObject::SetPropertyPostInterceptor( |
+ Handle<JSObject> object, |
+ Handle<Name> name, |
+ Handle<Object> value, |
PropertyAttributes attributes, |
- StrictModeFlag strict_mode, |
- StoreMode mode) { |
+ StrictModeFlag strict_mode) { |
// Check local property, ignore interceptor. |
- LookupResult result(GetIsolate()); |
- LocalLookupRealNamedProperty(name, &result); |
- if (!result.IsFound()) map()->LookupTransition(this, name, &result); |
+ LookupResult result(object->GetIsolate()); |
+ object->LocalLookupRealNamedProperty(*name, &result); |
+ if (!result.IsFound()) { |
+ object->map()->LookupTransition(*object, *name, &result); |
+ } |
if (result.IsFound()) { |
// An existing property or a map transition was found. Use set property to |
// handle all these cases. |
- return SetProperty(&result, name, value, attributes, strict_mode); |
+ return SetPropertyForResult(object, &result, name, value, attributes, |
+ strict_mode, MAY_BE_STORE_FROM_KEYED); |
} |
bool done = false; |
- MaybeObject* result_object = |
- SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done); |
+ Handle<Object> result_object = SetPropertyViaPrototypes( |
+ object, name, value, attributes, strict_mode, &done); |
if (done) return result_object; |
// Add a new real property. |
- return AddProperty(name, value, attributes, strict_mode, |
- MAY_BE_STORE_FROM_KEYED, PERFORM_EXTENSIBILITY_CHECK, |
- OPTIMAL_REPRESENTATION, mode); |
+ return AddProperty(object, name, value, attributes, strict_mode); |
} |
-MaybeObject* JSObject::ReplaceSlowProperty(Name* name, |
- Object* value, |
- PropertyAttributes attributes) { |
- NameDictionary* dictionary = property_dictionary(); |
- int old_index = dictionary->FindEntry(name); |
+static Handle<Object> ReplaceSlowProperty(Handle<JSObject> object, |
+ Handle<Name> name, |
+ Handle<Object> value, |
+ PropertyAttributes attributes) { |
+ NameDictionary* dictionary = object->property_dictionary(); |
+ int old_index = dictionary->FindEntry(*name); |
int new_enumeration_index = 0; // 0 means "Use the next available index." |
if (old_index != -1) { |
// All calls to ReplaceSlowProperty have had all transitions removed. |
@@ -2153,7 +2200,7 @@ MaybeObject* JSObject::ReplaceSlowProperty(Name* name, |
} |
PropertyDetails new_details(attributes, NORMAL, new_enumeration_index); |
- return SetNormalizedProperty(name, value, new_details); |
+ return JSObject::SetNormalizedProperty(object, name, value, new_details); |
} |
@@ -2260,6 +2307,11 @@ bool Map::InstancesNeedRewriting(Map* target, |
} |
+void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) { |
+ CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), object->MigrateToMap(*new_map)); |
+} |
+ |
+ |
// To migrate an instance to a map: |
// - First check whether the instance needs to be rewritten. If not, simply |
// change the map. |
@@ -2361,17 +2413,14 @@ MaybeObject* JSObject::MigrateToMap(Map* new_map) { |
} |
-MaybeObject* JSObject::GeneralizeFieldRepresentation( |
- int modify_index, |
- Representation new_representation, |
- StoreMode store_mode) { |
- Map* new_map; |
- MaybeObject* maybe_new_map = map()->GeneralizeRepresentation( |
- modify_index, new_representation, store_mode); |
- if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
- if (map() == new_map) return this; |
- |
- return MigrateToMap(new_map); |
+void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object, |
+ int modify_index, |
+ Representation new_representation, |
+ StoreMode store_mode) { |
+ Handle<Map> new_map = Map::GeneralizeRepresentation( |
+ handle(object->map()), modify_index, new_representation, store_mode); |
+ if (object->map() == *new_map) return; |
+ return MigrateToMap(object, new_map); |
} |
@@ -2385,14 +2434,12 @@ int Map::NumberOfFields() { |
} |
-MaybeObject* Map::CopyGeneralizeAllRepresentations( |
- int modify_index, |
- StoreMode store_mode, |
- PropertyAttributes attributes, |
- const char* reason) { |
- Map* new_map; |
- MaybeObject* maybe_map = this->Copy(); |
- if (!maybe_map->To(&new_map)) return maybe_map; |
+Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map, |
+ int modify_index, |
+ StoreMode store_mode, |
+ PropertyAttributes attributes, |
+ const char* reason) { |
+ Handle<Map> new_map = Copy(map); |
DescriptorArray* descriptors = new_map->instance_descriptors(); |
descriptors->InitializeRepresentations(Representation::Tagged()); |
@@ -2414,7 +2461,7 @@ MaybeObject* Map::CopyGeneralizeAllRepresentations( |
} |
if (FLAG_trace_generalization) { |
- PrintGeneralization(stdout, reason, modify_index, |
+ map->PrintGeneralization(stdout, reason, modify_index, |
new_map->NumberOfOwnDescriptors(), |
new_map->NumberOfOwnDescriptors(), |
details.type() == CONSTANT && store_mode == FORCE_FIELD, |
@@ -2562,11 +2609,11 @@ Map* Map::FindLastMatchMap(int verbatim, |
// - If |updated| == |split_map|, |updated| is in the expected state. Return it. |
// - Otherwise, invalidate the outdated transition target from |updated|, and |
// replace its transition tree with a new branch for the updated descriptors. |
-MaybeObject* Map::GeneralizeRepresentation(int modify_index, |
- Representation new_representation, |
- StoreMode store_mode) { |
- Map* old_map = this; |
- DescriptorArray* old_descriptors = old_map->instance_descriptors(); |
+Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map, |
+ int modify_index, |
+ Representation new_representation, |
+ StoreMode store_mode) { |
+ Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors()); |
PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
Representation old_representation = old_details.representation(); |
@@ -2582,37 +2629,37 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index, |
} |
int descriptors = old_map->NumberOfOwnDescriptors(); |
- Map* root_map = old_map->FindRootMap(); |
+ Handle<Map> root_map(old_map->FindRootMap()); |
// Check the state of the root map. |
- if (!old_map->EquivalentToForTransition(root_map)) { |
- return CopyGeneralizeAllRepresentations( |
- modify_index, store_mode, old_details.attributes(), "not equivalent"); |
+ if (!old_map->EquivalentToForTransition(*root_map)) { |
+ return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
+ old_details.attributes(), "not equivalent"); |
} |
int verbatim = root_map->NumberOfOwnDescriptors(); |
if (store_mode != ALLOW_AS_CONSTANT && modify_index < verbatim) { |
- return CopyGeneralizeAllRepresentations( |
- modify_index, store_mode, |
+ return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
old_details.attributes(), "root modification"); |
} |
- Map* updated = root_map->FindUpdatedMap( |
- verbatim, descriptors, old_descriptors); |
- if (updated == NULL) { |
- return CopyGeneralizeAllRepresentations( |
- modify_index, store_mode, old_details.attributes(), "incompatible"); |
+ Map* raw_updated = root_map->FindUpdatedMap( |
+ verbatim, descriptors, *old_descriptors); |
+ if (raw_updated == NULL) { |
+ return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
+ old_details.attributes(), "incompatible"); |
} |
- DescriptorArray* updated_descriptors = updated->instance_descriptors(); |
+ Handle<Map> updated(raw_updated); |
+ Handle<DescriptorArray> updated_descriptors(updated->instance_descriptors()); |
int valid = updated->NumberOfOwnDescriptors(); |
// Directly change the map if the target map is more general. Ensure that the |
// target type of the modify_index is a FIELD, unless we are migrating. |
if (updated_descriptors->IsMoreGeneralThan( |
- verbatim, valid, descriptors, old_descriptors) && |
+ verbatim, valid, descriptors, *old_descriptors) && |
(store_mode == ALLOW_AS_CONSTANT || |
updated_descriptors->GetDetails(modify_index).type() == FIELD)) { |
Representation updated_representation = |
@@ -2620,10 +2667,9 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index, |
if (new_representation.fits_into(updated_representation)) return updated; |
} |
- DescriptorArray* new_descriptors; |
- MaybeObject* maybe_descriptors = updated_descriptors->Merge( |
- verbatim, valid, descriptors, modify_index, store_mode, old_descriptors); |
- if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; |
+ Handle<DescriptorArray> new_descriptors = DescriptorArray::Merge( |
+ updated_descriptors, verbatim, valid, descriptors, modify_index, |
+ store_mode, old_descriptors); |
ASSERT(store_mode == ALLOW_AS_CONSTANT || |
new_descriptors->GetDetails(modify_index).type() == FIELD); |
@@ -2635,8 +2681,8 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index, |
new_descriptors->SetRepresentation(modify_index, updated_representation); |
} |
- Map* split_map = root_map->FindLastMatchMap( |
- verbatim, descriptors, new_descriptors); |
+ Handle<Map> split_map(root_map->FindLastMatchMap( |
+ verbatim, descriptors, *new_descriptors)); |
int split_descriptors = split_map->NumberOfOwnDescriptors(); |
// This is shadowed by |updated_descriptors| being more general than |
@@ -2645,28 +2691,20 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index, |
int descriptor = split_descriptors; |
split_map->DeprecateTarget( |
- old_descriptors->GetKey(descriptor), new_descriptors); |
+ old_descriptors->GetKey(descriptor), *new_descriptors); |
if (FLAG_trace_generalization) { |
- PrintGeneralization( |
+ old_map->PrintGeneralization( |
stdout, "", modify_index, descriptor, descriptors, |
old_descriptors->GetDetails(modify_index).type() == CONSTANT && |
store_mode == FORCE_FIELD, |
old_representation, updated_representation); |
} |
- Map* new_map = split_map; |
// Add missing transitions. |
+ Handle<Map> new_map = split_map; |
for (; descriptor < descriptors; descriptor++) { |
- MaybeObject* maybe_map = new_map->CopyInstallDescriptors( |
- descriptor, new_descriptors); |
- if (!maybe_map->To(&new_map)) { |
- // Create a handle for the last created map to ensure it stays alive |
- // during GC. Its descriptor array is too large, but it will be |
- // overwritten during retry anyway. |
- Handle<Map>(new_map); |
- return maybe_map; |
- } |
+ new_map = Map::CopyInstallDescriptors(new_map, descriptor, new_descriptors); |
new_map->set_migration_target(true); |
} |
@@ -2703,79 +2741,52 @@ Map* Map::CurrentMapForDeprecated() { |
} |
-MaybeObject* JSObject::SetPropertyWithInterceptor( |
- Name* name, |
- Object* value, |
+Handle<Object> JSObject::SetPropertyWithInterceptor( |
+ Handle<JSObject> object, |
+ Handle<Name> name, |
+ Handle<Object> value, |
PropertyAttributes attributes, |
StrictModeFlag strict_mode) { |
// TODO(rossberg): Support symbols in the API. |
if (name->IsSymbol()) return value; |
- 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()); |
+ Isolate* isolate = object->GetIsolate(); |
+ Handle<String> name_string = Handle<String>::cast(name); |
+ Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor()); |
if (!interceptor->setter()->IsUndefined()) { |
- LOG(isolate, ApiNamedPropertyAccess("interceptor-named-set", this, name)); |
- PropertyCallbackArguments args(isolate, interceptor->data(), this, this); |
+ LOG(isolate, |
+ ApiNamedPropertyAccess("interceptor-named-set", *object, *name)); |
+ PropertyCallbackArguments args( |
+ isolate, interceptor->data(), *object, *object); |
v8::NamedPropertySetterCallback setter = |
v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter()); |
- Handle<Object> value_unhole(value->IsTheHole() ? |
- isolate->heap()->undefined_value() : |
- value, |
- isolate); |
+ Handle<Object> value_unhole = value->IsTheHole() |
+ ? Handle<Object>(isolate->factory()->undefined_value()) : value; |
v8::Handle<v8::Value> result = args.Call(setter, |
- v8::Utils::ToLocal(name_handle), |
+ v8::Utils::ToLocal(name_string), |
v8::Utils::ToLocal(value_unhole)); |
- RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
- if (!result.IsEmpty()) return *value_handle; |
+ RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); |
+ if (!result.IsEmpty()) return value; |
} |
- MaybeObject* raw_result = |
- this_handle->SetPropertyPostInterceptor(*name_handle, |
- *value_handle, |
- attributes, |
- strict_mode); |
- RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
- return raw_result; |
+ Handle<Object> result = |
+ SetPropertyPostInterceptor(object, name, value, attributes, strict_mode); |
+ RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); |
+ return result; |
} |
Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, |
- Handle<Name> key, |
+ Handle<Name> name, |
Handle<Object> value, |
PropertyAttributes attributes, |
- StrictModeFlag strict_mode) { |
- CALL_HEAP_FUNCTION(object->GetIsolate(), |
- object->SetProperty(*key, *value, attributes, strict_mode), |
- Object); |
-} |
- |
- |
-MaybeObject* JSReceiver::SetPropertyOrFail( |
- Handle<JSReceiver> object, |
- Handle<Name> key, |
- Handle<Object> value, |
- PropertyAttributes attributes, |
- StrictModeFlag strict_mode, |
- JSReceiver::StoreFromKeyed store_mode) { |
- CALL_HEAP_FUNCTION_PASS_EXCEPTION( |
- object->GetIsolate(), |
- object->SetProperty(*key, *value, attributes, strict_mode, store_mode)); |
-} |
- |
- |
-MaybeObject* JSReceiver::SetProperty(Name* name, |
- Object* value, |
- PropertyAttributes attributes, |
- StrictModeFlag strict_mode, |
- JSReceiver::StoreFromKeyed store_mode) { |
- LookupResult result(GetIsolate()); |
- LocalLookup(name, &result, true); |
+ StrictModeFlag strict_mode, |
+ StoreFromKeyed store_mode) { |
+ LookupResult result(object->GetIsolate()); |
+ object->LocalLookup(*name, &result, true); |
if (!result.IsFound()) { |
- map()->LookupTransition(JSObject::cast(this), name, &result); |
+ object->map()->LookupTransition(JSObject::cast(*object), *name, &result); |
} |
- return SetProperty(&result, name, value, attributes, strict_mode, store_mode); |
+ return SetProperty(object, &result, name, value, attributes, strict_mode, |
+ store_mode); |
} |
@@ -2930,21 +2941,20 @@ MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( |
return heap->the_hole_value(); |
} |
-MaybeObject* JSObject::SetPropertyViaPrototypes( |
- Name* name, |
- Object* value, |
- PropertyAttributes attributes, |
- StrictModeFlag strict_mode, |
- bool* done) { |
- Heap* heap = GetHeap(); |
- Isolate* isolate = heap->isolate(); |
+Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object, |
+ Handle<Name> name, |
+ Handle<Object> value, |
+ PropertyAttributes attributes, |
+ StrictModeFlag strict_mode, |
+ bool* done) { |
+ Isolate* isolate = object->GetIsolate(); |
*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); |
- LookupRealNamedPropertyInPrototypes(name, &result); |
+ object->LookupRealNamedPropertyInPrototypes(*name, &result); |
if (result.IsFound()) { |
switch (result.type()) { |
case NORMAL: |
@@ -2955,19 +2965,25 @@ MaybeObject* JSObject::SetPropertyViaPrototypes( |
case INTERCEPTOR: { |
PropertyAttributes attr = |
result.holder()->GetPropertyAttributeWithInterceptor( |
- this, name, true); |
+ *object, *name, true); |
*done = !!(attr & READ_ONLY); |
break; |
} |
case CALLBACKS: { |
if (!FLAG_es5_readonly && result.IsReadOnly()) break; |
*done = true; |
- return SetPropertyWithCallback(result.GetCallbackObject(), |
- name, value, result.holder(), strict_mode); |
+ CALL_HEAP_FUNCTION(isolate, |
+ object->SetPropertyWithCallback( |
+ result.GetCallbackObject(), |
+ *name, *value, result.holder(), strict_mode), |
+ Object); |
} |
case HANDLER: { |
- return result.proxy()->SetPropertyViaPrototypesWithHandler( |
- this, name, value, attributes, strict_mode, done); |
+ CALL_HEAP_FUNCTION(isolate, |
+ result.proxy()->SetPropertyViaPrototypesWithHandler( |
+ *object, *name, *value, attributes, strict_mode, |
+ done), |
+ Object); |
} |
case TRANSITION: |
case NONEXISTENT: |
@@ -2980,12 +2996,13 @@ MaybeObject* JSObject::SetPropertyViaPrototypes( |
if (!FLAG_es5_readonly) *done = false; |
if (*done) { |
if (strict_mode == kNonStrictMode) return value; |
- 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)))); |
+ 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>(); |
} |
- return heap->the_hole_value(); |
+ return isolate->factory()->the_hole_value(); |
} |
@@ -3406,17 +3423,18 @@ MaybeObject* JSObject::SetPropertyWithFailedAccessCheck( |
} |
-MaybeObject* JSReceiver::SetProperty(LookupResult* result, |
- Name* key, |
- Object* value, |
- PropertyAttributes attributes, |
- StrictModeFlag strict_mode, |
- JSReceiver::StoreFromKeyed store_mode) { |
+Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, |
+ LookupResult* result, |
+ Handle<Name> key, |
+ Handle<Object> value, |
+ PropertyAttributes attributes, |
+ StrictModeFlag strict_mode, |
+ StoreFromKeyed store_mode) { |
if (result->IsHandler()) { |
- return result->proxy()->SetPropertyWithHandler( |
- this, key, value, attributes, strict_mode); |
+ return JSProxy::SetPropertyWithHandler(handle(result->proxy()), |
+ object, key, value, attributes, strict_mode); |
} else { |
- return JSObject::cast(this)->SetPropertyForResult( |
+ return JSObject::SetPropertyForResult(Handle<JSObject>::cast(object), |
result, key, value, attributes, strict_mode, store_mode); |
} |
} |
@@ -3440,26 +3458,22 @@ bool JSProxy::HasPropertyWithHandler(Name* name_raw) { |
} |
-MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler( |
- JSReceiver* receiver_raw, |
- Name* name_raw, |
- Object* value_raw, |
- PropertyAttributes attributes, |
- StrictModeFlag strict_mode) { |
- Isolate* isolate = GetIsolate(); |
- HandleScope scope(isolate); |
- Handle<JSReceiver> receiver(receiver_raw); |
- Handle<Object> name(name_raw, isolate); |
- Handle<Object> value(value_raw, isolate); |
+Handle<Object> JSProxy::SetPropertyWithHandler(Handle<JSProxy> proxy, |
+ Handle<JSReceiver> receiver, |
+ Handle<Name> name, |
+ Handle<Object> value, |
+ PropertyAttributes attributes, |
+ StrictModeFlag strict_mode) { |
+ Isolate* isolate = proxy->GetIsolate(); |
// TODO(rossberg): adjust once there is a story for symbols vs proxies. |
- if (name->IsSymbol()) return *value; |
+ if (name->IsSymbol()) return value; |
Handle<Object> args[] = { receiver, name, value }; |
- CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args); |
- if (isolate->has_pending_exception()) return Failure::Exception(); |
+ proxy->CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args); |
+ if (isolate->has_pending_exception()) return Handle<Object>(); |
- return *value; |
+ return value; |
} |
@@ -3734,36 +3748,31 @@ void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) { |
void JSObject::MigrateInstance(Handle<JSObject> object) { |
- CALL_HEAP_FUNCTION_VOID( |
- object->GetIsolate(), |
- object->MigrateInstance()); |
+ // Converting any field to the most specific type will cause the |
+ // GeneralizeFieldRepresentation algorithm to create the most general existing |
+ // transition that matches the object. This achieves what is needed. |
+ Handle<Map> original_map(object->map()); |
+ GeneralizeFieldRepresentation( |
+ object, 0, Representation::None(), ALLOW_AS_CONSTANT); |
+ if (FLAG_trace_migration) { |
+ object->PrintInstanceMigration(stdout, *original_map, object->map()); |
+ } |
} |
Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) { |
- CALL_HEAP_FUNCTION( |
- object->GetIsolate(), |
- object->MigrateInstance(), |
- Object); |
-} |
- |
- |
-Handle<Map> Map::GeneralizeRepresentation(Handle<Map> map, |
- int modify_index, |
- Representation representation, |
- StoreMode store_mode) { |
- CALL_HEAP_FUNCTION( |
- map->GetIsolate(), |
- map->GeneralizeRepresentation(modify_index, representation, store_mode), |
- Map); |
+ MigrateInstance(object); |
+ return object; |
} |
-static MaybeObject* SetPropertyUsingTransition(LookupResult* lookup, |
- Handle<Name> name, |
- Handle<Object> value, |
- PropertyAttributes attributes) { |
- Map* transition_map = lookup->GetTransitionTarget(); |
+Handle<Object> JSObject::SetPropertyUsingTransition( |
+ Handle<JSObject> object, |
+ LookupResult* lookup, |
+ Handle<Name> name, |
+ Handle<Object> value, |
+ PropertyAttributes attributes) { |
+ Handle<Map> transition_map(lookup->GetTransitionTarget()); |
int descriptor = transition_map->LastAdded(); |
DescriptorArray* descriptors = transition_map->instance_descriptors(); |
@@ -3773,8 +3782,8 @@ 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. |
- return lookup->holder()->AddProperty( |
- *name, *value, attributes, kNonStrictMode, |
+ return JSObject::AddProperty( |
+ object, name, value, attributes, kNonStrictMode, |
JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, |
JSReceiver::OMIT_EXTENSIBILITY_CHECK, |
JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION); |
@@ -3785,45 +3794,40 @@ static MaybeObject* SetPropertyUsingTransition(LookupResult* lookup, |
// (value->IsUninitialized) as constant. |
if (details.type() == CONSTANT && |
descriptors->GetValue(descriptor) == *value) { |
- lookup->holder()->set_map(transition_map); |
- return *value; |
+ object->set_map(*transition_map); |
+ return value; |
} |
Representation representation = details.representation(); |
if (!value->FitsRepresentation(representation) || |
details.type() == CONSTANT) { |
- MaybeObject* maybe_map = transition_map->GeneralizeRepresentation( |
+ transition_map = Map::GeneralizeRepresentation(transition_map, |
descriptor, value->OptimalRepresentation(), FORCE_FIELD); |
- if (!maybe_map->To(&transition_map)) return maybe_map; |
Object* back = transition_map->GetBackPointer(); |
if (back->IsMap()) { |
- MaybeObject* maybe_failure = |
- lookup->holder()->MigrateToMap(Map::cast(back)); |
- if (maybe_failure->IsFailure()) return maybe_failure; |
+ MigrateToMap(object, handle(Map::cast(back))); |
} |
descriptors = transition_map->instance_descriptors(); |
representation = descriptors->GetDetails(descriptor).representation(); |
} |
int field_index = descriptors->GetFieldIndex(descriptor); |
- return lookup->holder()->AddFastPropertyUsingMap( |
- transition_map, *name, *value, field_index, representation); |
+ return AddFastPropertyUsingMap( |
+ object, transition_map, name, value, field_index, representation); |
} |
-static MaybeObject* SetPropertyToField(LookupResult* lookup, |
- Handle<Name> name, |
- Handle<Object> value) { |
+static Handle<Object> SetPropertyToField(LookupResult* lookup, |
+ Handle<Name> name, |
+ Handle<Object> value) { |
Representation representation = lookup->representation(); |
if (!value->FitsRepresentation(representation) || |
lookup->type() == CONSTANT) { |
- MaybeObject* maybe_failure = |
- lookup->holder()->GeneralizeFieldRepresentation( |
- lookup->GetDescriptorIndex(), |
- value->OptimalRepresentation(), |
- FORCE_FIELD); |
- if (maybe_failure->IsFailure()) return maybe_failure; |
+ JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()), |
+ lookup->GetDescriptorIndex(), |
+ value->OptimalRepresentation(), |
+ FORCE_FIELD); |
DescriptorArray* desc = lookup->holder()->map()->instance_descriptors(); |
int descriptor = lookup->GetDescriptorIndex(); |
representation = desc->GetDetails(descriptor).representation(); |
@@ -3833,199 +3837,189 @@ static MaybeObject* SetPropertyToField(LookupResult* lookup, |
HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt( |
lookup->GetFieldIndex().field_index())); |
storage->set_value(value->Number()); |
- return *value; |
+ return value; |
} |
lookup->holder()->FastPropertyAtPut( |
lookup->GetFieldIndex().field_index(), *value); |
- return *value; |
+ return value; |
} |
-static MaybeObject* ConvertAndSetLocalProperty(LookupResult* lookup, |
- Name* name, |
- Object* value, |
- PropertyAttributes attributes) { |
- JSObject* object = lookup->holder(); |
+static Handle<Object> ConvertAndSetLocalProperty( |
+ LookupResult* lookup, |
+ Handle<Name> name, |
+ Handle<Object> value, |
+ PropertyAttributes attributes) { |
+ Handle<JSObject> object(lookup->holder()); |
if (object->TooManyFastProperties()) { |
- MaybeObject* maybe_failure = object->NormalizeProperties( |
- CLEAR_INOBJECT_PROPERTIES, 0); |
- if (maybe_failure->IsFailure()) return maybe_failure; |
+ JSObject::NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
} |
if (!object->HasFastProperties()) { |
- return object->ReplaceSlowProperty(name, value, attributes); |
+ return ReplaceSlowProperty(object, name, value, attributes); |
} |
int descriptor_index = lookup->GetDescriptorIndex(); |
if (lookup->GetAttributes() == attributes) { |
- MaybeObject* maybe_failure = object->GeneralizeFieldRepresentation( |
- descriptor_index, Representation::Tagged(), FORCE_FIELD); |
- if (maybe_failure->IsFailure()) return maybe_failure; |
+ JSObject::GeneralizeFieldRepresentation( |
+ object, descriptor_index, Representation::Tagged(), FORCE_FIELD); |
} else { |
- Map* map; |
- MaybeObject* maybe_map = object->map()->CopyGeneralizeAllRepresentations( |
+ Handle<Map> old_map(object->map()); |
+ Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map, |
descriptor_index, FORCE_FIELD, attributes, "attributes mismatch"); |
- if (!maybe_map->To(&map)) return maybe_map; |
- MaybeObject* maybe_failure = object->MigrateToMap(map); |
- if (maybe_failure->IsFailure()) return maybe_failure; |
+ JSObject::MigrateToMap(object, new_map); |
} |
DescriptorArray* descriptors = object->map()->instance_descriptors(); |
int index = descriptors->GetDetails(descriptor_index).field_index(); |
- object->FastPropertyAtPut(index, value); |
+ object->FastPropertyAtPut(index, *value); |
return value; |
} |
-static MaybeObject* SetPropertyToFieldWithAttributes( |
+static Handle<Object> SetPropertyToFieldWithAttributes( |
LookupResult* lookup, |
Handle<Name> name, |
Handle<Object> value, |
PropertyAttributes attributes) { |
if (lookup->GetAttributes() == attributes) { |
- if (value->IsUninitialized()) return *value; |
+ if (value->IsUninitialized()) return value; |
return SetPropertyToField(lookup, name, value); |
} else { |
- return ConvertAndSetLocalProperty(lookup, *name, *value, attributes); |
+ return ConvertAndSetLocalProperty(lookup, name, value, attributes); |
} |
} |
-MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup, |
- Name* name_raw, |
- Object* value_raw, |
- PropertyAttributes attributes, |
- StrictModeFlag strict_mode, |
- StoreFromKeyed store_mode) { |
- Heap* heap = GetHeap(); |
- Isolate* isolate = heap->isolate(); |
+Handle<Object> JSObject::SetPropertyForResult(Handle<JSObject> object, |
+ LookupResult* lookup, |
+ Handle<Name> name, |
+ Handle<Object> value, |
+ PropertyAttributes attributes, |
+ StrictModeFlag strict_mode, |
+ StoreFromKeyed store_mode) { |
+ Isolate* isolate = object->GetIsolate(); |
// Make sure that the top context does not change when doing callbacks or |
// interceptor calls. |
- AssertNoContextChangeWithHandleScope ncc; |
+ AssertNoContextChange ncc; |
// Optimization for 2-byte strings often used as keys in a decompression |
// dictionary. We internalize these short keys to avoid constantly |
// reallocating them. |
- if (name_raw->IsString() && !name_raw->IsInternalizedString() && |
- String::cast(name_raw)->length() <= 2) { |
- Object* internalized_version; |
- { MaybeObject* maybe_string_version = |
- heap->InternalizeString(String::cast(name_raw)); |
- if (maybe_string_version->ToObject(&internalized_version)) { |
- name_raw = String::cast(internalized_version); |
- } |
- } |
+ if (name->IsString() && !name->IsInternalizedString() && |
+ Handle<String>::cast(name)->length() <= 2) { |
+ name = isolate->factory()->InternalizeString(Handle<String>::cast(name)); |
} |
// Check access rights if needed. |
- if (IsAccessCheckNeeded()) { |
- if (!isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { |
- return SetPropertyWithFailedAccessCheck( |
- lookup, name_raw, value_raw, true, strict_mode); |
+ if (object->IsAccessCheckNeeded()) { |
+ if (!isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) { |
+ CALL_HEAP_FUNCTION( |
+ isolate, |
+ object->SetPropertyWithFailedAccessCheck( |
+ lookup, *name, *value, true, strict_mode), |
+ Object); |
} |
} |
- if (IsJSGlobalProxy()) { |
- Object* proto = GetPrototype(); |
- if (proto->IsNull()) return value_raw; |
+ if (object->IsJSGlobalProxy()) { |
+ Handle<Object> proto(object->GetPrototype(), isolate); |
+ if (proto->IsNull()) return value; |
ASSERT(proto->IsJSGlobalObject()); |
- return JSObject::cast(proto)->SetPropertyForResult( |
- lookup, name_raw, value_raw, attributes, strict_mode, store_mode); |
+ return SetPropertyForResult(Handle<JSObject>::cast(proto), |
+ lookup, name, value, attributes, strict_mode, store_mode); |
} |
- ASSERT(!lookup->IsFound() || lookup->holder() == this || |
+ ASSERT(!lookup->IsFound() || lookup->holder() == *object || |
lookup->holder()->map()->is_hidden_prototype()); |
- // From this point on everything needs to be handlified, because |
- // SetPropertyViaPrototypes might call back into JavaScript. |
- HandleScope scope(isolate); |
- Handle<JSObject> self(this); |
- Handle<Name> name(name_raw); |
- Handle<Object> value(value_raw, isolate); |
- |
- if (!lookup->IsProperty() && !self->IsJSContextExtensionObject()) { |
+ if (!lookup->IsProperty() && !object->IsJSContextExtensionObject()) { |
bool done = false; |
- MaybeObject* result_object = self->SetPropertyViaPrototypes( |
- *name, *value, attributes, strict_mode, &done); |
+ Handle<Object> result_object = SetPropertyViaPrototypes( |
+ object, name, value, attributes, strict_mode, &done); |
if (done) return result_object; |
} |
if (!lookup->IsFound()) { |
// Neither properties nor transitions found. |
- return self->AddProperty( |
- *name, *value, attributes, strict_mode, store_mode); |
+ return AddProperty( |
+ object, name, value, attributes, strict_mode, store_mode); |
} |
if (lookup->IsProperty() && lookup->IsReadOnly()) { |
if (strict_mode == kStrictMode) { |
- Handle<Object> args[] = { name, self }; |
- return isolate->Throw(*isolate->factory()->NewTypeError( |
- "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)))); |
+ 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>(); |
} else { |
- return *value; |
+ return value; |
} |
} |
- Handle<Object> old_value(heap->the_hole_value(), isolate); |
+ Handle<Object> old_value = isolate->factory()->the_hole_value(); |
if (FLAG_harmony_observation && |
- map()->is_observed() && lookup->IsDataProperty()) { |
- old_value = Object::GetProperty(self, name); |
+ object->map()->is_observed() && lookup->IsDataProperty()) { |
+ old_value = Object::GetProperty(object, name); |
} |
// This is a real property that is not read-only, or it is a |
// transition or null descriptor and there are no setters in the prototypes. |
- MaybeObject* result = *value; |
+ Handle<Object> result = value; |
switch (lookup->type()) { |
case NORMAL: |
- result = lookup->holder()->SetNormalizedProperty(lookup, *value); |
+ result = SetNormalizedProperty(handle(lookup->holder()), lookup, value); |
break; |
case FIELD: |
result = SetPropertyToField(lookup, name, value); |
break; |
case CONSTANT: |
// Only replace the constant if necessary. |
- if (*value == lookup->GetConstant()) return *value; |
+ if (*value == lookup->GetConstant()) return value; |
result = SetPropertyToField(lookup, name, value); |
break; |
case CALLBACKS: { |
- Object* callback_object = lookup->GetCallbackObject(); |
- return self->SetPropertyWithCallback( |
- callback_object, *name, *value, lookup->holder(), strict_mode); |
+ Handle<Object> callback_object(lookup->GetCallbackObject(), isolate); |
+ CALL_HEAP_FUNCTION( |
+ isolate, |
+ object->SetPropertyWithCallback(*callback_object, *name, *value, |
+ lookup->holder(), strict_mode), |
+ Object); |
} |
case INTERCEPTOR: |
- result = lookup->holder()->SetPropertyWithInterceptor( |
- *name, *value, attributes, strict_mode); |
+ result = SetPropertyWithInterceptor(handle(lookup->holder()), name, value, |
+ attributes, strict_mode); |
break; |
- case TRANSITION: { |
- result = SetPropertyUsingTransition(lookup, name, value, attributes); |
+ case TRANSITION: |
+ result = SetPropertyUsingTransition(handle(lookup->holder()), lookup, |
+ name, value, attributes); |
break; |
- } |
case HANDLER: |
case NONEXISTENT: |
UNREACHABLE(); |
} |
- Handle<Object> hresult; |
- if (!result->ToHandle(&hresult, isolate)) return result; |
+ RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<Object>()); |
- if (FLAG_harmony_observation && self->map()->is_observed()) { |
+ if (FLAG_harmony_observation && object->map()->is_observed()) { |
if (lookup->IsTransition()) { |
- EnqueueChangeRecord(self, "new", name, old_value); |
+ EnqueueChangeRecord(object, "new", name, old_value); |
} else { |
LookupResult new_lookup(isolate); |
- self->LocalLookup(*name, &new_lookup, true); |
+ object->LocalLookup(*name, &new_lookup, true); |
if (new_lookup.IsDataProperty()) { |
- Handle<Object> new_value = Object::GetProperty(self, name); |
+ Handle<Object> new_value = Object::GetProperty(object, name); |
if (!new_value->SameValue(*old_value)) { |
- EnqueueChangeRecord(self, "updated", name, old_value); |
+ EnqueueChangeRecord(object, "updated", name, old_value); |
} |
} |
} |
} |
- return *hresult; |
+ return result; |
} |
@@ -4063,91 +4057,69 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributesTrampoline( |
// doesn't handle function prototypes correctly. |
Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes( |
Handle<JSObject> object, |
- Handle<Name> key, |
+ Handle<Name> name, |
Handle<Object> value, |
PropertyAttributes attributes, |
ValueType value_type, |
StoreMode mode, |
ExtensibilityCheck extensibility_check) { |
- CALL_HEAP_FUNCTION( |
- object->GetIsolate(), |
- object->SetLocalPropertyIgnoreAttributes( |
- *key, *value, attributes, value_type, mode, extensibility_check), |
- Object); |
-} |
- |
+ Isolate* isolate = object->GetIsolate(); |
-MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( |
- Name* name_raw, |
- Object* value_raw, |
- PropertyAttributes attributes, |
- ValueType value_type, |
- StoreMode mode, |
- ExtensibilityCheck extensibility_check) { |
// Make sure that the top context does not change when doing callbacks or |
// interceptor calls. |
- AssertNoContextChangeWithHandleScope ncc; |
- Isolate* isolate = GetIsolate(); |
+ AssertNoContextChange ncc; |
+ |
LookupResult lookup(isolate); |
- LocalLookup(name_raw, &lookup, true); |
- if (!lookup.IsFound()) map()->LookupTransition(this, name_raw, &lookup); |
+ object->LocalLookup(*name, &lookup, true); |
+ if (!lookup.IsFound()) { |
+ object->map()->LookupTransition(*object, *name, &lookup); |
+ } |
+ |
// Check access rights if needed. |
- if (IsAccessCheckNeeded()) { |
- if (!isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { |
- return SetPropertyWithFailedAccessCheck(&lookup, |
- name_raw, |
- value_raw, |
- false, |
- kNonStrictMode); |
+ if (object->IsAccessCheckNeeded()) { |
+ if (!isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) { |
+ CALL_HEAP_FUNCTION( |
+ isolate, |
+ object->SetPropertyWithFailedAccessCheck( |
+ &lookup, *name, *value, false, kNonStrictMode), |
+ Object); |
} |
} |
- if (IsJSGlobalProxy()) { |
- Object* proto = GetPrototype(); |
- if (proto->IsNull()) return value_raw; |
+ if (object->IsJSGlobalProxy()) { |
+ Handle<Object> proto(object->GetPrototype(), isolate); |
+ if (proto->IsNull()) return value; |
ASSERT(proto->IsJSGlobalObject()); |
- return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes( |
- name_raw, |
- value_raw, |
- attributes, |
- value_type, |
- mode, |
- extensibility_check); |
+ return SetLocalPropertyIgnoreAttributes(Handle<JSObject>::cast(proto), |
+ name, value, attributes, value_type, mode, extensibility_check); |
} |
if (lookup.IsFound() && |
(lookup.type() == INTERCEPTOR || lookup.type() == CALLBACKS)) { |
- LocalLookupRealNamedProperty(name_raw, &lookup); |
+ object->LocalLookupRealNamedProperty(*name, &lookup); |
} |
// Check for accessor in prototype chain removed here in clone. |
if (!lookup.IsFound()) { |
// Neither properties nor transitions found. |
- return AddProperty( |
- name_raw, value_raw, attributes, kNonStrictMode, |
+ return AddProperty(object, name, value, attributes, kNonStrictMode, |
MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode); |
} |
- // 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); |
+ Handle<Object> old_value = isolate->factory()->the_hole_value(); |
PropertyAttributes old_attributes = ABSENT; |
- bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); |
+ bool is_observed = FLAG_harmony_observation && object->map()->is_observed(); |
if (is_observed && lookup.IsProperty()) { |
if (lookup.IsDataProperty()) old_value = |
- Object::GetProperty(self, name); |
+ Object::GetProperty(object, name); |
old_attributes = lookup.GetAttributes(); |
} |
// Check of IsReadOnly removed from here in clone. |
- MaybeObject* result = *value; |
+ Handle<Object> result = value; |
switch (lookup.type()) { |
case NORMAL: |
- result = self->ReplaceSlowProperty(*name, *value, attributes); |
+ result = ReplaceSlowProperty(object, name, value, attributes); |
break; |
case FIELD: |
result = SetPropertyToFieldWithAttributes( |
@@ -4162,10 +4134,11 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( |
} |
break; |
case CALLBACKS: |
- result = ConvertAndSetLocalProperty(&lookup, *name, *value, attributes); |
+ result = ConvertAndSetLocalProperty(&lookup, name, value, attributes); |
break; |
case TRANSITION: |
- result = SetPropertyUsingTransition(&lookup, name, value, attributes); |
+ result = SetPropertyUsingTransition(handle(lookup.holder()), &lookup, |
+ name, value, attributes); |
break; |
case NONEXISTENT: |
case HANDLER: |
@@ -4173,32 +4146,31 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( |
UNREACHABLE(); |
} |
- Handle<Object> hresult; |
- if (!result->ToHandle(&hresult, isolate)) return result; |
+ if (result.is_null()) return result; |
if (is_observed) { |
if (lookup.IsTransition()) { |
- EnqueueChangeRecord(self, "new", name, old_value); |
+ EnqueueChangeRecord(object, "new", name, old_value); |
} else if (old_value->IsTheHole()) { |
- EnqueueChangeRecord(self, "reconfigured", name, old_value); |
+ EnqueueChangeRecord(object, "reconfigured", name, old_value); |
} else { |
LookupResult new_lookup(isolate); |
- self->LocalLookup(*name, &new_lookup, true); |
+ object->LocalLookup(*name, &new_lookup, true); |
bool value_changed = false; |
if (new_lookup.IsDataProperty()) { |
- Handle<Object> new_value = Object::GetProperty(self, name); |
+ Handle<Object> new_value = Object::GetProperty(object, name); |
value_changed = !old_value->SameValue(*new_value); |
} |
if (new_lookup.GetAttributes() != old_attributes) { |
if (!value_changed) old_value = isolate->factory()->the_hole_value(); |
- EnqueueChangeRecord(self, "reconfigured", name, old_value); |
+ EnqueueChangeRecord(object, "reconfigured", name, old_value); |
} else if (value_changed) { |
- EnqueueChangeRecord(self, "updated", name, old_value); |
+ EnqueueChangeRecord(object, "updated", name, old_value); |
} |
} |
} |
- return *hresult; |
+ return result; |
} |
@@ -6690,6 +6662,15 @@ MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors, |
} |
+Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map, |
+ int new_descriptor, |
+ Handle<DescriptorArray> descriptors) { |
+ CALL_HEAP_FUNCTION(map->GetIsolate(), |
+ map->CopyInstallDescriptors(new_descriptor, *descriptors), |
+ Map); |
+} |
+ |
+ |
// Since this method is used to rewrite an existing transition tree, it can |
// always insert transitions without checking. |
MaybeObject* Map::CopyInstallDescriptors(int new_descriptor, |
@@ -7802,6 +7783,20 @@ void DescriptorArray::CopyFrom(int dst_index, |
} |
+Handle<DescriptorArray> DescriptorArray::Merge(Handle<DescriptorArray> desc, |
+ int verbatim, |
+ int valid, |
+ int new_size, |
+ int modify_index, |
+ StoreMode store_mode, |
+ Handle<DescriptorArray> other) { |
+ CALL_HEAP_FUNCTION(desc->GetIsolate(), |
+ desc->Merge(verbatim, valid, new_size, modify_index, |
+ store_mode, *other), |
+ DescriptorArray); |
+} |
+ |
+ |
// Generalize the |other| descriptor array by merging it into the (at least |
// partly) updated |this| descriptor array. |
// The method merges two descriptor array in three parts. Both descriptor arrays |
@@ -14520,17 +14515,6 @@ PropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) { |
} |
-// TODO(mstarzinger): Temporary wrapper until handlified. |
-static Handle<NameDictionary> NameDictionaryAdd(Handle<NameDictionary> dict, |
- Handle<Name> name, |
- Handle<Object> value, |
- PropertyDetails details) { |
- CALL_HEAP_FUNCTION(dict->GetIsolate(), |
- dict->Add(*name, *value, details), |
- NameDictionary); |
-} |
- |
- |
Handle<PropertyCell> GlobalObject::EnsurePropertyCell( |
Handle<GlobalObject> global, |
Handle<Name> name) { |
@@ -16109,6 +16093,14 @@ Type* PropertyCell::UpdateType(Handle<PropertyCell> cell, |
} |
+void PropertyCell::SetValueInferType(Handle<PropertyCell> cell, |
+ Handle<Object> value, |
+ WriteBarrierMode mode) { |
+ CALL_HEAP_FUNCTION_VOID(cell->GetIsolate(), |
+ cell->SetValueInferType(*value, mode)); |
+} |
+ |
+ |
MaybeObject* PropertyCell::SetValueInferType(Object* value, |
WriteBarrierMode ignored) { |
set_value(value, ignored); |