Remove experiment for restricting constructor return values

This is not web compatible, so let's delete the code.

Bug: v8:5536
Change-Id: I50506d37dcdff1f7f95577c47adcec653cc1f06e
Reviewed-on: https://chromium-review.googlesource.com/1064740
Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53264}
This commit is contained in:
Sathya Gunasekaran 2018-05-18 11:56:34 -07:00 committed by Commit Bot
parent 0300caa502
commit 813094ac8c
23 changed files with 64 additions and 703 deletions

View File

@ -4180,7 +4180,6 @@ EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_static_fields)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_class_fields)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_dynamic_import)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_import_meta)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_restrict_constructor_return)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_optional_catch_binding)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_subsume_json)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_numeric_separator)

View File

@ -249,9 +249,10 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
__ Jump(lr);
}
} // namespace
// The construct stub for ES5 constructor functions and ES6 class constructors.
void Generate_JSConstructStubGeneric(MacroAssembler* masm,
bool restrict_constructor_return) {
void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r0: number of arguments (untagged)
// -- r1: constructor function
@ -379,7 +380,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
// If the result is an object (in the ECMA sense), we should get rid
// of the receiver and use the result; see ECMA-262 section 13.2.2-7
// on page 74.
Label use_receiver, do_throw, other_result, leave_frame;
Label use_receiver, do_throw, leave_frame;
// If the result is undefined, we jump out to using the implicit receiver.
__ JumpIfRoot(r0, Heap::kUndefinedValueRootIndex, &use_receiver);
@ -388,30 +389,14 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
// is a valid receiver.
// If the result is a smi, it is *not* an object in the ECMA sense.
__ JumpIfSmi(r0, &other_result);
__ JumpIfSmi(r0, &use_receiver);
// If the type of the result (stored in its map) is less than
// FIRST_JS_RECEIVER_TYPE, it is not an object in the ECMA sense.
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
__ CompareObjectType(r0, r4, r5, FIRST_JS_RECEIVER_TYPE);
__ b(ge, &leave_frame);
// The result is now neither undefined nor an object.
__ bind(&other_result);
__ ldr(r4, MemOperand(fp, ConstructFrameConstants::kConstructorOffset));
__ ldr(r4, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
__ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kFlagsOffset));
__ tst(r4, Operand(SharedFunctionInfo::IsClassConstructorBit::kMask));
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
__ b(eq, &use_receiver);
} else {
__ b(ne, &use_receiver);
__ CallRuntime(
Runtime::kIncrementUseCounterConstructorReturnNonUndefinedPrimitive);
__ b(&use_receiver);
}
__ b(&use_receiver);
__ bind(&do_throw);
__ CallRuntime(Runtime::kThrowConstructorReturnedNonObject);
@ -433,16 +418,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ add(sp, sp, Operand(kPointerSize));
__ Jump(lr);
}
} // namespace
void Builtins::Generate_JSConstructStubGenericRestrictedReturn(
MacroAssembler* masm) {
Generate_JSConstructStubGeneric(masm, true);
}
void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn(
MacroAssembler* masm) {
Generate_JSConstructStubGeneric(masm, false);
}
void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
Generate_JSBuiltinsConstructStubHelper(masm);
}
@ -2321,7 +2297,7 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
RelocInfo::CODE_TARGET);
__ bind(&call_generic_stub);
__ Jump(masm->isolate()->builtins()->JSConstructStubGeneric(),
__ Jump(BUILTIN_CODE(masm->isolate(), JSConstructStubGeneric),
RelocInfo::CODE_TARGET);
}

View File

