OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |