Skip to content
Permalink
Browse files

[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}
  • Loading branch information...
schuay authored and Commit Bot committed Jan 24, 2018
1 parent 1f7d86c commit c0a6e85153f148f051b6e3d90de8a3f1bf59fc69
Showing with 40 additions and 7 deletions.
  1. +6 −7 src/builtins/builtins-collections-gen.cc
  2. +34 −0 test/mjsunit/regress/regress-804801.js
@@ -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,8 +86,8 @@ 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> collection);
TNode<Object> GetAddFunction(Variant variant, TNode<Context> context,
TNode<Object> collection);

// Retrieves the collection constructor function.
TNode<JSFunction> GetConstructor(Variant variant,
@@ -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()
@@ -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);

0 comments on commit c0a6e85

Please sign in to comment.
You can’t perform that action at this time.