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

Side by Side Diff: src/full-codegen/arm64/full-codegen-arm64.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/arm/full-codegen-arm.cc ('k') | src/full-codegen/full-codegen.h » ('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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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_ARM64 5 #if V8_TARGET_ARCH_ARM64
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 785 matching lines...) Expand 10 before | Expand all | Expand 10 after
796 if (variable->binding_needs_init()) { 796 if (variable->binding_needs_init()) {
797 Comment cmnt(masm_, "[ VariableDeclaration"); 797 Comment cmnt(masm_, "[ VariableDeclaration");
798 EmitDebugCheckDeclarationContext(variable); 798 EmitDebugCheckDeclarationContext(variable);
799 __ LoadRoot(x10, Heap::kTheHoleValueRootIndex); 799 __ LoadRoot(x10, Heap::kTheHoleValueRootIndex);
800 __ Str(x10, ContextMemOperand(cp, variable->index())); 800 __ Str(x10, ContextMemOperand(cp, variable->index()));
801 // No write barrier since the_hole_value is in old space. 801 // No write barrier since the_hole_value is in old space.
802 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 802 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
803 } 803 }
804 break; 804 break;
805 805
806 case VariableLocation::LOOKUP: { 806 case VariableLocation::LOOKUP:
807 Comment cmnt(masm_, "[ VariableDeclaration");
808 DCHECK_EQ(VAR, variable->mode());
809 DCHECK(!variable->binding_needs_init());
810 __ Mov(x2, Operand(variable->name()));
811 __ Push(x2);
812 __ CallRuntime(Runtime::kDeclareEvalVar);
813 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
814 break;
815 }
816
817 case VariableLocation::MODULE: 807 case VariableLocation::MODULE:
818 UNREACHABLE(); 808 UNREACHABLE();
819 } 809 }
820 } 810 }
821 811
822 812
823 void FullCodeGenerator::VisitFunctionDeclaration( 813 void FullCodeGenerator::VisitFunctionDeclaration(
824 FunctionDeclaration* declaration) { 814 FunctionDeclaration* declaration) {
825 VariableProxy* proxy = declaration->proxy(); 815 VariableProxy* proxy = declaration->proxy();
826 Variable* variable = proxy->var(); 816 Variable* variable = proxy->var();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
858 result_register(), 848 result_register(),
859 x2, 849 x2,
860 kLRHasBeenSaved, 850 kLRHasBeenSaved,
861 kDontSaveFPRegs, 851 kDontSaveFPRegs,
862 EMIT_REMEMBERED_SET, 852 EMIT_REMEMBERED_SET,
863 OMIT_SMI_CHECK); 853 OMIT_SMI_CHECK);
864 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 854 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
865 break; 855 break;
866 } 856 }
867 857
868 case VariableLocation::LOOKUP: { 858 case VariableLocation::LOOKUP:
869 Comment cmnt(masm_, "[ Function Declaration");
870 __ Mov(x2, Operand(variable->name()));
871 PushOperand(x2);
872 // Push initial value for function declaration.
873 VisitForStackValue(declaration->fun());
874 CallRuntimeWithOperands(Runtime::kDeclareEvalFunction);
875 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
876 break;
877 }
878
879 case VariableLocation::MODULE: 859 case VariableLocation::MODULE:
880 UNREACHABLE(); 860 UNREACHABLE();
881 } 861 }
882 } 862 }
883 863
884 864
885 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 865 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
886 // Call the runtime to declare the globals. 866 // Call the runtime to declare the globals.
887 __ Mov(x11, Operand(pairs)); 867 __ Mov(x11, Operand(pairs));
888 Register flags = xzr; 868 Register flags = xzr;
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
1164 1144
1165 void FullCodeGenerator::EmitSetHomeObjectAccumulator(Expression* initializer, 1145 void FullCodeGenerator::EmitSetHomeObjectAccumulator(Expression* initializer,
1166 int offset, 1146 int offset,
1167 FeedbackVectorSlot slot) { 1147 FeedbackVectorSlot slot) {
1168 DCHECK(NeedsHomeObject(initializer)); 1148 DCHECK(NeedsHomeObject(initializer));
1169 __ Move(StoreDescriptor::ReceiverRegister(), x0); 1149 __ Move(StoreDescriptor::ReceiverRegister(), x0);
1170 __ Peek(StoreDescriptor::ValueRegister(), offset * kPointerSize); 1150 __ Peek(StoreDescriptor::ValueRegister(), offset * kPointerSize);
1171 CallStoreIC(slot, isolate()->factory()->home_object_symbol()); 1151 CallStoreIC(slot, isolate()->factory()->home_object_symbol());
1172 } 1152 }
1173 1153
1174
1175 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
1176 TypeofMode typeof_mode,
1177 Label* slow) {
1178 Register current = cp;
1179 Register next = x10;
1180 Register temp = x11;
1181
1182 int to_check = scope()->ContextChainLengthUntilOutermostSloppyEval();
1183 for (Scope* s = scope(); to_check > 0; s = s->outer_scope()) {
1184 if (!s->NeedsContext()) continue;
1185 if (s->calls_sloppy_eval()) {
1186 // Check that extension is "the hole".
1187 __ Ldr(temp, ContextMemOperand(current, Context::EXTENSION_INDEX));
1188 __ JumpIfNotRoot(temp, Heap::kTheHoleValueRootIndex, slow);
1189 }
1190 // Load next context in chain.
1191 __ Ldr(next, ContextMemOperand(current, Context::PREVIOUS_INDEX));
1192 // Walk the rest of the chain without clobbering cp.
1193 current = next;
1194 to_check--;
1195 }
1196
1197 // All extension objects were empty and it is safe to use a normal global
1198 // load machinery.
1199 EmitGlobalVariableLoad(proxy, typeof_mode);
1200 }
1201
1202
1203 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
1204 Label* slow) {
1205 DCHECK(var->IsContextSlot());
1206 Register context = cp;
1207 Register next = x10;
1208 Register temp = x11;
1209
1210 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) {
1211 if (s->NeedsContext()) {
1212 if (s->calls_sloppy_eval()) {
1213 // Check that extension is "the hole".
1214 __ Ldr(temp, ContextMemOperand(context, Context::EXTENSION_INDEX));
1215 __ JumpIfNotRoot(temp, Heap::kTheHoleValueRootIndex, slow);
1216 }
1217 __ Ldr(next, ContextMemOperand(context, Context::PREVIOUS_INDEX));
1218 // Walk the rest of the chain without clobbering cp.
1219 context = next;
1220 }
1221 }
1222 // Check that last extension is "the hole".
1223 __ Ldr(temp, ContextMemOperand(context, Context::EXTENSION_INDEX));
1224 __ JumpIfNotRoot(temp, Heap::kTheHoleValueRootIndex, slow);
1225
1226 // This function is used only for loads, not stores, so it's safe to
1227 // return an cp-based operand (the write barrier cannot be allowed to
1228 // destroy the cp register).
1229 return ContextMemOperand(context, var->index());
1230 }
1231
1232
1233 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
1234 TypeofMode typeof_mode,
1235 Label* slow, Label* done) {
1236 // Generate fast-case code for variables that might be shadowed by
1237 // eval-introduced variables. Eval is used a lot without
1238 // introducing variables. In those cases, we do not want to
1239 // perform a runtime call for all variables in the scope
1240 // containing the eval.
1241 Variable* var = proxy->var();
1242 if (var->mode() == DYNAMIC_GLOBAL) {
1243 EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
1244 __ B(done);
1245 } else if (var->mode() == DYNAMIC_LOCAL) {
1246 Variable* local = var->local_if_not_shadowed();
1247 __ Ldr(x0, ContextSlotOperandCheckExtensions(local, slow));
1248 if (local->binding_needs_init()) {
1249 __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, done);
1250 __ Mov(x0, Operand(var->name()));
1251 __ Push(x0);
1252 __ CallRuntime(Runtime::kThrowReferenceError);
1253 } else {
1254 __ B(done);
1255 }
1256 }
1257 }
1258
1259 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1154 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1260 TypeofMode typeof_mode) { 1155 TypeofMode typeof_mode) {
1261 // Record position before possible IC call. 1156 // Record position before possible IC call.
1262 SetExpressionPosition(proxy); 1157 SetExpressionPosition(proxy);
1263 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS); 1158 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS);
1264 Variable* var = proxy->var(); 1159 Variable* var = proxy->var();
1265 1160
1266 // Three cases: global variables, lookup variables, and all other types of 1161 // Two cases: global variables and all other types of variables.
1267 // variables.
1268 switch (var->location()) { 1162 switch (var->location()) {
1269 case VariableLocation::UNALLOCATED: { 1163 case VariableLocation::UNALLOCATED: {
1270 Comment cmnt(masm_, "Global variable"); 1164 Comment cmnt(masm_, "Global variable");
1271 EmitGlobalVariableLoad(proxy, typeof_mode); 1165 EmitGlobalVariableLoad(proxy, typeof_mode);
1272 context()->Plug(x0); 1166 context()->Plug(x0);
1273 break; 1167 break;
1274 } 1168 }
1275 1169
1276 case VariableLocation::PARAMETER: 1170 case VariableLocation::PARAMETER:
1277 case VariableLocation::LOCAL: 1171 case VariableLocation::LOCAL:
(...skipping 12 matching lines...) Expand all
1290 __ Push(x0); 1184 __ Push(x0);
1291 __ CallRuntime(Runtime::kThrowReferenceError); 1185 __ CallRuntime(Runtime::kThrowReferenceError);
1292 __ Bind(&done); 1186 __ Bind(&done);
1293 context()->Plug(x0); 1187 context()->Plug(x0);
1294 break; 1188 break;
1295 } 1189 }
1296 context()->Plug(var); 1190 context()->Plug(var);
1297 break; 1191 break;
1298 } 1192 }
1299 1193
1300 case VariableLocation::LOOKUP: { 1194 case VariableLocation::LOOKUP:
1301 Label done, slow;
1302 // Generate code for loading from variables potentially shadowed by
1303 // eval-introduced variables.
1304 EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
1305 __ Bind(&slow);
1306 Comment cmnt(masm_, "Lookup variable");
1307 __ Push(var->name());
1308 Runtime::FunctionId function_id =
1309 typeof_mode == NOT_INSIDE_TYPEOF
1310 ? Runtime::kLoadLookupSlot
1311 : Runtime::kLoadLookupSlotInsideTypeof;
1312 __ CallRuntime(function_id);
1313 __ Bind(&done);
1314 context()->Plug(x0);
1315 break;
1316 }
1317
1318 case VariableLocation::MODULE: 1195 case VariableLocation::MODULE:
1319 UNREACHABLE(); 1196 UNREACHABLE();
1320 } 1197 }
1321 } 1198 }
1322 1199
1323 1200
1324 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { 1201 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
1325 Expression* expression = (property == NULL) ? NULL : property->value(); 1202 Expression* expression = (property == NULL) ? NULL : property->value();
1326 if (expression == NULL) { 1203 if (expression == NULL) {
1327 __ LoadRoot(x10, Heap::kNullValueRootIndex); 1204 __ LoadRoot(x10, Heap::kNullValueRootIndex);
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after
2031 __ Ldr(x10, location); 1908 __ Ldr(x10, location);
2032 __ JumpIfRoot(x10, Heap::kTheHoleValueRootIndex, &uninitialized_this); 1909 __ JumpIfRoot(x10, Heap::kTheHoleValueRootIndex, &uninitialized_this);
2033 __ Mov(x0, Operand(var->name())); 1910 __ Mov(x0, Operand(var->name()));
2034 __ Push(x0); 1911 __ Push(x0);
2035 __ CallRuntime(Runtime::kThrowReferenceError); 1912 __ CallRuntime(Runtime::kThrowReferenceError);
2036 __ bind(&uninitialized_this); 1913 __ bind(&uninitialized_this);
2037 EmitStoreToStackLocalOrContextSlot(var, location); 1914 EmitStoreToStackLocalOrContextSlot(var, location);
2038 1915
2039 } else { 1916 } else {
2040 DCHECK(var->mode() != CONST || op == Token::INIT); 1917 DCHECK(var->mode() != CONST || op == Token::INIT);
2041 if (var->IsLookupSlot()) { 1918 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2042 // Assignment to var. 1919 DCHECK(!var->IsLookupSlot());
2043 __ Push(var->name()); 1920 // Assignment to var or initializing assignment to let/const in harmony
2044 __ Push(x0); 1921 // mode.
2045 __ CallRuntime(is_strict(language_mode()) 1922 MemOperand location = VarOperand(var, x1);
2046 ? Runtime::kStoreLookupSlot_Strict 1923 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) {
2047 : Runtime::kStoreLookupSlot_Sloppy); 1924 __ Ldr(x10, location);
2048 } else { 1925 __ CompareRoot(x10, Heap::kTheHoleValueRootIndex);
2049 // Assignment to var or initializing assignment to let/const in harmony 1926 __ Check(eq, kLetBindingReInitialization);
2050 // mode.
2051 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2052 MemOperand location = VarOperand(var, x1);
2053 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) {
2054 __ Ldr(x10, location);
2055 __ CompareRoot(x10, Heap::kTheHoleValueRootIndex);
2056 __ Check(eq, kLetBindingReInitialization);
2057 }
2058 EmitStoreToStackLocalOrContextSlot(var, location);
2059 } 1927 }
1928 EmitStoreToStackLocalOrContextSlot(var, location);
2060 } 1929 }
2061 } 1930 }
2062 1931
2063 1932
2064 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 1933 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2065 ASM_LOCATION("FullCodeGenerator::EmitNamedPropertyAssignment"); 1934 ASM_LOCATION("FullCodeGenerator::EmitNamedPropertyAssignment");
2066 // Assignment to a property, using a named store IC. 1935 // Assignment to a property, using a named store IC.
2067 Property* prop = expr->target()->AsProperty(); 1936 Property* prop = expr->target()->AsProperty();
2068 DCHECK(prop != NULL); 1937 DCHECK(prop != NULL);
2069 DCHECK(prop->key()->IsLiteral()); 1938 DCHECK(prop->key()->IsLiteral());
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
2288 __ Peek(x1, (arg_count + 1) * kXRegSize); 2157 __ Peek(x1, (arg_count + 1) * kXRegSize);
2289 __ Mov(x0, arg_count); 2158 __ Mov(x0, arg_count);
2290 CallIC(code); 2159 CallIC(code);
2291 OperandStackDepthDecrement(arg_count + 1); 2160 OperandStackDepthDecrement(arg_count + 1);
2292 2161
2293 RecordJSReturnSite(expr); 2162 RecordJSReturnSite(expr);
2294 RestoreContext(); 2163 RestoreContext();
2295 context()->DropAndPlug(1, x0); 2164 context()->DropAndPlug(1, x0);
2296 } 2165 }
2297 2166
2298 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) {
2299 int arg_count = expr->arguments()->length();
2300 ASM_LOCATION("FullCodeGenerator::EmitResolvePossiblyDirectEval");
2301 // Prepare to push a copy of the first argument or undefined if it doesn't
2302 // exist.
2303 if (arg_count > 0) {
2304 __ Peek(x9, arg_count * kXRegSize);
2305 } else {
2306 __ LoadRoot(x9, Heap::kUndefinedValueRootIndex);
2307 }
2308
2309 __ Ldr(x10, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
2310
2311 // Prepare to push the language mode.
2312 __ Mov(x11, Smi::FromInt(language_mode()));
2313 // Prepare to push the start position of the scope the calls resides in.
2314 __ Mov(x12, Smi::FromInt(scope()->start_position()));
2315 // Prepare to push the source position of the eval call.
2316 __ Mov(x13, Smi::FromInt(expr->position()));
2317
2318 // Push.
2319 __ Push(x9, x10, x11, x12, x13);
2320
2321 // Do the runtime call.
2322 __ CallRuntime(Runtime::kResolvePossiblyDirectEval);
2323 }
2324
2325
2326 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls.
2327 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
2328 VariableProxy* callee = expr->expression()->AsVariableProxy();
2329 if (callee->var()->IsLookupSlot()) {
2330 Label slow, done;
2331 SetExpressionPosition(callee);
2332 // Generate code for loading from variables potentially shadowed
2333 // by eval-introduced variables.
2334 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2335
2336 __ Bind(&slow);
2337 // Call the runtime to find the function to call (returned in x0)
2338 // and the object holding it (returned in x1).
2339 __ Push(callee->name());
2340 __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2341 PushOperands(x0, x1); // Receiver, function.
2342 PrepareForBailoutForId(expr->LookupId(), BailoutState::NO_REGISTERS);
2343
2344 // If fast case code has been generated, emit code to push the
2345 // function and receiver and have the slow path jump around this
2346 // code.
2347 if (done.is_linked()) {
2348 Label call;
2349 __ B(&call);
2350 __ Bind(&done);
2351 // Push function.
2352 // The receiver is implicitly the global receiver. Indicate this
2353 // by passing the undefined to the call function stub.
2354 __ LoadRoot(x1, Heap::kUndefinedValueRootIndex);
2355 __ Push(x0, x1);
2356 __ Bind(&call);
2357 }
2358 } else {
2359 VisitForStackValue(callee);
2360 // refEnv.WithBaseObject()
2361 __ LoadRoot(x10, Heap::kUndefinedValueRootIndex);
2362 PushOperand(x10); // Reserved receiver slot.
2363 }
2364 }
2365
2366
2367 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
2368 ASM_LOCATION("FullCodeGenerator::EmitPossiblyEvalCall");
2369 // In a call to eval, we first call Runtime_ResolvePossiblyDirectEval
2370 // to resolve the function we need to call. Then we call the resolved
2371 // function using the given arguments.
2372 ZoneList<Expression*>* args = expr->arguments();
2373 int arg_count = args->length();
2374
2375 PushCalleeAndWithBaseObject(expr);
2376
2377 // Push the arguments.
2378 for (int i = 0; i < arg_count; i++) {
2379 VisitForStackValue(args->at(i));
2380 }
2381
2382 // Push a copy of the function (found below the arguments) and
2383 // resolve eval.
2384 __ Peek(x10, (arg_count + 1) * kPointerSize);
2385 __ Push(x10);
2386 EmitResolvePossiblyDirectEval(expr);
2387
2388 // Touch up the stack with the resolved function.
2389 __ Poke(x0, (arg_count + 1) * kPointerSize);
2390
2391 PrepareForBailoutForId(expr->EvalId(), BailoutState::NO_REGISTERS);
2392
2393 // Record source position for debugger.
2394 SetCallPosition(expr);
2395
2396 // Call the evaluated function.
2397 Handle<Code> code = CodeFactory::CallIC(isolate(), ConvertReceiverMode::kAny,
2398 expr->tail_call_mode())
2399 .code();
2400 __ Mov(x3, SmiFromSlot(expr->CallFeedbackICSlot()));
2401 __ Peek(x1, (arg_count + 1) * kXRegSize);
2402 __ Mov(x0, arg_count);
2403 __ Call(code, RelocInfo::CODE_TARGET);
2404 OperandStackDepthDecrement(arg_count + 1);
2405 RecordJSReturnSite(expr);
2406 RestoreContext();
2407 context()->DropAndPlug(1, x0);
2408 }
2409
2410
2411 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2167 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
2412 Comment cmnt(masm_, "[ CallNew"); 2168 Comment cmnt(masm_, "[ CallNew");
2413 // According to ECMA-262, section 11.2.2, page 44, the function 2169 // According to ECMA-262, section 11.2.2, page 44, the function
2414 // expression in new calls must be evaluated before the 2170 // expression in new calls must be evaluated before the
2415 // arguments. 2171 // arguments.
2416 2172
2417 // Push constructor on the stack. If it's not a function it's used as 2173 // Push constructor on the stack. If it's not a function it's used as
2418 // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is 2174 // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
2419 // ignored. 2175 // ignored.
2420 DCHECK(!expr->expression()->IsSuperPropertyReference()); 2176 DCHECK(!expr->expression()->IsSuperPropertyReference());
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after
2844 // Delete of an unqualified identifier is disallowed in strict mode but 2600 // Delete of an unqualified identifier is disallowed in strict mode but
2845 // "delete this" is allowed. 2601 // "delete this" is allowed.
2846 bool is_this = var->is_this(); 2602 bool is_this = var->is_this();
2847 DCHECK(is_sloppy(language_mode()) || is_this); 2603 DCHECK(is_sloppy(language_mode()) || is_this);
2848 if (var->IsUnallocated()) { 2604 if (var->IsUnallocated()) {
2849 __ LoadGlobalObject(x12); 2605 __ LoadGlobalObject(x12);
2850 __ Mov(x11, Operand(var->name())); 2606 __ Mov(x11, Operand(var->name()));
2851 __ Push(x12, x11); 2607 __ Push(x12, x11);
2852 __ CallRuntime(Runtime::kDeleteProperty_Sloppy); 2608 __ CallRuntime(Runtime::kDeleteProperty_Sloppy);
2853 context()->Plug(x0); 2609 context()->Plug(x0);
2854 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 2610 } else {
2611 DCHECK(!var->IsLookupSlot());
2612 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2855 // Result of deleting non-global, non-dynamic variables is false. 2613 // Result of deleting non-global, non-dynamic variables is false.
2856 // The subexpression does not have side effects. 2614 // The subexpression does not have side effects.
2857 context()->Plug(is_this); 2615 context()->Plug(is_this);
2858 } else {
2859 // Non-global variable. Call the runtime to try to delete from the
2860 // context where the variable was introduced.
2861 __ Push(var->name());
2862 __ CallRuntime(Runtime::kDeleteLookupSlot);
2863 context()->Plug(x0);
2864 } 2616 }
2865 } else { 2617 } else {
2866 // Result of deleting non-property, non-variable reference is true. 2618 // Result of deleting non-property, non-variable reference is true.
2867 // The subexpression may have side effects. 2619 // The subexpression may have side effects.
2868 VisitForEffect(expr->expression()); 2620 VisitForEffect(expr->expression());
2869 context()->Plug(true); 2621 context()->Plug(true);
2870 } 2622 }
2871 break; 2623 break;
2872 break; 2624 break;
2873 } 2625 }
(...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after
3644 } 3396 }
3645 3397
3646 return INTERRUPT; 3398 return INTERRUPT;
3647 } 3399 }
3648 3400
3649 3401
3650 } // namespace internal 3402 } // namespace internal
3651 } // namespace v8 3403 } // namespace v8
3652 3404
3653 #endif // V8_TARGET_ARCH_ARM64 3405 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/full-codegen/arm/full-codegen-arm.cc ('k') | src/full-codegen/full-codegen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698