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

Side by Side Diff: src/full-codegen/x87/full-codegen-x87.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/x64/full-codegen-x64.cc ('k') | no next file » | 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_X87 5 #if V8_TARGET_ARCH_X87
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 735 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 if (variable->binding_needs_init()) { 746 if (variable->binding_needs_init()) {
747 Comment cmnt(masm_, "[ VariableDeclaration"); 747 Comment cmnt(masm_, "[ VariableDeclaration");
748 EmitDebugCheckDeclarationContext(variable); 748 EmitDebugCheckDeclarationContext(variable);
749 __ mov(ContextOperand(esi, variable->index()), 749 __ mov(ContextOperand(esi, variable->index()),
750 Immediate(isolate()->factory()->the_hole_value())); 750 Immediate(isolate()->factory()->the_hole_value()));
751 // No write barrier since the hole value is in old space. 751 // No write barrier since the hole value is in old space.
752 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 752 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
753 } 753 }
754 break; 754 break;
755 755
756 case VariableLocation::LOOKUP: { 756 case VariableLocation::LOOKUP:
757 Comment cmnt(masm_, "[ VariableDeclaration");
758 DCHECK_EQ(VAR, variable->mode());
759 DCHECK(!variable->binding_needs_init());
760 __ push(Immediate(variable->name()));
761 __ CallRuntime(Runtime::kDeclareEvalVar);
762 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
763 break;
764 }
765
766 case VariableLocation::MODULE: 757 case VariableLocation::MODULE:
767 UNREACHABLE(); 758 UNREACHABLE();
768 } 759 }
769 } 760 }
770 761
771 void FullCodeGenerator::VisitFunctionDeclaration( 762 void FullCodeGenerator::VisitFunctionDeclaration(
772 FunctionDeclaration* declaration) { 763 FunctionDeclaration* declaration) {
773 VariableProxy* proxy = declaration->proxy(); 764 VariableProxy* proxy = declaration->proxy();
774 Variable* variable = proxy->var(); 765 Variable* variable = proxy->var();
775 switch (variable->location()) { 766 switch (variable->location()) {
(...skipping 24 matching lines...) Expand all
800 VisitForAccumulatorValue(declaration->fun()); 791 VisitForAccumulatorValue(declaration->fun());
801 __ mov(ContextOperand(esi, variable->index()), result_register()); 792 __ mov(ContextOperand(esi, variable->index()), result_register());
802 // We know that we have written a function, which is not a smi. 793 // We know that we have written a function, which is not a smi.
803 __ RecordWriteContextSlot(esi, Context::SlotOffset(variable->index()), 794 __ RecordWriteContextSlot(esi, Context::SlotOffset(variable->index()),
804 result_register(), ecx, kDontSaveFPRegs, 795 result_register(), ecx, kDontSaveFPRegs,
805 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); 796 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
806 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 797 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
807 break; 798 break;
808 } 799 }
809 800
810 case VariableLocation::LOOKUP: { 801 case VariableLocation::LOOKUP:
811 Comment cmnt(masm_, "[ FunctionDeclaration");
812 PushOperand(variable->name());
813 VisitForStackValue(declaration->fun());
814 CallRuntimeWithOperands(Runtime::kDeclareEvalFunction);
815 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
816 break;
817 }
818
819 case VariableLocation::MODULE: 802 case VariableLocation::MODULE:
820 UNREACHABLE(); 803 UNREACHABLE();
821 } 804 }
822 } 805 }
823 806
824 807
825 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 808 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
826 // Call the runtime to declare the globals. 809 // Call the runtime to declare the globals.
827 __ Push(pairs); 810 __ Push(pairs);
828 __ Push(Smi::FromInt(DeclareGlobalsFlags())); 811 __ Push(Smi::FromInt(DeclareGlobalsFlags()));
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
1094 1077
1095 void FullCodeGenerator::EmitSetHomeObjectAccumulator(Expression* initializer, 1078 void FullCodeGenerator::EmitSetHomeObjectAccumulator(Expression* initializer,
1096 int offset, 1079 int offset,
1097 FeedbackVectorSlot slot) { 1080 FeedbackVectorSlot slot) {
1098 DCHECK(NeedsHomeObject(initializer)); 1081 DCHECK(NeedsHomeObject(initializer));
1099 __ mov(StoreDescriptor::ReceiverRegister(), eax); 1082 __ mov(StoreDescriptor::ReceiverRegister(), eax);
1100 __ mov(StoreDescriptor::ValueRegister(), Operand(esp, offset * kPointerSize)); 1083 __ mov(StoreDescriptor::ValueRegister(), Operand(esp, offset * kPointerSize));
1101 CallStoreIC(slot, isolate()->factory()->home_object_symbol()); 1084 CallStoreIC(slot, isolate()->factory()->home_object_symbol());
1102 } 1085 }
1103 1086
1104
1105 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
1106 TypeofMode typeof_mode,
1107 Label* slow) {
1108 Register context = esi;
1109 Register temp = edx;
1110
1111 int to_check = scope()->ContextChainLengthUntilOutermostSloppyEval();
1112 for (Scope* s = scope(); to_check > 0; s = s->outer_scope()) {
1113 if (!s->NeedsContext()) continue;
1114 if (s->calls_sloppy_eval()) {
1115 // Check that extension is "the hole".
1116 __ JumpIfNotRoot(ContextOperand(context, Context::EXTENSION_INDEX),
1117 Heap::kTheHoleValueRootIndex, slow);
1118 }
1119 // Load next context in chain.
1120 __ mov(temp, ContextOperand(context, Context::PREVIOUS_INDEX));
1121 // Walk the rest of the chain without clobbering esi.
1122 context = temp;
1123 to_check--;
1124 }
1125
1126 // All extension objects were empty and it is safe to use a normal global
1127 // load machinery.
1128 EmitGlobalVariableLoad(proxy, typeof_mode);
1129 }
1130
1131
1132 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
1133 Label* slow) {
1134 DCHECK(var->IsContextSlot());
1135 Register context = esi;
1136 Register temp = ebx;
1137
1138 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) {
1139 if (s->NeedsContext()) {
1140 if (s->calls_sloppy_eval()) {
1141 // Check that extension is "the hole".
1142 __ JumpIfNotRoot(ContextOperand(context, Context::EXTENSION_INDEX),
1143 Heap::kTheHoleValueRootIndex, slow);
1144 }
1145 __ mov(temp, ContextOperand(context, Context::PREVIOUS_INDEX));
1146 // Walk the rest of the chain without clobbering esi.
1147 context = temp;
1148 }
1149 }
1150 // Check that last extension is "the hole".
1151 __ JumpIfNotRoot(ContextOperand(context, Context::EXTENSION_INDEX),
1152 Heap::kTheHoleValueRootIndex, slow);
1153
1154 // This function is used only for loads, not stores, so it's safe to
1155 // return an esi-based operand (the write barrier cannot be allowed to
1156 // destroy the esi register).
1157 return ContextOperand(context, var->index());
1158 }
1159
1160
1161 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
1162 TypeofMode typeof_mode,
1163 Label* slow, Label* done) {
1164 // Generate fast-case code for variables that might be shadowed by
1165 // eval-introduced variables. Eval is used a lot without
1166 // introducing variables. In those cases, we do not want to
1167 // perform a runtime call for all variables in the scope
1168 // containing the eval.
1169 Variable* var = proxy->var();
1170 if (var->mode() == DYNAMIC_GLOBAL) {
1171 EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
1172 __ jmp(done);
1173 } else if (var->mode() == DYNAMIC_LOCAL) {
1174 Variable* local = var->local_if_not_shadowed();
1175 __ mov(eax, ContextSlotOperandCheckExtensions(local, slow));
1176 if (local->binding_needs_init()) {
1177 __ cmp(eax, isolate()->factory()->the_hole_value());
1178 __ j(not_equal, done);
1179 __ push(Immediate(var->name()));
1180 __ CallRuntime(Runtime::kThrowReferenceError);
1181 } else {
1182 __ jmp(done);
1183 }
1184 }
1185 }
1186
1187 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1087 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1188 TypeofMode typeof_mode) { 1088 TypeofMode typeof_mode) {
1189 SetExpressionPosition(proxy); 1089 SetExpressionPosition(proxy);
1190 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS); 1090 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS);
1191 Variable* var = proxy->var(); 1091 Variable* var = proxy->var();
1192 1092
1193 // Three cases: global variables, lookup variables, and all other types of 1093 // Two cases: global variables and all other types of variables.
1194 // variables.
1195 switch (var->location()) { 1094 switch (var->location()) {
1196 case VariableLocation::UNALLOCATED: { 1095 case VariableLocation::UNALLOCATED: {
1197 Comment cmnt(masm_, "[ Global variable"); 1096 Comment cmnt(masm_, "[ Global variable");
1198 EmitGlobalVariableLoad(proxy, typeof_mode); 1097 EmitGlobalVariableLoad(proxy, typeof_mode);
1199 context()->Plug(eax); 1098 context()->Plug(eax);
1200 break; 1099 break;
1201 } 1100 }
1202 1101
1203 case VariableLocation::PARAMETER: 1102 case VariableLocation::PARAMETER:
1204 case VariableLocation::LOCAL: 1103 case VariableLocation::LOCAL:
(...skipping 12 matching lines...) Expand all
1217 __ push(Immediate(var->name())); 1116 __ push(Immediate(var->name()));
1218 __ CallRuntime(Runtime::kThrowReferenceError); 1117 __ CallRuntime(Runtime::kThrowReferenceError);
1219 __ bind(&done); 1118 __ bind(&done);
1220 context()->Plug(eax); 1119 context()->Plug(eax);
1221 break; 1120 break;
1222 } 1121 }
1223 context()->Plug(var); 1122 context()->Plug(var);
1224 break; 1123 break;
1225 } 1124 }
1226 1125
1227 case VariableLocation::LOOKUP: { 1126 case VariableLocation::LOOKUP:
1228 Comment cmnt(masm_, "[ Lookup variable");
1229 Label done, slow;
1230 // Generate code for loading from variables potentially shadowed
1231 // by eval-introduced variables.
1232 EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
1233 __ bind(&slow);
1234 __ push(Immediate(var->name()));
1235 Runtime::FunctionId function_id =
1236 typeof_mode == NOT_INSIDE_TYPEOF
1237 ? Runtime::kLoadLookupSlot
1238 : Runtime::kLoadLookupSlotInsideTypeof;
1239 __ CallRuntime(function_id);
1240 __ bind(&done);
1241 context()->Plug(eax);
1242 break;
1243 }
1244
1245 case VariableLocation::MODULE: 1127 case VariableLocation::MODULE:
1246 UNREACHABLE(); 1128 UNREACHABLE();
1247 } 1129 }
1248 } 1130 }
1249 1131
1250 1132
1251 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { 1133 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
1252 Expression* expression = (property == NULL) ? NULL : property->value(); 1134 Expression* expression = (property == NULL) ? NULL : property->value();
1253 if (expression == NULL) { 1135 if (expression == NULL) {
1254 PushOperand(isolate()->factory()->null_value()); 1136 PushOperand(isolate()->factory()->null_value());
(...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after
1992 __ mov(edx, location); 1874 __ mov(edx, location);
1993 __ cmp(edx, isolate()->factory()->the_hole_value()); 1875 __ cmp(edx, isolate()->factory()->the_hole_value());
1994 __ j(equal, &uninitialized_this); 1876 __ j(equal, &uninitialized_this);
1995 __ push(Immediate(var->name())); 1877 __ push(Immediate(var->name()));
1996 __ CallRuntime(Runtime::kThrowReferenceError); 1878 __ CallRuntime(Runtime::kThrowReferenceError);
1997 __ bind(&uninitialized_this); 1879 __ bind(&uninitialized_this);
1998 EmitStoreToStackLocalOrContextSlot(var, location); 1880 EmitStoreToStackLocalOrContextSlot(var, location);
1999 1881
2000 } else { 1882 } else {
2001 DCHECK(var->mode() != CONST || op == Token::INIT); 1883 DCHECK(var->mode() != CONST || op == Token::INIT);
2002 if (var->IsLookupSlot()) { 1884 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2003 // Assignment to var. 1885 DCHECK(!var->IsLookupSlot());
2004 __ Push(Immediate(var->name())); 1886 // Assignment to var or initializing assignment to let/const in harmony
2005 __ Push(eax); 1887 // mode.
2006 __ CallRuntime(is_strict(language_mode()) 1888 MemOperand location = VarOperand(var, ecx);
2007 ? Runtime::kStoreLookupSlot_Strict 1889 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) {
2008 : Runtime::kStoreLookupSlot_Sloppy); 1890 // Check for an uninitialized let binding.
2009 } else { 1891 __ mov(edx, location);
2010 // Assignment to var or initializing assignment to let/const in harmony 1892 __ cmp(edx, isolate()->factory()->the_hole_value());
2011 // mode. 1893 __ Check(equal, kLetBindingReInitialization);
2012 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2013 MemOperand location = VarOperand(var, ecx);
2014 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) {
2015 // Check for an uninitialized let binding.
2016 __ mov(edx, location);
2017 __ cmp(edx, isolate()->factory()->the_hole_value());
2018 __ Check(equal, kLetBindingReInitialization);
2019 }
2020 EmitStoreToStackLocalOrContextSlot(var, location);
2021 } 1894 }
1895 EmitStoreToStackLocalOrContextSlot(var, location);
2022 } 1896 }
2023 } 1897 }
2024 1898
2025 1899
2026 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 1900 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2027 // Assignment to a property, using a named store IC. 1901 // Assignment to a property, using a named store IC.
2028 // eax : value 1902 // eax : value
2029 // esp[0] : receiver 1903 // esp[0] : receiver
2030 Property* prop = expr->target()->AsProperty(); 1904 Property* prop = expr->target()->AsProperty();
2031 DCHECK(prop != NULL); 1905 DCHECK(prop != NULL);
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
2231 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 2105 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
2232 __ Move(eax, Immediate(arg_count)); 2106 __ Move(eax, Immediate(arg_count));
2233 CallIC(code); 2107 CallIC(code);
2234 OperandStackDepthDecrement(arg_count + 1); 2108 OperandStackDepthDecrement(arg_count + 1);
2235 2109
2236 RecordJSReturnSite(expr); 2110 RecordJSReturnSite(expr);
2237 RestoreContext(); 2111 RestoreContext();
2238 context()->DropAndPlug(1, eax); 2112 context()->DropAndPlug(1, eax);
2239 } 2113 }
2240 2114
2241 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) {
2242 int arg_count = expr->arguments()->length();
2243 // Push copy of the first argument or undefined if it doesn't exist.
2244 if (arg_count > 0) {
2245 __ push(Operand(esp, arg_count * kPointerSize));
2246 } else {
2247 __ push(Immediate(isolate()->factory()->undefined_value()));
2248 }
2249
2250 // Push the enclosing function.
2251 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
2252
2253 // Push the language mode.
2254 __ push(Immediate(Smi::FromInt(language_mode())));
2255
2256 // Push the start position of the scope the calls resides in.
2257 __ push(Immediate(Smi::FromInt(scope()->start_position())));
2258
2259 // Push the source position of the eval call.
2260 __ push(Immediate(Smi::FromInt(expr->position())));
2261
2262 // Do the runtime call.
2263 __ CallRuntime(Runtime::kResolvePossiblyDirectEval);
2264 }
2265
2266
2267 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls.
2268 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
2269 VariableProxy* callee = expr->expression()->AsVariableProxy();
2270 if (callee->var()->IsLookupSlot()) {
2271 Label slow, done;
2272 SetExpressionPosition(callee);
2273 // Generate code for loading from variables potentially shadowed by
2274 // eval-introduced variables.
2275 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2276
2277 __ bind(&slow);
2278 // Call the runtime to find the function to call (returned in eax) and
2279 // the object holding it (returned in edx).
2280 __ Push(callee->name());
2281 __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2282 PushOperand(eax); // Function.
2283 PushOperand(edx); // Receiver.
2284 PrepareForBailoutForId(expr->LookupId(), BailoutState::NO_REGISTERS);
2285
2286 // If fast case code has been generated, emit code to push the function
2287 // and receiver and have the slow path jump around this code.
2288 if (done.is_linked()) {
2289 Label call;
2290 __ jmp(&call, Label::kNear);
2291 __ bind(&done);
2292 // Push function.
2293 __ push(eax);
2294 // The receiver is implicitly the global receiver. Indicate this by
2295 // passing the hole to the call function stub.
2296 __ push(Immediate(isolate()->factory()->undefined_value()));
2297 __ bind(&call);
2298 }
2299 } else {
2300 VisitForStackValue(callee);
2301 // refEnv.WithBaseObject()
2302 PushOperand(isolate()->factory()->undefined_value());
2303 }
2304 }
2305
2306
2307 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
2308 // In a call to eval, we first call Runtime_ResolvePossiblyDirectEval
2309 // to resolve the function we need to call. Then we call the resolved
2310 // function using the given arguments.
2311 ZoneList<Expression*>* args = expr->arguments();
2312 int arg_count = args->length();
2313
2314 PushCalleeAndWithBaseObject(expr);
2315
2316 // Push the arguments.
2317 for (int i = 0; i < arg_count; i++) {
2318 VisitForStackValue(args->at(i));
2319 }
2320
2321 // Push a copy of the function (found below the arguments) and
2322 // resolve eval.
2323 __ push(Operand(esp, (arg_count + 1) * kPointerSize));
2324 EmitResolvePossiblyDirectEval(expr);
2325
2326 // Touch up the stack with the resolved function.
2327 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
2328
2329 PrepareForBailoutForId(expr->EvalId(), BailoutState::NO_REGISTERS);
2330
2331 SetCallPosition(expr);
2332 Handle<Code> code = CodeFactory::CallIC(isolate(), ConvertReceiverMode::kAny,
2333 expr->tail_call_mode())
2334 .code();
2335 __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot())));
2336 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
2337 __ Move(eax, Immediate(arg_count));
2338 __ call(code, RelocInfo::CODE_TARGET);
2339 OperandStackDepthDecrement(arg_count + 1);
2340 RecordJSReturnSite(expr);
2341 RestoreContext();
2342 context()->DropAndPlug(1, eax);
2343 }
2344
2345
2346 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2115 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
2347 Comment cmnt(masm_, "[ CallNew"); 2116 Comment cmnt(masm_, "[ CallNew");
2348 // According to ECMA-262, section 11.2.2, page 44, the function 2117 // According to ECMA-262, section 11.2.2, page 44, the function
2349 // expression in new calls must be evaluated before the 2118 // expression in new calls must be evaluated before the
2350 // arguments. 2119 // arguments.
2351 2120
2352 // Push constructor on the stack. If it's not a function it's used as 2121 // Push constructor on the stack. If it's not a function it's used as
2353 // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is 2122 // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
2354 // ignored. 2123 // ignored.
2355 DCHECK(!expr->expression()->IsSuperPropertyReference()); 2124 DCHECK(!expr->expression()->IsSuperPropertyReference());
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
2759 // Delete of an unqualified identifier is disallowed in strict mode but 2528 // Delete of an unqualified identifier is disallowed in strict mode but
2760 // "delete this" is allowed. 2529 // "delete this" is allowed.
2761 bool is_this = var->is_this(); 2530 bool is_this = var->is_this();
2762 DCHECK(is_sloppy(language_mode()) || is_this); 2531 DCHECK(is_sloppy(language_mode()) || is_this);
2763 if (var->IsUnallocated()) { 2532 if (var->IsUnallocated()) {
2764 __ mov(eax, NativeContextOperand()); 2533 __ mov(eax, NativeContextOperand());
2765 __ push(ContextOperand(eax, Context::EXTENSION_INDEX)); 2534 __ push(ContextOperand(eax, Context::EXTENSION_INDEX));
2766 __ push(Immediate(var->name())); 2535 __ push(Immediate(var->name()));
2767 __ CallRuntime(Runtime::kDeleteProperty_Sloppy); 2536 __ CallRuntime(Runtime::kDeleteProperty_Sloppy);
2768 context()->Plug(eax); 2537 context()->Plug(eax);
2769 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 2538 } else {
2539 DCHECK(!var->IsLookupSlot());
2540 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2770 // Result of deleting non-global variables is false. 'this' is 2541 // Result of deleting non-global variables is false. 'this' is
2771 // not really a variable, though we implement it as one. The 2542 // not really a variable, though we implement it as one. The
2772 // subexpression does not have side effects. 2543 // subexpression does not have side effects.
2773 context()->Plug(is_this); 2544 context()->Plug(is_this);
2774 } else {
2775 // Non-global variable. Call the runtime to try to delete from the
2776 // context where the variable was introduced.
2777 __ Push(var->name());
2778 __ CallRuntime(Runtime::kDeleteLookupSlot);
2779 context()->Plug(eax);
2780 } 2545 }
2781 } else { 2546 } else {
2782 // Result of deleting non-property, non-variable reference is true. 2547 // Result of deleting non-property, non-variable reference is true.
2783 // The subexpression may have side effects. 2548 // The subexpression may have side effects.
2784 VisitForEffect(expr->expression()); 2549 VisitForEffect(expr->expression());
2785 context()->Plug(true); 2550 context()->Plug(true);
2786 } 2551 }
2787 break; 2552 break;
2788 } 2553 }
2789 2554
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after
3469 isolate->builtins()->OnStackReplacement()->entry(), 3234 isolate->builtins()->OnStackReplacement()->entry(),
3470 Assembler::target_address_at(call_target_address, unoptimized_code)); 3235 Assembler::target_address_at(call_target_address, unoptimized_code));
3471 return ON_STACK_REPLACEMENT; 3236 return ON_STACK_REPLACEMENT;
3472 } 3237 }
3473 3238
3474 3239
3475 } // namespace internal 3240 } // namespace internal
3476 } // namespace v8 3241 } // namespace v8
3477 3242
3478 #endif // V8_TARGET_ARCH_X87 3243 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « src/full-codegen/x64/full-codegen-x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698