diff --git a/src/builtins/builtins-promise-gen.cc b/src/builtins/builtins-promise-gen.cc index b1412eb7cd5..1b236ec97c6 100644 --- a/src/builtins/builtins-promise-gen.cc +++ b/src/builtins/builtins-promise-gen.cc @@ -106,6 +106,10 @@ Node* PromiseBuiltinsAssembler::NewPromiseCapability(Node* context, debug_event = TrueConstant(); } + Label if_not_constructor(this, Label::kDeferred); + GotoIf(TaggedIsSmi(constructor), &if_not_constructor); + GotoIfNot(IsConstructorMap(LoadMap(constructor)), &if_not_constructor); + Node* native_context = LoadNativeContext(context); Node* map = LoadRoot(Heap::kJSPromiseCapabilityMapRootIndex); @@ -189,6 +193,13 @@ Node* PromiseBuiltinsAssembler::NewPromiseCapability(Node* context, Unreachable(); } + BIND(&if_not_constructor); + { + Node* const message_id = SmiConstant(MessageTemplate::kNotConstructor); + CallRuntime(Runtime::kThrowTypeError, context, message_id, constructor); + Unreachable(); + } + BIND(&out); return var_result.value(); } @@ -312,6 +323,7 @@ Node* PromiseBuiltinsAssembler::SpeciesConstructor(Node* context, Node* object, // 7. If IsConstructor(S) is true, return S. Label throw_error(this); + GotoIf(TaggedIsSmi(species), &throw_error); Node* species_bitfield = LoadMapBitField(LoadMap(species)); GotoIfNot(Word32Equal(Word32And(species_bitfield, Int32Constant((1 << Map::kIsConstructor))), diff --git a/test/mjsunit/regress/regress-726636.js b/test/mjsunit/regress/regress-726636.js new file mode 100644 index 00000000000..843cfdf8834 --- /dev/null +++ b/test/mjsunit/regress/regress-726636.js @@ -0,0 +1,14 @@ +// Copyright 2017 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. +// +// Flags: --allow-natives-syntax + +Object.defineProperty(Promise, Symbol.species, { value: 0 }); +var p = new Promise(function() {}); +try { + p.then(); + assertUnreachable(); +} catch(e) { + assertTrue(e instanceof TypeError); +}