OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 // r3: argc | 207 // r3: argc |
208 // r4: argv | 208 // r4: argv |
209 // r5-r7, cp may be clobbered | 209 // r5-r7, cp may be clobbered |
210 | 210 |
211 // Clear the context before we push it when entering the JS frame. | 211 // Clear the context before we push it when entering the JS frame. |
212 __ mov(cp, Operand(0)); | 212 __ mov(cp, Operand(0)); |
213 | 213 |
214 // Enter an internal frame. | 214 // Enter an internal frame. |
215 __ EnterInternalFrame(); | 215 __ EnterInternalFrame(); |
216 | 216 |
217 // Setup the context from the function argument. | 217 // Set up the context from the function argument. |
218 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); | 218 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
219 | 219 |
| 220 // Set up the roots register. |
| 221 ExternalReference roots_address = ExternalReference::roots_address(); |
| 222 __ mov(r10, Operand(roots_address)); |
| 223 |
220 // Push the function and the receiver onto the stack. | 224 // Push the function and the receiver onto the stack. |
221 __ push(r1); | 225 __ push(r1); |
222 __ push(r2); | 226 __ push(r2); |
223 | 227 |
224 // Copy arguments to the stack in a loop. | 228 // Copy arguments to the stack in a loop. |
225 // r1: function | 229 // r1: function |
226 // r3: argc | 230 // r3: argc |
227 // r4: argv, i.e. points to first arg | 231 // r4: argv, i.e. points to first arg |
228 Label loop, entry; | 232 Label loop, entry; |
229 __ add(r2, r4, Operand(r3, LSL, kPointerSizeLog2)); | 233 __ add(r2, r4, Operand(r3, LSL, kPointerSizeLog2)); |
230 // r2 points past last arg. | 234 // r2 points past last arg. |
231 __ b(&entry); | 235 __ b(&entry); |
232 __ bind(&loop); | 236 __ bind(&loop); |
233 __ ldr(r0, MemOperand(r4, kPointerSize, PostIndex)); // read next parameter | 237 __ ldr(r0, MemOperand(r4, kPointerSize, PostIndex)); // read next parameter |
234 __ ldr(r0, MemOperand(r0)); // dereference handle | 238 __ ldr(r0, MemOperand(r0)); // dereference handle |
235 __ push(r0); // push parameter | 239 __ push(r0); // push parameter |
236 __ bind(&entry); | 240 __ bind(&entry); |
237 __ cmp(r4, Operand(r2)); | 241 __ cmp(r4, Operand(r2)); |
238 __ b(ne, &loop); | 242 __ b(ne, &loop); |
239 | 243 |
240 // Initialize all JavaScript callee-saved registers, since they will be seen | 244 // Initialize all JavaScript callee-saved registers, since they will be seen |
241 // by the garbage collector as part of handlers. | 245 // by the garbage collector as part of handlers. |
242 __ mov(r4, Operand(Factory::undefined_value())); | 246 __ LoadRoot(r4, Heap::kUndefinedValueRootIndex); |
243 __ mov(r5, Operand(r4)); | 247 __ mov(r5, Operand(r4)); |
244 __ mov(r6, Operand(r4)); | 248 __ mov(r6, Operand(r4)); |
245 __ mov(r7, Operand(r4)); | 249 __ mov(r7, Operand(r4)); |
246 if (kR9Available == 1) { | 250 if (kR9Available == 1) { |
247 __ mov(r9, Operand(r4)); | 251 __ mov(r9, Operand(r4)); |
248 } | 252 } |
249 | 253 |
250 // Invoke the code and pass argc as r0. | 254 // Invoke the code and pass argc as r0. |
251 __ mov(r0, Operand(r3)); | 255 __ mov(r0, Operand(r3)); |
252 if (is_construct) { | 256 if (is_construct) { |
(...skipping 22 matching lines...) Expand all Loading... |
275 Generate_JSEntryTrampolineHelper(masm, true); | 279 Generate_JSEntryTrampolineHelper(masm, true); |
276 } | 280 } |
277 | 281 |
278 | 282 |
279 void Builtins::Generate_FunctionCall(MacroAssembler* masm) { | 283 void Builtins::Generate_FunctionCall(MacroAssembler* masm) { |
280 // 1. Make sure we have at least one argument. | 284 // 1. Make sure we have at least one argument. |
281 // r0: actual number of argument | 285 // r0: actual number of argument |
282 { Label done; | 286 { Label done; |
283 __ tst(r0, Operand(r0)); | 287 __ tst(r0, Operand(r0)); |
284 __ b(ne, &done); | 288 __ b(ne, &done); |
285 __ mov(r2, Operand(Factory::undefined_value())); | 289 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
286 __ push(r2); | 290 __ push(r2); |
287 __ add(r0, r0, Operand(1)); | 291 __ add(r0, r0, Operand(1)); |
288 __ bind(&done); | 292 __ bind(&done); |
289 } | 293 } |
290 | 294 |
291 // 2. Get the function to call from the stack. | 295 // 2. Get the function to call from the stack. |
292 // r0: actual number of argument | 296 // r0: actual number of argument |
293 { Label done, non_function, function; | 297 { Label done, non_function, function; |
294 __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); | 298 __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); |
295 __ tst(r1, Operand(kSmiTagMask)); | 299 __ tst(r1, Operand(kSmiTagMask)); |
(...skipping 20 matching lines...) Expand all Loading... |
316 { Label call_to_object, use_global_receiver, patch_receiver, done; | 320 { Label call_to_object, use_global_receiver, patch_receiver, done; |
317 __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2)); | 321 __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2)); |
318 __ ldr(r2, MemOperand(r2, -kPointerSize)); | 322 __ ldr(r2, MemOperand(r2, -kPointerSize)); |
319 | 323 |
320 // r0: actual number of arguments | 324 // r0: actual number of arguments |
321 // r1: function | 325 // r1: function |
322 // r2: first argument | 326 // r2: first argument |
323 __ tst(r2, Operand(kSmiTagMask)); | 327 __ tst(r2, Operand(kSmiTagMask)); |
324 __ b(eq, &call_to_object); | 328 __ b(eq, &call_to_object); |
325 | 329 |
326 __ mov(r3, Operand(Factory::null_value())); | 330 __ LoadRoot(r3, Heap::kNullValueRootIndex); |
327 __ cmp(r2, r3); | 331 __ cmp(r2, r3); |
328 __ b(eq, &use_global_receiver); | 332 __ b(eq, &use_global_receiver); |
329 __ mov(r3, Operand(Factory::undefined_value())); | 333 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex); |
330 __ cmp(r2, r3); | 334 __ cmp(r2, r3); |
331 __ b(eq, &use_global_receiver); | 335 __ b(eq, &use_global_receiver); |
332 | 336 |
333 __ CompareObjectType(r2, r3, r3, FIRST_JS_OBJECT_TYPE); | 337 __ CompareObjectType(r2, r3, r3, FIRST_JS_OBJECT_TYPE); |
334 __ b(lt, &call_to_object); | 338 __ b(lt, &call_to_object); |
335 __ cmp(r3, Operand(LAST_JS_OBJECT_TYPE)); | 339 __ cmp(r3, Operand(LAST_JS_OBJECT_TYPE)); |
336 __ b(le, &done); | 340 __ b(le, &done); |
337 | 341 |
338 __ bind(&call_to_object); | 342 __ bind(&call_to_object); |
339 __ EnterInternalFrame(); | 343 __ EnterInternalFrame(); |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 | 489 |
486 // Change context eagerly to get the right global object if necessary. | 490 // Change context eagerly to get the right global object if necessary. |
487 __ ldr(r0, MemOperand(fp, kFunctionOffset)); | 491 __ ldr(r0, MemOperand(fp, kFunctionOffset)); |
488 __ ldr(cp, FieldMemOperand(r0, JSFunction::kContextOffset)); | 492 __ ldr(cp, FieldMemOperand(r0, JSFunction::kContextOffset)); |
489 | 493 |
490 // Compute the receiver. | 494 // Compute the receiver. |
491 Label call_to_object, use_global_receiver, push_receiver; | 495 Label call_to_object, use_global_receiver, push_receiver; |
492 __ ldr(r0, MemOperand(fp, kRecvOffset)); | 496 __ ldr(r0, MemOperand(fp, kRecvOffset)); |
493 __ tst(r0, Operand(kSmiTagMask)); | 497 __ tst(r0, Operand(kSmiTagMask)); |
494 __ b(eq, &call_to_object); | 498 __ b(eq, &call_to_object); |
495 __ mov(r1, Operand(Factory::null_value())); | 499 __ LoadRoot(r1, Heap::kNullValueRootIndex); |
496 __ cmp(r0, r1); | 500 __ cmp(r0, r1); |
497 __ b(eq, &use_global_receiver); | 501 __ b(eq, &use_global_receiver); |
498 __ mov(r1, Operand(Factory::undefined_value())); | 502 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); |
499 __ cmp(r0, r1); | 503 __ cmp(r0, r1); |
500 __ b(eq, &use_global_receiver); | 504 __ b(eq, &use_global_receiver); |
501 | 505 |
502 // Check if the receiver is already a JavaScript object. | 506 // Check if the receiver is already a JavaScript object. |
503 // r0: receiver | 507 // r0: receiver |
504 __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE); | 508 __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE); |
505 __ b(lt, &call_to_object); | 509 __ b(lt, &call_to_object); |
506 __ cmp(r1, Operand(LAST_JS_OBJECT_TYPE)); | 510 __ cmp(r1, Operand(LAST_JS_OBJECT_TYPE)); |
507 __ b(le, &push_receiver); | 511 __ b(le, &push_receiver); |
508 | 512 |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
658 __ ldr(ip, MemOperand(r0, 2 * kPointerSize)); | 662 __ ldr(ip, MemOperand(r0, 2 * kPointerSize)); |
659 __ push(ip); | 663 __ push(ip); |
660 __ cmp(r0, fp); // Compare before moving to next argument. | 664 __ cmp(r0, fp); // Compare before moving to next argument. |
661 __ sub(r0, r0, Operand(kPointerSize)); | 665 __ sub(r0, r0, Operand(kPointerSize)); |
662 __ b(ne, ©); | 666 __ b(ne, ©); |
663 | 667 |
664 // Fill the remaining expected arguments with undefined. | 668 // Fill the remaining expected arguments with undefined. |
665 // r1: function | 669 // r1: function |
666 // r2: expected number of arguments | 670 // r2: expected number of arguments |
667 // r3: code entry to call | 671 // r3: code entry to call |
668 __ mov(ip, Operand(Factory::undefined_value())); | 672 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
669 __ sub(r2, fp, Operand(r2, LSL, kPointerSizeLog2)); | 673 __ sub(r2, fp, Operand(r2, LSL, kPointerSizeLog2)); |
670 __ sub(r2, r2, Operand(4 * kPointerSize)); // Adjust for frame. | 674 __ sub(r2, r2, Operand(4 * kPointerSize)); // Adjust for frame. |
671 | 675 |
672 Label fill; | 676 Label fill; |
673 __ bind(&fill); | 677 __ bind(&fill); |
674 __ push(ip); | 678 __ push(ip); |
675 __ cmp(sp, r2); | 679 __ cmp(sp, r2); |
676 __ b(ne, &fill); | 680 __ b(ne, &fill); |
677 } | 681 } |
678 | 682 |
(...skipping 10 matching lines...) Expand all Loading... |
689 // Dont adapt arguments. | 693 // Dont adapt arguments. |
690 // ------------------------------------------- | 694 // ------------------------------------------- |
691 __ bind(&dont_adapt_arguments); | 695 __ bind(&dont_adapt_arguments); |
692 __ Jump(r3); | 696 __ Jump(r3); |
693 } | 697 } |
694 | 698 |
695 | 699 |
696 #undef __ | 700 #undef __ |
697 | 701 |
698 } } // namespace v8::internal | 702 } } // namespace v8::internal |
OLD | NEW |