Never let the hole escape...

Review URL: https://chromiumcodereview.appspot.com/9605042

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10951 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent d0437e78
...@@ -4694,7 +4694,7 @@ Object* JSObject::LookupAccessor(String* name, AccessorComponent component) { ...@@ -4694,7 +4694,7 @@ Object* JSObject::LookupAccessor(String* name, AccessorComponent component) {
Object* element = dictionary->ValueAt(entry); Object* element = dictionary->ValueAt(entry);
if (dictionary->DetailsAt(entry).type() == CALLBACKS && if (dictionary->DetailsAt(entry).type() == CALLBACKS &&
element->IsAccessorPair()) { element->IsAccessorPair()) {
return AccessorPair::cast(element)->get(component); return AccessorPair::cast(element)->SafeGet(component);
} }
} }
} }
...@@ -4710,7 +4710,7 @@ Object* JSObject::LookupAccessor(String* name, AccessorComponent component) { ...@@ -4710,7 +4710,7 @@ Object* JSObject::LookupAccessor(String* name, AccessorComponent component) {
if (result.type() == CALLBACKS) { if (result.type() == CALLBACKS) {
Object* obj = result.GetCallbackObject(); Object* obj = result.GetCallbackObject();
if (obj->IsAccessorPair()) { if (obj->IsAccessorPair()) {
return AccessorPair::cast(obj)->get(component); return AccessorPair::cast(obj)->SafeGet(component);
} }
} }
} }
...@@ -5947,6 +5947,12 @@ MaybeObject* AccessorPair::CopyWithoutTransitions() { ...@@ -5947,6 +5947,12 @@ MaybeObject* AccessorPair::CopyWithoutTransitions() {
} }
Object* AccessorPair::SafeGet(AccessorComponent component) {
Object* accessor = get(component);
return accessor->IsTheHole() ? GetHeap()->undefined_value() : accessor;
}
MaybeObject* DeoptimizationInputData::Allocate(int deopt_entry_count, MaybeObject* DeoptimizationInputData::Allocate(int deopt_entry_count,
PretenureFlag pretenure) { PretenureFlag pretenure) {
ASSERT(deopt_entry_count > 0); ASSERT(deopt_entry_count > 0);
......
...@@ -7944,6 +7944,9 @@ class AccessorPair: public Struct { ...@@ -7944,6 +7944,9 @@ class AccessorPair: public Struct {
} }
} }
// Same as get, but returns undefined instead of the hole.
Object* SafeGet(AccessorComponent component);
bool ContainsAccessor() { bool ContainsAccessor() {
return IsJSAccessor(getter()) || IsJSAccessor(setter()); return IsJSAccessor(getter()) || IsJSAccessor(setter());
} }
......
...@@ -1073,10 +1073,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) { ...@@ -1073,10 +1073,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) {
AccessorPair::cast(dictionary->ValueAt(entry)); AccessorPair::cast(dictionary->ValueAt(entry));
elms->set(IS_ACCESSOR_INDEX, heap->true_value()); elms->set(IS_ACCESSOR_INDEX, heap->true_value());
if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) { 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)) { if (CheckElementAccess(*obj, index, v8::ACCESS_SET)) {
elms->set(SETTER_INDEX, accessors->setter()); elms->set(SETTER_INDEX, accessors->SafeGet(ACCESSOR_SETTER));
} }
break; break;
} }
...@@ -1123,10 +1123,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) { ...@@ -1123,10 +1123,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) {
AccessorPair* accessors = AccessorPair::cast(result.GetCallbackObject()); AccessorPair* accessors = AccessorPair::cast(result.GetCallbackObject());
if (CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) { 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)) { if (CheckAccess(*obj, *name, &result, v8::ACCESS_SET)) {
elms->set(SETTER_INDEX, accessors->setter()); elms->set(SETTER_INDEX, accessors->SafeGet(ACCESSOR_SETTER));
} }
} else { } else {
elms->set(IS_ACCESSOR_INDEX, heap->false_value()); elms->set(IS_ACCESSOR_INDEX, heap->false_value());
......
...@@ -1075,3 +1075,13 @@ assertEquals(999, o[999]); ...@@ -1075,3 +1075,13 @@ assertEquals(999, o[999]);
assertEquals(2, arg0); assertEquals(2, arg0);
assertEquals(3, arguments[0]); assertEquals(3, arguments[0]);
})(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'));
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment