OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_ARM | 5 #if V8_TARGET_ARCH_ARM |
6 | 6 |
7 #include "src/codegen.h" | 7 #include "src/codegen.h" |
8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 __ TailCallRuntime(Runtime::kSymbolDescriptiveString, 1, 1); | 206 __ TailCallRuntime(Runtime::kSymbolDescriptiveString, 1, 1); |
207 } | 207 } |
208 } | 208 } |
209 | 209 |
210 | 210 |
211 // static | 211 // static |
212 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { | 212 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { |
213 // ----------- S t a t e ------------- | 213 // ----------- S t a t e ------------- |
214 // -- r0 : number of arguments | 214 // -- r0 : number of arguments |
215 // -- r1 : constructor function | 215 // -- r1 : constructor function |
| 216 // -- r3 : original constructor |
216 // -- lr : return address | 217 // -- lr : return address |
217 // -- sp[(argc - n - 1) * 4] : arg[n] (zero based) | 218 // -- sp[(argc - n - 1) * 4] : arg[n] (zero based) |
218 // -- sp[argc * 4] : receiver | 219 // -- sp[argc * 4] : receiver |
219 // ----------------------------------- | 220 // ----------------------------------- |
220 | 221 |
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 |
222 // receiver). | 223 // receiver). |
223 { | 224 { |
224 Label no_arguments, done; | 225 Label no_arguments, done; |
225 __ sub(r0, r0, Operand(1), SetCC); | 226 __ sub(r0, r0, Operand(1), SetCC); |
226 __ b(lo, &no_arguments); | 227 __ b(lo, &no_arguments); |
227 __ ldr(r0, MemOperand(sp, r0, LSL, kPointerSizeLog2, PreIndex)); | 228 __ ldr(r2, MemOperand(sp, r0, LSL, kPointerSizeLog2, PreIndex)); |
228 __ Drop(2); | 229 __ Drop(2); |
229 __ b(&done); | 230 __ b(&done); |
230 __ bind(&no_arguments); | 231 __ bind(&no_arguments); |
231 __ LoadRoot(r0, Heap::kempty_stringRootIndex); | 232 __ LoadRoot(r2, Heap::kempty_stringRootIndex); |
232 __ Drop(1); | 233 __ Drop(1); |
233 __ bind(&done); | 234 __ bind(&done); |
234 } | 235 } |
235 | 236 |
236 // 2. Make sure r0 is a string. | 237 // 2. Make sure r2 is a string. |
237 { | 238 { |
238 Label convert, done_convert; | 239 Label convert, done_convert; |
239 __ JumpIfSmi(r0, &convert); | 240 __ JumpIfSmi(r2, &convert); |
240 __ CompareObjectType(r0, r2, r2, FIRST_NONSTRING_TYPE); | 241 __ CompareObjectType(r2, r4, r4, FIRST_NONSTRING_TYPE); |
241 __ b(lo, &done_convert); | 242 __ b(lo, &done_convert); |
242 __ bind(&convert); | 243 __ bind(&convert); |
243 { | 244 { |
244 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 245 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
245 ToStringStub stub(masm->isolate()); | 246 ToStringStub stub(masm->isolate()); |
246 __ Push(r1); | 247 __ Push(r1, r3); |
| 248 __ Move(r0, r2); |
247 __ CallStub(&stub); | 249 __ CallStub(&stub); |
248 __ Pop(r1); | 250 __ Move(r2, r0); |
| 251 __ Pop(r1, r3); |
249 } | 252 } |
250 __ bind(&done_convert); | 253 __ bind(&done_convert); |
251 } | 254 } |
252 | 255 |
253 // 3. Allocate a JSValue wrapper for the string. | 256 // 3. Allocate a JSValue wrapper for the string. |
254 { | 257 { |
255 // ----------- S t a t e ------------- | 258 // ----------- S t a t e ------------- |
256 // -- r0 : the first argument | 259 // -- r2 : the first argument |
257 // -- r1 : constructor function | 260 // -- r1 : constructor function |
| 261 // -- r3 : original constructor |
258 // -- lr : return address | 262 // -- lr : return address |
259 // ----------------------------------- | 263 // ----------------------------------- |
260 | 264 |
261 Label allocate, done_allocate; | 265 Label allocate, done_allocate, rt_call; |
262 __ Move(r2, r0); | 266 |
| 267 // Fall back to runtime if the original constructor and function differ. |
| 268 __ cmp(r1, r3); |
| 269 __ b(ne, &rt_call); |
| 270 |
263 __ Allocate(JSValue::kSize, r0, r3, r4, &allocate, TAG_OBJECT); | 271 __ Allocate(JSValue::kSize, r0, r3, r4, &allocate, TAG_OBJECT); |
264 __ bind(&done_allocate); | 272 __ bind(&done_allocate); |
265 | 273 |
266 // Initialize the JSValue in r0. | 274 // Initialize the JSValue in r0. |
267 __ LoadGlobalFunctionInitialMap(r1, r3, r4); | 275 __ LoadGlobalFunctionInitialMap(r1, r3, r4); |
268 __ str(r3, FieldMemOperand(r0, HeapObject::kMapOffset)); | 276 __ str(r3, FieldMemOperand(r0, HeapObject::kMapOffset)); |
269 __ LoadRoot(r3, Heap::kEmptyFixedArrayRootIndex); | 277 __ LoadRoot(r3, Heap::kEmptyFixedArrayRootIndex); |
270 __ str(r3, FieldMemOperand(r0, JSObject::kPropertiesOffset)); | 278 __ str(r3, FieldMemOperand(r0, JSObject::kPropertiesOffset)); |
271 __ str(r3, FieldMemOperand(r0, JSObject::kElementsOffset)); | 279 __ str(r3, FieldMemOperand(r0, JSObject::kElementsOffset)); |
272 __ str(r2, FieldMemOperand(r0, JSValue::kValueOffset)); | 280 __ str(r2, FieldMemOperand(r0, JSValue::kValueOffset)); |
273 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); | 281 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); |
274 __ Ret(); | 282 __ Ret(); |
275 | 283 |
276 // Fallback to the runtime to allocate in new space. | 284 // Fallback to the runtime to allocate in new space. |
277 __ bind(&allocate); | 285 __ bind(&allocate); |
278 { | 286 { |
279 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 287 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
280 __ Move(r3, Smi::FromInt(JSValue::kSize)); | 288 __ Move(r3, Smi::FromInt(JSValue::kSize)); |
281 __ Push(r1, r2, r3); | 289 __ Push(r1, r2, r3); |
282 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); | 290 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); |
283 __ Pop(r1, r2); | 291 __ Pop(r1, r2); |
284 } | 292 } |
285 __ b(&done_allocate); | 293 __ 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(); |
286 } | 306 } |
287 } | 307 } |
288 | 308 |
289 | 309 |
290 static void CallRuntimePassFunction( | 310 static void CallRuntimePassFunction( |
291 MacroAssembler* masm, Runtime::FunctionId function_id) { | 311 MacroAssembler* masm, Runtime::FunctionId function_id) { |
292 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 312 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
293 // Push a copy of the function onto the stack. | 313 // Push a copy of the function onto the stack. |
294 __ push(r1); | 314 __ push(r1); |
295 // Push function as parameter to the runtime call. | 315 // Push function as parameter to the runtime call. |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 // Reload the original constructor and fall-through. | 513 // Reload the original constructor and fall-through. |
494 __ bind(&rt_call_reload_new_target); | 514 __ bind(&rt_call_reload_new_target); |
495 __ ldr(r3, MemOperand(sp, 0 * kPointerSize)); | 515 __ ldr(r3, MemOperand(sp, 0 * kPointerSize)); |
496 } | 516 } |
497 | 517 |
498 // Allocate the new receiver object using the runtime call. | 518 // Allocate the new receiver object using the runtime call. |
499 // r1: constructor function | 519 // r1: constructor function |
500 // r3: original constructor | 520 // r3: original constructor |
501 __ bind(&rt_call); | 521 __ bind(&rt_call); |
502 | 522 |
503 __ push(r1); // argument 2/1: constructor function | 523 __ push(r1); // constructor function |
504 __ push(r3); // argument 3/2: original constructor | 524 __ push(r3); // original constructor |
505 __ CallRuntime(Runtime::kNewObject, 2); | 525 __ CallRuntime(Runtime::kNewObject, 2); |
506 __ mov(r4, r0); | 526 __ mov(r4, r0); |
507 | 527 |
508 // Receiver for constructor call allocated. | 528 // Receiver for constructor call allocated. |
509 // r4: JSObject | 529 // r4: JSObject |
510 __ bind(&allocated); | 530 __ bind(&allocated); |
511 | 531 |
512 // Restore the parameters. | 532 // Restore the parameters. |
513 __ pop(r3); | 533 __ pop(r3); |
514 __ pop(r1); | 534 __ pop(r1); |
(...skipping 1385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1900 } | 1920 } |
1901 } | 1921 } |
1902 | 1922 |
1903 | 1923 |
1904 #undef __ | 1924 #undef __ |
1905 | 1925 |
1906 } // namespace internal | 1926 } // namespace internal |
1907 } // namespace v8 | 1927 } // namespace v8 |
1908 | 1928 |
1909 #endif // V8_TARGET_ARCH_ARM | 1929 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |