@@ -213,53 +213,61 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
213213 // ----------- S t a t e -------------
214214 // -- r0 : number of arguments
215215 // -- r1 : constructor function
216+ // -- r3 : original constructor
216217 // -- lr : return address
217218 // -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
218219 // -- sp[argc * 4] : receiver
219220 // -----------------------------------
220221
221- // 1. Load the first argument into r0 and get rid of the rest (including the
222+ // 1. Load the first argument into r2 and get rid of the rest (including the
222223 // receiver).
223224 {
224225 Label no_arguments, done;
225226 __ sub (r0, r0, Operand (1 ), SetCC);
226227 __ b (lo, &no_arguments);
227- __ ldr (r0 , MemOperand (sp, r0, LSL , kPointerSizeLog2 , PreIndex));
228+ __ ldr (r2 , MemOperand (sp, r0, LSL , kPointerSizeLog2 , PreIndex));
228229 __ Drop (2 );
229230 __ b (&done);
230231 __ bind (&no_arguments);
231- __ LoadRoot (r0 , Heap::kempty_stringRootIndex);
232+ __ LoadRoot (r2 , Heap::kempty_stringRootIndex);
232233 __ Drop (1 );
233234 __ bind (&done);
234235 }
235236
236- // 2. Make sure r0 is a string.
237+ // 2. Make sure r2 is a string.
237238 {
238239 Label convert, done_convert;
239- __ JumpIfSmi (r0 , &convert);
240- __ CompareObjectType (r0, r2, r2 , FIRST_NONSTRING_TYPE );
240+ __ JumpIfSmi (r2 , &convert);
241+ __ CompareObjectType (r2, r4, r4 , FIRST_NONSTRING_TYPE );
241242 __ b (lo, &done_convert);
242243 __ bind (&convert);
243244 {
244245 FrameAndConstantPoolScope scope (masm, StackFrame::INTERNAL );
245246 ToStringStub stub (masm->isolate ());
246- __ Push (r1);
247+ __ Push (r1, r3);
248+ __ Move (r0, r2);
247249 __ CallStub (&stub);
248- __ Pop (r1);
250+ __ Move (r2, r0);
251+ __ Pop (r1, r3);
249252 }
250253 __ bind (&done_convert);
251254 }
252255
253256 // 3. Allocate a JSValue wrapper for the string.
254257 {
255258 // ----------- S t a t e -------------
256- // -- r0 : the first argument
259+ // -- r2 : the first argument
257260 // -- r1 : constructor function
261+ // -- r3 : original constructor
258262 // -- lr : return address
259263 // -----------------------------------
260264
261- Label allocate, done_allocate;
262- __ Move (r2, r0);
265+ Label allocate, done_allocate, rt_call;
266+
267+ // Fall back to runtime if the original constructor and function differ.
268+ __ cmp (r1, r3);
269+ __ b (ne, &rt_call);
270+
263271 __ Allocate (JSValue::kSize , r0, r3, r4, &allocate, TAG_OBJECT );
264272 __ bind (&done_allocate);
265273
@@ -283,6 +291,18 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
283291 __ Pop (r1, r2);
284292 }
285293 __ b (&done_allocate);
294+
295+ // Fallback to the runtime to create new object.
296+ __ bind (&rt_call);
297+ {
298+ FrameScope scope (masm, StackFrame::INTERNAL );
299+ __ Push (r1, r2);
300+ __ Push (r1, r3); // constructor function, original constructor
301+ __ CallRuntime (Runtime::kNewObject , 2 );
302+ __ Pop (r1, r2);
303+ }
304+ __ str (r2, FieldMemOperand (r0, JSValue::kValueOffset ));
305+ __ Ret ();
286306 }
287307}
288308
@@ -500,8 +520,8 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
500520 // r3: original constructor
501521 __ bind (&rt_call);
502522
503- __ push (r1); // argument 2/1: constructor function
504- __ push (r3); // argument 3/2: original constructor
523+ __ push (r1); // constructor function
524+ __ push (r3); // original constructor
505525 __ CallRuntime (Runtime::kNewObject , 2 );
506526 __ mov (r4, r0);
507527
0 commit comments