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:
parent
0300caa502
commit
813094ac8c
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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) \
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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())) {
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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") \
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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") \
|
||||
|
@ -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) {
|
||||
|
@ -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) \
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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');
|
||||
}
|
@ -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));
|
||||
|
@ -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);
|
||||
})();
|
@ -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);
|
Loading…
Reference in New Issue
Block a user