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

Side by Side Diff: src/full-codegen/ppc/full-codegen-ppc.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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_PPC 5 #if V8_TARGET_ARCH_PPC
6 6
7 #include "src/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 int locals_count = info->scope()->num_stack_slots(); 142 int locals_count = info->scope()->num_stack_slots();
143 // Generators allocate locals, if any, in context slots. 143 // Generators allocate locals, if any, in context slots.
144 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0); 144 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0);
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 __ Add(ip, sp, -(locals_count * kPointerSize), r0); 148 __ Add(ip, sp, -(locals_count * kPointerSize), r0);
149 __ LoadRoot(r5, Heap::kRealStackLimitRootIndex); 149 __ LoadRoot(r5, Heap::kRealStackLimitRootIndex);
150 __ cmpl(ip, r5); 150 __ cmpl(ip, r5);
151 __ bc_short(ge, &ok); 151 __ bc_short(ge, &ok);
152 __ CallRuntime(Runtime::kThrowStackOverflow, 0); 152 __ CallRuntime(Runtime::kThrowStackOverflow);
153 __ bind(&ok); 153 __ bind(&ok);
154 } 154 }
155 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 155 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
156 int kMaxPushes = FLAG_optimize_for_size ? 4 : 32; 156 int kMaxPushes = FLAG_optimize_for_size ? 4 : 32;
157 if (locals_count >= kMaxPushes) { 157 if (locals_count >= kMaxPushes) {
158 int loop_iterations = locals_count / kMaxPushes; 158 int loop_iterations = locals_count / kMaxPushes;
159 __ mov(r5, Operand(loop_iterations)); 159 __ mov(r5, Operand(loop_iterations));
160 __ mtctr(r5); 160 __ mtctr(r5);
161 Label loop_header; 161 Label loop_header;
162 __ bind(&loop_header); 162 __ bind(&loop_header);
(...skipping 16 matching lines...) Expand all
179 179
180 // Possibly allocate a local context. 180 // Possibly allocate a local context.
181 if (info->scope()->num_heap_slots() > 0) { 181 if (info->scope()->num_heap_slots() > 0) {
182 // Argument to NewContext is the function, which is still in r4. 182 // Argument to NewContext is the function, which is still in r4.
183 Comment cmnt(masm_, "[ Allocate context"); 183 Comment cmnt(masm_, "[ Allocate context");
184 bool need_write_barrier = true; 184 bool need_write_barrier = true;
185 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 185 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
186 if (info->scope()->is_script_scope()) { 186 if (info->scope()->is_script_scope()) {
187 __ push(r4); 187 __ push(r4);
188 __ Push(info->scope()->GetScopeInfo(info->isolate())); 188 __ Push(info->scope()->GetScopeInfo(info->isolate()));
189 __ CallRuntime(Runtime::kNewScriptContext, 2); 189 __ CallRuntime(Runtime::kNewScriptContext);
190 PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG); 190 PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG);
191 // The new target value is not used, clobbering is safe. 191 // The new target value is not used, clobbering is safe.
192 DCHECK_NULL(info->scope()->new_target_var()); 192 DCHECK_NULL(info->scope()->new_target_var());
193 } else { 193 } else {
194 if (info->scope()->new_target_var() != nullptr) { 194 if (info->scope()->new_target_var() != nullptr) {
195 __ push(r6); // Preserve new target. 195 __ push(r6); // Preserve new target.
196 } 196 }
197 if (slots <= FastNewContextStub::kMaximumSlots) { 197 if (slots <= FastNewContextStub::kMaximumSlots) {
198 FastNewContextStub stub(isolate(), slots); 198 FastNewContextStub stub(isolate(), slots);
199 __ CallStub(&stub); 199 __ CallStub(&stub);
200 // Result of FastNewContextStub is always in new space. 200 // Result of FastNewContextStub is always in new space.
201 need_write_barrier = false; 201 need_write_barrier = false;
202 } else { 202 } else {
203 __ push(r4); 203 __ push(r4);
204 __ CallRuntime(Runtime::kNewFunctionContext, 1); 204 __ CallRuntime(Runtime::kNewFunctionContext);
205 } 205 }
206 if (info->scope()->new_target_var() != nullptr) { 206 if (info->scope()->new_target_var() != nullptr) {
207 __ pop(r6); // Preserve new target. 207 __ pop(r6); // Preserve new target.
208 } 208 }
209 } 209 }
210 function_in_register_r4 = false; 210 function_in_register_r4 = false;
211 // Context is returned in r3. It replaces the context passed to us. 211 // Context is returned in r3. It replaces the context passed to us.
212 // It's saved in the stack and kept live in cp. 212 // It's saved in the stack and kept live in cp.
213 __ mr(cp, r3); 213 __ mr(cp, r3);
214 __ StoreP(r3, MemOperand(fp, StandardFrameConstants::kContextOffset)); 214 __ StoreP(r3, MemOperand(fp, StandardFrameConstants::kContextOffset));
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 bool is_unmapped = is_strict(language_mode()) || !has_simple_parameters(); 310 bool is_unmapped = is_strict(language_mode()) || !has_simple_parameters();
311 ArgumentsAccessStub::Type type = ArgumentsAccessStub::ComputeType( 311 ArgumentsAccessStub::Type type = ArgumentsAccessStub::ComputeType(
312 is_unmapped, literal()->has_duplicate_parameters()); 312 is_unmapped, literal()->has_duplicate_parameters());
313 ArgumentsAccessStub stub(isolate(), type); 313 ArgumentsAccessStub stub(isolate(), type);
314 __ CallStub(&stub); 314 __ CallStub(&stub);
315 315
316 SetVar(arguments, r3, r4, r5); 316 SetVar(arguments, r3, r4, r5);
317 } 317 }
318 318
319 if (FLAG_trace) { 319 if (FLAG_trace) {
320 __ CallRuntime(Runtime::kTraceEnter, 0); 320 __ CallRuntime(Runtime::kTraceEnter);
321 } 321 }
322 322
323 // Visit the declarations and body unless there is an illegal 323 // Visit the declarations and body unless there is an illegal
324 // redeclaration. 324 // redeclaration.
325 if (scope()->HasIllegalRedeclaration()) { 325 if (scope()->HasIllegalRedeclaration()) {
326 Comment cmnt(masm_, "[ Declarations"); 326 Comment cmnt(masm_, "[ Declarations");
327 VisitForEffect(scope()->GetIllegalRedeclaration()); 327 VisitForEffect(scope()->GetIllegalRedeclaration());
328 328
329 } else { 329 } else {
330 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); 330 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 void FullCodeGenerator::EmitReturnSequence() { 429 void FullCodeGenerator::EmitReturnSequence() {
430 Comment cmnt(masm_, "[ Return sequence"); 430 Comment cmnt(masm_, "[ Return sequence");
431 if (return_label_.is_bound()) { 431 if (return_label_.is_bound()) {
432 __ b(&return_label_); 432 __ b(&return_label_);
433 } else { 433 } else {
434 __ bind(&return_label_); 434 __ bind(&return_label_);
435 if (FLAG_trace) { 435 if (FLAG_trace) {
436 // Push the return value on the stack as the parameter. 436 // Push the return value on the stack as the parameter.
437 // Runtime::TraceExit returns its parameter in r3 437 // Runtime::TraceExit returns its parameter in r3
438 __ push(r3); 438 __ push(r3);
439 __ CallRuntime(Runtime::kTraceExit, 1); 439 __ CallRuntime(Runtime::kTraceExit);
440 } 440 }
441 // Pretend that the exit is a backwards jump to the entry. 441 // Pretend that the exit is a backwards jump to the entry.
442 int weight = 1; 442 int weight = 1;
443 if (info_->ShouldSelfOptimize()) { 443 if (info_->ShouldSelfOptimize()) {
444 weight = FLAG_interrupt_budget / FLAG_self_opt_count; 444 weight = FLAG_interrupt_budget / FLAG_self_opt_count;
445 } else { 445 } else {
446 int distance = masm_->pc_offset() + kCodeSizeMultiplier / 2; 446 int distance = masm_->pc_offset() + kCodeSizeMultiplier / 2;
447 weight = Min(kMaxBackEdgeWeight, Max(1, distance / kCodeSizeMultiplier)); 447 weight = Min(kMaxBackEdgeWeight, Max(1, distance / kCodeSizeMultiplier));
448 } 448 }
449 EmitProfilingCounterDecrement(weight); 449 EmitProfilingCounterDecrement(weight);
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 // Note: For variables we must not push an initial value (such as 808 // Note: For variables we must not push an initial value (such as
809 // 'undefined') because we may have a (legal) redeclaration and we 809 // 'undefined') because we may have a (legal) redeclaration and we
810 // must not destroy the current value. 810 // must not destroy the current value.
811 if (hole_init) { 811 if (hole_init) {
812 __ LoadRoot(r3, Heap::kTheHoleValueRootIndex); 812 __ LoadRoot(r3, Heap::kTheHoleValueRootIndex);
813 } else { 813 } else {
814 __ LoadSmiLiteral(r3, Smi::FromInt(0)); // Indicates no initial value. 814 __ LoadSmiLiteral(r3, Smi::FromInt(0)); // Indicates no initial value.
815 } 815 }
816 __ Push(r5, r3); 816 __ Push(r5, r3);
817 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); 817 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes()));
818 __ CallRuntime(Runtime::kDeclareLookupSlot, 3); 818 __ CallRuntime(Runtime::kDeclareLookupSlot);
819 break; 819 break;
820 } 820 }
821 } 821 }
822 } 822 }
823 823
824 824
825 void FullCodeGenerator::VisitFunctionDeclaration( 825 void FullCodeGenerator::VisitFunctionDeclaration(
826 FunctionDeclaration* declaration) { 826 FunctionDeclaration* declaration) {
827 VariableProxy* proxy = declaration->proxy(); 827 VariableProxy* proxy = declaration->proxy();
828 Variable* variable = proxy->var(); 828 Variable* variable = proxy->var();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
861 break; 861 break;
862 } 862 }
863 863
864 case VariableLocation::LOOKUP: { 864 case VariableLocation::LOOKUP: {
865 Comment cmnt(masm_, "[ FunctionDeclaration"); 865 Comment cmnt(masm_, "[ FunctionDeclaration");
866 __ mov(r5, Operand(variable->name())); 866 __ mov(r5, Operand(variable->name()));
867 __ Push(r5); 867 __ Push(r5);
868 // Push initial value for function declaration. 868 // Push initial value for function declaration.
869 VisitForStackValue(declaration->fun()); 869 VisitForStackValue(declaration->fun());
870 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); 870 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes()));
871 __ CallRuntime(Runtime::kDeclareLookupSlot, 3); 871 __ CallRuntime(Runtime::kDeclareLookupSlot);
872 break; 872 break;
873 } 873 }
874 } 874 }
875 } 875 }
876 876
877 877
878 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 878 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
879 // Call the runtime to declare the globals. 879 // Call the runtime to declare the globals.
880 __ mov(r4, Operand(pairs)); 880 __ mov(r4, Operand(pairs));
881 __ LoadSmiLiteral(r3, Smi::FromInt(DeclareGlobalsFlags())); 881 __ LoadSmiLiteral(r3, Smi::FromInt(DeclareGlobalsFlags()));
882 __ Push(r4, r3); 882 __ Push(r4, r3);
883 __ CallRuntime(Runtime::kDeclareGlobals, 2); 883 __ CallRuntime(Runtime::kDeclareGlobals);
884 // Return value is ignored. 884 // Return value is ignored.
885 } 885 }
886 886
887 887
888 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) { 888 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) {
889 // Call the runtime to declare the modules. 889 // Call the runtime to declare the modules.
890 __ Push(descriptions); 890 __ Push(descriptions);
891 __ CallRuntime(Runtime::kDeclareModules, 1); 891 __ CallRuntime(Runtime::kDeclareModules);
892 // Return value is ignored. 892 // Return value is ignored.
893 } 893 }
894 894
895 895
896 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 896 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
897 Comment cmnt(masm_, "[ SwitchStatement"); 897 Comment cmnt(masm_, "[ SwitchStatement");
898 Breakable nested_statement(this, stmt); 898 Breakable nested_statement(this, stmt);
899 SetStatementPosition(stmt); 899 SetStatementPosition(stmt);
900 900
901 // Keep the switch value on the stack until a case matches. 901 // Keep the switch value on the stack until a case matches.
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1036 1036
1037 // The enum cache is valid. Load the map of the object being 1037 // The enum cache is valid. Load the map of the object being
1038 // iterated over and use the cache for the iteration. 1038 // iterated over and use the cache for the iteration.
1039 Label use_cache; 1039 Label use_cache;
1040 __ LoadP(r3, FieldMemOperand(r3, HeapObject::kMapOffset)); 1040 __ LoadP(r3, FieldMemOperand(r3, HeapObject::kMapOffset));
1041 __ b(&use_cache); 1041 __ b(&use_cache);
1042 1042
1043 // Get the set of properties to enumerate. 1043 // Get the set of properties to enumerate.
1044 __ bind(&call_runtime); 1044 __ bind(&call_runtime);
1045 __ push(r3); // Duplicate the enumerable object on the stack. 1045 __ push(r3); // Duplicate the enumerable object on the stack.
1046 __ CallRuntime(Runtime::kGetPropertyNamesFast, 1); 1046 __ CallRuntime(Runtime::kGetPropertyNamesFast);
1047 PrepareForBailoutForId(stmt->EnumId(), TOS_REG); 1047 PrepareForBailoutForId(stmt->EnumId(), TOS_REG);
1048 1048
1049 // If we got a map from the runtime call, we can do a fast 1049 // If we got a map from the runtime call, we can do a fast
1050 // modification check. Otherwise, we got a fixed array, and we have 1050 // modification check. Otherwise, we got a fixed array, and we have
1051 // to do a slow check. 1051 // to do a slow check.
1052 Label fixed_array; 1052 Label fixed_array;
1053 __ LoadP(r5, FieldMemOperand(r3, HeapObject::kMapOffset)); 1053 __ LoadP(r5, FieldMemOperand(r3, HeapObject::kMapOffset));
1054 __ LoadRoot(ip, Heap::kMetaMapRootIndex); 1054 __ LoadRoot(ip, Heap::kMetaMapRootIndex);
1055 __ cmp(r5, ip); 1055 __ cmp(r5, ip);
1056 __ bne(&fixed_array); 1056 __ bne(&fixed_array);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1118 Label update_each; 1118 Label update_each;
1119 __ LoadP(r4, MemOperand(sp, 4 * kPointerSize)); 1119 __ LoadP(r4, MemOperand(sp, 4 * kPointerSize));
1120 __ LoadP(r7, FieldMemOperand(r4, HeapObject::kMapOffset)); 1120 __ LoadP(r7, FieldMemOperand(r4, HeapObject::kMapOffset));
1121 __ cmp(r7, r5); 1121 __ cmp(r7, r5);
1122 __ beq(&update_each); 1122 __ beq(&update_each);
1123 1123
1124 // Convert the entry to a string or (smi) 0 if it isn't a property 1124 // Convert the entry to a string or (smi) 0 if it isn't a property
1125 // any more. If the property has been removed while iterating, we 1125 // any more. If the property has been removed while iterating, we
1126 // just skip it. 1126 // just skip it.
1127 __ Push(r4, r6); // Enumerable and current entry. 1127 __ Push(r4, r6); // Enumerable and current entry.
1128 __ CallRuntime(Runtime::kForInFilter, 2); 1128 __ CallRuntime(Runtime::kForInFilter);
1129 PrepareForBailoutForId(stmt->FilterId(), TOS_REG); 1129 PrepareForBailoutForId(stmt->FilterId(), TOS_REG);
1130 __ mr(r6, r3); 1130 __ mr(r6, r3);
1131 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); 1131 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
1132 __ cmp(r3, r0); 1132 __ cmp(r3, r0);
1133 __ beq(loop_statement.continue_label()); 1133 __ beq(loop_statement.continue_label());
1134 1134
1135 // Update the 'each' property or variable from the possibly filtered 1135 // Update the 'each' property or variable from the possibly filtered
1136 // entry in register r6. 1136 // entry in register r6.
1137 __ bind(&update_each); 1137 __ bind(&update_each);
1138 __ mr(result_register(), r6); 1138 __ mr(result_register(), r6);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1177 // flag, we need to use the runtime function so that the new function 1177 // flag, we need to use the runtime function so that the new function
1178 // we are creating here gets a chance to have its code optimized and 1178 // we are creating here gets a chance to have its code optimized and
1179 // doesn't just get a copy of the existing unoptimized code. 1179 // doesn't just get a copy of the existing unoptimized code.
1180 if (!FLAG_always_opt && !FLAG_prepare_always_opt && !pretenure && 1180 if (!FLAG_always_opt && !FLAG_prepare_always_opt && !pretenure &&
1181 scope()->is_function_scope() && info->num_literals() == 0) { 1181 scope()->is_function_scope() && info->num_literals() == 0) {
1182 FastNewClosureStub stub(isolate(), info->language_mode(), info->kind()); 1182 FastNewClosureStub stub(isolate(), info->language_mode(), info->kind());
1183 __ mov(r5, Operand(info)); 1183 __ mov(r5, Operand(info));
1184 __ CallStub(&stub); 1184 __ CallStub(&stub);
1185 } else { 1185 } else {
1186 __ Push(info); 1186 __ Push(info);
1187 __ CallRuntime( 1187 __ CallRuntime(pretenure ? Runtime::kNewClosure_Tenured
1188 pretenure ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure, 1); 1188 : Runtime::kNewClosure);
1189 } 1189 }
1190 context()->Plug(r3); 1190 context()->Plug(r3);
1191 } 1191 }
1192 1192
1193 1193
1194 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, 1194 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset,
1195 FeedbackVectorSlot slot) { 1195 FeedbackVectorSlot slot) {
1196 DCHECK(NeedsHomeObject(initializer)); 1196 DCHECK(NeedsHomeObject(initializer));
1197 __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); 1197 __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
1198 __ mov(StoreDescriptor::NameRegister(), 1198 __ mov(StoreDescriptor::NameRegister(),
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1317 __ LoadP(r3, ContextSlotOperandCheckExtensions(local, slow)); 1317 __ LoadP(r3, ContextSlotOperandCheckExtensions(local, slow));
1318 if (local->mode() == LET || local->mode() == CONST || 1318 if (local->mode() == LET || local->mode() == CONST ||
1319 local->mode() == CONST_LEGACY) { 1319 local->mode() == CONST_LEGACY) {
1320 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); 1320 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex);
1321 __ bne(done); 1321 __ bne(done);
1322 if (local->mode() == CONST_LEGACY) { 1322 if (local->mode() == CONST_LEGACY) {
1323 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex); 1323 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex);
1324 } else { // LET || CONST 1324 } else { // LET || CONST
1325 __ mov(r3, Operand(var->name())); 1325 __ mov(r3, Operand(var->name()));
1326 __ push(r3); 1326 __ push(r3);
1327 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1327 __ CallRuntime(Runtime::kThrowReferenceError);
1328 } 1328 }
1329 } 1329 }
1330 __ b(done); 1330 __ b(done);
1331 } 1331 }
1332 } 1332 }
1333 1333
1334 1334
1335 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, 1335 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
1336 TypeofMode typeof_mode) { 1336 TypeofMode typeof_mode) {
1337 Variable* var = proxy->var(); 1337 Variable* var = proxy->var();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1373 Label done; 1373 Label done;
1374 // Let and const need a read barrier. 1374 // Let and const need a read barrier.
1375 GetVar(r3, var); 1375 GetVar(r3, var);
1376 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); 1376 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex);
1377 __ bne(&done); 1377 __ bne(&done);
1378 if (var->mode() == LET || var->mode() == CONST) { 1378 if (var->mode() == LET || var->mode() == CONST) {
1379 // Throw a reference error when using an uninitialized let/const 1379 // Throw a reference error when using an uninitialized let/const
1380 // binding in harmony mode. 1380 // binding in harmony mode.
1381 __ mov(r3, Operand(var->name())); 1381 __ mov(r3, Operand(var->name()));
1382 __ push(r3); 1382 __ push(r3);
1383 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1383 __ CallRuntime(Runtime::kThrowReferenceError);
1384 } else { 1384 } else {
1385 // Uninitialized legacy const bindings are unholed. 1385 // Uninitialized legacy const bindings are unholed.
1386 DCHECK(var->mode() == CONST_LEGACY); 1386 DCHECK(var->mode() == CONST_LEGACY);
1387 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex); 1387 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex);
1388 } 1388 }
1389 __ bind(&done); 1389 __ bind(&done);
1390 context()->Plug(r3); 1390 context()->Plug(r3);
1391 break; 1391 break;
1392 } 1392 }
1393 context()->Plug(var); 1393 context()->Plug(var);
1394 break; 1394 break;
1395 } 1395 }
1396 1396
1397 case VariableLocation::LOOKUP: { 1397 case VariableLocation::LOOKUP: {
1398 Comment cmnt(masm_, "[ Lookup variable"); 1398 Comment cmnt(masm_, "[ Lookup variable");
1399 Label done, slow; 1399 Label done, slow;
1400 // Generate code for loading from variables potentially shadowed 1400 // Generate code for loading from variables potentially shadowed
1401 // by eval-introduced variables. 1401 // by eval-introduced variables.
1402 EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done); 1402 EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
1403 __ bind(&slow); 1403 __ bind(&slow);
1404 __ mov(r4, Operand(var->name())); 1404 __ mov(r4, Operand(var->name()));
1405 __ Push(cp, r4); // Context and name. 1405 __ Push(cp, r4); // Context and name.
1406 Runtime::FunctionId function_id = 1406 Runtime::FunctionId function_id =
1407 typeof_mode == NOT_INSIDE_TYPEOF 1407 typeof_mode == NOT_INSIDE_TYPEOF
1408 ? Runtime::kLoadLookupSlot 1408 ? Runtime::kLoadLookupSlot
1409 : Runtime::kLoadLookupSlotNoReferenceError; 1409 : Runtime::kLoadLookupSlotNoReferenceError;
1410 __ CallRuntime(function_id, 2); 1410 __ CallRuntime(function_id);
1411 __ bind(&done); 1411 __ bind(&done);
1412 context()->Plug(r3); 1412 context()->Plug(r3);
1413 } 1413 }
1414 } 1414 }
1415 } 1415 }
1416 1416
1417 1417
1418 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1418 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1419 Comment cmnt(masm_, "[ RegExpLiteral"); 1419 Comment cmnt(masm_, "[ RegExpLiteral");
1420 __ LoadP(r6, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 1420 __ LoadP(r6, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
(...skipping 27 matching lines...) Expand all
1448 Comment cmnt(masm_, "[ ObjectLiteral"); 1448 Comment cmnt(masm_, "[ ObjectLiteral");
1449 1449
1450 Handle<FixedArray> constant_properties = expr->constant_properties(); 1450 Handle<FixedArray> constant_properties = expr->constant_properties();
1451 __ LoadP(r6, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 1451 __ LoadP(r6, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1452 __ LoadSmiLiteral(r5, Smi::FromInt(expr->literal_index())); 1452 __ LoadSmiLiteral(r5, Smi::FromInt(expr->literal_index()));
1453 __ mov(r4, Operand(constant_properties)); 1453 __ mov(r4, Operand(constant_properties));
1454 int flags = expr->ComputeFlags(); 1454 int flags = expr->ComputeFlags();
1455 __ LoadSmiLiteral(r3, Smi::FromInt(flags)); 1455 __ LoadSmiLiteral(r3, Smi::FromInt(flags));
1456 if (MustCreateObjectLiteralWithRuntime(expr)) { 1456 if (MustCreateObjectLiteralWithRuntime(expr)) {
1457 __ Push(r6, r5, r4, r3); 1457 __ Push(r6, r5, r4, r3);
1458 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); 1458 __ CallRuntime(Runtime::kCreateObjectLiteral);
1459 } else { 1459 } else {
1460 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); 1460 FastCloneShallowObjectStub stub(isolate(), expr->properties_count());
1461 __ CallStub(&stub); 1461 __ CallStub(&stub);
1462 } 1462 }
1463 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1463 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
1464 1464
1465 // If result_saved is true the result is on top of the stack. If 1465 // If result_saved is true the result is on top of the stack. If
1466 // result_saved is false the result is in r3. 1466 // result_saved is false the result is in r3.
1467 bool result_saved = false; 1467 bool result_saved = false;
1468 1468
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1510 __ LoadP(r3, MemOperand(sp)); 1510 __ LoadP(r3, MemOperand(sp));
1511 __ push(r3); 1511 __ push(r3);
1512 VisitForStackValue(key); 1512 VisitForStackValue(key);
1513 VisitForStackValue(value); 1513 VisitForStackValue(value);
1514 if (property->emit_store()) { 1514 if (property->emit_store()) {
1515 if (NeedsHomeObject(value)) { 1515 if (NeedsHomeObject(value)) {
1516 EmitSetHomeObject(value, 2, property->GetSlot()); 1516 EmitSetHomeObject(value, 2, property->GetSlot());
1517 } 1517 }
1518 __ LoadSmiLiteral(r3, Smi::FromInt(SLOPPY)); // PropertyAttributes 1518 __ LoadSmiLiteral(r3, Smi::FromInt(SLOPPY)); // PropertyAttributes
1519 __ push(r3); 1519 __ push(r3);
1520 __ CallRuntime(Runtime::kSetProperty, 4); 1520 __ CallRuntime(Runtime::kSetProperty);
1521 } else { 1521 } else {
1522 __ Drop(3); 1522 __ Drop(3);
1523 } 1523 }
1524 break; 1524 break;
1525 case ObjectLiteral::Property::PROTOTYPE: 1525 case ObjectLiteral::Property::PROTOTYPE:
1526 // Duplicate receiver on stack. 1526 // Duplicate receiver on stack.
1527 __ LoadP(r3, MemOperand(sp)); 1527 __ LoadP(r3, MemOperand(sp));
1528 __ push(r3); 1528 __ push(r3);
1529 VisitForStackValue(value); 1529 VisitForStackValue(value);
1530 DCHECK(property->emit_store()); 1530 DCHECK(property->emit_store());
1531 __ CallRuntime(Runtime::kInternalSetPrototype, 2); 1531 __ CallRuntime(Runtime::kInternalSetPrototype);
1532 break; 1532 break;
1533 case ObjectLiteral::Property::GETTER: 1533 case ObjectLiteral::Property::GETTER:
1534 if (property->emit_store()) { 1534 if (property->emit_store()) {
1535 accessor_table.lookup(key)->second->getter = property; 1535 accessor_table.lookup(key)->second->getter = property;
1536 } 1536 }
1537 break; 1537 break;
1538 case ObjectLiteral::Property::SETTER: 1538 case ObjectLiteral::Property::SETTER:
1539 if (property->emit_store()) { 1539 if (property->emit_store()) {
1540 accessor_table.lookup(key)->second->setter = property; 1540 accessor_table.lookup(key)->second->setter = property;
1541 } 1541 }
1542 break; 1542 break;
1543 } 1543 }
1544 } 1544 }
1545 1545
1546 // Emit code to define accessors, using only a single call to the runtime for 1546 // Emit code to define accessors, using only a single call to the runtime for
1547 // each pair of corresponding getters and setters. 1547 // each pair of corresponding getters and setters.
1548 for (AccessorTable::Iterator it = accessor_table.begin(); 1548 for (AccessorTable::Iterator it = accessor_table.begin();
1549 it != accessor_table.end(); ++it) { 1549 it != accessor_table.end(); ++it) {
1550 __ LoadP(r3, MemOperand(sp)); // Duplicate receiver. 1550 __ LoadP(r3, MemOperand(sp)); // Duplicate receiver.
1551 __ push(r3); 1551 __ push(r3);
1552 VisitForStackValue(it->first); 1552 VisitForStackValue(it->first);
1553 EmitAccessor(it->second->getter); 1553 EmitAccessor(it->second->getter);
1554 EmitAccessor(it->second->setter); 1554 EmitAccessor(it->second->setter);
1555 __ LoadSmiLiteral(r3, Smi::FromInt(NONE)); 1555 __ LoadSmiLiteral(r3, Smi::FromInt(NONE));
1556 __ push(r3); 1556 __ push(r3);
1557 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); 1557 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked);
1558 } 1558 }
1559 1559
1560 // Object literals have two parts. The "static" part on the left contains no 1560 // Object literals have two parts. The "static" part on the left contains no
1561 // computed property names, and so we can compute its map ahead of time; see 1561 // computed property names, and so we can compute its map ahead of time; see
1562 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part 1562 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part
1563 // starts with the first computed property name, and continues with all 1563 // starts with the first computed property name, and continues with all
1564 // properties to its right. All the code from above initializes the static 1564 // properties to its right. All the code from above initializes the static
1565 // component of the object literal, and arranges for the map of the result to 1565 // component of the object literal, and arranges for the map of the result to
1566 // reflect the static order in which the keys appear. For the dynamic 1566 // reflect the static order in which the keys appear. For the dynamic
1567 // properties, we compile them into a series of "SetOwnProperty" runtime 1567 // properties, we compile them into a series of "SetOwnProperty" runtime
1568 // calls. This will preserve insertion order. 1568 // calls. This will preserve insertion order.
1569 for (; property_index < expr->properties()->length(); property_index++) { 1569 for (; property_index < expr->properties()->length(); property_index++) {
1570 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1570 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1571 1571
1572 Expression* value = property->value(); 1572 Expression* value = property->value();
1573 if (!result_saved) { 1573 if (!result_saved) {
1574 __ push(r3); // Save result on the stack 1574 __ push(r3); // Save result on the stack
1575 result_saved = true; 1575 result_saved = true;
1576 } 1576 }
1577 1577
1578 __ LoadP(r3, MemOperand(sp)); // Duplicate receiver. 1578 __ LoadP(r3, MemOperand(sp)); // Duplicate receiver.
1579 __ push(r3); 1579 __ push(r3);
1580 1580
1581 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1581 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1582 DCHECK(!property->is_computed_name()); 1582 DCHECK(!property->is_computed_name());
1583 VisitForStackValue(value); 1583 VisitForStackValue(value);
1584 DCHECK(property->emit_store()); 1584 DCHECK(property->emit_store());
1585 __ CallRuntime(Runtime::kInternalSetPrototype, 2); 1585 __ CallRuntime(Runtime::kInternalSetPrototype);
1586 } else { 1586 } else {
1587 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); 1587 EmitPropertyKey(property, expr->GetIdForProperty(property_index));
1588 VisitForStackValue(value); 1588 VisitForStackValue(value);
1589 if (NeedsHomeObject(value)) { 1589 if (NeedsHomeObject(value)) {
1590 EmitSetHomeObject(value, 2, property->GetSlot()); 1590 EmitSetHomeObject(value, 2, property->GetSlot());
1591 } 1591 }
1592 1592
1593 switch (property->kind()) { 1593 switch (property->kind()) {
1594 case ObjectLiteral::Property::CONSTANT: 1594 case ObjectLiteral::Property::CONSTANT:
1595 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1595 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1596 case ObjectLiteral::Property::COMPUTED: 1596 case ObjectLiteral::Property::COMPUTED:
1597 if (property->emit_store()) { 1597 if (property->emit_store()) {
1598 __ LoadSmiLiteral(r3, Smi::FromInt(NONE)); 1598 __ LoadSmiLiteral(r3, Smi::FromInt(NONE));
1599 __ push(r3); 1599 __ push(r3);
1600 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); 1600 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked);
1601 } else { 1601 } else {
1602 __ Drop(3); 1602 __ Drop(3);
1603 } 1603 }
1604 break; 1604 break;
1605 1605
1606 case ObjectLiteral::Property::PROTOTYPE: 1606 case ObjectLiteral::Property::PROTOTYPE:
1607 UNREACHABLE(); 1607 UNREACHABLE();
1608 break; 1608 break;
1609 1609
1610 case ObjectLiteral::Property::GETTER: 1610 case ObjectLiteral::Property::GETTER:
1611 __ mov(r3, Operand(Smi::FromInt(NONE))); 1611 __ mov(r3, Operand(Smi::FromInt(NONE)));
1612 __ push(r3); 1612 __ push(r3);
1613 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 4); 1613 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
1614 break; 1614 break;
1615 1615
1616 case ObjectLiteral::Property::SETTER: 1616 case ObjectLiteral::Property::SETTER:
1617 __ mov(r3, Operand(Smi::FromInt(NONE))); 1617 __ mov(r3, Operand(Smi::FromInt(NONE)));
1618 __ push(r3); 1618 __ push(r3);
1619 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 4); 1619 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
1620 break; 1620 break;
1621 } 1621 }
1622 } 1622 }
1623 } 1623 }
1624 1624
1625 if (expr->has_function()) { 1625 if (expr->has_function()) {
1626 DCHECK(result_saved); 1626 DCHECK(result_saved);
1627 __ LoadP(r3, MemOperand(sp)); 1627 __ LoadP(r3, MemOperand(sp));
1628 __ push(r3); 1628 __ push(r3);
1629 __ CallRuntime(Runtime::kToFastProperties, 1); 1629 __ CallRuntime(Runtime::kToFastProperties);
1630 } 1630 }
1631 1631
1632 if (result_saved) { 1632 if (result_saved) {
1633 context()->PlugTOS(); 1633 context()->PlugTOS();
1634 } else { 1634 } else {
1635 context()->Plug(r3); 1635 context()->Plug(r3);
1636 } 1636 }
1637 } 1637 }
1638 1638
1639 1639
(...skipping 12 matching lines...) Expand all
1652 // we can turn it off if we don't have anywhere else to transition to. 1652 // we can turn it off if we don't have anywhere else to transition to.
1653 allocation_site_mode = DONT_TRACK_ALLOCATION_SITE; 1653 allocation_site_mode = DONT_TRACK_ALLOCATION_SITE;
1654 } 1654 }
1655 1655
1656 __ LoadP(r6, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 1656 __ LoadP(r6, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1657 __ LoadSmiLiteral(r5, Smi::FromInt(expr->literal_index())); 1657 __ LoadSmiLiteral(r5, Smi::FromInt(expr->literal_index()));
1658 __ mov(r4, Operand(constant_elements)); 1658 __ mov(r4, Operand(constant_elements));
1659 if (MustCreateArrayLiteralWithRuntime(expr)) { 1659 if (MustCreateArrayLiteralWithRuntime(expr)) {
1660 __ LoadSmiLiteral(r3, Smi::FromInt(expr->ComputeFlags())); 1660 __ LoadSmiLiteral(r3, Smi::FromInt(expr->ComputeFlags()));
1661 __ Push(r6, r5, r4, r3); 1661 __ Push(r6, r5, r4, r3);
1662 __ CallRuntime(Runtime::kCreateArrayLiteral, 4); 1662 __ CallRuntime(Runtime::kCreateArrayLiteral);
1663 } else { 1663 } else {
1664 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); 1664 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode);
1665 __ CallStub(&stub); 1665 __ CallStub(&stub);
1666 } 1666 }
1667 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1667 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
1668 1668
1669 bool result_saved = false; // Is the result saved to the stack? 1669 bool result_saved = false; // Is the result saved to the stack?
1670 ZoneList<Expression*>* subexprs = expr->values(); 1670 ZoneList<Expression*>* subexprs = expr->values();
1671 int length = subexprs->length(); 1671 int length = subexprs->length();
1672 1672
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1709 for (; array_index < length; array_index++) { 1709 for (; array_index < length; array_index++) {
1710 Expression* subexpr = subexprs->at(array_index); 1710 Expression* subexpr = subexprs->at(array_index);
1711 1711
1712 __ Push(r3); 1712 __ Push(r3);
1713 if (subexpr->IsSpread()) { 1713 if (subexpr->IsSpread()) {
1714 VisitForStackValue(subexpr->AsSpread()->expression()); 1714 VisitForStackValue(subexpr->AsSpread()->expression());
1715 __ InvokeBuiltin(Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX, 1715 __ InvokeBuiltin(Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX,
1716 CALL_FUNCTION); 1716 CALL_FUNCTION);
1717 } else { 1717 } else {
1718 VisitForStackValue(subexpr); 1718 VisitForStackValue(subexpr);
1719 __ CallRuntime(Runtime::kAppendElement, 2); 1719 __ CallRuntime(Runtime::kAppendElement);
1720 } 1720 }
1721 1721
1722 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1722 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1723 } 1723 }
1724 1724
1725 if (result_saved) { 1725 if (result_saved) {
1726 context()->PlugTOS(); 1726 context()->PlugTOS();
1727 } else { 1727 } else {
1728 context()->Plug(r3); 1728 context()->Plug(r3);
1729 } 1729 }
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
2128 Label operand_loop; 2128 Label operand_loop;
2129 __ mtctr(r6); 2129 __ mtctr(r6);
2130 __ bind(&operand_loop); 2130 __ bind(&operand_loop);
2131 __ push(r5); 2131 __ push(r5);
2132 __ bdnz(&operand_loop); 2132 __ bdnz(&operand_loop);
2133 2133
2134 __ bind(&call_resume); 2134 __ bind(&call_resume);
2135 DCHECK(!result_register().is(r4)); 2135 DCHECK(!result_register().is(r4));
2136 __ Push(r4, result_register()); 2136 __ Push(r4, result_register());
2137 __ Push(Smi::FromInt(resume_mode)); 2137 __ Push(Smi::FromInt(resume_mode));
2138 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); 2138 __ CallRuntime(Runtime::kResumeJSGeneratorObject);
2139 // Not reached: the runtime call returns elsewhere. 2139 // Not reached: the runtime call returns elsewhere.
2140 __ stop("not-reached"); 2140 __ stop("not-reached");
2141 2141
2142 __ bind(&done); 2142 __ bind(&done);
2143 context()->Plug(result_register()); 2143 context()->Plug(result_register());
2144 } 2144 }
2145 2145
2146 2146
2147 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { 2147 void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
2148 Label allocate, done_allocate; 2148 Label allocate, done_allocate;
2149 2149
2150 __ Allocate(JSIteratorResult::kSize, r3, r5, r6, &allocate, TAG_OBJECT); 2150 __ Allocate(JSIteratorResult::kSize, r3, r5, r6, &allocate, TAG_OBJECT);
2151 __ b(&done_allocate); 2151 __ b(&done_allocate);
2152 2152
2153 __ bind(&allocate); 2153 __ bind(&allocate);
2154 __ Push(Smi::FromInt(JSIteratorResult::kSize)); 2154 __ Push(Smi::FromInt(JSIteratorResult::kSize));
2155 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); 2155 __ CallRuntime(Runtime::kAllocateInNewSpace);
2156 2156
2157 __ bind(&done_allocate); 2157 __ bind(&done_allocate);
2158 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, r4); 2158 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, r4);
2159 __ pop(r5); 2159 __ pop(r5);
2160 __ LoadRoot(r6, 2160 __ LoadRoot(r6,
2161 done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex); 2161 done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex);
2162 __ LoadRoot(r7, Heap::kEmptyFixedArrayRootIndex); 2162 __ LoadRoot(r7, Heap::kEmptyFixedArrayRootIndex);
2163 __ StoreP(r4, FieldMemOperand(r3, HeapObject::kMapOffset), r0); 2163 __ StoreP(r4, FieldMemOperand(r3, HeapObject::kMapOffset), r0);
2164 __ StoreP(r7, FieldMemOperand(r3, JSObject::kPropertiesOffset), r0); 2164 __ StoreP(r7, FieldMemOperand(r3, JSObject::kPropertiesOffset), r0);
2165 __ StoreP(r7, FieldMemOperand(r3, JSObject::kElementsOffset), r0); 2165 __ StoreP(r7, FieldMemOperand(r3, JSObject::kElementsOffset), r0);
(...skipping 16 matching lines...) Expand all
2182 2182
2183 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { 2183 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
2184 // Stack: receiver, home_object. 2184 // Stack: receiver, home_object.
2185 SetExpressionPosition(prop); 2185 SetExpressionPosition(prop);
2186 Literal* key = prop->key()->AsLiteral(); 2186 Literal* key = prop->key()->AsLiteral();
2187 DCHECK(!key->value()->IsSmi()); 2187 DCHECK(!key->value()->IsSmi());
2188 DCHECK(prop->IsSuperAccess()); 2188 DCHECK(prop->IsSuperAccess());
2189 2189
2190 __ Push(key->value()); 2190 __ Push(key->value());
2191 __ Push(Smi::FromInt(language_mode())); 2191 __ Push(Smi::FromInt(language_mode()));
2192 __ CallRuntime(Runtime::kLoadFromSuper, 4); 2192 __ CallRuntime(Runtime::kLoadFromSuper);
2193 } 2193 }
2194 2194
2195 2195
2196 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 2196 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2197 SetExpressionPosition(prop); 2197 SetExpressionPosition(prop);
2198 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code(); 2198 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
2199 __ mov(LoadDescriptor::SlotRegister(), 2199 __ mov(LoadDescriptor::SlotRegister(),
2200 Operand(SmiFromSlot(prop->PropertyFeedbackSlot()))); 2200 Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
2201 CallIC(ic); 2201 CallIC(ic);
2202 } 2202 }
2203 2203
2204 2204
2205 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { 2205 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
2206 // Stack: receiver, home_object, key. 2206 // Stack: receiver, home_object, key.
2207 SetExpressionPosition(prop); 2207 SetExpressionPosition(prop);
2208 __ Push(Smi::FromInt(language_mode())); 2208 __ Push(Smi::FromInt(language_mode()));
2209 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4); 2209 __ CallRuntime(Runtime::kLoadKeyedFromSuper);
2210 } 2210 }
2211 2211
2212 2212
2213 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 2213 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
2214 Token::Value op, 2214 Token::Value op,
2215 Expression* left_expr, 2215 Expression* left_expr,
2216 Expression* right_expr) { 2216 Expression* right_expr) {
2217 Label done, smi_case, stub_call; 2217 Label done, smi_case, stub_call;
2218 2218
2219 Register scratch1 = r5; 2219 Register scratch1 = r5;
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
2358 __ LoadP(scratch, MemOperand(sp, 0)); // prototype 2358 __ LoadP(scratch, MemOperand(sp, 0)); // prototype
2359 } 2359 }
2360 __ push(scratch); 2360 __ push(scratch);
2361 EmitPropertyKey(property, lit->GetIdForProperty(i)); 2361 EmitPropertyKey(property, lit->GetIdForProperty(i));
2362 2362
2363 // The static prototype property is read only. We handle the non computed 2363 // The static prototype property is read only. We handle the non computed
2364 // property name case in the parser. Since this is the only case where we 2364 // property name case in the parser. Since this is the only case where we
2365 // need to check for an own read only property we special case this so we do 2365 // need to check for an own read only property we special case this so we do
2366 // not need to do this for every property. 2366 // not need to do this for every property.
2367 if (property->is_static() && property->is_computed_name()) { 2367 if (property->is_static() && property->is_computed_name()) {
2368 __ CallRuntime(Runtime::kThrowIfStaticPrototype, 1); 2368 __ CallRuntime(Runtime::kThrowIfStaticPrototype);
2369 __ push(r3); 2369 __ push(r3);
2370 } 2370 }
2371 2371
2372 VisitForStackValue(value); 2372 VisitForStackValue(value);
2373 if (NeedsHomeObject(value)) { 2373 if (NeedsHomeObject(value)) {
2374 EmitSetHomeObject(value, 2, property->GetSlot()); 2374 EmitSetHomeObject(value, 2, property->GetSlot());
2375 } 2375 }
2376 2376
2377 switch (property->kind()) { 2377 switch (property->kind()) {
2378 case ObjectLiteral::Property::CONSTANT: 2378 case ObjectLiteral::Property::CONSTANT:
2379 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 2379 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
2380 case ObjectLiteral::Property::PROTOTYPE: 2380 case ObjectLiteral::Property::PROTOTYPE:
2381 UNREACHABLE(); 2381 UNREACHABLE();
2382 case ObjectLiteral::Property::COMPUTED: 2382 case ObjectLiteral::Property::COMPUTED:
2383 __ CallRuntime(Runtime::kDefineClassMethod, 3); 2383 __ CallRuntime(Runtime::kDefineClassMethod);
2384 break; 2384 break;
2385 2385
2386 case ObjectLiteral::Property::GETTER: 2386 case ObjectLiteral::Property::GETTER:
2387 __ mov(r3, Operand(Smi::FromInt(DONT_ENUM))); 2387 __ mov(r3, Operand(Smi::FromInt(DONT_ENUM)));
2388 __ push(r3); 2388 __ push(r3);
2389 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 4); 2389 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
2390 break; 2390 break;
2391 2391
2392 case ObjectLiteral::Property::SETTER: 2392 case ObjectLiteral::Property::SETTER:
2393 __ mov(r3, Operand(Smi::FromInt(DONT_ENUM))); 2393 __ mov(r3, Operand(Smi::FromInt(DONT_ENUM)));
2394 __ push(r3); 2394 __ push(r3);
2395 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 4); 2395 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
2396 break; 2396 break;
2397 2397
2398 default: 2398 default:
2399 UNREACHABLE(); 2399 UNREACHABLE();
2400 } 2400 }
2401 } 2401 }
2402 2402
2403 // Set both the prototype and constructor to have fast properties, and also 2403 // Set both the prototype and constructor to have fast properties, and also
2404 // freeze them in strong mode. 2404 // freeze them in strong mode.
2405 __ CallRuntime(Runtime::kFinalizeClassDefinition, 2); 2405 __ CallRuntime(Runtime::kFinalizeClassDefinition);
2406 } 2406 }
2407 2407
2408 2408
2409 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { 2409 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
2410 __ pop(r4); 2410 __ pop(r4);
2411 Handle<Code> code = 2411 Handle<Code> code =
2412 CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code(); 2412 CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
2413 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 2413 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
2414 CallIC(code, expr->BinaryOperationFeedbackId()); 2414 CallIC(code, expr->BinaryOperationFeedbackId());
2415 patch_site.EmitPatchInfo(); 2415 patch_site.EmitPatchInfo();
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
2523 // Non-initializing assignment to let variable needs a write barrier. 2523 // Non-initializing assignment to let variable needs a write barrier.
2524 DCHECK(!var->IsLookupSlot()); 2524 DCHECK(!var->IsLookupSlot());
2525 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2525 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2526 Label assign; 2526 Label assign;
2527 MemOperand location = VarOperand(var, r4); 2527 MemOperand location = VarOperand(var, r4);
2528 __ LoadP(r6, location); 2528 __ LoadP(r6, location);
2529 __ CompareRoot(r6, Heap::kTheHoleValueRootIndex); 2529 __ CompareRoot(r6, Heap::kTheHoleValueRootIndex);
2530 __ bne(&assign); 2530 __ bne(&assign);
2531 __ mov(r6, Operand(var->name())); 2531 __ mov(r6, Operand(var->name()));
2532 __ push(r6); 2532 __ push(r6);
2533 __ CallRuntime(Runtime::kThrowReferenceError, 1); 2533 __ CallRuntime(Runtime::kThrowReferenceError);
2534 // Perform the assignment. 2534 // Perform the assignment.
2535 __ bind(&assign); 2535 __ bind(&assign);
2536 EmitStoreToStackLocalOrContextSlot(var, location); 2536 EmitStoreToStackLocalOrContextSlot(var, location);
2537 2537
2538 } else if (var->mode() == CONST && op != Token::INIT) { 2538 } else if (var->mode() == CONST && op != Token::INIT) {
2539 // Assignment to const variable needs a write barrier. 2539 // Assignment to const variable needs a write barrier.
2540 DCHECK(!var->IsLookupSlot()); 2540 DCHECK(!var->IsLookupSlot());
2541 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2541 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2542 Label const_error; 2542 Label const_error;
2543 MemOperand location = VarOperand(var, r4); 2543 MemOperand location = VarOperand(var, r4);
2544 __ LoadP(r6, location); 2544 __ LoadP(r6, location);
2545 __ CompareRoot(r6, Heap::kTheHoleValueRootIndex); 2545 __ CompareRoot(r6, Heap::kTheHoleValueRootIndex);
2546 __ bne(&const_error); 2546 __ bne(&const_error);
2547 __ mov(r6, Operand(var->name())); 2547 __ mov(r6, Operand(var->name()));
2548 __ push(r6); 2548 __ push(r6);
2549 __ CallRuntime(Runtime::kThrowReferenceError, 1); 2549 __ CallRuntime(Runtime::kThrowReferenceError);
2550 __ bind(&const_error); 2550 __ bind(&const_error);
2551 __ CallRuntime(Runtime::kThrowConstAssignError, 0); 2551 __ CallRuntime(Runtime::kThrowConstAssignError);
2552 2552
2553 } else if (var->is_this() && var->mode() == CONST && op == Token::INIT) { 2553 } else if (var->is_this() && var->mode() == CONST && op == Token::INIT) {
2554 // Initializing assignment to const {this} needs a write barrier. 2554 // Initializing assignment to const {this} needs a write barrier.
2555 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2555 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2556 Label uninitialized_this; 2556 Label uninitialized_this;
2557 MemOperand location = VarOperand(var, r4); 2557 MemOperand location = VarOperand(var, r4);
2558 __ LoadP(r6, location); 2558 __ LoadP(r6, location);
2559 __ CompareRoot(r6, Heap::kTheHoleValueRootIndex); 2559 __ CompareRoot(r6, Heap::kTheHoleValueRootIndex);
2560 __ beq(&uninitialized_this); 2560 __ beq(&uninitialized_this);
2561 __ mov(r4, Operand(var->name())); 2561 __ mov(r4, Operand(var->name()));
2562 __ push(r4); 2562 __ push(r4);
2563 __ CallRuntime(Runtime::kThrowReferenceError, 1); 2563 __ CallRuntime(Runtime::kThrowReferenceError);
2564 __ bind(&uninitialized_this); 2564 __ bind(&uninitialized_this);
2565 EmitStoreToStackLocalOrContextSlot(var, location); 2565 EmitStoreToStackLocalOrContextSlot(var, location);
2566 2566
2567 } else if (!var->is_const_mode() || 2567 } else if (!var->is_const_mode() ||
2568 (var->mode() == CONST && op == Token::INIT)) { 2568 (var->mode() == CONST && op == Token::INIT)) {
2569 if (var->IsLookupSlot()) { 2569 if (var->IsLookupSlot()) {
2570 // Assignment to var. 2570 // Assignment to var.
2571 __ push(r3); // Value. 2571 __ push(r3); // Value.
2572 __ mov(r4, Operand(var->name())); 2572 __ mov(r4, Operand(var->name()));
2573 __ mov(r3, Operand(Smi::FromInt(language_mode()))); 2573 __ mov(r3, Operand(Smi::FromInt(language_mode())));
2574 __ Push(cp, r4, r3); // Context, name, language mode. 2574 __ Push(cp, r4, r3); // Context, name, language mode.
2575 __ CallRuntime(Runtime::kStoreLookupSlot, 4); 2575 __ CallRuntime(Runtime::kStoreLookupSlot);
2576 } else { 2576 } else {
2577 // Assignment to var or initializing assignment to let/const in harmony 2577 // Assignment to var or initializing assignment to let/const in harmony
2578 // mode. 2578 // mode.
2579 DCHECK((var->IsStackAllocated() || var->IsContextSlot())); 2579 DCHECK((var->IsStackAllocated() || var->IsContextSlot()));
2580 MemOperand location = VarOperand(var, r4); 2580 MemOperand location = VarOperand(var, r4);
2581 if (generate_debug_code_ && var->mode() == LET && op == Token::INIT) { 2581 if (generate_debug_code_ && var->mode() == LET && op == Token::INIT) {
2582 // Check for an uninitialized let binding. 2582 // Check for an uninitialized let binding.
2583 __ LoadP(r5, location); 2583 __ LoadP(r5, location);
2584 __ CompareRoot(r5, Heap::kTheHoleValueRootIndex); 2584 __ CompareRoot(r5, Heap::kTheHoleValueRootIndex);
2585 __ Check(eq, kLetBindingReInitialization); 2585 __ Check(eq, kLetBindingReInitialization);
2586 } 2586 }
2587 EmitStoreToStackLocalOrContextSlot(var, location); 2587 EmitStoreToStackLocalOrContextSlot(var, location);
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 __ push(r3); 2593 __ push(r3);
2594 __ mov(r3, Operand(var->name())); 2594 __ mov(r3, Operand(var->name()));
2595 __ Push(cp, r3); // Context and name. 2595 __ Push(cp, r3); // Context and name.
2596 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); 2596 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot);
2597 } else { 2597 } else {
2598 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2598 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2599 Label skip; 2599 Label skip;
2600 MemOperand location = VarOperand(var, r4); 2600 MemOperand location = VarOperand(var, r4);
2601 __ LoadP(r5, location); 2601 __ LoadP(r5, location);
2602 __ CompareRoot(r5, Heap::kTheHoleValueRootIndex); 2602 __ CompareRoot(r5, Heap::kTheHoleValueRootIndex);
2603 __ bne(&skip); 2603 __ bne(&skip);
2604 EmitStoreToStackLocalOrContextSlot(var, location); 2604 EmitStoreToStackLocalOrContextSlot(var, location);
2605 __ bind(&skip); 2605 __ bind(&skip);
2606 } 2606 }
2607 2607
2608 } else { 2608 } else {
2609 DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT); 2609 DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT);
2610 if (is_strict(language_mode())) { 2610 if (is_strict(language_mode())) {
2611 __ CallRuntime(Runtime::kThrowConstAssignError, 0); 2611 __ CallRuntime(Runtime::kThrowConstAssignError);
2612 } 2612 }
2613 // Silently ignore store in sloppy mode. 2613 // Silently ignore store in sloppy mode.
2614 } 2614 }
2615 } 2615 }
2616 2616
2617 2617
2618 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2618 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2619 // Assignment to a property, using a named store IC. 2619 // Assignment to a property, using a named store IC.
2620 Property* prop = expr->target()->AsProperty(); 2620 Property* prop = expr->target()->AsProperty();
2621 DCHECK(prop != NULL); 2621 DCHECK(prop != NULL);
(...skipping 14 matching lines...) Expand all
2636 // Assignment to named property of super. 2636 // Assignment to named property of super.
2637 // r3 : value 2637 // r3 : 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(r3); 2644 __ Push(r3);
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 // r3 : value 2652 // r3 : 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(r3); 2656 __ Push(r3);
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 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); 2665 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister());
2668 DCHECK(StoreDescriptor::ValueRegister().is(r3)); 2666 DCHECK(StoreDescriptor::ValueRegister().is(r3));
2669 2667
2670 Handle<Code> ic = 2668 Handle<Code> ic =
2671 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2669 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
2774 __ Push(key->value()); 2772 __ Push(key->value());
2775 __ Push(Smi::FromInt(language_mode())); 2773 __ Push(Smi::FromInt(language_mode()));
2776 2774
2777 // Stack here: 2775 // Stack here:
2778 // - home_object 2776 // - home_object
2779 // - this (receiver) 2777 // - this (receiver)
2780 // - this (receiver) <-- LoadFromSuper will pop here and below. 2778 // - this (receiver) <-- LoadFromSuper will pop here and below.
2781 // - home_object 2779 // - home_object
2782 // - key 2780 // - key
2783 // - language_mode 2781 // - language_mode
2784 __ CallRuntime(Runtime::kLoadFromSuper, 4); 2782 __ CallRuntime(Runtime::kLoadFromSuper);
2785 2783
2786 // Replace home_object with target function. 2784 // Replace home_object with target function.
2787 __ StoreP(r3, MemOperand(sp, kPointerSize)); 2785 __ StoreP(r3, MemOperand(sp, kPointerSize));
2788 2786
2789 // Stack here: 2787 // Stack here:
2790 // - target function 2788 // - target function
2791 // - this (receiver) 2789 // - this (receiver)
2792 EmitCall(expr); 2790 EmitCall(expr);
2793 } 2791 }
2794 2792
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2833 VisitForStackValue(prop->key()); 2831 VisitForStackValue(prop->key());
2834 __ Push(Smi::FromInt(language_mode())); 2832 __ Push(Smi::FromInt(language_mode()));
2835 2833
2836 // Stack here: 2834 // Stack here:
2837 // - home_object 2835 // - home_object
2838 // - this (receiver) 2836 // - this (receiver)
2839 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. 2837 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
2840 // - home_object 2838 // - home_object
2841 // - key 2839 // - key
2842 // - language_mode 2840 // - language_mode
2843 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4); 2841 __ CallRuntime(Runtime::kLoadKeyedFromSuper);
2844 2842
2845 // Replace home_object with target function. 2843 // Replace home_object with target function.
2846 __ StoreP(r3, MemOperand(sp, kPointerSize)); 2844 __ StoreP(r3, MemOperand(sp, kPointerSize));
2847 2845
2848 // Stack here: 2846 // Stack here:
2849 // - target function 2847 // - target function
2850 // - this (receiver) 2848 // - this (receiver)
2851 EmitCall(expr); 2849 EmitCall(expr);
2852 } 2850 }
2853 2851
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2888 __ LoadP(r6, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 2886 __ LoadP(r6, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
2889 2887
2890 // r5: language mode. 2888 // r5: language mode.
2891 __ LoadSmiLiteral(r5, Smi::FromInt(language_mode())); 2889 __ LoadSmiLiteral(r5, Smi::FromInt(language_mode()));
2892 2890
2893 // r4: the start position of the scope the calls resides in. 2891 // r4: the start position of the scope the calls resides in.
2894 __ LoadSmiLiteral(r4, Smi::FromInt(scope()->start_position())); 2892 __ LoadSmiLiteral(r4, Smi::FromInt(scope()->start_position()));
2895 2893
2896 // Do the runtime call. 2894 // Do the runtime call.
2897 __ Push(r7, r6, r5, r4); 2895 __ Push(r7, r6, r5, r4);
2898 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); 2896 __ CallRuntime(Runtime::kResolvePossiblyDirectEval);
2899 } 2897 }
2900 2898
2901 2899
2902 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. 2900 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls.
2903 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { 2901 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
2904 VariableProxy* callee = expr->expression()->AsVariableProxy(); 2902 VariableProxy* callee = expr->expression()->AsVariableProxy();
2905 if (callee->var()->IsLookupSlot()) { 2903 if (callee->var()->IsLookupSlot()) {
2906 Label slow, done; 2904 Label slow, done;
2907 SetExpressionPosition(callee); 2905 SetExpressionPosition(callee);
2908 // Generate code for loading from variables potentially shadowed by 2906 // Generate code for loading from variables potentially shadowed by
2909 // eval-introduced variables. 2907 // eval-introduced variables.
2910 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); 2908 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2911 2909
2912 __ bind(&slow); 2910 __ bind(&slow);
2913 // Call the runtime to find the function to call (returned in r3) and 2911 // Call the runtime to find the function to call (returned in r3) and
2914 // the object holding it (returned in r4). 2912 // the object holding it (returned in r4).
2915 DCHECK(!context_register().is(r5)); 2913 DCHECK(!context_register().is(r5));
2916 __ mov(r5, Operand(callee->name())); 2914 __ mov(r5, Operand(callee->name()));
2917 __ Push(context_register(), r5); 2915 __ Push(context_register(), r5);
2918 __ CallRuntime(Runtime::kLoadLookupSlot, 2); 2916 __ CallRuntime(Runtime::kLoadLookupSlot);
2919 __ Push(r3, r4); // Function, receiver. 2917 __ Push(r3, r4); // Function, receiver.
2920 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); 2918 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
2921 2919
2922 // If fast case code has been generated, emit code to push the function 2920 // If fast case code has been generated, emit code to push the function
2923 // and receiver and have the slow path jump around this code. 2921 // and receiver and have the slow path jump around this code.
2924 if (done.is_linked()) { 2922 if (done.is_linked()) {
2925 Label call; 2923 Label call;
2926 __ b(&call); 2924 __ b(&call);
2927 __ bind(&done); 2925 __ bind(&done);
2928 // Push function. 2926 // Push function.
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after
3565 ZoneList<Expression*>* args = expr->arguments(); 3563 ZoneList<Expression*>* args = expr->arguments();
3566 DCHECK_EQ(1, args->length()); 3564 DCHECK_EQ(1, args->length());
3567 3565
3568 // Load the argument into r3 and convert it. 3566 // Load the argument into r3 and convert it.
3569 VisitForAccumulatorValue(args->at(0)); 3567 VisitForAccumulatorValue(args->at(0));
3570 3568
3571 // Convert the object to an integer. 3569 // Convert the object to an integer.
3572 Label done_convert; 3570 Label done_convert;
3573 __ JumpIfSmi(r3, &done_convert); 3571 __ JumpIfSmi(r3, &done_convert);
3574 __ Push(r3); 3572 __ Push(r3);
3575 __ CallRuntime(Runtime::kToInteger, 1); 3573 __ CallRuntime(Runtime::kToInteger);
3576 __ bind(&done_convert); 3574 __ bind(&done_convert);
3577 context()->Plug(r3); 3575 context()->Plug(r3);
3578 } 3576 }
3579 3577
3580 3578
3581 void FullCodeGenerator::EmitToName(CallRuntime* expr) { 3579 void FullCodeGenerator::EmitToName(CallRuntime* expr) {
3582 ZoneList<Expression*>* args = expr->arguments(); 3580 ZoneList<Expression*>* args = expr->arguments();
3583 DCHECK_EQ(1, args->length()); 3581 DCHECK_EQ(1, args->length());
3584 3582
3585 // Load the argument into r3 and convert it. 3583 // Load the argument into r3 and convert it.
3586 VisitForAccumulatorValue(args->at(0)); 3584 VisitForAccumulatorValue(args->at(0));
3587 3585
3588 Label convert, done_convert; 3586 Label convert, done_convert;
3589 __ JumpIfSmi(r3, &convert); 3587 __ JumpIfSmi(r3, &convert);
3590 STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE); 3588 STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE);
3591 __ CompareObjectType(r3, r4, r4, LAST_NAME_TYPE); 3589 __ CompareObjectType(r3, r4, r4, LAST_NAME_TYPE);
3592 __ ble(&done_convert); 3590 __ ble(&done_convert);
3593 __ bind(&convert); 3591 __ bind(&convert);
3594 __ Push(r3); 3592 __ Push(r3);
3595 __ CallRuntime(Runtime::kToName, 1); 3593 __ CallRuntime(Runtime::kToName);
3596 __ bind(&done_convert); 3594 __ bind(&done_convert);
3597 context()->Plug(r3); 3595 context()->Plug(r3);
3598 } 3596 }
3599 3597
3600 3598
3601 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { 3599 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) {
3602 ZoneList<Expression*>* args = expr->arguments(); 3600 ZoneList<Expression*>* args = expr->arguments();
3603 DCHECK(args->length() == 1); 3601 DCHECK(args->length() == 1);
3604 VisitForAccumulatorValue(args->at(0)); 3602 VisitForAccumulatorValue(args->at(0));
3605 3603
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
4047 __ LoadRoot(r7, Heap::kEmptyFixedArrayRootIndex); 4045 __ LoadRoot(r7, Heap::kEmptyFixedArrayRootIndex);
4048 __ StoreP(r4, FieldMemOperand(r3, HeapObject::kMapOffset), r0); 4046 __ StoreP(r4, FieldMemOperand(r3, HeapObject::kMapOffset), r0);
4049 __ StoreP(r7, FieldMemOperand(r3, JSObject::kPropertiesOffset), r0); 4047 __ StoreP(r7, FieldMemOperand(r3, JSObject::kPropertiesOffset), r0);
4050 __ StoreP(r7, FieldMemOperand(r3, JSObject::kElementsOffset), r0); 4048 __ StoreP(r7, FieldMemOperand(r3, JSObject::kElementsOffset), r0);
4051 __ StoreP(r5, FieldMemOperand(r3, JSIteratorResult::kValueOffset), r0); 4049 __ StoreP(r5, FieldMemOperand(r3, JSIteratorResult::kValueOffset), r0);
4052 __ StoreP(r6, FieldMemOperand(r3, JSIteratorResult::kDoneOffset), r0); 4050 __ StoreP(r6, FieldMemOperand(r3, JSIteratorResult::kDoneOffset), r0);
4053 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); 4051 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize);
4054 __ b(&done); 4052 __ b(&done);
4055 4053
4056 __ bind(&runtime); 4054 __ bind(&runtime);
4057 __ CallRuntime(Runtime::kCreateIterResultObject, 2); 4055 __ CallRuntime(Runtime::kCreateIterResultObject);
4058 4056
4059 __ bind(&done); 4057 __ bind(&done);
4060 context()->Plug(r3); 4058 context()->Plug(r3);
4061 } 4059 }
4062 4060
4063 4061
4064 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { 4062 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
4065 // Push undefined as the receiver. 4063 // Push undefined as the receiver.
4066 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex); 4064 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex);
4067 __ push(r3); 4065 __ push(r3);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
4140 case Token::DELETE: { 4138 case Token::DELETE: {
4141 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 4139 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
4142 Property* property = expr->expression()->AsProperty(); 4140 Property* property = expr->expression()->AsProperty();
4143 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 4141 VariableProxy* proxy = expr->expression()->AsVariableProxy();
4144 4142
4145 if (property != NULL) { 4143 if (property != NULL) {
4146 VisitForStackValue(property->obj()); 4144 VisitForStackValue(property->obj());
4147 VisitForStackValue(property->key()); 4145 VisitForStackValue(property->key());
4148 __ CallRuntime(is_strict(language_mode()) 4146 __ CallRuntime(is_strict(language_mode())
4149 ? Runtime::kDeleteProperty_Strict 4147 ? Runtime::kDeleteProperty_Strict
4150 : Runtime::kDeleteProperty_Sloppy, 4148 : Runtime::kDeleteProperty_Sloppy);
4151 2);
4152 context()->Plug(r3); 4149 context()->Plug(r3);
4153 } else if (proxy != NULL) { 4150 } else if (proxy != NULL) {
4154 Variable* var = proxy->var(); 4151 Variable* var = proxy->var();
4155 // Delete of an unqualified identifier is disallowed in strict mode but 4152 // Delete of an unqualified identifier is disallowed in strict mode but
4156 // "delete this" is allowed. 4153 // "delete this" is allowed.
4157 bool is_this = var->HasThisName(isolate()); 4154 bool is_this = var->HasThisName(isolate());
4158 DCHECK(is_sloppy(language_mode()) || is_this); 4155 DCHECK(is_sloppy(language_mode()) || is_this);
4159 if (var->IsUnallocatedOrGlobalSlot()) { 4156 if (var->IsUnallocatedOrGlobalSlot()) {
4160 __ LoadGlobalObject(r5); 4157 __ LoadGlobalObject(r5);
4161 __ mov(r4, Operand(var->name())); 4158 __ mov(r4, Operand(var->name()));
4162 __ Push(r5, r4); 4159 __ Push(r5, r4);
4163 __ CallRuntime(Runtime::kDeleteProperty_Sloppy, 2); 4160 __ CallRuntime(Runtime::kDeleteProperty_Sloppy);
4164 context()->Plug(r3); 4161 context()->Plug(r3);
4165 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 4162 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
4166 // Result of deleting non-global, non-dynamic variables is false. 4163 // Result of deleting non-global, non-dynamic variables is false.
4167 // The subexpression does not have side effects. 4164 // The subexpression does not have side effects.
4168 context()->Plug(is_this); 4165 context()->Plug(is_this);
4169 } else { 4166 } else {
4170 // Non-global variable. Call the runtime to try to delete from the 4167 // Non-global variable. Call the runtime to try to delete from the
4171 // context where the variable was introduced. 4168 // context where the variable was introduced.
4172 DCHECK(!context_register().is(r5)); 4169 DCHECK(!context_register().is(r5));
4173 __ mov(r5, Operand(var->name())); 4170 __ mov(r5, Operand(var->name()));
4174 __ Push(context_register(), r5); 4171 __ Push(context_register(), r5);
4175 __ CallRuntime(Runtime::kDeleteLookupSlot, 2); 4172 __ CallRuntime(Runtime::kDeleteLookupSlot);
4176 context()->Plug(r3); 4173 context()->Plug(r3);
4177 } 4174 }
4178 } else { 4175 } else {
4179 // Result of deleting non-property, non-variable reference is true. 4176 // Result of deleting non-property, non-variable reference is true.
4180 // The subexpression may have side effects. 4177 // The subexpression may have side effects.
4181 VisitForEffect(expr->expression()); 4178 VisitForEffect(expr->expression());
4182 context()->Plug(true); 4179 context()->Plug(true);
4183 } 4180 }
4184 break; 4181 break;
4185 } 4182 }
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
4595 Label* if_false = NULL; 4592 Label* if_false = NULL;
4596 Label* fall_through = NULL; 4593 Label* fall_through = NULL;
4597 context()->PrepareTest(&materialize_true, &materialize_false, &if_true, 4594 context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
4598 &if_false, &fall_through); 4595 &if_false, &fall_through);
4599 4596
4600 Token::Value op = expr->op(); 4597 Token::Value op = expr->op();
4601 VisitForStackValue(expr->left()); 4598 VisitForStackValue(expr->left());
4602 switch (op) { 4599 switch (op) {
4603 case Token::IN: 4600 case Token::IN:
4604 VisitForStackValue(expr->right()); 4601 VisitForStackValue(expr->right());
4605 __ CallRuntime(Runtime::kHasProperty, 2); 4602 __ CallRuntime(Runtime::kHasProperty);
4606 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 4603 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
4607 __ CompareRoot(r3, Heap::kTrueValueRootIndex); 4604 __ CompareRoot(r3, Heap::kTrueValueRootIndex);
4608 Split(eq, if_true, if_false, fall_through); 4605 Split(eq, if_true, if_false, fall_through);
4609 break; 4606 break;
4610 4607
4611 case Token::INSTANCEOF: { 4608 case Token::INSTANCEOF: {
4612 VisitForAccumulatorValue(expr->right()); 4609 VisitForAccumulatorValue(expr->right());
4613 __ pop(r4); 4610 __ pop(r4);
4614 InstanceOfStub stub(isolate()); 4611 InstanceOfStub stub(isolate());
4615 __ CallStub(&stub); 4612 __ CallStub(&stub);
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
4858 return ON_STACK_REPLACEMENT; 4855 return ON_STACK_REPLACEMENT;
4859 } 4856 }
4860 4857
4861 DCHECK(interrupt_address == 4858 DCHECK(interrupt_address ==
4862 isolate->builtins()->OsrAfterStackCheck()->entry()); 4859 isolate->builtins()->OsrAfterStackCheck()->entry());
4863 return OSR_AFTER_STACK_CHECK; 4860 return OSR_AFTER_STACK_CHECK;
4864 } 4861 }
4865 } // namespace internal 4862 } // namespace internal
4866 } // namespace v8 4863 } // namespace v8
4867 #endif // V8_TARGET_ARCH_PPC 4864 #endif // V8_TARGET_ARCH_PPC
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698