Object* element = dictionary->ValueAt(entry);
if (dictionary->DetailsAt(entry).type() == CALLBACKS &&
element->IsAccessorPair()) {
- return AccessorPair::cast(element)->get(component);
+ return AccessorPair::cast(element)->SafeGet(component);
}
}
}
if (result.type() == CALLBACKS) {
Object* obj = result.GetCallbackObject();
if (obj->IsAccessorPair()) {
- return AccessorPair::cast(obj)->get(component);
+ return AccessorPair::cast(obj)->SafeGet(component);
}
}
}
}
+Object* AccessorPair::SafeGet(AccessorComponent component) {
+ Object* accessor = get(component);
+ return accessor->IsTheHole() ? GetHeap()->undefined_value() : accessor;
+}
+
+
MaybeObject* DeoptimizationInputData::Allocate(int deopt_entry_count,
PretenureFlag pretenure) {
ASSERT(deopt_entry_count > 0);
}
}
+ // Same as get, but returns undefined instead of the hole.
+ Object* SafeGet(AccessorComponent component);
+
bool ContainsAccessor() {
return IsJSAccessor(getter()) || IsJSAccessor(setter());
}
AccessorPair::cast(dictionary->ValueAt(entry));
elms->set(IS_ACCESSOR_INDEX, heap->true_value());
if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) {
- elms->set(GETTER_INDEX, accessors->getter());
+ elms->set(GETTER_INDEX, accessors->SafeGet(ACCESSOR_GETTER));
}
if (CheckElementAccess(*obj, index, v8::ACCESS_SET)) {
- elms->set(SETTER_INDEX, accessors->setter());
+ elms->set(SETTER_INDEX, accessors->SafeGet(ACCESSOR_SETTER));
}
break;
}
AccessorPair* accessors = AccessorPair::cast(result.GetCallbackObject());
if (CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) {
- elms->set(GETTER_INDEX, accessors->getter());
+ elms->set(GETTER_INDEX, accessors->SafeGet(ACCESSOR_GETTER));
}
if (CheckAccess(*obj, *name, &result, v8::ACCESS_SET)) {
- elms->set(SETTER_INDEX, accessors->setter());
+ elms->set(SETTER_INDEX, accessors->SafeGet(ACCESSOR_SETTER));
}
} else {
elms->set(IS_ACCESSOR_INDEX, heap->false_value());
assertEquals(2, arg0);
assertEquals(3, arguments[0]);
})(0);
+
+
+// Regression test: We should never observe the hole value.
+var objectWithGetter = {};
+objectWithGetter.__defineGetter__('foo', function() {});
+assertEquals(undefined, objectWithGetter.__lookupSetter__('foo'));
+
+var objectWithSetter = {};
+objectWithSetter.__defineSetter__('foo', function(x) {});
+assertEquals(undefined, objectWithSetter.__lookupGetter__('foo'));