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

Side by Side Diff: src/full-codegen/mips/full-codegen-mips.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
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_MIPS 5 #if V8_TARGET_ARCH_MIPS
6 6
7 // Note on Mips implementation: 7 // Note on Mips implementation:
8 // 8 //
9 // The result_register() for mips is the 'v0' register, which is defined 9 // The result_register() for mips is the 'v0' register, which is defined
10 // by the ABI to contain function return values. However, the first 10 // by the ABI to contain function return values. However, the first
(...skipping 789 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 if (variable->binding_needs_init()) { 800 if (variable->binding_needs_init()) {
801 Comment cmnt(masm_, "[ VariableDeclaration"); 801 Comment cmnt(masm_, "[ VariableDeclaration");
802 EmitDebugCheckDeclarationContext(variable); 802 EmitDebugCheckDeclarationContext(variable);
803 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 803 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
804 __ sw(at, ContextMemOperand(cp, variable->index())); 804 __ sw(at, ContextMemOperand(cp, variable->index()));
805 // No write barrier since the_hole_value is in old space. 805 // No write barrier since the_hole_value is in old space.
806 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 806 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
807 } 807 }
808 break; 808 break;
809 809
810 case VariableLocation::LOOKUP: { 810 case VariableLocation::LOOKUP:
811 Comment cmnt(masm_, "[ VariableDeclaration");
812 DCHECK_EQ(VAR, variable->mode());
813 DCHECK(!variable->binding_needs_init());
814 __ li(a2, Operand(variable->name()));
815 __ Push(a2);
816 __ CallRuntime(Runtime::kDeclareEvalVar);
817 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
818 break;
819 }
820
821 case VariableLocation::MODULE: 811 case VariableLocation::MODULE:
822 UNREACHABLE(); 812 UNREACHABLE();
823 } 813 }
824 } 814 }
825 815
826 816
827 void FullCodeGenerator::VisitFunctionDeclaration( 817 void FullCodeGenerator::VisitFunctionDeclaration(
828 FunctionDeclaration* declaration) { 818 FunctionDeclaration* declaration) {
829 VariableProxy* proxy = declaration->proxy(); 819 VariableProxy* proxy = declaration->proxy();
830 Variable* variable = proxy->var(); 820 Variable* variable = proxy->var();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
862 result_register(), 852 result_register(),
863 a2, 853 a2,
864 kRAHasBeenSaved, 854 kRAHasBeenSaved,
865 kDontSaveFPRegs, 855 kDontSaveFPRegs,
866 EMIT_REMEMBERED_SET, 856 EMIT_REMEMBERED_SET,
867 OMIT_SMI_CHECK); 857 OMIT_SMI_CHECK);
868 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 858 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
869 break; 859 break;
870 } 860 }
871 861
872 case VariableLocation::LOOKUP: { 862 case VariableLocation::LOOKUP:
873 Comment cmnt(masm_, "[ FunctionDeclaration");
874 __ li(a2, Operand(variable->name()));
875 PushOperand(a2);
876 // Push initial value for function declaration.
877 VisitForStackValue(declaration->fun());
878 CallRuntimeWithOperands(Runtime::kDeclareEvalFunction);
879 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
880 break;
881 }
882
883 case VariableLocation::MODULE: 863 case VariableLocation::MODULE:
884 UNREACHABLE(); 864 UNREACHABLE();
885 } 865 }
886 } 866 }
887 867
888 868
889 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 869 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
890 // Call the runtime to declare the globals. 870 // Call the runtime to declare the globals.
891 __ li(a1, Operand(pairs)); 871 __ li(a1, Operand(pairs));
892 __ li(a0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); 872 __ li(a0, Operand(Smi::FromInt(DeclareGlobalsFlags())));
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
1176 void FullCodeGenerator::EmitSetHomeObjectAccumulator(Expression* initializer, 1156 void FullCodeGenerator::EmitSetHomeObjectAccumulator(Expression* initializer,
1177 int offset, 1157 int offset,
1178 FeedbackVectorSlot slot) { 1158 FeedbackVectorSlot slot) {
1179 DCHECK(NeedsHomeObject(initializer)); 1159 DCHECK(NeedsHomeObject(initializer));
1180 __ Move(StoreDescriptor::ReceiverRegister(), v0); 1160 __ Move(StoreDescriptor::ReceiverRegister(), v0);
1181 __ lw(StoreDescriptor::ValueRegister(), 1161 __ lw(StoreDescriptor::ValueRegister(),
1182 MemOperand(sp, offset * kPointerSize)); 1162 MemOperand(sp, offset * kPointerSize));
1183 CallStoreIC(slot, isolate()->factory()->home_object_symbol()); 1163 CallStoreIC(slot, isolate()->factory()->home_object_symbol());
1184 } 1164 }
1185 1165
1186
1187 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
1188 TypeofMode typeof_mode,
1189 Label* slow) {
1190 Register current = cp;
1191 Register next = a1;
1192 Register temp = a2;
1193
1194 int to_check = scope()->ContextChainLengthUntilOutermostSloppyEval();
1195 for (Scope* s = scope(); to_check > 0; s = s->outer_scope()) {
1196 if (!s->NeedsContext()) continue;
1197 if (s->calls_sloppy_eval()) {
1198 // Check that extension is "the hole".
1199 __ lw(temp, ContextMemOperand(current, Context::EXTENSION_INDEX));
1200 __ JumpIfNotRoot(temp, Heap::kTheHoleValueRootIndex, slow);
1201 }
1202 // Load next context in chain.
1203 __ lw(next, ContextMemOperand(current, Context::PREVIOUS_INDEX));
1204 // Walk the rest of the chain without clobbering cp.
1205 current = next;
1206 to_check--;
1207 }
1208
1209 // All extension objects were empty and it is safe to use a normal global
1210 // load machinery.
1211 EmitGlobalVariableLoad(proxy, typeof_mode);
1212 }
1213
1214
1215 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
1216 Label* slow) {
1217 DCHECK(var->IsContextSlot());
1218 Register context = cp;
1219 Register next = a3;
1220 Register temp = t0;
1221
1222 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) {
1223 if (s->NeedsContext()) {
1224 if (s->calls_sloppy_eval()) {
1225 // Check that extension is "the hole".
1226 __ lw(temp, ContextMemOperand(context, Context::EXTENSION_INDEX));
1227 __ JumpIfNotRoot(temp, Heap::kTheHoleValueRootIndex, slow);
1228 }
1229 __ lw(next, ContextMemOperand(context, Context::PREVIOUS_INDEX));
1230 // Walk the rest of the chain without clobbering cp.
1231 context = next;
1232 }
1233 }
1234 // Check that last extension is "the hole".
1235 __ lw(temp, ContextMemOperand(context, Context::EXTENSION_INDEX));
1236 __ JumpIfNotRoot(temp, Heap::kTheHoleValueRootIndex, slow);
1237
1238 // This function is used only for loads, not stores, so it's safe to
1239 // return an cp-based operand (the write barrier cannot be allowed to
1240 // destroy the cp register).
1241 return ContextMemOperand(context, var->index());
1242 }
1243
1244
1245 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
1246 TypeofMode typeof_mode,
1247 Label* slow, Label* done) {
1248 // Generate fast-case code for variables that might be shadowed by
1249 // eval-introduced variables. Eval is used a lot without
1250 // introducing variables. In those cases, we do not want to
1251 // perform a runtime call for all variables in the scope
1252 // containing the eval.
1253 Variable* var = proxy->var();
1254 if (var->mode() == DYNAMIC_GLOBAL) {
1255 EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
1256 __ Branch(done);
1257 } else if (var->mode() == DYNAMIC_LOCAL) {
1258 Variable* local = var->local_if_not_shadowed();
1259 __ lw(v0, ContextSlotOperandCheckExtensions(local, slow));
1260 if (local->binding_needs_init()) {
1261 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
1262 __ subu(at, v0, at); // Sub as compare: at == 0 on eq.
1263 __ Branch(done, ne, at, Operand(zero_reg));
1264 __ li(a0, Operand(var->name()));
1265 __ push(a0);
1266 __ CallRuntime(Runtime::kThrowReferenceError);
1267 } else {
1268 __ Branch(done);
1269 }
1270 }
1271 }
1272
1273 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1166 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1274 TypeofMode typeof_mode) { 1167 TypeofMode typeof_mode) {
1275 // Record position before possible IC call. 1168 // Record position before possible IC call.
1276 SetExpressionPosition(proxy); 1169 SetExpressionPosition(proxy);
1277 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS); 1170 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS);
1278 Variable* var = proxy->var(); 1171 Variable* var = proxy->var();
1279 1172
1280 // Three cases: global variables, lookup variables, and all other types of 1173 // Two cases: global variables and all other types of variables.
1281 // variables.
1282 switch (var->location()) { 1174 switch (var->location()) {
1283 case VariableLocation::UNALLOCATED: { 1175 case VariableLocation::UNALLOCATED: {
1284 Comment cmnt(masm_, "[ Global variable"); 1176 Comment cmnt(masm_, "[ Global variable");
1285 EmitGlobalVariableLoad(proxy, typeof_mode); 1177 EmitGlobalVariableLoad(proxy, typeof_mode);
1286 context()->Plug(v0); 1178 context()->Plug(v0);
1287 break; 1179 break;
1288 } 1180 }
1289 1181
1290 case VariableLocation::PARAMETER: 1182 case VariableLocation::PARAMETER:
1291 case VariableLocation::LOCAL: 1183 case VariableLocation::LOCAL:
(...skipping 13 matching lines...) Expand all
1305 __ push(a0); 1197 __ push(a0);
1306 __ CallRuntime(Runtime::kThrowReferenceError); 1198 __ CallRuntime(Runtime::kThrowReferenceError);
1307 __ bind(&done); 1199 __ bind(&done);
1308 context()->Plug(v0); 1200 context()->Plug(v0);
1309 break; 1201 break;
1310 } 1202 }
1311 context()->Plug(var); 1203 context()->Plug(var);
1312 break; 1204 break;
1313 } 1205 }
1314 1206
1315 case VariableLocation::LOOKUP: { 1207 case VariableLocation::LOOKUP:
1316 Comment cmnt(masm_, "[ Lookup variable");
1317 Label done, slow;
1318 // Generate code for loading from variables potentially shadowed
1319 // by eval-introduced variables.
1320 EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
1321 __ bind(&slow);
1322 __ Push(var->name());
1323 Runtime::FunctionId function_id =
1324 typeof_mode == NOT_INSIDE_TYPEOF
1325 ? Runtime::kLoadLookupSlot
1326 : Runtime::kLoadLookupSlotInsideTypeof;
1327 __ CallRuntime(function_id);
1328 __ bind(&done);
1329 context()->Plug(v0);
1330 break;
1331 }
1332
1333 case VariableLocation::MODULE: 1208 case VariableLocation::MODULE:
1334 UNREACHABLE(); 1209 UNREACHABLE();
1335 } 1210 }
1336 } 1211 }
1337 1212
1338 1213
1339 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { 1214 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
1340 Expression* expression = (property == NULL) ? NULL : property->value(); 1215 Expression* expression = (property == NULL) ? NULL : property->value();
1341 if (expression == NULL) { 1216 if (expression == NULL) {
1342 __ LoadRoot(a1, Heap::kNullValueRootIndex); 1217 __ LoadRoot(a1, Heap::kNullValueRootIndex);
(...skipping 761 matching lines...) Expand 10 before | Expand all | Expand 10 after
2104 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 1979 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2105 __ Branch(&uninitialized_this, eq, a3, Operand(at)); 1980 __ Branch(&uninitialized_this, eq, a3, Operand(at));
2106 __ li(a0, Operand(var->name())); 1981 __ li(a0, Operand(var->name()));
2107 __ Push(a0); 1982 __ Push(a0);
2108 __ CallRuntime(Runtime::kThrowReferenceError); 1983 __ CallRuntime(Runtime::kThrowReferenceError);
2109 __ bind(&uninitialized_this); 1984 __ bind(&uninitialized_this);
2110 EmitStoreToStackLocalOrContextSlot(var, location); 1985 EmitStoreToStackLocalOrContextSlot(var, location);
2111 1986
2112 } else { 1987 } else {
2113 DCHECK(var->mode() != CONST || op == Token::INIT); 1988 DCHECK(var->mode() != CONST || op == Token::INIT);
2114 if (var->IsLookupSlot()) { 1989 DCHECK((var->IsStackAllocated() || var->IsContextSlot()));
2115 // Assignment to var. 1990 DCHECK(!var->IsLookupSlot());
2116 __ Push(var->name()); 1991 // Assignment to var or initializing assignment to let/const in harmony
2117 __ Push(v0); 1992 // mode.
2118 __ CallRuntime(is_strict(language_mode()) 1993 MemOperand location = VarOperand(var, a1);
2119 ? Runtime::kStoreLookupSlot_Strict 1994 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) {
2120 : Runtime::kStoreLookupSlot_Sloppy); 1995 // Check for an uninitialized let binding.
2121 } else { 1996 __ lw(a2, location);
2122 // Assignment to var or initializing assignment to let/const in harmony 1997 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
2123 // mode. 1998 __ Check(eq, kLetBindingReInitialization, a2, Operand(t0));
2124 DCHECK((var->IsStackAllocated() || var->IsContextSlot()));
2125 MemOperand location = VarOperand(var, a1);
2126 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) {
2127 // Check for an uninitialized let binding.
2128 __ lw(a2, location);
2129 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
2130 __ Check(eq, kLetBindingReInitialization, a2, Operand(t0));
2131 }
2132 EmitStoreToStackLocalOrContextSlot(var, location);
2133 } 1999 }
2000 EmitStoreToStackLocalOrContextSlot(var, location);
2134 } 2001 }
2135 } 2002 }
2136 2003
2137 2004
2138 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2005 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2139 // Assignment to a property, using a named store IC. 2006 // Assignment to a property, using a named store IC.
2140 Property* prop = expr->target()->AsProperty(); 2007 Property* prop = expr->target()->AsProperty();
2141 DCHECK(prop != NULL); 2008 DCHECK(prop != NULL);
2142 DCHECK(prop->key()->IsLiteral()); 2009 DCHECK(prop->key()->IsLiteral());
2143 2010
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
2354 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2221 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2355 __ li(a0, Operand(arg_count)); 2222 __ li(a0, Operand(arg_count));
2356 CallIC(code); 2223 CallIC(code);
2357 OperandStackDepthDecrement(arg_count + 1); 2224 OperandStackDepthDecrement(arg_count + 1);
2358 2225
2359 RecordJSReturnSite(expr); 2226 RecordJSReturnSite(expr);
2360 RestoreContext(); 2227 RestoreContext();
2361 context()->DropAndPlug(1, v0); 2228 context()->DropAndPlug(1, v0);
2362 } 2229 }
2363 2230
2364 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) {
2365 int arg_count = expr->arguments()->length();
2366 // t4: copy of the first argument or undefined if it doesn't exist.
2367 if (arg_count > 0) {
2368 __ lw(t4, MemOperand(sp, arg_count * kPointerSize));
2369 } else {
2370 __ LoadRoot(t4, Heap::kUndefinedValueRootIndex);
2371 }
2372
2373 // t3: the receiver of the enclosing function.
2374 __ lw(t3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
2375
2376 // t2: the language mode.
2377 __ li(t2, Operand(Smi::FromInt(language_mode())));
2378
2379 // t1: the start position of the scope the calls resides in.
2380 __ li(t1, Operand(Smi::FromInt(scope()->start_position())));
2381
2382 // t0: the source position of the eval call.
2383 __ li(t0, Operand(Smi::FromInt(expr->position())));
2384
2385 // Do the runtime call.
2386 __ Push(t4, t3, t2, t1, t0);
2387 __ CallRuntime(Runtime::kResolvePossiblyDirectEval);
2388 }
2389
2390
2391 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls.
2392 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
2393 VariableProxy* callee = expr->expression()->AsVariableProxy();
2394 if (callee->var()->IsLookupSlot()) {
2395 Label slow, done;
2396
2397 SetExpressionPosition(callee);
2398 // Generate code for loading from variables potentially shadowed by
2399 // eval-introduced variables.
2400 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2401
2402 __ bind(&slow);
2403 // Call the runtime to find the function to call (returned in v0)
2404 // and the object holding it (returned in v1).
2405 __ Push(callee->name());
2406 __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2407 PushOperands(v0, v1); // Function, receiver.
2408 PrepareForBailoutForId(expr->LookupId(), BailoutState::NO_REGISTERS);
2409
2410 // If fast case code has been generated, emit code to push the
2411 // function and receiver and have the slow path jump around this
2412 // code.
2413 if (done.is_linked()) {
2414 Label call;
2415 __ Branch(&call);
2416 __ bind(&done);
2417 // Push function.
2418 __ push(v0);
2419 // The receiver is implicitly the global receiver. Indicate this
2420 // by passing the hole to the call function stub.
2421 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex);
2422 __ push(a1);
2423 __ bind(&call);
2424 }
2425 } else {
2426 VisitForStackValue(callee);
2427 // refEnv.WithBaseObject()
2428 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
2429 PushOperand(a2); // Reserved receiver slot.
2430 }
2431 }
2432
2433
2434 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
2435 // In a call to eval, we first call Runtime_ResolvePossiblyDirectEval
2436 // to resolve the function we need to call. Then we call the resolved
2437 // function using the given arguments.
2438 ZoneList<Expression*>* args = expr->arguments();
2439 int arg_count = args->length();
2440 PushCalleeAndWithBaseObject(expr);
2441
2442 // Push the arguments.
2443 for (int i = 0; i < arg_count; i++) {
2444 VisitForStackValue(args->at(i));
2445 }
2446
2447 // Push a copy of the function (found below the arguments) and
2448 // resolve eval.
2449 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2450 __ push(a1);
2451 EmitResolvePossiblyDirectEval(expr);
2452
2453 // Touch up the stack with the resolved function.
2454 __ sw(v0, MemOperand(sp, (arg_count + 1) * kPointerSize));
2455
2456 PrepareForBailoutForId(expr->EvalId(), BailoutState::NO_REGISTERS);
2457 // Record source position for debugger.
2458 SetCallPosition(expr);
2459 Handle<Code> code = CodeFactory::CallIC(isolate(), ConvertReceiverMode::kAny,
2460 expr->tail_call_mode())
2461 .code();
2462 __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackICSlot())));
2463 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2464 __ li(a0, Operand(arg_count));
2465 __ Call(code, RelocInfo::CODE_TARGET);
2466 OperandStackDepthDecrement(arg_count + 1);
2467 RecordJSReturnSite(expr);
2468 RestoreContext();
2469 context()->DropAndPlug(1, v0);
2470 }
2471
2472
2473 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2231 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
2474 Comment cmnt(masm_, "[ CallNew"); 2232 Comment cmnt(masm_, "[ CallNew");
2475 // According to ECMA-262, section 11.2.2, page 44, the function 2233 // According to ECMA-262, section 11.2.2, page 44, the function
2476 // expression in new calls must be evaluated before the 2234 // expression in new calls must be evaluated before the
2477 // arguments. 2235 // arguments.
2478 2236
2479 // Push constructor on the stack. If it's not a function it's used as 2237 // Push constructor on the stack. If it's not a function it's used as
2480 // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is 2238 // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
2481 // ignored.g 2239 // ignored.g
2482 DCHECK(!expr->expression()->IsSuperPropertyReference()); 2240 DCHECK(!expr->expression()->IsSuperPropertyReference());
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
2892 // Delete of an unqualified identifier is disallowed in strict mode but 2650 // Delete of an unqualified identifier is disallowed in strict mode but
2893 // "delete this" is allowed. 2651 // "delete this" is allowed.
2894 bool is_this = var->is_this(); 2652 bool is_this = var->is_this();
2895 DCHECK(is_sloppy(language_mode()) || is_this); 2653 DCHECK(is_sloppy(language_mode()) || is_this);
2896 if (var->IsUnallocated()) { 2654 if (var->IsUnallocated()) {
2897 __ LoadGlobalObject(a2); 2655 __ LoadGlobalObject(a2);
2898 __ li(a1, Operand(var->name())); 2656 __ li(a1, Operand(var->name()));
2899 __ Push(a2, a1); 2657 __ Push(a2, a1);
2900 __ CallRuntime(Runtime::kDeleteProperty_Sloppy); 2658 __ CallRuntime(Runtime::kDeleteProperty_Sloppy);
2901 context()->Plug(v0); 2659 context()->Plug(v0);
2902 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 2660 } else {
2661 DCHECK(!var->IsLookupSlot());
2662 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2903 // Result of deleting non-global, non-dynamic variables is false. 2663 // Result of deleting non-global, non-dynamic variables is false.
2904 // The subexpression does not have side effects. 2664 // The subexpression does not have side effects.
2905 context()->Plug(is_this); 2665 context()->Plug(is_this);
2906 } else {
2907 // Non-global variable. Call the runtime to try to delete from the
2908 // context where the variable was introduced.
2909 __ Push(var->name());
2910 __ CallRuntime(Runtime::kDeleteLookupSlot);
2911 context()->Plug(v0);
2912 } 2666 }
2913 } else { 2667 } else {
2914 // Result of deleting non-property, non-variable reference is true. 2668 // Result of deleting non-property, non-variable reference is true.
2915 // The subexpression may have side effects. 2669 // The subexpression may have side effects.
2916 VisitForEffect(expr->expression()); 2670 VisitForEffect(expr->expression());
2917 context()->Plug(true); 2671 context()->Plug(true);
2918 } 2672 }
2919 break; 2673 break;
2920 } 2674 }
2921 2675
(...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after
3594 reinterpret_cast<uint32_t>( 3348 reinterpret_cast<uint32_t>(
3595 isolate->builtins()->OnStackReplacement()->entry())); 3349 isolate->builtins()->OnStackReplacement()->entry()));
3596 return ON_STACK_REPLACEMENT; 3350 return ON_STACK_REPLACEMENT;
3597 } 3351 }
3598 3352
3599 3353
3600 } // namespace internal 3354 } // namespace internal
3601 } // namespace v8 3355 } // namespace v8
3602 3356
3603 #endif // V8_TARGET_ARCH_MIPS 3357 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/full-codegen/ia32/full-codegen-ia32.cc ('k') | src/full-codegen/mips64/full-codegen-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698