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

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

Issue 3432022: Clean up some messiness in Scopes. (Closed)
Patch Set: Created 10 years, 3 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 | « src/arm/codegen-arm.cc ('k') | src/ast.h » ('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 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 } else { 93 } else {
94 __ CallRuntime(Runtime::kNewContext, 1); 94 __ CallRuntime(Runtime::kNewContext, 1);
95 } 95 }
96 function_in_register = false; 96 function_in_register = false;
97 // Context is returned in both r0 and cp. It replaces the context 97 // Context is returned in both r0 and cp. It replaces the context
98 // passed to us. It's saved in the stack and kept live in cp. 98 // passed to us. It's saved in the stack and kept live in cp.
99 __ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 99 __ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
100 // Copy any necessary parameters into the context. 100 // Copy any necessary parameters into the context.
101 int num_parameters = scope()->num_parameters(); 101 int num_parameters = scope()->num_parameters();
102 for (int i = 0; i < num_parameters; i++) { 102 for (int i = 0; i < num_parameters; i++) {
103 Slot* slot = scope()->parameter(i)->slot(); 103 Slot* slot = scope()->parameter(i)->AsSlot();
104 if (slot != NULL && slot->type() == Slot::CONTEXT) { 104 if (slot != NULL && slot->type() == Slot::CONTEXT) {
105 int parameter_offset = StandardFrameConstants::kCallerSPOffset + 105 int parameter_offset = StandardFrameConstants::kCallerSPOffset +
106 (num_parameters - 1 - i) * kPointerSize; 106 (num_parameters - 1 - i) * kPointerSize;
107 // Load parameter from stack. 107 // Load parameter from stack.
108 __ ldr(r0, MemOperand(fp, parameter_offset)); 108 __ ldr(r0, MemOperand(fp, parameter_offset));
109 // Store it in the context. 109 // Store it in the context.
110 __ mov(r1, Operand(Context::SlotOffset(slot->index()))); 110 __ mov(r1, Operand(Context::SlotOffset(slot->index())));
111 __ str(r0, MemOperand(cp, r1)); 111 __ str(r0, MemOperand(cp, r1));
112 // Update the write barrier. This clobbers all involved 112 // Update the write barrier. This clobbers all involved
113 // registers, so we have to use two more registers to avoid 113 // registers, so we have to use two more registers to avoid
114 // clobbering cp. 114 // clobbering cp.
115 __ mov(r2, Operand(cp)); 115 __ mov(r2, Operand(cp));
116 __ RecordWrite(r2, Operand(r1), r3, r0); 116 __ RecordWrite(r2, Operand(r1), r3, r0);
117 } 117 }
118 } 118 }
119 } 119 }
120 120
121 Variable* arguments = scope()->arguments()->AsVariable(); 121 Variable* arguments = scope()->arguments();
122 if (arguments != NULL) { 122 if (arguments != NULL) {
123 // Function uses arguments object. 123 // Function uses arguments object.
124 Comment cmnt(masm_, "[ Allocate arguments object"); 124 Comment cmnt(masm_, "[ Allocate arguments object");
125 if (!function_in_register) { 125 if (!function_in_register) {
126 // Load this again, if it's used by the local context below. 126 // Load this again, if it's used by the local context below.
127 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 127 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
128 } else { 128 } else {
129 __ mov(r3, r1); 129 __ mov(r3, r1);
130 } 130 }
131 // Receiver is just before the parameters on the caller's stack. 131 // Receiver is just before the parameters on the caller's stack.
132 int offset = scope()->num_parameters() * kPointerSize; 132 int offset = scope()->num_parameters() * kPointerSize;
133 __ add(r2, fp, 133 __ add(r2, fp,
134 Operand(StandardFrameConstants::kCallerSPOffset + offset)); 134 Operand(StandardFrameConstants::kCallerSPOffset + offset));
135 __ mov(r1, Operand(Smi::FromInt(scope()->num_parameters()))); 135 __ mov(r1, Operand(Smi::FromInt(scope()->num_parameters())));
136 __ Push(r3, r2, r1); 136 __ Push(r3, r2, r1);
137 137
138 // Arguments to ArgumentsAccessStub: 138 // Arguments to ArgumentsAccessStub:
139 // function, receiver address, parameter count. 139 // function, receiver address, parameter count.
140 // The stub will rewrite receiever and parameter count if the previous 140 // The stub will rewrite receiever and parameter count if the previous
141 // stack frame was an arguments adapter frame. 141 // stack frame was an arguments adapter frame.
142 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); 142 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT);
143 __ CallStub(&stub); 143 __ CallStub(&stub);
144 // Duplicate the value; move-to-slot operation might clobber registers. 144 // Duplicate the value; move-to-slot operation might clobber registers.
145 __ mov(r3, r0); 145 __ mov(r3, r0);
146 Move(arguments->slot(), r0, r1, r2); 146 Move(arguments->AsSlot(), r0, r1, r2);
147 Slot* dot_arguments_slot = 147 Slot* dot_arguments_slot = scope()->arguments_shadow()->AsSlot();
148 scope()->arguments_shadow()->AsVariable()->slot();
149 Move(dot_arguments_slot, r3, r1, r2); 148 Move(dot_arguments_slot, r3, r1, r2);
150 } 149 }
151 150
152 { Comment cmnt(masm_, "[ Declarations"); 151 { Comment cmnt(masm_, "[ Declarations");
153 // For named function expressions, declare the function name as a 152 // For named function expressions, declare the function name as a
154 // constant. 153 // constant.
155 if (scope()->is_function_scope() && scope()->function() != NULL) { 154 if (scope()->is_function_scope() && scope()->function() != NULL) {
156 EmitDeclaration(scope()->function(), Variable::CONST, NULL); 155 EmitDeclaration(scope()->function(), Variable::CONST, NULL);
157 } 156 }
158 // Visit all the explicit declarations unless there is an illegal 157 // Visit all the explicit declarations unless there is an illegal
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 src); 522 src);
524 } 523 }
525 } 524 }
526 525
527 526
528 void FullCodeGenerator::EmitDeclaration(Variable* variable, 527 void FullCodeGenerator::EmitDeclaration(Variable* variable,
529 Variable::Mode mode, 528 Variable::Mode mode,
530 FunctionLiteral* function) { 529 FunctionLiteral* function) {
531 Comment cmnt(masm_, "[ Declaration"); 530 Comment cmnt(masm_, "[ Declaration");
532 ASSERT(variable != NULL); // Must have been resolved. 531 ASSERT(variable != NULL); // Must have been resolved.
533 Slot* slot = variable->slot(); 532 Slot* slot = variable->AsSlot();
534 Property* prop = variable->AsProperty(); 533 Property* prop = variable->AsProperty();
535 534
536 if (slot != NULL) { 535 if (slot != NULL) {
537 switch (slot->type()) { 536 switch (slot->type()) {
538 case Slot::PARAMETER: 537 case Slot::PARAMETER:
539 case Slot::LOCAL: 538 case Slot::LOCAL:
540 if (mode == Variable::CONST) { 539 if (mode == Variable::CONST) {
541 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 540 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
542 __ str(ip, MemOperand(fp, SlotOffset(slot))); 541 __ str(ip, MemOperand(fp, SlotOffset(slot)));
543 } else if (function != NULL) { 542 } else if (function != NULL) {
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 Label* done) { 916 Label* done) {
918 // Generate fast-case code for variables that might be shadowed by 917 // Generate fast-case code for variables that might be shadowed by
919 // eval-introduced variables. Eval is used a lot without 918 // eval-introduced variables. Eval is used a lot without
920 // introducing variables. In those cases, we do not want to 919 // introducing variables. In those cases, we do not want to
921 // perform a runtime call for all variables in the scope 920 // perform a runtime call for all variables in the scope
922 // containing the eval. 921 // containing the eval.
923 if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) { 922 if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) {
924 EmitLoadGlobalSlotCheckExtensions(slot, typeof_state, slow); 923 EmitLoadGlobalSlotCheckExtensions(slot, typeof_state, slow);
925 __ jmp(done); 924 __ jmp(done);
926 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) { 925 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) {
927 Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot(); 926 Slot* potential_slot = slot->var()->local_if_not_shadowed()->AsSlot();
928 Expression* rewrite = slot->var()->local_if_not_shadowed()->rewrite(); 927 Expression* rewrite = slot->var()->local_if_not_shadowed()->rewrite();
929 if (potential_slot != NULL) { 928 if (potential_slot != NULL) {
930 // Generate fast case for locals that rewrite to slots. 929 // Generate fast case for locals that rewrite to slots.
931 __ ldr(r0, ContextSlotOperandCheckExtensions(potential_slot, slow)); 930 __ ldr(r0, ContextSlotOperandCheckExtensions(potential_slot, slow));
932 if (potential_slot->var()->mode() == Variable::CONST) { 931 if (potential_slot->var()->mode() == Variable::CONST) {
933 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 932 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
934 __ cmp(r0, ip); 933 __ cmp(r0, ip);
935 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); 934 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
936 } 935 }
937 __ jmp(done); 936 __ jmp(done);
938 } else if (rewrite != NULL) { 937 } else if (rewrite != NULL) {
939 // Generate fast case for calls of an argument function. 938 // Generate fast case for calls of an argument function.
940 Property* property = rewrite->AsProperty(); 939 Property* property = rewrite->AsProperty();
941 if (property != NULL) { 940 if (property != NULL) {
942 VariableProxy* obj_proxy = property->obj()->AsVariableProxy(); 941 VariableProxy* obj_proxy = property->obj()->AsVariableProxy();
943 Literal* key_literal = property->key()->AsLiteral(); 942 Literal* key_literal = property->key()->AsLiteral();
944 if (obj_proxy != NULL && 943 if (obj_proxy != NULL &&
945 key_literal != NULL && 944 key_literal != NULL &&
946 obj_proxy->IsArguments() && 945 obj_proxy->IsArguments() &&
947 key_literal->handle()->IsSmi()) { 946 key_literal->handle()->IsSmi()) {
948 // Load arguments object if there are no eval-introduced 947 // Load arguments object if there are no eval-introduced
949 // variables. Then load the argument from the arguments 948 // variables. Then load the argument from the arguments
950 // object using keyed load. 949 // object using keyed load.
951 __ ldr(r1, 950 __ ldr(r1,
952 ContextSlotOperandCheckExtensions(obj_proxy->var()->slot(), 951 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(),
953 slow)); 952 slow));
954 __ mov(r0, Operand(key_literal->handle())); 953 __ mov(r0, Operand(key_literal->handle()));
955 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 954 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
956 EmitCallIC(ic, RelocInfo::CODE_TARGET); 955 EmitCallIC(ic, RelocInfo::CODE_TARGET);
957 __ jmp(done); 956 __ jmp(done);
958 } 957 }
959 } 958 }
960 } 959 }
961 } 960 }
962 } 961 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1020 : RelocInfo::CODE_TARGET_CONTEXT; 1019 : RelocInfo::CODE_TARGET_CONTEXT;
1021 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1020 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1022 EmitCallIC(ic, mode); 1021 EmitCallIC(ic, mode);
1023 } 1022 }
1024 1023
1025 1024
1026 void FullCodeGenerator::EmitVariableLoad(Variable* var) { 1025 void FullCodeGenerator::EmitVariableLoad(Variable* var) {
1027 // Four cases: non-this global variables, lookup slots, all other 1026 // Four cases: non-this global variables, lookup slots, all other
1028 // types of slots, and parameters that rewrite to explicit property 1027 // types of slots, and parameters that rewrite to explicit property
1029 // accesses on the arguments object. 1028 // accesses on the arguments object.
1030 Slot* slot = var->slot(); 1029 Slot* slot = var->AsSlot();
1031 Property* property = var->AsProperty(); 1030 Property* property = var->AsProperty();
1032 1031
1033 if (var->is_global() && !var->is_this()) { 1032 if (var->is_global() && !var->is_this()) {
1034 Comment cmnt(masm_, "Global variable"); 1033 Comment cmnt(masm_, "Global variable");
1035 // Use inline caching. Variable name is passed in r2 and the global 1034 // Use inline caching. Variable name is passed in r2 and the global
1036 // object (receiver) in r0. 1035 // object (receiver) in r0.
1037 __ ldr(r0, CodeGenerator::GlobalObject()); 1036 __ ldr(r0, CodeGenerator::GlobalObject());
1038 __ mov(r2, Operand(var->name())); 1037 __ mov(r2, Operand(var->name()));
1039 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1038 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1040 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); 1039 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1073 context()->Plug(slot); 1072 context()->Plug(slot);
1074 } 1073 }
1075 } else { 1074 } else {
1076 Comment cmnt(masm_, "Rewritten parameter"); 1075 Comment cmnt(masm_, "Rewritten parameter");
1077 ASSERT_NOT_NULL(property); 1076 ASSERT_NOT_NULL(property);
1078 // Rewritten parameter accesses are of the form "slot[literal]". 1077 // Rewritten parameter accesses are of the form "slot[literal]".
1079 1078
1080 // Assert that the object is in a slot. 1079 // Assert that the object is in a slot.
1081 Variable* object_var = property->obj()->AsVariableProxy()->AsVariable(); 1080 Variable* object_var = property->obj()->AsVariableProxy()->AsVariable();
1082 ASSERT_NOT_NULL(object_var); 1081 ASSERT_NOT_NULL(object_var);
1083 Slot* object_slot = object_var->slot(); 1082 Slot* object_slot = object_var->AsSlot();
1084 ASSERT_NOT_NULL(object_slot); 1083 ASSERT_NOT_NULL(object_slot);
1085 1084
1086 // Load the object. 1085 // Load the object.
1087 Move(r1, object_slot); 1086 Move(r1, object_slot);
1088 1087
1089 // Assert that the key is a smi. 1088 // Assert that the key is a smi.
1090 Literal* key_literal = property->key()->AsLiteral(); 1089 Literal* key_literal = property->key()->AsLiteral();
1091 ASSERT_NOT_NULL(key_literal); 1090 ASSERT_NOT_NULL(key_literal);
1092 ASSERT(key_literal->handle()->IsSmi()); 1091 ASSERT(key_literal->handle()->IsSmi());
1093 1092
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after
1482 } 1481 }
1483 } 1482 }
1484 } 1483 }
1485 1484
1486 1485
1487 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 1486 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1488 Token::Value op) { 1487 Token::Value op) {
1489 // Left-hand sides that rewrite to explicit property accesses do not reach 1488 // Left-hand sides that rewrite to explicit property accesses do not reach
1490 // here. 1489 // here.
1491 ASSERT(var != NULL); 1490 ASSERT(var != NULL);
1492 ASSERT(var->is_global() || var->slot() != NULL); 1491 ASSERT(var->is_global() || var->AsSlot() != NULL);
1493 1492
1494 if (var->is_global()) { 1493 if (var->is_global()) {
1495 ASSERT(!var->is_this()); 1494 ASSERT(!var->is_this());
1496 // Assignment to a global variable. Use inline caching for the 1495 // Assignment to a global variable. Use inline caching for the
1497 // assignment. Right-hand-side value is passed in r0, variable name in 1496 // assignment. Right-hand-side value is passed in r0, variable name in
1498 // r2, and the global object in r1. 1497 // r2, and the global object in r1.
1499 __ mov(r2, Operand(var->name())); 1498 __ mov(r2, Operand(var->name()));
1500 __ ldr(r1, CodeGenerator::GlobalObject()); 1499 __ ldr(r1, CodeGenerator::GlobalObject());
1501 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 1500 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
1502 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1501 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1503 1502
1504 } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) { 1503 } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) {
1505 // Perform the assignment for non-const variables and for initialization 1504 // Perform the assignment for non-const variables and for initialization
1506 // of const variables. Const assignments are simply skipped. 1505 // of const variables. Const assignments are simply skipped.
1507 Label done; 1506 Label done;
1508 Slot* slot = var->slot(); 1507 Slot* slot = var->AsSlot();
1509 switch (slot->type()) { 1508 switch (slot->type()) {
1510 case Slot::PARAMETER: 1509 case Slot::PARAMETER:
1511 case Slot::LOCAL: 1510 case Slot::LOCAL:
1512 if (op == Token::INIT_CONST) { 1511 if (op == Token::INIT_CONST) {
1513 // Detect const reinitialization by checking for the hole value. 1512 // Detect const reinitialization by checking for the hole value.
1514 __ ldr(r1, MemOperand(fp, SlotOffset(slot))); 1513 __ ldr(r1, MemOperand(fp, SlotOffset(slot)));
1515 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 1514 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
1516 __ cmp(r1, ip); 1515 __ cmp(r1, ip);
1517 __ b(ne, &done); 1516 __ b(ne, &done);
1518 } 1517 }
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
1778 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); 1777 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
1779 __ CallStub(&stub); 1778 __ CallStub(&stub);
1780 // Restore context register. 1779 // Restore context register.
1781 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1780 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1782 context()->DropAndPlug(1, r0); 1781 context()->DropAndPlug(1, r0);
1783 } else if (var != NULL && !var->is_this() && var->is_global()) { 1782 } else if (var != NULL && !var->is_this() && var->is_global()) {
1784 // Push global object as receiver for the call IC. 1783 // Push global object as receiver for the call IC.
1785 __ ldr(r0, CodeGenerator::GlobalObject()); 1784 __ ldr(r0, CodeGenerator::GlobalObject());
1786 __ push(r0); 1785 __ push(r0);
1787 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); 1786 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT);
1788 } else if (var != NULL && var->slot() != NULL && 1787 } else if (var != NULL && var->AsSlot() != NULL &&
1789 var->slot()->type() == Slot::LOOKUP) { 1788 var->AsSlot()->type() == Slot::LOOKUP) {
1790 // Call to a lookup slot (dynamically introduced variable). 1789 // Call to a lookup slot (dynamically introduced variable).
1791 Label slow, done; 1790 Label slow, done;
1792 1791
1793 // Generate code for loading from variables potentially shadowed 1792 // Generate code for loading from variables potentially shadowed
1794 // by eval-introduced variables. 1793 // by eval-introduced variables.
1795 EmitDynamicLoadFromSlotFastCase(var->slot(), 1794 EmitDynamicLoadFromSlotFastCase(var->AsSlot(),
1796 NOT_INSIDE_TYPEOF, 1795 NOT_INSIDE_TYPEOF,
1797 &slow, 1796 &slow,
1798 &done); 1797 &done);
1799 1798
1800 __ bind(&slow); 1799 __ bind(&slow);
1801 // Call the runtime to find the function to call (returned in r0) 1800 // Call the runtime to find the function to call (returned in r0)
1802 // and the object holding it (returned in edx). 1801 // and the object holding it (returned in edx).
1803 __ push(context_register()); 1802 __ push(context_register());
1804 __ mov(r2, Operand(var->name())); 1803 __ mov(r2, Operand(var->name()));
1805 __ push(r2); 1804 __ push(r2);
(...skipping 969 matching lines...) Expand 10 before | Expand all | Expand 10 after
2775 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 2774 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
2776 Property* prop = expr->expression()->AsProperty(); 2775 Property* prop = expr->expression()->AsProperty();
2777 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); 2776 Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
2778 if (prop == NULL && var == NULL) { 2777 if (prop == NULL && var == NULL) {
2779 // Result of deleting non-property, non-variable reference is true. 2778 // Result of deleting non-property, non-variable reference is true.
2780 // The subexpression may have side effects. 2779 // The subexpression may have side effects.
2781 VisitForEffect(expr->expression()); 2780 VisitForEffect(expr->expression());
2782 context()->Plug(true); 2781 context()->Plug(true);
2783 } else if (var != NULL && 2782 } else if (var != NULL &&
2784 !var->is_global() && 2783 !var->is_global() &&
2785 var->slot() != NULL && 2784 var->AsSlot() != NULL &&
2786 var->slot()->type() != Slot::LOOKUP) { 2785 var->AsSlot()->type() != Slot::LOOKUP) {
2787 // Result of deleting non-global, non-dynamic variables is false. 2786 // Result of deleting non-global, non-dynamic variables is false.
2788 // The subexpression does not have side effects. 2787 // The subexpression does not have side effects.
2789 context()->Plug(false); 2788 context()->Plug(false);
2790 } else { 2789 } else {
2791 // Property or variable reference. Call the delete builtin with 2790 // Property or variable reference. Call the delete builtin with
2792 // object and property name as arguments. 2791 // object and property name as arguments.
2793 if (prop != NULL) { 2792 if (prop != NULL) {
2794 VisitForStackValue(prop->obj()); 2793 VisitForStackValue(prop->obj());
2795 VisitForStackValue(prop->key()); 2794 VisitForStackValue(prop->key());
2796 } else if (var->is_global()) { 2795 } else if (var->is_global()) {
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
3061 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { 3060 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) {
3062 Comment cmnt(masm_, "Global variable"); 3061 Comment cmnt(masm_, "Global variable");
3063 __ ldr(r0, CodeGenerator::GlobalObject()); 3062 __ ldr(r0, CodeGenerator::GlobalObject());
3064 __ mov(r2, Operand(proxy->name())); 3063 __ mov(r2, Operand(proxy->name()));
3065 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 3064 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
3066 // Use a regular load, not a contextual load, to avoid a reference 3065 // Use a regular load, not a contextual load, to avoid a reference
3067 // error. 3066 // error.
3068 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3067 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3069 context()->Plug(r0); 3068 context()->Plug(r0);
3070 } else if (proxy != NULL && 3069 } else if (proxy != NULL &&
3071 proxy->var()->slot() != NULL && 3070 proxy->var()->AsSlot() != NULL &&
3072 proxy->var()->slot()->type() == Slot::LOOKUP) { 3071 proxy->var()->AsSlot()->type() == Slot::LOOKUP) {
3073 Label done, slow; 3072 Label done, slow;
3074 3073
3075 // Generate code for loading from variables potentially shadowed 3074 // Generate code for loading from variables potentially shadowed
3076 // by eval-introduced variables. 3075 // by eval-introduced variables.
3077 Slot* slot = proxy->var()->slot(); 3076 Slot* slot = proxy->var()->AsSlot();
3078 EmitDynamicLoadFromSlotFastCase(slot, INSIDE_TYPEOF, &slow, &done); 3077 EmitDynamicLoadFromSlotFastCase(slot, INSIDE_TYPEOF, &slow, &done);
3079 3078
3080 __ bind(&slow); 3079 __ bind(&slow);
3081 __ mov(r0, Operand(proxy->name())); 3080 __ mov(r0, Operand(proxy->name()));
3082 __ Push(cp, r0); 3081 __ Push(cp, r0);
3083 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); 3082 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
3084 __ bind(&done); 3083 __ bind(&done);
3085 3084
3086 context()->Plug(r0); 3085 context()->Plug(r0);
3087 } else { 3086 } else {
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
3384 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. 3383 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value.
3385 __ add(pc, r1, Operand(masm_->CodeObject())); 3384 __ add(pc, r1, Operand(masm_->CodeObject()));
3386 } 3385 }
3387 3386
3388 3387
3389 #undef __ 3388 #undef __
3390 3389
3391 } } // namespace v8::internal 3390 } } // namespace v8::internal
3392 3391
3393 #endif // V8_TARGET_ARCH_ARM 3392 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/codegen-arm.cc ('k') | src/ast.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698