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

Powered by Google App Engine
This is Rietveld 408576698