Author: olehougaard
Date: Tue Nov 18 02:02:37 2008
New Revision: 784
Modified:
branches/bleeding_edge/src/runtime.cc
branches/bleeding_edge/src/runtime.h
branches/bleeding_edge/src/v8natives.js
branches/bleeding_edge/test/cctest/test-api.cc
Log:
Fixing wrong reference to this in eval.
Review URL: http://codereview.chromium.org/11227
Modified: branches/bleeding_edge/src/runtime.cc
==============================================================================
--- branches/bleeding_edge/src/runtime.cc (original)
+++ branches/bleeding_edge/src/runtime.cc Tue Nov 18 02:02:37 2008
@@ -3961,6 +3961,26 @@
}
+static Object* Runtime_EvalReceiver(Arguments args) {
+ ASSERT(args.length() == 1);
+ StackFrameLocator locator;
+ JavaScriptFrame* frame = locator.FindJavaScriptFrame(1);
+ // Fetch the caller context from the frame.
+ Context* caller = Context::cast(frame->context());
+
+ // Check for eval() invocations that cross environments. Use the
+ // top frames receiver if evaluating in current environment.
+ Context* global_context = Top::context()->global()->global_context();
+ if (caller->global_context() == global_context) {
+ return frame->receiver();
+ }
+
+ // Otherwise use the given argument (the global object of the
+ // receiving context).
+ return args[0];
+}
+
+
static Object* Runtime_GlobalReceiver(Arguments args) {
ASSERT(args.length() == 1);
Object* global = args[0];
Modified: branches/bleeding_edge/src/runtime.h
==============================================================================
--- branches/bleeding_edge/src/runtime.h (original)
+++ branches/bleeding_edge/src/runtime.h Tue Nov 18 02:02:37 2008
@@ -195,6 +195,7 @@
F(GlobalPrint, 1) \
\
/* Eval */ \
+ F(EvalReceiver, 1) \
F(GlobalReceiver, 1) \
\
F(SetProperty, -1 /* 3 or 4 */) \
Modified: branches/bleeding_edge/src/v8natives.js
==============================================================================
--- branches/bleeding_edge/src/v8natives.js (original)
+++ branches/bleeding_edge/src/v8natives.js Tue Nov 18 02:02:37 2008
@@ -113,7 +113,7 @@
var f = %CompileString(x, 0, true);
if (!IS_FUNCTION(f)) return f;
- return f.call(this);
+ return f.call(%EvalReceiver(this));
}
Modified: branches/bleeding_edge/test/cctest/test-api.cc
==============================================================================
--- branches/bleeding_edge/test/cctest/test-api.cc (original)
+++ branches/bleeding_edge/test/cctest/test-api.cc Tue Nov 18 02:02:37 2008
@@ -4029,8 +4029,16 @@
" var foo = 2;"
" return eval('foo');"
"})();"));
- Local<Value> foo = script->Run();
- CHECK_EQ(2, foo->Int32Value());
+ Local<Value> result = script->Run();
+ CHECK_EQ(2, result->Int32Value());
+
+ // Test that un-aliased eval has right this.
+ script =
+ Script::Compile(v8_str("function MyObject() { this.self =
eval('this'); }"
+ "var o = new MyObject();"
+ "o === o.self"));
+ result = script->Run();
+ CHECK(result->IsTrue());
}
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---