From 27e4365abafb2bce2fdbaed0cc3b7f586660af56 Mon Sep 17 00:00:00 2001 From: olehougaard Date: Tue, 18 Nov 2008 10:02:37 +0000 Subject: [PATCH] Fixing wrong reference to this in eval. Review URL: http://codereview.chromium.org/11227 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@784 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/runtime.cc | 20 ++++++++++++++++++++ src/runtime.h | 1 + src/v8natives.js | 2 +- test/cctest/test-api.cc | 12 ++++++++++-- 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/runtime.cc b/src/runtime.cc index f2b102d..5e60c0d 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -3961,6 +3961,26 @@ static Object* EvalContext() { } +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]; diff --git a/src/runtime.h b/src/runtime.h index f0fdf1f..36a7180 100644 --- a/src/runtime.h +++ b/src/runtime.h @@ -195,6 +195,7 @@ namespace v8 { namespace internal { F(GlobalPrint, 1) \ \ /* Eval */ \ + F(EvalReceiver, 1) \ F(GlobalReceiver, 1) \ \ F(SetProperty, -1 /* 3 or 4 */) \ diff --git a/src/v8natives.js b/src/v8natives.js index 21e3c93..f3c98a5 100644 --- a/src/v8natives.js +++ b/src/v8natives.js @@ -113,7 +113,7 @@ function GlobalEval(x) { var f = %CompileString(x, 0, true); if (!IS_FUNCTION(f)) return f; - return f.call(this); + return f.call(%EvalReceiver(this)); } diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index 7fba4f3..3c91294 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -4029,8 +4029,16 @@ THREADED_TEST(Eval) { " var foo = 2;" " return eval('foo');" "})();")); - Local foo = script->Run(); - CHECK_EQ(2, foo->Int32Value()); + Local 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()); } -- 2.7.4