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