Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(32)

Unified Diff: src/runtime.cc

Issue 376233002: Introduce a PrototypeIterator class and use it for prototype access (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: updates Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/prototype.h ('k') | src/string-stream.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
}
}
« no previous file with comments | « src/prototype.h ('k') | src/string-stream.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698