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

Side by Side Diff: src/full-codegen/ppc/full-codegen-ppc.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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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_PPC 5 #if V8_TARGET_ARCH_PPC
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 758 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 if (variable->binding_needs_init()) { 769 if (variable->binding_needs_init()) {
770 Comment cmnt(masm_, "[ VariableDeclaration"); 770 Comment cmnt(masm_, "[ VariableDeclaration");
771 EmitDebugCheckDeclarationContext(variable); 771 EmitDebugCheckDeclarationContext(variable);
772 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 772 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
773 __ StoreP(ip, ContextMemOperand(cp, variable->index()), r0); 773 __ StoreP(ip, ContextMemOperand(cp, variable->index()), r0);
774 // No write barrier since the_hole_value is in old space. 774 // No write barrier since the_hole_value is in old space.
775 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 775 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
776 } 776 }
777 break; 777 break;
778 778
779 case VariableLocation::LOOKUP: { 779 case VariableLocation::LOOKUP:
780 Comment cmnt(masm_, "[ VariableDeclaration");
781 DCHECK_EQ(VAR, variable->mode());
782 DCHECK(!variable->binding_needs_init());
783 __ mov(r5, Operand(variable->name()));
784 __ Push(r5);
785 __ CallRuntime(Runtime::kDeclareEvalVar);
786 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
787 break;
788 }
789
790 case VariableLocation::MODULE: 780 case VariableLocation::MODULE:
791 UNREACHABLE(); 781 UNREACHABLE();
792 } 782 }
793 } 783 }
794 784
795 785
796 void FullCodeGenerator::VisitFunctionDeclaration( 786 void FullCodeGenerator::VisitFunctionDeclaration(
797 FunctionDeclaration* declaration) { 787 FunctionDeclaration* declaration) {
798 VariableProxy* proxy = declaration->proxy(); 788 VariableProxy* proxy = declaration->proxy();
799 Variable* variable = proxy->var(); 789 Variable* variable = proxy->var();
(...skipping 27 matching lines...) Expand all
827 r0); 817 r0);
828 int offset = Context::SlotOffset(variable->index()); 818 int offset = Context::SlotOffset(variable->index());
829 // We know that we have written a function, which is not a smi. 819 // We know that we have written a function, which is not a smi.
830 __ RecordWriteContextSlot(cp, offset, result_register(), r5, 820 __ RecordWriteContextSlot(cp, offset, result_register(), r5,
831 kLRHasBeenSaved, kDontSaveFPRegs, 821 kLRHasBeenSaved, kDontSaveFPRegs,
832 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); 822 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
833 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 823 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
834 break; 824 break;
835 } 825 }
836 826
837 case VariableLocation::LOOKUP: { 827 case VariableLocation::LOOKUP:
838 Comment cmnt(masm_, "[ FunctionDeclaration");
839 __ mov(r5, Operand(variable->name()));
840 PushOperand(r5);
841 // Push initial value for function declaration.
842 VisitForStackValue(declaration->fun());
843 CallRuntimeWithOperands(Runtime::kDeclareEvalFunction);
844 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
845 break;
846 }
847
848 case VariableLocation::MODULE: 828 case VariableLocation::MODULE:
849 UNREACHABLE(); 829 UNREACHABLE();
850 } 830 }
851 } 831 }
852 832
853 833
854 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 834 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
855 // Call the runtime to declare the globals. 835 // Call the runtime to declare the globals.
856 __ mov(r4, Operand(pairs)); 836 __ mov(r4, Operand(pairs));
857 __ LoadSmiLiteral(r3, Smi::FromInt(DeclareGlobalsFlags())); 837 __ LoadSmiLiteral(r3, Smi::FromInt(DeclareGlobalsFlags()));
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
1148 void FullCodeGenerator::EmitSetHomeObjectAccumulator(Expression* initializer, 1128 void FullCodeGenerator::EmitSetHomeObjectAccumulator(Expression* initializer,
1149 int offset, 1129 int offset,
1150 FeedbackVectorSlot slot) { 1130 FeedbackVectorSlot slot) {
1151 DCHECK(NeedsHomeObject(initializer)); 1131 DCHECK(NeedsHomeObject(initializer));
1152 __ Move(StoreDescriptor::ReceiverRegister(), r3); 1132 __ Move(StoreDescriptor::ReceiverRegister(), r3);
1153 __ LoadP(StoreDescriptor::ValueRegister(), 1133 __ LoadP(StoreDescriptor::ValueRegister(),
1154 MemOperand(sp, offset * kPointerSize)); 1134 MemOperand(sp, offset * kPointerSize));
1155 CallStoreIC(slot, isolate()->factory()->home_object_symbol()); 1135 CallStoreIC(slot, isolate()->factory()->home_object_symbol());
1156 } 1136 }
1157 1137
1158
1159 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
1160 TypeofMode typeof_mode,
1161 Label* slow) {
1162 Register current = cp;
1163 Register next = r4;
1164 Register temp = r5;
1165
1166 int to_check = scope()->ContextChainLengthUntilOutermostSloppyEval();
1167 for (Scope* s = scope(); to_check > 0; s = s->outer_scope()) {
1168 if (!s->NeedsContext()) continue;
1169 if (s->calls_sloppy_eval()) {
1170 // Check that extension is "the hole".
1171 __ LoadP(temp, ContextMemOperand(current, Context::EXTENSION_INDEX));
1172 __ JumpIfNotRoot(temp, Heap::kTheHoleValueRootIndex, slow);
1173 }
1174 // Load next context in chain.
1175 __ LoadP(next, ContextMemOperand(current, Context::PREVIOUS_INDEX));
1176 // Walk the rest of the chain without clobbering cp.
1177 current = next;
1178 to_check--;
1179 }
1180
1181 // All extension objects were empty and it is safe to use a normal global
1182 // load machinery.
1183 EmitGlobalVariableLoad(proxy, typeof_mode);
1184 }
1185
1186
1187 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
1188 Label* slow) {
1189 DCHECK(var->IsContextSlot());
1190 Register context = cp;
1191 Register next = r6;
1192 Register temp = r7;
1193
1194 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) {
1195 if (s->NeedsContext()) {
1196 if (s->calls_sloppy_eval()) {
1197 // Check that extension is "the hole".
1198 __ LoadP(temp, ContextMemOperand(context, Context::EXTENSION_INDEX));
1199 __ JumpIfNotRoot(temp, Heap::kTheHoleValueRootIndex, slow);
1200 }
1201 __ LoadP(next, ContextMemOperand(context, Context::PREVIOUS_INDEX));
1202 // Walk the rest of the chain without clobbering cp.
1203 context = next;
1204 }
1205 }
1206 // Check that last extension is "the hole".
1207 __ LoadP(temp, ContextMemOperand(context, Context::EXTENSION_INDEX));
1208 __ JumpIfNotRoot(temp, Heap::kTheHoleValueRootIndex, slow);
1209
1210 // This function is used only for loads, not stores, so it's safe to
1211 // return an cp-based operand (the write barrier cannot be allowed to
1212 // destroy the cp register).
1213 return ContextMemOperand(context, var->index());
1214 }
1215
1216
1217 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
1218 TypeofMode typeof_mode,
1219 Label* slow, Label* done) {
1220 // Generate fast-case code for variables that might be shadowed by
1221 // eval-introduced variables. Eval is used a lot without
1222 // introducing variables. In those cases, we do not want to
1223 // perform a runtime call for all variables in the scope
1224 // containing the eval.
1225 Variable* var = proxy->var();
1226 if (var->mode() == DYNAMIC_GLOBAL) {
1227 EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
1228 __ b(done);
1229 } else if (var->mode() == DYNAMIC_LOCAL) {
1230 Variable* local = var->local_if_not_shadowed();
1231 __ LoadP(r3, ContextSlotOperandCheckExtensions(local, slow));
1232 if (local->binding_needs_init()) {
1233 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex);
1234 __ bne(done);
1235 __ mov(r3, Operand(var->name()));
1236 __ push(r3);
1237 __ CallRuntime(Runtime::kThrowReferenceError);
1238 } else {
1239 __ b(done);
1240 }
1241 }
1242 }
1243
1244 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1138 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1245 TypeofMode typeof_mode) { 1139 TypeofMode typeof_mode) {
1246 // Record position before possible IC call. 1140 // Record position before possible IC call.
1247 SetExpressionPosition(proxy); 1141 SetExpressionPosition(proxy);
1248 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS); 1142 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS);
1249 Variable* var = proxy->var(); 1143 Variable* var = proxy->var();
1250 1144
1251 // Three cases: global variables, lookup variables, and all other types of 1145 // Two cases: global variables and all other types of variables.
1252 // variables.
1253 switch (var->location()) { 1146 switch (var->location()) {
1254 case VariableLocation::UNALLOCATED: { 1147 case VariableLocation::UNALLOCATED: {
1255 Comment cmnt(masm_, "[ Global variable"); 1148 Comment cmnt(masm_, "[ Global variable");
1256 EmitGlobalVariableLoad(proxy, typeof_mode); 1149 EmitGlobalVariableLoad(proxy, typeof_mode);
1257 context()->Plug(r3); 1150 context()->Plug(r3);
1258 break; 1151 break;
1259 } 1152 }
1260 1153
1261 case VariableLocation::PARAMETER: 1154 case VariableLocation::PARAMETER:
1262 case VariableLocation::LOCAL: 1155 case VariableLocation::LOCAL:
(...skipping 12 matching lines...) Expand all
1275 __ push(r3); 1168 __ push(r3);
1276 __ CallRuntime(Runtime::kThrowReferenceError); 1169 __ CallRuntime(Runtime::kThrowReferenceError);
1277 __ bind(&done); 1170 __ bind(&done);
1278 context()->Plug(r3); 1171 context()->Plug(r3);
1279 break; 1172 break;
1280 } 1173 }
1281 context()->Plug(var); 1174 context()->Plug(var);
1282 break; 1175 break;
1283 } 1176 }
1284 1177
1285 case VariableLocation::LOOKUP: { 1178 case VariableLocation::LOOKUP:
1286 Comment cmnt(masm_, "[ Lookup variable");
1287 Label done, slow;
1288 // Generate code for loading from variables potentially shadowed
1289 // by eval-introduced variables.
1290 EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
1291 __ bind(&slow);
1292 __ Push(var->name());
1293 Runtime::FunctionId function_id =
1294 typeof_mode == NOT_INSIDE_TYPEOF
1295 ? Runtime::kLoadLookupSlot
1296 : Runtime::kLoadLookupSlotInsideTypeof;
1297 __ CallRuntime(function_id);
1298 __ bind(&done);
1299 context()->Plug(r3);
1300 break;
1301 }
1302
1303 case VariableLocation::MODULE: 1179 case VariableLocation::MODULE:
1304 UNREACHABLE(); 1180 UNREACHABLE();
1305 } 1181 }
1306 } 1182 }
1307 1183
1308 1184
1309 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { 1185 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
1310 Expression* expression = (property == NULL) ? NULL : property->value(); 1186 Expression* expression = (property == NULL) ? NULL : property->value();
1311 if (expression == NULL) { 1187 if (expression == NULL) {
1312 __ LoadRoot(r4, Heap::kNullValueRootIndex); 1188 __ LoadRoot(r4, Heap::kNullValueRootIndex);
(...skipping 791 matching lines...) Expand 10 before | Expand all | Expand 10 after
2104 __ CompareRoot(r6, Heap::kTheHoleValueRootIndex); 1980 __ CompareRoot(r6, Heap::kTheHoleValueRootIndex);
2105 __ beq(&uninitialized_this); 1981 __ beq(&uninitialized_this);
2106 __ mov(r4, Operand(var->name())); 1982 __ mov(r4, Operand(var->name()));
2107 __ push(r4); 1983 __ push(r4);
2108 __ CallRuntime(Runtime::kThrowReferenceError); 1984 __ CallRuntime(Runtime::kThrowReferenceError);
2109 __ bind(&uninitialized_this); 1985 __ bind(&uninitialized_this);
2110 EmitStoreToStackLocalOrContextSlot(var, location); 1986 EmitStoreToStackLocalOrContextSlot(var, location);
2111 1987
2112 } else { 1988 } else {
2113 DCHECK(var->mode() != CONST || op == Token::INIT); 1989 DCHECK(var->mode() != CONST || op == Token::INIT);
2114 if (var->IsLookupSlot()) { 1990 DCHECK((var->IsStackAllocated() || var->IsContextSlot()));
2115 // Assignment to var. 1991 DCHECK(!var->IsLookupSlot());
2116 __ Push(var->name()); 1992 // Assignment to var or initializing assignment to let/const in harmony
2117 __ Push(r3); 1993 // mode.
2118 __ CallRuntime(is_strict(language_mode()) 1994 MemOperand location = VarOperand(var, r4);
2119 ? Runtime::kStoreLookupSlot_Strict 1995 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) {
2120 : Runtime::kStoreLookupSlot_Sloppy); 1996 // Check for an uninitialized let binding.
2121 } else { 1997 __ LoadP(r5, location);
2122 // Assignment to var or initializing assignment to let/const in harmony 1998 __ CompareRoot(r5, Heap::kTheHoleValueRootIndex);
2123 // mode. 1999 __ Check(eq, kLetBindingReInitialization);
2124 DCHECK((var->IsStackAllocated() || var->IsContextSlot()));
2125 MemOperand location = VarOperand(var, r4);
2126 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) {
2127 // Check for an uninitialized let binding.
2128 __ LoadP(r5, location);
2129 __ CompareRoot(r5, Heap::kTheHoleValueRootIndex);
2130 __ Check(eq, kLetBindingReInitialization);
2131 }
2132 EmitStoreToStackLocalOrContextSlot(var, location);
2133 } 2000 }
2001 EmitStoreToStackLocalOrContextSlot(var, location);
2134 } 2002 }
2135 } 2003 }
2136 2004
2137 2005
2138 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2006 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2139 // Assignment to a property, using a named store IC. 2007 // Assignment to a property, using a named store IC.
2140 Property* prop = expr->target()->AsProperty(); 2008 Property* prop = expr->target()->AsProperty();
2141 DCHECK(prop != NULL); 2009 DCHECK(prop != NULL);
2142 DCHECK(prop->key()->IsLiteral()); 2010 DCHECK(prop->key()->IsLiteral());
2143 2011
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
2346 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); 2214 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
2347 __ mov(r3, Operand(arg_count)); 2215 __ mov(r3, Operand(arg_count));
2348 CallIC(code); 2216 CallIC(code);
2349 OperandStackDepthDecrement(arg_count + 1); 2217 OperandStackDepthDecrement(arg_count + 1);
2350 2218
2351 RecordJSReturnSite(expr); 2219 RecordJSReturnSite(expr);
2352 RestoreContext(); 2220 RestoreContext();
2353 context()->DropAndPlug(1, r3); 2221 context()->DropAndPlug(1, r3);
2354 } 2222 }
2355 2223
2356
2357 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) {
2358 int arg_count = expr->arguments()->length();
2359 // r7: copy of the first argument or undefined if it doesn't exist.
2360 if (arg_count > 0) {
2361 __ LoadP(r7, MemOperand(sp, arg_count * kPointerSize), r0);
2362 } else {
2363 __ LoadRoot(r7, Heap::kUndefinedValueRootIndex);
2364 }
2365
2366 // r6: the receiver of the enclosing function.
2367 __ LoadP(r6, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
2368
2369 // r5: language mode.
2370 __ LoadSmiLiteral(r5, Smi::FromInt(language_mode()));
2371
2372 // r4: the start position of the scope the calls resides in.
2373 __ LoadSmiLiteral(r4, Smi::FromInt(scope()->start_position()));
2374
2375 // r3: the source position of the eval call.
2376 __ LoadSmiLiteral(r3, Smi::FromInt(expr->position()));
2377
2378 // Do the runtime call.
2379 __ Push(r7, r6, r5, r4, r3);
2380 __ CallRuntime(Runtime::kResolvePossiblyDirectEval);
2381 }
2382
2383
2384 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls.
2385 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
2386 VariableProxy* callee = expr->expression()->AsVariableProxy();
2387 if (callee->var()->IsLookupSlot()) {
2388 Label slow, done;
2389 SetExpressionPosition(callee);
2390 // Generate code for loading from variables potentially shadowed by
2391 // eval-introduced variables.
2392 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2393
2394 __ bind(&slow);
2395 // Call the runtime to find the function to call (returned in r3) and
2396 // the object holding it (returned in r4).
2397 __ Push(callee->name());
2398 __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2399 PushOperands(r3, r4); // Function, receiver.
2400 PrepareForBailoutForId(expr->LookupId(), BailoutState::NO_REGISTERS);
2401
2402 // If fast case code has been generated, emit code to push the function
2403 // and receiver and have the slow path jump around this code.
2404 if (done.is_linked()) {
2405 Label call;
2406 __ b(&call);
2407 __ bind(&done);
2408 // Push function.
2409 __ push(r3);
2410 // Pass undefined as the receiver, which is the WithBaseObject of a
2411 // non-object environment record. If the callee is sloppy, it will patch
2412 // it up to be the global receiver.
2413 __ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
2414 __ push(r4);
2415 __ bind(&call);
2416 }
2417 } else {
2418 VisitForStackValue(callee);
2419 // refEnv.WithBaseObject()
2420 __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
2421 PushOperand(r5); // Reserved receiver slot.
2422 }
2423 }
2424
2425
2426 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
2427 // In a call to eval, we first call
2428 // Runtime_ResolvePossiblyDirectEval to resolve the function we need
2429 // to call. Then we call the resolved function using the given arguments.
2430 ZoneList<Expression*>* args = expr->arguments();
2431 int arg_count = args->length();
2432
2433 PushCalleeAndWithBaseObject(expr);
2434
2435 // Push the arguments.
2436 for (int i = 0; i < arg_count; i++) {
2437 VisitForStackValue(args->at(i));
2438 }
2439
2440 // Push a copy of the function (found below the arguments) and
2441 // resolve eval.
2442 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
2443 __ push(r4);
2444 EmitResolvePossiblyDirectEval(expr);
2445
2446 // Touch up the stack with the resolved function.
2447 __ StoreP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
2448
2449 PrepareForBailoutForId(expr->EvalId(), BailoutState::NO_REGISTERS);
2450
2451 // Record source position for debugger.
2452 SetCallPosition(expr);
2453 Handle<Code> code = CodeFactory::CallIC(isolate(), ConvertReceiverMode::kAny,
2454 expr->tail_call_mode())
2455 .code();
2456 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackICSlot()));
2457 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
2458 __ mov(r3, Operand(arg_count));
2459 __ Call(code, RelocInfo::CODE_TARGET);
2460 OperandStackDepthDecrement(arg_count + 1);
2461 RecordJSReturnSite(expr);
2462 RestoreContext();
2463 context()->DropAndPlug(1, r3);
2464 }
2465
2466
2467 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2224 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
2468 Comment cmnt(masm_, "[ CallNew"); 2225 Comment cmnt(masm_, "[ CallNew");
2469 // According to ECMA-262, section 11.2.2, page 44, the function 2226 // According to ECMA-262, section 11.2.2, page 44, the function
2470 // expression in new calls must be evaluated before the 2227 // expression in new calls must be evaluated before the
2471 // arguments. 2228 // arguments.
2472 2229
2473 // Push constructor on the stack. If it's not a function it's used as 2230 // Push constructor on the stack. If it's not a function it's used as
2474 // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is 2231 // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
2475 // ignored. 2232 // ignored.
2476 DCHECK(!expr->expression()->IsSuperPropertyReference()); 2233 DCHECK(!expr->expression()->IsSuperPropertyReference());
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
2885 // Delete of an unqualified identifier is disallowed in strict mode but 2642 // Delete of an unqualified identifier is disallowed in strict mode but
2886 // "delete this" is allowed. 2643 // "delete this" is allowed.
2887 bool is_this = var->is_this(); 2644 bool is_this = var->is_this();
2888 DCHECK(is_sloppy(language_mode()) || is_this); 2645 DCHECK(is_sloppy(language_mode()) || is_this);
2889 if (var->IsUnallocated()) { 2646 if (var->IsUnallocated()) {
2890 __ LoadGlobalObject(r5); 2647 __ LoadGlobalObject(r5);
2891 __ mov(r4, Operand(var->name())); 2648 __ mov(r4, Operand(var->name()));
2892 __ Push(r5, r4); 2649 __ Push(r5, r4);
2893 __ CallRuntime(Runtime::kDeleteProperty_Sloppy); 2650 __ CallRuntime(Runtime::kDeleteProperty_Sloppy);
2894 context()->Plug(r3); 2651 context()->Plug(r3);
2895 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 2652 } else {
2653 DCHECK(!var->IsLookupSlot());
2654 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2896 // Result of deleting non-global, non-dynamic variables is false. 2655 // Result of deleting non-global, non-dynamic variables is false.
2897 // The subexpression does not have side effects. 2656 // The subexpression does not have side effects.
2898 context()->Plug(is_this); 2657 context()->Plug(is_this);
2899 } else {
2900 // Non-global variable. Call the runtime to try to delete from the
2901 // context where the variable was introduced.
2902 __ Push(var->name());
2903 __ CallRuntime(Runtime::kDeleteLookupSlot);
2904 context()->Plug(r3);
2905 } 2658 }
2906 } else { 2659 } else {
2907 // Result of deleting non-property, non-variable reference is true. 2660 // Result of deleting non-property, non-variable reference is true.
2908 // The subexpression may have side effects. 2661 // The subexpression may have side effects.
2909 VisitForEffect(expr->expression()); 2662 VisitForEffect(expr->expression());
2910 context()->Plug(true); 2663 context()->Plug(true);
2911 } 2664 }
2912 break; 2665 break;
2913 } 2666 }
2914 2667
(...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after
3576 3329
3577 DCHECK(Assembler::IsCrSet(Assembler::instr_at(cmp_address))); 3330 DCHECK(Assembler::IsCrSet(Assembler::instr_at(cmp_address)));
3578 3331
3579 DCHECK(interrupt_address == 3332 DCHECK(interrupt_address ==
3580 isolate->builtins()->OnStackReplacement()->entry()); 3333 isolate->builtins()->OnStackReplacement()->entry());
3581 return ON_STACK_REPLACEMENT; 3334 return ON_STACK_REPLACEMENT;
3582 } 3335 }
3583 } // namespace internal 3336 } // namespace internal
3584 } // namespace v8 3337 } // namespace v8
3585 #endif // V8_TARGET_ARCH_PPC 3338 #endif // V8_TARGET_ARCH_PPC
OLDNEW
« no previous file with comments | « src/full-codegen/mips64/full-codegen-mips64.cc ('k') | src/full-codegen/s390/full-codegen-s390.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698