Fix for .bind regression.
authorrossberg@chromium.org <rossberg@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 13 Sep 2011 17:14:39 +0000 (17:14 +0000)
committerrossberg@chromium.org <rossberg@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 13 Sep 2011 17:14:39 +0000 (17:14 +0000)
R=jkummerow@chromium.org
BUG=
TEST=

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

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

src/execution.cc
test/mjsunit/regress/regress-bind-receiver.js [new file with mode: 0644]

index cdea005..7ad2dc0 100644 (file)
@@ -161,10 +161,11 @@ Handle<Object> Execution::Call(Handle<Object> callable,
   if (convert_receiver && !receiver->IsJSReceiver() &&
       !func->shared()->native() && !func->shared()->strict_mode()) {
     if (receiver->IsUndefined() || receiver->IsNull()) {
-      // Careful, func->context()->global()->global_receiver() gives
-      // the JSBuiltinsObject if func is a builtin. Not what we want here.
-      receiver =
-          Handle<Object>(func->GetIsolate()->global()->global_receiver());
+      Object* global = func->context()->global()->global_receiver();
+      // For reasons that escape me, 'global' can be the JSBuiltinsObject
+      // under some circumstances.  In that case, don't rewrite.
+      // FWIW, the same holds for GetIsolate()->global()->global_receiver().
+      if (!global->IsJSBuiltinsObject()) receiver = Handle<Object>(global);
     } else {
       receiver = ToObject(receiver, pending_exception);
     }
diff --git a/test/mjsunit/regress/regress-bind-receiver.js b/test/mjsunit/regress/regress-bind-receiver.js
new file mode 100644 (file)
index 0000000..19756da
--- /dev/null
@@ -0,0 +1,17 @@
+function strict() { 'use strict'; return this; }
+function lenient() { return this; }
+var obj = {};
+       
+assertEquals(true, strict.bind(true)());
+assertEquals(42, strict.bind(42)());
+assertEquals("", strict.bind("")());
+assertEquals(null, strict.bind(null)()l);
+assertEquals(undefined, strict.bind(undefined)());
+assertEquals(obj, strict.bind(obj)());
+
+assertEquals(true, lenient.bind(true)() instanceof Boolean);
+assertEquals(true, lenient.bind(42)() instanceof Number);
+assertEquals(true, lenient.bind("")() instanceof String);
+assertEquals(this, lenient.bind(null)());
+assertEquals(this, lenient.bind(undefined)());
+assertEquals(obj, lenient.bind(obj)());