Commit 66f5779c authored by arv's avatar arv Committed by Commit bot

[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
R=adamk@chromium.org, verwaest@chromium.org
CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_chromium_rel_ng;tryserver.blink:linux_blink_rel

Review URL: https://codereview.chromium.org/1217603005

Cr-Commit-Position: refs/heads/master@{#29556}
parent bbb05833
......@@ -443,9 +443,18 @@ 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());
// The new function should have the same [[Prototype]] as the bindee.
Handle<Map> bound_function_map(
isolate->native_context()->bound_function_map());
PrototypeIterator iter(isolate, bindee);
Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
if (bound_function_map->prototype() != *proto) {
bound_function_map = Map::TransitionToPrototype(bound_function_map, proto,
REGULAR_PROTOTYPE);
}
JSObject::MigrateToMap(bound_function, bound_function_map);
Handle<String> length_string = isolate->factory()->length_string();
// These attributes must be kept in sync with how the bootstrapper
// configures the bound_function_map retrieved above.
......
......@@ -25,6 +25,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax
// Tests the Function.prototype.bind (ES 15.3.4.5) method.
// Simple tests.
......@@ -298,3 +300,20 @@ 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));
var bound2 = fun.bind({});
assertTrue(%HaveSameMap(new bound, new bound2));
Object.setPrototypeOf(fun, null);
bound = Function.prototype.bind.call(fun, {});
assertEquals(null, Object.getPrototypeOf(bound));
})();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment