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

Side by Side Diff: src/full-codegen/arm64/full-codegen-arm64.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_ARM64 5 #if V8_TARGET_ARCH_ARM64
6 6
7 #include "src/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 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 // Generators allocate locals, if any, in context slots. 142 // Generators allocate locals, if any, in context slots.
143 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0); 143 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0);
144 144
145 if (locals_count > 0) { 145 if (locals_count > 0) {
146 if (locals_count >= 128) { 146 if (locals_count >= 128) {
147 Label ok; 147 Label ok;
148 DCHECK(jssp.Is(__ StackPointer())); 148 DCHECK(jssp.Is(__ StackPointer()));
149 __ Sub(x10, jssp, locals_count * kPointerSize); 149 __ Sub(x10, jssp, locals_count * kPointerSize);
150 __ CompareRoot(x10, Heap::kRealStackLimitRootIndex); 150 __ CompareRoot(x10, Heap::kRealStackLimitRootIndex);
151 __ B(hs, &ok); 151 __ B(hs, &ok);
152 __ CallRuntime(Runtime::kThrowStackOverflow, 0); 152 __ CallRuntime(Runtime::kThrowStackOverflow);
153 __ Bind(&ok); 153 __ Bind(&ok);
154 } 154 }
155 __ LoadRoot(x10, Heap::kUndefinedValueRootIndex); 155 __ LoadRoot(x10, Heap::kUndefinedValueRootIndex);
156 if (FLAG_optimize_for_size) { 156 if (FLAG_optimize_for_size) {
157 __ PushMultipleTimes(x10 , locals_count); 157 __ PushMultipleTimes(x10 , locals_count);
158 } else { 158 } else {
159 const int kMaxPushes = 32; 159 const int kMaxPushes = 32;
160 if (locals_count >= kMaxPushes) { 160 if (locals_count >= kMaxPushes) {
161 int loop_iterations = locals_count / kMaxPushes; 161 int loop_iterations = locals_count / kMaxPushes;
162 __ Mov(x2, loop_iterations); 162 __ Mov(x2, loop_iterations);
(...skipping 14 matching lines...) Expand all
177 bool function_in_register_x1 = true; 177 bool function_in_register_x1 = true;
178 178
179 if (info->scope()->num_heap_slots() > 0) { 179 if (info->scope()->num_heap_slots() > 0) {
180 // Argument to NewContext is the function, which is still in x1. 180 // Argument to NewContext is the function, which is still in x1.
181 Comment cmnt(masm_, "[ Allocate context"); 181 Comment cmnt(masm_, "[ Allocate context");
182 bool need_write_barrier = true; 182 bool need_write_barrier = true;
183 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 183 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
184 if (info->scope()->is_script_scope()) { 184 if (info->scope()->is_script_scope()) {
185 __ Mov(x10, Operand(info->scope()->GetScopeInfo(info->isolate()))); 185 __ Mov(x10, Operand(info->scope()->GetScopeInfo(info->isolate())));
186 __ Push(x1, x10); 186 __ Push(x1, x10);
187 __ CallRuntime(Runtime::kNewScriptContext, 2); 187 __ CallRuntime(Runtime::kNewScriptContext);
188 PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG); 188 PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG);
189 // The new target value is not used, clobbering is safe. 189 // The new target value is not used, clobbering is safe.
190 DCHECK_NULL(info->scope()->new_target_var()); 190 DCHECK_NULL(info->scope()->new_target_var());
191 } else { 191 } else {
192 if (info->scope()->new_target_var() != nullptr) { 192 if (info->scope()->new_target_var() != nullptr) {
193 __ Push(x3); // Preserve new target. 193 __ Push(x3); // Preserve new target.
194 } 194 }
195 if (slots <= FastNewContextStub::kMaximumSlots) { 195 if (slots <= FastNewContextStub::kMaximumSlots) {
196 FastNewContextStub stub(isolate(), slots); 196 FastNewContextStub stub(isolate(), slots);
197 __ CallStub(&stub); 197 __ CallStub(&stub);
198 // Result of FastNewContextStub is always in new space. 198 // Result of FastNewContextStub is always in new space.
199 need_write_barrier = false; 199 need_write_barrier = false;
200 } else { 200 } else {
201 __ Push(x1); 201 __ Push(x1);
202 __ CallRuntime(Runtime::kNewFunctionContext, 1); 202 __ CallRuntime(Runtime::kNewFunctionContext);
203 } 203 }
204 if (info->scope()->new_target_var() != nullptr) { 204 if (info->scope()->new_target_var() != nullptr) {
205 __ Pop(x3); // Restore new target. 205 __ Pop(x3); // Restore new target.
206 } 206 }
207 } 207 }
208 function_in_register_x1 = false; 208 function_in_register_x1 = false;
209 // Context is returned in x0. It replaces the context passed to us. 209 // Context is returned in x0. It replaces the context passed to us.
210 // It's saved in the stack and kept live in cp. 210 // It's saved in the stack and kept live in cp.
211 __ Mov(cp, x0); 211 __ Mov(cp, x0);
212 __ Str(x0, MemOperand(fp, StandardFrameConstants::kContextOffset)); 212 __ Str(x0, MemOperand(fp, StandardFrameConstants::kContextOffset));
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 bool is_unmapped = is_strict(language_mode()) || !has_simple_parameters(); 308 bool is_unmapped = is_strict(language_mode()) || !has_simple_parameters();
309 ArgumentsAccessStub::Type type = ArgumentsAccessStub::ComputeType( 309 ArgumentsAccessStub::Type type = ArgumentsAccessStub::ComputeType(
310 is_unmapped, literal()->has_duplicate_parameters()); 310 is_unmapped, literal()->has_duplicate_parameters());
311 ArgumentsAccessStub stub(isolate(), type); 311 ArgumentsAccessStub stub(isolate(), type);
312 __ CallStub(&stub); 312 __ CallStub(&stub);
313 313
314 SetVar(arguments, x0, x1, x2); 314 SetVar(arguments, x0, x1, x2);
315 } 315 }
316 316
317 if (FLAG_trace) { 317 if (FLAG_trace) {
318 __ CallRuntime(Runtime::kTraceEnter, 0); 318 __ CallRuntime(Runtime::kTraceEnter);
319 } 319 }
320 320
321 // Visit the declarations and body unless there is an illegal 321 // Visit the declarations and body unless there is an illegal
322 // redeclaration. 322 // redeclaration.
323 if (scope()->HasIllegalRedeclaration()) { 323 if (scope()->HasIllegalRedeclaration()) {
324 Comment cmnt(masm_, "[ Declarations"); 324 Comment cmnt(masm_, "[ Declarations");
325 VisitForEffect(scope()->GetIllegalRedeclaration()); 325 VisitForEffect(scope()->GetIllegalRedeclaration());
326 326
327 } else { 327 } else {
328 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); 328 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS);
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 434
435 if (return_label_.is_bound()) { 435 if (return_label_.is_bound()) {
436 __ B(&return_label_); 436 __ B(&return_label_);
437 437
438 } else { 438 } else {
439 __ Bind(&return_label_); 439 __ Bind(&return_label_);
440 if (FLAG_trace) { 440 if (FLAG_trace) {
441 // Push the return value on the stack as the parameter. 441 // Push the return value on the stack as the parameter.
442 // Runtime::TraceExit returns its parameter in x0. 442 // Runtime::TraceExit returns its parameter in x0.
443 __ Push(result_register()); 443 __ Push(result_register());
444 __ CallRuntime(Runtime::kTraceExit, 1); 444 __ CallRuntime(Runtime::kTraceExit);
445 DCHECK(x0.Is(result_register())); 445 DCHECK(x0.Is(result_register()));
446 } 446 }
447 // Pretend that the exit is a backwards jump to the entry. 447 // Pretend that the exit is a backwards jump to the entry.
448 int weight = 1; 448 int weight = 1;
449 if (info_->ShouldSelfOptimize()) { 449 if (info_->ShouldSelfOptimize()) {
450 weight = FLAG_interrupt_budget / FLAG_self_opt_count; 450 weight = FLAG_interrupt_budget / FLAG_self_opt_count;
451 } else { 451 } else {
452 int distance = masm_->pc_offset() + kCodeSizeMultiplier / 2; 452 int distance = masm_->pc_offset() + kCodeSizeMultiplier / 2;
453 weight = Min(kMaxBackEdgeWeight, 453 weight = Min(kMaxBackEdgeWeight,
454 Max(1, distance / kCodeSizeMultiplier)); 454 Max(1, distance / kCodeSizeMultiplier));
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
847 // 'undefined') because we may have a (legal) redeclaration and we 847 // 'undefined') because we may have a (legal) redeclaration and we
848 // must not destroy the current value. 848 // must not destroy the current value.
849 if (hole_init) { 849 if (hole_init) {
850 __ LoadRoot(x0, Heap::kTheHoleValueRootIndex); 850 __ LoadRoot(x0, Heap::kTheHoleValueRootIndex);
851 __ Push(x2, x0); 851 __ Push(x2, x0);
852 } else { 852 } else {
853 // Pushing 0 (xzr) indicates no initial value. 853 // Pushing 0 (xzr) indicates no initial value.
854 __ Push(x2, xzr); 854 __ Push(x2, xzr);
855 } 855 }
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_, "[ Function Declaration"); 908 Comment cmnt(masm_, "[ Function Declaration");
909 __ Mov(x2, Operand(variable->name())); 909 __ Mov(x2, Operand(variable->name()));
910 __ Push(x2); 910 __ Push(x2);
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(x11, Operand(pairs)); 923 __ Mov(x11, Operand(pairs));
924 Register flags = xzr; 924 Register flags = xzr;
925 if (Smi::FromInt(DeclareGlobalsFlags())) { 925 if (Smi::FromInt(DeclareGlobalsFlags())) {
926 flags = x10; 926 flags = x10;
927 __ Mov(flags, Smi::FromInt(DeclareGlobalsFlags())); 927 __ Mov(flags, Smi::FromInt(DeclareGlobalsFlags()));
928 } 928 }
929 __ Push(x11, flags); 929 __ Push(x11, flags);
930 __ CallRuntime(Runtime::kDeclareGlobals, 2); 930 __ CallRuntime(Runtime::kDeclareGlobals);
931 // Return value is ignored. 931 // Return value is ignored.
932 } 932 }
933 933
934 934
935 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) { 935 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) {
936 // Call the runtime to declare the modules. 936 // Call the runtime to declare the modules.
937 __ Push(descriptions); 937 __ Push(descriptions);
938 __ CallRuntime(Runtime::kDeclareModules, 1); 938 __ CallRuntime(Runtime::kDeclareModules);
939 // Return value is ignored. 939 // Return value is ignored.
940 } 940 }
941 941
942 942
943 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 943 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
944 ASM_LOCATION("FullCodeGenerator::VisitSwitchStatement"); 944 ASM_LOCATION("FullCodeGenerator::VisitSwitchStatement");
945 Comment cmnt(masm_, "[ SwitchStatement"); 945 Comment cmnt(masm_, "[ SwitchStatement");
946 Breakable nested_statement(this, stmt); 946 Breakable nested_statement(this, stmt);
947 SetStatementPosition(stmt); 947 SetStatementPosition(stmt);
948 948
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1078 1078
1079 // The enum cache is valid. Load the map of the object being 1079 // The enum cache is valid. Load the map of the object being
1080 // iterated over and use the cache for the iteration. 1080 // iterated over and use the cache for the iteration.
1081 Label use_cache; 1081 Label use_cache;
1082 __ Ldr(x0, FieldMemOperand(x0, HeapObject::kMapOffset)); 1082 __ Ldr(x0, FieldMemOperand(x0, HeapObject::kMapOffset));
1083 __ B(&use_cache); 1083 __ B(&use_cache);
1084 1084
1085 // Get the set of properties to enumerate. 1085 // Get the set of properties to enumerate.
1086 __ Bind(&call_runtime); 1086 __ Bind(&call_runtime);
1087 __ Push(x0); // Duplicate the enumerable object on the stack. 1087 __ Push(x0); // Duplicate the enumerable object on the stack.
1088 __ CallRuntime(Runtime::kGetPropertyNamesFast, 1); 1088 __ CallRuntime(Runtime::kGetPropertyNamesFast);
1089 PrepareForBailoutForId(stmt->EnumId(), TOS_REG); 1089 PrepareForBailoutForId(stmt->EnumId(), TOS_REG);
1090 1090
1091 // If we got a map from the runtime call, we can do a fast 1091 // If we got a map from the runtime call, we can do a fast
1092 // modification check. Otherwise, we got a fixed array, and we have 1092 // modification check. Otherwise, we got a fixed array, and we have
1093 // to do a slow check. 1093 // to do a slow check.
1094 Label fixed_array, no_descriptors; 1094 Label fixed_array, no_descriptors;
1095 __ Ldr(x2, FieldMemOperand(x0, HeapObject::kMapOffset)); 1095 __ Ldr(x2, FieldMemOperand(x0, HeapObject::kMapOffset));
1096 __ JumpIfNotRoot(x2, Heap::kMetaMapRootIndex, &fixed_array); 1096 __ JumpIfNotRoot(x2, Heap::kMetaMapRootIndex, &fixed_array);
1097 1097
1098 // We got a map in register x0. Get the enumeration cache from it. 1098 // We got a map in register x0. Get the enumeration cache from it.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1151 Label update_each; 1151 Label update_each;
1152 __ Peek(x1, 4 * kXRegSize); 1152 __ Peek(x1, 4 * kXRegSize);
1153 __ Ldr(x11, FieldMemOperand(x1, HeapObject::kMapOffset)); 1153 __ Ldr(x11, FieldMemOperand(x1, HeapObject::kMapOffset));
1154 __ Cmp(x11, x2); 1154 __ Cmp(x11, x2);
1155 __ B(eq, &update_each); 1155 __ B(eq, &update_each);
1156 1156
1157 // Convert the entry to a string or (smi) 0 if it isn't a property 1157 // Convert the entry to a string or (smi) 0 if it isn't a property
1158 // any more. If the property has been removed while iterating, we 1158 // any more. If the property has been removed while iterating, we
1159 // just skip it. 1159 // just skip it.
1160 __ Push(x1, x3); 1160 __ Push(x1, x3);
1161 __ CallRuntime(Runtime::kForInFilter, 2); 1161 __ CallRuntime(Runtime::kForInFilter);
1162 PrepareForBailoutForId(stmt->FilterId(), TOS_REG); 1162 PrepareForBailoutForId(stmt->FilterId(), TOS_REG);
1163 __ Mov(x3, x0); 1163 __ Mov(x3, x0);
1164 __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, 1164 __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex,
1165 loop_statement.continue_label()); 1165 loop_statement.continue_label());
1166 1166
1167 // Update the 'each' property or variable from the possibly filtered 1167 // Update the 'each' property or variable from the possibly filtered
1168 // entry in register x3. 1168 // entry in register x3.
1169 __ Bind(&update_each); 1169 __ Bind(&update_each);
1170 __ Mov(result_register(), x3); 1170 __ Mov(result_register(), x3);
1171 // Perform the assignment as if via '='. 1171 // Perform the assignment as if via '='.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1212 if (!FLAG_always_opt && 1212 if (!FLAG_always_opt &&
1213 !FLAG_prepare_always_opt && 1213 !FLAG_prepare_always_opt &&
1214 !pretenure && 1214 !pretenure &&
1215 scope()->is_function_scope() && 1215 scope()->is_function_scope() &&
1216 info->num_literals() == 0) { 1216 info->num_literals() == 0) {
1217 FastNewClosureStub stub(isolate(), info->language_mode(), info->kind()); 1217 FastNewClosureStub stub(isolate(), info->language_mode(), info->kind());
1218 __ Mov(x2, Operand(info)); 1218 __ Mov(x2, Operand(info));
1219 __ CallStub(&stub); 1219 __ CallStub(&stub);
1220 } else { 1220 } else {
1221 __ Push(info); 1221 __ Push(info);
1222 __ CallRuntime( 1222 __ CallRuntime(pretenure ? Runtime::kNewClosure_Tenured
1223 pretenure ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure, 1); 1223 : Runtime::kNewClosure);
1224 } 1224 }
1225 context()->Plug(x0); 1225 context()->Plug(x0);
1226 } 1226 }
1227 1227
1228 1228
1229 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, 1229 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset,
1230 FeedbackVectorSlot slot) { 1230 FeedbackVectorSlot slot) {
1231 DCHECK(NeedsHomeObject(initializer)); 1231 DCHECK(NeedsHomeObject(initializer));
1232 __ Peek(StoreDescriptor::ReceiverRegister(), 0); 1232 __ Peek(StoreDescriptor::ReceiverRegister(), 0);
1233 __ Mov(StoreDescriptor::NameRegister(), 1233 __ Mov(StoreDescriptor::NameRegister(),
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1346 Variable* local = var->local_if_not_shadowed(); 1346 Variable* local = var->local_if_not_shadowed();
1347 __ Ldr(x0, ContextSlotOperandCheckExtensions(local, slow)); 1347 __ Ldr(x0, ContextSlotOperandCheckExtensions(local, slow));
1348 if (local->mode() == LET || local->mode() == CONST || 1348 if (local->mode() == LET || local->mode() == CONST ||
1349 local->mode() == CONST_LEGACY) { 1349 local->mode() == CONST_LEGACY) {
1350 __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, done); 1350 __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, done);
1351 if (local->mode() == CONST_LEGACY) { 1351 if (local->mode() == CONST_LEGACY) {
1352 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); 1352 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex);
1353 } else { // LET || CONST 1353 } else { // LET || CONST
1354 __ Mov(x0, Operand(var->name())); 1354 __ Mov(x0, Operand(var->name()));
1355 __ Push(x0); 1355 __ Push(x0);
1356 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1356 __ CallRuntime(Runtime::kThrowReferenceError);
1357 } 1357 }
1358 } 1358 }
1359 __ B(done); 1359 __ B(done);
1360 } 1360 }
1361 } 1361 }
1362 1362
1363 1363
1364 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, 1364 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
1365 TypeofMode typeof_mode) { 1365 TypeofMode typeof_mode) {
1366 Variable* var = proxy->var(); 1366 Variable* var = proxy->var();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1402 if (NeedsHoleCheckForLoad(proxy)) { 1402 if (NeedsHoleCheckForLoad(proxy)) {
1403 // Let and const need a read barrier. 1403 // Let and const need a read barrier.
1404 GetVar(x0, var); 1404 GetVar(x0, var);
1405 Label done; 1405 Label done;
1406 __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, &done); 1406 __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, &done);
1407 if (var->mode() == LET || var->mode() == CONST) { 1407 if (var->mode() == LET || var->mode() == CONST) {
1408 // Throw a reference error when using an uninitialized let/const 1408 // Throw a reference error when using an uninitialized let/const
1409 // binding in harmony mode. 1409 // binding in harmony mode.
1410 __ Mov(x0, Operand(var->name())); 1410 __ Mov(x0, Operand(var->name()));
1411 __ Push(x0); 1411 __ Push(x0);
1412 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1412 __ CallRuntime(Runtime::kThrowReferenceError);
1413 __ Bind(&done); 1413 __ Bind(&done);
1414 } else { 1414 } else {
1415 // Uninitialized legacy const bindings are unholed. 1415 // Uninitialized legacy const bindings are unholed.
1416 DCHECK(var->mode() == CONST_LEGACY); 1416 DCHECK(var->mode() == CONST_LEGACY);
1417 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); 1417 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex);
1418 __ Bind(&done); 1418 __ Bind(&done);
1419 } 1419 }
1420 context()->Plug(x0); 1420 context()->Plug(x0);
1421 break; 1421 break;
1422 } 1422 }
1423 context()->Plug(var); 1423 context()->Plug(var);
1424 break; 1424 break;
1425 } 1425 }
1426 1426
1427 case VariableLocation::LOOKUP: { 1427 case VariableLocation::LOOKUP: {
1428 Label done, slow; 1428 Label done, slow;
1429 // Generate code for loading from variables potentially shadowed by 1429 // Generate code for loading from variables potentially shadowed by
1430 // eval-introduced variables. 1430 // eval-introduced variables.
1431 EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done); 1431 EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
1432 __ Bind(&slow); 1432 __ Bind(&slow);
1433 Comment cmnt(masm_, "Lookup variable"); 1433 Comment cmnt(masm_, "Lookup variable");
1434 __ Mov(x1, Operand(var->name())); 1434 __ Mov(x1, Operand(var->name()));
1435 __ Push(cp, x1); // Context and name. 1435 __ Push(cp, x1); // Context and name.
1436 Runtime::FunctionId function_id = 1436 Runtime::FunctionId function_id =
1437 typeof_mode == NOT_INSIDE_TYPEOF 1437 typeof_mode == NOT_INSIDE_TYPEOF
1438 ? Runtime::kLoadLookupSlot 1438 ? Runtime::kLoadLookupSlot
1439 : Runtime::kLoadLookupSlotNoReferenceError; 1439 : Runtime::kLoadLookupSlotNoReferenceError;
1440 __ CallRuntime(function_id, 2); 1440 __ CallRuntime(function_id);
1441 __ Bind(&done); 1441 __ Bind(&done);
1442 context()->Plug(x0); 1442 context()->Plug(x0);
1443 break; 1443 break;
1444 } 1444 }
1445 } 1445 }
1446 } 1446 }
1447 1447
1448 1448
1449 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1449 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1450 Comment cmnt(masm_, "[ RegExpLiteral"); 1450 Comment cmnt(masm_, "[ RegExpLiteral");
(...skipping 28 matching lines...) Expand all
1479 Comment cmnt(masm_, "[ ObjectLiteral"); 1479 Comment cmnt(masm_, "[ ObjectLiteral");
1480 1480
1481 Handle<FixedArray> constant_properties = expr->constant_properties(); 1481 Handle<FixedArray> constant_properties = expr->constant_properties();
1482 __ Ldr(x3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 1482 __ Ldr(x3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1483 __ Mov(x2, Smi::FromInt(expr->literal_index())); 1483 __ Mov(x2, Smi::FromInt(expr->literal_index()));
1484 __ Mov(x1, Operand(constant_properties)); 1484 __ Mov(x1, Operand(constant_properties));
1485 int flags = expr->ComputeFlags(); 1485 int flags = expr->ComputeFlags();
1486 __ Mov(x0, Smi::FromInt(flags)); 1486 __ Mov(x0, Smi::FromInt(flags));
1487 if (MustCreateObjectLiteralWithRuntime(expr)) { 1487 if (MustCreateObjectLiteralWithRuntime(expr)) {
1488 __ Push(x3, x2, x1, x0); 1488 __ Push(x3, x2, x1, x0);
1489 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); 1489 __ CallRuntime(Runtime::kCreateObjectLiteral);
1490 } else { 1490 } else {
1491 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); 1491 FastCloneShallowObjectStub stub(isolate(), expr->properties_count());
1492 __ CallStub(&stub); 1492 __ CallStub(&stub);
1493 } 1493 }
1494 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1494 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
1495 1495
1496 // If result_saved is true the result is on top of the stack. If 1496 // If result_saved is true the result is on top of the stack. If
1497 // result_saved is false the result is in x0. 1497 // result_saved is false the result is in x0.
1498 bool result_saved = false; 1498 bool result_saved = false;
1499 1499
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1540 __ Peek(x0, 0); 1540 __ Peek(x0, 0);
1541 __ Push(x0); 1541 __ Push(x0);
1542 VisitForStackValue(key); 1542 VisitForStackValue(key);
1543 VisitForStackValue(value); 1543 VisitForStackValue(value);
1544 if (property->emit_store()) { 1544 if (property->emit_store()) {
1545 if (NeedsHomeObject(value)) { 1545 if (NeedsHomeObject(value)) {
1546 EmitSetHomeObject(value, 2, property->GetSlot()); 1546 EmitSetHomeObject(value, 2, property->GetSlot());
1547 } 1547 }
1548 __ Mov(x0, Smi::FromInt(SLOPPY)); // Language mode 1548 __ Mov(x0, Smi::FromInt(SLOPPY)); // Language mode
1549 __ Push(x0); 1549 __ Push(x0);
1550 __ CallRuntime(Runtime::kSetProperty, 4); 1550 __ CallRuntime(Runtime::kSetProperty);
1551 } else { 1551 } else {
1552 __ Drop(3); 1552 __ Drop(3);
1553 } 1553 }
1554 break; 1554 break;
1555 case ObjectLiteral::Property::PROTOTYPE: 1555 case ObjectLiteral::Property::PROTOTYPE:
1556 DCHECK(property->emit_store()); 1556 DCHECK(property->emit_store());
1557 // Duplicate receiver on stack. 1557 // Duplicate receiver on stack.
1558 __ Peek(x0, 0); 1558 __ Peek(x0, 0);
1559 __ Push(x0); 1559 __ Push(x0);
1560 VisitForStackValue(value); 1560 VisitForStackValue(value);
1561 __ CallRuntime(Runtime::kInternalSetPrototype, 2); 1561 __ CallRuntime(Runtime::kInternalSetPrototype);
1562 break; 1562 break;
1563 case ObjectLiteral::Property::GETTER: 1563 case ObjectLiteral::Property::GETTER:
1564 if (property->emit_store()) { 1564 if (property->emit_store()) {
1565 accessor_table.lookup(key)->second->getter = property; 1565 accessor_table.lookup(key)->second->getter = property;
1566 } 1566 }
1567 break; 1567 break;
1568 case ObjectLiteral::Property::SETTER: 1568 case ObjectLiteral::Property::SETTER:
1569 if (property->emit_store()) { 1569 if (property->emit_store()) {
1570 accessor_table.lookup(key)->second->setter = property; 1570 accessor_table.lookup(key)->second->setter = property;
1571 } 1571 }
1572 break; 1572 break;
1573 } 1573 }
1574 } 1574 }
1575 1575
1576 // Emit code to define accessors, using only a single call to the runtime for 1576 // Emit code to define accessors, using only a single call to the runtime for
1577 // each pair of corresponding getters and setters. 1577 // each pair of corresponding getters and setters.
1578 for (AccessorTable::Iterator it = accessor_table.begin(); 1578 for (AccessorTable::Iterator it = accessor_table.begin();
1579 it != accessor_table.end(); 1579 it != accessor_table.end();
1580 ++it) { 1580 ++it) {
1581 __ Peek(x10, 0); // Duplicate receiver. 1581 __ Peek(x10, 0); // Duplicate receiver.
1582 __ Push(x10); 1582 __ Push(x10);
1583 VisitForStackValue(it->first); 1583 VisitForStackValue(it->first);
1584 EmitAccessor(it->second->getter); 1584 EmitAccessor(it->second->getter);
1585 EmitAccessor(it->second->setter); 1585 EmitAccessor(it->second->setter);
1586 __ Mov(x10, Smi::FromInt(NONE)); 1586 __ Mov(x10, Smi::FromInt(NONE));
1587 __ Push(x10); 1587 __ Push(x10);
1588 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); 1588 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked);
1589 } 1589 }
1590 1590
1591 // Object literals have two parts. The "static" part on the left contains no 1591 // Object literals have two parts. The "static" part on the left contains no
1592 // computed property names, and so we can compute its map ahead of time; see 1592 // computed property names, and so we can compute its map ahead of time; see
1593 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part 1593 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part
1594 // starts with the first computed property name, and continues with all 1594 // starts with the first computed property name, and continues with all
1595 // properties to its right. All the code from above initializes the static 1595 // properties to its right. All the code from above initializes the static
1596 // component of the object literal, and arranges for the map of the result to 1596 // component of the object literal, and arranges for the map of the result to
1597 // reflect the static order in which the keys appear. For the dynamic 1597 // reflect the static order in which the keys appear. For the dynamic
1598 // properties, we compile them into a series of "SetOwnProperty" runtime 1598 // properties, we compile them into a series of "SetOwnProperty" runtime
1599 // calls. This will preserve insertion order. 1599 // calls. This will preserve insertion order.
1600 for (; property_index < expr->properties()->length(); property_index++) { 1600 for (; property_index < expr->properties()->length(); property_index++) {
1601 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1601 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1602 1602
1603 Expression* value = property->value(); 1603 Expression* value = property->value();
1604 if (!result_saved) { 1604 if (!result_saved) {
1605 __ Push(x0); // Save result on stack 1605 __ Push(x0); // Save result on stack
1606 result_saved = true; 1606 result_saved = true;
1607 } 1607 }
1608 1608
1609 __ Peek(x10, 0); // Duplicate receiver. 1609 __ Peek(x10, 0); // Duplicate receiver.
1610 __ Push(x10); 1610 __ Push(x10);
1611 1611
1612 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1612 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1613 DCHECK(!property->is_computed_name()); 1613 DCHECK(!property->is_computed_name());
1614 VisitForStackValue(value); 1614 VisitForStackValue(value);
1615 DCHECK(property->emit_store()); 1615 DCHECK(property->emit_store());
1616 __ CallRuntime(Runtime::kInternalSetPrototype, 2); 1616 __ CallRuntime(Runtime::kInternalSetPrototype);
1617 } else { 1617 } else {
1618 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); 1618 EmitPropertyKey(property, expr->GetIdForProperty(property_index));
1619 VisitForStackValue(value); 1619 VisitForStackValue(value);
1620 if (NeedsHomeObject(value)) { 1620 if (NeedsHomeObject(value)) {
1621 EmitSetHomeObject(value, 2, property->GetSlot()); 1621 EmitSetHomeObject(value, 2, property->GetSlot());
1622 } 1622 }
1623 1623
1624 switch (property->kind()) { 1624 switch (property->kind()) {
1625 case ObjectLiteral::Property::CONSTANT: 1625 case ObjectLiteral::Property::CONSTANT:
1626 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1626 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1627 case ObjectLiteral::Property::COMPUTED: 1627 case ObjectLiteral::Property::COMPUTED:
1628 if (property->emit_store()) { 1628 if (property->emit_store()) {
1629 __ Mov(x0, Smi::FromInt(NONE)); 1629 __ Mov(x0, Smi::FromInt(NONE));
1630 __ Push(x0); 1630 __ Push(x0);
1631 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); 1631 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked);
1632 } else { 1632 } else {
1633 __ Drop(3); 1633 __ Drop(3);
1634 } 1634 }
1635 break; 1635 break;
1636 1636
1637 case ObjectLiteral::Property::PROTOTYPE: 1637 case ObjectLiteral::Property::PROTOTYPE:
1638 UNREACHABLE(); 1638 UNREACHABLE();
1639 break; 1639 break;
1640 1640
1641 case ObjectLiteral::Property::GETTER: 1641 case ObjectLiteral::Property::GETTER:
1642 __ Mov(x0, Smi::FromInt(NONE)); 1642 __ Mov(x0, Smi::FromInt(NONE));
1643 __ Push(x0); 1643 __ Push(x0);
1644 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 4); 1644 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
1645 break; 1645 break;
1646 1646
1647 case ObjectLiteral::Property::SETTER: 1647 case ObjectLiteral::Property::SETTER:
1648 __ Mov(x0, Smi::FromInt(NONE)); 1648 __ Mov(x0, Smi::FromInt(NONE));
1649 __ Push(x0); 1649 __ Push(x0);
1650 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 4); 1650 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
1651 break; 1651 break;
1652 } 1652 }
1653 } 1653 }
1654 } 1654 }
1655 1655
1656 if (expr->has_function()) { 1656 if (expr->has_function()) {
1657 DCHECK(result_saved); 1657 DCHECK(result_saved);
1658 __ Peek(x0, 0); 1658 __ Peek(x0, 0);
1659 __ Push(x0); 1659 __ Push(x0);
1660 __ CallRuntime(Runtime::kToFastProperties, 1); 1660 __ CallRuntime(Runtime::kToFastProperties);
1661 } 1661 }
1662 1662
1663 if (result_saved) { 1663 if (result_saved) {
1664 context()->PlugTOS(); 1664 context()->PlugTOS();
1665 } else { 1665 } else {
1666 context()->Plug(x0); 1666 context()->Plug(x0);
1667 } 1667 }
1668 } 1668 }
1669 1669
1670 1670
(...skipping 10 matching lines...) Expand all
1681 // we can turn it off if we don't have anywhere else to transition to. 1681 // we can turn it off if we don't have anywhere else to transition to.
1682 allocation_site_mode = DONT_TRACK_ALLOCATION_SITE; 1682 allocation_site_mode = DONT_TRACK_ALLOCATION_SITE;
1683 } 1683 }
1684 1684
1685 __ Ldr(x3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 1685 __ Ldr(x3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1686 __ Mov(x2, Smi::FromInt(expr->literal_index())); 1686 __ Mov(x2, Smi::FromInt(expr->literal_index()));
1687 __ Mov(x1, Operand(constant_elements)); 1687 __ Mov(x1, Operand(constant_elements));
1688 if (MustCreateArrayLiteralWithRuntime(expr)) { 1688 if (MustCreateArrayLiteralWithRuntime(expr)) {
1689 __ Mov(x0, Smi::FromInt(expr->ComputeFlags())); 1689 __ Mov(x0, Smi::FromInt(expr->ComputeFlags()));
1690 __ Push(x3, x2, x1, x0); 1690 __ Push(x3, x2, x1, x0);
1691 __ CallRuntime(Runtime::kCreateArrayLiteral, 4); 1691 __ CallRuntime(Runtime::kCreateArrayLiteral);
1692 } else { 1692 } else {
1693 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); 1693 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode);
1694 __ CallStub(&stub); 1694 __ CallStub(&stub);
1695 } 1695 }
1696 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1696 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
1697 1697
1698 bool result_saved = false; // Is the result saved to the stack? 1698 bool result_saved = false; // Is the result saved to the stack?
1699 ZoneList<Expression*>* subexprs = expr->values(); 1699 ZoneList<Expression*>* subexprs = expr->values();
1700 int length = subexprs->length(); 1700 int length = subexprs->length();
1701 1701
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1738 for (; array_index < length; array_index++) { 1738 for (; array_index < length; array_index++) {
1739 Expression* subexpr = subexprs->at(array_index); 1739 Expression* subexpr = subexprs->at(array_index);
1740 1740
1741 __ Push(x0); 1741 __ Push(x0);
1742 if (subexpr->IsSpread()) { 1742 if (subexpr->IsSpread()) {
1743 VisitForStackValue(subexpr->AsSpread()->expression()); 1743 VisitForStackValue(subexpr->AsSpread()->expression());
1744 __ InvokeBuiltin(Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX, 1744 __ InvokeBuiltin(Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX,
1745 CALL_FUNCTION); 1745 CALL_FUNCTION);
1746 } else { 1746 } else {
1747 VisitForStackValue(subexpr); 1747 VisitForStackValue(subexpr);
1748 __ CallRuntime(Runtime::kAppendElement, 2); 1748 __ CallRuntime(Runtime::kAppendElement);
1749 } 1749 }
1750 1750
1751 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1751 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1752 } 1752 }
1753 1753
1754 if (result_saved) { 1754 if (result_saved) {
1755 context()->PlugTOS(); 1755 context()->PlugTOS();
1756 } else { 1756 } else {
1757 context()->Plug(x0); 1757 context()->Plug(x0);
1758 } 1758 }
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1912 1912
1913 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { 1913 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
1914 // Stack: receiver, home_object. 1914 // Stack: receiver, home_object.
1915 SetExpressionPosition(prop); 1915 SetExpressionPosition(prop);
1916 Literal* key = prop->key()->AsLiteral(); 1916 Literal* key = prop->key()->AsLiteral();
1917 DCHECK(!key->value()->IsSmi()); 1917 DCHECK(!key->value()->IsSmi());
1918 DCHECK(prop->IsSuperAccess()); 1918 DCHECK(prop->IsSuperAccess());
1919 1919
1920 __ Push(key->value()); 1920 __ Push(key->value());
1921 __ Push(Smi::FromInt(language_mode())); 1921 __ Push(Smi::FromInt(language_mode()));
1922 __ CallRuntime(Runtime::kLoadFromSuper, 4); 1922 __ CallRuntime(Runtime::kLoadFromSuper);
1923 } 1923 }
1924 1924
1925 1925
1926 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 1926 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
1927 SetExpressionPosition(prop); 1927 SetExpressionPosition(prop);
1928 // Call keyed load IC. It has arguments key and receiver in x0 and x1. 1928 // Call keyed load IC. It has arguments key and receiver in x0 and x1.
1929 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code(); 1929 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
1930 __ Mov(LoadDescriptor::SlotRegister(), 1930 __ Mov(LoadDescriptor::SlotRegister(),
1931 SmiFromSlot(prop->PropertyFeedbackSlot())); 1931 SmiFromSlot(prop->PropertyFeedbackSlot()));
1932 CallIC(ic); 1932 CallIC(ic);
1933 } 1933 }
1934 1934
1935 1935
1936 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { 1936 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
1937 // Stack: receiver, home_object, key. 1937 // Stack: receiver, home_object, key.
1938 SetExpressionPosition(prop); 1938 SetExpressionPosition(prop);
1939 __ Push(Smi::FromInt(language_mode())); 1939 __ Push(Smi::FromInt(language_mode()));
1940 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4); 1940 __ CallRuntime(Runtime::kLoadKeyedFromSuper);
1941 } 1941 }
1942 1942
1943 1943
1944 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 1944 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
1945 Token::Value op, 1945 Token::Value op,
1946 Expression* left_expr, 1946 Expression* left_expr,
1947 Expression* right_expr) { 1947 Expression* right_expr) {
1948 Label done, both_smis, stub_call; 1948 Label done, both_smis, stub_call;
1949 1949
1950 // Get the arguments. 1950 // Get the arguments.
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
2077 __ Peek(scratch, 0); // prototype 2077 __ Peek(scratch, 0); // prototype
2078 } 2078 }
2079 __ Push(scratch); 2079 __ Push(scratch);
2080 EmitPropertyKey(property, lit->GetIdForProperty(i)); 2080 EmitPropertyKey(property, lit->GetIdForProperty(i));
2081 2081
2082 // The static prototype property is read only. We handle the non computed 2082 // The static prototype property is read only. We handle the non computed
2083 // property name case in the parser. Since this is the only case where we 2083 // property name case in the parser. Since this is the only case where we
2084 // need to check for an own read only property we special case this so we do 2084 // need to check for an own read only property we special case this so we do
2085 // not need to do this for every property. 2085 // not need to do this for every property.
2086 if (property->is_static() && property->is_computed_name()) { 2086 if (property->is_static() && property->is_computed_name()) {
2087 __ CallRuntime(Runtime::kThrowIfStaticPrototype, 1); 2087 __ CallRuntime(Runtime::kThrowIfStaticPrototype);
2088 __ Push(x0); 2088 __ Push(x0);
2089 } 2089 }
2090 2090
2091 VisitForStackValue(value); 2091 VisitForStackValue(value);
2092 if (NeedsHomeObject(value)) { 2092 if (NeedsHomeObject(value)) {
2093 EmitSetHomeObject(value, 2, property->GetSlot()); 2093 EmitSetHomeObject(value, 2, property->GetSlot());
2094 } 2094 }
2095 2095
2096 switch (property->kind()) { 2096 switch (property->kind()) {
2097 case ObjectLiteral::Property::CONSTANT: 2097 case ObjectLiteral::Property::CONSTANT:
2098 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 2098 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
2099 case ObjectLiteral::Property::PROTOTYPE: 2099 case ObjectLiteral::Property::PROTOTYPE:
2100 UNREACHABLE(); 2100 UNREACHABLE();
2101 case ObjectLiteral::Property::COMPUTED: 2101 case ObjectLiteral::Property::COMPUTED:
2102 __ CallRuntime(Runtime::kDefineClassMethod, 3); 2102 __ CallRuntime(Runtime::kDefineClassMethod);
2103 break; 2103 break;
2104 2104
2105 case ObjectLiteral::Property::GETTER: 2105 case ObjectLiteral::Property::GETTER:
2106 __ Mov(x0, Smi::FromInt(DONT_ENUM)); 2106 __ Mov(x0, Smi::FromInt(DONT_ENUM));
2107 __ Push(x0); 2107 __ Push(x0);
2108 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 4); 2108 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
2109 break; 2109 break;
2110 2110
2111 case ObjectLiteral::Property::SETTER: 2111 case ObjectLiteral::Property::SETTER:
2112 __ Mov(x0, Smi::FromInt(DONT_ENUM)); 2112 __ Mov(x0, Smi::FromInt(DONT_ENUM));
2113 __ Push(x0); 2113 __ Push(x0);
2114 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 4); 2114 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
2115 break; 2115 break;
2116 2116
2117 default: 2117 default:
2118 UNREACHABLE(); 2118 UNREACHABLE();
2119 } 2119 }
2120 } 2120 }
2121 2121
2122 // Set both the prototype and constructor to have fast properties, and also 2122 // Set both the prototype and constructor to have fast properties, and also
2123 // freeze them in strong mode. 2123 // freeze them in strong mode.
2124 __ CallRuntime(Runtime::kFinalizeClassDefinition, 2); 2124 __ CallRuntime(Runtime::kFinalizeClassDefinition);
2125 } 2125 }
2126 2126
2127 2127
2128 void FullCodeGenerator::EmitAssignment(Expression* expr, 2128 void FullCodeGenerator::EmitAssignment(Expression* expr,
2129 FeedbackVectorSlot slot) { 2129 FeedbackVectorSlot slot) {
2130 DCHECK(expr->IsValidReferenceExpressionOrThis()); 2130 DCHECK(expr->IsValidReferenceExpressionOrThis());
2131 2131
2132 Property* prop = expr->AsProperty(); 2132 Property* prop = expr->AsProperty();
2133 LhsKind assign_type = Property::GetAssignType(prop); 2133 LhsKind assign_type = Property::GetAssignType(prop);
2134 2134
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
2233 } else if (var->mode() == LET && op != Token::INIT) { 2233 } else if (var->mode() == LET && op != Token::INIT) {
2234 // Non-initializing assignment to let variable needs a write barrier. 2234 // Non-initializing assignment to let variable needs a write barrier.
2235 DCHECK(!var->IsLookupSlot()); 2235 DCHECK(!var->IsLookupSlot());
2236 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2236 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2237 Label assign; 2237 Label assign;
2238 MemOperand location = VarOperand(var, x1); 2238 MemOperand location = VarOperand(var, x1);
2239 __ Ldr(x10, location); 2239 __ Ldr(x10, location);
2240 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &assign); 2240 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &assign);
2241 __ Mov(x10, Operand(var->name())); 2241 __ Mov(x10, Operand(var->name()));
2242 __ Push(x10); 2242 __ Push(x10);
2243 __ CallRuntime(Runtime::kThrowReferenceError, 1); 2243 __ CallRuntime(Runtime::kThrowReferenceError);
2244 // Perform the assignment. 2244 // Perform the assignment.
2245 __ Bind(&assign); 2245 __ Bind(&assign);
2246 EmitStoreToStackLocalOrContextSlot(var, location); 2246 EmitStoreToStackLocalOrContextSlot(var, location);
2247 2247
2248 } else if (var->mode() == CONST && op != Token::INIT) { 2248 } else if (var->mode() == CONST && op != Token::INIT) {
2249 // Assignment to const variable needs a write barrier. 2249 // Assignment to const variable needs a write barrier.
2250 DCHECK(!var->IsLookupSlot()); 2250 DCHECK(!var->IsLookupSlot());
2251 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2251 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2252 Label const_error; 2252 Label const_error;
2253 MemOperand location = VarOperand(var, x1); 2253 MemOperand location = VarOperand(var, x1);
2254 __ Ldr(x10, location); 2254 __ Ldr(x10, location);
2255 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &const_error); 2255 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &const_error);
2256 __ Mov(x10, Operand(var->name())); 2256 __ Mov(x10, Operand(var->name()));
2257 __ Push(x10); 2257 __ Push(x10);
2258 __ CallRuntime(Runtime::kThrowReferenceError, 1); 2258 __ CallRuntime(Runtime::kThrowReferenceError);
2259 __ Bind(&const_error); 2259 __ Bind(&const_error);
2260 __ CallRuntime(Runtime::kThrowConstAssignError, 0); 2260 __ CallRuntime(Runtime::kThrowConstAssignError);
2261 2261
2262 } else if (var->is_this() && var->mode() == CONST && op == Token::INIT) { 2262 } else if (var->is_this() && var->mode() == CONST && op == Token::INIT) {
2263 // Initializing assignment to const {this} needs a write barrier. 2263 // Initializing assignment to const {this} needs a write barrier.
2264 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2264 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2265 Label uninitialized_this; 2265 Label uninitialized_this;
2266 MemOperand location = VarOperand(var, x1); 2266 MemOperand location = VarOperand(var, x1);
2267 __ Ldr(x10, location); 2267 __ Ldr(x10, location);
2268 __ JumpIfRoot(x10, Heap::kTheHoleValueRootIndex, &uninitialized_this); 2268 __ JumpIfRoot(x10, Heap::kTheHoleValueRootIndex, &uninitialized_this);
2269 __ Mov(x0, Operand(var->name())); 2269 __ Mov(x0, Operand(var->name()));
2270 __ Push(x0); 2270 __ Push(x0);
2271 __ CallRuntime(Runtime::kThrowReferenceError, 1); 2271 __ CallRuntime(Runtime::kThrowReferenceError);
2272 __ bind(&uninitialized_this); 2272 __ bind(&uninitialized_this);
2273 EmitStoreToStackLocalOrContextSlot(var, location); 2273 EmitStoreToStackLocalOrContextSlot(var, location);
2274 2274
2275 } else if (!var->is_const_mode() || 2275 } else if (!var->is_const_mode() ||
2276 (var->mode() == CONST && op == Token::INIT)) { 2276 (var->mode() == CONST && op == Token::INIT)) {
2277 if (var->IsLookupSlot()) { 2277 if (var->IsLookupSlot()) {
2278 // Assignment to var. 2278 // Assignment to var.
2279 __ Mov(x11, Operand(var->name())); 2279 __ Mov(x11, Operand(var->name()));
2280 __ Mov(x10, Smi::FromInt(language_mode())); 2280 __ Mov(x10, Smi::FromInt(language_mode()));
2281 // jssp[0] : mode. 2281 // jssp[0] : mode.
2282 // jssp[8] : name. 2282 // jssp[8] : name.
2283 // jssp[16] : context. 2283 // jssp[16] : context.
2284 // jssp[24] : value. 2284 // jssp[24] : value.
2285 __ Push(x0, cp, x11, x10); 2285 __ Push(x0, cp, x11, x10);
2286 __ CallRuntime(Runtime::kStoreLookupSlot, 4); 2286 __ CallRuntime(Runtime::kStoreLookupSlot);
2287 } else { 2287 } else {
2288 // Assignment to var or initializing assignment to let/const in harmony 2288 // Assignment to var or initializing assignment to let/const in harmony
2289 // mode. 2289 // mode.
2290 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2290 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2291 MemOperand location = VarOperand(var, x1); 2291 MemOperand location = VarOperand(var, x1);
2292 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) { 2292 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) {
2293 __ Ldr(x10, location); 2293 __ Ldr(x10, location);
2294 __ CompareRoot(x10, Heap::kTheHoleValueRootIndex); 2294 __ CompareRoot(x10, Heap::kTheHoleValueRootIndex);
2295 __ Check(eq, kLetBindingReInitialization); 2295 __ Check(eq, kLetBindingReInitialization);
2296 } 2296 }
2297 EmitStoreToStackLocalOrContextSlot(var, location); 2297 EmitStoreToStackLocalOrContextSlot(var, location);
2298 } 2298 }
2299 2299
2300 } else if (var->mode() == CONST_LEGACY && op == Token::INIT) { 2300 } else if (var->mode() == CONST_LEGACY && op == Token::INIT) {
2301 // Const initializers need a write barrier. 2301 // Const initializers need a write barrier.
2302 DCHECK(!var->IsParameter()); // No const parameters. 2302 DCHECK(!var->IsParameter()); // No const parameters.
2303 if (var->IsLookupSlot()) { 2303 if (var->IsLookupSlot()) {
2304 __ Mov(x1, Operand(var->name())); 2304 __ Mov(x1, Operand(var->name()));
2305 __ Push(x0, cp, x1); 2305 __ Push(x0, cp, x1);
2306 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); 2306 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot);
2307 } else { 2307 } else {
2308 DCHECK(var->IsStackLocal() || var->IsContextSlot()); 2308 DCHECK(var->IsStackLocal() || var->IsContextSlot());
2309 Label skip; 2309 Label skip;
2310 MemOperand location = VarOperand(var, x1); 2310 MemOperand location = VarOperand(var, x1);
2311 __ Ldr(x10, location); 2311 __ Ldr(x10, location);
2312 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &skip); 2312 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &skip);
2313 EmitStoreToStackLocalOrContextSlot(var, location); 2313 EmitStoreToStackLocalOrContextSlot(var, location);
2314 __ Bind(&skip); 2314 __ Bind(&skip);
2315 } 2315 }
2316 2316
2317 } else { 2317 } else {
2318 DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT); 2318 DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT);
2319 if (is_strict(language_mode())) { 2319 if (is_strict(language_mode())) {
2320 __ CallRuntime(Runtime::kThrowConstAssignError, 0); 2320 __ CallRuntime(Runtime::kThrowConstAssignError);
2321 } 2321 }
2322 // Silently ignore store in sloppy mode. 2322 // Silently ignore store in sloppy mode.
2323 } 2323 }
2324 } 2324 }
2325 2325
2326 2326
2327 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2327 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2328 ASM_LOCATION("FullCodeGenerator::EmitNamedPropertyAssignment"); 2328 ASM_LOCATION("FullCodeGenerator::EmitNamedPropertyAssignment");
2329 // Assignment to a property, using a named store IC. 2329 // Assignment to a property, using a named store IC.
2330 Property* prop = expr->target()->AsProperty(); 2330 Property* prop = expr->target()->AsProperty();
(...skipping 15 matching lines...) Expand all
2346 // Assignment to named property of super. 2346 // Assignment to named property of super.
2347 // x0 : value 2347 // x0 : value
2348 // stack : receiver ('this'), home_object 2348 // stack : receiver ('this'), home_object
2349 DCHECK(prop != NULL); 2349 DCHECK(prop != NULL);
2350 Literal* key = prop->key()->AsLiteral(); 2350 Literal* key = prop->key()->AsLiteral();
2351 DCHECK(key != NULL); 2351 DCHECK(key != NULL);
2352 2352
2353 __ Push(key->value()); 2353 __ Push(key->value());
2354 __ Push(x0); 2354 __ Push(x0);
2355 __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict 2355 __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict
2356 : Runtime::kStoreToSuper_Sloppy), 2356 : Runtime::kStoreToSuper_Sloppy));
2357 4);
2358 } 2357 }
2359 2358
2360 2359
2361 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { 2360 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
2362 // Assignment to named property of super. 2361 // Assignment to named property of super.
2363 // x0 : value 2362 // x0 : value
2364 // stack : receiver ('this'), home_object, key 2363 // stack : receiver ('this'), home_object, key
2365 DCHECK(prop != NULL); 2364 DCHECK(prop != NULL);
2366 2365
2367 __ Push(x0); 2366 __ Push(x0);
2368 __ CallRuntime( 2367 __ CallRuntime((is_strict(language_mode())
2369 (is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict 2368 ? Runtime::kStoreKeyedToSuper_Strict
2370 : Runtime::kStoreKeyedToSuper_Sloppy), 2369 : Runtime::kStoreKeyedToSuper_Sloppy));
2371 4);
2372 } 2370 }
2373 2371
2374 2372
2375 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2373 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2376 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment"); 2374 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment");
2377 // Assignment to a property, using a keyed store IC. 2375 // Assignment to a property, using a keyed store IC.
2378 2376
2379 // TODO(all): Could we pass this in registers rather than on the stack? 2377 // TODO(all): Could we pass this in registers rather than on the stack?
2380 __ Pop(StoreDescriptor::NameRegister(), StoreDescriptor::ReceiverRegister()); 2378 __ Pop(StoreDescriptor::NameRegister(), StoreDescriptor::ReceiverRegister());
2381 DCHECK(StoreDescriptor::ValueRegister().is(x0)); 2379 DCHECK(StoreDescriptor::ValueRegister().is(x0));
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
2493 __ Push(x0, scratch); 2491 __ Push(x0, scratch);
2494 __ Push(key->value()); 2492 __ Push(key->value());
2495 __ Push(Smi::FromInt(language_mode())); 2493 __ Push(Smi::FromInt(language_mode()));
2496 2494
2497 // Stack here: 2495 // Stack here:
2498 // - home_object 2496 // - home_object
2499 // - this (receiver) 2497 // - this (receiver)
2500 // - this (receiver) <-- LoadFromSuper will pop here and below. 2498 // - this (receiver) <-- LoadFromSuper will pop here and below.
2501 // - home_object 2499 // - home_object
2502 // - language_mode 2500 // - language_mode
2503 __ CallRuntime(Runtime::kLoadFromSuper, 4); 2501 __ CallRuntime(Runtime::kLoadFromSuper);
2504 2502
2505 // Replace home_object with target function. 2503 // Replace home_object with target function.
2506 __ Poke(x0, kPointerSize); 2504 __ Poke(x0, kPointerSize);
2507 2505
2508 // Stack here: 2506 // Stack here:
2509 // - target function 2507 // - target function
2510 // - this (receiver) 2508 // - this (receiver)
2511 EmitCall(expr); 2509 EmitCall(expr);
2512 } 2510 }
2513 2511
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2554 VisitForStackValue(prop->key()); 2552 VisitForStackValue(prop->key());
2555 __ Push(Smi::FromInt(language_mode())); 2553 __ Push(Smi::FromInt(language_mode()));
2556 2554
2557 // Stack here: 2555 // Stack here:
2558 // - home_object 2556 // - home_object
2559 // - this (receiver) 2557 // - this (receiver)
2560 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. 2558 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
2561 // - home_object 2559 // - home_object
2562 // - key 2560 // - key
2563 // - language_mode 2561 // - language_mode
2564 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4); 2562 __ CallRuntime(Runtime::kLoadKeyedFromSuper);
2565 2563
2566 // Replace home_object with target function. 2564 // Replace home_object with target function.
2567 __ Poke(x0, kPointerSize); 2565 __ Poke(x0, kPointerSize);
2568 2566
2569 // Stack here: 2567 // Stack here:
2570 // - target function 2568 // - target function
2571 // - this (receiver) 2569 // - this (receiver)
2572 EmitCall(expr); 2570 EmitCall(expr);
2573 } 2571 }
2574 2572
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2612 2610
2613 // Prepare to push the language mode. 2611 // Prepare to push the language mode.
2614 __ Mov(x11, Smi::FromInt(language_mode())); 2612 __ Mov(x11, Smi::FromInt(language_mode()));
2615 // Prepare to push the start position of the scope the calls resides in. 2613 // Prepare to push the start position of the scope the calls resides in.
2616 __ Mov(x12, Smi::FromInt(scope()->start_position())); 2614 __ Mov(x12, Smi::FromInt(scope()->start_position()));
2617 2615
2618 // Push. 2616 // Push.
2619 __ Push(x9, x10, x11, x12); 2617 __ Push(x9, x10, x11, x12);
2620 2618
2621 // Do the runtime call. 2619 // Do the runtime call.
2622 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); 2620 __ CallRuntime(Runtime::kResolvePossiblyDirectEval);
2623 } 2621 }
2624 2622
2625 2623
2626 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. 2624 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls.
2627 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { 2625 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
2628 VariableProxy* callee = expr->expression()->AsVariableProxy(); 2626 VariableProxy* callee = expr->expression()->AsVariableProxy();
2629 if (callee->var()->IsLookupSlot()) { 2627 if (callee->var()->IsLookupSlot()) {
2630 Label slow, done; 2628 Label slow, done;
2631 SetExpressionPosition(callee); 2629 SetExpressionPosition(callee);
2632 // Generate code for loading from variables potentially shadowed 2630 // Generate code for loading from variables potentially shadowed
2633 // by eval-introduced variables. 2631 // by eval-introduced variables.
2634 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); 2632 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2635 2633
2636 __ Bind(&slow); 2634 __ Bind(&slow);
2637 // Call the runtime to find the function to call (returned in x0) 2635 // Call the runtime to find the function to call (returned in x0)
2638 // and the object holding it (returned in x1). 2636 // and the object holding it (returned in x1).
2639 __ Mov(x10, Operand(callee->name())); 2637 __ Mov(x10, Operand(callee->name()));
2640 __ Push(context_register(), x10); 2638 __ Push(context_register(), x10);
2641 __ CallRuntime(Runtime::kLoadLookupSlot, 2); 2639 __ CallRuntime(Runtime::kLoadLookupSlot);
2642 __ Push(x0, x1); // Receiver, function. 2640 __ Push(x0, x1); // Receiver, function.
2643 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); 2641 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
2644 2642
2645 // If fast case code has been generated, emit code to push the 2643 // If fast case code has been generated, emit code to push the
2646 // function and receiver and have the slow path jump around this 2644 // function and receiver and have the slow path jump around this
2647 // code. 2645 // code.
2648 if (done.is_linked()) { 2646 if (done.is_linked()) {
2649 Label call; 2647 Label call;
2650 __ B(&call); 2648 __ B(&call);
2651 __ Bind(&done); 2649 __ Bind(&done);
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after
3274 ZoneList<Expression*>* args = expr->arguments(); 3272 ZoneList<Expression*>* args = expr->arguments();
3275 DCHECK_EQ(1, args->length()); 3273 DCHECK_EQ(1, args->length());
3276 3274
3277 // Load the argument into x0 and convert it. 3275 // Load the argument into x0 and convert it.
3278 VisitForAccumulatorValue(args->at(0)); 3276 VisitForAccumulatorValue(args->at(0));
3279 3277
3280 // Convert the object to an integer. 3278 // Convert the object to an integer.
3281 Label done_convert; 3279 Label done_convert;
3282 __ JumpIfSmi(x0, &done_convert); 3280 __ JumpIfSmi(x0, &done_convert);
3283 __ Push(x0); 3281 __ Push(x0);
3284 __ CallRuntime(Runtime::kToInteger, 1); 3282 __ CallRuntime(Runtime::kToInteger);
3285 __ bind(&done_convert); 3283 __ bind(&done_convert);
3286 context()->Plug(x0); 3284 context()->Plug(x0);
3287 } 3285 }
3288 3286
3289 3287
3290 void FullCodeGenerator::EmitToName(CallRuntime* expr) { 3288 void FullCodeGenerator::EmitToName(CallRuntime* expr) {
3291 ZoneList<Expression*>* args = expr->arguments(); 3289 ZoneList<Expression*>* args = expr->arguments();
3292 DCHECK_EQ(1, args->length()); 3290 DCHECK_EQ(1, args->length());
3293 3291
3294 // Load the argument into x0 and convert it. 3292 // Load the argument into x0 and convert it.
3295 VisitForAccumulatorValue(args->at(0)); 3293 VisitForAccumulatorValue(args->at(0));
3296 3294
3297 Label convert, done_convert; 3295 Label convert, done_convert;
3298 __ JumpIfSmi(x0, &convert); 3296 __ JumpIfSmi(x0, &convert);
3299 STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE); 3297 STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE);
3300 __ JumpIfObjectType(x0, x1, x1, LAST_NAME_TYPE, &done_convert, ls); 3298 __ JumpIfObjectType(x0, x1, x1, LAST_NAME_TYPE, &done_convert, ls);
3301 __ Bind(&convert); 3299 __ Bind(&convert);
3302 __ Push(x0); 3300 __ Push(x0);
3303 __ CallRuntime(Runtime::kToName, 1); 3301 __ CallRuntime(Runtime::kToName);
3304 __ Bind(&done_convert); 3302 __ Bind(&done_convert);
3305 context()->Plug(x0); 3303 context()->Plug(x0);
3306 } 3304 }
3307 3305
3308 3306
3309 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { 3307 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) {
3310 ZoneList<Expression*>* args = expr->arguments(); 3308 ZoneList<Expression*>* args = expr->arguments();
3311 DCHECK(args->length() == 1); 3309 DCHECK(args->length() == 1);
3312 3310
3313 VisitForAccumulatorValue(args->at(0)); 3311 VisitForAccumulatorValue(args->at(0));
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
3743 __ ObjectUntag(untagged_result, result); 3741 __ ObjectUntag(untagged_result, result);
3744 __ Str(map_reg, MemOperand(untagged_result, HeapObject::kMapOffset)); 3742 __ Str(map_reg, MemOperand(untagged_result, HeapObject::kMapOffset));
3745 __ Stp(empty_fixed_array, empty_fixed_array, 3743 __ Stp(empty_fixed_array, empty_fixed_array,
3746 MemOperand(untagged_result, JSObject::kPropertiesOffset)); 3744 MemOperand(untagged_result, JSObject::kPropertiesOffset));
3747 __ Stp(result_value, boolean_done, 3745 __ Stp(result_value, boolean_done,
3748 MemOperand(untagged_result, JSIteratorResult::kValueOffset)); 3746 MemOperand(untagged_result, JSIteratorResult::kValueOffset));
3749 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); 3747 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize);
3750 __ B(&done); 3748 __ B(&done);
3751 3749
3752 __ Bind(&runtime); 3750 __ Bind(&runtime);
3753 __ CallRuntime(Runtime::kCreateIterResultObject, 2); 3751 __ CallRuntime(Runtime::kCreateIterResultObject);
3754 3752
3755 __ Bind(&done); 3753 __ Bind(&done);
3756 context()->Plug(x0); 3754 context()->Plug(x0);
3757 } 3755 }
3758 3756
3759 3757
3760 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { 3758 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
3761 // Push undefined as the receiver. 3759 // Push undefined as the receiver.
3762 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); 3760 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex);
3763 __ Push(x0); 3761 __ Push(x0);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
3834 case Token::DELETE: { 3832 case Token::DELETE: {
3835 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3833 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3836 Property* property = expr->expression()->AsProperty(); 3834 Property* property = expr->expression()->AsProperty();
3837 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 3835 VariableProxy* proxy = expr->expression()->AsVariableProxy();
3838 3836
3839 if (property != NULL) { 3837 if (property != NULL) {
3840 VisitForStackValue(property->obj()); 3838 VisitForStackValue(property->obj());
3841 VisitForStackValue(property->key()); 3839 VisitForStackValue(property->key());
3842 __ CallRuntime(is_strict(language_mode()) 3840 __ CallRuntime(is_strict(language_mode())
3843 ? Runtime::kDeleteProperty_Strict 3841 ? Runtime::kDeleteProperty_Strict
3844 : Runtime::kDeleteProperty_Sloppy, 3842 : Runtime::kDeleteProperty_Sloppy);
3845 2);
3846 context()->Plug(x0); 3843 context()->Plug(x0);
3847 } else if (proxy != NULL) { 3844 } else if (proxy != NULL) {
3848 Variable* var = proxy->var(); 3845 Variable* var = proxy->var();
3849 // Delete of an unqualified identifier is disallowed in strict mode but 3846 // Delete of an unqualified identifier is disallowed in strict mode but
3850 // "delete this" is allowed. 3847 // "delete this" is allowed.
3851 bool is_this = var->HasThisName(isolate()); 3848 bool is_this = var->HasThisName(isolate());
3852 DCHECK(is_sloppy(language_mode()) || is_this); 3849 DCHECK(is_sloppy(language_mode()) || is_this);
3853 if (var->IsUnallocatedOrGlobalSlot()) { 3850 if (var->IsUnallocatedOrGlobalSlot()) {
3854 __ LoadGlobalObject(x12); 3851 __ LoadGlobalObject(x12);
3855 __ Mov(x11, Operand(var->name())); 3852 __ Mov(x11, Operand(var->name()));
3856 __ Push(x12, x11); 3853 __ Push(x12, x11);
3857 __ CallRuntime(Runtime::kDeleteProperty_Sloppy, 2); 3854 __ CallRuntime(Runtime::kDeleteProperty_Sloppy);
3858 context()->Plug(x0); 3855 context()->Plug(x0);
3859 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 3856 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
3860 // Result of deleting non-global, non-dynamic variables is false. 3857 // Result of deleting non-global, non-dynamic variables is false.
3861 // The subexpression does not have side effects. 3858 // The subexpression does not have side effects.
3862 context()->Plug(is_this); 3859 context()->Plug(is_this);
3863 } else { 3860 } else {
3864 // Non-global variable. Call the runtime to try to delete from the 3861 // Non-global variable. Call the runtime to try to delete from the
3865 // context where the variable was introduced. 3862 // context where the variable was introduced.
3866 __ Mov(x2, Operand(var->name())); 3863 __ Mov(x2, Operand(var->name()));
3867 __ Push(context_register(), x2); 3864 __ Push(context_register(), x2);
3868 __ CallRuntime(Runtime::kDeleteLookupSlot, 2); 3865 __ CallRuntime(Runtime::kDeleteLookupSlot);
3869 context()->Plug(x0); 3866 context()->Plug(x0);
3870 } 3867 }
3871 } else { 3868 } else {
3872 // Result of deleting non-property, non-variable reference is true. 3869 // Result of deleting non-property, non-variable reference is true.
3873 // The subexpression may have side effects. 3870 // The subexpression may have side effects.
3874 VisitForEffect(expr->expression()); 3871 VisitForEffect(expr->expression());
3875 context()->Plug(true); 3872 context()->Plug(true);
3876 } 3873 }
3877 break; 3874 break;
3878 break; 3875 break;
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
4297 Label* if_false = NULL; 4294 Label* if_false = NULL;
4298 Label* fall_through = NULL; 4295 Label* fall_through = NULL;
4299 context()->PrepareTest(&materialize_true, &materialize_false, 4296 context()->PrepareTest(&materialize_true, &materialize_false,
4300 &if_true, &if_false, &fall_through); 4297 &if_true, &if_false, &fall_through);
4301 4298
4302 Token::Value op = expr->op(); 4299 Token::Value op = expr->op();
4303 VisitForStackValue(expr->left()); 4300 VisitForStackValue(expr->left());
4304 switch (op) { 4301 switch (op) {
4305 case Token::IN: 4302 case Token::IN:
4306 VisitForStackValue(expr->right()); 4303 VisitForStackValue(expr->right());
4307 __ CallRuntime(Runtime::kHasProperty, 2); 4304 __ CallRuntime(Runtime::kHasProperty);
4308 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 4305 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
4309 __ CompareRoot(x0, Heap::kTrueValueRootIndex); 4306 __ CompareRoot(x0, Heap::kTrueValueRootIndex);
4310 Split(eq, if_true, if_false, fall_through); 4307 Split(eq, if_true, if_false, fall_through);
4311 break; 4308 break;
4312 4309
4313 case Token::INSTANCEOF: { 4310 case Token::INSTANCEOF: {
4314 VisitForAccumulatorValue(expr->right()); 4311 VisitForAccumulatorValue(expr->right());
4315 __ Pop(x1); 4312 __ Pop(x1);
4316 InstanceOfStub stub(isolate()); 4313 InstanceOfStub stub(isolate());
4317 __ CallStub(&stub); 4314 __ CallStub(&stub);
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
4644 4641
4645 __ Bind(&slow_resume); 4642 __ Bind(&slow_resume);
4646 } 4643 }
4647 4644
4648 // Otherwise, we push holes for the operand stack and call the runtime to fix 4645 // Otherwise, we push holes for the operand stack and call the runtime to fix
4649 // up the stack and the handlers. 4646 // up the stack and the handlers.
4650 __ PushMultipleTimes(the_hole, operand_stack_size); 4647 __ PushMultipleTimes(the_hole, operand_stack_size);
4651 4648
4652 __ Mov(x10, Smi::FromInt(resume_mode)); 4649 __ Mov(x10, Smi::FromInt(resume_mode));
4653 __ Push(generator_object, result_register(), x10); 4650 __ Push(generator_object, result_register(), x10);
4654 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); 4651 __ CallRuntime(Runtime::kResumeJSGeneratorObject);
4655 // Not reached: the runtime call returns elsewhere. 4652 // Not reached: the runtime call returns elsewhere.
4656 __ Unreachable(); 4653 __ Unreachable();
4657 4654
4658 __ Bind(&done); 4655 __ Bind(&done);
4659 context()->Plug(result_register()); 4656 context()->Plug(result_register());
4660 } 4657 }
4661 4658
4662 4659
4663 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { 4660 void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
4664 Label allocate, done_allocate; 4661 Label allocate, done_allocate;
4665 4662
4666 // Allocate and populate an object with this form: { value: VAL, done: DONE } 4663 // Allocate and populate an object with this form: { value: VAL, done: DONE }
4667 4664
4668 Register result = x0; 4665 Register result = x0;
4669 __ Allocate(JSIteratorResult::kSize, result, x10, x11, &allocate, TAG_OBJECT); 4666 __ Allocate(JSIteratorResult::kSize, result, x10, x11, &allocate, TAG_OBJECT);
4670 __ B(&done_allocate); 4667 __ B(&done_allocate);
4671 4668
4672 __ Bind(&allocate); 4669 __ Bind(&allocate);
4673 __ Push(Smi::FromInt(JSIteratorResult::kSize)); 4670 __ Push(Smi::FromInt(JSIteratorResult::kSize));
4674 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); 4671 __ CallRuntime(Runtime::kAllocateInNewSpace);
4675 4672
4676 __ Bind(&done_allocate); 4673 __ Bind(&done_allocate);
4677 Register map_reg = x1; 4674 Register map_reg = x1;
4678 Register result_value = x2; 4675 Register result_value = x2;
4679 Register boolean_done = x3; 4676 Register boolean_done = x3;
4680 Register empty_fixed_array = x4; 4677 Register empty_fixed_array = x4;
4681 Register untagged_result = x5; 4678 Register untagged_result = x5;
4682 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, map_reg); 4679 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, map_reg);
4683 __ Pop(result_value); 4680 __ Pop(result_value);
4684 __ LoadRoot(boolean_done, 4681 __ LoadRoot(boolean_done,
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
4895 } 4892 }
4896 4893
4897 return INTERRUPT; 4894 return INTERRUPT;
4898 } 4895 }
4899 4896
4900 4897
4901 } // namespace internal 4898 } // namespace internal
4902 } // namespace v8 4899 } // namespace v8
4903 4900
4904 #endif // V8_TARGET_ARCH_ARM64 4901 #endif // V8_TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698