}
+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];
var f = %CompileString(x, 0, true);
if (!IS_FUNCTION(f)) return f;
- return f.call(this);
+ return f.call(%EvalReceiver(this));
}
" 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());
}