| 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 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 706 break; | 706 break; |
| 707 | 707 |
| 708 case Slot::CONTEXT: | 708 case Slot::CONTEXT: |
| 709 // We bypass the general EmitSlotSearch because we know more about | 709 // We bypass the general EmitSlotSearch because we know more about |
| 710 // this specific context. | 710 // this specific context. |
| 711 | 711 |
| 712 // The variable in the decl always resides in the current function | 712 // The variable in the decl always resides in the current function |
| 713 // context. | 713 // context. |
| 714 ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); | 714 ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); |
| 715 if (FLAG_debug_code) { | 715 if (FLAG_debug_code) { |
| 716 // Check that we're not inside a 'with'. | 716 // Check that we're not inside a with or catch context. |
| 717 __ ldr(r1, ContextOperand(cp, Context::FCONTEXT_INDEX)); | 717 __ ldr(r1, FieldMemOperand(cp, HeapObject::kMapOffset)); |
| 718 __ cmp(r1, cp); | 718 __ CompareRoot(r1, Heap::kWithContextMapRootIndex); |
| 719 __ Check(eq, "Unexpected declaration in current context."); | 719 __ Check(ne, "Declaration in with context."); |
| 720 __ CompareRoot(r1, Heap::kCatchContextMapRootIndex); |
| 721 __ Check(ne, "Declaration in catch context."); |
| 720 } | 722 } |
| 721 if (mode == Variable::CONST) { | 723 if (mode == Variable::CONST) { |
| 722 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 724 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
| 723 __ str(ip, ContextOperand(cp, slot->index())); | 725 __ str(ip, ContextOperand(cp, slot->index())); |
| 724 // No write barrier since the_hole_value is in old space. | 726 // No write barrier since the_hole_value is in old space. |
| 725 } else if (function != NULL) { | 727 } else if (function != NULL) { |
| 726 VisitForAccumulatorValue(function); | 728 VisitForAccumulatorValue(function); |
| 727 __ str(result_register(), ContextOperand(cp, slot->index())); | 729 __ str(result_register(), ContextOperand(cp, slot->index())); |
| 728 int offset = Context::SlotOffset(slot->index()); | 730 int offset = Context::SlotOffset(slot->index()); |
| 729 // We know that we have written a function, which is not a smi. | 731 // We know that we have written a function, which is not a smi. |
| (...skipping 1130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1860 UNREACHABLE(); | 1862 UNREACHABLE(); |
| 1861 break; | 1863 break; |
| 1862 case Slot::LOCAL: | 1864 case Slot::LOCAL: |
| 1863 // Detect const reinitialization by checking for the hole value. | 1865 // Detect const reinitialization by checking for the hole value. |
| 1864 __ ldr(r1, MemOperand(fp, SlotOffset(slot))); | 1866 __ ldr(r1, MemOperand(fp, SlotOffset(slot))); |
| 1865 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 1867 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
| 1866 __ cmp(r1, ip); | 1868 __ cmp(r1, ip); |
| 1867 __ b(ne, &skip); | 1869 __ b(ne, &skip); |
| 1868 __ str(result_register(), MemOperand(fp, SlotOffset(slot))); | 1870 __ str(result_register(), MemOperand(fp, SlotOffset(slot))); |
| 1869 break; | 1871 break; |
| 1870 case Slot::CONTEXT: { | 1872 case Slot::CONTEXT: |
| 1871 __ ldr(r1, ContextOperand(cp, Context::FCONTEXT_INDEX)); | |
| 1872 __ ldr(r2, ContextOperand(r1, slot->index())); | |
| 1873 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | |
| 1874 __ cmp(r2, ip); | |
| 1875 __ b(ne, &skip); | |
| 1876 __ str(r0, ContextOperand(r1, slot->index())); | |
| 1877 int offset = Context::SlotOffset(slot->index()); | |
| 1878 __ mov(r3, r0); // Preserve the stored value in r0. | |
| 1879 __ RecordWrite(r1, Operand(offset), r3, r2); | |
| 1880 break; | |
| 1881 } | |
| 1882 case Slot::LOOKUP: | 1873 case Slot::LOOKUP: |
| 1883 __ push(r0); | 1874 __ push(r0); |
| 1884 __ mov(r0, Operand(slot->var()->name())); | 1875 __ mov(r0, Operand(slot->var()->name())); |
| 1885 __ Push(cp, r0); // Context and name. | 1876 __ Push(cp, r0); // Context and name. |
| 1886 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); | 1877 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); |
| 1887 break; | 1878 break; |
| 1888 } | 1879 } |
| 1889 __ bind(&skip); | 1880 __ bind(&skip); |
| 1890 | 1881 |
| 1891 } else if (var->mode() != Variable::CONST) { | 1882 } else if (var->mode() != Variable::CONST) { |
| (...skipping 1852 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3744 // TODO(svenpanne): Allowing format strings in Comment would be nice here... | 3735 // TODO(svenpanne): Allowing format strings in Comment would be nice here... |
| 3745 Comment cmt(masm_, comment); | 3736 Comment cmt(masm_, comment); |
| 3746 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); | 3737 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); |
| 3747 UnaryOverwriteMode overwrite = | 3738 UnaryOverwriteMode overwrite = |
| 3748 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; | 3739 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; |
| 3749 UnaryOpStub stub(expr->op(), overwrite); | 3740 UnaryOpStub stub(expr->op(), overwrite); |
| 3750 // UnaryOpStub expects the argument to be in the | 3741 // UnaryOpStub expects the argument to be in the |
| 3751 // accumulator register r0. | 3742 // accumulator register r0. |
| 3752 VisitForAccumulatorValue(expr->expression()); | 3743 VisitForAccumulatorValue(expr->expression()); |
| 3753 SetSourcePosition(expr->position()); | 3744 SetSourcePosition(expr->position()); |
| 3754 EmitCallIC(stub.GetCode(), NULL, expr->id()); | 3745 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); |
| 3755 context()->Plug(r0); | 3746 context()->Plug(r0); |
| 3756 } | 3747 } |
| 3757 | 3748 |
| 3758 | 3749 |
| 3759 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 3750 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
| 3760 Comment cmnt(masm_, "[ CountOperation"); | 3751 Comment cmnt(masm_, "[ CountOperation"); |
| 3761 SetSourcePosition(expr->position()); | 3752 SetSourcePosition(expr->position()); |
| 3762 | 3753 |
| 3763 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' | 3754 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' |
| 3764 // as the left-hand side. | 3755 // as the left-hand side. |
| (...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4264 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); | 4255 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); |
| 4265 __ str(value, MemOperand(fp, frame_offset)); | 4256 __ str(value, MemOperand(fp, frame_offset)); |
| 4266 } | 4257 } |
| 4267 | 4258 |
| 4268 | 4259 |
| 4269 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { | 4260 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { |
| 4270 __ ldr(dst, ContextOperand(cp, context_index)); | 4261 __ ldr(dst, ContextOperand(cp, context_index)); |
| 4271 } | 4262 } |
| 4272 | 4263 |
| 4273 | 4264 |
| 4265 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() { |
| 4266 if (scope()->is_global_scope()) { |
| 4267 // Contexts nested in the global context have a canonical empty function |
| 4268 // as their closure, not the anonymous closure containing the global |
| 4269 // code. Pass a smi sentinel and let the runtime look up the empty |
| 4270 // function. |
| 4271 __ mov(ip, Operand(Smi::FromInt(0))); |
| 4272 } else if (scope()->is_eval_scope()) { |
| 4273 // Contexts created by a call to eval have the same closure as the |
| 4274 // context calling eval, not the anonymous closure containing the eval |
| 4275 // code. Fetch it from the context. |
| 4276 __ ldr(ip, ContextOperand(cp, Context::CLOSURE_INDEX)); |
| 4277 } else { |
| 4278 ASSERT(scope()->is_function_scope()); |
| 4279 __ ldr(ip, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 4280 } |
| 4281 __ push(ip); |
| 4282 } |
| 4283 |
| 4284 |
| 4274 // ---------------------------------------------------------------------------- | 4285 // ---------------------------------------------------------------------------- |
| 4275 // Non-local control flow support. | 4286 // Non-local control flow support. |
| 4276 | 4287 |
| 4277 void FullCodeGenerator::EnterFinallyBlock() { | 4288 void FullCodeGenerator::EnterFinallyBlock() { |
| 4278 ASSERT(!result_register().is(r1)); | 4289 ASSERT(!result_register().is(r1)); |
| 4279 // Store result register while executing finally block. | 4290 // Store result register while executing finally block. |
| 4280 __ push(result_register()); | 4291 __ push(result_register()); |
| 4281 // Cook return address in link register to stack (smi encoded Code* delta) | 4292 // Cook return address in link register to stack (smi encoded Code* delta) |
| 4282 __ sub(r1, lr, Operand(masm_->CodeObject())); | 4293 __ sub(r1, lr, Operand(masm_->CodeObject())); |
| 4283 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); | 4294 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 4297 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | 4308 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. |
| 4298 __ add(pc, r1, Operand(masm_->CodeObject())); | 4309 __ add(pc, r1, Operand(masm_->CodeObject())); |
| 4299 } | 4310 } |
| 4300 | 4311 |
| 4301 | 4312 |
| 4302 #undef __ | 4313 #undef __ |
| 4303 | 4314 |
| 4304 } } // namespace v8::internal | 4315 } } // namespace v8::internal |
| 4305 | 4316 |
| 4306 #endif // V8_TARGET_ARCH_ARM | 4317 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |