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

Unified Diff: src/runtime.cc

Issue 8097: Fix issue 124 by computing the receiver correctly when... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 12 years, 2 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/objects-inl.h ('k') | test/mjsunit/bugs/bug-124.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/runtime.cc
===================================================================
--- src/runtime.cc (revision 556)
+++ src/runtime.cc (working copy)
@@ -474,7 +474,7 @@
int index;
PropertyAttributes attributes;
ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
- Handle<Object> context_obj =
+ Handle<Object> holder =
context->Lookup(name, flags, &index, &attributes);
if (attributes != ABSENT) {
@@ -494,14 +494,14 @@
// The variable or constant context slot should always be in
// the function context; not in any outer context nor in the
// arguments object.
- ASSERT(context_obj.is_identical_to(context));
+ ASSERT(holder.is_identical_to(context));
if (((attributes & READ_ONLY) == 0) ||
context->get(index)->IsTheHole()) {
context->set(index, *initial_value);
}
} else {
// Slow case: The property is not in the FixedArray part of the context.
- Handle<JSObject> context_ext = Handle<JSObject>::cast(context_obj);
+ Handle<JSObject> context_ext = Handle<JSObject>::cast(holder);
SetProperty(context_ext, name, initial_value, mode);
}
}
@@ -702,7 +702,7 @@
int index;
PropertyAttributes attributes;
ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
- Handle<Object> context_obj =
+ Handle<Object> holder =
context->Lookup(name, flags, &index, &attributes);
// The property should always be present. It is always declared
@@ -714,7 +714,7 @@
if (index >= 0) {
// The constant context slot should always be in the function
// context; not in any outer context nor in the arguments object.
- ASSERT(context_obj.is_identical_to(context));
+ ASSERT(holder.is_identical_to(context));
if (context->get(index)->IsTheHole()) {
context->set(index, *value);
}
@@ -722,7 +722,7 @@
}
// Otherwise, the slot must be in a JS object extension.
- Handle<JSObject> context_ext(JSObject::cast(*context_obj));
+ Handle<JSObject> context_ext(JSObject::cast(*holder));
// We must initialize the value only if it wasn't initialized
// before, e.g. for const declarations in a loop. The property has
@@ -3301,12 +3301,12 @@
int index;
PropertyAttributes attributes;
ContextLookupFlags flags = FOLLOW_CHAINS;
- Handle<Object> context_obj =
+ Handle<Object> holder =
context->Lookup(name, flags, &index, &attributes);
- if (index < 0 && *context_obj != NULL) {
- ASSERT(context_obj->IsJSObject());
- return *context_obj;
+ if (index < 0 && *holder != NULL) {
+ ASSERT(holder->IsJSObject());
+ return *holder;
}
// No intermediate context found. Use global object by default.
@@ -3335,6 +3335,40 @@
}
+static Object* ComputeContextSlotReceiver(Object* holder) {
+ // If the "property" we were looking for is a local variable or an
+ // argument in a context, the receiver is the global object; see
+ // ECMA-262, 3rd., 10.1.6 and 10.2.3.
+ HeapObject* object = HeapObject::cast(holder);
+ Context* top = Top::context();
+ if (holder->IsContext()) return top->global()->global_receiver();
+
+ // TODO(xxx): Find a better - and faster way - of checking for
+ // arguments and context extension objects. This kinda sucks.
+ JSFunction* context_extension_function =
+ top->global_context()->context_extension_function();
+ JSObject* arguments_boilerplate =
+ top->global_context()->arguments_boilerplate();
+ JSFunction* arguments_function =
+ JSFunction::cast(arguments_boilerplate->map()->constructor());
+ // If the holder is an arguments object or a context extension then the
+ // receiver is also the global object;
+ Object* constructor = HeapObject::cast(holder)->map()->constructor();
+ if (constructor == context_extension_function ||
+ constructor == arguments_function) {
+ return Top::context()->global()->global_receiver();
+ }
+
+ // If the holder is a global object, we have to be careful to wrap
+ // it in its proxy if necessary.
+ if (object->IsGlobalObject()) {
+ return GlobalObject::cast(object)->global_receiver();
+ } else {
+ return object;
+ }
+}
+
+
static ObjPair LoadContextSlotHelper(Arguments args, bool throw_error) {
HandleScope scope;
ASSERT(args.length() == 2);
@@ -3346,34 +3380,32 @@
int index;
PropertyAttributes attributes;
ContextLookupFlags flags = FOLLOW_CHAINS;
- Handle<Object> context_obj =
+ Handle<Object> holder =
context->Lookup(name, flags, &index, &attributes);
if (index >= 0) {
- if (context_obj->IsContext()) {
- // The context is an Execution context, and the "property" we were looking
- // for is a local variable in that context. According to ECMA-262, 3rd.,
- // 10.1.6 and 10.2.3, the receiver is the global object.
- return MakePair(
- Unhole(Handle<Context>::cast(context_obj)->get(index), attributes),
- Top::context()->global());
+ Handle<Object> receiver =
+ Handle<Object>(ComputeContextSlotReceiver(*holder));
+ Handle<Object> value;
+ if (holder->IsContext()) {
+ value = Handle<Object>(Context::cast(*holder)->get(index));
} else {
- return MakePair(
- Unhole(Handle<JSObject>::cast(context_obj)->GetElement(index),
- attributes),
- *context_obj);
+ // Arguments object.
+ value = Handle<Object>(JSObject::cast(*holder)->GetElement(index));
}
+ return MakePair(Unhole(*value, attributes), *receiver);
}
- if (*context_obj != NULL) {
- ASSERT(Handle<JSObject>::cast(context_obj)->HasProperty(*name));
- // Note: As of 5/29/2008, GetProperty does the "unholing" and so this call
- // here is redundant. We left it anyway, to be explicit; also it's not clear
- // why GetProperty should do the unholing in the first place.
+ if (*holder != NULL) {
+ ASSERT(Handle<JSObject>::cast(holder)->HasProperty(*name));
+ // Note: As of 5/29/2008, GetProperty does the "unholing" and so
+ // this call here is redundant. We left it anyway, to be explicit;
+ // also it's not clear why GetProperty should do the unholing in
+ // the first place.
return MakePair(
- Unhole(Handle<JSObject>::cast(context_obj)->GetProperty(*name),
+ Unhole(Handle<JSObject>::cast(holder)->GetProperty(*name),
attributes),
- *context_obj);
+ ComputeContextSlotReceiver(*holder));
}
if (throw_error) {
@@ -3409,19 +3441,19 @@
int index;
PropertyAttributes attributes;
ContextLookupFlags flags = FOLLOW_CHAINS;
- Handle<Object> context_obj =
+ Handle<Object> holder =
context->Lookup(name, flags, &index, &attributes);
if (index >= 0) {
- if (context_obj->IsContext()) {
+ if (holder->IsContext()) {
// Ignore if read_only variable.
if ((attributes & READ_ONLY) == 0) {
- Handle<Context>::cast(context_obj)->set(index, *value);
+ Handle<Context>::cast(holder)->set(index, *value);
}
} else {
ASSERT((attributes & READ_ONLY) == 0);
Object* result =
- Handle<JSObject>::cast(context_obj)->SetElement(index, *value);
+ Handle<JSObject>::cast(holder)->SetElement(index, *value);
USE(result);
ASSERT(!result->IsFailure());
}
@@ -3432,9 +3464,9 @@
// It is either in an JSObject extension context or it was not found.
Handle<JSObject> context_ext;
- if (*context_obj != NULL) {
+ if (*holder != NULL) {
// The property exists in the extension context.
- context_ext = Handle<JSObject>::cast(context_obj);
+ context_ext = Handle<JSObject>::cast(holder);
} else {
// The property was not found. It needs to be stored in the global context.
ASSERT(attributes == ABSENT);
« no previous file with comments | « src/objects-inl.h ('k') | test/mjsunit/bugs/bug-124.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698