@ -276,9 +276,10 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
__ Ret();
}
} // namespace
// The construct stub for ES5 constructor functions and ES6 class constructors.
void Generate_JSConstructStubGeneric(MacroAssembler* masm,
bool restrict_constructor_return) {
void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- x0 : number of arguments
// -- x1 : constructor function
@ -420,7 +421,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
// If the result is an object (in the ECMA sense), we should get rid
// of the receiver and use the result; see ECMA-262 section 13.2.2-7
// on page 74.
Label use_receiver, do_throw, other_result, leave_frame;
Label use_receiver, do_throw, leave_frame;
// If the result is undefined, we jump out to using the implicit receiver.
__ CompareRoot(x0, Heap::kUndefinedValueRootIndex);
@ -430,30 +431,13 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
// is a valid receiver.
// If the result is a smi, it is *not* an object in the ECMA sense.
__ JumpIfSmi(x0, &other_result);
__ JumpIfSmi(x0, &use_receiver);
// If the type of the result (stored in its map) is less than
// FIRST_JS_RECEIVER_TYPE, it is not an object in the ECMA sense.
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
__ JumpIfObjectType(x0, x4, x5, FIRST_JS_RECEIVER_TYPE, &leave_frame, ge);
// The result is now neither undefined nor an object.
__ Bind(&other_result);
__ Ldr(x4, MemOperand(fp, ConstructFrameConstants::kConstructorOffset));
__ Ldr(x4, FieldMemOperand(x4, JSFunction::kSharedFunctionInfoOffset));
__ Ldr(w4, FieldMemOperand(x4, SharedFunctionInfo::kFlagsOffset));
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
__ TestAndBranchIfAllClear(
w4, SharedFunctionInfo::IsClassConstructorBit::kMask, &use_receiver);
} else {
__ TestAndBranchIfAnySet(
w4, SharedFunctionInfo::IsClassConstructorBit::kMask, &use_receiver);
__ CallRuntime(
Runtime::kIncrementUseCounterConstructorReturnNonUndefinedPrimitive);
__ B(&use_receiver);
}
__ B(&use_receiver);
__ Bind(&do_throw);
__ CallRuntime(Runtime::kThrowConstructorReturnedNonObject);
@ -475,16 +459,6 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ DropArguments(x1, TurboAssembler::kCountExcludesReceiver);
__ Ret();
}
} // namespace
void Builtins::Generate_JSConstructStubGenericRestrictedReturn(
MacroAssembler* masm) {
Generate_JSConstructStubGeneric(masm, true);
}
void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn(
MacroAssembler* masm) {
Generate_JSConstructStubGeneric(masm, false);
}
void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
Generate_JSBuiltinsConstructStubHelper(masm);
}
@ -2714,7 +2688,7 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
RelocInfo::CODE_TARGET);
__ bind(&call_generic_stub);
__ Jump(masm->isolate()->builtins()->JSConstructStubGeneric(),
__ Jump(BUILTIN_CODE(masm->isolate(), JSConstructStubGeneric),
RelocInfo::CODE_TARGET);
}

View File

@ -68,8 +68,7 @@ namespace internal {
TFC(ConstructWithArrayLike, ConstructWithArrayLike, 1) \
ASM(ConstructForwardVarargs) \
ASM(ConstructFunctionForwardVarargs) \
ASM(JSConstructStubGenericRestrictedReturn) \
ASM(JSConstructStubGenericUnrestrictedReturn) \
ASM(JSConstructStubGeneric) \
ASM(JSBuiltinsConstructStub) \
TFC(FastNewObject, FastNewObject, 1) \
TFS(FastNewClosure, kSharedFunctionInfo, kFeedbackCell) \

View File

@ -375,12 +375,6 @@ bool Builtins::HasCppImplementation(int index) {
return (kind == CPP || kind == API);
}
Handle<Code> Builtins::JSConstructStubGeneric() {
return FLAG_harmony_restrict_constructor_return
? builtin_handle(kJSConstructStubGenericRestrictedReturn)
: builtin_handle(kJSConstructStubGenericUnrestrictedReturn);
}
// static
bool Builtins::AllowDynamicFunction(Isolate* isolate, Handle<JSFunction> target,
Handle<JSObject> target_global_proxy) {

View File

@ -186,9 +186,10 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
__ ret(0);
}
} // namespace
// The construct stub for ES5 constructor functions and ES6 class constructors.
void Generate_JSConstructStubGeneric(MacroAssembler* masm,
bool restrict_constructor_return) {
void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- eax: number of arguments (untagged)
// -- edi: constructor function
@ -319,7 +320,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
// If the result is an object (in the ECMA sense), we should get rid
// of the receiver and use the result; see ECMA-262 section 13.2.2-7
// on page 74.
Label use_receiver, do_throw, other_result, leave_frame;
Label use_receiver, do_throw, leave_frame;
// If the result is undefined, we jump out to using the implicit receiver.
__ JumpIfRoot(eax, Heap::kUndefinedValueRootIndex, &use_receiver,
@ -329,30 +330,14 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
// is a valid receiver.
// If the result is a smi, it is *not* an object in the ECMA sense.
__ JumpIfSmi(eax, &other_result, Label::kNear);
__ JumpIfSmi(eax, &use_receiver, Label::kNear);
// If the type of the result (stored in its map) is less than
// FIRST_JS_RECEIVER_TYPE, it is not an object in the ECMA sense.
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
__ CmpObjectType(eax, FIRST_JS_RECEIVER_TYPE, ecx);
__ j(above_equal, &leave_frame, Label::kNear);
// The result is now neither undefined nor an object.
__ bind(&other_result);
__ mov(ebx, Operand(ebp, ConstructFrameConstants::kConstructorOffset));
__ mov(ebx, FieldOperand(ebx, JSFunction::kSharedFunctionInfoOffset));
__ test(FieldOperand(ebx, SharedFunctionInfo::kFlagsOffset),
Immediate(SharedFunctionInfo::IsClassConstructorBit::kMask));
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
__ j(Condition::zero, &use_receiver, Label::kNear);
} else {
__ j(not_zero, &use_receiver, Label::kNear);
__ CallRuntime(
Runtime::kIncrementUseCounterConstructorReturnNonUndefinedPrimitive);
__ jmp(&use_receiver, Label::kNear);
}
__ jmp(&use_receiver, Label::kNear);
__ bind(&do_throw);
__ CallRuntime(Runtime::kThrowConstructorReturnedNonObject);
@ -375,16 +360,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ push(ecx);
__ ret(0);
}
} // namespace
void Builtins::Generate_JSConstructStubGenericRestrictedReturn(
MacroAssembler* masm) {
return Generate_JSConstructStubGeneric(masm, true);
}
void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn(
MacroAssembler* masm) {
return Generate_JSConstructStubGeneric(masm, false);
}
void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
Generate_JSBuiltinsConstructStubHelper(masm);
}
@ -2465,7 +2441,7 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
RelocInfo::CODE_TARGET);
__ bind(&call_generic_stub);
__ Jump(masm->isolate()->builtins()->JSConstructStubGeneric(),
__ Jump(BUILTIN_CODE(masm->isolate(), JSConstructStubGeneric),
RelocInfo::CODE_TARGET);
}

