[builtins] Allow bound function / proxy add in collection ctors

Bug: chromium:804801
Change-Id: I2d54e98df09b0ed5ccfcddd0815ad162641e03d6
Reviewed-on: https://chromium-review.googlesource.com/883121
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Peter Marshall <petermarshall@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50827}
This commit is contained in:
jgruber 2018-01-24 10:06:28 +01:00 committed by Commit Bot
parent 1f7d86c187
commit c0a6e85153
2 changed files with 40 additions and 7 deletions

View File

@ -31,8 +31,7 @@ class BaseCollectionsAssembler : public CodeStubAssembler {
// Adds an entry to a collection. For Maps, properly handles extracting the
// key and value from the entry (see LoadKeyValue()).
void AddConstructorEntry(Variant variant, TNode<Context> context,
TNode<Object> collection,
TNode<JSFunction> add_function,
TNode<Object> collection, TNode<Object> add_function,
TNode<Object> key_value,
Label* if_may_have_side_effects = nullptr,
Label* if_exception = nullptr,
@ -87,7 +86,7 @@ class BaseCollectionsAssembler : public CodeStubAssembler {
// Retrieves the collection function that adds an entry. `set` for Maps and
// `add` for Sets.
TNode<JSFunction> GetAddFunction(Variant variant, TNode<Context> context,
TNode<Object> GetAddFunction(Variant variant, TNode<Context> context,
TNode<Object> collection);
// Retrieves the collection constructor function.
@ -137,7 +136,7 @@ class BaseCollectionsAssembler : public CodeStubAssembler {
void BaseCollectionsAssembler::AddConstructorEntry(
Variant variant, TNode<Context> context, TNode<Object> collection,
TNode<JSFunction> add_function, TNode<Object> key_value,
TNode<Object> add_function, TNode<Object> key_value,
Label* if_may_have_side_effects, Label* if_exception,
TVariable<Object>* var_exception) {
CSA_ASSERT(this, Word32BinaryNot(IsTheHole(key_value)));
@ -292,7 +291,7 @@ void BaseCollectionsAssembler::AddConstructorEntriesFromIterable(
Label exit(this), loop(this), if_exception(this, Label::kDeferred);
CSA_ASSERT(this, Word32BinaryNot(IsNullOrUndefined(iterable)));
TNode<JSFunction> add_func = GetAddFunction(variant, context, collection);
TNode<Object> add_func = GetAddFunction(variant, context, collection);
IteratorBuiltinsAssembler iterator_assembler(this->state());
IteratorRecord iterator = iterator_assembler.GetIterator(context, iterable);
@ -380,7 +379,7 @@ void BaseCollectionsAssembler::GenerateConstructor(
HeapConstant(constructor_function_name));
}
TNode<JSFunction> BaseCollectionsAssembler::GetAddFunction(
TNode<Object> BaseCollectionsAssembler::GetAddFunction(
Variant variant, TNode<Context> context, TNode<Object> collection) {
Handle<String> add_func_name = (variant == kMap || variant == kWeakMap)
? isolate()->factory()->set_string()

View File

@ -0,0 +1,34 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function f() { return 42; }
const bound_function = f.bind();
const callable_proxy = new Proxy(function(){}.__proto__, {});
function testSet(ctor) {
new ctor([]);
new ctor([{},{}]);
}
function testMap(ctor) {
new ctor([]);
new ctor([[{},{}],[{},{}]]);
}
function testAllVariants(set_or_add_function) {
Set.prototype.add = set_or_add_function;
testSet(Set);
WeakSet.prototype.add = set_or_add_function;
testSet(WeakSet);
Map.prototype.set = set_or_add_function;
testMap(Map);
WeakMap.prototype.set = set_or_add_function;
testMap(WeakMap);
}
testAllVariants(bound_function);
testAllVariants(callable_proxy);