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

Side by Side Diff: src/full-codegen/arm/full-codegen-arm.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/compiler/ast-graph-builder.cc ('k') | src/full-codegen/arm64/full-codegen-arm64.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_ARM 5 #if V8_TARGET_ARCH_ARM
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 790 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 if (variable->binding_needs_init()) { 801 if (variable->binding_needs_init()) {
802 Comment cmnt(masm_, "[ VariableDeclaration"); 802 Comment cmnt(masm_, "[ VariableDeclaration");
803 EmitDebugCheckDeclarationContext(variable); 803 EmitDebugCheckDeclarationContext(variable);
804 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex); 804 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex);
805 __ str(r0, ContextMemOperand(cp, variable->index())); 805 __ str(r0, ContextMemOperand(cp, variable->index()));
806 // No write barrier since the_hole_value is in old space. 806 // No write barrier since the_hole_value is in old space.
807 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 807 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
808 } 808 }
809 break; 809 break;
810 810
811 case VariableLocation::LOOKUP: { 811 case VariableLocation::LOOKUP:
812 Comment cmnt(masm_, "[ VariableDeclaration");
813 DCHECK_EQ(VAR, variable->mode());
814 DCHECK(!variable->binding_needs_init());
815 __ mov(r2, Operand(variable->name()));
816 __ Push(r2);
817 __ CallRuntime(Runtime::kDeclareEvalVar);
818 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
819 break;
820 }
821
822 case VariableLocation::MODULE: 812 case VariableLocation::MODULE:
823 UNREACHABLE(); 813 UNREACHABLE();
824 } 814 }
825 } 815 }
826 816
827 817
828 void FullCodeGenerator::VisitFunctionDeclaration( 818 void FullCodeGenerator::VisitFunctionDeclaration(
829 FunctionDeclaration* declaration) { 819 FunctionDeclaration* declaration) {
830 VariableProxy* proxy = declaration->proxy(); 820 VariableProxy* proxy = declaration->proxy();
831 Variable* variable = proxy->var(); 821 Variable* variable = proxy->var();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
863 result_register(), 853 result_register(),
864 r2, 854 r2,
865 kLRHasBeenSaved, 855 kLRHasBeenSaved,
866 kDontSaveFPRegs, 856 kDontSaveFPRegs,
867 EMIT_REMEMBERED_SET, 857 EMIT_REMEMBERED_SET,
868 OMIT_SMI_CHECK); 858 OMIT_SMI_CHECK);
869 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 859 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
870 break; 860 break;
871 } 861 }
872 862
873 case VariableLocation::LOOKUP: { 863 case VariableLocation::LOOKUP:
874 Comment cmnt(masm_, "[ FunctionDeclaration");
875 __ mov(r2, Operand(variable->name()));
876 PushOperand(r2);
877 // Push initial value for function declaration.
878 VisitForStackValue(declaration->fun());
879 CallRuntimeWithOperands(Runtime::kDeclareEvalFunction);
880 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
881 break;
882 }
883
884 case VariableLocation::MODULE: 864 case VariableLocation::MODULE:
885 UNREACHABLE(); 865 UNREACHABLE();
886 } 866 }
887 } 867 }
888 868
889 869
890 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 870 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
891 // Call the runtime to declare the globals. 871 // Call the runtime to declare the globals.
892 __ mov(r1, Operand(pairs)); 872 __ mov(r1, Operand(pairs));
893 __ mov(r0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); 873 __ mov(r0, Operand(Smi::FromInt(DeclareGlobalsFlags())));
(...skipping 283 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(), r0); 1161 __ Move(StoreDescriptor::ReceiverRegister(), r0);
1182 __ ldr(StoreDescriptor::ValueRegister(), 1162 __ ldr(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 = r1;
1193 Register temp = r2;
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 __ ldr(temp, ContextMemOperand(current, Context::EXTENSION_INDEX));
1201 __ JumpIfNotRoot(temp, Heap::kTheHoleValueRootIndex, slow);
1202 }
1203 // Load next context in chain.
1204 __ ldr(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 = r3;
1221 Register temp = r4;
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 __ ldr(temp, ContextMemOperand(context, Context::EXTENSION_INDEX));
1228 __ JumpIfNotRoot(temp, Heap::kTheHoleValueRootIndex, slow);
1229 }
1230 __ ldr(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 __ ldr(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 __ jmp(done);
1258 } else if (var->mode() == DYNAMIC_LOCAL) {
1259 Variable* local = var->local_if_not_shadowed();
1260 __ ldr(r0, ContextSlotOperandCheckExtensions(local, slow));
1261 if (local->binding_needs_init()) {
1262 __ CompareRoot(r0, Heap::kTheHoleValueRootIndex);
1263 __ b(ne, done);
1264 __ mov(r0, Operand(var->name()));
1265 __ push(r0);
1266 __ CallRuntime(Runtime::kThrowReferenceError);
1267 } else {
1268 __ jmp(done);
1269 }
1270 }
1271 }
1272
1273 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1167 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1274 TypeofMode typeof_mode) { 1168 TypeofMode typeof_mode) {
1275 // Record position before possible IC call. 1169 // Record position before possible IC call.
1276 SetExpressionPosition(proxy); 1170 SetExpressionPosition(proxy);
1277 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS); 1171 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS);
1278 Variable* var = proxy->var(); 1172 Variable* var = proxy->var();
1279 1173
1280 // Three cases: global variables, lookup variables, and all other types of 1174 // Two cases: global variables and all other types of variables.
1281 // variables.
1282 switch (var->location()) { 1175 switch (var->location()) {
1283 case VariableLocation::UNALLOCATED: { 1176 case VariableLocation::UNALLOCATED: {
1284 Comment cmnt(masm_, "[ Global variable"); 1177 Comment cmnt(masm_, "[ Global variable");
1285 EmitGlobalVariableLoad(proxy, typeof_mode); 1178 EmitGlobalVariableLoad(proxy, typeof_mode);
1286 context()->Plug(r0); 1179 context()->Plug(r0);
1287 break; 1180 break;
1288 } 1181 }
1289 1182
1290 case VariableLocation::PARAMETER: 1183 case VariableLocation::PARAMETER:
1291 case VariableLocation::LOCAL: 1184 case VariableLocation::LOCAL:
(...skipping 12 matching lines...) Expand all
1304 __ push(r0); 1197 __ push(r0);
1305 __ CallRuntime(Runtime::kThrowReferenceError); 1198 __ CallRuntime(Runtime::kThrowReferenceError);
1306 __ bind(&done); 1199 __ bind(&done);
1307 context()->Plug(r0); 1200 context()->Plug(r0);
1308 break; 1201 break;
1309 } 1202 }
1310 context()->Plug(var); 1203 context()->Plug(var);
1311 break; 1204 break;
1312 } 1205 }
1313 1206
1314 case VariableLocation::LOOKUP: { 1207 case VariableLocation::LOOKUP:
1315 Comment cmnt(masm_, "[ Lookup variable");
1316 Label done, slow;
1317 // Generate code for loading from variables potentially shadowed
1318 // by eval-introduced variables.
1319 EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
1320 __ bind(&slow);
1321 __ Push(var->name());
1322 Runtime::FunctionId function_id =
1323 typeof_mode == NOT_INSIDE_TYPEOF
1324 ? Runtime::kLoadLookupSlot
1325 : Runtime::kLoadLookupSlotInsideTypeof;
1326 __ CallRuntime(function_id);
1327 __ bind(&done);
1328 context()->Plug(r0);
1329 break;
1330 }
1331
1332 case VariableLocation::MODULE: 1208 case VariableLocation::MODULE:
1333 UNREACHABLE(); 1209 UNREACHABLE();
1334 } 1210 }
1335 } 1211 }
1336 1212
1337 1213
1338 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { 1214 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
1339 Expression* expression = (property == NULL) ? NULL : property->value(); 1215 Expression* expression = (property == NULL) ? NULL : property->value();
1340 if (expression == NULL) { 1216 if (expression == NULL) {
1341 __ LoadRoot(r1, Heap::kNullValueRootIndex); 1217 __ LoadRoot(r1, Heap::kNullValueRootIndex);
(...skipping 750 matching lines...) Expand 10 before | Expand all | Expand 10 after
2092 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); 1968 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex);
2093 __ b(eq, &uninitialized_this); 1969 __ b(eq, &uninitialized_this);
2094 __ mov(r0, Operand(var->name())); 1970 __ mov(r0, Operand(var->name()));
2095 __ Push(r0); 1971 __ Push(r0);
2096 __ CallRuntime(Runtime::kThrowReferenceError); 1972 __ CallRuntime(Runtime::kThrowReferenceError);
2097 __ bind(&uninitialized_this); 1973 __ bind(&uninitialized_this);
2098 EmitStoreToStackLocalOrContextSlot(var, location); 1974 EmitStoreToStackLocalOrContextSlot(var, location);
2099 1975
2100 } else { 1976 } else {
2101 DCHECK(var->mode() != CONST || op == Token::INIT); 1977 DCHECK(var->mode() != CONST || op == Token::INIT);
2102 if (var->IsLookupSlot()) { 1978 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2103 // Assignment to var. 1979 DCHECK(!var->IsLookupSlot());
2104 __ Push(var->name()); 1980 // Assignment to var or initializing assignment to let/const in harmony
2105 __ Push(r0); 1981 // mode.
2106 __ CallRuntime(is_strict(language_mode()) 1982 MemOperand location = VarOperand(var, r1);
2107 ? Runtime::kStoreLookupSlot_Strict 1983 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) {
2108 : Runtime::kStoreLookupSlot_Sloppy); 1984 // Check for an uninitialized let binding.
2109 } else { 1985 __ ldr(r2, location);
2110 // Assignment to var or initializing assignment to let/const in harmony 1986 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex);
2111 // mode. 1987 __ Check(eq, kLetBindingReInitialization);
2112 DCHECK((var->IsStackAllocated() || var->IsContextSlot()));
2113 MemOperand location = VarOperand(var, r1);
2114 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) {
2115 // Check for an uninitialized let binding.
2116 __ ldr(r2, location);
2117 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex);
2118 __ Check(eq, kLetBindingReInitialization);
2119 }
2120 EmitStoreToStackLocalOrContextSlot(var, location);
2121 } 1988 }
1989 EmitStoreToStackLocalOrContextSlot(var, location);
2122 } 1990 }
2123 } 1991 }
2124 1992
2125 1993
2126 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 1994 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2127 // Assignment to a property, using a named store IC. 1995 // Assignment to a property, using a named store IC.
2128 Property* prop = expr->target()->AsProperty(); 1996 Property* prop = expr->target()->AsProperty();
2129 DCHECK(prop != NULL); 1997 DCHECK(prop != NULL);
2130 DCHECK(prop->key()->IsLiteral()); 1998 DCHECK(prop->key()->IsLiteral());
2131 1999
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
2338 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2206 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2339 __ mov(r0, Operand(arg_count)); 2207 __ mov(r0, Operand(arg_count));
2340 CallIC(code); 2208 CallIC(code);
2341 OperandStackDepthDecrement(arg_count + 1); 2209 OperandStackDepthDecrement(arg_count + 1);
2342 2210
2343 RecordJSReturnSite(expr); 2211 RecordJSReturnSite(expr);
2344 RestoreContext(); 2212 RestoreContext();
2345 context()->DropAndPlug(1, r0); 2213 context()->DropAndPlug(1, r0);
2346 } 2214 }
2347 2215
2348 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) {
2349 int arg_count = expr->arguments()->length();
2350 // r4: copy of the first argument or undefined if it doesn't exist.
2351 if (arg_count > 0) {
2352 __ ldr(r4, MemOperand(sp, arg_count * kPointerSize));
2353 } else {
2354 __ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
2355 }
2356
2357 // r3: the receiver of the enclosing function.
2358 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
2359
2360 // r2: language mode.
2361 __ mov(r2, Operand(Smi::FromInt(language_mode())));
2362
2363 // r1: the start position of the scope the calls resides in.
2364 __ mov(r1, Operand(Smi::FromInt(scope()->start_position())));
2365
2366 // r0: the source position of the eval call.
2367 __ mov(r0, Operand(Smi::FromInt(expr->position())));
2368
2369 // Do the runtime call.
2370 __ Push(r4, r3, r2, r1, r0);
2371 __ CallRuntime(Runtime::kResolvePossiblyDirectEval);
2372 }
2373
2374
2375 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls.
2376 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
2377 VariableProxy* callee = expr->expression()->AsVariableProxy();
2378 if (callee->var()->IsLookupSlot()) {
2379 Label slow, done;
2380 SetExpressionPosition(callee);
2381 // Generate code for loading from variables potentially shadowed
2382 // by eval-introduced variables.
2383 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2384
2385 __ bind(&slow);
2386 // Call the runtime to find the function to call (returned in r0)
2387 // and the object holding it (returned in edx).
2388 __ Push(callee->name());
2389 __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2390 PushOperands(r0, r1); // Function, receiver.
2391 PrepareForBailoutForId(expr->LookupId(), BailoutState::NO_REGISTERS);
2392
2393 // If fast case code has been generated, emit code to push the
2394 // function and receiver and have the slow path jump around this
2395 // code.
2396 if (done.is_linked()) {
2397 Label call;
2398 __ b(&call);
2399 __ bind(&done);
2400 // Push function.
2401 __ push(r0);
2402 // The receiver is implicitly the global receiver. Indicate this
2403 // by passing the hole to the call function stub.
2404 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
2405 __ push(r1);
2406 __ bind(&call);
2407 }
2408 } else {
2409 VisitForStackValue(callee);
2410 // refEnv.WithBaseObject()
2411 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
2412 PushOperand(r2); // Reserved receiver slot.
2413 }
2414 }
2415
2416
2417 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
2418 // In a call to eval, we first call
2419 // Runtime_ResolvePossiblyDirectEval to resolve the function we need
2420 // to call. Then we call the resolved function using the given arguments.
2421 ZoneList<Expression*>* args = expr->arguments();
2422 int arg_count = args->length();
2423
2424 PushCalleeAndWithBaseObject(expr);
2425
2426 // Push the arguments.
2427 for (int i = 0; i < arg_count; i++) {
2428 VisitForStackValue(args->at(i));
2429 }
2430
2431 // Push a copy of the function (found below the arguments) and
2432 // resolve eval.
2433 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2434 __ push(r1);
2435 EmitResolvePossiblyDirectEval(expr);
2436
2437 // Touch up the stack with the resolved function.
2438 __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize));
2439
2440 PrepareForBailoutForId(expr->EvalId(), BailoutState::NO_REGISTERS);
2441
2442 // Record source position for debugger.
2443 SetCallPosition(expr);
2444 Handle<Code> code = CodeFactory::CallIC(isolate(), ConvertReceiverMode::kAny,
2445 expr->tail_call_mode())
2446 .code();
2447 __ mov(r3, Operand(SmiFromSlot(expr->CallFeedbackICSlot())));
2448 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2449 __ mov(r0, Operand(arg_count));
2450 __ Call(code, RelocInfo::CODE_TARGET);
2451 OperandStackDepthDecrement(arg_count + 1);
2452 RecordJSReturnSite(expr);
2453 RestoreContext();
2454 context()->DropAndPlug(1, r0);
2455 }
2456
2457
2458 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2216 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
2459 Comment cmnt(masm_, "[ CallNew"); 2217 Comment cmnt(masm_, "[ CallNew");
2460 // According to ECMA-262, section 11.2.2, page 44, the function 2218 // According to ECMA-262, section 11.2.2, page 44, the function
2461 // expression in new calls must be evaluated before the 2219 // expression in new calls must be evaluated before the
2462 // arguments. 2220 // arguments.
2463 2221
2464 // Push constructor on the stack. If it's not a function it's used as 2222 // Push constructor on the stack. If it's not a function it's used as
2465 // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is 2223 // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
2466 // ignored. 2224 // ignored.
2467 DCHECK(!expr->expression()->IsSuperPropertyReference()); 2225 DCHECK(!expr->expression()->IsSuperPropertyReference());
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
2876 // Delete of an unqualified identifier is disallowed in strict mode but 2634 // Delete of an unqualified identifier is disallowed in strict mode but
2877 // "delete this" is allowed. 2635 // "delete this" is allowed.
2878 bool is_this = var->is_this(); 2636 bool is_this = var->is_this();
2879 DCHECK(is_sloppy(language_mode()) || is_this); 2637 DCHECK(is_sloppy(language_mode()) || is_this);
2880 if (var->IsUnallocated()) { 2638 if (var->IsUnallocated()) {
2881 __ LoadGlobalObject(r2); 2639 __ LoadGlobalObject(r2);
2882 __ mov(r1, Operand(var->name())); 2640 __ mov(r1, Operand(var->name()));
2883 __ Push(r2, r1); 2641 __ Push(r2, r1);
2884 __ CallRuntime(Runtime::kDeleteProperty_Sloppy); 2642 __ CallRuntime(Runtime::kDeleteProperty_Sloppy);
2885 context()->Plug(r0); 2643 context()->Plug(r0);
2886 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 2644 } else {
2645 DCHECK(!var->IsLookupSlot());
2646 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2887 // Result of deleting non-global, non-dynamic variables is false. 2647 // Result of deleting non-global, non-dynamic variables is false.
2888 // The subexpression does not have side effects. 2648 // The subexpression does not have side effects.
2889 context()->Plug(is_this); 2649 context()->Plug(is_this);
2890 } else {
2891 // Non-global variable. Call the runtime to try to delete from the
2892 // context where the variable was introduced.
2893 __ Push(var->name());
2894 __ CallRuntime(Runtime::kDeleteLookupSlot);
2895 context()->Plug(r0);
2896 } 2650 }
2897 } else { 2651 } else {
2898 // Result of deleting non-property, non-variable reference is true. 2652 // Result of deleting non-property, non-variable reference is true.
2899 // The subexpression may have side effects. 2653 // The subexpression may have side effects.
2900 VisitForEffect(expr->expression()); 2654 VisitForEffect(expr->expression());
2901 context()->Plug(true); 2655 context()->Plug(true);
2902 } 2656 }
2903 break; 2657 break;
2904 } 2658 }
2905 2659
(...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after
3645 DCHECK(interrupt_address == 3399 DCHECK(interrupt_address ==
3646 isolate->builtins()->OnStackReplacement()->entry()); 3400 isolate->builtins()->OnStackReplacement()->entry());
3647 return ON_STACK_REPLACEMENT; 3401 return ON_STACK_REPLACEMENT;
3648 } 3402 }
3649 3403
3650 3404
3651 } // namespace internal 3405 } // namespace internal
3652 } // namespace v8 3406 } // namespace v8
3653 3407
3654 #endif // V8_TARGET_ARCH_ARM 3408 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/compiler/ast-graph-builder.cc ('k') | src/full-codegen/arm64/full-codegen-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698