Skip to content

Commit

Permalink
[builtins] Allow bound function / proxy add in collection ctors
Browse files Browse the repository at this point in the history
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 c0a6e85
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 7 deletions.
13 changes: 6 additions & 7 deletions src/builtins/builtins-collections-gen.cc
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ class BaseCollectionsAssembler : public CodeStubAssembler {
// Adds an entry to a collection. For Maps, properly handles extracting the // Adds an entry to a collection. For Maps, properly handles extracting the
// key and value from the entry (see LoadKeyValue()). // key and value from the entry (see LoadKeyValue()).
void AddConstructorEntry(Variant variant, TNode<Context> context, void AddConstructorEntry(Variant variant, TNode<Context> context,
TNode<Object> collection, TNode<Object> collection, TNode<Object> add_function,
TNode<JSFunction> add_function,
TNode<Object> key_value, TNode<Object> key_value,
Label* if_may_have_side_effects = nullptr, Label* if_may_have_side_effects = nullptr,
Label* if_exception = nullptr, Label* if_exception = nullptr,
Expand Down Expand Up @@ -87,8 +86,8 @@ class BaseCollectionsAssembler : public CodeStubAssembler {


// Retrieves the collection function that adds an entry. `set` for Maps and // Retrieves the collection function that adds an entry. `set` for Maps and
// `add` for Sets. // `add` for Sets.
TNode<JSFunction> GetAddFunction(Variant variant, TNode<Context> context, TNode<Object> GetAddFunction(Variant variant, TNode<Context> context,
TNode<Object> collection); TNode<Object> collection);


// Retrieves the collection constructor function. // Retrieves the collection constructor function.
TNode<JSFunction> GetConstructor(Variant variant, TNode<JSFunction> GetConstructor(Variant variant,
Expand Down Expand Up @@ -137,7 +136,7 @@ class BaseCollectionsAssembler : public CodeStubAssembler {


void BaseCollectionsAssembler::AddConstructorEntry( void BaseCollectionsAssembler::AddConstructorEntry(
Variant variant, TNode<Context> context, TNode<Object> collection, 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, Label* if_may_have_side_effects, Label* if_exception,
TVariable<Object>* var_exception) { TVariable<Object>* var_exception) {
CSA_ASSERT(this, Word32BinaryNot(IsTheHole(key_value))); CSA_ASSERT(this, Word32BinaryNot(IsTheHole(key_value)));
Expand Down Expand Up @@ -292,7 +291,7 @@ void BaseCollectionsAssembler::AddConstructorEntriesFromIterable(
Label exit(this), loop(this), if_exception(this, Label::kDeferred); Label exit(this), loop(this), if_exception(this, Label::kDeferred);
CSA_ASSERT(this, Word32BinaryNot(IsNullOrUndefined(iterable))); 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()); IteratorBuiltinsAssembler iterator_assembler(this->state());
IteratorRecord iterator = iterator_assembler.GetIterator(context, iterable); IteratorRecord iterator = iterator_assembler.GetIterator(context, iterable);


Expand Down Expand Up @@ -380,7 +379,7 @@ void BaseCollectionsAssembler::GenerateConstructor(
HeapConstant(constructor_function_name)); HeapConstant(constructor_function_name));
} }


TNode<JSFunction> BaseCollectionsAssembler::GetAddFunction( TNode<Object> BaseCollectionsAssembler::GetAddFunction(
Variant variant, TNode<Context> context, TNode<Object> collection) { Variant variant, TNode<Context> context, TNode<Object> collection) {
Handle<String> add_func_name = (variant == kMap || variant == kWeakMap) Handle<String> add_func_name = (variant == kMap || variant == kWeakMap)
? isolate()->factory()->set_string() ? isolate()->factory()->set_string()
Expand Down
34 changes: 34 additions & 0 deletions test/mjsunit/regress/regress-804801.js
Original file line number Original file line Diff line number Diff line change
@@ -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.