Index: src/builtins/s390/builtins-s390.cc |
diff --git a/src/builtins/s390/builtins-s390.cc b/src/builtins/s390/builtins-s390.cc |
index e08ef0b9de4af07fedb885ddb92cc975c2aad34e..7c0a9ece07b9df63dba0820c5df9ceaaea5834a4 100644 |
--- a/src/builtins/s390/builtins-s390.cc |
+++ b/src/builtins/s390/builtins-s390.cc |
@@ -444,7 +444,7 @@ namespace { |
void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function, |
bool create_implicit_receiver, |
- bool check_derived_construct) { |
+ bool disallow_non_object_return) { |
Label post_instantiation_deopt_entry; |
// ----------- S t a t e ------------- |
// -- r2 : number of arguments |
@@ -533,7 +533,8 @@ void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function, |
CheckDebugStepCallWrapper()); |
// Store offset of return address for deoptimizer. |
- if (create_implicit_receiver && !is_api_function) { |
+ if (create_implicit_receiver && !disallow_non_object_return && |
+ !is_api_function) { |
masm->isolate()->heap()->SetConstructStubInvokeDeoptPCOffset( |
masm->pc_offset()); |
} |
@@ -548,19 +549,33 @@ void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function, |
// 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, exit; |
+ Label use_receiver, return_value, do_throw; |
// If the result is a smi, it is *not* an object in the ECMA sense. |
// r2: result |
// sp[0]: receiver |
// sp[1]: new.target |
// sp[2]: number of arguments (smi-tagged) |
- __ JumpIfSmi(r2, &use_receiver); |
+ // If the result is undefined, we jump out to using the implicit |
+ // receiver, otherwise we do a smi check and fall through to |
+ // check if the return value is a valid receiver. |
+ if (disallow_non_object_return) { |
+ __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); |
+ __ beq(&use_receiver); |
+ __ JumpIfSmi(r2, &do_throw); |
+ } else { |
+ __ JumpIfSmi(r2, &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. |
__ CompareObjectType(r2, r3, r5, FIRST_JS_RECEIVER_TYPE); |
- __ bge(&exit); |
+ __ bge(&return_value); |
+ |
+ if (disallow_non_object_return) { |
+ __ bind(&do_throw); |
+ __ CallRuntime(Runtime::kThrowConstructorReturnedNonObject); |
+ } |
// Throw away the result of the constructor invocation and use the |
// on-stack receiver as the result. |
@@ -569,7 +584,7 @@ void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function, |
// Remove receiver from the stack, remove caller arguments, and |
// return. |
- __ bind(&exit); |
+ __ bind(&return_value); |
// r2: result |
// sp[0]: receiver (newly allocated object) |
// sp[1]: number of arguments (smi-tagged) |
@@ -582,9 +597,10 @@ void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function, |
} |
// ES6 9.2.2. Step 13+ |
- // Check that the result is not a Smi, indicating that the constructor result |
- // from a derived class is neither undefined nor an Object. |
- if (check_derived_construct) { |
+ // For derived class constructors, throw a TypeError here if the result |
+ // is not a JSReceiver. For the base constructor, we've already checked |
+ // the result, so we omit the check. |
+ if (disallow_non_object_return && !create_implicit_receiver) { |
Label do_throw, dont_throw; |
__ JumpIfSmi(r2, &do_throw); |
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
@@ -593,7 +609,7 @@ void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function, |
__ bind(&do_throw); |
{ |
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
- __ CallRuntime(Runtime::kThrowDerivedConstructorReturnedNonObject); |
+ __ CallRuntime(Runtime::kThrowConstructorReturnedNonObject); |
} |
__ bind(&dont_throw); |
} |
@@ -609,7 +625,8 @@ void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function, |
// Store offset of trampoline address for deoptimizer. This is the bailout |
// point after the receiver instantiation but before the function invocation. |
// We need to restore some registers in order to continue the above code. |
- if (create_implicit_receiver && !is_api_function) { |
+ if (create_implicit_receiver && !disallow_non_object_return && |
+ !is_api_function) { |
masm->isolate()->heap()->SetConstructStubCreateDeoptPCOffset( |
masm->pc_offset()); |
@@ -650,6 +667,10 @@ void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) { |
Generate_JSConstructStubHelper(masm, false, false, false); |
} |
+void Builtins::Generate_JSBuiltinsConstructStubForBase(MacroAssembler* masm) { |
+ Generate_JSConstructStubHelper(masm, false, true, true); |
+} |
+ |
void Builtins::Generate_JSBuiltinsConstructStubForDerived( |
MacroAssembler* masm) { |
Generate_JSConstructStubHelper(masm, false, false, true); |