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

Side by Side Diff: src/full-codegen/mips64/full-codegen-mips64.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_MIPS64 5 #if V8_TARGET_ARCH_MIPS64
6 6
7 // Note on Mips implementation: 7 // Note on Mips implementation:
8 // 8 //
9 // The result_register() for mips is the 'v0' register, which is defined 9 // The result_register() for mips is the 'v0' register, which is defined
10 // by the ABI to contain function return values. However, the first 10 // by the ABI to contain function return values. However, the first
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 { Comment cmnt(masm_, "[ Allocate locals"); 144 { Comment cmnt(masm_, "[ Allocate locals");
145 int locals_count = info->scope()->num_stack_slots(); 145 int locals_count = info->scope()->num_stack_slots();
146 // Generators allocate locals, if any, in context slots. 146 // Generators allocate locals, if any, in context slots.
147 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0); 147 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0);
148 if (locals_count > 0) { 148 if (locals_count > 0) {
149 if (locals_count >= 128) { 149 if (locals_count >= 128) {
150 Label ok; 150 Label ok;
151 __ Dsubu(t1, sp, Operand(locals_count * kPointerSize)); 151 __ Dsubu(t1, sp, Operand(locals_count * kPointerSize));
152 __ LoadRoot(a2, Heap::kRealStackLimitRootIndex); 152 __ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
153 __ Branch(&ok, hs, t1, Operand(a2)); 153 __ Branch(&ok, hs, t1, Operand(a2));
154 __ CallRuntime(Runtime::kThrowStackOverflow, 0); 154 __ CallRuntime(Runtime::kThrowStackOverflow);
155 __ bind(&ok); 155 __ bind(&ok);
156 } 156 }
157 __ LoadRoot(t1, Heap::kUndefinedValueRootIndex); 157 __ LoadRoot(t1, Heap::kUndefinedValueRootIndex);
158 int kMaxPushes = FLAG_optimize_for_size ? 4 : 32; 158 int kMaxPushes = FLAG_optimize_for_size ? 4 : 32;
159 if (locals_count >= kMaxPushes) { 159 if (locals_count >= kMaxPushes) {
160 int loop_iterations = locals_count / kMaxPushes; 160 int loop_iterations = locals_count / kMaxPushes;
161 __ li(a2, Operand(loop_iterations)); 161 __ li(a2, Operand(loop_iterations));
162 Label loop_header; 162 Label loop_header;
163 __ bind(&loop_header); 163 __ bind(&loop_header);
164 // Do pushes. 164 // Do pushes.
(...skipping 18 matching lines...) Expand all
183 183
184 // Possibly allocate a local context. 184 // Possibly allocate a local context.
185 if (info->scope()->num_heap_slots() > 0) { 185 if (info->scope()->num_heap_slots() > 0) {
186 Comment cmnt(masm_, "[ Allocate context"); 186 Comment cmnt(masm_, "[ Allocate context");
187 // Argument to NewContext is the function, which is still in a1. 187 // Argument to NewContext is the function, which is still in a1.
188 bool need_write_barrier = true; 188 bool need_write_barrier = true;
189 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 189 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
190 if (info->scope()->is_script_scope()) { 190 if (info->scope()->is_script_scope()) {
191 __ push(a1); 191 __ push(a1);
192 __ Push(info->scope()->GetScopeInfo(info->isolate())); 192 __ Push(info->scope()->GetScopeInfo(info->isolate()));
193 __ CallRuntime(Runtime::kNewScriptContext, 2); 193 __ CallRuntime(Runtime::kNewScriptContext);
194 PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG); 194 PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG);
195 // The new target value is not used, clobbering is safe. 195 // The new target value is not used, clobbering is safe.
196 DCHECK_NULL(info->scope()->new_target_var()); 196 DCHECK_NULL(info->scope()->new_target_var());
197 } else { 197 } else {
198 if (info->scope()->new_target_var() != nullptr) { 198 if (info->scope()->new_target_var() != nullptr) {
199 __ push(a3); // Preserve new target. 199 __ push(a3); // Preserve new target.
200 } 200 }
201 if (slots <= FastNewContextStub::kMaximumSlots) { 201 if (slots <= FastNewContextStub::kMaximumSlots) {
202 FastNewContextStub stub(isolate(), slots); 202 FastNewContextStub stub(isolate(), slots);
203 __ CallStub(&stub); 203 __ CallStub(&stub);
204 // Result of FastNewContextStub is always in new space. 204 // Result of FastNewContextStub is always in new space.
205 need_write_barrier = false; 205 need_write_barrier = false;
206 } else { 206 } else {
207 __ push(a1); 207 __ push(a1);
208 __ CallRuntime(Runtime::kNewFunctionContext, 1); 208 __ CallRuntime(Runtime::kNewFunctionContext);
209 } 209 }
210 if (info->scope()->new_target_var() != nullptr) { 210 if (info->scope()->new_target_var() != nullptr) {
211 __ pop(a3); // Restore new target. 211 __ pop(a3); // Restore new target.
212 } 212 }
213 } 213 }
214 function_in_register_a1 = false; 214 function_in_register_a1 = false;
215 // Context is returned in v0. It replaces the context passed to us. 215 // Context is returned in v0. It replaces the context passed to us.
216 // It's saved in the stack and kept live in cp. 216 // It's saved in the stack and kept live in cp.
217 __ mov(cp, v0); 217 __ mov(cp, v0);
218 __ sd(v0, MemOperand(fp, StandardFrameConstants::kContextOffset)); 218 __ sd(v0, MemOperand(fp, StandardFrameConstants::kContextOffset));
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 bool is_unmapped = is_strict(language_mode()) || !has_simple_parameters(); 313 bool is_unmapped = is_strict(language_mode()) || !has_simple_parameters();
314 ArgumentsAccessStub::Type type = ArgumentsAccessStub::ComputeType( 314 ArgumentsAccessStub::Type type = ArgumentsAccessStub::ComputeType(
315 is_unmapped, literal()->has_duplicate_parameters()); 315 is_unmapped, literal()->has_duplicate_parameters());
316 ArgumentsAccessStub stub(isolate(), type); 316 ArgumentsAccessStub stub(isolate(), type);
317 __ CallStub(&stub); 317 __ CallStub(&stub);
318 318
319 SetVar(arguments, v0, a1, a2); 319 SetVar(arguments, v0, a1, a2);
320 } 320 }
321 321
322 if (FLAG_trace) { 322 if (FLAG_trace) {
323 __ CallRuntime(Runtime::kTraceEnter, 0); 323 __ CallRuntime(Runtime::kTraceEnter);
324 } 324 }
325 325
326 // Visit the declarations and body unless there is an illegal 326 // Visit the declarations and body unless there is an illegal
327 // redeclaration. 327 // redeclaration.
328 if (scope()->HasIllegalRedeclaration()) { 328 if (scope()->HasIllegalRedeclaration()) {
329 Comment cmnt(masm_, "[ Declarations"); 329 Comment cmnt(masm_, "[ Declarations");
330 VisitForEffect(scope()->GetIllegalRedeclaration()); 330 VisitForEffect(scope()->GetIllegalRedeclaration());
331 331
332 } else { 332 } else {
333 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); 333 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 void FullCodeGenerator::EmitReturnSequence() { 433 void FullCodeGenerator::EmitReturnSequence() {
434 Comment cmnt(masm_, "[ Return sequence"); 434 Comment cmnt(masm_, "[ Return sequence");
435 if (return_label_.is_bound()) { 435 if (return_label_.is_bound()) {
436 __ Branch(&return_label_); 436 __ Branch(&return_label_);
437 } else { 437 } else {
438 __ bind(&return_label_); 438 __ bind(&return_label_);
439 if (FLAG_trace) { 439 if (FLAG_trace) {
440 // Push the return value on the stack as the parameter. 440 // Push the return value on the stack as the parameter.
441 // Runtime::TraceExit returns its parameter in v0. 441 // Runtime::TraceExit returns its parameter in v0.
442 __ push(v0); 442 __ push(v0);
443 __ CallRuntime(Runtime::kTraceExit, 1); 443 __ CallRuntime(Runtime::kTraceExit);
444 } 444 }
445 // Pretend that the exit is a backwards jump to the entry. 445 // Pretend that the exit is a backwards jump to the entry.
446 int weight = 1; 446 int weight = 1;
447 if (info_->ShouldSelfOptimize()) { 447 if (info_->ShouldSelfOptimize()) {
448 weight = FLAG_interrupt_budget / FLAG_self_opt_count; 448 weight = FLAG_interrupt_budget / FLAG_self_opt_count;
449 } else { 449 } else {
450 int distance = masm_->pc_offset(); 450 int distance = masm_->pc_offset();
451 weight = Min(kMaxBackEdgeWeight, 451 weight = Min(kMaxBackEdgeWeight,
452 Max(1, distance / kCodeSizeMultiplier)); 452 Max(1, distance / kCodeSizeMultiplier));
453 } 453 }
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
843 // 'undefined') because we may have a (legal) redeclaration and we 843 // 'undefined') because we may have a (legal) redeclaration and we
844 // must not destroy the current value. 844 // must not destroy the current value.
845 if (hole_init) { 845 if (hole_init) {
846 __ LoadRoot(a0, Heap::kTheHoleValueRootIndex); 846 __ LoadRoot(a0, Heap::kTheHoleValueRootIndex);
847 } else { 847 } else {
848 DCHECK(Smi::FromInt(0) == 0); 848 DCHECK(Smi::FromInt(0) == 0);
849 __ mov(a0, zero_reg); // Smi::FromInt(0) indicates no initial value. 849 __ mov(a0, zero_reg); // Smi::FromInt(0) indicates no initial value.
850 } 850 }
851 __ Push(a2, a0); 851 __ Push(a2, a0);
852 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); 852 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes()));
853 __ CallRuntime(Runtime::kDeclareLookupSlot, 3); 853 __ CallRuntime(Runtime::kDeclareLookupSlot);
854 break; 854 break;
855 } 855 }
856 } 856 }
857 } 857 }
858 858
859 859
860 void FullCodeGenerator::VisitFunctionDeclaration( 860 void FullCodeGenerator::VisitFunctionDeclaration(
861 FunctionDeclaration* declaration) { 861 FunctionDeclaration* declaration) {
862 VariableProxy* proxy = declaration->proxy(); 862 VariableProxy* proxy = declaration->proxy();
863 Variable* variable = proxy->var(); 863 Variable* variable = proxy->var();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
900 break; 900 break;
901 } 901 }
902 902
903 case VariableLocation::LOOKUP: { 903 case VariableLocation::LOOKUP: {
904 Comment cmnt(masm_, "[ FunctionDeclaration"); 904 Comment cmnt(masm_, "[ FunctionDeclaration");
905 __ li(a2, Operand(variable->name())); 905 __ li(a2, Operand(variable->name()));
906 __ Push(a2); 906 __ Push(a2);
907 // Push initial value for function declaration. 907 // Push initial value for function declaration.
908 VisitForStackValue(declaration->fun()); 908 VisitForStackValue(declaration->fun());
909 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); 909 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes()));
910 __ CallRuntime(Runtime::kDeclareLookupSlot, 3); 910 __ CallRuntime(Runtime::kDeclareLookupSlot);
911 break; 911 break;
912 } 912 }
913 } 913 }
914 } 914 }
915 915
916 916
917 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 917 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
918 // Call the runtime to declare the globals. 918 // Call the runtime to declare the globals.
919 __ li(a1, Operand(pairs)); 919 __ li(a1, Operand(pairs));
920 __ li(a0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); 920 __ li(a0, Operand(Smi::FromInt(DeclareGlobalsFlags())));
921 __ Push(a1, a0); 921 __ Push(a1, a0);
922 __ CallRuntime(Runtime::kDeclareGlobals, 2); 922 __ CallRuntime(Runtime::kDeclareGlobals);
923 // Return value is ignored. 923 // Return value is ignored.
924 } 924 }
925 925
926 926
927 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) { 927 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) {
928 // Call the runtime to declare the modules. 928 // Call the runtime to declare the modules.
929 __ Push(descriptions); 929 __ Push(descriptions);
930 __ CallRuntime(Runtime::kDeclareModules, 1); 930 __ CallRuntime(Runtime::kDeclareModules);
931 // Return value is ignored. 931 // Return value is ignored.
932 } 932 }
933 933
934 934
935 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 935 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
936 Comment cmnt(masm_, "[ SwitchStatement"); 936 Comment cmnt(masm_, "[ SwitchStatement");
937 Breakable nested_statement(this, stmt); 937 Breakable nested_statement(this, stmt);
938 SetStatementPosition(stmt); 938 SetStatementPosition(stmt);
939 939
940 // Keep the switch value on the stack until a case matches. 940 // Keep the switch value on the stack until a case matches.
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1073 1073
1074 // The enum cache is valid. Load the map of the object being 1074 // The enum cache is valid. Load the map of the object being
1075 // iterated over and use the cache for the iteration. 1075 // iterated over and use the cache for the iteration.
1076 Label use_cache; 1076 Label use_cache;
1077 __ ld(v0, FieldMemOperand(a0, HeapObject::kMapOffset)); 1077 __ ld(v0, FieldMemOperand(a0, HeapObject::kMapOffset));
1078 __ Branch(&use_cache); 1078 __ Branch(&use_cache);
1079 1079
1080 // Get the set of properties to enumerate. 1080 // Get the set of properties to enumerate.
1081 __ bind(&call_runtime); 1081 __ bind(&call_runtime);
1082 __ push(a0); // Duplicate the enumerable object on the stack. 1082 __ push(a0); // Duplicate the enumerable object on the stack.
1083 __ CallRuntime(Runtime::kGetPropertyNamesFast, 1); 1083 __ CallRuntime(Runtime::kGetPropertyNamesFast);
1084 PrepareForBailoutForId(stmt->EnumId(), TOS_REG); 1084 PrepareForBailoutForId(stmt->EnumId(), TOS_REG);
1085 1085
1086 // If we got a map from the runtime call, we can do a fast 1086 // If we got a map from the runtime call, we can do a fast
1087 // modification check. Otherwise, we got a fixed array, and we have 1087 // modification check. Otherwise, we got a fixed array, and we have
1088 // to do a slow check. 1088 // to do a slow check.
1089 Label fixed_array; 1089 Label fixed_array;
1090 __ ld(a2, FieldMemOperand(v0, HeapObject::kMapOffset)); 1090 __ ld(a2, FieldMemOperand(v0, HeapObject::kMapOffset));
1091 __ LoadRoot(at, Heap::kMetaMapRootIndex); 1091 __ LoadRoot(at, Heap::kMetaMapRootIndex);
1092 __ Branch(&fixed_array, ne, a2, Operand(at)); 1092 __ Branch(&fixed_array, ne, a2, Operand(at));
1093 1093
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1150 // If not, we may have to filter the key. 1150 // If not, we may have to filter the key.
1151 Label update_each; 1151 Label update_each;
1152 __ ld(a1, MemOperand(sp, 4 * kPointerSize)); 1152 __ ld(a1, MemOperand(sp, 4 * kPointerSize));
1153 __ ld(a4, FieldMemOperand(a1, HeapObject::kMapOffset)); 1153 __ ld(a4, FieldMemOperand(a1, HeapObject::kMapOffset));
1154 __ Branch(&update_each, eq, a4, Operand(a2)); 1154 __ Branch(&update_each, eq, a4, Operand(a2));
1155 1155
1156 // Convert the entry to a string or (smi) 0 if it isn't a property 1156 // Convert the entry to a string or (smi) 0 if it isn't a property
1157 // any more. If the property has been removed while iterating, we 1157 // any more. If the property has been removed while iterating, we
1158 // just skip it. 1158 // just skip it.
1159 __ Push(a1, a3); // Enumerable and current entry. 1159 __ Push(a1, a3); // Enumerable and current entry.
1160 __ CallRuntime(Runtime::kForInFilter, 2); 1160 __ CallRuntime(Runtime::kForInFilter);
1161 PrepareForBailoutForId(stmt->FilterId(), TOS_REG); 1161 PrepareForBailoutForId(stmt->FilterId(), TOS_REG);
1162 __ mov(a3, result_register()); 1162 __ mov(a3, result_register());
1163 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 1163 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
1164 __ Branch(loop_statement.continue_label(), eq, a3, Operand(at)); 1164 __ Branch(loop_statement.continue_label(), eq, a3, Operand(at));
1165 1165
1166 // Update the 'each' property or variable from the possibly filtered 1166 // Update the 'each' property or variable from the possibly filtered
1167 // entry in register a3. 1167 // entry in register a3.
1168 __ bind(&update_each); 1168 __ bind(&update_each);
1169 __ mov(result_register(), a3); 1169 __ mov(result_register(), a3);
1170 // Perform the assignment as if via '='. 1170 // Perform the assignment as if via '='.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1210 if (!FLAG_always_opt && 1210 if (!FLAG_always_opt &&
1211 !FLAG_prepare_always_opt && 1211 !FLAG_prepare_always_opt &&
1212 !pretenure && 1212 !pretenure &&
1213 scope()->is_function_scope() && 1213 scope()->is_function_scope() &&
1214 info->num_literals() == 0) { 1214 info->num_literals() == 0) {
1215 FastNewClosureStub stub(isolate(), info->language_mode(), info->kind()); 1215 FastNewClosureStub stub(isolate(), info->language_mode(), info->kind());
1216 __ li(a2, Operand(info)); 1216 __ li(a2, Operand(info));
1217 __ CallStub(&stub); 1217 __ CallStub(&stub);
1218 } else { 1218 } else {
1219 __ Push(info); 1219 __ Push(info);
1220 __ CallRuntime( 1220 __ CallRuntime(pretenure ? Runtime::kNewClosure_Tenured
1221 pretenure ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure, 1); 1221 : Runtime::kNewClosure);
1222 } 1222 }
1223 context()->Plug(v0); 1223 context()->Plug(v0);
1224 } 1224 }
1225 1225
1226 1226
1227 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, 1227 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset,
1228 FeedbackVectorSlot slot) { 1228 FeedbackVectorSlot slot) {
1229 DCHECK(NeedsHomeObject(initializer)); 1229 DCHECK(NeedsHomeObject(initializer));
1230 __ ld(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); 1230 __ ld(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
1231 __ li(StoreDescriptor::NameRegister(), 1231 __ li(StoreDescriptor::NameRegister(),
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1351 local->mode() == CONST_LEGACY) { 1351 local->mode() == CONST_LEGACY) {
1352 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 1352 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
1353 __ dsubu(at, v0, at); // Sub as compare: at == 0 on eq. 1353 __ dsubu(at, v0, at); // Sub as compare: at == 0 on eq.
1354 if (local->mode() == CONST_LEGACY) { 1354 if (local->mode() == CONST_LEGACY) {
1355 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); 1355 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
1356 __ Movz(v0, a0, at); // Conditional move: return Undefined if TheHole. 1356 __ Movz(v0, a0, at); // Conditional move: return Undefined if TheHole.
1357 } else { // LET || CONST 1357 } else { // LET || CONST
1358 __ Branch(done, ne, at, Operand(zero_reg)); 1358 __ Branch(done, ne, at, Operand(zero_reg));
1359 __ li(a0, Operand(var->name())); 1359 __ li(a0, Operand(var->name()));
1360 __ push(a0); 1360 __ push(a0);
1361 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1361 __ CallRuntime(Runtime::kThrowReferenceError);
1362 } 1362 }
1363 } 1363 }
1364 __ Branch(done); 1364 __ Branch(done);
1365 } 1365 }
1366 } 1366 }
1367 1367
1368 1368
1369 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, 1369 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
1370 TypeofMode typeof_mode) { 1370 TypeofMode typeof_mode) {
1371 Variable* var = proxy->var(); 1371 Variable* var = proxy->var();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1408 GetVar(v0, var); 1408 GetVar(v0, var);
1409 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 1409 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
1410 __ dsubu(at, v0, at); // Sub as compare: at == 0 on eq. 1410 __ dsubu(at, v0, at); // Sub as compare: at == 0 on eq.
1411 if (var->mode() == LET || var->mode() == CONST) { 1411 if (var->mode() == LET || var->mode() == CONST) {
1412 // Throw a reference error when using an uninitialized let/const 1412 // Throw a reference error when using an uninitialized let/const
1413 // binding in harmony mode. 1413 // binding in harmony mode.
1414 Label done; 1414 Label done;
1415 __ Branch(&done, ne, at, Operand(zero_reg)); 1415 __ Branch(&done, ne, at, Operand(zero_reg));
1416 __ li(a0, Operand(var->name())); 1416 __ li(a0, Operand(var->name()));
1417 __ push(a0); 1417 __ push(a0);
1418 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1418 __ CallRuntime(Runtime::kThrowReferenceError);
1419 __ bind(&done); 1419 __ bind(&done);
1420 } else { 1420 } else {
1421 // Uninitialized legacy const bindings are unholed. 1421 // Uninitialized legacy const bindings are unholed.
1422 DCHECK(var->mode() == CONST_LEGACY); 1422 DCHECK(var->mode() == CONST_LEGACY);
1423 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); 1423 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
1424 __ Movz(v0, a0, at); // Conditional move: Undefined if TheHole. 1424 __ Movz(v0, a0, at); // Conditional move: Undefined if TheHole.
1425 } 1425 }
1426 context()->Plug(v0); 1426 context()->Plug(v0);
1427 break; 1427 break;
1428 } 1428 }
1429 context()->Plug(var); 1429 context()->Plug(var);
1430 break; 1430 break;
1431 } 1431 }
1432 1432
1433 case VariableLocation::LOOKUP: { 1433 case VariableLocation::LOOKUP: {
1434 Comment cmnt(masm_, "[ Lookup variable"); 1434 Comment cmnt(masm_, "[ Lookup variable");
1435 Label done, slow; 1435 Label done, slow;
1436 // Generate code for loading from variables potentially shadowed 1436 // Generate code for loading from variables potentially shadowed
1437 // by eval-introduced variables. 1437 // by eval-introduced variables.
1438 EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done); 1438 EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
1439 __ bind(&slow); 1439 __ bind(&slow);
1440 __ li(a1, Operand(var->name())); 1440 __ li(a1, Operand(var->name()));
1441 __ Push(cp, a1); // Context and name. 1441 __ Push(cp, a1); // Context and name.
1442 Runtime::FunctionId function_id = 1442 Runtime::FunctionId function_id =
1443 typeof_mode == NOT_INSIDE_TYPEOF 1443 typeof_mode == NOT_INSIDE_TYPEOF
1444 ? Runtime::kLoadLookupSlot 1444 ? Runtime::kLoadLookupSlot
1445 : Runtime::kLoadLookupSlotNoReferenceError; 1445 : Runtime::kLoadLookupSlotNoReferenceError;
1446 __ CallRuntime(function_id, 2); 1446 __ CallRuntime(function_id);
1447 __ bind(&done); 1447 __ bind(&done);
1448 context()->Plug(v0); 1448 context()->Plug(v0);
1449 } 1449 }
1450 } 1450 }
1451 } 1451 }
1452 1452
1453 1453
1454 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1454 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1455 Comment cmnt(masm_, "[ RegExpLiteral"); 1455 Comment cmnt(masm_, "[ RegExpLiteral");
1456 __ ld(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 1456 __ ld(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
(...skipping 26 matching lines...) Expand all
1483 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { 1483 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
1484 Comment cmnt(masm_, "[ ObjectLiteral"); 1484 Comment cmnt(masm_, "[ ObjectLiteral");
1485 1485
1486 Handle<FixedArray> constant_properties = expr->constant_properties(); 1486 Handle<FixedArray> constant_properties = expr->constant_properties();
1487 __ ld(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 1487 __ ld(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1488 __ li(a2, Operand(Smi::FromInt(expr->literal_index()))); 1488 __ li(a2, Operand(Smi::FromInt(expr->literal_index())));
1489 __ li(a1, Operand(constant_properties)); 1489 __ li(a1, Operand(constant_properties));
1490 __ li(a0, Operand(Smi::FromInt(expr->ComputeFlags()))); 1490 __ li(a0, Operand(Smi::FromInt(expr->ComputeFlags())));
1491 if (MustCreateObjectLiteralWithRuntime(expr)) { 1491 if (MustCreateObjectLiteralWithRuntime(expr)) {
1492 __ Push(a3, a2, a1, a0); 1492 __ Push(a3, a2, a1, a0);
1493 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); 1493 __ CallRuntime(Runtime::kCreateObjectLiteral);
1494 } else { 1494 } else {
1495 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); 1495 FastCloneShallowObjectStub stub(isolate(), expr->properties_count());
1496 __ CallStub(&stub); 1496 __ CallStub(&stub);
1497 } 1497 }
1498 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1498 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
1499 1499
1500 // If result_saved is true the result is on top of the stack. If 1500 // If result_saved is true the result is on top of the stack. If
1501 // result_saved is false the result is in v0. 1501 // result_saved is false the result is in v0.
1502 bool result_saved = false; 1502 bool result_saved = false;
1503 1503
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1546 __ ld(a0, MemOperand(sp)); 1546 __ ld(a0, MemOperand(sp));
1547 __ push(a0); 1547 __ push(a0);
1548 VisitForStackValue(key); 1548 VisitForStackValue(key);
1549 VisitForStackValue(value); 1549 VisitForStackValue(value);
1550 if (property->emit_store()) { 1550 if (property->emit_store()) {
1551 if (NeedsHomeObject(value)) { 1551 if (NeedsHomeObject(value)) {
1552 EmitSetHomeObject(value, 2, property->GetSlot()); 1552 EmitSetHomeObject(value, 2, property->GetSlot());
1553 } 1553 }
1554 __ li(a0, Operand(Smi::FromInt(SLOPPY))); // PropertyAttributes. 1554 __ li(a0, Operand(Smi::FromInt(SLOPPY))); // PropertyAttributes.
1555 __ push(a0); 1555 __ push(a0);
1556 __ CallRuntime(Runtime::kSetProperty, 4); 1556 __ CallRuntime(Runtime::kSetProperty);
1557 } else { 1557 } else {
1558 __ Drop(3); 1558 __ Drop(3);
1559 } 1559 }
1560 break; 1560 break;
1561 case ObjectLiteral::Property::PROTOTYPE: 1561 case ObjectLiteral::Property::PROTOTYPE:
1562 // Duplicate receiver on stack. 1562 // Duplicate receiver on stack.
1563 __ ld(a0, MemOperand(sp)); 1563 __ ld(a0, MemOperand(sp));
1564 __ push(a0); 1564 __ push(a0);
1565 VisitForStackValue(value); 1565 VisitForStackValue(value);
1566 DCHECK(property->emit_store()); 1566 DCHECK(property->emit_store());
1567 __ CallRuntime(Runtime::kInternalSetPrototype, 2); 1567 __ CallRuntime(Runtime::kInternalSetPrototype);
1568 break; 1568 break;
1569 case ObjectLiteral::Property::GETTER: 1569 case ObjectLiteral::Property::GETTER:
1570 if (property->emit_store()) { 1570 if (property->emit_store()) {
1571 accessor_table.lookup(key)->second->getter = property; 1571 accessor_table.lookup(key)->second->getter = property;
1572 } 1572 }
1573 break; 1573 break;
1574 case ObjectLiteral::Property::SETTER: 1574 case ObjectLiteral::Property::SETTER:
1575 if (property->emit_store()) { 1575 if (property->emit_store()) {
1576 accessor_table.lookup(key)->second->setter = property; 1576 accessor_table.lookup(key)->second->setter = property;
1577 } 1577 }
1578 break; 1578 break;
1579 } 1579 }
1580 } 1580 }
1581 1581
1582 // Emit code to define accessors, using only a single call to the runtime for 1582 // Emit code to define accessors, using only a single call to the runtime for
1583 // each pair of corresponding getters and setters. 1583 // each pair of corresponding getters and setters.
1584 for (AccessorTable::Iterator it = accessor_table.begin(); 1584 for (AccessorTable::Iterator it = accessor_table.begin();
1585 it != accessor_table.end(); 1585 it != accessor_table.end();
1586 ++it) { 1586 ++it) {
1587 __ ld(a0, MemOperand(sp)); // Duplicate receiver. 1587 __ ld(a0, MemOperand(sp)); // Duplicate receiver.
1588 __ push(a0); 1588 __ push(a0);
1589 VisitForStackValue(it->first); 1589 VisitForStackValue(it->first);
1590 EmitAccessor(it->second->getter); 1590 EmitAccessor(it->second->getter);
1591 EmitAccessor(it->second->setter); 1591 EmitAccessor(it->second->setter);
1592 __ li(a0, Operand(Smi::FromInt(NONE))); 1592 __ li(a0, Operand(Smi::FromInt(NONE)));
1593 __ push(a0); 1593 __ push(a0);
1594 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); 1594 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked);
1595 } 1595 }
1596 1596
1597 // Object literals have two parts. The "static" part on the left contains no 1597 // Object literals have two parts. The "static" part on the left contains no
1598 // computed property names, and so we can compute its map ahead of time; see 1598 // computed property names, and so we can compute its map ahead of time; see
1599 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part 1599 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part
1600 // starts with the first computed property name, and continues with all 1600 // starts with the first computed property name, and continues with all
1601 // properties to its right. All the code from above initializes the static 1601 // properties to its right. All the code from above initializes the static
1602 // component of the object literal, and arranges for the map of the result to 1602 // component of the object literal, and arranges for the map of the result to
1603 // reflect the static order in which the keys appear. For the dynamic 1603 // reflect the static order in which the keys appear. For the dynamic
1604 // properties, we compile them into a series of "SetOwnProperty" runtime 1604 // properties, we compile them into a series of "SetOwnProperty" runtime
1605 // calls. This will preserve insertion order. 1605 // calls. This will preserve insertion order.
1606 for (; property_index < expr->properties()->length(); property_index++) { 1606 for (; property_index < expr->properties()->length(); property_index++) {
1607 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1607 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1608 1608
1609 Expression* value = property->value(); 1609 Expression* value = property->value();
1610 if (!result_saved) { 1610 if (!result_saved) {
1611 __ push(v0); // Save result on the stack 1611 __ push(v0); // Save result on the stack
1612 result_saved = true; 1612 result_saved = true;
1613 } 1613 }
1614 1614
1615 __ ld(a0, MemOperand(sp)); // Duplicate receiver. 1615 __ ld(a0, MemOperand(sp)); // Duplicate receiver.
1616 __ push(a0); 1616 __ push(a0);
1617 1617
1618 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1618 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1619 DCHECK(!property->is_computed_name()); 1619 DCHECK(!property->is_computed_name());
1620 VisitForStackValue(value); 1620 VisitForStackValue(value);
1621 DCHECK(property->emit_store()); 1621 DCHECK(property->emit_store());
1622 __ CallRuntime(Runtime::kInternalSetPrototype, 2); 1622 __ CallRuntime(Runtime::kInternalSetPrototype);
1623 } else { 1623 } else {
1624 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); 1624 EmitPropertyKey(property, expr->GetIdForProperty(property_index));
1625 VisitForStackValue(value); 1625 VisitForStackValue(value);
1626 if (NeedsHomeObject(value)) { 1626 if (NeedsHomeObject(value)) {
1627 EmitSetHomeObject(value, 2, property->GetSlot()); 1627 EmitSetHomeObject(value, 2, property->GetSlot());
1628 } 1628 }
1629 1629
1630 switch (property->kind()) { 1630 switch (property->kind()) {
1631 case ObjectLiteral::Property::CONSTANT: 1631 case ObjectLiteral::Property::CONSTANT:
1632 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1632 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1633 case ObjectLiteral::Property::COMPUTED: 1633 case ObjectLiteral::Property::COMPUTED:
1634 if (property->emit_store()) { 1634 if (property->emit_store()) {
1635 __ li(a0, Operand(Smi::FromInt(NONE))); 1635 __ li(a0, Operand(Smi::FromInt(NONE)));
1636 __ push(a0); 1636 __ push(a0);
1637 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); 1637 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked);
1638 } else { 1638 } else {
1639 __ Drop(3); 1639 __ Drop(3);
1640 } 1640 }
1641 break; 1641 break;
1642 1642
1643 case ObjectLiteral::Property::PROTOTYPE: 1643 case ObjectLiteral::Property::PROTOTYPE:
1644 UNREACHABLE(); 1644 UNREACHABLE();
1645 break; 1645 break;
1646 1646
1647 case ObjectLiteral::Property::GETTER: 1647 case ObjectLiteral::Property::GETTER:
1648 __ li(a0, Operand(Smi::FromInt(NONE))); 1648 __ li(a0, Operand(Smi::FromInt(NONE)));
1649 __ push(a0); 1649 __ push(a0);
1650 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 4); 1650 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
1651 break; 1651 break;
1652 1652
1653 case ObjectLiteral::Property::SETTER: 1653 case ObjectLiteral::Property::SETTER:
1654 __ li(a0, Operand(Smi::FromInt(NONE))); 1654 __ li(a0, Operand(Smi::FromInt(NONE)));
1655 __ push(a0); 1655 __ push(a0);
1656 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 4); 1656 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
1657 break; 1657 break;
1658 } 1658 }
1659 } 1659 }
1660 } 1660 }
1661 1661
1662 if (expr->has_function()) { 1662 if (expr->has_function()) {
1663 DCHECK(result_saved); 1663 DCHECK(result_saved);
1664 __ ld(a0, MemOperand(sp)); 1664 __ ld(a0, MemOperand(sp));
1665 __ push(a0); 1665 __ push(a0);
1666 __ CallRuntime(Runtime::kToFastProperties, 1); 1666 __ CallRuntime(Runtime::kToFastProperties);
1667 } 1667 }
1668 1668
1669 if (result_saved) { 1669 if (result_saved) {
1670 context()->PlugTOS(); 1670 context()->PlugTOS();
1671 } else { 1671 } else {
1672 context()->Plug(v0); 1672 context()->Plug(v0);
1673 } 1673 }
1674 } 1674 }
1675 1675
1676 1676
(...skipping 11 matching lines...) Expand all
1688 allocation_site_mode = DONT_TRACK_ALLOCATION_SITE; 1688 allocation_site_mode = DONT_TRACK_ALLOCATION_SITE;
1689 } 1689 }
1690 1690
1691 __ mov(a0, result_register()); 1691 __ mov(a0, result_register());
1692 __ ld(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 1692 __ ld(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1693 __ li(a2, Operand(Smi::FromInt(expr->literal_index()))); 1693 __ li(a2, Operand(Smi::FromInt(expr->literal_index())));
1694 __ li(a1, Operand(constant_elements)); 1694 __ li(a1, Operand(constant_elements));
1695 if (MustCreateArrayLiteralWithRuntime(expr)) { 1695 if (MustCreateArrayLiteralWithRuntime(expr)) {
1696 __ li(a0, Operand(Smi::FromInt(expr->ComputeFlags()))); 1696 __ li(a0, Operand(Smi::FromInt(expr->ComputeFlags())));
1697 __ Push(a3, a2, a1, a0); 1697 __ Push(a3, a2, a1, a0);
1698 __ CallRuntime(Runtime::kCreateArrayLiteral, 4); 1698 __ CallRuntime(Runtime::kCreateArrayLiteral);
1699 } else { 1699 } else {
1700 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); 1700 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode);
1701 __ CallStub(&stub); 1701 __ CallStub(&stub);
1702 } 1702 }
1703 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1703 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
1704 1704
1705 bool result_saved = false; // Is the result saved to the stack? 1705 bool result_saved = false; // Is the result saved to the stack?
1706 ZoneList<Expression*>* subexprs = expr->values(); 1706 ZoneList<Expression*>* subexprs = expr->values();
1707 int length = subexprs->length(); 1707 int length = subexprs->length();
1708 1708
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1747 for (; array_index < length; array_index++) { 1747 for (; array_index < length; array_index++) {
1748 Expression* subexpr = subexprs->at(array_index); 1748 Expression* subexpr = subexprs->at(array_index);
1749 1749
1750 __ Push(v0); 1750 __ Push(v0);
1751 if (subexpr->IsSpread()) { 1751 if (subexpr->IsSpread()) {
1752 VisitForStackValue(subexpr->AsSpread()->expression()); 1752 VisitForStackValue(subexpr->AsSpread()->expression());
1753 __ InvokeBuiltin(Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX, 1753 __ InvokeBuiltin(Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX,
1754 CALL_FUNCTION); 1754 CALL_FUNCTION);
1755 } else { 1755 } else {
1756 VisitForStackValue(subexpr); 1756 VisitForStackValue(subexpr);
1757 __ CallRuntime(Runtime::kAppendElement, 2); 1757 __ CallRuntime(Runtime::kAppendElement);
1758 } 1758 }
1759 1759
1760 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1760 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1761 } 1761 }
1762 1762
1763 if (result_saved) { 1763 if (result_saved) {
1764 context()->PlugTOS(); 1764 context()->PlugTOS();
1765 } else { 1765 } else {
1766 context()->Plug(v0); 1766 context()->Plug(v0);
1767 } 1767 }
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
2152 Label push_operand_holes, call_resume; 2152 Label push_operand_holes, call_resume;
2153 __ bind(&push_operand_holes); 2153 __ bind(&push_operand_holes);
2154 __ Dsubu(a3, a3, Operand(1)); 2154 __ Dsubu(a3, a3, Operand(1));
2155 __ Branch(&call_resume, lt, a3, Operand(zero_reg)); 2155 __ Branch(&call_resume, lt, a3, Operand(zero_reg));
2156 __ push(a2); 2156 __ push(a2);
2157 __ Branch(&push_operand_holes); 2157 __ Branch(&push_operand_holes);
2158 __ bind(&call_resume); 2158 __ bind(&call_resume);
2159 DCHECK(!result_register().is(a1)); 2159 DCHECK(!result_register().is(a1));
2160 __ Push(a1, result_register()); 2160 __ Push(a1, result_register());
2161 __ Push(Smi::FromInt(resume_mode)); 2161 __ Push(Smi::FromInt(resume_mode));
2162 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); 2162 __ CallRuntime(Runtime::kResumeJSGeneratorObject);
2163 // Not reached: the runtime call returns elsewhere. 2163 // Not reached: the runtime call returns elsewhere.
2164 __ stop("not-reached"); 2164 __ stop("not-reached");
2165 2165
2166 __ bind(&done); 2166 __ bind(&done);
2167 context()->Plug(result_register()); 2167 context()->Plug(result_register());
2168 } 2168 }
2169 2169
2170 2170
2171 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { 2171 void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
2172 Label allocate, done_allocate; 2172 Label allocate, done_allocate;
2173 2173
2174 __ Allocate(JSIteratorResult::kSize, v0, a2, a3, &allocate, TAG_OBJECT); 2174 __ Allocate(JSIteratorResult::kSize, v0, a2, a3, &allocate, TAG_OBJECT);
2175 __ jmp(&done_allocate); 2175 __ jmp(&done_allocate);
2176 2176
2177 __ bind(&allocate); 2177 __ bind(&allocate);
2178 __ Push(Smi::FromInt(JSIteratorResult::kSize)); 2178 __ Push(Smi::FromInt(JSIteratorResult::kSize));
2179 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); 2179 __ CallRuntime(Runtime::kAllocateInNewSpace);
2180 2180
2181 __ bind(&done_allocate); 2181 __ bind(&done_allocate);
2182 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, a1); 2182 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, a1);
2183 __ pop(a2); 2183 __ pop(a2);
2184 __ LoadRoot(a3, 2184 __ LoadRoot(a3,
2185 done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex); 2185 done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex);
2186 __ LoadRoot(a4, Heap::kEmptyFixedArrayRootIndex); 2186 __ LoadRoot(a4, Heap::kEmptyFixedArrayRootIndex);
2187 __ sd(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); 2187 __ sd(a1, FieldMemOperand(v0, HeapObject::kMapOffset));
2188 __ sd(a4, FieldMemOperand(v0, JSObject::kPropertiesOffset)); 2188 __ sd(a4, FieldMemOperand(v0, JSObject::kPropertiesOffset));
2189 __ sd(a4, FieldMemOperand(v0, JSObject::kElementsOffset)); 2189 __ sd(a4, FieldMemOperand(v0, JSObject::kElementsOffset));
(...skipping 18 matching lines...) Expand all
2208 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { 2208 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
2209 // Stack: receiver, home_object. 2209 // Stack: receiver, home_object.
2210 SetExpressionPosition(prop); 2210 SetExpressionPosition(prop);
2211 2211
2212 Literal* key = prop->key()->AsLiteral(); 2212 Literal* key = prop->key()->AsLiteral();
2213 DCHECK(!key->value()->IsSmi()); 2213 DCHECK(!key->value()->IsSmi());
2214 DCHECK(prop->IsSuperAccess()); 2214 DCHECK(prop->IsSuperAccess());
2215 2215
2216 __ Push(key->value()); 2216 __ Push(key->value());
2217 __ Push(Smi::FromInt(language_mode())); 2217 __ Push(Smi::FromInt(language_mode()));
2218 __ CallRuntime(Runtime::kLoadFromSuper, 4); 2218 __ CallRuntime(Runtime::kLoadFromSuper);
2219 } 2219 }
2220 2220
2221 2221
2222 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 2222 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2223 // Call keyed load IC. It has register arguments receiver and key. 2223 // Call keyed load IC. It has register arguments receiver and key.
2224 SetExpressionPosition(prop); 2224 SetExpressionPosition(prop);
2225 2225
2226 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code(); 2226 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
2227 __ li(LoadDescriptor::SlotRegister(), 2227 __ li(LoadDescriptor::SlotRegister(),
2228 Operand(SmiFromSlot(prop->PropertyFeedbackSlot()))); 2228 Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
2229 CallIC(ic); 2229 CallIC(ic);
2230 } 2230 }
2231 2231
2232 2232
2233 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { 2233 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
2234 // Stack: receiver, home_object, key. 2234 // Stack: receiver, home_object, key.
2235 SetExpressionPosition(prop); 2235 SetExpressionPosition(prop);
2236 __ Push(Smi::FromInt(language_mode())); 2236 __ Push(Smi::FromInt(language_mode()));
2237 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4); 2237 __ CallRuntime(Runtime::kLoadKeyedFromSuper);
2238 } 2238 }
2239 2239
2240 2240
2241 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 2241 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
2242 Token::Value op, 2242 Token::Value op,
2243 Expression* left_expr, 2243 Expression* left_expr,
2244 Expression* right_expr) { 2244 Expression* right_expr) {
2245 Label done, smi_case, stub_call; 2245 Label done, smi_case, stub_call;
2246 2246
2247 Register scratch1 = a2; 2247 Register scratch1 = a2;
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
2352 __ ld(scratch, MemOperand(sp, 0)); // prototype 2352 __ ld(scratch, MemOperand(sp, 0)); // prototype
2353 } 2353 }
2354 __ push(scratch); 2354 __ push(scratch);
2355 EmitPropertyKey(property, lit->GetIdForProperty(i)); 2355 EmitPropertyKey(property, lit->GetIdForProperty(i));
2356 2356
2357 // The static prototype property is read only. We handle the non computed 2357 // The static prototype property is read only. We handle the non computed
2358 // property name case in the parser. Since this is the only case where we 2358 // property name case in the parser. Since this is the only case where we
2359 // need to check for an own read only property we special case this so we do 2359 // need to check for an own read only property we special case this so we do
2360 // not need to do this for every property. 2360 // not need to do this for every property.
2361 if (property->is_static() && property->is_computed_name()) { 2361 if (property->is_static() && property->is_computed_name()) {
2362 __ CallRuntime(Runtime::kThrowIfStaticPrototype, 1); 2362 __ CallRuntime(Runtime::kThrowIfStaticPrototype);
2363 __ push(v0); 2363 __ push(v0);
2364 } 2364 }
2365 2365
2366 VisitForStackValue(value); 2366 VisitForStackValue(value);
2367 if (NeedsHomeObject(value)) { 2367 if (NeedsHomeObject(value)) {
2368 EmitSetHomeObject(value, 2, property->GetSlot()); 2368 EmitSetHomeObject(value, 2, property->GetSlot());
2369 } 2369 }
2370 2370
2371 switch (property->kind()) { 2371 switch (property->kind()) {
2372 case ObjectLiteral::Property::CONSTANT: 2372 case ObjectLiteral::Property::CONSTANT:
2373 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 2373 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
2374 case ObjectLiteral::Property::PROTOTYPE: 2374 case ObjectLiteral::Property::PROTOTYPE:
2375 UNREACHABLE(); 2375 UNREACHABLE();
2376 case ObjectLiteral::Property::COMPUTED: 2376 case ObjectLiteral::Property::COMPUTED:
2377 __ CallRuntime(Runtime::kDefineClassMethod, 3); 2377 __ CallRuntime(Runtime::kDefineClassMethod);
2378 break; 2378 break;
2379 2379
2380 case ObjectLiteral::Property::GETTER: 2380 case ObjectLiteral::Property::GETTER:
2381 __ li(a0, Operand(Smi::FromInt(DONT_ENUM))); 2381 __ li(a0, Operand(Smi::FromInt(DONT_ENUM)));
2382 __ push(a0); 2382 __ push(a0);
2383 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 4); 2383 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
2384 break; 2384 break;
2385 2385
2386 case ObjectLiteral::Property::SETTER: 2386 case ObjectLiteral::Property::SETTER:
2387 __ li(a0, Operand(Smi::FromInt(DONT_ENUM))); 2387 __ li(a0, Operand(Smi::FromInt(DONT_ENUM)));
2388 __ push(a0); 2388 __ push(a0);
2389 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 4); 2389 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
2390 break; 2390 break;
2391 2391
2392 default: 2392 default:
2393 UNREACHABLE(); 2393 UNREACHABLE();
2394 } 2394 }
2395 } 2395 }
2396 2396
2397 // Set both the prototype and constructor to have fast properties, and also 2397 // Set both the prototype and constructor to have fast properties, and also
2398 // freeze them in strong mode. 2398 // freeze them in strong mode.
2399 __ CallRuntime(Runtime::kFinalizeClassDefinition, 2); 2399 __ CallRuntime(Runtime::kFinalizeClassDefinition);
2400 } 2400 }
2401 2401
2402 2402
2403 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { 2403 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
2404 __ mov(a0, result_register()); 2404 __ mov(a0, result_register());
2405 __ pop(a1); 2405 __ pop(a1);
2406 Handle<Code> code = 2406 Handle<Code> code =
2407 CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code(); 2407 CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
2408 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 2408 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
2409 CallIC(code, expr->BinaryOperationFeedbackId()); 2409 CallIC(code, expr->BinaryOperationFeedbackId());
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
2519 // Non-initializing assignment to let variable needs a write barrier. 2519 // Non-initializing assignment to let variable needs a write barrier.
2520 DCHECK(!var->IsLookupSlot()); 2520 DCHECK(!var->IsLookupSlot());
2521 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2521 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2522 Label assign; 2522 Label assign;
2523 MemOperand location = VarOperand(var, a1); 2523 MemOperand location = VarOperand(var, a1);
2524 __ ld(a3, location); 2524 __ ld(a3, location);
2525 __ LoadRoot(a4, Heap::kTheHoleValueRootIndex); 2525 __ LoadRoot(a4, Heap::kTheHoleValueRootIndex);
2526 __ Branch(&assign, ne, a3, Operand(a4)); 2526 __ Branch(&assign, ne, a3, Operand(a4));
2527 __ li(a3, Operand(var->name())); 2527 __ li(a3, Operand(var->name()));
2528 __ push(a3); 2528 __ push(a3);
2529 __ CallRuntime(Runtime::kThrowReferenceError, 1); 2529 __ CallRuntime(Runtime::kThrowReferenceError);
2530 // Perform the assignment. 2530 // Perform the assignment.
2531 __ bind(&assign); 2531 __ bind(&assign);
2532 EmitStoreToStackLocalOrContextSlot(var, location); 2532 EmitStoreToStackLocalOrContextSlot(var, location);
2533 2533
2534 } else if (var->mode() == CONST && op != Token::INIT) { 2534 } else if (var->mode() == CONST && op != Token::INIT) {
2535 // Assignment to const variable needs a write barrier. 2535 // Assignment to const variable needs a write barrier.
2536 DCHECK(!var->IsLookupSlot()); 2536 DCHECK(!var->IsLookupSlot());
2537 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2537 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2538 Label const_error; 2538 Label const_error;
2539 MemOperand location = VarOperand(var, a1); 2539 MemOperand location = VarOperand(var, a1);
2540 __ ld(a3, location); 2540 __ ld(a3, location);
2541 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2541 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2542 __ Branch(&const_error, ne, a3, Operand(at)); 2542 __ Branch(&const_error, ne, a3, Operand(at));
2543 __ li(a3, Operand(var->name())); 2543 __ li(a3, Operand(var->name()));
2544 __ push(a3); 2544 __ push(a3);
2545 __ CallRuntime(Runtime::kThrowReferenceError, 1); 2545 __ CallRuntime(Runtime::kThrowReferenceError);
2546 __ bind(&const_error); 2546 __ bind(&const_error);
2547 __ CallRuntime(Runtime::kThrowConstAssignError, 0); 2547 __ CallRuntime(Runtime::kThrowConstAssignError);
2548 2548
2549 } else if (var->is_this() && var->mode() == CONST && op == Token::INIT) { 2549 } else if (var->is_this() && var->mode() == CONST && op == Token::INIT) {
2550 // Initializing assignment to const {this} needs a write barrier. 2550 // Initializing assignment to const {this} needs a write barrier.
2551 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2551 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2552 Label uninitialized_this; 2552 Label uninitialized_this;
2553 MemOperand location = VarOperand(var, a1); 2553 MemOperand location = VarOperand(var, a1);
2554 __ ld(a3, location); 2554 __ ld(a3, location);
2555 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2555 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2556 __ Branch(&uninitialized_this, eq, a3, Operand(at)); 2556 __ Branch(&uninitialized_this, eq, a3, Operand(at));
2557 __ li(a0, Operand(var->name())); 2557 __ li(a0, Operand(var->name()));
2558 __ Push(a0); 2558 __ Push(a0);
2559 __ CallRuntime(Runtime::kThrowReferenceError, 1); 2559 __ CallRuntime(Runtime::kThrowReferenceError);
2560 __ bind(&uninitialized_this); 2560 __ bind(&uninitialized_this);
2561 EmitStoreToStackLocalOrContextSlot(var, location); 2561 EmitStoreToStackLocalOrContextSlot(var, location);
2562 2562
2563 } else if (!var->is_const_mode() || 2563 } else if (!var->is_const_mode() ||
2564 (var->mode() == CONST && op == Token::INIT)) { 2564 (var->mode() == CONST && op == Token::INIT)) {
2565 if (var->IsLookupSlot()) { 2565 if (var->IsLookupSlot()) {
2566 // Assignment to var. 2566 // Assignment to var.
2567 __ li(a4, Operand(var->name())); 2567 __ li(a4, Operand(var->name()));
2568 __ li(a3, Operand(Smi::FromInt(language_mode()))); 2568 __ li(a3, Operand(Smi::FromInt(language_mode())));
2569 // jssp[0] : language mode. 2569 // jssp[0] : language mode.
2570 // jssp[8] : name. 2570 // jssp[8] : name.
2571 // jssp[16] : context. 2571 // jssp[16] : context.
2572 // jssp[24] : value. 2572 // jssp[24] : value.
2573 __ Push(v0, cp, a4, a3); 2573 __ Push(v0, cp, a4, a3);
2574 __ CallRuntime(Runtime::kStoreLookupSlot, 4); 2574 __ CallRuntime(Runtime::kStoreLookupSlot);
2575 } else { 2575 } else {
2576 // Assignment to var or initializing assignment to let/const in harmony 2576 // Assignment to var or initializing assignment to let/const in harmony
2577 // mode. 2577 // mode.
2578 DCHECK((var->IsStackAllocated() || var->IsContextSlot())); 2578 DCHECK((var->IsStackAllocated() || var->IsContextSlot()));
2579 MemOperand location = VarOperand(var, a1); 2579 MemOperand location = VarOperand(var, a1);
2580 if (generate_debug_code_ && var->mode() == LET && op == Token::INIT) { 2580 if (generate_debug_code_ && var->mode() == LET && op == Token::INIT) {
2581 // Check for an uninitialized let binding. 2581 // Check for an uninitialized let binding.
2582 __ ld(a2, location); 2582 __ ld(a2, location);
2583 __ LoadRoot(a4, Heap::kTheHoleValueRootIndex); 2583 __ LoadRoot(a4, Heap::kTheHoleValueRootIndex);
2584 __ Check(eq, kLetBindingReInitialization, a2, Operand(a4)); 2584 __ Check(eq, kLetBindingReInitialization, a2, Operand(a4));
2585 } 2585 }
2586 EmitStoreToStackLocalOrContextSlot(var, location); 2586 EmitStoreToStackLocalOrContextSlot(var, location);
2587 } 2587 }
2588 2588
2589 } else if (var->mode() == CONST_LEGACY && op == Token::INIT) { 2589 } else if (var->mode() == CONST_LEGACY && op == Token::INIT) {
2590 // Const initializers need a write barrier. 2590 // Const initializers need a write barrier.
2591 DCHECK(!var->IsParameter()); // No const parameters. 2591 DCHECK(!var->IsParameter()); // No const parameters.
2592 if (var->IsLookupSlot()) { 2592 if (var->IsLookupSlot()) {
2593 __ li(a0, Operand(var->name())); 2593 __ li(a0, Operand(var->name()));
2594 __ Push(v0, cp, a0); // Context and name. 2594 __ Push(v0, cp, a0); // Context and name.
2595 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); 2595 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot);
2596 } else { 2596 } else {
2597 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2597 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2598 Label skip; 2598 Label skip;
2599 MemOperand location = VarOperand(var, a1); 2599 MemOperand location = VarOperand(var, a1);
2600 __ ld(a2, location); 2600 __ ld(a2, location);
2601 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2601 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2602 __ Branch(&skip, ne, a2, Operand(at)); 2602 __ Branch(&skip, ne, a2, Operand(at));
2603 EmitStoreToStackLocalOrContextSlot(var, location); 2603 EmitStoreToStackLocalOrContextSlot(var, location);
2604 __ bind(&skip); 2604 __ bind(&skip);
2605 } 2605 }
2606 2606
2607 } else { 2607 } else {
2608 DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT); 2608 DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT);
2609 if (is_strict(language_mode())) { 2609 if (is_strict(language_mode())) {
2610 __ CallRuntime(Runtime::kThrowConstAssignError, 0); 2610 __ CallRuntime(Runtime::kThrowConstAssignError);
2611 } 2611 }
2612 // Silently ignore store in sloppy mode. 2612 // Silently ignore store in sloppy mode.
2613 } 2613 }
2614 } 2614 }
2615 2615
2616 2616
2617 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2617 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2618 // Assignment to a property, using a named store IC. 2618 // Assignment to a property, using a named store IC.
2619 Property* prop = expr->target()->AsProperty(); 2619 Property* prop = expr->target()->AsProperty();
2620 DCHECK(prop != NULL); 2620 DCHECK(prop != NULL);
(...skipping 15 matching lines...) Expand all
2636 // Assignment to named property of super. 2636 // Assignment to named property of super.
2637 // v0 : value 2637 // v0 : value
2638 // stack : receiver ('this'), home_object 2638 // stack : receiver ('this'), home_object
2639 DCHECK(prop != NULL); 2639 DCHECK(prop != NULL);
2640 Literal* key = prop->key()->AsLiteral(); 2640 Literal* key = prop->key()->AsLiteral();
2641 DCHECK(key != NULL); 2641 DCHECK(key != NULL);
2642 2642
2643 __ Push(key->value()); 2643 __ Push(key->value());
2644 __ Push(v0); 2644 __ Push(v0);
2645 __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict 2645 __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict
2646 : Runtime::kStoreToSuper_Sloppy), 2646 : Runtime::kStoreToSuper_Sloppy));
2647 4);
2648 } 2647 }
2649 2648
2650 2649
2651 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { 2650 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
2652 // Assignment to named property of super. 2651 // Assignment to named property of super.
2653 // v0 : value 2652 // v0 : value
2654 // stack : receiver ('this'), home_object, key 2653 // stack : receiver ('this'), home_object, key
2655 DCHECK(prop != NULL); 2654 DCHECK(prop != NULL);
2656 2655
2657 __ Push(v0); 2656 __ Push(v0);
2658 __ CallRuntime( 2657 __ CallRuntime((is_strict(language_mode())
2659 (is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict 2658 ? Runtime::kStoreKeyedToSuper_Strict
2660 : Runtime::kStoreKeyedToSuper_Sloppy), 2659 : Runtime::kStoreKeyedToSuper_Sloppy));
2661 4);
2662 } 2660 }
2663 2661
2664 2662
2665 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2663 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2666 // Assignment to a property, using a keyed store IC. 2664 // Assignment to a property, using a keyed store IC.
2667 // Call keyed store IC. 2665 // Call keyed store IC.
2668 // The arguments are: 2666 // The arguments are:
2669 // - a0 is the value, 2667 // - a0 is the value,
2670 // - a1 is the key, 2668 // - a1 is the key,
2671 // - a2 is the receiver. 2669 // - a2 is the receiver.
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2780 __ Push(key->value()); 2778 __ Push(key->value());
2781 __ Push(Smi::FromInt(language_mode())); 2779 __ Push(Smi::FromInt(language_mode()));
2782 2780
2783 // Stack here: 2781 // Stack here:
2784 // - home_object 2782 // - home_object
2785 // - this (receiver) 2783 // - this (receiver)
2786 // - this (receiver) <-- LoadFromSuper will pop here and below. 2784 // - this (receiver) <-- LoadFromSuper will pop here and below.
2787 // - home_object 2785 // - home_object
2788 // - key 2786 // - key
2789 // - language_mode 2787 // - language_mode
2790 __ CallRuntime(Runtime::kLoadFromSuper, 4); 2788 __ CallRuntime(Runtime::kLoadFromSuper);
2791 2789
2792 // Replace home_object with target function. 2790 // Replace home_object with target function.
2793 __ sd(v0, MemOperand(sp, kPointerSize)); 2791 __ sd(v0, MemOperand(sp, kPointerSize));
2794 2792
2795 // Stack here: 2793 // Stack here:
2796 // - target function 2794 // - target function
2797 // - this (receiver) 2795 // - this (receiver)
2798 EmitCall(expr); 2796 EmitCall(expr);
2799 } 2797 }
2800 2798
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2840 VisitForStackValue(prop->key()); 2838 VisitForStackValue(prop->key());
2841 __ Push(Smi::FromInt(language_mode())); 2839 __ Push(Smi::FromInt(language_mode()));
2842 2840
2843 // Stack here: 2841 // Stack here:
2844 // - home_object 2842 // - home_object
2845 // - this (receiver) 2843 // - this (receiver)
2846 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. 2844 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
2847 // - home_object 2845 // - home_object
2848 // - key 2846 // - key
2849 // - language_mode 2847 // - language_mode
2850 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4); 2848 __ CallRuntime(Runtime::kLoadKeyedFromSuper);
2851 2849
2852 // Replace home_object with target function. 2850 // Replace home_object with target function.
2853 __ sd(v0, MemOperand(sp, kPointerSize)); 2851 __ sd(v0, MemOperand(sp, kPointerSize));
2854 2852
2855 // Stack here: 2853 // Stack here:
2856 // - target function 2854 // - target function
2857 // - this (receiver) 2855 // - this (receiver)
2858 EmitCall(expr); 2856 EmitCall(expr);
2859 } 2857 }
2860 2858
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2895 __ ld(a5, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 2893 __ ld(a5, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
2896 2894
2897 // a4: the language mode. 2895 // a4: the language mode.
2898 __ li(a4, Operand(Smi::FromInt(language_mode()))); 2896 __ li(a4, Operand(Smi::FromInt(language_mode())));
2899 2897
2900 // a1: the start position of the scope the calls resides in. 2898 // a1: the start position of the scope the calls resides in.
2901 __ li(a1, Operand(Smi::FromInt(scope()->start_position()))); 2899 __ li(a1, Operand(Smi::FromInt(scope()->start_position())));
2902 2900
2903 // Do the runtime call. 2901 // Do the runtime call.
2904 __ Push(a6, a5, a4, a1); 2902 __ Push(a6, a5, a4, a1);
2905 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); 2903 __ CallRuntime(Runtime::kResolvePossiblyDirectEval);
2906 } 2904 }
2907 2905
2908 2906
2909 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. 2907 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls.
2910 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { 2908 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
2911 VariableProxy* callee = expr->expression()->AsVariableProxy(); 2909 VariableProxy* callee = expr->expression()->AsVariableProxy();
2912 if (callee->var()->IsLookupSlot()) { 2910 if (callee->var()->IsLookupSlot()) {
2913 Label slow, done; 2911 Label slow, done;
2914 2912
2915 SetExpressionPosition(callee); 2913 SetExpressionPosition(callee);
2916 // Generate code for loading from variables potentially shadowed by 2914 // Generate code for loading from variables potentially shadowed by
2917 // eval-introduced variables. 2915 // eval-introduced variables.
2918 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); 2916 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2919 2917
2920 __ bind(&slow); 2918 __ bind(&slow);
2921 // Call the runtime to find the function to call (returned in v0) 2919 // Call the runtime to find the function to call (returned in v0)
2922 // and the object holding it (returned in v1). 2920 // and the object holding it (returned in v1).
2923 DCHECK(!context_register().is(a2)); 2921 DCHECK(!context_register().is(a2));
2924 __ li(a2, Operand(callee->name())); 2922 __ li(a2, Operand(callee->name()));
2925 __ Push(context_register(), a2); 2923 __ Push(context_register(), a2);
2926 __ CallRuntime(Runtime::kLoadLookupSlot, 2); 2924 __ CallRuntime(Runtime::kLoadLookupSlot);
2927 __ Push(v0, v1); // Function, receiver. 2925 __ Push(v0, v1); // Function, receiver.
2928 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); 2926 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
2929 2927
2930 // If fast case code has been generated, emit code to push the 2928 // If fast case code has been generated, emit code to push the
2931 // function and receiver and have the slow path jump around this 2929 // function and receiver and have the slow path jump around this
2932 // code. 2930 // code.
2933 if (done.is_linked()) { 2931 if (done.is_linked()) {
2934 Label call; 2932 Label call;
2935 __ Branch(&call); 2933 __ Branch(&call);
2936 __ bind(&done); 2934 __ bind(&done);
(...skipping 638 matching lines...) Expand 10 before | Expand all | Expand 10 after
3575 ZoneList<Expression*>* args = expr->arguments(); 3573 ZoneList<Expression*>* args = expr->arguments();
3576 DCHECK_EQ(1, args->length()); 3574 DCHECK_EQ(1, args->length());
3577 3575
3578 // Load the argument into v0 and convert it. 3576 // Load the argument into v0 and convert it.
3579 VisitForAccumulatorValue(args->at(0)); 3577 VisitForAccumulatorValue(args->at(0));
3580 3578
3581 // Convert the object to an integer. 3579 // Convert the object to an integer.
3582 Label done_convert; 3580 Label done_convert;
3583 __ JumpIfSmi(v0, &done_convert); 3581 __ JumpIfSmi(v0, &done_convert);
3584 __ Push(v0); 3582 __ Push(v0);
3585 __ CallRuntime(Runtime::kToInteger, 1); 3583 __ CallRuntime(Runtime::kToInteger);
3586 __ bind(&done_convert); 3584 __ bind(&done_convert);
3587 context()->Plug(v0); 3585 context()->Plug(v0);
3588 } 3586 }
3589 3587
3590 3588
3591 void FullCodeGenerator::EmitToName(CallRuntime* expr) { 3589 void FullCodeGenerator::EmitToName(CallRuntime* expr) {
3592 ZoneList<Expression*>* args = expr->arguments(); 3590 ZoneList<Expression*>* args = expr->arguments();
3593 DCHECK_EQ(1, args->length()); 3591 DCHECK_EQ(1, args->length());
3594 3592
3595 // Load the argument into v0 and convert it. 3593 // Load the argument into v0 and convert it.
3596 VisitForAccumulatorValue(args->at(0)); 3594 VisitForAccumulatorValue(args->at(0));
3597 3595
3598 Label convert, done_convert; 3596 Label convert, done_convert;
3599 __ JumpIfSmi(v0, &convert); 3597 __ JumpIfSmi(v0, &convert);
3600 STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE); 3598 STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE);
3601 __ GetObjectType(v0, a1, a1); 3599 __ GetObjectType(v0, a1, a1);
3602 __ Branch(&done_convert, le, a1, Operand(LAST_NAME_TYPE)); 3600 __ Branch(&done_convert, le, a1, Operand(LAST_NAME_TYPE));
3603 __ bind(&convert); 3601 __ bind(&convert);
3604 __ Push(v0); 3602 __ Push(v0);
3605 __ CallRuntime(Runtime::kToName, 1); 3603 __ CallRuntime(Runtime::kToName);
3606 __ bind(&done_convert); 3604 __ bind(&done_convert);
3607 context()->Plug(v0); 3605 context()->Plug(v0);
3608 } 3606 }
3609 3607
3610 3608
3611 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { 3609 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) {
3612 ZoneList<Expression*>* args = expr->arguments(); 3610 ZoneList<Expression*>* args = expr->arguments();
3613 DCHECK(args->length() == 1); 3611 DCHECK(args->length() == 1);
3614 3612
3615 VisitForAccumulatorValue(args->at(0)); 3613 VisitForAccumulatorValue(args->at(0));
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after
4051 __ LoadRoot(a4, Heap::kEmptyFixedArrayRootIndex); 4049 __ LoadRoot(a4, Heap::kEmptyFixedArrayRootIndex);
4052 __ sd(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); 4050 __ sd(a1, FieldMemOperand(v0, HeapObject::kMapOffset));
4053 __ sd(a4, FieldMemOperand(v0, JSObject::kPropertiesOffset)); 4051 __ sd(a4, FieldMemOperand(v0, JSObject::kPropertiesOffset));
4054 __ sd(a4, FieldMemOperand(v0, JSObject::kElementsOffset)); 4052 __ sd(a4, FieldMemOperand(v0, JSObject::kElementsOffset));
4055 __ sd(a2, FieldMemOperand(v0, JSIteratorResult::kValueOffset)); 4053 __ sd(a2, FieldMemOperand(v0, JSIteratorResult::kValueOffset));
4056 __ sd(a3, FieldMemOperand(v0, JSIteratorResult::kDoneOffset)); 4054 __ sd(a3, FieldMemOperand(v0, JSIteratorResult::kDoneOffset));
4057 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); 4055 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize);
4058 __ jmp(&done); 4056 __ jmp(&done);
4059 4057
4060 __ bind(&runtime); 4058 __ bind(&runtime);
4061 __ CallRuntime(Runtime::kCreateIterResultObject, 2); 4059 __ CallRuntime(Runtime::kCreateIterResultObject);
4062 4060
4063 __ bind(&done); 4061 __ bind(&done);
4064 context()->Plug(v0); 4062 context()->Plug(v0);
4065 } 4063 }
4066 4064
4067 4065
4068 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { 4066 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
4069 // Push undefined as the receiver. 4067 // Push undefined as the receiver.
4070 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); 4068 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
4071 __ push(v0); 4069 __ push(v0);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
4143 case Token::DELETE: { 4141 case Token::DELETE: {
4144 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 4142 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
4145 Property* property = expr->expression()->AsProperty(); 4143 Property* property = expr->expression()->AsProperty();
4146 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 4144 VariableProxy* proxy = expr->expression()->AsVariableProxy();
4147 4145
4148 if (property != NULL) { 4146 if (property != NULL) {
4149 VisitForStackValue(property->obj()); 4147 VisitForStackValue(property->obj());
4150 VisitForStackValue(property->key()); 4148 VisitForStackValue(property->key());
4151 __ CallRuntime(is_strict(language_mode()) 4149 __ CallRuntime(is_strict(language_mode())
4152 ? Runtime::kDeleteProperty_Strict 4150 ? Runtime::kDeleteProperty_Strict
4153 : Runtime::kDeleteProperty_Sloppy, 4151 : Runtime::kDeleteProperty_Sloppy);
4154 2);
4155 context()->Plug(v0); 4152 context()->Plug(v0);
4156 } else if (proxy != NULL) { 4153 } else if (proxy != NULL) {
4157 Variable* var = proxy->var(); 4154 Variable* var = proxy->var();
4158 // Delete of an unqualified identifier is disallowed in strict mode but 4155 // Delete of an unqualified identifier is disallowed in strict mode but
4159 // "delete this" is allowed. 4156 // "delete this" is allowed.
4160 bool is_this = var->HasThisName(isolate()); 4157 bool is_this = var->HasThisName(isolate());
4161 DCHECK(is_sloppy(language_mode()) || is_this); 4158 DCHECK(is_sloppy(language_mode()) || is_this);
4162 if (var->IsUnallocatedOrGlobalSlot()) { 4159 if (var->IsUnallocatedOrGlobalSlot()) {
4163 __ LoadGlobalObject(a2); 4160 __ LoadGlobalObject(a2);
4164 __ li(a1, Operand(var->name())); 4161 __ li(a1, Operand(var->name()));
4165 __ Push(a2, a1); 4162 __ Push(a2, a1);
4166 __ CallRuntime(Runtime::kDeleteProperty_Sloppy, 2); 4163 __ CallRuntime(Runtime::kDeleteProperty_Sloppy);
4167 context()->Plug(v0); 4164 context()->Plug(v0);
4168 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 4165 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
4169 // Result of deleting non-global, non-dynamic variables is false. 4166 // Result of deleting non-global, non-dynamic variables is false.
4170 // The subexpression does not have side effects. 4167 // The subexpression does not have side effects.
4171 context()->Plug(is_this); 4168 context()->Plug(is_this);
4172 } else { 4169 } else {
4173 // Non-global variable. Call the runtime to try to delete from the 4170 // Non-global variable. Call the runtime to try to delete from the
4174 // context where the variable was introduced. 4171 // context where the variable was introduced.
4175 DCHECK(!context_register().is(a2)); 4172 DCHECK(!context_register().is(a2));
4176 __ li(a2, Operand(var->name())); 4173 __ li(a2, Operand(var->name()));
4177 __ Push(context_register(), a2); 4174 __ Push(context_register(), a2);
4178 __ CallRuntime(Runtime::kDeleteLookupSlot, 2); 4175 __ CallRuntime(Runtime::kDeleteLookupSlot);
4179 context()->Plug(v0); 4176 context()->Plug(v0);
4180 } 4177 }
4181 } else { 4178 } else {
4182 // Result of deleting non-property, non-variable reference is true. 4179 // Result of deleting non-property, non-variable reference is true.
4183 // The subexpression may have side effects. 4180 // The subexpression may have side effects.
4184 VisitForEffect(expr->expression()); 4181 VisitForEffect(expr->expression());
4185 context()->Plug(true); 4182 context()->Plug(true);
4186 } 4183 }
4187 break; 4184 break;
4188 } 4185 }
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
4603 Label* if_false = NULL; 4600 Label* if_false = NULL;
4604 Label* fall_through = NULL; 4601 Label* fall_through = NULL;
4605 context()->PrepareTest(&materialize_true, &materialize_false, 4602 context()->PrepareTest(&materialize_true, &materialize_false,
4606 &if_true, &if_false, &fall_through); 4603 &if_true, &if_false, &fall_through);
4607 4604
4608 Token::Value op = expr->op(); 4605 Token::Value op = expr->op();
4609 VisitForStackValue(expr->left()); 4606 VisitForStackValue(expr->left());
4610 switch (op) { 4607 switch (op) {
4611 case Token::IN: 4608 case Token::IN:
4612 VisitForStackValue(expr->right()); 4609 VisitForStackValue(expr->right());
4613 __ CallRuntime(Runtime::kHasProperty, 2); 4610 __ CallRuntime(Runtime::kHasProperty);
4614 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 4611 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
4615 __ LoadRoot(a4, Heap::kTrueValueRootIndex); 4612 __ LoadRoot(a4, Heap::kTrueValueRootIndex);
4616 Split(eq, v0, Operand(a4), if_true, if_false, fall_through); 4613 Split(eq, v0, Operand(a4), if_true, if_false, fall_through);
4617 break; 4614 break;
4618 4615
4619 case Token::INSTANCEOF: { 4616 case Token::INSTANCEOF: {
4620 VisitForAccumulatorValue(expr->right()); 4617 VisitForAccumulatorValue(expr->right());
4621 __ mov(a0, result_register()); 4618 __ mov(a0, result_register());
4622 __ pop(a1); 4619 __ pop(a1);
4623 InstanceOfStub stub(isolate()); 4620 InstanceOfStub stub(isolate());
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
4882 reinterpret_cast<uint64_t>( 4879 reinterpret_cast<uint64_t>(
4883 isolate->builtins()->OsrAfterStackCheck()->entry())); 4880 isolate->builtins()->OsrAfterStackCheck()->entry()));
4884 return OSR_AFTER_STACK_CHECK; 4881 return OSR_AFTER_STACK_CHECK;
4885 } 4882 }
4886 4883
4887 4884
4888 } // namespace internal 4885 } // namespace internal
4889 } // namespace v8 4886 } // namespace v8
4890 4887
4891 #endif // V8_TARGET_ARCH_MIPS64 4888 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698