OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 3478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3489 __ SmiUntag(result); | 3489 __ SmiUntag(result); |
3490 | 3490 |
3491 // Argument length is in result register. | 3491 // Argument length is in result register. |
3492 __ bind(&done); | 3492 __ bind(&done); |
3493 } | 3493 } |
3494 | 3494 |
3495 | 3495 |
3496 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { | 3496 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { |
3497 Register receiver = ToRegister(instr->receiver()); | 3497 Register receiver = ToRegister(instr->receiver()); |
3498 Register function = ToRegister(instr->function()); | 3498 Register function = ToRegister(instr->function()); |
| 3499 Register result = ToRegister(instr->result()); |
3499 Register scratch = scratch0(); | 3500 Register scratch = scratch0(); |
3500 | 3501 |
3501 // If the receiver is null or undefined, we have to pass the global | 3502 // If the receiver is null or undefined, we have to pass the global |
3502 // object as a receiver to normal functions. Values have to be | 3503 // object as a receiver to normal functions. Values have to be |
3503 // passed unchanged to builtins and strict-mode functions. | 3504 // passed unchanged to builtins and strict-mode functions. |
3504 Label global_object, receiver_ok; | 3505 Label global_object, result_in_receiver; |
3505 | 3506 |
3506 // Do not transform the receiver to object for strict mode | 3507 // Do not transform the receiver to object for strict mode |
3507 // functions. | 3508 // functions. |
3508 __ ldr(scratch, | 3509 __ ldr(scratch, |
3509 FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset)); | 3510 FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset)); |
3510 __ ldr(scratch, | 3511 __ ldr(scratch, |
3511 FieldMemOperand(scratch, SharedFunctionInfo::kCompilerHintsOffset)); | 3512 FieldMemOperand(scratch, SharedFunctionInfo::kCompilerHintsOffset)); |
3512 __ tst(scratch, | 3513 __ tst(scratch, |
3513 Operand(1 << (SharedFunctionInfo::kStrictModeFunction + kSmiTagSize))); | 3514 Operand(1 << (SharedFunctionInfo::kStrictModeFunction + kSmiTagSize))); |
3514 __ b(ne, &receiver_ok); | 3515 __ b(ne, &result_in_receiver); |
3515 | 3516 |
3516 // Do not transform the receiver to object for builtins. | 3517 // Do not transform the receiver to object for builtins. |
3517 __ tst(scratch, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize))); | 3518 __ tst(scratch, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize))); |
3518 __ b(ne, &receiver_ok); | 3519 __ b(ne, &result_in_receiver); |
3519 | 3520 |
3520 // Normal function. Replace undefined or null with global receiver. | 3521 // Normal function. Replace undefined or null with global receiver. |
3521 __ LoadRoot(scratch, Heap::kNullValueRootIndex); | 3522 __ LoadRoot(scratch, Heap::kNullValueRootIndex); |
3522 __ cmp(receiver, scratch); | 3523 __ cmp(receiver, scratch); |
3523 __ b(eq, &global_object); | 3524 __ b(eq, &global_object); |
3524 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); | 3525 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); |
3525 __ cmp(receiver, scratch); | 3526 __ cmp(receiver, scratch); |
3526 __ b(eq, &global_object); | 3527 __ b(eq, &global_object); |
3527 | 3528 |
3528 // Deoptimize if the receiver is not a JS object. | 3529 // Deoptimize if the receiver is not a JS object. |
3529 __ SmiTst(receiver); | 3530 __ SmiTst(receiver); |
3530 DeoptimizeIf(eq, instr->environment()); | 3531 DeoptimizeIf(eq, instr->environment()); |
3531 __ CompareObjectType(receiver, scratch, scratch, FIRST_SPEC_OBJECT_TYPE); | 3532 __ CompareObjectType(receiver, scratch, scratch, FIRST_SPEC_OBJECT_TYPE); |
3532 DeoptimizeIf(lt, instr->environment()); | 3533 DeoptimizeIf(lt, instr->environment()); |
3533 __ jmp(&receiver_ok); | 3534 __ b(&result_in_receiver); |
3534 | 3535 |
3535 __ bind(&global_object); | 3536 __ bind(&global_object); |
3536 __ ldr(receiver, GlobalObjectOperand()); | 3537 __ ldr(result, GlobalObjectOperand()); |
3537 __ ldr(receiver, | 3538 __ ldr(result, |
3538 FieldMemOperand(receiver, JSGlobalObject::kGlobalReceiverOffset)); | 3539 FieldMemOperand(result, JSGlobalObject::kGlobalReceiverOffset)); |
3539 __ bind(&receiver_ok); | 3540 if (result.is(receiver)) { |
| 3541 __ bind(&result_in_receiver); |
| 3542 } else { |
| 3543 Label result_ok; |
| 3544 __ b(&result_ok); |
| 3545 __ bind(&result_in_receiver); |
| 3546 __ mov(result, receiver); |
| 3547 __ bind(&result_ok); |
| 3548 } |
3540 } | 3549 } |
3541 | 3550 |
3542 | 3551 |
3543 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { | 3552 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { |
3544 Register receiver = ToRegister(instr->receiver()); | 3553 Register receiver = ToRegister(instr->receiver()); |
3545 Register function = ToRegister(instr->function()); | 3554 Register function = ToRegister(instr->function()); |
3546 Register length = ToRegister(instr->length()); | 3555 Register length = ToRegister(instr->length()); |
3547 Register elements = ToRegister(instr->elements()); | 3556 Register elements = ToRegister(instr->elements()); |
3548 Register scratch = scratch0(); | 3557 Register scratch = scratch0(); |
3549 ASSERT(receiver.is(r0)); // Used for parameter count. | 3558 ASSERT(receiver.is(r0)); // Used for parameter count. |
(...skipping 2325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5875 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); | 5884 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); |
5876 __ ldr(result, FieldMemOperand(scratch, | 5885 __ ldr(result, FieldMemOperand(scratch, |
5877 FixedArray::kHeaderSize - kPointerSize)); | 5886 FixedArray::kHeaderSize - kPointerSize)); |
5878 __ bind(&done); | 5887 __ bind(&done); |
5879 } | 5888 } |
5880 | 5889 |
5881 | 5890 |
5882 #undef __ | 5891 #undef __ |
5883 | 5892 |
5884 } } // namespace v8::internal | 5893 } } // namespace v8::internal |
OLD | NEW |