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

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

Issue 2514393002: [fullcodegen] Remove deprecated support for lookup variables, eval and with. (Closed)
Patch Set: Address comment Created 4 years 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/full-codegen/full-codegen.cc ('k') | src/full-codegen/mips/full-codegen-mips.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_IA32 5 #if V8_TARGET_ARCH_IA32
6 6
7 #include "src/full-codegen/full-codegen.h" 7 #include "src/full-codegen/full-codegen.h"
8 #include "src/ast/compile-time-value.h" 8 #include "src/ast/compile-time-value.h"
9 #include "src/ast/scopes.h" 9 #include "src/ast/scopes.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 if (variable->binding_needs_init()) { 749 if (variable->binding_needs_init()) {
750 Comment cmnt(masm_, "[ VariableDeclaration"); 750 Comment cmnt(masm_, "[ VariableDeclaration");
751 EmitDebugCheckDeclarationContext(variable); 751 EmitDebugCheckDeclarationContext(variable);
752 __ mov(ContextOperand(esi, variable->index()), 752 __ mov(ContextOperand(esi, variable->index()),
753 Immediate(isolate()->factory()->the_hole_value())); 753 Immediate(isolate()->factory()->the_hole_value()));
754 // No write barrier since the hole value is in old space. 754 // No write barrier since the hole value is in old space.
755 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 755 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
756 } 756 }
757 break; 757 break;
758 758
759 case VariableLocation::LOOKUP: { 759 case VariableLocation::LOOKUP:
760 Comment cmnt(masm_, "[ VariableDeclaration");
761 DCHECK_EQ(VAR, variable->mode());
762 DCHECK(!variable->binding_needs_init());
763 __ push(Immediate(variable->name()));
764 __ CallRuntime(Runtime::kDeclareEvalVar);
765 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
766 break;
767 }
768
769 case VariableLocation::MODULE: 760 case VariableLocation::MODULE:
770 UNREACHABLE(); 761 UNREACHABLE();
771 } 762 }
772 } 763 }
773 764
774 765
775 void FullCodeGenerator::VisitFunctionDeclaration( 766 void FullCodeGenerator::VisitFunctionDeclaration(
776 FunctionDeclaration* declaration) { 767 FunctionDeclaration* declaration) {
777 VariableProxy* proxy = declaration->proxy(); 768 VariableProxy* proxy = declaration->proxy();
778 Variable* variable = proxy->var(); 769 Variable* variable = proxy->var();
(...skipping 29 matching lines...) Expand all
808 Context::SlotOffset(variable->index()), 799 Context::SlotOffset(variable->index()),
809 result_register(), 800 result_register(),
810 ecx, 801 ecx,
811 kDontSaveFPRegs, 802 kDontSaveFPRegs,
812 EMIT_REMEMBERED_SET, 803 EMIT_REMEMBERED_SET,
813 OMIT_SMI_CHECK); 804 OMIT_SMI_CHECK);
814 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 805 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
815 break; 806 break;
816 } 807 }
817 808
818 case VariableLocation::LOOKUP: { 809 case VariableLocation::LOOKUP:
819 Comment cmnt(masm_, "[ FunctionDeclaration");
820 PushOperand(variable->name());
821 VisitForStackValue(declaration->fun());
822 CallRuntimeWithOperands(Runtime::kDeclareEvalFunction);
823 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
824 break;
825 }
826
827 case VariableLocation::MODULE: 810 case VariableLocation::MODULE:
828 UNREACHABLE(); 811 UNREACHABLE();
829 } 812 }
830 } 813 }
831 814
832 815
833 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 816 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
834 // Call the runtime to declare the globals. 817 // Call the runtime to declare the globals.
835 __ Push(pairs); 818 __ Push(pairs);
836 __ Push(Smi::FromInt(DeclareGlobalsFlags())); 819 __ Push(Smi::FromInt(DeclareGlobalsFlags()));
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
1102 1085
1103 void FullCodeGenerator::EmitSetHomeObjectAccumulator(Expression* initializer, 1086 void FullCodeGenerator::EmitSetHomeObjectAccumulator(Expression* initializer,
1104 int offset, 1087 int offset,
1105 FeedbackVectorSlot slot) { 1088 FeedbackVectorSlot slot) {
1106 DCHECK(NeedsHomeObject(initializer)); 1089 DCHECK(NeedsHomeObject(initializer));
1107 __ mov(StoreDescriptor::ReceiverRegister(), eax); 1090 __ mov(StoreDescriptor::ReceiverRegister(), eax);
1108 __ mov(StoreDescriptor::ValueRegister(), Operand(esp, offset * kPointerSize)); 1091 __ mov(StoreDescriptor::ValueRegister(), Operand(esp, offset * kPointerSize));
1109 CallStoreIC(slot, isolate()->factory()->home_object_symbol()); 1092 CallStoreIC(slot, isolate()->factory()->home_object_symbol());
1110 } 1093 }
1111 1094
1112
1113 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
1114 TypeofMode typeof_mode,
1115 Label* slow) {
1116 Register context = esi;
1117 Register temp = edx;
1118
1119 int to_check = scope()->ContextChainLengthUntilOutermostSloppyEval();
1120 for (Scope* s = scope(); to_check > 0; s = s->outer_scope()) {
1121 if (!s->NeedsContext()) continue;
1122 if (s->calls_sloppy_eval()) {
1123 // Check that extension is "the hole".
1124 __ JumpIfNotRoot(ContextOperand(context, Context::EXTENSION_INDEX),
1125 Heap::kTheHoleValueRootIndex, slow);
1126 }
1127 // Load next context in chain.
1128 __ mov(temp, ContextOperand(context, Context::PREVIOUS_INDEX));
1129 // Walk the rest of the chain without clobbering esi.
1130 context = temp;
1131 to_check--;
1132 }
1133
1134 // All extension objects were empty and it is safe to use a normal global
1135 // load machinery.
1136 EmitGlobalVariableLoad(proxy, typeof_mode);
1137 }
1138
1139
1140 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
1141 Label* slow) {
1142 DCHECK(var->IsContextSlot());
1143 Register context = esi;
1144 Register temp = ebx;
1145
1146 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) {
1147 if (s->NeedsContext()) {
1148 if (s->calls_sloppy_eval()) {
1149 // Check that extension is "the hole".
1150 __ JumpIfNotRoot(ContextOperand(context, Context::EXTENSION_INDEX),
1151 Heap::kTheHoleValueRootIndex, slow);
1152 }
1153 __ mov(temp, ContextOperand(context, Context::PREVIOUS_INDEX));
1154 // Walk the rest of the chain without clobbering esi.
1155 context = temp;
1156 }
1157 }
1158 // Check that last extension is "the hole".
1159 __ JumpIfNotRoot(ContextOperand(context, Context::EXTENSION_INDEX),
1160 Heap::kTheHoleValueRootIndex, slow);
1161
1162 // This function is used only for loads, not stores, so it's safe to
1163 // return an esi-based operand (the write barrier cannot be allowed to
1164 // destroy the esi register).
1165 return ContextOperand(context, var->index());
1166 }
1167
1168
1169 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
1170 TypeofMode typeof_mode,
1171 Label* slow, Label* done) {
1172 // Generate fast-case code for variables that might be shadowed by
1173 // eval-introduced variables. Eval is used a lot without
1174 // introducing variables. In those cases, we do not want to
1175 // perform a runtime call for all variables in the scope
1176 // containing the eval.
1177 Variable* var = proxy->var();
1178 if (var->mode() == DYNAMIC_GLOBAL) {
1179 EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
1180 __ jmp(done);
1181 } else if (var->mode() == DYNAMIC_LOCAL) {
1182 Variable* local = var->local_if_not_shadowed();
1183 __ mov(eax, ContextSlotOperandCheckExtensions(local, slow));
1184 if (local->binding_needs_init()) {
1185 __ cmp(eax, isolate()->factory()->the_hole_value());
1186 __ j(not_equal, done);
1187 __ push(Immediate(var->name()));
1188 __ CallRuntime(Runtime::kThrowReferenceError);
1189 } else {
1190 __ jmp(done);
1191 }
1192 }
1193 }
1194
1195 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1095 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1196 TypeofMode typeof_mode) { 1096 TypeofMode typeof_mode) {
1197 SetExpressionPosition(proxy); 1097 SetExpressionPosition(proxy);
1198 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS); 1098 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS);
1199 Variable* var = proxy->var(); 1099 Variable* var = proxy->var();
1200 1100
1201 // Three cases: global variables, lookup variables, and all other types of 1101 // Two cases: global variables and all other types of variables.
1202 // variables.
1203 switch (var->location()) { 1102 switch (var->location()) {
1204 case VariableLocation::UNALLOCATED: { 1103 case VariableLocation::UNALLOCATED: {
1205 Comment cmnt(masm_, "[ Global variable"); 1104 Comment cmnt(masm_, "[ Global variable");
1206 EmitGlobalVariableLoad(proxy, typeof_mode); 1105 EmitGlobalVariableLoad(proxy, typeof_mode);
1207 context()->Plug(eax); 1106 context()->Plug(eax);
1208 break; 1107 break;
1209 } 1108 }
1210 1109
1211 case VariableLocation::PARAMETER: 1110 case VariableLocation::PARAMETER:
1212 case VariableLocation::LOCAL: 1111 case VariableLocation::LOCAL:
(...skipping 12 matching lines...) Expand all
1225 __ push(Immediate(var->name())); 1124 __ push(Immediate(var->name()));
1226 __ CallRuntime(Runtime::kThrowReferenceError); 1125 __ CallRuntime(Runtime::kThrowReferenceError);
1227 __ bind(&done); 1126 __ bind(&done);
1228 context()->Plug(eax); 1127 context()->Plug(eax);
1229 break; 1128 break;
1230 } 1129 }
1231 context()->Plug(var); 1130 context()->Plug(var);
1232 break; 1131 break;
1233 } 1132 }
1234 1133
1235 case VariableLocation::LOOKUP: { 1134 case VariableLocation::LOOKUP:
1236 Comment cmnt(masm_, "[ Lookup variable");
1237 Label done, slow;
1238 // Generate code for loading from variables potentially shadowed
1239 // by eval-introduced variables.
1240 EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
1241 __ bind(&slow);
1242 __ push(Immediate(var->name()));
1243 Runtime::FunctionId function_id =
1244 typeof_mode == NOT_INSIDE_TYPEOF
1245 ? Runtime::kLoadLookupSlot
1246 : Runtime::kLoadLookupSlotInsideTypeof;
1247 __ CallRuntime(function_id);
1248 __ bind(&done);
1249 context()->Plug(eax);
1250 break;
1251 }
1252
1253 case VariableLocation::MODULE: 1135 case VariableLocation::MODULE:
1254 UNREACHABLE(); 1136 UNREACHABLE();
1255 } 1137 }
1256 } 1138 }
1257 1139
1258 1140
1259 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { 1141 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
1260 Expression* expression = (property == NULL) ? NULL : property->value(); 1142 Expression* expression = (property == NULL) ? NULL : property->value();
1261 if (expression == NULL) { 1143 if (expression == NULL) {
1262 PushOperand(isolate()->factory()->null_value()); 1144 PushOperand(isolate()->factory()->null_value());
(...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after
2000 __ mov(edx, location); 1882 __ mov(edx, location);
2001 __ cmp(edx, isolate()->factory()->the_hole_value()); 1883 __ cmp(edx, isolate()->factory()->the_hole_value());
2002 __ j(equal, &uninitialized_this); 1884 __ j(equal, &uninitialized_this);
2003 __ push(Immediate(var->name())); 1885 __ push(Immediate(var->name()));
2004 __ CallRuntime(Runtime::kThrowReferenceError); 1886 __ CallRuntime(Runtime::kThrowReferenceError);
2005 __ bind(&uninitialized_this); 1887 __ bind(&uninitialized_this);
2006 EmitStoreToStackLocalOrContextSlot(var, location); 1888 EmitStoreToStackLocalOrContextSlot(var, location);
2007 1889
2008 } else { 1890 } else {
2009 DCHECK(var->mode() != CONST || op == Token::INIT); 1891 DCHECK(var->mode() != CONST || op == Token::INIT);
2010 if (var->IsLookupSlot()) { 1892 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2011 // Assignment to var. 1893 DCHECK(!var->IsLookupSlot());
2012 __ Push(Immediate(var->name())); 1894 // Assignment to var or initializing assignment to let/const in harmony
2013 __ Push(eax); 1895 // mode.
2014 __ CallRuntime(is_strict(language_mode()) 1896 MemOperand location = VarOperand(var, ecx);
2015 ? Runtime::kStoreLookupSlot_Strict 1897 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) {
2016 : Runtime::kStoreLookupSlot_Sloppy); 1898 // Check for an uninitialized let binding.
2017 } else { 1899 __ mov(edx, location);
2018 // Assignment to var or initializing assignment to let/const in harmony 1900 __ cmp(edx, isolate()->factory()->the_hole_value());
2019 // mode. 1901 __ Check(equal, kLetBindingReInitialization);
2020 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2021 MemOperand location = VarOperand(var, ecx);
2022 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) {
2023 // Check for an uninitialized let binding.
2024 __ mov(edx, location);
2025 __ cmp(edx, isolate()->factory()->the_hole_value());
2026 __ Check(equal, kLetBindingReInitialization);
2027 }
2028 EmitStoreToStackLocalOrContextSlot(var, location);
2029 } 1902 }
1903 EmitStoreToStackLocalOrContextSlot(var, location);
2030 } 1904 }
2031 } 1905 }
2032 1906
2033 1907
2034 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 1908 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2035 // Assignment to a property, using a named store IC. 1909 // Assignment to a property, using a named store IC.
2036 // eax : value 1910 // eax : value
2037 // esp[0] : receiver 1911 // esp[0] : receiver
2038 Property* prop = expr->target()->AsProperty(); 1912 Property* prop = expr->target()->AsProperty();
2039 DCHECK(prop != NULL); 1913 DCHECK(prop != NULL);
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
2239 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 2113 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
2240 __ Move(eax, Immediate(arg_count)); 2114 __ Move(eax, Immediate(arg_count));
2241 CallIC(code); 2115 CallIC(code);
2242 OperandStackDepthDecrement(arg_count + 1); 2116 OperandStackDepthDecrement(arg_count + 1);
2243 2117
2244 RecordJSReturnSite(expr); 2118 RecordJSReturnSite(expr);
2245 RestoreContext(); 2119 RestoreContext();
2246 context()->DropAndPlug(1, eax); 2120 context()->DropAndPlug(1, eax);
2247 } 2121 }
2248 2122
2249 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) {
2250 int arg_count = expr->arguments()->length();
2251 // Push copy of the first argument or undefined if it doesn't exist.
2252 if (arg_count > 0) {
2253 __ push(Operand(esp, arg_count * kPointerSize));
2254 } else {
2255 __ push(Immediate(isolate()->factory()->undefined_value()));
2256 }
2257
2258 // Push the enclosing function.
2259 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
2260
2261 // Push the language mode.
2262 __ push(Immediate(Smi::FromInt(language_mode())));
2263
2264 // Push the start position of the scope the calls resides in.
2265 __ push(Immediate(Smi::FromInt(scope()->start_position())));
2266
2267 // Push the source position of the eval call.
2268 __ push(Immediate(Smi::FromInt(expr->position())));
2269
2270 // Do the runtime call.
2271 __ CallRuntime(Runtime::kResolvePossiblyDirectEval);
2272 }
2273
2274
2275 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls.
2276 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
2277 VariableProxy* callee = expr->expression()->AsVariableProxy();
2278 if (callee->var()->IsLookupSlot()) {
2279 Label slow, done;
2280 SetExpressionPosition(callee);
2281 // Generate code for loading from variables potentially shadowed by
2282 // eval-introduced variables.
2283 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2284
2285 __ bind(&slow);
2286 // Call the runtime to find the function to call (returned in eax) and
2287 // the object holding it (returned in edx).
2288 __ Push(callee->name());
2289 __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2290 PushOperand(eax); // Function.
2291 PushOperand(edx); // Receiver.
2292 PrepareForBailoutForId(expr->LookupId(), BailoutState::NO_REGISTERS);
2293
2294 // If fast case code has been generated, emit code to push the function
2295 // and receiver and have the slow path jump around this code.
2296 if (done.is_linked()) {
2297 Label call;
2298 __ jmp(&call, Label::kNear);
2299 __ bind(&done);
2300 // Push function.
2301 __ push(eax);
2302 // The receiver is implicitly the global receiver. Indicate this by
2303 // passing the hole to the call function stub.
2304 __ push(Immediate(isolate()->factory()->undefined_value()));
2305 __ bind(&call);
2306 }
2307 } else {
2308 VisitForStackValue(callee);
2309 // refEnv.WithBaseObject()
2310 PushOperand(isolate()->factory()->undefined_value());
2311 }
2312 }
2313
2314
2315 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
2316 // In a call to eval, we first call Runtime_ResolvePossiblyDirectEval
2317 // to resolve the function we need to call. Then we call the resolved
2318 // function using the given arguments.
2319 ZoneList<Expression*>* args = expr->arguments();
2320 int arg_count = args->length();
2321
2322 PushCalleeAndWithBaseObject(expr);
2323
2324 // Push the arguments.
2325 for (int i = 0; i < arg_count; i++) {
2326 VisitForStackValue(args->at(i));
2327 }
2328
2329 // Push a copy of the function (found below the arguments) and
2330 // resolve eval.
2331 __ push(Operand(esp, (arg_count + 1) * kPointerSize));
2332 EmitResolvePossiblyDirectEval(expr);
2333
2334 // Touch up the stack with the resolved function.
2335 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
2336
2337 PrepareForBailoutForId(expr->EvalId(), BailoutState::NO_REGISTERS);
2338
2339 SetCallPosition(expr);
2340 Handle<Code> code = CodeFactory::CallIC(isolate(), ConvertReceiverMode::kAny,
2341 expr->tail_call_mode())
2342 .code();
2343 __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot())));
2344 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
2345 __ Move(eax, Immediate(arg_count));
2346 __ call(code, RelocInfo::CODE_TARGET);
2347 OperandStackDepthDecrement(arg_count + 1);
2348 RecordJSReturnSite(expr);
2349 RestoreContext();
2350 context()->DropAndPlug(1, eax);
2351 }
2352
2353
2354 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2123 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
2355 Comment cmnt(masm_, "[ CallNew"); 2124 Comment cmnt(masm_, "[ CallNew");
2356 // According to ECMA-262, section 11.2.2, page 44, the function 2125 // According to ECMA-262, section 11.2.2, page 44, the function
2357 // expression in new calls must be evaluated before the 2126 // expression in new calls must be evaluated before the
2358 // arguments. 2127 // arguments.
2359 2128
2360 // Push constructor on the stack. If it's not a function it's used as 2129 // Push constructor on the stack. If it's not a function it's used as
2361 // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is 2130 // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
2362 // ignored. 2131 // ignored.
2363 DCHECK(!expr->expression()->IsSuperPropertyReference()); 2132 DCHECK(!expr->expression()->IsSuperPropertyReference());
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
2767 // Delete of an unqualified identifier is disallowed in strict mode but 2536 // Delete of an unqualified identifier is disallowed in strict mode but
2768 // "delete this" is allowed. 2537 // "delete this" is allowed.
2769 bool is_this = var->is_this(); 2538 bool is_this = var->is_this();
2770 DCHECK(is_sloppy(language_mode()) || is_this); 2539 DCHECK(is_sloppy(language_mode()) || is_this);
2771 if (var->IsUnallocated()) { 2540 if (var->IsUnallocated()) {
2772 __ mov(eax, NativeContextOperand()); 2541 __ mov(eax, NativeContextOperand());
2773 __ push(ContextOperand(eax, Context::EXTENSION_INDEX)); 2542 __ push(ContextOperand(eax, Context::EXTENSION_INDEX));
2774 __ push(Immediate(var->name())); 2543 __ push(Immediate(var->name()));
2775 __ CallRuntime(Runtime::kDeleteProperty_Sloppy); 2544 __ CallRuntime(Runtime::kDeleteProperty_Sloppy);
2776 context()->Plug(eax); 2545 context()->Plug(eax);
2777 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 2546 } else {
2547 DCHECK(!var->IsLookupSlot());
2548 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2778 // Result of deleting non-global variables is false. 'this' is 2549 // Result of deleting non-global variables is false. 'this' is
2779 // not really a variable, though we implement it as one. The 2550 // not really a variable, though we implement it as one. The
2780 // subexpression does not have side effects. 2551 // subexpression does not have side effects.
2781 context()->Plug(is_this); 2552 context()->Plug(is_this);
2782 } else {
2783 // Non-global variable. Call the runtime to try to delete from the
2784 // context where the variable was introduced.
2785 __ Push(var->name());
2786 __ CallRuntime(Runtime::kDeleteLookupSlot);
2787 context()->Plug(eax);
2788 } 2553 }
2789 } else { 2554 } else {
2790 // Result of deleting non-property, non-variable reference is true. 2555 // Result of deleting non-property, non-variable reference is true.
2791 // The subexpression may have side effects. 2556 // The subexpression may have side effects.
2792 VisitForEffect(expr->expression()); 2557 VisitForEffect(expr->expression());
2793 context()->Plug(true); 2558 context()->Plug(true);
2794 } 2559 }
2795 break; 2560 break;
2796 } 2561 }
2797 2562
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after
3477 isolate->builtins()->OnStackReplacement()->entry(), 3242 isolate->builtins()->OnStackReplacement()->entry(),
3478 Assembler::target_address_at(call_target_address, unoptimized_code)); 3243 Assembler::target_address_at(call_target_address, unoptimized_code));
3479 return ON_STACK_REPLACEMENT; 3244 return ON_STACK_REPLACEMENT;
3480 } 3245 }
3481 3246
3482 3247
3483 } // namespace internal 3248 } // namespace internal
3484 } // namespace v8 3249 } // namespace v8
3485 3250
3486 #endif // V8_TARGET_ARCH_IA32 3251 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/full-codegen/full-codegen.cc ('k') | src/full-codegen/mips/full-codegen-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698