Fix a bug in a corner case of direct eval detection.
authorkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 28 Apr 2011 05:04:48 +0000 (05:04 +0000)
committerkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 28 Apr 2011 05:04:48 +0000 (05:04 +0000)
The corner case is calling a function named 'eval' that is looked up at
runtime and found in a non-global context (but not an extension object).
The bug is that we used the function itself as the receiver rather than
using the global object.

R=ager@chromium.org
TEST=has been added to the eval mjsunit test

Review URL: http://codereview.chromium.org/6893057

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7696 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/runtime.cc
test/mjsunit/eval.js

index ff05037..42357d6 100644 (file)
@@ -8244,10 +8244,7 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) {
   if (!context->IsGlobalContext()) {
     // 'eval' is not bound in the global context. Just call the function
     // with the given arguments. This is not necessarily the global eval.
-    if (receiver->IsContext()) {
-      context = Handle<Context>::cast(receiver);
-      receiver = Handle<Object>(context->get(index), isolate);
-    } else if (receiver->IsJSContextExtensionObject()) {
+    if (receiver->IsContext() || receiver->IsJSContextExtensionObject()) {
       receiver = Handle<JSObject>(
           isolate->context()->global()->global_receiver(), isolate);
     }
index 25cfcb6..b6284ba 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -155,3 +155,12 @@ result =
     return (function() { return eval(2); })();
   })();
 assertEquals(4, result);
+
+// Regression test: calling a function named eval found in a context that is
+// not the global context should get the global object as receiver.
+result =
+    (function () {
+      var eval = function (x) { return this; };
+      with ({}) { return eval('ignore'); }
+    })();
+assertEquals(this, result);