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

Side by Side Diff: src/full-codegen/arm/full-codegen-arm.cc

Issue 1553703002: [runtime] TailCallRuntime and CallRuntime should use default argument counts (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@2015-12-29_TailCallRuntime_default_result_size_1_1550923002
Patch Set: Created 4 years, 11 months 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 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/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 int locals_count = info->scope()->num_stack_slots(); 137 int locals_count = info->scope()->num_stack_slots();
138 // Generators allocate locals, if any, in context slots. 138 // Generators allocate locals, if any, in context slots.
139 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0); 139 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0);
140 if (locals_count > 0) { 140 if (locals_count > 0) {
141 if (locals_count >= 128) { 141 if (locals_count >= 128) {
142 Label ok; 142 Label ok;
143 __ sub(r9, sp, Operand(locals_count * kPointerSize)); 143 __ sub(r9, sp, Operand(locals_count * kPointerSize));
144 __ LoadRoot(r2, Heap::kRealStackLimitRootIndex); 144 __ LoadRoot(r2, Heap::kRealStackLimitRootIndex);
145 __ cmp(r9, Operand(r2)); 145 __ cmp(r9, Operand(r2));
146 __ b(hs, &ok); 146 __ b(hs, &ok);
147 __ CallRuntime(Runtime::kThrowStackOverflow, 0); 147 __ CallRuntime(Runtime::kThrowStackOverflow);
148 __ bind(&ok); 148 __ bind(&ok);
149 } 149 }
150 __ LoadRoot(r9, Heap::kUndefinedValueRootIndex); 150 __ LoadRoot(r9, Heap::kUndefinedValueRootIndex);
151 int kMaxPushes = FLAG_optimize_for_size ? 4 : 32; 151 int kMaxPushes = FLAG_optimize_for_size ? 4 : 32;
152 if (locals_count >= kMaxPushes) { 152 if (locals_count >= kMaxPushes) {
153 int loop_iterations = locals_count / kMaxPushes; 153 int loop_iterations = locals_count / kMaxPushes;
154 __ mov(r2, Operand(loop_iterations)); 154 __ mov(r2, Operand(loop_iterations));
155 Label loop_header; 155 Label loop_header;
156 __ bind(&loop_header); 156 __ bind(&loop_header);
157 // Do pushes. 157 // Do pushes.
(...skipping 16 matching lines...) Expand all
174 174
175 // Possibly allocate a local context. 175 // Possibly allocate a local context.
176 if (info->scope()->num_heap_slots() > 0) { 176 if (info->scope()->num_heap_slots() > 0) {
177 // Argument to NewContext is the function, which is still in r1. 177 // Argument to NewContext is the function, which is still in r1.
178 Comment cmnt(masm_, "[ Allocate context"); 178 Comment cmnt(masm_, "[ Allocate context");
179 bool need_write_barrier = true; 179 bool need_write_barrier = true;
180 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 180 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
181 if (info->scope()->is_script_scope()) { 181 if (info->scope()->is_script_scope()) {
182 __ push(r1); 182 __ push(r1);
183 __ Push(info->scope()->GetScopeInfo(info->isolate())); 183 __ Push(info->scope()->GetScopeInfo(info->isolate()));
184 __ CallRuntime(Runtime::kNewScriptContext, 2); 184 __ CallRuntime(Runtime::kNewScriptContext);
185 PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG); 185 PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG);
186 // The new target value is not used, clobbering is safe. 186 // The new target value is not used, clobbering is safe.
187 DCHECK_NULL(info->scope()->new_target_var()); 187 DCHECK_NULL(info->scope()->new_target_var());
188 } else { 188 } else {
189 if (info->scope()->new_target_var() != nullptr) { 189 if (info->scope()->new_target_var() != nullptr) {
190 __ push(r3); // Preserve new target. 190 __ push(r3); // Preserve new target.
191 } 191 }
192 if (slots <= FastNewContextStub::kMaximumSlots) { 192 if (slots <= FastNewContextStub::kMaximumSlots) {
193 FastNewContextStub stub(isolate(), slots); 193 FastNewContextStub stub(isolate(), slots);
194 __ CallStub(&stub); 194 __ CallStub(&stub);
195 // Result of FastNewContextStub is always in new space. 195 // Result of FastNewContextStub is always in new space.
196 need_write_barrier = false; 196 need_write_barrier = false;
197 } else { 197 } else {
198 __ push(r1); 198 __ push(r1);
199 __ CallRuntime(Runtime::kNewFunctionContext, 1); 199 __ CallRuntime(Runtime::kNewFunctionContext);
200 } 200 }
201 if (info->scope()->new_target_var() != nullptr) { 201 if (info->scope()->new_target_var() != nullptr) {
202 __ pop(r3); // Preserve new target. 202 __ pop(r3); // Preserve new target.
203 } 203 }
204 } 204 }
205 function_in_register_r1 = false; 205 function_in_register_r1 = false;
206 // Context is returned in r0. It replaces the context passed to us. 206 // Context is returned in r0. It replaces the context passed to us.
207 // It's saved in the stack and kept live in cp. 207 // It's saved in the stack and kept live in cp.
208 __ mov(cp, r0); 208 __ mov(cp, r0);
209 __ str(r0, MemOperand(fp, StandardFrameConstants::kContextOffset)); 209 __ str(r0, MemOperand(fp, StandardFrameConstants::kContextOffset));
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 bool is_unmapped = is_strict(language_mode()) || !has_simple_parameters(); 305 bool is_unmapped = is_strict(language_mode()) || !has_simple_parameters();
306 ArgumentsAccessStub::Type type = ArgumentsAccessStub::ComputeType( 306 ArgumentsAccessStub::Type type = ArgumentsAccessStub::ComputeType(
307 is_unmapped, literal()->has_duplicate_parameters()); 307 is_unmapped, literal()->has_duplicate_parameters());
308 ArgumentsAccessStub stub(isolate(), type); 308 ArgumentsAccessStub stub(isolate(), type);
309 __ CallStub(&stub); 309 __ CallStub(&stub);
310 310
311 SetVar(arguments, r0, r1, r2); 311 SetVar(arguments, r0, r1, r2);
312 } 312 }
313 313
314 if (FLAG_trace) { 314 if (FLAG_trace) {
315 __ CallRuntime(Runtime::kTraceEnter, 0); 315 __ CallRuntime(Runtime::kTraceEnter);
316 } 316 }
317 317
318 // Visit the declarations and body unless there is an illegal 318 // Visit the declarations and body unless there is an illegal
319 // redeclaration. 319 // redeclaration.
320 if (scope()->HasIllegalRedeclaration()) { 320 if (scope()->HasIllegalRedeclaration()) {
321 Comment cmnt(masm_, "[ Declarations"); 321 Comment cmnt(masm_, "[ Declarations");
322 VisitForEffect(scope()->GetIllegalRedeclaration()); 322 VisitForEffect(scope()->GetIllegalRedeclaration());
323 323
324 } else { 324 } else {
325 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); 325 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS);
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 void FullCodeGenerator::EmitReturnSequence() { 442 void FullCodeGenerator::EmitReturnSequence() {
443 Comment cmnt(masm_, "[ Return sequence"); 443 Comment cmnt(masm_, "[ Return sequence");
444 if (return_label_.is_bound()) { 444 if (return_label_.is_bound()) {
445 __ b(&return_label_); 445 __ b(&return_label_);
446 } else { 446 } else {
447 __ bind(&return_label_); 447 __ bind(&return_label_);
448 if (FLAG_trace) { 448 if (FLAG_trace) {
449 // Push the return value on the stack as the parameter. 449 // Push the return value on the stack as the parameter.
450 // Runtime::TraceExit returns its parameter in r0. 450 // Runtime::TraceExit returns its parameter in r0.
451 __ push(r0); 451 __ push(r0);
452 __ CallRuntime(Runtime::kTraceExit, 1); 452 __ CallRuntime(Runtime::kTraceExit);
453 } 453 }
454 // Pretend that the exit is a backwards jump to the entry. 454 // Pretend that the exit is a backwards jump to the entry.
455 int weight = 1; 455 int weight = 1;
456 if (info_->ShouldSelfOptimize()) { 456 if (info_->ShouldSelfOptimize()) {
457 weight = FLAG_interrupt_budget / FLAG_self_opt_count; 457 weight = FLAG_interrupt_budget / FLAG_self_opt_count;
458 } else { 458 } else {
459 int distance = masm_->pc_offset(); 459 int distance = masm_->pc_offset();
460 weight = Min(kMaxBackEdgeWeight, 460 weight = Min(kMaxBackEdgeWeight,
461 Max(1, distance / kCodeSizeMultiplier)); 461 Max(1, distance / kCodeSizeMultiplier));
462 } 462 }
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
847 // Note: For variables we must not push an initial value (such as 847 // Note: For variables we must not push an initial value (such as
848 // 'undefined') because we may have a (legal) redeclaration and we 848 // 'undefined') because we may have a (legal) redeclaration and we
849 // must not destroy the current value. 849 // must not destroy the current value.
850 if (hole_init) { 850 if (hole_init) {
851 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex); 851 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex);
852 } else { 852 } else {
853 __ mov(r0, Operand(Smi::FromInt(0))); // Indicates no initial value. 853 __ mov(r0, Operand(Smi::FromInt(0))); // Indicates no initial value.
854 } 854 }
855 __ Push(r2, r0); 855 __ Push(r2, r0);
856 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); 856 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes()));
857 __ CallRuntime(Runtime::kDeclareLookupSlot, 3); 857 __ CallRuntime(Runtime::kDeclareLookupSlot);
858 break; 858 break;
859 } 859 }
860 } 860 }
861 } 861 }
862 862
863 863
864 void FullCodeGenerator::VisitFunctionDeclaration( 864 void FullCodeGenerator::VisitFunctionDeclaration(
865 FunctionDeclaration* declaration) { 865 FunctionDeclaration* declaration) {
866 VariableProxy* proxy = declaration->proxy(); 866 VariableProxy* proxy = declaration->proxy();
867 Variable* variable = proxy->var(); 867 Variable* variable = proxy->var();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 break; 904 break;
905 } 905 }
906 906
907 case VariableLocation::LOOKUP: { 907 case VariableLocation::LOOKUP: {
908 Comment cmnt(masm_, "[ FunctionDeclaration"); 908 Comment cmnt(masm_, "[ FunctionDeclaration");
909 __ mov(r2, Operand(variable->name())); 909 __ mov(r2, Operand(variable->name()));
910 __ Push(r2); 910 __ Push(r2);
911 // Push initial value for function declaration. 911 // Push initial value for function declaration.
912 VisitForStackValue(declaration->fun()); 912 VisitForStackValue(declaration->fun());
913 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); 913 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes()));
914 __ CallRuntime(Runtime::kDeclareLookupSlot, 3); 914 __ CallRuntime(Runtime::kDeclareLookupSlot);
915 break; 915 break;
916 } 916 }
917 } 917 }
918 } 918 }
919 919
920 920
921 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 921 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
922 // Call the runtime to declare the globals. 922 // Call the runtime to declare the globals.
923 __ mov(r1, Operand(pairs)); 923 __ mov(r1, Operand(pairs));
924 __ mov(r0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); 924 __ mov(r0, Operand(Smi::FromInt(DeclareGlobalsFlags())));
925 __ Push(r1, r0); 925 __ Push(r1, r0);
926 __ CallRuntime(Runtime::kDeclareGlobals, 2); 926 __ CallRuntime(Runtime::kDeclareGlobals);
927 // Return value is ignored. 927 // Return value is ignored.
928 } 928 }
929 929
930 930
931 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) { 931 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) {
932 // Call the runtime to declare the modules. 932 // Call the runtime to declare the modules.
933 __ Push(descriptions); 933 __ Push(descriptions);
934 __ CallRuntime(Runtime::kDeclareModules, 1); 934 __ CallRuntime(Runtime::kDeclareModules);
935 // Return value is ignored. 935 // Return value is ignored.
936 } 936 }
937 937
938 938
939 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 939 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
940 Comment cmnt(masm_, "[ SwitchStatement"); 940 Comment cmnt(masm_, "[ SwitchStatement");
941 Breakable nested_statement(this, stmt); 941 Breakable nested_statement(this, stmt);
942 SetStatementPosition(stmt); 942 SetStatementPosition(stmt);
943 943
944 // Keep the switch value on the stack until a case matches. 944 // Keep the switch value on the stack until a case matches.
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1079 1079
1080 // The enum cache is valid. Load the map of the object being 1080 // The enum cache is valid. Load the map of the object being
1081 // iterated over and use the cache for the iteration. 1081 // iterated over and use the cache for the iteration.
1082 Label use_cache; 1082 Label use_cache;
1083 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); 1083 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset));
1084 __ b(&use_cache); 1084 __ b(&use_cache);
1085 1085
1086 // Get the set of properties to enumerate. 1086 // Get the set of properties to enumerate.
1087 __ bind(&call_runtime); 1087 __ bind(&call_runtime);
1088 __ push(r0); // Duplicate the enumerable object on the stack. 1088 __ push(r0); // Duplicate the enumerable object on the stack.
1089 __ CallRuntime(Runtime::kGetPropertyNamesFast, 1); 1089 __ CallRuntime(Runtime::kGetPropertyNamesFast);
1090 PrepareForBailoutForId(stmt->EnumId(), TOS_REG); 1090 PrepareForBailoutForId(stmt->EnumId(), TOS_REG);
1091 1091
1092 // If we got a map from the runtime call, we can do a fast 1092 // If we got a map from the runtime call, we can do a fast
1093 // modification check. Otherwise, we got a fixed array, and we have 1093 // modification check. Otherwise, we got a fixed array, and we have
1094 // to do a slow check. 1094 // to do a slow check.
1095 Label fixed_array; 1095 Label fixed_array;
1096 __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset)); 1096 __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
1097 __ LoadRoot(ip, Heap::kMetaMapRootIndex); 1097 __ LoadRoot(ip, Heap::kMetaMapRootIndex);
1098 __ cmp(r2, ip); 1098 __ cmp(r2, ip);
1099 __ b(ne, &fixed_array); 1099 __ b(ne, &fixed_array);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1158 __ ldr(r1, MemOperand(sp, 4 * kPointerSize)); 1158 __ ldr(r1, MemOperand(sp, 4 * kPointerSize));
1159 __ ldr(r4, FieldMemOperand(r1, HeapObject::kMapOffset)); 1159 __ ldr(r4, FieldMemOperand(r1, HeapObject::kMapOffset));
1160 __ cmp(r4, Operand(r2)); 1160 __ cmp(r4, Operand(r2));
1161 __ b(eq, &update_each); 1161 __ b(eq, &update_each);
1162 1162
1163 // Convert the entry to a string or (smi) 0 if it isn't a property 1163 // Convert the entry to a string or (smi) 0 if it isn't a property
1164 // any more. If the property has been removed while iterating, we 1164 // any more. If the property has been removed while iterating, we
1165 // just skip it. 1165 // just skip it.
1166 __ push(r1); // Enumerable. 1166 __ push(r1); // Enumerable.
1167 __ push(r3); // Current entry. 1167 __ push(r3); // Current entry.
1168 __ CallRuntime(Runtime::kForInFilter, 2); 1168 __ CallRuntime(Runtime::kForInFilter);
1169 PrepareForBailoutForId(stmt->FilterId(), TOS_REG); 1169 PrepareForBailoutForId(stmt->FilterId(), TOS_REG);
1170 __ mov(r3, Operand(r0)); 1170 __ mov(r3, Operand(r0));
1171 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 1171 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
1172 __ cmp(r0, ip); 1172 __ cmp(r0, ip);
1173 __ b(eq, loop_statement.continue_label()); 1173 __ b(eq, loop_statement.continue_label());
1174 1174
1175 // Update the 'each' property or variable from the possibly filtered 1175 // Update the 'each' property or variable from the possibly filtered
1176 // entry in register r3. 1176 // entry in register r3.
1177 __ bind(&update_each); 1177 __ bind(&update_each);
1178 __ mov(result_register(), r3); 1178 __ mov(result_register(), r3);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1219 if (!FLAG_always_opt && 1219 if (!FLAG_always_opt &&
1220 !FLAG_prepare_always_opt && 1220 !FLAG_prepare_always_opt &&
1221 !pretenure && 1221 !pretenure &&
1222 scope()->is_function_scope() && 1222 scope()->is_function_scope() &&
1223 info->num_literals() == 0) { 1223 info->num_literals() == 0) {
1224 FastNewClosureStub stub(isolate(), info->language_mode(), info->kind()); 1224 FastNewClosureStub stub(isolate(), info->language_mode(), info->kind());
1225 __ mov(r2, Operand(info)); 1225 __ mov(r2, Operand(info));
1226 __ CallStub(&stub); 1226 __ CallStub(&stub);
1227 } else { 1227 } else {
1228 __ Push(info); 1228 __ Push(info);
1229 __ CallRuntime( 1229 __ CallRuntime(pretenure ? Runtime::kNewClosure_Tenured
1230 pretenure ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure, 1); 1230 : Runtime::kNewClosure);
1231 } 1231 }
1232 context()->Plug(r0); 1232 context()->Plug(r0);
1233 } 1233 }
1234 1234
1235 1235
1236 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, 1236 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset,
1237 FeedbackVectorSlot slot) { 1237 FeedbackVectorSlot slot) {
1238 DCHECK(NeedsHomeObject(initializer)); 1238 DCHECK(NeedsHomeObject(initializer));
1239 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); 1239 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
1240 __ mov(StoreDescriptor::NameRegister(), 1240 __ mov(StoreDescriptor::NameRegister(),
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1359 __ ldr(r0, ContextSlotOperandCheckExtensions(local, slow)); 1359 __ ldr(r0, ContextSlotOperandCheckExtensions(local, slow));
1360 if (local->mode() == LET || local->mode() == CONST || 1360 if (local->mode() == LET || local->mode() == CONST ||
1361 local->mode() == CONST_LEGACY) { 1361 local->mode() == CONST_LEGACY) {
1362 __ CompareRoot(r0, Heap::kTheHoleValueRootIndex); 1362 __ CompareRoot(r0, Heap::kTheHoleValueRootIndex);
1363 if (local->mode() == CONST_LEGACY) { 1363 if (local->mode() == CONST_LEGACY) {
1364 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); 1364 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
1365 } else { // LET || CONST 1365 } else { // LET || CONST
1366 __ b(ne, done); 1366 __ b(ne, done);
1367 __ mov(r0, Operand(var->name())); 1367 __ mov(r0, Operand(var->name()));
1368 __ push(r0); 1368 __ push(r0);
1369 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1369 __ CallRuntime(Runtime::kThrowReferenceError);
1370 } 1370 }
1371 } 1371 }
1372 __ jmp(done); 1372 __ jmp(done);
1373 } 1373 }
1374 } 1374 }
1375 1375
1376 1376
1377 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, 1377 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
1378 TypeofMode typeof_mode) { 1378 TypeofMode typeof_mode) {
1379 Variable* var = proxy->var(); 1379 Variable* var = proxy->var();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1415 // Let and const need a read barrier. 1415 // Let and const need a read barrier.
1416 GetVar(r0, var); 1416 GetVar(r0, var);
1417 __ CompareRoot(r0, Heap::kTheHoleValueRootIndex); 1417 __ CompareRoot(r0, Heap::kTheHoleValueRootIndex);
1418 if (var->mode() == LET || var->mode() == CONST) { 1418 if (var->mode() == LET || var->mode() == CONST) {
1419 // Throw a reference error when using an uninitialized let/const 1419 // Throw a reference error when using an uninitialized let/const
1420 // binding in harmony mode. 1420 // binding in harmony mode.
1421 Label done; 1421 Label done;
1422 __ b(ne, &done); 1422 __ b(ne, &done);
1423 __ mov(r0, Operand(var->name())); 1423 __ mov(r0, Operand(var->name()));
1424 __ push(r0); 1424 __ push(r0);
1425 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1425 __ CallRuntime(Runtime::kThrowReferenceError);
1426 __ bind(&done); 1426 __ bind(&done);
1427 } else { 1427 } else {
1428 // Uninitialized legacy const bindings are unholed. 1428 // Uninitialized legacy const bindings are unholed.
1429 DCHECK(var->mode() == CONST_LEGACY); 1429 DCHECK(var->mode() == CONST_LEGACY);
1430 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); 1430 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
1431 } 1431 }
1432 context()->Plug(r0); 1432 context()->Plug(r0);
1433 break; 1433 break;
1434 } 1434 }
1435 context()->Plug(var); 1435 context()->Plug(var);
1436 break; 1436 break;
1437 } 1437 }
1438 1438
1439 case VariableLocation::LOOKUP: { 1439 case VariableLocation::LOOKUP: {
1440 Comment cmnt(masm_, "[ Lookup variable"); 1440 Comment cmnt(masm_, "[ Lookup variable");
1441 Label done, slow; 1441 Label done, slow;
1442 // Generate code for loading from variables potentially shadowed 1442 // Generate code for loading from variables potentially shadowed
1443 // by eval-introduced variables. 1443 // by eval-introduced variables.
1444 EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done); 1444 EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
1445 __ bind(&slow); 1445 __ bind(&slow);
1446 __ mov(r1, Operand(var->name())); 1446 __ mov(r1, Operand(var->name()));
1447 __ Push(cp, r1); // Context and name. 1447 __ Push(cp, r1); // Context and name.
1448 Runtime::FunctionId function_id = 1448 Runtime::FunctionId function_id =
1449 typeof_mode == NOT_INSIDE_TYPEOF 1449 typeof_mode == NOT_INSIDE_TYPEOF
1450 ? Runtime::kLoadLookupSlot 1450 ? Runtime::kLoadLookupSlot
1451 : Runtime::kLoadLookupSlotNoReferenceError; 1451 : Runtime::kLoadLookupSlotNoReferenceError;
1452 __ CallRuntime(function_id, 2); 1452 __ CallRuntime(function_id);
1453 __ bind(&done); 1453 __ bind(&done);
1454 context()->Plug(r0); 1454 context()->Plug(r0);
1455 } 1455 }
1456 } 1456 }
1457 } 1457 }
1458 1458
1459 1459
1460 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1460 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1461 Comment cmnt(masm_, "[ RegExpLiteral"); 1461 Comment cmnt(masm_, "[ RegExpLiteral");
1462 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 1462 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
(...skipping 27 matching lines...) Expand all
1490 Comment cmnt(masm_, "[ ObjectLiteral"); 1490 Comment cmnt(masm_, "[ ObjectLiteral");
1491 1491
1492 Handle<FixedArray> constant_properties = expr->constant_properties(); 1492 Handle<FixedArray> constant_properties = expr->constant_properties();
1493 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 1493 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1494 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); 1494 __ mov(r2, Operand(Smi::FromInt(expr->literal_index())));
1495 __ mov(r1, Operand(constant_properties)); 1495 __ mov(r1, Operand(constant_properties));
1496 int flags = expr->ComputeFlags(); 1496 int flags = expr->ComputeFlags();
1497 __ mov(r0, Operand(Smi::FromInt(flags))); 1497 __ mov(r0, Operand(Smi::FromInt(flags)));
1498 if (MustCreateObjectLiteralWithRuntime(expr)) { 1498 if (MustCreateObjectLiteralWithRuntime(expr)) {
1499 __ Push(r3, r2, r1, r0); 1499 __ Push(r3, r2, r1, r0);
1500 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); 1500 __ CallRuntime(Runtime::kCreateObjectLiteral);
1501 } else { 1501 } else {
1502 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); 1502 FastCloneShallowObjectStub stub(isolate(), expr->properties_count());
1503 __ CallStub(&stub); 1503 __ CallStub(&stub);
1504 } 1504 }
1505 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1505 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
1506 1506
1507 // If result_saved is true the result is on top of the stack. If 1507 // If result_saved is true the result is on top of the stack. If
1508 // result_saved is false the result is in r0. 1508 // result_saved is false the result is in r0.
1509 bool result_saved = false; 1509 bool result_saved = false;
1510 1510
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1552 __ ldr(r0, MemOperand(sp)); 1552 __ ldr(r0, MemOperand(sp));
1553 __ push(r0); 1553 __ push(r0);
1554 VisitForStackValue(key); 1554 VisitForStackValue(key);
1555 VisitForStackValue(value); 1555 VisitForStackValue(value);
1556 if (property->emit_store()) { 1556 if (property->emit_store()) {
1557 if (NeedsHomeObject(value)) { 1557 if (NeedsHomeObject(value)) {
1558 EmitSetHomeObject(value, 2, property->GetSlot()); 1558 EmitSetHomeObject(value, 2, property->GetSlot());
1559 } 1559 }
1560 __ mov(r0, Operand(Smi::FromInt(SLOPPY))); // PropertyAttributes 1560 __ mov(r0, Operand(Smi::FromInt(SLOPPY))); // PropertyAttributes
1561 __ push(r0); 1561 __ push(r0);
1562 __ CallRuntime(Runtime::kSetProperty, 4); 1562 __ CallRuntime(Runtime::kSetProperty);
1563 } else { 1563 } else {
1564 __ Drop(3); 1564 __ Drop(3);
1565 } 1565 }
1566 break; 1566 break;
1567 case ObjectLiteral::Property::PROTOTYPE: 1567 case ObjectLiteral::Property::PROTOTYPE:
1568 // Duplicate receiver on stack. 1568 // Duplicate receiver on stack.
1569 __ ldr(r0, MemOperand(sp)); 1569 __ ldr(r0, MemOperand(sp));
1570 __ push(r0); 1570 __ push(r0);
1571 VisitForStackValue(value); 1571 VisitForStackValue(value);
1572 DCHECK(property->emit_store()); 1572 DCHECK(property->emit_store());
1573 __ CallRuntime(Runtime::kInternalSetPrototype, 2); 1573 __ CallRuntime(Runtime::kInternalSetPrototype);
1574 break; 1574 break;
1575 1575
1576 case ObjectLiteral::Property::GETTER: 1576 case ObjectLiteral::Property::GETTER:
1577 if (property->emit_store()) { 1577 if (property->emit_store()) {
1578 accessor_table.lookup(key)->second->getter = property; 1578 accessor_table.lookup(key)->second->getter = property;
1579 } 1579 }
1580 break; 1580 break;
1581 case ObjectLiteral::Property::SETTER: 1581 case ObjectLiteral::Property::SETTER:
1582 if (property->emit_store()) { 1582 if (property->emit_store()) {
1583 accessor_table.lookup(key)->second->setter = property; 1583 accessor_table.lookup(key)->second->setter = property;
1584 } 1584 }
1585 break; 1585 break;
1586 } 1586 }
1587 } 1587 }
1588 1588
1589 // Emit code to define accessors, using only a single call to the runtime for 1589 // Emit code to define accessors, using only a single call to the runtime for
1590 // each pair of corresponding getters and setters. 1590 // each pair of corresponding getters and setters.
1591 for (AccessorTable::Iterator it = accessor_table.begin(); 1591 for (AccessorTable::Iterator it = accessor_table.begin();
1592 it != accessor_table.end(); 1592 it != accessor_table.end();
1593 ++it) { 1593 ++it) {
1594 __ ldr(r0, MemOperand(sp)); // Duplicate receiver. 1594 __ ldr(r0, MemOperand(sp)); // Duplicate receiver.
1595 __ push(r0); 1595 __ push(r0);
1596 VisitForStackValue(it->first); 1596 VisitForStackValue(it->first);
1597 EmitAccessor(it->second->getter); 1597 EmitAccessor(it->second->getter);
1598 EmitAccessor(it->second->setter); 1598 EmitAccessor(it->second->setter);
1599 __ mov(r0, Operand(Smi::FromInt(NONE))); 1599 __ mov(r0, Operand(Smi::FromInt(NONE)));
1600 __ push(r0); 1600 __ push(r0);
1601 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); 1601 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked);
1602 } 1602 }
1603 1603
1604 // Object literals have two parts. The "static" part on the left contains no 1604 // Object literals have two parts. The "static" part on the left contains no
1605 // computed property names, and so we can compute its map ahead of time; see 1605 // computed property names, and so we can compute its map ahead of time; see
1606 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part 1606 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part
1607 // starts with the first computed property name, and continues with all 1607 // starts with the first computed property name, and continues with all
1608 // properties to its right. All the code from above initializes the static 1608 // properties to its right. All the code from above initializes the static
1609 // component of the object literal, and arranges for the map of the result to 1609 // component of the object literal, and arranges for the map of the result to
1610 // reflect the static order in which the keys appear. For the dynamic 1610 // reflect the static order in which the keys appear. For the dynamic
1611 // properties, we compile them into a series of "SetOwnProperty" runtime 1611 // properties, we compile them into a series of "SetOwnProperty" runtime
1612 // calls. This will preserve insertion order. 1612 // calls. This will preserve insertion order.
1613 for (; property_index < expr->properties()->length(); property_index++) { 1613 for (; property_index < expr->properties()->length(); property_index++) {
1614 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1614 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1615 1615
1616 Expression* value = property->value(); 1616 Expression* value = property->value();
1617 if (!result_saved) { 1617 if (!result_saved) {
1618 __ push(r0); // Save result on the stack 1618 __ push(r0); // Save result on the stack
1619 result_saved = true; 1619 result_saved = true;
1620 } 1620 }
1621 1621
1622 __ ldr(r0, MemOperand(sp)); // Duplicate receiver. 1622 __ ldr(r0, MemOperand(sp)); // Duplicate receiver.
1623 __ push(r0); 1623 __ push(r0);
1624 1624
1625 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1625 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1626 DCHECK(!property->is_computed_name()); 1626 DCHECK(!property->is_computed_name());
1627 VisitForStackValue(value); 1627 VisitForStackValue(value);
1628 DCHECK(property->emit_store()); 1628 DCHECK(property->emit_store());
1629 __ CallRuntime(Runtime::kInternalSetPrototype, 2); 1629 __ CallRuntime(Runtime::kInternalSetPrototype);
1630 } else { 1630 } else {
1631 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); 1631 EmitPropertyKey(property, expr->GetIdForProperty(property_index));
1632 VisitForStackValue(value); 1632 VisitForStackValue(value);
1633 if (NeedsHomeObject(value)) { 1633 if (NeedsHomeObject(value)) {
1634 EmitSetHomeObject(value, 2, property->GetSlot()); 1634 EmitSetHomeObject(value, 2, property->GetSlot());
1635 } 1635 }
1636 1636
1637 switch (property->kind()) { 1637 switch (property->kind()) {
1638 case ObjectLiteral::Property::CONSTANT: 1638 case ObjectLiteral::Property::CONSTANT:
1639 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1639 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1640 case ObjectLiteral::Property::COMPUTED: 1640 case ObjectLiteral::Property::COMPUTED:
1641 if (property->emit_store()) { 1641 if (property->emit_store()) {
1642 __ mov(r0, Operand(Smi::FromInt(NONE))); 1642 __ mov(r0, Operand(Smi::FromInt(NONE)));
1643 __ push(r0); 1643 __ push(r0);
1644 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); 1644 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked);
1645 } else { 1645 } else {
1646 __ Drop(3); 1646 __ Drop(3);
1647 } 1647 }
1648 break; 1648 break;
1649 1649
1650 case ObjectLiteral::Property::PROTOTYPE: 1650 case ObjectLiteral::Property::PROTOTYPE:
1651 UNREACHABLE(); 1651 UNREACHABLE();
1652 break; 1652 break;
1653 1653
1654 case ObjectLiteral::Property::GETTER: 1654 case ObjectLiteral::Property::GETTER:
1655 __ mov(r0, Operand(Smi::FromInt(NONE))); 1655 __ mov(r0, Operand(Smi::FromInt(NONE)));
1656 __ push(r0); 1656 __ push(r0);
1657 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 4); 1657 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
1658 break; 1658 break;
1659 1659
1660 case ObjectLiteral::Property::SETTER: 1660 case ObjectLiteral::Property::SETTER:
1661 __ mov(r0, Operand(Smi::FromInt(NONE))); 1661 __ mov(r0, Operand(Smi::FromInt(NONE)));
1662 __ push(r0); 1662 __ push(r0);
1663 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 4); 1663 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
1664 break; 1664 break;
1665 } 1665 }
1666 } 1666 }
1667 } 1667 }
1668 1668
1669 if (expr->has_function()) { 1669 if (expr->has_function()) {
1670 DCHECK(result_saved); 1670 DCHECK(result_saved);
1671 __ ldr(r0, MemOperand(sp)); 1671 __ ldr(r0, MemOperand(sp));
1672 __ push(r0); 1672 __ push(r0);
1673 __ CallRuntime(Runtime::kToFastProperties, 1); 1673 __ CallRuntime(Runtime::kToFastProperties);
1674 } 1674 }
1675 1675
1676 if (result_saved) { 1676 if (result_saved) {
1677 context()->PlugTOS(); 1677 context()->PlugTOS();
1678 } else { 1678 } else {
1679 context()->Plug(r0); 1679 context()->Plug(r0);
1680 } 1680 }
1681 } 1681 }
1682 1682
1683 1683
(...skipping 12 matching lines...) Expand all
1696 // we can turn it off if we don't have anywhere else to transition to. 1696 // we can turn it off if we don't have anywhere else to transition to.
1697 allocation_site_mode = DONT_TRACK_ALLOCATION_SITE; 1697 allocation_site_mode = DONT_TRACK_ALLOCATION_SITE;
1698 } 1698 }
1699 1699
1700 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 1700 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1701 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); 1701 __ mov(r2, Operand(Smi::FromInt(expr->literal_index())));
1702 __ mov(r1, Operand(constant_elements)); 1702 __ mov(r1, Operand(constant_elements));
1703 if (MustCreateArrayLiteralWithRuntime(expr)) { 1703 if (MustCreateArrayLiteralWithRuntime(expr)) {
1704 __ mov(r0, Operand(Smi::FromInt(expr->ComputeFlags()))); 1704 __ mov(r0, Operand(Smi::FromInt(expr->ComputeFlags())));
1705 __ Push(r3, r2, r1, r0); 1705 __ Push(r3, r2, r1, r0);
1706 __ CallRuntime(Runtime::kCreateArrayLiteral, 4); 1706 __ CallRuntime(Runtime::kCreateArrayLiteral);
1707 } else { 1707 } else {
1708 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); 1708 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode);
1709 __ CallStub(&stub); 1709 __ CallStub(&stub);
1710 } 1710 }
1711 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1711 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
1712 1712
1713 bool result_saved = false; // Is the result saved to the stack? 1713 bool result_saved = false; // Is the result saved to the stack?
1714 ZoneList<Expression*>* subexprs = expr->values(); 1714 ZoneList<Expression*>* subexprs = expr->values();
1715 int length = subexprs->length(); 1715 int length = subexprs->length();
1716 1716
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1753 for (; array_index < length; array_index++) { 1753 for (; array_index < length; array_index++) {
1754 Expression* subexpr = subexprs->at(array_index); 1754 Expression* subexpr = subexprs->at(array_index);
1755 1755
1756 __ Push(r0); 1756 __ Push(r0);
1757 if (subexpr->IsSpread()) { 1757 if (subexpr->IsSpread()) {
1758 VisitForStackValue(subexpr->AsSpread()->expression()); 1758 VisitForStackValue(subexpr->AsSpread()->expression());
1759 __ InvokeBuiltin(Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX, 1759 __ InvokeBuiltin(Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX,
1760 CALL_FUNCTION); 1760 CALL_FUNCTION);
1761 } else { 1761 } else {
1762 VisitForStackValue(subexpr); 1762 VisitForStackValue(subexpr);
1763 __ CallRuntime(Runtime::kAppendElement, 2); 1763 __ CallRuntime(Runtime::kAppendElement);
1764 } 1764 }
1765 1765
1766 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1766 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1767 } 1767 }
1768 1768
1769 if (result_saved) { 1769 if (result_saved) {
1770 context()->PlugTOS(); 1770 context()->PlugTOS();
1771 } else { 1771 } else {
1772 context()->Plug(r0); 1772 context()->Plug(r0);
1773 } 1773 }
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
2165 Label push_operand_holes, call_resume; 2165 Label push_operand_holes, call_resume;
2166 __ bind(&push_operand_holes); 2166 __ bind(&push_operand_holes);
2167 __ sub(r3, r3, Operand(1), SetCC); 2167 __ sub(r3, r3, Operand(1), SetCC);
2168 __ b(mi, &call_resume); 2168 __ b(mi, &call_resume);
2169 __ push(r2); 2169 __ push(r2);
2170 __ b(&push_operand_holes); 2170 __ b(&push_operand_holes);
2171 __ bind(&call_resume); 2171 __ bind(&call_resume);
2172 DCHECK(!result_register().is(r1)); 2172 DCHECK(!result_register().is(r1));
2173 __ Push(r1, result_register()); 2173 __ Push(r1, result_register());
2174 __ Push(Smi::FromInt(resume_mode)); 2174 __ Push(Smi::FromInt(resume_mode));
2175 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); 2175 __ CallRuntime(Runtime::kResumeJSGeneratorObject);
2176 // Not reached: the runtime call returns elsewhere. 2176 // Not reached: the runtime call returns elsewhere.
2177 __ stop("not-reached"); 2177 __ stop("not-reached");
2178 2178
2179 __ bind(&done); 2179 __ bind(&done);
2180 context()->Plug(result_register()); 2180 context()->Plug(result_register());
2181 } 2181 }
2182 2182
2183 2183
2184 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { 2184 void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
2185 Label allocate, done_allocate; 2185 Label allocate, done_allocate;
2186 2186
2187 __ Allocate(JSIteratorResult::kSize, r0, r2, r3, &allocate, TAG_OBJECT); 2187 __ Allocate(JSIteratorResult::kSize, r0, r2, r3, &allocate, TAG_OBJECT);
2188 __ b(&done_allocate); 2188 __ b(&done_allocate);
2189 2189
2190 __ bind(&allocate); 2190 __ bind(&allocate);
2191 __ Push(Smi::FromInt(JSIteratorResult::kSize)); 2191 __ Push(Smi::FromInt(JSIteratorResult::kSize));
2192 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); 2192 __ CallRuntime(Runtime::kAllocateInNewSpace);
2193 2193
2194 __ bind(&done_allocate); 2194 __ bind(&done_allocate);
2195 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, r1); 2195 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, r1);
2196 __ pop(r2); 2196 __ pop(r2);
2197 __ LoadRoot(r3, 2197 __ LoadRoot(r3,
2198 done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex); 2198 done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex);
2199 __ LoadRoot(r4, Heap::kEmptyFixedArrayRootIndex); 2199 __ LoadRoot(r4, Heap::kEmptyFixedArrayRootIndex);
2200 __ str(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); 2200 __ str(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
2201 __ str(r4, FieldMemOperand(r0, JSObject::kPropertiesOffset)); 2201 __ str(r4, FieldMemOperand(r0, JSObject::kPropertiesOffset));
2202 __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset)); 2202 __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset));
(...skipping 16 matching lines...) Expand all
2219 2219
2220 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { 2220 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
2221 // Stack: receiver, home_object. 2221 // Stack: receiver, home_object.
2222 SetExpressionPosition(prop); 2222 SetExpressionPosition(prop);
2223 Literal* key = prop->key()->AsLiteral(); 2223 Literal* key = prop->key()->AsLiteral();
2224 DCHECK(!key->value()->IsSmi()); 2224 DCHECK(!key->value()->IsSmi());
2225 DCHECK(prop->IsSuperAccess()); 2225 DCHECK(prop->IsSuperAccess());
2226 2226
2227 __ Push(key->value()); 2227 __ Push(key->value());
2228 __ Push(Smi::FromInt(language_mode())); 2228 __ Push(Smi::FromInt(language_mode()));
2229 __ CallRuntime(Runtime::kLoadFromSuper, 4); 2229 __ CallRuntime(Runtime::kLoadFromSuper);
2230 } 2230 }
2231 2231
2232 2232
2233 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 2233 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2234 SetExpressionPosition(prop); 2234 SetExpressionPosition(prop);
2235 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code(); 2235 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
2236 __ mov(LoadDescriptor::SlotRegister(), 2236 __ mov(LoadDescriptor::SlotRegister(),
2237 Operand(SmiFromSlot(prop->PropertyFeedbackSlot()))); 2237 Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
2238 CallIC(ic); 2238 CallIC(ic);
2239 } 2239 }
2240 2240
2241 2241
2242 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { 2242 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
2243 // Stack: receiver, home_object, key. 2243 // Stack: receiver, home_object, key.
2244 SetExpressionPosition(prop); 2244 SetExpressionPosition(prop);
2245 __ Push(Smi::FromInt(language_mode())); 2245 __ Push(Smi::FromInt(language_mode()));
2246 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4); 2246 __ CallRuntime(Runtime::kLoadKeyedFromSuper);
2247 } 2247 }
2248 2248
2249 2249
2250 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 2250 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
2251 Token::Value op, 2251 Token::Value op,
2252 Expression* left_expr, 2252 Expression* left_expr,
2253 Expression* right_expr) { 2253 Expression* right_expr) {
2254 Label done, smi_case, stub_call; 2254 Label done, smi_case, stub_call;
2255 2255
2256 Register scratch1 = r2; 2256 Register scratch1 = r2;
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
2363 __ ldr(scratch, MemOperand(sp, 0)); // prototype 2363 __ ldr(scratch, MemOperand(sp, 0)); // prototype
2364 } 2364 }
2365 __ push(scratch); 2365 __ push(scratch);
2366 EmitPropertyKey(property, lit->GetIdForProperty(i)); 2366 EmitPropertyKey(property, lit->GetIdForProperty(i));
2367 2367
2368 // The static prototype property is read only. We handle the non computed 2368 // The static prototype property is read only. We handle the non computed
2369 // property name case in the parser. Since this is the only case where we 2369 // property name case in the parser. Since this is the only case where we
2370 // need to check for an own read only property we special case this so we do 2370 // need to check for an own read only property we special case this so we do
2371 // not need to do this for every property. 2371 // not need to do this for every property.
2372 if (property->is_static() && property->is_computed_name()) { 2372 if (property->is_static() && property->is_computed_name()) {
2373 __ CallRuntime(Runtime::kThrowIfStaticPrototype, 1); 2373 __ CallRuntime(Runtime::kThrowIfStaticPrototype);
2374 __ push(r0); 2374 __ push(r0);
2375 } 2375 }
2376 2376
2377 VisitForStackValue(value); 2377 VisitForStackValue(value);
2378 if (NeedsHomeObject(value)) { 2378 if (NeedsHomeObject(value)) {
2379 EmitSetHomeObject(value, 2, property->GetSlot()); 2379 EmitSetHomeObject(value, 2, property->GetSlot());
2380 } 2380 }
2381 2381
2382 switch (property->kind()) { 2382 switch (property->kind()) {
2383 case ObjectLiteral::Property::CONSTANT: 2383 case ObjectLiteral::Property::CONSTANT:
2384 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 2384 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
2385 case ObjectLiteral::Property::PROTOTYPE: 2385 case ObjectLiteral::Property::PROTOTYPE:
2386 UNREACHABLE(); 2386 UNREACHABLE();
2387 case ObjectLiteral::Property::COMPUTED: 2387 case ObjectLiteral::Property::COMPUTED:
2388 __ CallRuntime(Runtime::kDefineClassMethod, 3); 2388 __ CallRuntime(Runtime::kDefineClassMethod);
2389 break; 2389 break;
2390 2390
2391 case ObjectLiteral::Property::GETTER: 2391 case ObjectLiteral::Property::GETTER:
2392 __ mov(r0, Operand(Smi::FromInt(DONT_ENUM))); 2392 __ mov(r0, Operand(Smi::FromInt(DONT_ENUM)));
2393 __ push(r0); 2393 __ push(r0);
2394 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 4); 2394 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
2395 break; 2395 break;
2396 2396
2397 case ObjectLiteral::Property::SETTER: 2397 case ObjectLiteral::Property::SETTER:
2398 __ mov(r0, Operand(Smi::FromInt(DONT_ENUM))); 2398 __ mov(r0, Operand(Smi::FromInt(DONT_ENUM)));
2399 __ push(r0); 2399 __ push(r0);
2400 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 4); 2400 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
2401 break; 2401 break;
2402 2402
2403 default: 2403 default:
2404 UNREACHABLE(); 2404 UNREACHABLE();
2405 } 2405 }
2406 } 2406 }
2407 2407
2408 // Set both the prototype and constructor to have fast properties, and also 2408 // Set both the prototype and constructor to have fast properties, and also
2409 // freeze them in strong mode. 2409 // freeze them in strong mode.
2410 __ CallRuntime(Runtime::kFinalizeClassDefinition, 2); 2410 __ CallRuntime(Runtime::kFinalizeClassDefinition);
2411 } 2411 }
2412 2412
2413 2413
2414 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { 2414 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
2415 __ pop(r1); 2415 __ pop(r1);
2416 Handle<Code> code = 2416 Handle<Code> code =
2417 CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code(); 2417 CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
2418 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 2418 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
2419 CallIC(code, expr->BinaryOperationFeedbackId()); 2419 CallIC(code, expr->BinaryOperationFeedbackId());
2420 patch_site.EmitPatchInfo(); 2420 patch_site.EmitPatchInfo();
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
2528 // Non-initializing assignment to let variable needs a write barrier. 2528 // Non-initializing assignment to let variable needs a write barrier.
2529 DCHECK(!var->IsLookupSlot()); 2529 DCHECK(!var->IsLookupSlot());
2530 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2530 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2531 Label assign; 2531 Label assign;
2532 MemOperand location = VarOperand(var, r1); 2532 MemOperand location = VarOperand(var, r1);
2533 __ ldr(r3, location); 2533 __ ldr(r3, location);
2534 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); 2534 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex);
2535 __ b(ne, &assign); 2535 __ b(ne, &assign);
2536 __ mov(r3, Operand(var->name())); 2536 __ mov(r3, Operand(var->name()));
2537 __ push(r3); 2537 __ push(r3);
2538 __ CallRuntime(Runtime::kThrowReferenceError, 1); 2538 __ CallRuntime(Runtime::kThrowReferenceError);
2539 // Perform the assignment. 2539 // Perform the assignment.
2540 __ bind(&assign); 2540 __ bind(&assign);
2541 EmitStoreToStackLocalOrContextSlot(var, location); 2541 EmitStoreToStackLocalOrContextSlot(var, location);
2542 2542
2543 } else if (var->mode() == CONST && op != Token::INIT) { 2543 } else if (var->mode() == CONST && op != Token::INIT) {
2544 // Assignment to const variable needs a write barrier. 2544 // Assignment to const variable needs a write barrier.
2545 DCHECK(!var->IsLookupSlot()); 2545 DCHECK(!var->IsLookupSlot());
2546 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2546 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2547 Label const_error; 2547 Label const_error;
2548 MemOperand location = VarOperand(var, r1); 2548 MemOperand location = VarOperand(var, r1);
2549 __ ldr(r3, location); 2549 __ ldr(r3, location);
2550 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); 2550 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex);
2551 __ b(ne, &const_error); 2551 __ b(ne, &const_error);
2552 __ mov(r3, Operand(var->name())); 2552 __ mov(r3, Operand(var->name()));
2553 __ push(r3); 2553 __ push(r3);
2554 __ CallRuntime(Runtime::kThrowReferenceError, 1); 2554 __ CallRuntime(Runtime::kThrowReferenceError);
2555 __ bind(&const_error); 2555 __ bind(&const_error);
2556 __ CallRuntime(Runtime::kThrowConstAssignError, 0); 2556 __ CallRuntime(Runtime::kThrowConstAssignError);
2557 2557
2558 } else if (var->is_this() && var->mode() == CONST && op == Token::INIT) { 2558 } else if (var->is_this() && var->mode() == CONST && op == Token::INIT) {
2559 // Initializing assignment to const {this} needs a write barrier. 2559 // Initializing assignment to const {this} needs a write barrier.
2560 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2560 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2561 Label uninitialized_this; 2561 Label uninitialized_this;
2562 MemOperand location = VarOperand(var, r1); 2562 MemOperand location = VarOperand(var, r1);
2563 __ ldr(r3, location); 2563 __ ldr(r3, location);
2564 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); 2564 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex);
2565 __ b(eq, &uninitialized_this); 2565 __ b(eq, &uninitialized_this);
2566 __ mov(r0, Operand(var->name())); 2566 __ mov(r0, Operand(var->name()));
2567 __ Push(r0); 2567 __ Push(r0);
2568 __ CallRuntime(Runtime::kThrowReferenceError, 1); 2568 __ CallRuntime(Runtime::kThrowReferenceError);
2569 __ bind(&uninitialized_this); 2569 __ bind(&uninitialized_this);
2570 EmitStoreToStackLocalOrContextSlot(var, location); 2570 EmitStoreToStackLocalOrContextSlot(var, location);
2571 2571
2572 } else if (!var->is_const_mode() || 2572 } else if (!var->is_const_mode() ||
2573 (var->mode() == CONST && op == Token::INIT)) { 2573 (var->mode() == CONST && op == Token::INIT)) {
2574 if (var->IsLookupSlot()) { 2574 if (var->IsLookupSlot()) {
2575 // Assignment to var. 2575 // Assignment to var.
2576 __ push(r0); // Value. 2576 __ push(r0); // Value.
2577 __ mov(r1, Operand(var->name())); 2577 __ mov(r1, Operand(var->name()));
2578 __ mov(r0, Operand(Smi::FromInt(language_mode()))); 2578 __ mov(r0, Operand(Smi::FromInt(language_mode())));
2579 __ Push(cp, r1, r0); // Context, name, language mode. 2579 __ Push(cp, r1, r0); // Context, name, language mode.
2580 __ CallRuntime(Runtime::kStoreLookupSlot, 4); 2580 __ CallRuntime(Runtime::kStoreLookupSlot);
2581 } else { 2581 } else {
2582 // Assignment to var or initializing assignment to let/const in harmony 2582 // Assignment to var or initializing assignment to let/const in harmony
2583 // mode. 2583 // mode.
2584 DCHECK((var->IsStackAllocated() || var->IsContextSlot())); 2584 DCHECK((var->IsStackAllocated() || var->IsContextSlot()));
2585 MemOperand location = VarOperand(var, r1); 2585 MemOperand location = VarOperand(var, r1);
2586 if (generate_debug_code_ && var->mode() == LET && op == Token::INIT) { 2586 if (generate_debug_code_ && var->mode() == LET && op == Token::INIT) {
2587 // Check for an uninitialized let binding. 2587 // Check for an uninitialized let binding.
2588 __ ldr(r2, location); 2588 __ ldr(r2, location);
2589 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); 2589 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex);
2590 __ Check(eq, kLetBindingReInitialization); 2590 __ Check(eq, kLetBindingReInitialization);
2591 } 2591 }
2592 EmitStoreToStackLocalOrContextSlot(var, location); 2592 EmitStoreToStackLocalOrContextSlot(var, location);
2593 } 2593 }
2594 2594
2595 } else if (var->mode() == CONST_LEGACY && op == Token::INIT) { 2595 } else if (var->mode() == CONST_LEGACY && op == Token::INIT) {
2596 // Const initializers need a write barrier. 2596 // Const initializers need a write barrier.
2597 DCHECK(!var->IsParameter()); // No const parameters. 2597 DCHECK(!var->IsParameter()); // No const parameters.
2598 if (var->IsLookupSlot()) { 2598 if (var->IsLookupSlot()) {
2599 __ push(r0); 2599 __ push(r0);
2600 __ mov(r0, Operand(var->name())); 2600 __ mov(r0, Operand(var->name()));
2601 __ Push(cp, r0); // Context and name. 2601 __ Push(cp, r0); // Context and name.
2602 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); 2602 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot);
2603 } else { 2603 } else {
2604 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2604 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2605 Label skip; 2605 Label skip;
2606 MemOperand location = VarOperand(var, r1); 2606 MemOperand location = VarOperand(var, r1);
2607 __ ldr(r2, location); 2607 __ ldr(r2, location);
2608 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); 2608 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex);
2609 __ b(ne, &skip); 2609 __ b(ne, &skip);
2610 EmitStoreToStackLocalOrContextSlot(var, location); 2610 EmitStoreToStackLocalOrContextSlot(var, location);
2611 __ bind(&skip); 2611 __ bind(&skip);
2612 } 2612 }
2613 2613
2614 } else { 2614 } else {
2615 DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT); 2615 DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT);
2616 if (is_strict(language_mode())) { 2616 if (is_strict(language_mode())) {
2617 __ CallRuntime(Runtime::kThrowConstAssignError, 0); 2617 __ CallRuntime(Runtime::kThrowConstAssignError);
2618 } 2618 }
2619 // Silently ignore store in sloppy mode. 2619 // Silently ignore store in sloppy mode.
2620 } 2620 }
2621 } 2621 }
2622 2622
2623 2623
2624 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2624 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2625 // Assignment to a property, using a named store IC. 2625 // Assignment to a property, using a named store IC.
2626 Property* prop = expr->target()->AsProperty(); 2626 Property* prop = expr->target()->AsProperty();
2627 DCHECK(prop != NULL); 2627 DCHECK(prop != NULL);
(...skipping 14 matching lines...) Expand all
2642 // Assignment to named property of super. 2642 // Assignment to named property of super.
2643 // r0 : value 2643 // r0 : value
2644 // stack : receiver ('this'), home_object 2644 // stack : receiver ('this'), home_object
2645 DCHECK(prop != NULL); 2645 DCHECK(prop != NULL);
2646 Literal* key = prop->key()->AsLiteral(); 2646 Literal* key = prop->key()->AsLiteral();
2647 DCHECK(key != NULL); 2647 DCHECK(key != NULL);
2648 2648
2649 __ Push(key->value()); 2649 __ Push(key->value());
2650 __ Push(r0); 2650 __ Push(r0);
2651 __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict 2651 __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict
2652 : Runtime::kStoreToSuper_Sloppy), 2652 : Runtime::kStoreToSuper_Sloppy));
2653 4);
2654 } 2653 }
2655 2654
2656 2655
2657 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { 2656 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
2658 // Assignment to named property of super. 2657 // Assignment to named property of super.
2659 // r0 : value 2658 // r0 : value
2660 // stack : receiver ('this'), home_object, key 2659 // stack : receiver ('this'), home_object, key
2661 DCHECK(prop != NULL); 2660 DCHECK(prop != NULL);
2662 2661
2663 __ Push(r0); 2662 __ Push(r0);
2664 __ CallRuntime( 2663 __ CallRuntime((is_strict(language_mode())
2665 (is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict 2664 ? Runtime::kStoreKeyedToSuper_Strict
2666 : Runtime::kStoreKeyedToSuper_Sloppy), 2665 : Runtime::kStoreKeyedToSuper_Sloppy));
2667 4);
2668 } 2666 }
2669 2667
2670 2668
2671 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2669 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2672 // Assignment to a property, using a keyed store IC. 2670 // Assignment to a property, using a keyed store IC.
2673 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); 2671 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister());
2674 DCHECK(StoreDescriptor::ValueRegister().is(r0)); 2672 DCHECK(StoreDescriptor::ValueRegister().is(r0));
2675 2673
2676 Handle<Code> ic = 2674 Handle<Code> ic =
2677 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2675 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
2785 __ Push(key->value()); 2783 __ Push(key->value());
2786 __ Push(Smi::FromInt(language_mode())); 2784 __ Push(Smi::FromInt(language_mode()));
2787 2785
2788 // Stack here: 2786 // Stack here:
2789 // - home_object 2787 // - home_object
2790 // - this (receiver) 2788 // - this (receiver)
2791 // - this (receiver) <-- LoadFromSuper will pop here and below. 2789 // - this (receiver) <-- LoadFromSuper will pop here and below.
2792 // - home_object 2790 // - home_object
2793 // - key 2791 // - key
2794 // - language_mode 2792 // - language_mode
2795 __ CallRuntime(Runtime::kLoadFromSuper, 4); 2793 __ CallRuntime(Runtime::kLoadFromSuper);
2796 2794
2797 // Replace home_object with target function. 2795 // Replace home_object with target function.
2798 __ str(r0, MemOperand(sp, kPointerSize)); 2796 __ str(r0, MemOperand(sp, kPointerSize));
2799 2797
2800 // Stack here: 2798 // Stack here:
2801 // - target function 2799 // - target function
2802 // - this (receiver) 2800 // - this (receiver)
2803 EmitCall(expr); 2801 EmitCall(expr);
2804 } 2802 }
2805 2803
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2847 VisitForStackValue(prop->key()); 2845 VisitForStackValue(prop->key());
2848 __ Push(Smi::FromInt(language_mode())); 2846 __ Push(Smi::FromInt(language_mode()));
2849 2847
2850 // Stack here: 2848 // Stack here:
2851 // - home_object 2849 // - home_object
2852 // - this (receiver) 2850 // - this (receiver)
2853 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. 2851 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
2854 // - home_object 2852 // - home_object
2855 // - key 2853 // - key
2856 // - language_mode 2854 // - language_mode
2857 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4); 2855 __ CallRuntime(Runtime::kLoadKeyedFromSuper);
2858 2856
2859 // Replace home_object with target function. 2857 // Replace home_object with target function.
2860 __ str(r0, MemOperand(sp, kPointerSize)); 2858 __ str(r0, MemOperand(sp, kPointerSize));
2861 2859
2862 // Stack here: 2860 // Stack here:
2863 // - target function 2861 // - target function
2864 // - this (receiver) 2862 // - this (receiver)
2865 EmitCall(expr); 2863 EmitCall(expr);
2866 } 2864 }
2867 2865
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2902 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 2900 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
2903 2901
2904 // r2: language mode. 2902 // r2: language mode.
2905 __ mov(r2, Operand(Smi::FromInt(language_mode()))); 2903 __ mov(r2, Operand(Smi::FromInt(language_mode())));
2906 2904
2907 // r1: the start position of the scope the calls resides in. 2905 // r1: the start position of the scope the calls resides in.
2908 __ mov(r1, Operand(Smi::FromInt(scope()->start_position()))); 2906 __ mov(r1, Operand(Smi::FromInt(scope()->start_position())));
2909 2907
2910 // Do the runtime call. 2908 // Do the runtime call.
2911 __ Push(r4, r3, r2, r1); 2909 __ Push(r4, r3, r2, r1);
2912 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); 2910 __ CallRuntime(Runtime::kResolvePossiblyDirectEval);
2913 } 2911 }
2914 2912
2915 2913
2916 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. 2914 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls.
2917 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { 2915 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
2918 VariableProxy* callee = expr->expression()->AsVariableProxy(); 2916 VariableProxy* callee = expr->expression()->AsVariableProxy();
2919 if (callee->var()->IsLookupSlot()) { 2917 if (callee->var()->IsLookupSlot()) {
2920 Label slow, done; 2918 Label slow, done;
2921 SetExpressionPosition(callee); 2919 SetExpressionPosition(callee);
2922 // Generate code for loading from variables potentially shadowed 2920 // Generate code for loading from variables potentially shadowed
2923 // by eval-introduced variables. 2921 // by eval-introduced variables.
2924 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); 2922 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2925 2923
2926 __ bind(&slow); 2924 __ bind(&slow);
2927 // Call the runtime to find the function to call (returned in r0) 2925 // Call the runtime to find the function to call (returned in r0)
2928 // and the object holding it (returned in edx). 2926 // and the object holding it (returned in edx).
2929 DCHECK(!context_register().is(r2)); 2927 DCHECK(!context_register().is(r2));
2930 __ mov(r2, Operand(callee->name())); 2928 __ mov(r2, Operand(callee->name()));
2931 __ Push(context_register(), r2); 2929 __ Push(context_register(), r2);
2932 __ CallRuntime(Runtime::kLoadLookupSlot, 2); 2930 __ CallRuntime(Runtime::kLoadLookupSlot);
2933 __ Push(r0, r1); // Function, receiver. 2931 __ Push(r0, r1); // Function, receiver.
2934 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); 2932 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
2935 2933
2936 // If fast case code has been generated, emit code to push the 2934 // If fast case code has been generated, emit code to push the
2937 // function and receiver and have the slow path jump around this 2935 // function and receiver and have the slow path jump around this
2938 // code. 2936 // code.
2939 if (done.is_linked()) { 2937 if (done.is_linked()) {
2940 Label call; 2938 Label call;
2941 __ b(&call); 2939 __ b(&call);
2942 __ bind(&done); 2940 __ bind(&done);
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after
3565 ZoneList<Expression*>* args = expr->arguments(); 3563 ZoneList<Expression*>* args = expr->arguments();
3566 DCHECK_EQ(1, args->length()); 3564 DCHECK_EQ(1, args->length());
3567 3565
3568 // Load the argument into r0 and convert it. 3566 // Load the argument into r0 and convert it.
3569 VisitForAccumulatorValue(args->at(0)); 3567 VisitForAccumulatorValue(args->at(0));
3570 3568
3571 // Convert the object to an integer. 3569 // Convert the object to an integer.
3572 Label done_convert; 3570 Label done_convert;
3573 __ JumpIfSmi(r0, &done_convert); 3571 __ JumpIfSmi(r0, &done_convert);
3574 __ Push(r0); 3572 __ Push(r0);
3575 __ CallRuntime(Runtime::kToInteger, 1); 3573 __ CallRuntime(Runtime::kToInteger);
3576 __ bind(&done_convert); 3574 __ bind(&done_convert);
3577 context()->Plug(r0); 3575 context()->Plug(r0);
3578 } 3576 }
3579 3577
3580 3578
3581 void FullCodeGenerator::EmitToName(CallRuntime* expr) { 3579 void FullCodeGenerator::EmitToName(CallRuntime* expr) {
3582 ZoneList<Expression*>* args = expr->arguments(); 3580 ZoneList<Expression*>* args = expr->arguments();
3583 DCHECK_EQ(1, args->length()); 3581 DCHECK_EQ(1, args->length());
3584 3582
3585 // Load the argument into r0 and convert it. 3583 // Load the argument into r0 and convert it.
3586 VisitForAccumulatorValue(args->at(0)); 3584 VisitForAccumulatorValue(args->at(0));
3587 3585
3588 Label convert, done_convert; 3586 Label convert, done_convert;
3589 __ JumpIfSmi(r0, &convert); 3587 __ JumpIfSmi(r0, &convert);
3590 STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE); 3588 STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE);
3591 __ CompareObjectType(r0, r1, r1, LAST_NAME_TYPE); 3589 __ CompareObjectType(r0, r1, r1, LAST_NAME_TYPE);
3592 __ b(ls, &done_convert); 3590 __ b(ls, &done_convert);
3593 __ bind(&convert); 3591 __ bind(&convert);
3594 __ Push(r0); 3592 __ Push(r0);
3595 __ CallRuntime(Runtime::kToName, 1); 3593 __ CallRuntime(Runtime::kToName);
3596 __ bind(&done_convert); 3594 __ bind(&done_convert);
3597 context()->Plug(r0); 3595 context()->Plug(r0);
3598 } 3596 }
3599 3597
3600 3598
3601 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { 3599 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) {
3602 ZoneList<Expression*>* args = expr->arguments(); 3600 ZoneList<Expression*>* args = expr->arguments();
3603 DCHECK(args->length() == 1); 3601 DCHECK(args->length() == 1);
3604 VisitForAccumulatorValue(args->at(0)); 3602 VisitForAccumulatorValue(args->at(0));
3605 3603
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
4037 __ LoadRoot(r4, Heap::kEmptyFixedArrayRootIndex); 4035 __ LoadRoot(r4, Heap::kEmptyFixedArrayRootIndex);
4038 __ str(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); 4036 __ str(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
4039 __ str(r4, FieldMemOperand(r0, JSObject::kPropertiesOffset)); 4037 __ str(r4, FieldMemOperand(r0, JSObject::kPropertiesOffset));
4040 __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset)); 4038 __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset));
4041 __ str(r2, FieldMemOperand(r0, JSIteratorResult::kValueOffset)); 4039 __ str(r2, FieldMemOperand(r0, JSIteratorResult::kValueOffset));
4042 __ str(r3, FieldMemOperand(r0, JSIteratorResult::kDoneOffset)); 4040 __ str(r3, FieldMemOperand(r0, JSIteratorResult::kDoneOffset));
4043 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); 4041 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize);
4044 __ b(&done); 4042 __ b(&done);
4045 4043
4046 __ bind(&runtime); 4044 __ bind(&runtime);
4047 __ CallRuntime(Runtime::kCreateIterResultObject, 2); 4045 __ CallRuntime(Runtime::kCreateIterResultObject);
4048 4046
4049 __ bind(&done); 4047 __ bind(&done);
4050 context()->Plug(r0); 4048 context()->Plug(r0);
4051 } 4049 }
4052 4050
4053 4051
4054 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { 4052 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
4055 // Push undefined as the receiver. 4053 // Push undefined as the receiver.
4056 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); 4054 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
4057 __ push(r0); 4055 __ push(r0);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
4130 case Token::DELETE: { 4128 case Token::DELETE: {
4131 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 4129 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
4132 Property* property = expr->expression()->AsProperty(); 4130 Property* property = expr->expression()->AsProperty();
4133 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 4131 VariableProxy* proxy = expr->expression()->AsVariableProxy();
4134 4132
4135 if (property != NULL) { 4133 if (property != NULL) {
4136 VisitForStackValue(property->obj()); 4134 VisitForStackValue(property->obj());
4137 VisitForStackValue(property->key()); 4135 VisitForStackValue(property->key());
4138 __ CallRuntime(is_strict(language_mode()) 4136 __ CallRuntime(is_strict(language_mode())
4139 ? Runtime::kDeleteProperty_Strict 4137 ? Runtime::kDeleteProperty_Strict
4140 : Runtime::kDeleteProperty_Sloppy, 4138 : Runtime::kDeleteProperty_Sloppy);
4141 2);
4142 context()->Plug(r0); 4139 context()->Plug(r0);
4143 } else if (proxy != NULL) { 4140 } else if (proxy != NULL) {
4144 Variable* var = proxy->var(); 4141 Variable* var = proxy->var();
4145 // Delete of an unqualified identifier is disallowed in strict mode but 4142 // Delete of an unqualified identifier is disallowed in strict mode but
4146 // "delete this" is allowed. 4143 // "delete this" is allowed.
4147 bool is_this = var->HasThisName(isolate()); 4144 bool is_this = var->HasThisName(isolate());
4148 DCHECK(is_sloppy(language_mode()) || is_this); 4145 DCHECK(is_sloppy(language_mode()) || is_this);
4149 if (var->IsUnallocatedOrGlobalSlot()) { 4146 if (var->IsUnallocatedOrGlobalSlot()) {
4150 __ LoadGlobalObject(r2); 4147 __ LoadGlobalObject(r2);
4151 __ mov(r1, Operand(var->name())); 4148 __ mov(r1, Operand(var->name()));
4152 __ Push(r2, r1); 4149 __ Push(r2, r1);
4153 __ CallRuntime(Runtime::kDeleteProperty_Sloppy, 2); 4150 __ CallRuntime(Runtime::kDeleteProperty_Sloppy);
4154 context()->Plug(r0); 4151 context()->Plug(r0);
4155 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 4152 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
4156 // Result of deleting non-global, non-dynamic variables is false. 4153 // Result of deleting non-global, non-dynamic variables is false.
4157 // The subexpression does not have side effects. 4154 // The subexpression does not have side effects.
4158 context()->Plug(is_this); 4155 context()->Plug(is_this);
4159 } else { 4156 } else {
4160 // Non-global variable. Call the runtime to try to delete from the 4157 // Non-global variable. Call the runtime to try to delete from the
4161 // context where the variable was introduced. 4158 // context where the variable was introduced.
4162 DCHECK(!context_register().is(r2)); 4159 DCHECK(!context_register().is(r2));
4163 __ mov(r2, Operand(var->name())); 4160 __ mov(r2, Operand(var->name()));
4164 __ Push(context_register(), r2); 4161 __ Push(context_register(), r2);
4165 __ CallRuntime(Runtime::kDeleteLookupSlot, 2); 4162 __ CallRuntime(Runtime::kDeleteLookupSlot);
4166 context()->Plug(r0); 4163 context()->Plug(r0);
4167 } 4164 }
4168 } else { 4165 } else {
4169 // Result of deleting non-property, non-variable reference is true. 4166 // Result of deleting non-property, non-variable reference is true.
4170 // The subexpression may have side effects. 4167 // The subexpression may have side effects.
4171 VisitForEffect(expr->expression()); 4168 VisitForEffect(expr->expression());
4172 context()->Plug(true); 4169 context()->Plug(true);
4173 } 4170 }
4174 break; 4171 break;
4175 } 4172 }
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
4586 Label* if_false = NULL; 4583 Label* if_false = NULL;
4587 Label* fall_through = NULL; 4584 Label* fall_through = NULL;
4588 context()->PrepareTest(&materialize_true, &materialize_false, 4585 context()->PrepareTest(&materialize_true, &materialize_false,
4589 &if_true, &if_false, &fall_through); 4586 &if_true, &if_false, &fall_through);
4590 4587
4591 Token::Value op = expr->op(); 4588 Token::Value op = expr->op();
4592 VisitForStackValue(expr->left()); 4589 VisitForStackValue(expr->left());
4593 switch (op) { 4590 switch (op) {
4594 case Token::IN: 4591 case Token::IN:
4595 VisitForStackValue(expr->right()); 4592 VisitForStackValue(expr->right());
4596 __ CallRuntime(Runtime::kHasProperty, 2); 4593 __ CallRuntime(Runtime::kHasProperty);
4597 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 4594 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
4598 __ CompareRoot(r0, Heap::kTrueValueRootIndex); 4595 __ CompareRoot(r0, Heap::kTrueValueRootIndex);
4599 Split(eq, if_true, if_false, fall_through); 4596 Split(eq, if_true, if_false, fall_through);
4600 break; 4597 break;
4601 4598
4602 case Token::INSTANCEOF: { 4599 case Token::INSTANCEOF: {
4603 VisitForAccumulatorValue(expr->right()); 4600 VisitForAccumulatorValue(expr->right());
4604 __ pop(r1); 4601 __ pop(r1);
4605 InstanceOfStub stub(isolate()); 4602 InstanceOfStub stub(isolate());
4606 __ CallStub(&stub); 4603 __ CallStub(&stub);
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
4920 DCHECK(interrupt_address == 4917 DCHECK(interrupt_address ==
4921 isolate->builtins()->OsrAfterStackCheck()->entry()); 4918 isolate->builtins()->OsrAfterStackCheck()->entry());
4922 return OSR_AFTER_STACK_CHECK; 4919 return OSR_AFTER_STACK_CHECK;
4923 } 4920 }
4924 4921
4925 4922
4926 } // namespace internal 4923 } // namespace internal
4927 } // namespace v8 4924 } // namespace v8
4928 4925
4929 #endif // V8_TARGET_ARCH_ARM 4926 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698