Index: src/builtins/ppc/builtins-ppc.cc |
diff --git a/src/builtins/ppc/builtins-ppc.cc b/src/builtins/ppc/builtins-ppc.cc |
index 2915e7311a40e2ef343c62bdee4e7f8496b38f31..aee21db622d32f65e6da924870add26b631116b2 100644 |
--- a/src/builtins/ppc/builtins-ppc.cc |
+++ b/src/builtins/ppc/builtins-ppc.cc |
@@ -448,7 +448,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 ------------- |
// -- r3 : number of arguments |
@@ -537,7 +537,8 @@ void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function, |
} |
// 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()); |
} |
@@ -552,18 +553,32 @@ 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. |
// r3: result |
// sp[0]: receiver |
// sp[1]: number of arguments (smi-tagged) |
- __ JumpIfSmi(r3, &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(r3, Heap::kUndefinedValueRootIndex); |
+ __ beq(&use_receiver); |
+ __ JumpIfSmi(r3, &do_throw); |
+ } else { |
+ __ 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. |
__ CompareObjectType(r3, r4, r6, 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. |
@@ -572,7 +587,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); |
// r3: result |
// sp[0]: receiver (newly allocated object) |
// sp[1]: number of arguments (smi-tagged) |
@@ -585,9 +600,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(r3, &do_throw); |
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
@@ -596,7 +612,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); |
} |
@@ -611,7 +627,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()); |
@@ -652,6 +669,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); |