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

Side by Side Diff: src/ia32/full-codegen-ia32.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/ia32/codegen-ia32.cc ('k') | src/ia32/virtual-frame-ia32.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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 __ CallRuntime(Runtime::kNewContext, 1); 93 __ CallRuntime(Runtime::kNewContext, 1);
94 } 94 }
95 function_in_register = false; 95 function_in_register = false;
96 // Context is returned in both eax and esi. It replaces the context 96 // Context is returned in both eax and esi. It replaces the context
97 // passed to us. It's saved in the stack and kept live in esi. 97 // passed to us. It's saved in the stack and kept live in esi.
98 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi); 98 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi);
99 99
100 // Copy parameters into context if necessary. 100 // Copy parameters into context if necessary.
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 __ mov(eax, Operand(ebp, parameter_offset)); 108 __ mov(eax, Operand(ebp, parameter_offset));
109 // Store it in the context. 109 // Store it in the context.
110 int context_offset = Context::SlotOffset(slot->index()); 110 int context_offset = Context::SlotOffset(slot->index());
111 __ mov(Operand(esi, context_offset), eax); 111 __ mov(Operand(esi, context_offset), eax);
112 // Update the write barrier. This clobbers all involved 112 // Update the write barrier. This clobbers all involved
113 // registers, so we have use a third register to avoid 113 // registers, so we have use a third register to avoid
114 // clobbering esi. 114 // clobbering esi.
115 __ mov(ecx, esi); 115 __ mov(ecx, esi);
116 __ RecordWrite(ecx, context_offset, eax, ebx); 116 __ RecordWrite(ecx, context_offset, eax, ebx);
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 __ push(edi); 126 __ push(edi);
127 } else { 127 } else {
128 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 128 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
129 } 129 }
130 // Receiver is just before the parameters on the caller's stack. 130 // Receiver is just before the parameters on the caller's stack.
131 int offset = scope()->num_parameters() * kPointerSize; 131 int offset = scope()->num_parameters() * kPointerSize;
132 __ lea(edx, 132 __ lea(edx,
133 Operand(ebp, StandardFrameConstants::kCallerSPOffset + offset)); 133 Operand(ebp, StandardFrameConstants::kCallerSPOffset + offset));
134 __ push(edx); 134 __ push(edx);
135 __ push(Immediate(Smi::FromInt(scope()->num_parameters()))); 135 __ push(Immediate(Smi::FromInt(scope()->num_parameters())));
136 // Arguments to ArgumentsAccessStub: 136 // Arguments to ArgumentsAccessStub:
137 // function, receiver address, parameter count. 137 // function, receiver address, parameter count.
138 // The stub will rewrite receiver and parameter count if the previous 138 // The stub will rewrite receiver and parameter count if the previous
139 // stack frame was an arguments adapter frame. 139 // stack frame was an arguments adapter frame.
140 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); 140 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT);
141 __ CallStub(&stub); 141 __ CallStub(&stub);
142 __ mov(ecx, eax); // Duplicate result. 142 __ mov(ecx, eax); // Duplicate result.
143 Move(arguments->slot(), eax, ebx, edx); 143 Move(arguments->AsSlot(), eax, ebx, edx);
144 Slot* dot_arguments_slot = 144 Slot* dot_arguments_slot = scope()->arguments_shadow()->AsSlot();
145 scope()->arguments_shadow()->AsVariable()->slot();
146 Move(dot_arguments_slot, ecx, ebx, edx); 145 Move(dot_arguments_slot, ecx, ebx, edx);
147 } 146 }
148 147
149 { Comment cmnt(masm_, "[ Declarations"); 148 { Comment cmnt(masm_, "[ Declarations");
150 // For named function expressions, declare the function name as a 149 // For named function expressions, declare the function name as a
151 // constant. 150 // constant.
152 if (scope()->is_function_scope() && scope()->function() != NULL) { 151 if (scope()->is_function_scope() && scope()->function() != NULL) {
153 EmitDeclaration(scope()->function(), Variable::CONST, NULL); 152 EmitDeclaration(scope()->function(), Variable::CONST, NULL);
154 } 153 }
155 // Visit all the explicit declarations unless there is an illegal 154 // Visit all the explicit declarations unless there is an illegal
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 __ RecordWrite(scratch1, offset, src, scratch2); 508 __ RecordWrite(scratch1, offset, src, scratch2);
510 } 509 }
511 } 510 }
512 511
513 512
514 void FullCodeGenerator::EmitDeclaration(Variable* variable, 513 void FullCodeGenerator::EmitDeclaration(Variable* variable,
515 Variable::Mode mode, 514 Variable::Mode mode,
516 FunctionLiteral* function) { 515 FunctionLiteral* function) {
517 Comment cmnt(masm_, "[ Declaration"); 516 Comment cmnt(masm_, "[ Declaration");
518 ASSERT(variable != NULL); // Must have been resolved. 517 ASSERT(variable != NULL); // Must have been resolved.
519 Slot* slot = variable->slot(); 518 Slot* slot = variable->AsSlot();
520 Property* prop = variable->AsProperty(); 519 Property* prop = variable->AsProperty();
521 if (slot != NULL) { 520 if (slot != NULL) {
522 switch (slot->type()) { 521 switch (slot->type()) {
523 case Slot::PARAMETER: 522 case Slot::PARAMETER:
524 case Slot::LOCAL: 523 case Slot::LOCAL:
525 if (mode == Variable::CONST) { 524 if (mode == Variable::CONST) {
526 __ mov(Operand(ebp, SlotOffset(slot)), 525 __ mov(Operand(ebp, SlotOffset(slot)),
527 Immediate(Factory::the_hole_value())); 526 Immediate(Factory::the_hole_value()));
528 } else if (function != NULL) { 527 } else if (function != NULL) {
529 VisitForAccumulatorValue(function); 528 VisitForAccumulatorValue(function);
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
994 Label* done) { 993 Label* done) {
995 // Generate fast-case code for variables that might be shadowed by 994 // Generate fast-case code for variables that might be shadowed by
996 // eval-introduced variables. Eval is used a lot without 995 // eval-introduced variables. Eval is used a lot without
997 // introducing variables. In those cases, we do not want to 996 // introducing variables. In those cases, we do not want to
998 // perform a runtime call for all variables in the scope 997 // perform a runtime call for all variables in the scope
999 // containing the eval. 998 // containing the eval.
1000 if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) { 999 if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) {
1001 EmitLoadGlobalSlotCheckExtensions(slot, typeof_state, slow); 1000 EmitLoadGlobalSlotCheckExtensions(slot, typeof_state, slow);
1002 __ jmp(done); 1001 __ jmp(done);
1003 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) { 1002 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) {
1004 Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot(); 1003 Slot* potential_slot = slot->var()->local_if_not_shadowed()->AsSlot();
1005 Expression* rewrite = slot->var()->local_if_not_shadowed()->rewrite(); 1004 Expression* rewrite = slot->var()->local_if_not_shadowed()->rewrite();
1006 if (potential_slot != NULL) { 1005 if (potential_slot != NULL) {
1007 // Generate fast case for locals that rewrite to slots. 1006 // Generate fast case for locals that rewrite to slots.
1008 __ mov(eax, 1007 __ mov(eax,
1009 ContextSlotOperandCheckExtensions(potential_slot, slow)); 1008 ContextSlotOperandCheckExtensions(potential_slot, slow));
1010 if (potential_slot->var()->mode() == Variable::CONST) { 1009 if (potential_slot->var()->mode() == Variable::CONST) {
1011 __ cmp(eax, Factory::the_hole_value()); 1010 __ cmp(eax, Factory::the_hole_value());
1012 __ j(not_equal, done); 1011 __ j(not_equal, done);
1013 __ mov(eax, Factory::undefined_value()); 1012 __ mov(eax, Factory::undefined_value());
1014 } 1013 }
1015 __ jmp(done); 1014 __ jmp(done);
1016 } else if (rewrite != NULL) { 1015 } else if (rewrite != NULL) {
1017 // Generate fast case for calls of an argument function. 1016 // Generate fast case for calls of an argument function.
1018 Property* property = rewrite->AsProperty(); 1017 Property* property = rewrite->AsProperty();
1019 if (property != NULL) { 1018 if (property != NULL) {
1020 VariableProxy* obj_proxy = property->obj()->AsVariableProxy(); 1019 VariableProxy* obj_proxy = property->obj()->AsVariableProxy();
1021 Literal* key_literal = property->key()->AsLiteral(); 1020 Literal* key_literal = property->key()->AsLiteral();
1022 if (obj_proxy != NULL && 1021 if (obj_proxy != NULL &&
1023 key_literal != NULL && 1022 key_literal != NULL &&
1024 obj_proxy->IsArguments() && 1023 obj_proxy->IsArguments() &&
1025 key_literal->handle()->IsSmi()) { 1024 key_literal->handle()->IsSmi()) {
1026 // Load arguments object if there are no eval-introduced 1025 // Load arguments object if there are no eval-introduced
1027 // variables. Then load the argument from the arguments 1026 // variables. Then load the argument from the arguments
1028 // object using keyed load. 1027 // object using keyed load.
1029 __ mov(edx, 1028 __ mov(edx,
1030 ContextSlotOperandCheckExtensions(obj_proxy->var()->slot(), 1029 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(),
1031 slow)); 1030 slow));
1032 __ mov(eax, Immediate(key_literal->handle())); 1031 __ mov(eax, Immediate(key_literal->handle()));
1033 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 1032 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1034 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1033 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1035 __ jmp(done); 1034 __ jmp(done);
1036 } 1035 }
1037 } 1036 }
1038 } 1037 }
1039 } 1038 }
1040 } 1039 }
1041 1040
1042 1041
1043 void FullCodeGenerator::EmitVariableLoad(Variable* var) { 1042 void FullCodeGenerator::EmitVariableLoad(Variable* var) {
1044 // Four cases: non-this global variables, lookup slots, all other 1043 // Four cases: non-this global variables, lookup slots, all other
1045 // types of slots, and parameters that rewrite to explicit property 1044 // types of slots, and parameters that rewrite to explicit property
1046 // accesses on the arguments object. 1045 // accesses on the arguments object.
1047 Slot* slot = var->slot(); 1046 Slot* slot = var->AsSlot();
1048 Property* property = var->AsProperty(); 1047 Property* property = var->AsProperty();
1049 1048
1050 if (var->is_global() && !var->is_this()) { 1049 if (var->is_global() && !var->is_this()) {
1051 Comment cmnt(masm_, "Global variable"); 1050 Comment cmnt(masm_, "Global variable");
1052 // Use inline caching. Variable name is passed in ecx and the global 1051 // Use inline caching. Variable name is passed in ecx and the global
1053 // object on the stack. 1052 // object on the stack.
1054 __ mov(eax, CodeGenerator::GlobalObject()); 1053 __ mov(eax, CodeGenerator::GlobalObject());
1055 __ mov(ecx, var->name()); 1054 __ mov(ecx, var->name());
1056 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1055 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1057 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); 1056 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1093 } 1092 }
1094 1093
1095 } else { 1094 } else {
1096 Comment cmnt(masm_, "Rewritten parameter"); 1095 Comment cmnt(masm_, "Rewritten parameter");
1097 ASSERT_NOT_NULL(property); 1096 ASSERT_NOT_NULL(property);
1098 // Rewritten parameter accesses are of the form "slot[literal]". 1097 // Rewritten parameter accesses are of the form "slot[literal]".
1099 1098
1100 // Assert that the object is in a slot. 1099 // Assert that the object is in a slot.
1101 Variable* object_var = property->obj()->AsVariableProxy()->AsVariable(); 1100 Variable* object_var = property->obj()->AsVariableProxy()->AsVariable();
1102 ASSERT_NOT_NULL(object_var); 1101 ASSERT_NOT_NULL(object_var);
1103 Slot* object_slot = object_var->slot(); 1102 Slot* object_slot = object_var->AsSlot();
1104 ASSERT_NOT_NULL(object_slot); 1103 ASSERT_NOT_NULL(object_slot);
1105 1104
1106 // Load the object. 1105 // Load the object.
1107 MemOperand object_loc = EmitSlotSearch(object_slot, eax); 1106 MemOperand object_loc = EmitSlotSearch(object_slot, eax);
1108 __ mov(edx, object_loc); 1107 __ mov(edx, object_loc);
1109 1108
1110 // Assert that the key is a smi. 1109 // Assert that the key is a smi.
1111 Literal* key_literal = property->key()->AsLiteral(); 1110 Literal* key_literal = property->key()->AsLiteral();
1112 ASSERT_NOT_NULL(key_literal); 1111 ASSERT_NOT_NULL(key_literal);
1113 ASSERT(key_literal->handle()->IsSmi()); 1112 ASSERT(key_literal->handle()->IsSmi());
(...skipping 688 matching lines...) Expand 10 before | Expand all | Expand 10 after
1802 } 1801 }
1803 } 1802 }
1804 } 1803 }
1805 1804
1806 1805
1807 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 1806 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1808 Token::Value op) { 1807 Token::Value op) {
1809 // Left-hand sides that rewrite to explicit property accesses do not reach 1808 // Left-hand sides that rewrite to explicit property accesses do not reach
1810 // here. 1809 // here.
1811 ASSERT(var != NULL); 1810 ASSERT(var != NULL);
1812 ASSERT(var->is_global() || var->slot() != NULL); 1811 ASSERT(var->is_global() || var->AsSlot() != NULL);
1813 1812
1814 if (var->is_global()) { 1813 if (var->is_global()) {
1815 ASSERT(!var->is_this()); 1814 ASSERT(!var->is_this());
1816 // Assignment to a global variable. Use inline caching for the 1815 // Assignment to a global variable. Use inline caching for the
1817 // assignment. Right-hand-side value is passed in eax, variable name in 1816 // assignment. Right-hand-side value is passed in eax, variable name in
1818 // ecx, and the global object on the stack. 1817 // ecx, and the global object on the stack.
1819 __ mov(ecx, var->name()); 1818 __ mov(ecx, var->name());
1820 __ mov(edx, CodeGenerator::GlobalObject()); 1819 __ mov(edx, CodeGenerator::GlobalObject());
1821 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 1820 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
1822 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1821 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1823 1822
1824 } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) { 1823 } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) {
1825 // Perform the assignment for non-const variables and for initialization 1824 // Perform the assignment for non-const variables and for initialization
1826 // of const variables. Const assignments are simply skipped. 1825 // of const variables. Const assignments are simply skipped.
1827 Label done; 1826 Label done;
1828 Slot* slot = var->slot(); 1827 Slot* slot = var->AsSlot();
1829 switch (slot->type()) { 1828 switch (slot->type()) {
1830 case Slot::PARAMETER: 1829 case Slot::PARAMETER:
1831 case Slot::LOCAL: 1830 case Slot::LOCAL:
1832 if (op == Token::INIT_CONST) { 1831 if (op == Token::INIT_CONST) {
1833 // Detect const reinitialization by checking for the hole value. 1832 // Detect const reinitialization by checking for the hole value.
1834 __ mov(edx, Operand(ebp, SlotOffset(slot))); 1833 __ mov(edx, Operand(ebp, SlotOffset(slot)));
1835 __ cmp(edx, Factory::the_hole_value()); 1834 __ cmp(edx, Factory::the_hole_value());
1836 __ j(not_equal, &done); 1835 __ j(not_equal, &done);
1837 } 1836 }
1838 // Perform the assignment. 1837 // Perform the assignment.
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
2079 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2078 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2080 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); 2079 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
2081 __ CallStub(&stub); 2080 __ CallStub(&stub);
2082 // Restore context register. 2081 // Restore context register.
2083 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2082 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2084 context()->DropAndPlug(1, eax); 2083 context()->DropAndPlug(1, eax);
2085 } else if (var != NULL && !var->is_this() && var->is_global()) { 2084 } else if (var != NULL && !var->is_this() && var->is_global()) {
2086 // Push global object as receiver for the call IC. 2085 // Push global object as receiver for the call IC.
2087 __ push(CodeGenerator::GlobalObject()); 2086 __ push(CodeGenerator::GlobalObject());
2088 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); 2087 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT);
2089 } else if (var != NULL && var->slot() != NULL && 2088 } else if (var != NULL && var->AsSlot() != NULL &&
2090 var->slot()->type() == Slot::LOOKUP) { 2089 var->AsSlot()->type() == Slot::LOOKUP) {
2091 // Call to a lookup slot (dynamically introduced variable). 2090 // Call to a lookup slot (dynamically introduced variable).
2092 Label slow, done; 2091 Label slow, done;
2093 2092
2094 // Generate code for loading from variables potentially shadowed 2093 // Generate code for loading from variables potentially shadowed
2095 // by eval-introduced variables. 2094 // by eval-introduced variables.
2096 EmitDynamicLoadFromSlotFastCase(var->slot(), 2095 EmitDynamicLoadFromSlotFastCase(var->AsSlot(),
2097 NOT_INSIDE_TYPEOF, 2096 NOT_INSIDE_TYPEOF,
2098 &slow, 2097 &slow,
2099 &done); 2098 &done);
2100 2099
2101 __ bind(&slow); 2100 __ bind(&slow);
2102 // Call the runtime to find the function to call (returned in eax) 2101 // Call the runtime to find the function to call (returned in eax)
2103 // and the object holding it (returned in edx). 2102 // and the object holding it (returned in edx).
2104 __ push(context_register()); 2103 __ push(context_register());
2105 __ push(Immediate(var->name())); 2104 __ push(Immediate(var->name()));
2106 __ CallRuntime(Runtime::kLoadContextSlot, 2); 2105 __ CallRuntime(Runtime::kLoadContextSlot, 2);
(...skipping 981 matching lines...) Expand 10 before | Expand all | Expand 10 after
3088 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3087 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3089 Property* prop = expr->expression()->AsProperty(); 3088 Property* prop = expr->expression()->AsProperty();
3090 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); 3089 Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
3091 if (prop == NULL && var == NULL) { 3090 if (prop == NULL && var == NULL) {
3092 // Result of deleting non-property, non-variable reference is true. 3091 // Result of deleting non-property, non-variable reference is true.
3093 // The subexpression may have side effects. 3092 // The subexpression may have side effects.
3094 VisitForEffect(expr->expression()); 3093 VisitForEffect(expr->expression());
3095 context()->Plug(true); 3094 context()->Plug(true);
3096 } else if (var != NULL && 3095 } else if (var != NULL &&
3097 !var->is_global() && 3096 !var->is_global() &&
3098 var->slot() != NULL && 3097 var->AsSlot() != NULL &&
3099 var->slot()->type() != Slot::LOOKUP) { 3098 var->AsSlot()->type() != Slot::LOOKUP) {
3100 // Result of deleting non-global, non-dynamic variables is false. 3099 // Result of deleting non-global, non-dynamic variables is false.
3101 // The subexpression does not have side effects. 3100 // The subexpression does not have side effects.
3102 context()->Plug(false); 3101 context()->Plug(false);
3103 } else { 3102 } else {
3104 // Property or variable reference. Call the delete builtin with 3103 // Property or variable reference. Call the delete builtin with
3105 // object and property name as arguments. 3104 // object and property name as arguments.
3106 if (prop != NULL) { 3105 if (prop != NULL) {
3107 VisitForStackValue(prop->obj()); 3106 VisitForStackValue(prop->obj());
3108 VisitForStackValue(prop->key()); 3107 VisitForStackValue(prop->key());
3109 } else if (var->is_global()) { 3108 } else if (var->is_global()) {
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
3386 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { 3385 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) {
3387 Comment cmnt(masm_, "Global variable"); 3386 Comment cmnt(masm_, "Global variable");
3388 __ mov(eax, CodeGenerator::GlobalObject()); 3387 __ mov(eax, CodeGenerator::GlobalObject());
3389 __ mov(ecx, Immediate(proxy->name())); 3388 __ mov(ecx, Immediate(proxy->name()));
3390 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 3389 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
3391 // Use a regular load, not a contextual load, to avoid a reference 3390 // Use a regular load, not a contextual load, to avoid a reference
3392 // error. 3391 // error.
3393 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3392 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3394 context()->Plug(eax); 3393 context()->Plug(eax);
3395 } else if (proxy != NULL && 3394 } else if (proxy != NULL &&
3396 proxy->var()->slot() != NULL && 3395 proxy->var()->AsSlot() != NULL &&
3397 proxy->var()->slot()->type() == Slot::LOOKUP) { 3396 proxy->var()->AsSlot()->type() == Slot::LOOKUP) {
3398 Label done, slow; 3397 Label done, slow;
3399 3398
3400 // Generate code for loading from variables potentially shadowed 3399 // Generate code for loading from variables potentially shadowed
3401 // by eval-introduced variables. 3400 // by eval-introduced variables.
3402 Slot* slot = proxy->var()->slot(); 3401 Slot* slot = proxy->var()->AsSlot();
3403 EmitDynamicLoadFromSlotFastCase(slot, INSIDE_TYPEOF, &slow, &done); 3402 EmitDynamicLoadFromSlotFastCase(slot, INSIDE_TYPEOF, &slow, &done);
3404 3403
3405 __ bind(&slow); 3404 __ bind(&slow);
3406 __ push(esi); 3405 __ push(esi);
3407 __ push(Immediate(proxy->name())); 3406 __ push(Immediate(proxy->name()));
3408 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); 3407 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
3409 __ bind(&done); 3408 __ bind(&done);
3410 3409
3411 context()->Plug(eax); 3410 context()->Plug(eax);
3412 } else { 3411 } else {
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
3717 // And return. 3716 // And return.
3718 __ ret(0); 3717 __ ret(0);
3719 } 3718 }
3720 3719
3721 3720
3722 #undef __ 3721 #undef __
3723 3722
3724 } } // namespace v8::internal 3723 } } // namespace v8::internal
3725 3724
3726 #endif // V8_TARGET_ARCH_IA32 3725 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/codegen-ia32.cc ('k') | src/ia32/virtual-frame-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698