Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 5da24af979b199529b41a4702d92c1632938d4d5..d3469df796c1db9de194c3cbaa8fdda537309ddc 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -4324,21 +4324,20 @@ void JSObject::LookupCallback(String* name, LookupResult* result) { |
static bool UpdateGetterSetterInDictionary( |
SeededNumberDictionary* dictionary, |
uint32_t index, |
- AccessorComponent component, |
- Object* fun, |
+ Object* getter, |
+ Object* setter, |
PropertyAttributes attributes) { |
int entry = dictionary->FindEntry(index); |
if (entry != SeededNumberDictionary::kNotFound) { |
Object* result = dictionary->ValueAt(entry); |
PropertyDetails details = dictionary->DetailsAt(entry); |
- // TODO(mstarzinger): We should check for details.IsDontDelete() here once |
- // we only call into the runtime once to set both getter and setter. |
if (details.type() == CALLBACKS && result->IsAccessorPair()) { |
+ ASSERT(!details.IsDontDelete()); |
if (details.attributes() != attributes) { |
dictionary->DetailsAtPut(entry, |
PropertyDetails(attributes, CALLBACKS, index)); |
} |
- AccessorPair::cast(result)->set(component, fun); |
+ AccessorPair::cast(result)->SetComponents(getter, setter); |
return true; |
} |
} |
@@ -4347,8 +4346,8 @@ static bool UpdateGetterSetterInDictionary( |
MaybeObject* JSObject::DefineElementAccessor(uint32_t index, |
- AccessorComponent component, |
- Object* fun, |
+ Object* getter, |
+ Object* setter, |
PropertyAttributes attributes) { |
switch (GetElementsKind()) { |
case FAST_SMI_ONLY_ELEMENTS: |
@@ -4369,8 +4368,8 @@ MaybeObject* JSObject::DefineElementAccessor(uint32_t index, |
case DICTIONARY_ELEMENTS: |
if (UpdateGetterSetterInDictionary(element_dictionary(), |
index, |
- component, |
- fun, |
+ getter, |
+ setter, |
attributes)) { |
return GetHeap()->undefined_value(); |
} |
@@ -4390,8 +4389,8 @@ MaybeObject* JSObject::DefineElementAccessor(uint32_t index, |
SeededNumberDictionary::cast(arguments); |
if (UpdateGetterSetterInDictionary(dictionary, |
index, |
- component, |
- fun, |
+ getter, |
+ setter, |
attributes)) { |
return GetHeap()->undefined_value(); |
} |
@@ -4405,23 +4404,22 @@ MaybeObject* JSObject::DefineElementAccessor(uint32_t index, |
{ MaybeObject* maybe_accessors = GetHeap()->AllocateAccessorPair(); |
if (!maybe_accessors->To(&accessors)) return maybe_accessors; |
} |
- accessors->set(component, fun); |
+ accessors->SetComponents(getter, setter); |
return SetElementCallback(index, accessors, attributes); |
} |
MaybeObject* JSObject::DefinePropertyAccessor(String* name, |
- AccessorComponent component, |
- Object* fun, |
+ Object* getter, |
+ Object* setter, |
PropertyAttributes attributes) { |
// Lookup the name. |
LookupResult result(GetHeap()->isolate()); |
LocalLookupRealNamedProperty(name, &result); |
if (result.IsFound()) { |
- // TODO(mstarzinger): We should check for result.IsDontDelete() here once |
- // we only call into the runtime once to set both getter and setter. |
if (result.type() == CALLBACKS) { |
+ ASSERT(!result.IsDontDelete()); |
Object* obj = result.GetCallbackObject(); |
// Need to preserve old getters/setters. |
if (obj->IsAccessorPair()) { |
@@ -4430,7 +4428,7 @@ MaybeObject* JSObject::DefinePropertyAccessor(String* name, |
AccessorPair::cast(obj)->CopyWithoutTransitions(); |
if (!maybe_copy->To(©)) return maybe_copy; |
} |
- copy->set(component, fun); |
+ copy->SetComponents(getter, setter); |
// Use set to update attributes. |
return SetPropertyCallback(name, copy, attributes); |
} |
@@ -4441,7 +4439,7 @@ MaybeObject* JSObject::DefinePropertyAccessor(String* name, |
{ MaybeObject* maybe_accessors = GetHeap()->AllocateAccessorPair(); |
if (!maybe_accessors->To(&accessors)) return maybe_accessors; |
} |
- accessors->set(component, fun); |
+ accessors->SetComponents(getter, setter); |
return SetPropertyCallback(name, accessors, attributes); |
} |
@@ -4512,12 +4510,6 @@ MaybeObject* JSObject::SetElementCallback(uint32_t index, |
MaybeObject* JSObject::SetPropertyCallback(String* name, |
Object* structure, |
PropertyAttributes attributes) { |
- PropertyDetails details = PropertyDetails(attributes, CALLBACKS); |
- |
- bool convert_back_to_fast = HasFastProperties() && |
- (map()->instance_descriptors()->number_of_descriptors() |
- < DescriptorArray::kMaxNumberOfDescriptors); |
- |
// Normalize object to make this operation simple. |
{ MaybeObject* maybe_ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
if (maybe_ok->IsFailure()) return maybe_ok; |
@@ -4538,22 +4530,29 @@ MaybeObject* JSObject::SetPropertyCallback(String* name, |
} |
// Update the dictionary with the new CALLBACKS property. |
+ PropertyDetails details = PropertyDetails(attributes, CALLBACKS); |
{ MaybeObject* maybe_ok = SetNormalizedProperty(name, structure, details); |
if (maybe_ok->IsFailure()) return maybe_ok; |
} |
- if (convert_back_to_fast) { |
- MaybeObject* maybe_ok = TransformToFastProperties(0); |
- if (maybe_ok->IsFailure()) return maybe_ok; |
- } |
return GetHeap()->undefined_value(); |
} |
+ |
+void JSObject::DefineAccessor(Handle<JSObject> object, |
+ Handle<String> name, |
+ Handle<Object> getter, |
+ Handle<Object> setter, |
+ PropertyAttributes attributes) { |
+ CALL_HEAP_FUNCTION_VOID( |
+ object->GetIsolate(), |
+ object->DefineAccessor(*name, *getter, *setter, attributes)); |
+} |
+ |
MaybeObject* JSObject::DefineAccessor(String* name, |
- AccessorComponent component, |
- Object* fun, |
+ Object* getter, |
+ Object* setter, |
PropertyAttributes attributes) { |
- ASSERT(fun->IsSpecFunction() || fun->IsUndefined()); |
Isolate* isolate = GetIsolate(); |
// Check access rights if needed. |
if (IsAccessCheckNeeded() && |
@@ -4566,8 +4565,8 @@ MaybeObject* JSObject::DefineAccessor(String* name, |
Object* proto = GetPrototype(); |
if (proto->IsNull()) return this; |
ASSERT(proto->IsJSGlobalObject()); |
- return JSObject::cast(proto)->DefineAccessor(name, component, |
- fun, attributes); |
+ return JSObject::cast(proto)->DefineAccessor( |
+ name, getter, setter, attributes); |
} |
// Make sure that the top context does not change when doing callbacks or |
@@ -4581,8 +4580,8 @@ MaybeObject* JSObject::DefineAccessor(String* name, |
uint32_t index = 0; |
return name->AsArrayIndex(&index) ? |
- DefineElementAccessor(index, component, fun, attributes) : |
- DefinePropertyAccessor(name, component, fun, attributes); |
+ DefineElementAccessor(index, getter, setter, attributes) : |
+ DefinePropertyAccessor(name, getter, setter, attributes); |
} |
@@ -4696,7 +4695,7 @@ Object* JSObject::LookupAccessor(String* name, AccessorComponent component) { |
Object* element = dictionary->ValueAt(entry); |
if (dictionary->DetailsAt(entry).type() == CALLBACKS && |
element->IsAccessorPair()) { |
- return AccessorPair::cast(element)->SafeGet(component); |
+ return AccessorPair::cast(element)->GetComponent(component); |
} |
} |
} |
@@ -4712,7 +4711,7 @@ Object* JSObject::LookupAccessor(String* name, AccessorComponent component) { |
if (result.type() == CALLBACKS) { |
Object* obj = result.GetCallbackObject(); |
if (obj->IsAccessorPair()) { |
- return AccessorPair::cast(obj)->SafeGet(component); |
+ return AccessorPair::cast(obj)->GetComponent(component); |
} |
} |
} |
@@ -5949,8 +5948,8 @@ MaybeObject* AccessorPair::CopyWithoutTransitions() { |
} |
-Object* AccessorPair::SafeGet(AccessorComponent component) { |
- Object* accessor = get(component); |
+Object* AccessorPair::GetComponent(AccessorComponent component) { |
+ Object* accessor = (component == ACCESSOR_GETTER) ? getter() : setter(); |
return accessor->IsTheHole() ? GetHeap()->undefined_value() : accessor; |
} |