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

Side by Side Diff: src/full-codegen/s390/full-codegen-s390.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/ppc/full-codegen-ppc.cc ('k') | src/full-codegen/x64/full-codegen-x64.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 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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_S390 5 #if V8_TARGET_ARCH_S390
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 733 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 if (variable->binding_needs_init()) { 744 if (variable->binding_needs_init()) {
745 Comment cmnt(masm_, "[ VariableDeclaration"); 745 Comment cmnt(masm_, "[ VariableDeclaration");
746 EmitDebugCheckDeclarationContext(variable); 746 EmitDebugCheckDeclarationContext(variable);
747 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 747 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
748 __ StoreP(ip, ContextMemOperand(cp, variable->index())); 748 __ StoreP(ip, ContextMemOperand(cp, variable->index()));
749 // No write barrier since the_hole_value is in old space. 749 // No write barrier since the_hole_value is in old space.
750 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 750 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
751 } 751 }
752 break; 752 break;
753 753
754 case VariableLocation::LOOKUP: { 754 case VariableLocation::LOOKUP:
755 Comment cmnt(masm_, "[ VariableDeclaration");
756 DCHECK_EQ(VAR, variable->mode());
757 DCHECK(!variable->binding_needs_init());
758 __ mov(r4, Operand(variable->name()));
759 __ Push(r4);
760 __ CallRuntime(Runtime::kDeclareEvalVar);
761 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
762 break;
763 }
764
765 case VariableLocation::MODULE: 755 case VariableLocation::MODULE:
766 UNREACHABLE(); 756 UNREACHABLE();
767 } 757 }
768 } 758 }
769 759
770 void FullCodeGenerator::VisitFunctionDeclaration( 760 void FullCodeGenerator::VisitFunctionDeclaration(
771 FunctionDeclaration* declaration) { 761 FunctionDeclaration* declaration) {
772 VariableProxy* proxy = declaration->proxy(); 762 VariableProxy* proxy = declaration->proxy();
773 Variable* variable = proxy->var(); 763 Variable* variable = proxy->var();
774 switch (variable->location()) { 764 switch (variable->location()) {
(...skipping 25 matching lines...) Expand all
800 __ StoreP(result_register(), ContextMemOperand(cp, variable->index())); 790 __ StoreP(result_register(), ContextMemOperand(cp, variable->index()));
801 int offset = Context::SlotOffset(variable->index()); 791 int offset = Context::SlotOffset(variable->index());
802 // We know that we have written a function, which is not a smi. 792 // We know that we have written a function, which is not a smi.
803 __ RecordWriteContextSlot(cp, offset, result_register(), r4, 793 __ RecordWriteContextSlot(cp, offset, result_register(), r4,
804 kLRHasBeenSaved, kDontSaveFPRegs, 794 kLRHasBeenSaved, kDontSaveFPRegs,
805 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); 795 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
806 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 796 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
807 break; 797 break;
808 } 798 }
809 799
810 case VariableLocation::LOOKUP: { 800 case VariableLocation::LOOKUP:
811 Comment cmnt(masm_, "[ FunctionDeclaration");
812 __ mov(r4, Operand(variable->name()));
813 PushOperand(r4);
814 // Push initial value for function declaration.
815 VisitForStackValue(declaration->fun());
816 CallRuntimeWithOperands(Runtime::kDeclareEvalFunction);
817 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
818 break;
819 }
820
821 case VariableLocation::MODULE: 801 case VariableLocation::MODULE:
822 UNREACHABLE(); 802 UNREACHABLE();
823 } 803 }
824 } 804 }
825 805
826 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 806 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
827 // Call the runtime to declare the globals. 807 // Call the runtime to declare the globals.
828 __ mov(r3, Operand(pairs)); 808 __ mov(r3, Operand(pairs));
829 __ LoadSmiLiteral(r2, Smi::FromInt(DeclareGlobalsFlags())); 809 __ LoadSmiLiteral(r2, Smi::FromInt(DeclareGlobalsFlags()));
830 __ EmitLoadTypeFeedbackVector(r4); 810 __ EmitLoadTypeFeedbackVector(r4);
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
1115 void FullCodeGenerator::EmitSetHomeObjectAccumulator(Expression* initializer, 1095 void FullCodeGenerator::EmitSetHomeObjectAccumulator(Expression* initializer,
1116 int offset, 1096 int offset,
1117 FeedbackVectorSlot slot) { 1097 FeedbackVectorSlot slot) {
1118 DCHECK(NeedsHomeObject(initializer)); 1098 DCHECK(NeedsHomeObject(initializer));
1119 __ Move(StoreDescriptor::ReceiverRegister(), r2); 1099 __ Move(StoreDescriptor::ReceiverRegister(), r2);
1120 __ LoadP(StoreDescriptor::ValueRegister(), 1100 __ LoadP(StoreDescriptor::ValueRegister(),
1121 MemOperand(sp, offset * kPointerSize)); 1101 MemOperand(sp, offset * kPointerSize));
1122 CallStoreIC(slot, isolate()->factory()->home_object_symbol()); 1102 CallStoreIC(slot, isolate()->factory()->home_object_symbol());
1123 } 1103 }
1124 1104
1125 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
1126 TypeofMode typeof_mode,
1127 Label* slow) {
1128 Register current = cp;
1129 Register next = r3;
1130 Register temp = r4;
1131
1132 int to_check = scope()->ContextChainLengthUntilOutermostSloppyEval();
1133 for (Scope* s = scope(); to_check > 0; s = s->outer_scope()) {
1134 if (!s->NeedsContext()) continue;
1135 if (s->calls_sloppy_eval()) {
1136 // Check that extension is "the hole".
1137 __ LoadP(temp, ContextMemOperand(current, Context::EXTENSION_INDEX));
1138 __ JumpIfNotRoot(temp, Heap::kTheHoleValueRootIndex, slow);
1139 }
1140 // Load next context in chain.
1141 __ LoadP(next, ContextMemOperand(current, Context::PREVIOUS_INDEX));
1142 // Walk the rest of the chain without clobbering cp.
1143 current = next;
1144 to_check--;
1145 }
1146
1147 // All extension objects were empty and it is safe to use a normal global
1148 // load machinery.
1149 EmitGlobalVariableLoad(proxy, typeof_mode);
1150 }
1151
1152 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
1153 Label* slow) {
1154 DCHECK(var->IsContextSlot());
1155 Register context = cp;
1156 Register next = r5;
1157 Register temp = r6;
1158
1159 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) {
1160 if (s->NeedsContext()) {
1161 if (s->calls_sloppy_eval()) {
1162 // Check that extension is "the hole".
1163 __ LoadP(temp, ContextMemOperand(context, Context::EXTENSION_INDEX));
1164 __ JumpIfNotRoot(temp, Heap::kTheHoleValueRootIndex, slow);
1165 }
1166 __ LoadP(next, ContextMemOperand(context, Context::PREVIOUS_INDEX));
1167 // Walk the rest of the chain without clobbering cp.
1168 context = next;
1169 }
1170 }
1171 // Check that last extension is "the hole".
1172 __ LoadP(temp, ContextMemOperand(context, Context::EXTENSION_INDEX));
1173 __ JumpIfNotRoot(temp, Heap::kTheHoleValueRootIndex, slow);
1174
1175 // This function is used only for loads, not stores, so it's safe to
1176 // return an cp-based operand (the write barrier cannot be allowed to
1177 // destroy the cp register).
1178 return ContextMemOperand(context, var->index());
1179 }
1180
1181 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
1182 TypeofMode typeof_mode,
1183 Label* slow, Label* done) {
1184 // Generate fast-case code for variables that might be shadowed by
1185 // eval-introduced variables. Eval is used a lot without
1186 // introducing variables. In those cases, we do not want to
1187 // perform a runtime call for all variables in the scope
1188 // containing the eval.
1189 Variable* var = proxy->var();
1190 if (var->mode() == DYNAMIC_GLOBAL) {
1191 EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
1192 __ b(done);
1193 } else if (var->mode() == DYNAMIC_LOCAL) {
1194 Variable* local = var->local_if_not_shadowed();
1195 __ LoadP(r2, ContextSlotOperandCheckExtensions(local, slow));
1196 if (local->binding_needs_init()) {
1197 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex);
1198 __ bne(done);
1199 __ mov(r2, Operand(var->name()));
1200 __ push(r2);
1201 __ CallRuntime(Runtime::kThrowReferenceError);
1202 } else {
1203 __ b(done);
1204 }
1205 }
1206 }
1207
1208 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1105 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1209 TypeofMode typeof_mode) { 1106 TypeofMode typeof_mode) {
1210 // Record position before possible IC call. 1107 // Record position before possible IC call.
1211 SetExpressionPosition(proxy); 1108 SetExpressionPosition(proxy);
1212 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS); 1109 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS);
1213 Variable* var = proxy->var(); 1110 Variable* var = proxy->var();
1214 1111
1215 // Three cases: global variables, lookup variables, and all other types of 1112 // Two cases: global variables and all other types of variables.
1216 // variables.
1217 switch (var->location()) { 1113 switch (var->location()) {
1218 case VariableLocation::UNALLOCATED: { 1114 case VariableLocation::UNALLOCATED: {
1219 Comment cmnt(masm_, "[ Global variable"); 1115 Comment cmnt(masm_, "[ Global variable");
1220 EmitGlobalVariableLoad(proxy, typeof_mode); 1116 EmitGlobalVariableLoad(proxy, typeof_mode);
1221 context()->Plug(r2); 1117 context()->Plug(r2);
1222 break; 1118 break;
1223 } 1119 }
1224 1120
1225 case VariableLocation::PARAMETER: 1121 case VariableLocation::PARAMETER:
1226 case VariableLocation::LOCAL: 1122 case VariableLocation::LOCAL:
(...skipping 12 matching lines...) Expand all
1239 __ push(r2); 1135 __ push(r2);
1240 __ CallRuntime(Runtime::kThrowReferenceError); 1136 __ CallRuntime(Runtime::kThrowReferenceError);
1241 __ bind(&done); 1137 __ bind(&done);
1242 context()->Plug(r2); 1138 context()->Plug(r2);
1243 break; 1139 break;
1244 } 1140 }
1245 context()->Plug(var); 1141 context()->Plug(var);
1246 break; 1142 break;
1247 } 1143 }
1248 1144
1249 case VariableLocation::LOOKUP: { 1145 case VariableLocation::LOOKUP:
1250 Comment cmnt(masm_, "[ Lookup variable");
1251 Label done, slow;
1252 // Generate code for loading from variables potentially shadowed
1253 // by eval-introduced variables.
1254 EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
1255 __ bind(&slow);
1256 __ Push(var->name());
1257 Runtime::FunctionId function_id =
1258 typeof_mode == NOT_INSIDE_TYPEOF
1259 ? Runtime::kLoadLookupSlot
1260 : Runtime::kLoadLookupSlotInsideTypeof;
1261 __ CallRuntime(function_id);
1262 __ bind(&done);
1263 context()->Plug(r2);
1264 break;
1265 }
1266
1267 case VariableLocation::MODULE: 1146 case VariableLocation::MODULE:
1268 UNREACHABLE(); 1147 UNREACHABLE();
1269 } 1148 }
1270 } 1149 }
1271 1150
1272 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { 1151 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
1273 Expression* expression = (property == NULL) ? NULL : property->value(); 1152 Expression* expression = (property == NULL) ? NULL : property->value();
1274 if (expression == NULL) { 1153 if (expression == NULL) {
1275 __ LoadRoot(r3, Heap::kNullValueRootIndex); 1154 __ LoadRoot(r3, Heap::kNullValueRootIndex);
1276 PushOperand(r3); 1155 PushOperand(r3);
(...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after
2060 __ LoadP(r5, location); 1939 __ LoadP(r5, location);
2061 __ CompareRoot(r5, Heap::kTheHoleValueRootIndex); 1940 __ CompareRoot(r5, Heap::kTheHoleValueRootIndex);
2062 __ beq(&uninitialized_this); 1941 __ beq(&uninitialized_this);
2063 __ mov(r3, Operand(var->name())); 1942 __ mov(r3, Operand(var->name()));
2064 __ push(r3); 1943 __ push(r3);
2065 __ CallRuntime(Runtime::kThrowReferenceError); 1944 __ CallRuntime(Runtime::kThrowReferenceError);
2066 __ bind(&uninitialized_this); 1945 __ bind(&uninitialized_this);
2067 EmitStoreToStackLocalOrContextSlot(var, location); 1946 EmitStoreToStackLocalOrContextSlot(var, location);
2068 } else { 1947 } else {
2069 DCHECK(var->mode() != CONST || op == Token::INIT); 1948 DCHECK(var->mode() != CONST || op == Token::INIT);
2070 if (var->IsLookupSlot()) { 1949 DCHECK((var->IsStackAllocated() || var->IsContextSlot()));
2071 // Assignment to var. 1950 DCHECK(!var->IsLookupSlot());
2072 __ Push(var->name()); 1951 // Assignment to var or initializing assignment to let/const in harmony
2073 __ Push(r2); 1952 // mode.
2074 __ CallRuntime(is_strict(language_mode()) 1953 MemOperand location = VarOperand(var, r3);
2075 ? Runtime::kStoreLookupSlot_Strict 1954 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) {
2076 : Runtime::kStoreLookupSlot_Sloppy); 1955 // Check for an uninitialized let binding.
2077 } else { 1956 __ LoadP(r4, location);
2078 // Assignment to var or initializing assignment to let/const in harmony 1957 __ CompareRoot(r4, Heap::kTheHoleValueRootIndex);
2079 // mode. 1958 __ Check(eq, kLetBindingReInitialization);
2080 DCHECK((var->IsStackAllocated() || var->IsContextSlot()));
2081 MemOperand location = VarOperand(var, r3);
2082 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) {
2083 // Check for an uninitialized let binding.
2084 __ LoadP(r4, location);
2085 __ CompareRoot(r4, Heap::kTheHoleValueRootIndex);
2086 __ Check(eq, kLetBindingReInitialization);
2087 }
2088 EmitStoreToStackLocalOrContextSlot(var, location);
2089 } 1959 }
1960 EmitStoreToStackLocalOrContextSlot(var, location);
2090 } 1961 }
2091 } 1962 }
2092 1963
2093 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 1964 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2094 // Assignment to a property, using a named store IC. 1965 // Assignment to a property, using a named store IC.
2095 Property* prop = expr->target()->AsProperty(); 1966 Property* prop = expr->target()->AsProperty();
2096 DCHECK(prop != NULL); 1967 DCHECK(prop != NULL);
2097 DCHECK(prop->key()->IsLiteral()); 1968 DCHECK(prop->key()->IsLiteral());
2098 1969
2099 PopOperand(StoreDescriptor::ReceiverRegister()); 1970 PopOperand(StoreDescriptor::ReceiverRegister());
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
2294 __ LoadP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); 2165 __ LoadP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
2295 __ mov(r2, Operand(arg_count)); 2166 __ mov(r2, Operand(arg_count));
2296 CallIC(code); 2167 CallIC(code);
2297 OperandStackDepthDecrement(arg_count + 1); 2168 OperandStackDepthDecrement(arg_count + 1);
2298 2169
2299 RecordJSReturnSite(expr); 2170 RecordJSReturnSite(expr);
2300 RestoreContext(); 2171 RestoreContext();
2301 context()->DropAndPlug(1, r2); 2172 context()->DropAndPlug(1, r2);
2302 } 2173 }
2303 2174
2304 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) {
2305 int arg_count = expr->arguments()->length();
2306 // r6: copy of the first argument or undefined if it doesn't exist.
2307 if (arg_count > 0) {
2308 __ LoadP(r6, MemOperand(sp, arg_count * kPointerSize), r0);
2309 } else {
2310 __ LoadRoot(r6, Heap::kUndefinedValueRootIndex);
2311 }
2312
2313 // r5: the receiver of the enclosing function.
2314 __ LoadP(r5, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
2315
2316 // r4: language mode.
2317 __ LoadSmiLiteral(r4, Smi::FromInt(language_mode()));
2318
2319 // r3: the start position of the scope the calls resides in.
2320 __ LoadSmiLiteral(r3, Smi::FromInt(scope()->start_position()));
2321
2322 // r2: the source position of the eval call.
2323 __ LoadSmiLiteral(r2, Smi::FromInt(expr->position()));
2324
2325 // Do the runtime call.
2326 __ Push(r6, r5, r4, r3, r2);
2327 __ CallRuntime(Runtime::kResolvePossiblyDirectEval);
2328 }
2329
2330 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls.
2331 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
2332 VariableProxy* callee = expr->expression()->AsVariableProxy();
2333 if (callee->var()->IsLookupSlot()) {
2334 Label slow, done;
2335 SetExpressionPosition(callee);
2336 // Generate code for loading from variables potentially shadowed by
2337 // eval-introduced variables.
2338 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2339
2340 __ bind(&slow);
2341 // Call the runtime to find the function to call (returned in r2) and
2342 // the object holding it (returned in r3).
2343 __ Push(callee->name());
2344 __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2345 PushOperands(r2, r3); // Function, receiver.
2346 PrepareForBailoutForId(expr->LookupId(), BailoutState::NO_REGISTERS);
2347
2348 // If fast case code has been generated, emit code to push the function
2349 // and receiver and have the slow path jump around this code.
2350 if (done.is_linked()) {
2351 Label call;
2352 __ b(&call);
2353 __ bind(&done);
2354 // Push function.
2355 __ push(r2);
2356 // Pass undefined as the receiver, which is the WithBaseObject of a
2357 // non-object environment record. If the callee is sloppy, it will patch
2358 // it up to be the global receiver.
2359 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex);
2360 __ push(r3);
2361 __ bind(&call);
2362 }
2363 } else {
2364 VisitForStackValue(callee);
2365 // refEnv.WithBaseObject()
2366 __ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
2367 PushOperand(r4); // Reserved receiver slot.
2368 }
2369 }
2370
2371 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
2372 // In a call to eval, we first call
2373 // Runtime_ResolvePossiblyDirectEval to resolve the function we need
2374 // to call. Then we call the resolved function using the given arguments.
2375 ZoneList<Expression*>* args = expr->arguments();
2376 int arg_count = args->length();
2377
2378 PushCalleeAndWithBaseObject(expr);
2379
2380 // Push the arguments.
2381 for (int i = 0; i < arg_count; i++) {
2382 VisitForStackValue(args->at(i));
2383 }
2384
2385 // Push a copy of the function (found below the arguments) and
2386 // resolve eval.
2387 __ LoadP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
2388 __ push(r3);
2389 EmitResolvePossiblyDirectEval(expr);
2390
2391 // Touch up the stack with the resolved function.
2392 __ StoreP(r2, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
2393
2394 PrepareForBailoutForId(expr->EvalId(), BailoutState::NO_REGISTERS);
2395
2396 // Record source position for debugger.
2397 SetCallPosition(expr);
2398 Handle<Code> code = CodeFactory::CallIC(isolate(), ConvertReceiverMode::kAny,
2399 expr->tail_call_mode())
2400 .code();
2401 __ LoadSmiLiteral(r5, SmiFromSlot(expr->CallFeedbackICSlot()));
2402 __ LoadP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
2403 __ mov(r2, Operand(arg_count));
2404 __ Call(code, RelocInfo::CODE_TARGET);
2405 OperandStackDepthDecrement(arg_count + 1);
2406 RecordJSReturnSite(expr);
2407 RestoreContext();
2408 context()->DropAndPlug(1, r2);
2409 }
2410
2411 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2175 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
2412 Comment cmnt(masm_, "[ CallNew"); 2176 Comment cmnt(masm_, "[ CallNew");
2413 // According to ECMA-262, section 11.2.2, page 44, the function 2177 // According to ECMA-262, section 11.2.2, page 44, the function
2414 // expression in new calls must be evaluated before the 2178 // expression in new calls must be evaluated before the
2415 // arguments. 2179 // arguments.
2416 2180
2417 // Push constructor on the stack. If it's not a function it's used as 2181 // 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 2182 // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
2419 // ignored. 2183 // ignored.
2420 DCHECK(!expr->expression()->IsSuperPropertyReference()); 2184 DCHECK(!expr->expression()->IsSuperPropertyReference());
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
2815 // Delete of an unqualified identifier is disallowed in strict mode but 2579 // Delete of an unqualified identifier is disallowed in strict mode but
2816 // "delete this" is allowed. 2580 // "delete this" is allowed.
2817 bool is_this = var->is_this(); 2581 bool is_this = var->is_this();
2818 DCHECK(is_sloppy(language_mode()) || is_this); 2582 DCHECK(is_sloppy(language_mode()) || is_this);
2819 if (var->IsUnallocated()) { 2583 if (var->IsUnallocated()) {
2820 __ LoadGlobalObject(r4); 2584 __ LoadGlobalObject(r4);
2821 __ mov(r3, Operand(var->name())); 2585 __ mov(r3, Operand(var->name()));
2822 __ Push(r4, r3); 2586 __ Push(r4, r3);
2823 __ CallRuntime(Runtime::kDeleteProperty_Sloppy); 2587 __ CallRuntime(Runtime::kDeleteProperty_Sloppy);
2824 context()->Plug(r2); 2588 context()->Plug(r2);
2825 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 2589 } else {
2590 DCHECK(!var->IsLookupSlot());
2591 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2826 // Result of deleting non-global, non-dynamic variables is false. 2592 // Result of deleting non-global, non-dynamic variables is false.
2827 // The subexpression does not have side effects. 2593 // The subexpression does not have side effects.
2828 context()->Plug(is_this); 2594 context()->Plug(is_this);
2829 } else {
2830 // Non-global variable. Call the runtime to try to delete from the
2831 // context where the variable was introduced.
2832 __ Push(var->name());
2833 __ CallRuntime(Runtime::kDeleteLookupSlot);
2834 context()->Plug(r2);
2835 } 2595 }
2836 } else { 2596 } else {
2837 // Result of deleting non-property, non-variable reference is true. 2597 // Result of deleting non-property, non-variable reference is true.
2838 // The subexpression may have side effects. 2598 // The subexpression may have side effects.
2839 VisitForEffect(expr->expression()); 2599 VisitForEffect(expr->expression());
2840 context()->Plug(true); 2600 context()->Plug(true);
2841 } 2601 }
2842 break; 2602 break;
2843 } 2603 }
2844 2604
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after
3498 DCHECK(kOSRBranchInstruction == br_instr); 3258 DCHECK(kOSRBranchInstruction == br_instr);
3499 3259
3500 DCHECK(interrupt_address == 3260 DCHECK(interrupt_address ==
3501 isolate->builtins()->OnStackReplacement()->entry()); 3261 isolate->builtins()->OnStackReplacement()->entry());
3502 return ON_STACK_REPLACEMENT; 3262 return ON_STACK_REPLACEMENT;
3503 } 3263 }
3504 3264
3505 } // namespace internal 3265 } // namespace internal
3506 } // namespace v8 3266 } // namespace v8
3507 #endif // V8_TARGET_ARCH_S390 3267 #endif // V8_TARGET_ARCH_S390
OLDNEW
« no previous file with comments | « src/full-codegen/ppc/full-codegen-ppc.cc ('k') | src/full-codegen/x64/full-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698