View File

@ -240,9 +240,10 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
__ Ret();
}
} // namespace
// The construct stub for ES5 constructor functions and ES6 class constructors.
void Generate_JSConstructStubGeneric(MacroAssembler* masm,
bool restrict_constructor_return) {
void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- a0: number of arguments (untagged)
// -- a1: constructor function
@ -372,7 +373,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
// If the result is an object (in the ECMA sense), we should get rid
// of the receiver and use the result; see ECMA-262 section 13.2.2-7
// on page 74.
Label use_receiver, do_throw, other_result, leave_frame;
Label use_receiver, do_throw, leave_frame;
// If the result is undefined, we jump out to using the implicit receiver.
__ JumpIfRoot(v0, Heap::kUndefinedValueRootIndex, &use_receiver);
@ -381,30 +382,14 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
// is a valid receiver.
// If the result is a smi, it is *not* an object in the ECMA sense.
__ JumpIfSmi(v0, &other_result);
__ JumpIfSmi(v0, &use_receiver);
// If the type of the result (stored in its map) is less than
// FIRST_JS_RECEIVER_TYPE, it is not an object in the ECMA sense.
__ GetObjectType(v0, t2, t2);
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
__ Branch(&leave_frame, greater_equal, t2, Operand(FIRST_JS_RECEIVER_TYPE));
// The result is now neither undefined nor an object.
__ bind(&other_result);
__ lw(a1, MemOperand(fp, ConstructFrameConstants::kConstructorOffset));
__ lw(t2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ lw(t2, FieldMemOperand(t2, SharedFunctionInfo::kFlagsOffset));
__ And(t2, t2, Operand(SharedFunctionInfo::IsClassConstructorBit::kMask));
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
__ Branch(&use_receiver, eq, t2, Operand(zero_reg));
} else {
__ Branch(&use_receiver, ne, t2, Operand(zero_reg));
__ CallRuntime(
Runtime::kIncrementUseCounterConstructorReturnNonUndefinedPrimitive);
__ Branch(&use_receiver);
}
__ Branch(&use_receiver);
__ bind(&do_throw);
__ CallRuntime(Runtime::kThrowConstructorReturnedNonObject);
@ -426,16 +411,6 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ Ret();
}
} // namespace
void Builtins::Generate_JSConstructStubGenericRestrictedReturn(
MacroAssembler* masm) {
Generate_JSConstructStubGeneric(masm, true);
}
void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn(
MacroAssembler* masm) {
Generate_JSConstructStubGeneric(masm, false);
}
void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
Generate_JSBuiltinsConstructStubHelper(masm);
}
@ -2312,7 +2287,7 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
RelocInfo::CODE_TARGET);
__ bind(&call_generic_stub);
__ Jump(masm->isolate()->builtins()->JSConstructStubGeneric(),
__ Jump(BUILTIN_CODE(masm->isolate(), JSConstructStubGeneric),
RelocInfo::CODE_TARGET);
}

View File

