Fix Reflect.construct with constructors without a prototype slot

Bug: chromium:907714
Change-Id: Ie8eacff1b12ec74faa392a1d2c8545f873ab13a1
Reviewed-on: https://chromium-review.googlesource.com/c/1351023
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57866}
This commit is contained in:
Camillo Bruni 2018-11-27 11:30:15 +01:00 committed by Commit Bot
parent 3a437ce47a
commit 7a3cb59fad
2 changed files with 25 additions and 3 deletions

View File

@ -13383,6 +13383,8 @@ namespace {
bool FastInitializeDerivedMap(Isolate* isolate, Handle<JSFunction> new_target,
Handle<JSFunction> constructor,
Handle<Map> constructor_initial_map) {
// Use the default intrinsic prototype instead.
if (!new_target->has_prototype_slot()) return false;
// Check that |function|'s initial map still in sync with the |constructor|,
// otherwise we must create a new initial map for |function|.
if (new_target->has_initial_map() &&
@ -13457,9 +13459,14 @@ MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate,
Handle<Object> prototype;
if (new_target->IsJSFunction()) {
Handle<JSFunction> function = Handle<JSFunction>::cast(new_target);
// Make sure the new.target.prototype is cached.
EnsureHasInitialMap(function);
prototype = handle(function->prototype(), isolate);
if (function->has_prototype_slot()) {
// Make sure the new.target.prototype is cached.
EnsureHasInitialMap(function);
prototype = handle(function->prototype(), isolate);
} else {
// No prototype property, use the intrinsict default proto further down.
prototype = isolate->factory()->undefined_value();
}
} else {
Handle<String> prototype_string = isolate->factory()->prototype_string();
ASSIGN_RETURN_ON_EXCEPTION(

View File

@ -0,0 +1,15 @@
// 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.
// Flags: --allow-natives-syntax
function target() {};
for (let key of Object.getOwnPropertyNames(this)) {
try {
let newTarget = this[key];
let arg = target;
Reflect.construct(target, arg, newTarget);
} catch {}
}