Reviewers: adamk, Toon Verwaest,

Message:
PTAL

Description:
[es6] Function bind should preserve [[Prototype]]

The function returned from Function.prototype.bind should have the same
[[Prototype]] as the receiver.

BUG=v8:3889
LOG=N
[email protected], [email protected]
CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_chromium_rel_ng;tryserver.blink:linux_blink_rel

Please review this at https://codereview.chromium.org/1217603005/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+21, -2 lines):
  M src/runtime/runtime-function.cc
  M test/mjsunit/function-bind.js


Index: src/runtime/runtime-function.cc
diff --git a/src/runtime/runtime-function.cc b/src/runtime/runtime-function.cc index d644d37e42b2fff45685eb2c7604c5c68c801a3d..e7cffc1768a4a232d1c55fbe8fe13603bdded7f8 100644
--- a/src/runtime/runtime-function.cc
+++ b/src/runtime/runtime-function.cc
@@ -443,9 +443,14 @@ RUNTIME_FUNCTION(Runtime_FunctionBindArguments) {
// Update length. Have to remove the prototype first so that map migration
   // is happy about the number of fields.
   RUNTIME_ASSERT(bound_function->RemovePrototype());
-  Handle<Map> bound_function_map(
-      isolate->native_context()->bound_function_map());
+
+  // The new function should have the same [[Prototype]] as the bindee.
+  Handle<Map> bound_function_map = Map::Copy(
+ handle(isolate->native_context()->bound_function_map()), "FunctionBind");
+  PrototypeIterator iter(isolate, bindee);
+ Map::SetPrototype(bound_function_map, PrototypeIterator::GetCurrent(iter));
   JSObject::MigrateToMap(bound_function, bound_function_map);
+
   Handle<String> length_string = isolate->factory()->length_string();
   PropertyAttributes attr =
       static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
Index: test/mjsunit/function-bind.js
diff --git a/test/mjsunit/function-bind.js b/test/mjsunit/function-bind.js
index 23dacf157e6ea85064d4b69a1718c1ddcea1470e..a2efe4f034e163ffbc14cdfc5172f597ee29f94e 100644
--- a/test/mjsunit/function-bind.js
+++ b/test/mjsunit/function-bind.js
@@ -298,3 +298,17 @@ assertThrows(function() { f.arguments = 42; }, TypeError);
 // the caller is strict and the callee isn't. A bound function is built-in,
 // but not considered strict.
 (function foo() { return foo.caller; }).bind()();
+
+
+(function TestProtoIsPreserved() {
+  function fun() {}
+
+  function proto() {}
+  Object.setPrototypeOf(fun, proto);
+  var bound = fun.bind({});
+  assertEquals(proto, Object.getPrototypeOf(bound));
+
+  Object.setPrototypeOf(fun, null);
+  bound = Function.prototype.bind.call(fun, {});
+  assertEquals(null, Object.getPrototypeOf(bound));
+})();


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to