@ -240,9 +240,10 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
__ Ret();
}
} // namespace
// The construct stub for ES5 constructor functions and ES6 class constructors.
void Generate_JSConstructStubGeneric(MacroAssembler* masm,
bool restrict_constructor_return) {
void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- a0: number of arguments (untagged)
// -- a1: constructor function
@ -372,7 +373,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
// If the result is an object (in the ECMA sense), we should get rid
// of the receiver and use the result; see ECMA-262 section 13.2.2-7
// on page 74.
Label use_receiver, do_throw, other_result, leave_frame;
Label use_receiver, do_throw, leave_frame;
// If the result is undefined, we jump out to using the implicit receiver.
__ JumpIfRoot(v0, Heap::kUndefinedValueRootIndex, &use_receiver);
@ -381,30 +382,14 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
// is a valid receiver.
// If the result is a smi, it is *not* an object in the ECMA sense.
__ JumpIfSmi(v0, &other_result);
__ JumpIfSmi(v0, &use_receiver);
// If the type of the result (stored in its map) is less than
// FIRST_JS_RECEIVER_TYPE, it is not an object in the ECMA sense.
__ GetObjectType(v0, t2, t2);
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
__ Branch(&leave_frame, greater_equal, t2, Operand(FIRST_JS_RECEIVER_TYPE));
// The result is now neither undefined nor an object.
__ bind(&other_result);
__ Ld(a1, MemOperand(fp, ConstructFrameConstants::kConstructorOffset));
__ Ld(t2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ lwu(t2, FieldMemOperand(t2, SharedFunctionInfo::kFlagsOffset));
__ And(t2, t2, Operand(SharedFunctionInfo::IsClassConstructorBit::kMask));
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
__ Branch(&use_receiver, eq, t2, Operand(zero_reg));
} else {
__ Branch(&use_receiver, ne, t2, Operand(zero_reg));
__ CallRuntime(
Runtime::kIncrementUseCounterConstructorReturnNonUndefinedPrimitive);
__ Branch(&use_receiver);
}
__ Branch(&use_receiver);
__ bind(&do_throw);
__ CallRuntime(Runtime::kThrowConstructorReturnedNonObject);
@ -427,16 +412,6 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ Ret();
}
} // namespace
void Builtins::Generate_JSConstructStubGenericRestrictedReturn(
MacroAssembler* masm) {
Generate_JSConstructStubGeneric(masm, true);
}
void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn(
MacroAssembler* masm) {
Generate_JSConstructStubGeneric(masm, false);
}
void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
Generate_JSBuiltinsConstructStubHelper(masm);
}
@ -2331,7 +2306,7 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
RelocInfo::CODE_TARGET);
__ bind(&call_generic_stub);
__ Jump(masm->isolate()->builtins()->JSConstructStubGeneric(),
__ Jump(BUILTIN_CODE(masm->isolate(), JSConstructStubGeneric),
RelocInfo::CODE_TARGET);
}

View File

@ -246,9 +246,10 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
__ blr();
}
} // namespace
// The construct stub for ES5 constructor functions and ES6 class constructors.
void Generate_JSConstructStubGeneric(MacroAssembler* masm,
bool restrict_constructor_return) {
void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r3: number of arguments (untagged)
// -- r4: constructor function
@ -382,7 +383,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
// If the result is an object (in the ECMA sense), we should get rid
// of the receiver and use the result; see ECMA-262 section 13.2.2-7
// on page 74.
Label use_receiver, do_throw, other_result, leave_frame;
Label use_receiver, do_throw, leave_frame;
// If the result is undefined, we jump out to using the implicit receiver.
__ JumpIfRoot(r3, Heap::kUndefinedValueRootIndex, &use_receiver);
@ -391,27 +392,14 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
// is a valid receiver.
// If the result is a smi, it is *not* an object in the ECMA sense.
__ JumpIfSmi(r3, &other_result);
__ JumpIfSmi(r3, &use_receiver);
// If the type of the result (stored in its map) is less than
// FIRST_JS_RECEIVER_TYPE, it is not an object in the ECMA sense.
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
__ CompareObjectType(r3, r7, r7, FIRST_JS_RECEIVER_TYPE);
__ bge(&leave_frame);
__ bind(&other_result);
// The result is now neither undefined nor an object.
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
__ LoadP(r7, MemOperand(fp, ConstructFrameConstants::kConstructorOffset));
__ LoadP(r7, FieldMemOperand(r7, JSFunction::kSharedFunctionInfoOffset));
__ lwz(r7, FieldMemOperand(r7, SharedFunctionInfo::kFlagsOffset));
__ TestBitMask(r7, SharedFunctionInfo::IsClassConstructorBit::kMask, r0);
__ beq(&use_receiver, cr0);
} else {
__ b(&use_receiver);
}
__ b(&use_receiver);
__ bind(&do_throw);
__ CallRuntime(Runtime::kThrowConstructorReturnedNonObject);
@ -437,16 +425,6 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ blr();
}
} // namespace
void Builtins::Generate_JSConstructStubGenericRestrictedReturn(
MacroAssembler* masm) {
Generate_JSConstructStubGeneric(masm, true);
}
void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn(
MacroAssembler* masm) {
Generate_JSConstructStubGeneric(masm, false);
}
void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
Generate_JSBuiltinsConstructStubHelper(masm);
}
@ -2396,7 +2374,7 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
RelocInfo::CODE_TARGET);
__ bind(&call_generic_stub);
__ Jump(masm->isolate()->builtins()->JSConstructStubGeneric(),
__ Jump(BUILTIN_CODE(masm->isolate(), JSConstructStubGeneric),
RelocInfo::CODE_TARGET);
}

