OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 4468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4479 __ Ret(); | 4479 __ Ret(); |
4480 | 4480 |
4481 __ bind(&slowcase); | 4481 __ bind(&slowcase); |
4482 __ TailCallRuntime(Runtime::kRegExpConstructResult, 3, 1); | 4482 __ TailCallRuntime(Runtime::kRegExpConstructResult, 3, 1); |
4483 } | 4483 } |
4484 | 4484 |
4485 | 4485 |
4486 void CallFunctionStub::Generate(MacroAssembler* masm) { | 4486 void CallFunctionStub::Generate(MacroAssembler* masm) { |
4487 Label slow; | 4487 Label slow; |
4488 | 4488 |
4489 // If the receiver might be a value (string, number or boolean) check for this | 4489 // The receiver might implicitly be the global object. This is |
4490 // and box it if it is. | 4490 // indicated by passing the hole as the receiver to the call |
4491 if (ReceiverMightBeValue()) { | 4491 // function stub. |
| 4492 if (ReceiverMightBeImplicit()) { |
| 4493 Label call; |
4492 // Get the receiver from the stack. | 4494 // Get the receiver from the stack. |
4493 // function, receiver [, arguments] | 4495 // function, receiver [, arguments] |
4494 Label receiver_is_value, receiver_is_js_object; | 4496 __ ldr(r4, MemOperand(sp, argc_ * kPointerSize)); |
4495 __ ldr(r1, MemOperand(sp, argc_ * kPointerSize)); | 4497 // Call as function is indicated with the hole. |
4496 | 4498 __ CompareRoot(r4, Heap::kTheHoleValueRootIndex); |
4497 // Check if receiver is a smi (which is a number value). | 4499 __ b(ne, &call); |
4498 __ JumpIfSmi(r1, &receiver_is_value); | 4500 // Patch the receiver on the stack with the global receiver object. |
4499 | 4501 __ ldr(r1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); |
4500 // Check if the receiver is a valid JS object. | 4502 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
4501 __ CompareObjectType(r1, r2, r2, FIRST_JS_OBJECT_TYPE); | 4503 __ str(r1, MemOperand(sp, argc_ * kPointerSize)); |
4502 __ b(ge, &receiver_is_js_object); | 4504 __ bind(&call); |
4503 | |
4504 // Call the runtime to box the value. | |
4505 __ bind(&receiver_is_value); | |
4506 __ EnterInternalFrame(); | |
4507 __ push(r1); | |
4508 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); | |
4509 __ LeaveInternalFrame(); | |
4510 __ str(r0, MemOperand(sp, argc_ * kPointerSize)); | |
4511 | |
4512 __ bind(&receiver_is_js_object); | |
4513 } | 4505 } |
4514 | 4506 |
4515 // Get the function to call from the stack. | 4507 // Get the function to call from the stack. |
4516 // function, receiver [, arguments] | 4508 // function, receiver [, arguments] |
4517 __ ldr(r1, MemOperand(sp, (argc_ + 1) * kPointerSize)); | 4509 __ ldr(r1, MemOperand(sp, (argc_ + 1) * kPointerSize)); |
4518 | 4510 |
4519 // Check that the function is really a JavaScript function. | 4511 // Check that the function is really a JavaScript function. |
4520 // r1: pushed function (to be verified) | 4512 // r1: pushed function (to be verified) |
4521 __ JumpIfSmi(r1, &slow); | 4513 __ JumpIfSmi(r1, &slow); |
4522 // Get the map of the function object. | 4514 // Get the map of the function object. |
4523 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); | 4515 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); |
4524 __ b(ne, &slow); | 4516 __ b(ne, &slow); |
4525 | 4517 |
4526 // Fast-case: Invoke the function now. | 4518 // Fast-case: Invoke the function now. |
4527 // r1: pushed function | 4519 // r1: pushed function |
4528 ParameterCount actual(argc_); | 4520 ParameterCount actual(argc_); |
4529 __ InvokeFunction(r1, actual, JUMP_FUNCTION); | 4521 |
| 4522 if (ReceiverMightBeImplicit()) { |
| 4523 Label call_as_function; |
| 4524 __ CompareRoot(r4, Heap::kTheHoleValueRootIndex); |
| 4525 __ b(eq, &call_as_function); |
| 4526 __ InvokeFunction(r1, actual, JUMP_FUNCTION); |
| 4527 __ bind(&call_as_function); |
| 4528 } |
| 4529 __ InvokeFunction(r1, |
| 4530 actual, |
| 4531 JUMP_FUNCTION, |
| 4532 NullCallWrapper(), |
| 4533 CALL_AS_FUNCTION); |
4530 | 4534 |
4531 // Slow-case: Non-function called. | 4535 // Slow-case: Non-function called. |
4532 __ bind(&slow); | 4536 __ bind(&slow); |
4533 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead | 4537 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead |
4534 // of the original receiver from the call site). | 4538 // of the original receiver from the call site). |
4535 __ str(r1, MemOperand(sp, argc_ * kPointerSize)); | 4539 __ str(r1, MemOperand(sp, argc_ * kPointerSize)); |
4536 __ mov(r0, Operand(argc_)); // Setup the number of arguments. | 4540 __ mov(r0, Operand(argc_)); // Setup the number of arguments. |
4537 __ mov(r2, Operand(0, RelocInfo::NONE)); | 4541 __ mov(r2, Operand(0, RelocInfo::NONE)); |
4538 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); | 4542 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); |
4539 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 4543 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
(...skipping 1845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6385 __ mov(result, Operand(0)); | 6389 __ mov(result, Operand(0)); |
6386 __ Ret(); | 6390 __ Ret(); |
6387 } | 6391 } |
6388 | 6392 |
6389 | 6393 |
6390 #undef __ | 6394 #undef __ |
6391 | 6395 |
6392 } } // namespace v8::internal | 6396 } } // namespace v8::internal |
6393 | 6397 |
6394 #endif // V8_TARGET_ARCH_ARM | 6398 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |