Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index 28481383a5fbd846a6940deb9a1b08ee64dab56e..4e4e3707bf143bc0ef22216dea7af25d69dca266 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -34,6 +34,7 @@ |
#include "src/liveedit.h" |
#include "src/misc-intrinsics.h" |
#include "src/parser.h" |
+#include "src/prototype.h" |
#include "src/runtime.h" |
#include "src/runtime-profiler.h" |
#include "src/scopeinfo.h" |
@@ -1808,31 +1809,37 @@ RUNTIME_FUNCTION(Runtime_GetPrototype) { |
CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0); |
// We don't expect access checks to be needed on JSProxy objects. |
ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); |
+ PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); |
do { |
- if (obj->IsAccessCheckNeeded() && |
- !isolate->MayNamedAccess(Handle<JSObject>::cast(obj), |
- isolate->factory()->proto_string(), |
- v8::ACCESS_GET)) { |
- isolate->ReportFailedAccessCheck(Handle<JSObject>::cast(obj), |
- v8::ACCESS_GET); |
+ if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() && |
+ !isolate->MayNamedAccess( |
+ Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), |
+ isolate->factory()->proto_string(), v8::ACCESS_GET)) { |
+ isolate->ReportFailedAccessCheck( |
+ Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), |
+ v8::ACCESS_GET); |
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
return isolate->heap()->undefined_value(); |
} |
- obj = Object::GetPrototype(isolate, obj); |
- } while (obj->IsJSObject() && |
- JSObject::cast(*obj)->map()->is_hidden_prototype()); |
- return *obj; |
+ iter.AdvanceIgnoringProxies(); |
+ if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { |
+ return *PrototypeIterator::GetCurrent(iter); |
+ } |
+ } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)); |
+ return *PrototypeIterator::GetCurrent(iter); |
} |
static inline Handle<Object> GetPrototypeSkipHiddenPrototypes( |
Isolate* isolate, Handle<Object> receiver) { |
- Handle<Object> current = Object::GetPrototype(isolate, receiver); |
- while (current->IsJSObject() && |
- JSObject::cast(*current)->map()->is_hidden_prototype()) { |
- current = Object::GetPrototype(isolate, current); |
+ PrototypeIterator iter(isolate, receiver); |
+ while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) { |
+ if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { |
+ return PrototypeIterator::GetCurrent(iter); |
+ } |
+ iter.Advance(); |
} |
- return current; |
+ return PrototypeIterator::GetCurrent(iter); |
} |
@@ -1877,11 +1884,11 @@ RUNTIME_FUNCTION(Runtime_IsInPrototypeChain) { |
// See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8). |
CONVERT_ARG_HANDLE_CHECKED(Object, O, 0); |
CONVERT_ARG_HANDLE_CHECKED(Object, V, 1); |
+ PrototypeIterator iter(isolate, V, PrototypeIterator::START_AT_RECEIVER); |
while (true) { |
- Handle<Object> prototype = Object::GetPrototype(isolate, V); |
- if (prototype->IsNull()) return isolate->heap()->false_value(); |
- if (*O == *prototype) return isolate->heap()->true_value(); |
- V = prototype; |
+ iter.AdvanceIgnoringProxies(); |
+ if (iter.IsAtEnd()) return isolate->heap()->false_value(); |
+ if (iter.IsAtEnd(O)) return isolate->heap()->true_value(); |
} |
} |
@@ -4803,8 +4810,9 @@ MaybeHandle<Object> Runtime::GetElementOrCharAt(Isolate* isolate, |
Handle<Object> result; |
if (object->IsString() || object->IsNumber() || object->IsBoolean()) { |
- Handle<Object> proto(object->GetPrototype(isolate), isolate); |
- return Object::GetElement(isolate, proto, index); |
+ PrototypeIterator iter(isolate, object); |
+ return Object::GetElement(isolate, PrototypeIterator::GetCurrent(iter), |
+ index); |
} else { |
return Object::GetElement(isolate, object, index); |
} |
@@ -10685,15 +10693,18 @@ RUNTIME_FUNCTION(Runtime_GetArrayKeys) { |
CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); |
if (array->elements()->IsDictionary()) { |
Handle<FixedArray> keys = isolate->factory()->empty_fixed_array(); |
- for (Handle<Object> p = array; |
- !p->IsNull(); |
- p = Handle<Object>(p->GetPrototype(isolate), isolate)) { |
- if (p->IsJSProxy() || JSObject::cast(*p)->HasIndexedInterceptor()) { |
+ for (PrototypeIterator iter(isolate, array, |
+ PrototypeIterator::START_AT_RECEIVER); |
+ !iter.IsAtEnd(); iter.Advance()) { |
+ if (PrototypeIterator::GetCurrent(iter)->IsJSProxy() || |
+ JSObject::cast(*PrototypeIterator::GetCurrent(iter)) |
+ ->HasIndexedInterceptor()) { |
// Bail out if we find a proxy or interceptor, likely not worth |
// collecting keys in that case. |
return *isolate->factory()->NewNumberFromUint(length); |
} |
- Handle<JSObject> current = Handle<JSObject>::cast(p); |
+ Handle<JSObject> current = |
+ Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |
Handle<FixedArray> current_keys = |
isolate->factory()->NewFixedArray(current->NumberOfOwnElements(NONE)); |
current->GetOwnElementKeys(*current_keys, NONE); |
@@ -12856,7 +12867,9 @@ static MaybeHandle<Object> DebugEvaluate(Isolate* isolate, |
// Skip the global proxy as it has no properties and always delegates to the |
// real global object. |
if (result->IsJSGlobalProxy()) { |
- result = Handle<JSObject>(JSObject::cast(result->GetPrototype(isolate))); |
+ PrototypeIterator iter(isolate, result); |
+ // TODO(verwaest): This will crash when the global proxy is detached. |
+ result = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |
} |
// Clear the oneshot breakpoints so that the debugger does not step further. |
@@ -13032,17 +13045,12 @@ static int DebugReferencedBy(HeapIterator* iterator, |
// Check instance filter if supplied. This is normally used to avoid |
// references from mirror objects (see Runtime_IsInPrototypeChain). |
if (!instance_filter->IsUndefined()) { |
- Object* V = obj; |
- while (true) { |
- Object* prototype = V->GetPrototype(isolate); |
- if (prototype->IsNull()) { |
- break; |
- } |
- if (instance_filter == prototype) { |
+ for (PrototypeIterator iter(isolate, obj); !iter.IsAtEnd(); |
+ iter.Advance()) { |
+ if (iter.GetCurrent() == instance_filter) { |
obj = NULL; // Don't add this object. |
break; |
} |
- V = prototype; |
} |
} |