View File

@ -190,10 +190,10 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
__ ret(0);
}
} // namespace
// The construct stub for ES5 constructor functions and ES6 class constructors.
void Generate_JSConstructStubGeneric(MacroAssembler* masm,
bool restrict_constructor_return) {
void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- rax: number of arguments (untagged)
// -- rdi: constructor function
@ -322,7 +322,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
// If the result is an object (in the ECMA sense), we should get rid
// of the receiver and use the result; see ECMA-262 section 13.2.2-7
// on page 74.
Label use_receiver, do_throw, other_result, leave_frame;
Label use_receiver, do_throw, leave_frame;
// If the result is undefined, we jump out to using the implicit receiver.
__ JumpIfRoot(rax, Heap::kUndefinedValueRootIndex, &use_receiver,
@ -332,30 +332,14 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
// is a valid receiver.
// If the result is a smi, it is *not* an object in the ECMA sense.
__ JumpIfSmi(rax, &other_result, Label::kNear);
__ JumpIfSmi(rax, &use_receiver, Label::kNear);
// If the type of the result (stored in its map) is less than
// FIRST_JS_RECEIVER_TYPE, it is not an object in the ECMA sense.
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
__ CmpObjectType(rax, FIRST_JS_RECEIVER_TYPE, rcx);
__ j(above_equal, &leave_frame, Label::kNear);
// The result is now neither undefined nor an object.
__ bind(&other_result);
__ movp(rbx, Operand(rbp, ConstructFrameConstants::kConstructorOffset));
__ movp(rbx, FieldOperand(rbx, JSFunction::kSharedFunctionInfoOffset));
__ testl(FieldOperand(rbx, SharedFunctionInfo::kFlagsOffset),
Immediate(SharedFunctionInfo::IsClassConstructorBit::kMask));
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
__ j(Condition::zero, &use_receiver, Label::kNear);
} else {
__ j(not_zero, &use_receiver, Label::kNear);
__ CallRuntime(
Runtime::kIncrementUseCounterConstructorReturnNonUndefinedPrimitive);
__ jmp(&use_receiver, Label::kNear);
}
__ jmp(&use_receiver, Label::kNear);
__ bind(&do_throw);
__ CallRuntime(Runtime::kThrowConstructorReturnedNonObject);
@ -378,16 +362,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ PushReturnAddressFrom(rcx);
__ ret(0);
}
} // namespace
void Builtins::Generate_JSConstructStubGenericRestrictedReturn(
MacroAssembler* masm) {
return Generate_JSConstructStubGeneric(masm, true);
}
void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn(
MacroAssembler* masm) {
return Generate_JSConstructStubGeneric(masm, false);
}
void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
Generate_JSBuiltinsConstructStubHelper(masm);
}
@ -2567,7 +2542,7 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
__ Jump(BUILTIN_CODE(masm->isolate(), JSBuiltinsConstructStub),
RelocInfo::CODE_TARGET, not_zero);
__ Jump(masm->isolate()->builtins()->JSConstructStubGeneric(),
__ Jump(BUILTIN_CODE(masm->isolate(), JSConstructStubGeneric),
RelocInfo::CODE_TARGET);
}

View File

