[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:
parent
1f7d86c187
commit
c0a6e85153
@ -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()
|
||||
|
34
test/mjsunit/regress/regress-804801.js
Normal file
34
test/mjsunit/regress/regress-804801.js
Normal 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);
|
Loading…
Reference in New Issue
Block a user