Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(269)

Side by Side Diff: src/arm/codegen-arm.cc

Issue 3432022: Clean up some messiness in Scopes. (Closed)
Patch Set: Created 10 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/arm/full-codegen-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 // parameter twice (e.g., function (x, y, x)), and that parameter 239 // parameter twice (e.g., function (x, y, x)), and that parameter
240 // needs to be copied into the context, it must be the last argument 240 // needs to be copied into the context, it must be the last argument
241 // passed to the parameter that needs to be copied. This is a rare 241 // passed to the parameter that needs to be copied. This is a rare
242 // case so we don't check for it, instead we rely on the copying 242 // case so we don't check for it, instead we rely on the copying
243 // order: such a parameter is copied repeatedly into the same 243 // order: such a parameter is copied repeatedly into the same
244 // context location and thus the last value is what is seen inside 244 // context location and thus the last value is what is seen inside
245 // the function. 245 // the function.
246 frame_->AssertIsSpilled(); 246 frame_->AssertIsSpilled();
247 for (int i = 0; i < scope()->num_parameters(); i++) { 247 for (int i = 0; i < scope()->num_parameters(); i++) {
248 Variable* par = scope()->parameter(i); 248 Variable* par = scope()->parameter(i);
249 Slot* slot = par->slot(); 249 Slot* slot = par->AsSlot();
250 if (slot != NULL && slot->type() == Slot::CONTEXT) { 250 if (slot != NULL && slot->type() == Slot::CONTEXT) {
251 ASSERT(!scope()->is_global_scope()); // No params in global scope. 251 ASSERT(!scope()->is_global_scope()); // No params in global scope.
252 __ ldr(r1, frame_->ParameterAt(i)); 252 __ ldr(r1, frame_->ParameterAt(i));
253 // Loads r2 with context; used below in RecordWrite. 253 // Loads r2 with context; used below in RecordWrite.
254 __ str(r1, SlotOperand(slot, r2)); 254 __ str(r1, SlotOperand(slot, r2));
255 // Load the offset into r3. 255 // Load the offset into r3.
256 int slot_offset = 256 int slot_offset =
257 FixedArray::kHeaderSize + slot->index() * kPointerSize; 257 FixedArray::kHeaderSize + slot->index() * kPointerSize;
258 __ RecordWrite(r2, Operand(slot_offset), r3, r1); 258 __ RecordWrite(r2, Operand(slot_offset), r3, r1);
259 } 259 }
260 } 260 }
261 } 261 }
262 262
263 // Store the arguments object. This must happen after context 263 // Store the arguments object. This must happen after context
264 // initialization because the arguments object may be stored in 264 // initialization because the arguments object may be stored in
265 // the context. 265 // the context.
266 if (ArgumentsMode() != NO_ARGUMENTS_ALLOCATION) { 266 if (ArgumentsMode() != NO_ARGUMENTS_ALLOCATION) {
267 StoreArgumentsObject(true); 267 StoreArgumentsObject(true);
268 } 268 }
269 269
270 // Initialize ThisFunction reference if present. 270 // Initialize ThisFunction reference if present.
271 if (scope()->is_function_scope() && scope()->function() != NULL) { 271 if (scope()->is_function_scope() && scope()->function() != NULL) {
272 frame_->EmitPushRoot(Heap::kTheHoleValueRootIndex); 272 frame_->EmitPushRoot(Heap::kTheHoleValueRootIndex);
273 StoreToSlot(scope()->function()->slot(), NOT_CONST_INIT); 273 StoreToSlot(scope()->function()->AsSlot(), NOT_CONST_INIT);
274 } 274 }
275 275
276 // Initialize the function return target after the locals are set 276 // Initialize the function return target after the locals are set
277 // up, because it needs the expected frame height from the frame. 277 // up, because it needs the expected frame height from the frame.
278 function_return_.SetExpectedHeight(); 278 function_return_.SetExpectedHeight();
279 function_return_is_shadowed_ = false; 279 function_return_is_shadowed_ = false;
280 280
281 // Generate code to 'execute' declarations and initialize functions 281 // Generate code to 'execute' declarations and initialize functions
282 // (source elements). In case of an illegal redeclaration we need to 282 // (source elements). In case of an illegal redeclaration we need to
283 // handle that instead of processing the declarations. 283 // handle that instead of processing the declarations.
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 // frame pointer on the stack. 601 // frame pointer on the stack.
602 const int kReceiverDisplacement = 2 + scope()->num_parameters(); 602 const int kReceiverDisplacement = 2 + scope()->num_parameters();
603 __ add(r1, fp, Operand(kReceiverDisplacement * kPointerSize)); 603 __ add(r1, fp, Operand(kReceiverDisplacement * kPointerSize));
604 __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters()))); 604 __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters())));
605 frame_->Adjust(3); 605 frame_->Adjust(3);
606 __ Push(r2, r1, r0); 606 __ Push(r2, r1, r0);
607 frame_->CallStub(&stub, 3); 607 frame_->CallStub(&stub, 3);
608 frame_->EmitPush(r0); 608 frame_->EmitPush(r0);
609 } 609 }
610 610
611 Variable* arguments = scope()->arguments()->var(); 611 Variable* arguments = scope()->arguments();
612 Variable* shadow = scope()->arguments_shadow()->var(); 612 Variable* shadow = scope()->arguments_shadow();
613 ASSERT(arguments != NULL && arguments->slot() != NULL); 613 ASSERT(arguments != NULL && arguments->AsSlot() != NULL);
614 ASSERT(shadow != NULL && shadow->slot() != NULL); 614 ASSERT(shadow != NULL && shadow->AsSlot() != NULL);
615 JumpTarget done; 615 JumpTarget done;
616 if (mode == LAZY_ARGUMENTS_ALLOCATION && !initial) { 616 if (mode == LAZY_ARGUMENTS_ALLOCATION && !initial) {
617 // We have to skip storing into the arguments slot if it has 617 // We have to skip storing into the arguments slot if it has
618 // already been written to. This can happen if the a function 618 // already been written to. This can happen if the a function
619 // has a local variable named 'arguments'. 619 // has a local variable named 'arguments'.
620 LoadFromSlot(scope()->arguments()->var()->slot(), NOT_INSIDE_TYPEOF); 620 LoadFromSlot(scope()->arguments()->AsSlot(), NOT_INSIDE_TYPEOF);
621 Register arguments = frame_->PopToRegister(); 621 Register arguments = frame_->PopToRegister();
622 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 622 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
623 __ cmp(arguments, ip); 623 __ cmp(arguments, ip);
624 done.Branch(ne); 624 done.Branch(ne);
625 } 625 }
626 StoreToSlot(arguments->slot(), NOT_CONST_INIT); 626 StoreToSlot(arguments->AsSlot(), NOT_CONST_INIT);
627 if (mode == LAZY_ARGUMENTS_ALLOCATION) done.Bind(); 627 if (mode == LAZY_ARGUMENTS_ALLOCATION) done.Bind();
628 StoreToSlot(shadow->slot(), NOT_CONST_INIT); 628 StoreToSlot(shadow->AsSlot(), NOT_CONST_INIT);
629 } 629 }
630 630
631 631
632 void CodeGenerator::LoadTypeofExpression(Expression* expr) { 632 void CodeGenerator::LoadTypeofExpression(Expression* expr) {
633 // Special handling of identifiers as subexpressions of typeof. 633 // Special handling of identifiers as subexpressions of typeof.
634 Variable* variable = expr->AsVariableProxy()->AsVariable(); 634 Variable* variable = expr->AsVariableProxy()->AsVariable();
635 if (variable != NULL && !variable->is_this() && variable->is_global()) { 635 if (variable != NULL && !variable->is_this() && variable->is_global()) {
636 // For a global variable we build the property reference 636 // For a global variable we build the property reference
637 // <global>.<variable> and perform a (regular non-contextual) property 637 // <global>.<variable> and perform a (regular non-contextual) property
638 // load to make sure we do not get reference errors. 638 // load to make sure we do not get reference errors.
639 Slot global(variable, Slot::CONTEXT, Context::GLOBAL_INDEX); 639 Slot global(variable, Slot::CONTEXT, Context::GLOBAL_INDEX);
640 Literal key(variable->name()); 640 Literal key(variable->name());
641 Property property(&global, &key, RelocInfo::kNoPosition); 641 Property property(&global, &key, RelocInfo::kNoPosition);
642 Reference ref(this, &property); 642 Reference ref(this, &property);
643 ref.GetValue(); 643 ref.GetValue();
644 } else if (variable != NULL && variable->slot() != NULL) { 644 } else if (variable != NULL && variable->AsSlot() != NULL) {
645 // For a variable that rewrites to a slot, we signal it is the immediate 645 // For a variable that rewrites to a slot, we signal it is the immediate
646 // subexpression of a typeof. 646 // subexpression of a typeof.
647 LoadFromSlotCheckForArguments(variable->slot(), INSIDE_TYPEOF); 647 LoadFromSlotCheckForArguments(variable->AsSlot(), INSIDE_TYPEOF);
648 } else { 648 } else {
649 // Anything else can be handled normally. 649 // Anything else can be handled normally.
650 Load(expr); 650 Load(expr);
651 } 651 }
652 } 652 }
653 653
654 654
655 Reference::Reference(CodeGenerator* cgen, 655 Reference::Reference(CodeGenerator* cgen,
656 Expression* expression, 656 Expression* expression,
657 bool persist_after_get) 657 bool persist_after_get)
(...skipping 30 matching lines...) Expand all
688 Load(property->key()); 688 Load(property->key());
689 ref->set_type(Reference::KEYED); 689 ref->set_type(Reference::KEYED);
690 } 690 }
691 } else if (var != NULL) { 691 } else if (var != NULL) {
692 // The expression is a variable proxy that does not rewrite to a 692 // The expression is a variable proxy that does not rewrite to a
693 // property. Global variables are treated as named property references. 693 // property. Global variables are treated as named property references.
694 if (var->is_global()) { 694 if (var->is_global()) {
695 LoadGlobal(); 695 LoadGlobal();
696 ref->set_type(Reference::NAMED); 696 ref->set_type(Reference::NAMED);
697 } else { 697 } else {
698 ASSERT(var->slot() != NULL); 698 ASSERT(var->AsSlot() != NULL);
699 ref->set_type(Reference::SLOT); 699 ref->set_type(Reference::SLOT);
700 } 700 }
701 } else { 701 } else {
702 // Anything else is a runtime error. 702 // Anything else is a runtime error.
703 Load(e); 703 Load(e);
704 frame_->CallRuntime(Runtime::kThrowReferenceError, 1); 704 frame_->CallRuntime(Runtime::kThrowReferenceError, 1);
705 } 705 }
706 } 706 }
707 707
708 708
(...skipping 1002 matching lines...) Expand 10 before | Expand all | Expand 10 after
1711 // give us a megamorphic load site. Not super, but it works. 1711 // give us a megamorphic load site. Not super, but it works.
1712 Load(applicand); 1712 Load(applicand);
1713 Handle<String> name = Factory::LookupAsciiSymbol("apply"); 1713 Handle<String> name = Factory::LookupAsciiSymbol("apply");
1714 frame_->Dup(); 1714 frame_->Dup();
1715 frame_->CallLoadIC(name, RelocInfo::CODE_TARGET); 1715 frame_->CallLoadIC(name, RelocInfo::CODE_TARGET);
1716 frame_->EmitPush(r0); 1716 frame_->EmitPush(r0);
1717 1717
1718 // Load the receiver and the existing arguments object onto the 1718 // Load the receiver and the existing arguments object onto the
1719 // expression stack. Avoid allocating the arguments object here. 1719 // expression stack. Avoid allocating the arguments object here.
1720 Load(receiver); 1720 Load(receiver);
1721 LoadFromSlot(scope()->arguments()->var()->slot(), NOT_INSIDE_TYPEOF); 1721 LoadFromSlot(scope()->arguments()->AsSlot(), NOT_INSIDE_TYPEOF);
1722 1722
1723 // At this point the top two stack elements are probably in registers 1723 // At this point the top two stack elements are probably in registers
1724 // since they were just loaded. Ensure they are in regs and get the 1724 // since they were just loaded. Ensure they are in regs and get the
1725 // regs. 1725 // regs.
1726 Register receiver_reg = frame_->Peek2(); 1726 Register receiver_reg = frame_->Peek2();
1727 Register arguments_reg = frame_->Peek(); 1727 Register arguments_reg = frame_->Peek();
1728 1728
1729 // From now on the frame is spilled. 1729 // From now on the frame is spilled.
1730 frame_->SpillAll(); 1730 frame_->SpillAll();
1731 1731
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
1943 } 1943 }
1944 1944
1945 1945
1946 void CodeGenerator::VisitDeclaration(Declaration* node) { 1946 void CodeGenerator::VisitDeclaration(Declaration* node) {
1947 #ifdef DEBUG 1947 #ifdef DEBUG
1948 int original_height = frame_->height(); 1948 int original_height = frame_->height();
1949 #endif 1949 #endif
1950 Comment cmnt(masm_, "[ Declaration"); 1950 Comment cmnt(masm_, "[ Declaration");
1951 Variable* var = node->proxy()->var(); 1951 Variable* var = node->proxy()->var();
1952 ASSERT(var != NULL); // must have been resolved 1952 ASSERT(var != NULL); // must have been resolved
1953 Slot* slot = var->slot(); 1953 Slot* slot = var->AsSlot();
1954 1954
1955 // If it was not possible to allocate the variable at compile time, 1955 // If it was not possible to allocate the variable at compile time,
1956 // we need to "declare" it at runtime to make sure it actually 1956 // we need to "declare" it at runtime to make sure it actually
1957 // exists in the local context. 1957 // exists in the local context.
1958 if (slot != NULL && slot->type() == Slot::LOOKUP) { 1958 if (slot != NULL && slot->type() == Slot::LOOKUP) {
1959 // Variables with a "LOOKUP" slot were introduced as non-locals 1959 // Variables with a "LOOKUP" slot were introduced as non-locals
1960 // during variable resolution and must have mode DYNAMIC. 1960 // during variable resolution and must have mode DYNAMIC.
1961 ASSERT(var->is_dynamic()); 1961 ASSERT(var->is_dynamic());
1962 // For now, just do a runtime call. 1962 // For now, just do a runtime call.
1963 frame_->EmitPush(cp); 1963 frame_->EmitPush(cp);
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after
2473 node->break_target()->SetExpectedHeight(); 2473 node->break_target()->SetExpectedHeight();
2474 IncrementLoopNesting(); 2474 IncrementLoopNesting();
2475 2475
2476 // We know that the loop index is a smi if it is not modified in the 2476 // We know that the loop index is a smi if it is not modified in the
2477 // loop body and it is checked against a constant limit in the loop 2477 // loop body and it is checked against a constant limit in the loop
2478 // condition. In this case, we reset the static type information of the 2478 // condition. In this case, we reset the static type information of the
2479 // loop index to smi before compiling the body, the update expression, and 2479 // loop index to smi before compiling the body, the update expression, and
2480 // the bottom check of the loop condition. 2480 // the bottom check of the loop condition.
2481 TypeInfoCodeGenState type_info_scope(this, 2481 TypeInfoCodeGenState type_info_scope(this,
2482 node->is_fast_smi_loop() ? 2482 node->is_fast_smi_loop() ?
2483 node->loop_variable()->slot() : 2483 node->loop_variable()->AsSlot() :
2484 NULL, 2484 NULL,
2485 TypeInfo::Smi()); 2485 TypeInfo::Smi());
2486 2486
2487 // If there is no update statement, label the top of the loop with the 2487 // If there is no update statement, label the top of the loop with the
2488 // continue target, otherwise with the loop target. 2488 // continue target, otherwise with the loop target.
2489 JumpTarget loop(JumpTarget::BIDIRECTIONAL); 2489 JumpTarget loop(JumpTarget::BIDIRECTIONAL);
2490 if (node->next() == NULL) { 2490 if (node->next() == NULL) {
2491 node->continue_target()->SetExpectedHeight(); 2491 node->continue_target()->SetExpectedHeight();
2492 node->continue_target()->Bind(); 2492 node->continue_target()->Bind();
2493 } else { 2493 } else {
2494 node->continue_target()->SetExpectedHeight(); 2494 node->continue_target()->SetExpectedHeight();
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
2787 2787
2788 JumpTarget try_block; 2788 JumpTarget try_block;
2789 JumpTarget exit; 2789 JumpTarget exit;
2790 2790
2791 try_block.Call(); 2791 try_block.Call();
2792 // --- Catch block --- 2792 // --- Catch block ---
2793 frame_->EmitPush(r0); 2793 frame_->EmitPush(r0);
2794 2794
2795 // Store the caught exception in the catch variable. 2795 // Store the caught exception in the catch variable.
2796 Variable* catch_var = node->catch_var()->var(); 2796 Variable* catch_var = node->catch_var()->var();
2797 ASSERT(catch_var != NULL && catch_var->slot() != NULL); 2797 ASSERT(catch_var != NULL && catch_var->AsSlot() != NULL);
2798 StoreToSlot(catch_var->slot(), NOT_CONST_INIT); 2798 StoreToSlot(catch_var->AsSlot(), NOT_CONST_INIT);
2799 2799
2800 // Remove the exception from the stack. 2800 // Remove the exception from the stack.
2801 frame_->Drop(); 2801 frame_->Drop();
2802 2802
2803 { VirtualFrame::RegisterAllocationScope scope(this); 2803 { VirtualFrame::RegisterAllocationScope scope(this);
2804 VisitStatements(node->catch_block()->statements()); 2804 VisitStatements(node->catch_block()->statements());
2805 } 2805 }
2806 if (frame_ != NULL) { 2806 if (frame_ != NULL) {
2807 exit.Jump(); 2807 exit.Jump();
2808 } 2808 }
(...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after
3413 // introducing variables. In those cases, we do not want to 3413 // introducing variables. In those cases, we do not want to
3414 // perform a runtime call for all variables in the scope 3414 // perform a runtime call for all variables in the scope
3415 // containing the eval. 3415 // containing the eval.
3416 if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) { 3416 if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) {
3417 LoadFromGlobalSlotCheckExtensions(slot, typeof_state, slow); 3417 LoadFromGlobalSlotCheckExtensions(slot, typeof_state, slow);
3418 frame_->SpillAll(); 3418 frame_->SpillAll();
3419 done->Jump(); 3419 done->Jump();
3420 3420
3421 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) { 3421 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) {
3422 frame_->SpillAll(); 3422 frame_->SpillAll();
3423 Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot(); 3423 Slot* potential_slot = slot->var()->local_if_not_shadowed()->AsSlot();
3424 Expression* rewrite = slot->var()->local_if_not_shadowed()->rewrite(); 3424 Expression* rewrite = slot->var()->local_if_not_shadowed()->rewrite();
3425 if (potential_slot != NULL) { 3425 if (potential_slot != NULL) {
3426 // Generate fast case for locals that rewrite to slots. 3426 // Generate fast case for locals that rewrite to slots.
3427 __ ldr(r0, 3427 __ ldr(r0,
3428 ContextSlotOperandCheckExtensions(potential_slot, 3428 ContextSlotOperandCheckExtensions(potential_slot,
3429 r1, 3429 r1,
3430 r2, 3430 r2,
3431 slow)); 3431 slow));
3432 if (potential_slot->var()->mode() == Variable::CONST) { 3432 if (potential_slot->var()->mode() == Variable::CONST) {
3433 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 3433 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
3434 __ cmp(r0, ip); 3434 __ cmp(r0, ip);
3435 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); 3435 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
3436 } 3436 }
3437 done->Jump(); 3437 done->Jump();
3438 } else if (rewrite != NULL) { 3438 } else if (rewrite != NULL) {
3439 // Generate fast case for argument loads. 3439 // Generate fast case for argument loads.
3440 Property* property = rewrite->AsProperty(); 3440 Property* property = rewrite->AsProperty();
3441 if (property != NULL) { 3441 if (property != NULL) {
3442 VariableProxy* obj_proxy = property->obj()->AsVariableProxy(); 3442 VariableProxy* obj_proxy = property->obj()->AsVariableProxy();
3443 Literal* key_literal = property->key()->AsLiteral(); 3443 Literal* key_literal = property->key()->AsLiteral();
3444 if (obj_proxy != NULL && 3444 if (obj_proxy != NULL &&
3445 key_literal != NULL && 3445 key_literal != NULL &&
3446 obj_proxy->IsArguments() && 3446 obj_proxy->IsArguments() &&
3447 key_literal->handle()->IsSmi()) { 3447 key_literal->handle()->IsSmi()) {
3448 // Load arguments object if there are no eval-introduced 3448 // Load arguments object if there are no eval-introduced
3449 // variables. Then load the argument from the arguments 3449 // variables. Then load the argument from the arguments
3450 // object using keyed load. 3450 // object using keyed load.
3451 __ ldr(r0, 3451 __ ldr(r0,
3452 ContextSlotOperandCheckExtensions(obj_proxy->var()->slot(), 3452 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(),
3453 r1, 3453 r1,
3454 r2, 3454 r2,
3455 slow)); 3455 slow));
3456 frame_->EmitPush(r0); 3456 frame_->EmitPush(r0);
3457 __ mov(r1, Operand(key_literal->handle())); 3457 __ mov(r1, Operand(key_literal->handle()));
3458 frame_->EmitPush(r1); 3458 frame_->EmitPush(r1);
3459 EmitKeyedLoad(); 3459 EmitKeyedLoad();
3460 done->Jump(); 3460 done->Jump();
3461 } 3461 }
3462 } 3462 }
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
3728 } 3728 }
3729 3729
3730 3730
3731 void CodeGenerator::EmitSlotAssignment(Assignment* node) { 3731 void CodeGenerator::EmitSlotAssignment(Assignment* node) {
3732 #ifdef DEBUG 3732 #ifdef DEBUG
3733 int original_height = frame_->height(); 3733 int original_height = frame_->height();
3734 #endif 3734 #endif
3735 Comment cmnt(masm(), "[ Variable Assignment"); 3735 Comment cmnt(masm(), "[ Variable Assignment");
3736 Variable* var = node->target()->AsVariableProxy()->AsVariable(); 3736 Variable* var = node->target()->AsVariableProxy()->AsVariable();
3737 ASSERT(var != NULL); 3737 ASSERT(var != NULL);
3738 Slot* slot = var->slot(); 3738 Slot* slot = var->AsSlot();
3739 ASSERT(slot != NULL); 3739 ASSERT(slot != NULL);
3740 3740
3741 // Evaluate the right-hand side. 3741 // Evaluate the right-hand side.
3742 if (node->is_compound()) { 3742 if (node->is_compound()) {
3743 // For a compound assignment the right-hand side is a binary operation 3743 // For a compound assignment the right-hand side is a binary operation
3744 // between the current property value and the actual right-hand side. 3744 // between the current property value and the actual right-hand side.
3745 LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF); 3745 LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF);
3746 3746
3747 // Perform the binary operation. 3747 // Perform the binary operation.
3748 Literal* literal = node->value()->AsLiteral(); 3748 Literal* literal = node->value()->AsLiteral();
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
4129 Load(args->at(i)); 4129 Load(args->at(i));
4130 } 4130 }
4131 4131
4132 VirtualFrame::SpilledScope spilled_scope(frame_); 4132 VirtualFrame::SpilledScope spilled_scope(frame_);
4133 4133
4134 // If we know that eval can only be shadowed by eval-introduced 4134 // If we know that eval can only be shadowed by eval-introduced
4135 // variables we attempt to load the global eval function directly 4135 // variables we attempt to load the global eval function directly
4136 // in generated code. If we succeed, there is no need to perform a 4136 // in generated code. If we succeed, there is no need to perform a
4137 // context lookup in the runtime system. 4137 // context lookup in the runtime system.
4138 JumpTarget done; 4138 JumpTarget done;
4139 if (var->slot() != NULL && var->mode() == Variable::DYNAMIC_GLOBAL) { 4139 if (var->AsSlot() != NULL && var->mode() == Variable::DYNAMIC_GLOBAL) {
4140 ASSERT(var->slot()->type() == Slot::LOOKUP); 4140 ASSERT(var->AsSlot()->type() == Slot::LOOKUP);
4141 JumpTarget slow; 4141 JumpTarget slow;
4142 // Prepare the stack for the call to 4142 // Prepare the stack for the call to
4143 // ResolvePossiblyDirectEvalNoLookup by pushing the loaded 4143 // ResolvePossiblyDirectEvalNoLookup by pushing the loaded
4144 // function, the first argument to the eval call and the 4144 // function, the first argument to the eval call and the
4145 // receiver. 4145 // receiver.
4146 LoadFromGlobalSlotCheckExtensions(var->slot(), 4146 LoadFromGlobalSlotCheckExtensions(var->AsSlot(),
4147 NOT_INSIDE_TYPEOF, 4147 NOT_INSIDE_TYPEOF,
4148 &slow); 4148 &slow);
4149 frame_->EmitPush(r0); 4149 frame_->EmitPush(r0);
4150 if (arg_count > 0) { 4150 if (arg_count > 0) {
4151 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); 4151 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize));
4152 frame_->EmitPush(r1); 4152 frame_->EmitPush(r1);
4153 } else { 4153 } else {
4154 frame_->EmitPush(r2); 4154 frame_->EmitPush(r2);
4155 } 4155 }
4156 __ ldr(r1, frame_->Receiver()); 4156 __ ldr(r1, frame_->Receiver());
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
4218 // Setup the name register and call the IC initialization code. 4218 // Setup the name register and call the IC initialization code.
4219 __ mov(r2, Operand(var->name())); 4219 __ mov(r2, Operand(var->name()));
4220 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP; 4220 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
4221 Handle<Code> stub = ComputeCallInitialize(arg_count, in_loop); 4221 Handle<Code> stub = ComputeCallInitialize(arg_count, in_loop);
4222 CodeForSourcePosition(node->position()); 4222 CodeForSourcePosition(node->position());
4223 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET_CONTEXT, 4223 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET_CONTEXT,
4224 arg_count + 1); 4224 arg_count + 1);
4225 __ ldr(cp, frame_->Context()); 4225 __ ldr(cp, frame_->Context());
4226 frame_->EmitPush(r0); 4226 frame_->EmitPush(r0);
4227 4227
4228 } else if (var != NULL && var->slot() != NULL && 4228 } else if (var != NULL && var->AsSlot() != NULL &&
4229 var->slot()->type() == Slot::LOOKUP) { 4229 var->AsSlot()->type() == Slot::LOOKUP) {
4230 // ---------------------------------- 4230 // ----------------------------------
4231 // JavaScript examples: 4231 // JavaScript examples:
4232 // 4232 //
4233 // with (obj) foo(1, 2, 3) // foo may be in obj. 4233 // with (obj) foo(1, 2, 3) // foo may be in obj.
4234 // 4234 //
4235 // function f() {}; 4235 // function f() {};
4236 // function g() { 4236 // function g() {
4237 // eval(...); 4237 // eval(...);
4238 // f(); // f could be in extension object. 4238 // f(); // f could be in extension object.
4239 // } 4239 // }
4240 // ---------------------------------- 4240 // ----------------------------------
4241 4241
4242 JumpTarget slow, done; 4242 JumpTarget slow, done;
4243 4243
4244 // Generate fast case for loading functions from slots that 4244 // Generate fast case for loading functions from slots that
4245 // correspond to local/global variables or arguments unless they 4245 // correspond to local/global variables or arguments unless they
4246 // are shadowed by eval-introduced bindings. 4246 // are shadowed by eval-introduced bindings.
4247 EmitDynamicLoadFromSlotFastCase(var->slot(), 4247 EmitDynamicLoadFromSlotFastCase(var->AsSlot(),
4248 NOT_INSIDE_TYPEOF, 4248 NOT_INSIDE_TYPEOF,
4249 &slow, 4249 &slow,
4250 &done); 4250 &done);
4251 4251
4252 slow.Bind(); 4252 slow.Bind();
4253 // Load the function 4253 // Load the function
4254 frame_->EmitPush(cp); 4254 frame_->EmitPush(cp);
4255 frame_->EmitPush(Operand(var->name())); 4255 frame_->EmitPush(Operand(var->name()));
4256 frame_->CallRuntime(Runtime::kLoadContextSlot, 2); 4256 frame_->CallRuntime(Runtime::kLoadContextSlot, 2);
4257 // r0: slot value; r1: receiver 4257 // r0: slot value; r1: receiver
(...skipping 1663 matching lines...) Expand 10 before | Expand all | Expand 10 after
5921 } else if (op == Token::DELETE) { 5921 } else if (op == Token::DELETE) {
5922 Property* property = node->expression()->AsProperty(); 5922 Property* property = node->expression()->AsProperty();
5923 Variable* variable = node->expression()->AsVariableProxy()->AsVariable(); 5923 Variable* variable = node->expression()->AsVariableProxy()->AsVariable();
5924 if (property != NULL) { 5924 if (property != NULL) {
5925 Load(property->obj()); 5925 Load(property->obj());
5926 Load(property->key()); 5926 Load(property->key());
5927 frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, 2); 5927 frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, 2);
5928 frame_->EmitPush(r0); 5928 frame_->EmitPush(r0);
5929 5929
5930 } else if (variable != NULL) { 5930 } else if (variable != NULL) {
5931 Slot* slot = variable->slot(); 5931 Slot* slot = variable->AsSlot();
5932 if (variable->is_global()) { 5932 if (variable->is_global()) {
5933 LoadGlobal(); 5933 LoadGlobal();
5934 frame_->EmitPush(Operand(variable->name())); 5934 frame_->EmitPush(Operand(variable->name()));
5935 frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, 2); 5935 frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, 2);
5936 frame_->EmitPush(r0); 5936 frame_->EmitPush(r0);
5937 5937
5938 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { 5938 } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
5939 // lookup the context holding the named variable 5939 // lookup the context holding the named variable
5940 frame_->EmitPush(cp); 5940 frame_->EmitPush(cp);
5941 frame_->EmitPush(Operand(variable->name())); 5941 frame_->EmitPush(Operand(variable->name()));
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
6055 Comment cmnt(masm_, "[ CountOperation"); 6055 Comment cmnt(masm_, "[ CountOperation");
6056 VirtualFrame::RegisterAllocationScope scope(this); 6056 VirtualFrame::RegisterAllocationScope scope(this);
6057 6057
6058 bool is_postfix = node->is_postfix(); 6058 bool is_postfix = node->is_postfix();
6059 bool is_increment = node->op() == Token::INC; 6059 bool is_increment = node->op() == Token::INC;
6060 6060
6061 Variable* var = node->expression()->AsVariableProxy()->AsVariable(); 6061 Variable* var = node->expression()->AsVariableProxy()->AsVariable();
6062 bool is_const = (var != NULL && var->mode() == Variable::CONST); 6062 bool is_const = (var != NULL && var->mode() == Variable::CONST);
6063 bool is_slot = (var != NULL && var->mode() == Variable::VAR); 6063 bool is_slot = (var != NULL && var->mode() == Variable::VAR);
6064 6064
6065 if (!is_const && is_slot && type_info(var->slot()).IsSmi()) { 6065 if (!is_const && is_slot && type_info(var->AsSlot()).IsSmi()) {
6066 // The type info declares that this variable is always a Smi. That 6066 // The type info declares that this variable is always a Smi. That
6067 // means it is a Smi both before and after the increment/decrement. 6067 // means it is a Smi both before and after the increment/decrement.
6068 // Lets make use of that to make a very minimal count. 6068 // Lets make use of that to make a very minimal count.
6069 Reference target(this, node->expression(), !is_const); 6069 Reference target(this, node->expression(), !is_const);
6070 ASSERT(!target.is_illegal()); 6070 ASSERT(!target.is_illegal());
6071 target.GetValue(); // Pushes the value. 6071 target.GetValue(); // Pushes the value.
6072 Register value = frame_->PopToRegister(); 6072 Register value = frame_->PopToRegister();
6073 if (is_postfix) frame_->EmitPush(value); 6073 if (is_postfix) frame_->EmitPush(value);
6074 if (is_increment) { 6074 if (is_increment) {
6075 __ add(value, value, Operand(Smi::FromInt(1))); 6075 __ add(value, value, Operand(Smi::FromInt(1)));
(...skipping 1124 matching lines...) Expand 10 before | Expand all | Expand 10 after
7200 ASSERT(!cgen_->has_cc()); 7200 ASSERT(!cgen_->has_cc());
7201 MacroAssembler* masm = cgen_->masm(); 7201 MacroAssembler* masm = cgen_->masm();
7202 Property* property = expression_->AsProperty(); 7202 Property* property = expression_->AsProperty();
7203 if (property != NULL) { 7203 if (property != NULL) {
7204 cgen_->CodeForSourcePosition(property->position()); 7204 cgen_->CodeForSourcePosition(property->position());
7205 } 7205 }
7206 7206
7207 switch (type_) { 7207 switch (type_) {
7208 case SLOT: { 7208 case SLOT: {
7209 Comment cmnt(masm, "[ Load from Slot"); 7209 Comment cmnt(masm, "[ Load from Slot");
7210 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot(); 7210 Slot* slot = expression_->AsVariableProxy()->AsVariable()->AsSlot();
7211 ASSERT(slot != NULL); 7211 ASSERT(slot != NULL);
7212 DupIfPersist(); 7212 DupIfPersist();
7213 cgen_->LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF); 7213 cgen_->LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF);
7214 break; 7214 break;
7215 } 7215 }
7216 7216
7217 case NAMED: { 7217 case NAMED: {
7218 Variable* var = expression_->AsVariableProxy()->AsVariable(); 7218 Variable* var = expression_->AsVariableProxy()->AsVariable();
7219 bool is_global = var != NULL; 7219 bool is_global = var != NULL;
7220 ASSERT(!is_global || var->is_global()); 7220 ASSERT(!is_global || var->is_global());
(...skipping 23 matching lines...) Expand all
7244 MacroAssembler* masm = cgen_->masm(); 7244 MacroAssembler* masm = cgen_->masm();
7245 VirtualFrame* frame = cgen_->frame(); 7245 VirtualFrame* frame = cgen_->frame();
7246 Property* property = expression_->AsProperty(); 7246 Property* property = expression_->AsProperty();
7247 if (property != NULL) { 7247 if (property != NULL) {
7248 cgen_->CodeForSourcePosition(property->position()); 7248 cgen_->CodeForSourcePosition(property->position());
7249 } 7249 }
7250 7250
7251 switch (type_) { 7251 switch (type_) {
7252 case SLOT: { 7252 case SLOT: {
7253 Comment cmnt(masm, "[ Store to Slot"); 7253 Comment cmnt(masm, "[ Store to Slot");
7254 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot(); 7254 Slot* slot = expression_->AsVariableProxy()->AsVariable()->AsSlot();
7255 cgen_->StoreToSlot(slot, init_state); 7255 cgen_->StoreToSlot(slot, init_state);
7256 set_unloaded(); 7256 set_unloaded();
7257 break; 7257 break;
7258 } 7258 }
7259 7259
7260 case NAMED: { 7260 case NAMED: {
7261 Comment cmnt(masm, "[ Store to named Property"); 7261 Comment cmnt(masm, "[ Store to named Property");
7262 cgen_->EmitNamedStore(GetName(), false); 7262 cgen_->EmitNamedStore(GetName(), false);
7263 frame->EmitPush(r0); 7263 frame->EmitPush(r0);
7264 set_unloaded(); 7264 set_unloaded();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
7304 BinaryOpIC::GetName(runtime_operands_type_)); 7304 BinaryOpIC::GetName(runtime_operands_type_));
7305 return name_; 7305 return name_;
7306 } 7306 }
7307 7307
7308 7308
7309 #undef __ 7309 #undef __
7310 7310
7311 } } // namespace v8::internal 7311 } } // namespace v8::internal
7312 7312
7313 #endif // V8_TARGET_ARCH_ARM 7313 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/arm/full-codegen-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698