@ -548,62 +548,18 @@ Reduction JSInliner::ReduceJSCall(Node* node) {
uncaught_subcalls.push_back(create); // Adds {IfSuccess} & {IfException}.
NodeProperties::ReplaceControlInput(node, create);
NodeProperties::ReplaceEffectInput(node, create);
Node* node_success =
NodeProperties::FindSuccessfulControlProjection(node);
// Placeholder to hold {node}'s value dependencies while {node} is
// replaced.
Node* dummy = graph()->NewNode(common()->Dead());
NodeProperties::ReplaceUses(node, dummy, node, node, node);
Node* result;
if (FLAG_harmony_restrict_constructor_return &&
IsClassConstructor(shared_info->kind())) {
Node* is_undefined =
graph()->NewNode(simplified()->ReferenceEqual(), node,
jsgraph()->UndefinedConstant());
Node* branch_is_undefined =
graph()->NewNode(common()->Branch(), is_undefined, node_success);
Node* branch_is_undefined_true =
graph()->NewNode(common()->IfTrue(), branch_is_undefined);
Node* branch_is_undefined_false =
graph()->NewNode(common()->IfFalse(), branch_is_undefined);
Node* is_receiver =
graph()->NewNode(simplified()->ObjectIsReceiver(), node);
Node* branch_is_receiver = graph()->NewNode(
common()->Branch(), is_receiver, branch_is_undefined_false);
Node* branch_is_receiver_true =
graph()->NewNode(common()->IfTrue(), branch_is_receiver);
Node* branch_is_receiver_false =
graph()->NewNode(common()->IfFalse(), branch_is_receiver);
branch_is_receiver_false =
graph()->NewNode(javascript()->CallRuntime(
Runtime::kThrowConstructorReturnedNonObject),
context, NodeProperties::GetFrameStateInput(node),
node, branch_is_receiver_false);
uncaught_subcalls.push_back(branch_is_receiver_false);
branch_is_receiver_false =
graph()->NewNode(common()->Throw(), branch_is_receiver_false,
branch_is_receiver_false);
NodeProperties::MergeControlToEnd(graph(), common(),
branch_is_receiver_false);
Node* merge =
graph()->NewNode(common()->Merge(2), branch_is_undefined_true,
branch_is_receiver_true);
result =
graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
create, node, merge);
ReplaceWithValue(node_success, node_success, node_success, merge);
// Fix input destroyed by the above {ReplaceWithValue} call.
NodeProperties::ReplaceControlInput(branch_is_undefined, node_success,
0);
} else {
// Insert a check of the return value to determine whether the return
// value or the implicit receiver should be selected as a result of the
// call.
Node* check = graph()->NewNode(simplified()->ObjectIsReceiver(), node);
result =
graph()->NewNode(common()->Select(MachineRepresentation::kTagged),
check, node, create);
}
// Insert a check of the return value to determine whether the return
// value or the implicit receiver should be selected as a result of the
// call.
Node* check = graph()->NewNode(simplified()->ObjectIsReceiver(), node);
result =
graph()->NewNode(common()->Select(MachineRepresentation::kTagged),
check, node, create);
receiver = create; // The implicit receiver.
ReplaceWithValue(dummy, result);
} else if (IsDerivedConstructor(shared_info->kind())) {

View File

@ -1579,7 +1579,7 @@ Reduction JSTypedLowering::ReduceJSConstruct(Node* node) {
Handle<Code> code = use_builtin_construct_stub
? BUILTIN_CODE(isolate(), JSBuiltinsConstructStub)
: isolate()->builtins()->JSConstructStubGeneric();
: BUILTIN_CODE(isolate(), JSConstructStubGeneric);
node->RemoveInput(arity + 1);
node->InsertInput(graph()->zone(), 0, jsgraph()->HeapConstant(code));

View File

@ -1161,10 +1161,7 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslatedFrame* translated_frame,
CHECK(!is_topmost || bailout_type_ == LAZY);
Builtins* builtins = isolate_->builtins();
Code* construct_stub = builtins->builtin(
FLAG_harmony_restrict_constructor_return
? Builtins::kJSConstructStubGenericRestrictedReturn
: Builtins::kJSConstructStubGenericUnrestrictedReturn);
Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
BailoutId bailout_id = translated_frame->node_id();
unsigned height = translated_frame->height();
unsigned height_in_bytes = height * kPointerSize;

View File

@ -224,9 +224,6 @@ DEFINE_IMPLICATION(harmony_class_fields, harmony_private_fields)
// Features that are complete (but still behind --harmony/es-staging flag).
#define HARMONY_STAGED(V) \
V(harmony_restrict_constructor_return, \
"harmony disallow non undefined primitive return value from class " \
"constructor") \
V(harmony_public_fields, "harmony public fields in class literals") \
V(harmony_private_fields, "harmony private fields in class literals") \
V(harmony_numeric_separator, "harmony numeric separator between digits") \

View File

@ -76,18 +76,12 @@ void Heap::SetArgumentsAdaptorDeoptPCOffset(int pc_offset) {
}
void Heap::SetConstructStubCreateDeoptPCOffset(int pc_offset) {
// TODO(tebbi): Remove second half of DCHECK once
// FLAG_harmony_restrict_constructor_return is gone.
DCHECK(construct_stub_create_deopt_pc_offset() == Smi::kZero ||
construct_stub_create_deopt_pc_offset() == Smi::FromInt(pc_offset));
DCHECK(construct_stub_create_deopt_pc_offset() == Smi::kZero);
set_construct_stub_create_deopt_pc_offset(Smi::FromInt(pc_offset));
}
void Heap::SetConstructStubInvokeDeoptPCOffset(int pc_offset) {
// TODO(tebbi): Remove second half of DCHECK once
// FLAG_harmony_restrict_constructor_return is gone.
DCHECK(construct_stub_invoke_deopt_pc_offset() == Smi::kZero ||
construct_stub_invoke_deopt_pc_offset() == Smi::FromInt(pc_offset));
DCHECK(construct_stub_invoke_deopt_pc_offset() == Smi::kZero);
set_construct_stub_invoke_deopt_pc_offset(Smi::FromInt(pc_offset));
}

View File

@ -582,8 +582,6 @@ class ErrorUtils : public AllStatic {
T(ConstructorIsAccessor, "Class constructor may not be an accessor") \
T(ConstructorIsGenerator, "Class constructor may not be a generator") \
T(ConstructorIsAsync, "Class constructor may not be an async method") \
T(ClassConstructorReturnedNonObject, \
"Class constructors may only return object or undefined") \
T(DerivedConstructorReturnedNonObject, \
"Derived constructors may only return object or undefined") \
T(DuplicateConstructor, "A class may only have one constructor") \

View File

@ -430,11 +430,6 @@ RUNTIME_FUNCTION(Runtime_ThrowConstructedNonConstructable) {
RUNTIME_FUNCTION(Runtime_ThrowConstructorReturnedNonObject) {
HandleScope scope(isolate);
DCHECK_EQ(0, args.length());
if (FLAG_harmony_restrict_constructor_return) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate,
NewTypeError(MessageTemplate::kClassConstructorReturnedNonObject));
}
THROW_NEW_ERROR_RETURN_FAILURE(
isolate,
@ -485,15 +480,6 @@ RUNTIME_FUNCTION(Runtime_IncrementUseCounter) {
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(
Runtime_IncrementUseCounterConstructorReturnNonUndefinedPrimitive) {
HandleScope scope(isolate);
DCHECK_EQ(0, args.length());
isolate->CountUsage(
v8::Isolate::UseCounterFeature::kConstructorNonUndefinedPrimitiveReturn);
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(Runtime_GetAndResetRuntimeCallStats) {
HandleScope scope(isolate);
if (args.length() == 0) {

View File

@ -281,7 +281,6 @@ namespace internal {
F(ExportFromRuntime, 1, 1) \
F(GetAndResetRuntimeCallStats, -1 /* <= 2 */, 1) \
F(IncrementUseCounter, 1, 1) \
F(IncrementUseCounterConstructorReturnNonUndefinedPrimitive, 0, 1) \
F(InstallToContext, 1, 1) \
F(Interrupt, 0, 1) \
F(IS_VAR, 1, 1) \

View File

@ -754,24 +754,6 @@ bool Deserializer<AllocatorT>::ReadData(MaybeObject** current,
return true;
}
namespace {
int FixupJSConstructStub(Isolate* isolate, int builtin_id) {
if (isolate->serializer_enabled()) return builtin_id;
if (FLAG_harmony_restrict_constructor_return &&
builtin_id == Builtins::kJSConstructStubGenericUnrestrictedReturn) {
return Builtins::kJSConstructStubGenericRestrictedReturn;
} else if (!FLAG_harmony_restrict_constructor_return &&
builtin_id == Builtins::kJSConstructStubGenericRestrictedReturn) {
return Builtins::kJSConstructStubGenericUnrestrictedReturn;
} else {
return builtin_id;
}
}
} // namespace
template <class AllocatorT>
void** Deserializer<AllocatorT>::ReadExternalReferenceCase(
HowToCode how, Isolate* isolate, void** current,
@ -844,8 +826,7 @@ MaybeObject** Deserializer<AllocatorT>::ReadDataCase(
emit_write_barrier = isolate->heap()->InNewSpace(new_object);
} else {
DCHECK_EQ(where, kBuiltin);
int raw_id = MaybeReplaceWithDeserializeLazy(source_.GetInt());
int builtin_id = FixupJSConstructStub(isolate, raw_id);
int builtin_id = MaybeReplaceWithDeserializeLazy(source_.GetInt());
new_object = isolate->builtins()->builtin(builtin_id);
emit_write_barrier = false;
}

View File

@ -1,12 +0,0 @@
// 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 --no-harmony-restrict-constructor-return
this.FLAG_harmony_restrict_constructor_return = false;
try {
load('mjsunit/compiler/constructor-inlining.js');
} catch(e) {
load('test/mjsunit/compiler/constructor-inlining.js');
}

View File

@ -2,10 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-restrict-constructor-return --allow-natives-syntax --stress-inline
// Flags: --allow-natives-syntax --stress-inline
if (this.FLAG_harmony_restrict_constructor_return === undefined)
this.FLAG_harmony_restrict_constructor_return = true;
var counter = 0;
var deopt_at = -1;
@ -65,17 +63,7 @@ function testConstructorInlining(){
assertEquals(a, new Base(true, a));
assertEquals(7, new Base(false, 7).x);
if (FLAG_harmony_restrict_constructor_return) {
// not using assertThrows to ensure proper inlining
try {
new Base(true, 5);
assertTrue(false);
} catch (e) {
if (!(e instanceof TypeError)) throw e;
}
} else {
assertEquals(5, new Base(true, 5).x);
}
assertEquals(5, new Base(true, 5).x);
assertEquals(b, new Derived(true, a, b));
assertEquals(a, new Derived(true, a, undefined));
@ -87,16 +75,7 @@ function testConstructorInlining(){
} catch (e) {
if (!(e instanceof TypeError)) throw e;
}
if (FLAG_harmony_restrict_constructor_return) {
try {
new Derived(true, 5, a)
assertTrue(false);
} catch (e) {
if (!(e instanceof TypeError)) throw e;
}
} else {
assertEquals(a, new Derived(true, 5, a));
}
assertEquals(a, new Derived(true, 5, a));
%OptimizeFunctionOnNextCall(Derived);
assertEquals(b, new DerivedDeoptCreate(true, a, b));

View File

@ -1,318 +0,0 @@
// 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: --harmony-restrict-constructor-return
assertThrows(
() => {
new class {
constructor() {
return 1;
}
}();
},
TypeError,
"Class constructors may only return object or undefined"
);
assertThrows(
() => {
new class {
constructor() {
return 2147483649;
}
}();
},
TypeError,
"Class constructors may only return object or undefined"
);
assertThrows(
() => {
new class {
constructor() {
return true;
}
}();
},
TypeError,
"Class constructors may only return object or undefined"
);
assertThrows(
() => {
new class {
constructor() {
return null;
}
}();
},
TypeError,
"Class constructors may only return object or undefined"
);
assertThrows(
() => {
new class {
constructor() {
return "wat";
}
}();
},
TypeError,
"Class constructors may only return object or undefined"
);
assertThrows(
() => {
new class {
constructor() {
return Symbol();
}
}();
},
TypeError,
"Class constructors may only return object or undefined"
);
assertThrows(
() => {
new class {
constructor() {
return 2.2;
}
}();
},
TypeError,
"Class constructors may only return object or undefined"
);
assertThrows(
() => {
new class extends Object {
constructor() {
return 1;
}
}();
},
TypeError,
"Class constructors may only return object or undefined"
);
assertThrows(
() => {
new class extends Object {
constructor() {
return 2147483649;
}
}();
},
TypeError,
"Class constructors may only return object or undefined"
);
assertThrows(
() => {
new class extends Object {
constructor() {
return true;
}
}();
},
TypeError,
"Class constructors may only return object or undefined"
);
assertThrows(
() => {
new class extends Object {
constructor() {
return null;
}
}();
},
TypeError,
"Class constructors may only return object or undefined"
);
assertThrows(
() => {
new class extends Object {
constructor() {
return "wat";
}
}();
},
TypeError,
"Class constructors may only return object or undefined"
);
assertThrows(
() => {
new class extends Object {
constructor() {
return Symbol();
}
}();
},
TypeError,
"Class constructors may only return object or undefined"
);
assertThrows(
() => {
new class extends Object {
constructor() {
return 2.2;
}
}();
},
TypeError,
"Class constructors may only return object or undefined"
);
assertThrows(
() => {
new class extends Object {
constructor() {}
}();
},
ReferenceError,
"Must call super constructor in derived class before accessing " +
"'this' or returning from derived constructor"
);
(function() {
let ret_val = { x: 1 };
let x = new class {
constructor() {
return ret_val;
}
}();
assertSame(ret_val, x);
})();
(function() {
class Foo {
constructor() {}
}
let x = new Foo();
assertTrue(x instanceof Foo);
})();
(function() {
class Foo {
constructor() {
return undefined;
}
}
let x = new Foo();
assertTrue(x instanceof Foo);
})();
(function() {
let ret_val = { x: 1 };
let x = new class extends Object {
constructor() {
return ret_val;
}
}();
assertSame(ret_val, x);
})();
(function() {
class Foo extends Object {
constructor() {
super();
return undefined;
}
}
let x = new Foo();
assertTrue(x instanceof Foo);
})();
(function() {
class Foo extends Object {
constructor() {
super();
}
}
let x = new Foo();
assertTrue(x instanceof Foo);
})();
(function() {
function foo() {
return 1;
}
let x = new foo();
assertTrue(x instanceof foo);
})();
(function() {
function foo() {
return 2147483649;
}
let x = new foo();
assertTrue(x instanceof foo);
})();
(function() {
function foo() {
return true;
}
let x = new foo();
assertTrue(x instanceof foo);
})();
(function() {
function foo() {
return undefined;
}
let x = new foo();
assertTrue(x instanceof foo);
})();
(function() {
function foo() {
return null;
}
let x = new foo();
assertTrue(x instanceof foo);
})();
(function() {
function foo() {
return "wat";
}
let x = new foo();
assertTrue(x instanceof foo);
})();
(function() {
function foo() {
return Symbol();
}
let x = new foo();
assertTrue(x instanceof foo);
})();
(function() {
function foo() {
return 2.2;
}
let x = new foo();
assertTrue(x instanceof foo);
})();
(function() {
var ret_val = { x: 1 };
function foo() {
return ret_val;
}
let x = new foo();
assertSame(x, ret_val);
})();

View File

@ -1,17 +0,0 @@
// 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: --harmony-restrict-constructor-return --always-opt
class Base {
constructor(x) {
return x;
}
}
class Derived extends Base {
constructor(use, x) {
super(use, x);
}
}
assertThrows(() => new Derived(true, 5), TypeError);