Author: olehougaard
Date: Tue Nov 18 00:43:58 2008
New Revision: 781

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:
Changing the semantics of cross-frame eval to be compatible with Safari and  
Firefox.
Review URL: http://codereview.chromium.org/11601

Modified: branches/bleeding_edge/src/runtime.cc
==============================================================================
--- branches/bleeding_edge/src/runtime.cc       (original)
+++ branches/bleeding_edge/src/runtime.cc       Tue Nov 18 00:43:58 2008
@@ -3956,29 +3956,8 @@
    Handle<Context> target = Top::global_context();
    if (caller->global_context() == *target) return *caller;

-  // Compute a function closure that captures the calling context. We
-  // need a function that has trivial scope info, since it is only
-  // used to hold the context chain together.
-  Handle<JSFunction> closure =  
Factory::NewFunction(Factory::empty_symbol(),
-                                                     
Factory::undefined_value());
-  closure->set_context(*caller);
-
-  // Create a new adaptor context that has the target environment as
-  // the extension object. This enables the evaluated code to see both
-  // the current context with locals and everything and to see global
-  // variables declared in the target global object. Furthermore, any
-  // properties introduced with 'var' will be added to the target
-  // global object because it is the extension object.
-  Handle<Context> adaptor =
-    Factory::NewFunctionContext(Context::MIN_CONTEXT_SLOTS, closure);
-  adaptor->set_extension(target->global());
-  return *adaptor;
-}
-
-
-static Object* Runtime_EvalReceiver(Arguments args) {
-  StackFrameLocator locator;
-  return locator.FindJavaScriptFrame(1)->receiver();
+  // Otherwise, use the global context from the other environment.
+  return *target;
  }



Modified: branches/bleeding_edge/src/runtime.h
==============================================================================
--- branches/bleeding_edge/src/runtime.h        (original)
+++ branches/bleeding_edge/src/runtime.h        Tue Nov 18 00:43:58 2008
@@ -195,7 +195,6 @@
    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 00:43:58 2008
@@ -113,7 +113,7 @@
    var f = %CompileString(x, 0, true);
    if (!IS_FUNCTION(f)) return f;

-  return f.call(%EvalReceiver(this));
+  return f.call(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 00:43:58 2008
@@ -4018,6 +4018,22 @@
  }


+THREADED_TEST(Eval) {
+  v8::HandleScope scope;
+  LocalContext current;
+
+  // Test that un-aliased eval uses local context.
+  Local<Script> script =
+      Script::Compile(v8_str("foo = 0;"
+                             "(function() {"
+                             "  var foo = 2;"
+                             "  return eval('foo');"
+                             "})();"));
+  Local<Value> foo = script->Run();
+  CHECK_EQ(2, foo->Int32Value());
+}
+
+
  THREADED_TEST(CrossEval) {
    v8::HandleScope scope;
    LocalContext other;
@@ -4039,49 +4055,58 @@
    CHECK(!current->Global()->Has(v8_str("foo")));

    // Check that writing to non-existing properties introduces them in
-  // the current context.
+  // the other context.
    script =
        Script::Compile(v8_str("other.eval('na = 1234')"));
    script->Run();
-  CHECK_EQ(1234, current->Global()->Get(v8_str("na"))->Int32Value());
-  CHECK(!other->Global()->Has(v8_str("na")));
+  CHECK_EQ(1234, other->Global()->Get(v8_str("na"))->Int32Value());
+  CHECK(!current->Global()->Has(v8_str("na")));

-  // Check that variables in current context are visible in other
-  // context. This must include local variables.
+  // Check that global variables in current context are not visible in  
other
+  // context.
+  v8::TryCatch try_catch;
    script =
-      Script::Compile(v8_str("var bar = 42;"
-                                      "(function() { "
-                                      "  var baz = 87;"
-                                      "  return other.eval('bar + baz');"
-                                      "})();"));
+      Script::Compile(v8_str("var bar = 42; other.eval('bar');"));
    Local<Value> result = script->Run();
-  CHECK_EQ(42 + 87, result->Int32Value());
+  CHECK(try_catch.HasCaught());
+  try_catch.Reset();
+
+  // Check that local variables in current context are not visible in other
+  // context.
+  script =
+      Script::Compile(v8_str("(function() { "
+                             "  var baz = 87;"
+                             "  return other.eval('baz');"
+                             "})();"));
+  result = script->Run();
+  CHECK(try_catch.HasCaught());
+  try_catch.Reset();

    // Check that global variables in the other environment are visible
    // when evaluting code.
    other->Global()->Set(v8_str("bis"), v8_num(1234));
    script = Script::Compile(v8_str("other.eval('bis')"));
    CHECK_EQ(1234, script->Run()->Int32Value());
+  CHECK(!try_catch.HasCaught());

-  // Check that the 'this' pointer isn't touched as a result of
-  // calling eval across environments.
-  script =
-      Script::Compile(v8_str("var t = this; other.eval('this == t')"));
+  // Check that the 'this' pointer points to the global object evaluating
+  // code.
+  other->Global()->Set(v8_str("t"), other->Global());
+  script = Script::Compile(v8_str("other.eval('this == t')"));
    result = script->Run();
-  CHECK(result->IsBoolean());
-  CHECK(result->BooleanValue());
+  CHECK(result->IsTrue());
+  CHECK(!try_catch.HasCaught());

-  // Check that doing a cross eval works from within a global
-  // with-statement.
+  // Check that variables introduced in with-statement are not visible in
+  // other context.
    script =
-      Script::Compile(v8_str("other.y = 1;"
-                                      "with({x:2}){other.eval('x+y')}"));
+      Script::Compile(v8_str("with({x:2}){other.eval('x')}"));
    result = script->Run();
-  CHECK_EQ(3, result->Int32Value());
+  CHECK(try_catch.HasCaught());
+  try_catch.Reset();

    // Check that you cannot use 'eval.call' with another object than the
    // current global object.
-  v8::TryCatch try_catch;
    script =
        Script::Compile(v8_str("other.y = 1; eval.call(other, 'y')"));
    result = script->Run();

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to