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

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

Issue 196133017: Experimental parser: merge r19949 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « src/mips/frames-mips.h ('k') | src/mips/ic-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 // o sp: stack pointer 132 // o sp: stack pointer
133 // o ra: return address 133 // o ra: return address
134 // 134 //
135 // The function builds a JS frame. Please see JavaScriptFrameConstants in 135 // The function builds a JS frame. Please see JavaScriptFrameConstants in
136 // frames-mips.h for its layout. 136 // frames-mips.h for its layout.
137 void FullCodeGenerator::Generate() { 137 void FullCodeGenerator::Generate() {
138 CompilationInfo* info = info_; 138 CompilationInfo* info = info_;
139 handler_table_ = 139 handler_table_ =
140 isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED); 140 isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED);
141 141
142 InitializeFeedbackVector();
143
144 profiling_counter_ = isolate()->factory()->NewCell( 142 profiling_counter_ = isolate()->factory()->NewCell(
145 Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate())); 143 Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
146 SetFunctionPosition(function()); 144 SetFunctionPosition(function());
147 Comment cmnt(masm_, "[ function compiled by full code generator"); 145 Comment cmnt(masm_, "[ function compiled by full code generator");
148 146
149 ProfileEntryHookStub::MaybeCallEntryHook(masm_); 147 ProfileEntryHookStub::MaybeCallEntryHook(masm_);
150 148
151 #ifdef DEBUG 149 #ifdef DEBUG
152 if (strlen(FLAG_stop_at) > 0 && 150 if (strlen(FLAG_stop_at) > 0 &&
153 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { 151 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
154 __ stop("stop-at"); 152 __ stop("stop-at");
155 } 153 }
156 #endif 154 #endif
157 155
158 // Classic mode functions and builtins need to replace the receiver with the 156 // Sloppy mode functions and builtins need to replace the receiver with the
159 // global proxy when called as functions (without an explicit receiver 157 // global proxy when called as functions (without an explicit receiver
160 // object). 158 // object).
161 if (info->is_classic_mode() && !info->is_native()) { 159 if (info->strict_mode() == SLOPPY && !info->is_native()) {
162 Label ok; 160 Label ok;
163 int receiver_offset = info->scope()->num_parameters() * kPointerSize; 161 int receiver_offset = info->scope()->num_parameters() * kPointerSize;
164 __ lw(at, MemOperand(sp, receiver_offset)); 162 __ lw(at, MemOperand(sp, receiver_offset));
165 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); 163 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
166 __ Branch(&ok, ne, a2, Operand(at)); 164 __ Branch(&ok, ne, a2, Operand(at));
167 165
168 __ lw(a2, GlobalObjectOperand()); 166 __ lw(a2, GlobalObjectOperand());
169 __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset)); 167 __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset));
170 168
171 __ sw(a2, MemOperand(sp, receiver_offset)); 169 __ sw(a2, MemOperand(sp, receiver_offset));
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 __ Addu(a2, fp, 264 __ Addu(a2, fp,
267 Operand(StandardFrameConstants::kCallerSPOffset + offset)); 265 Operand(StandardFrameConstants::kCallerSPOffset + offset));
268 __ li(a1, Operand(Smi::FromInt(num_parameters))); 266 __ li(a1, Operand(Smi::FromInt(num_parameters)));
269 __ Push(a3, a2, a1); 267 __ Push(a3, a2, a1);
270 268
271 // Arguments to ArgumentsAccessStub: 269 // Arguments to ArgumentsAccessStub:
272 // function, receiver address, parameter count. 270 // function, receiver address, parameter count.
273 // The stub will rewrite receiever and parameter count if the previous 271 // The stub will rewrite receiever and parameter count if the previous
274 // stack frame was an arguments adapter frame. 272 // stack frame was an arguments adapter frame.
275 ArgumentsAccessStub::Type type; 273 ArgumentsAccessStub::Type type;
276 if (!is_classic_mode()) { 274 if (strict_mode() == STRICT) {
277 type = ArgumentsAccessStub::NEW_STRICT; 275 type = ArgumentsAccessStub::NEW_STRICT;
278 } else if (function()->has_duplicate_parameters()) { 276 } else if (function()->has_duplicate_parameters()) {
279 type = ArgumentsAccessStub::NEW_NON_STRICT_SLOW; 277 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
280 } else { 278 } else {
281 type = ArgumentsAccessStub::NEW_NON_STRICT_FAST; 279 type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
282 } 280 }
283 ArgumentsAccessStub stub(type); 281 ArgumentsAccessStub stub(type);
284 __ CallStub(&stub); 282 __ CallStub(&stub);
285 283
286 SetVar(arguments, v0, a1, a2); 284 SetVar(arguments, v0, a1, a2);
287 } 285 }
288 286
289 if (FLAG_trace) { 287 if (FLAG_trace) {
290 __ CallRuntime(Runtime::kTraceEnter, 0); 288 __ CallRuntime(Runtime::kTraceEnter, 0);
291 } 289 }
292 290
293 // Visit the declarations and body unless there is an illegal 291 // Visit the declarations and body unless there is an illegal
294 // redeclaration. 292 // redeclaration.
295 if (scope()->HasIllegalRedeclaration()) { 293 if (scope()->HasIllegalRedeclaration()) {
296 Comment cmnt(masm_, "[ Declarations"); 294 Comment cmnt(masm_, "[ Declarations");
297 scope()->VisitIllegalRedeclaration(this); 295 scope()->VisitIllegalRedeclaration(this);
298 296
299 } else { 297 } else {
300 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); 298 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS);
301 { Comment cmnt(masm_, "[ Declarations"); 299 { Comment cmnt(masm_, "[ Declarations");
302 // For named function expressions, declare the function name as a 300 // For named function expressions, declare the function name as a
303 // constant. 301 // constant.
304 if (scope()->is_function_scope() && scope()->function() != NULL) { 302 if (scope()->is_function_scope() && scope()->function() != NULL) {
305 VariableDeclaration* function = scope()->function(); 303 VariableDeclaration* function = scope()->function();
306 ASSERT(function->proxy()->var()->mode() == CONST || 304 ASSERT(function->proxy()->var()->mode() == CONST ||
307 function->proxy()->var()->mode() == CONST_HARMONY); 305 function->proxy()->var()->mode() == CONST_LEGACY);
308 ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED); 306 ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED);
309 VisitVariableDeclaration(function); 307 VisitVariableDeclaration(function);
310 } 308 }
311 VisitDeclarations(scope()->declarations()); 309 VisitDeclarations(scope()->declarations());
312 } 310 }
313 311
314 { Comment cmnt(masm_, "[ Stack check"); 312 { Comment cmnt(masm_, "[ Stack check");
315 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); 313 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS);
316 Label ok; 314 Label ok;
317 __ LoadRoot(t0, Heap::kStackLimitRootIndex); 315 __ LoadRoot(t0, Heap::kStackLimitRootIndex);
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 796
799 797
800 void FullCodeGenerator::VisitVariableDeclaration( 798 void FullCodeGenerator::VisitVariableDeclaration(
801 VariableDeclaration* declaration) { 799 VariableDeclaration* declaration) {
802 // If it was not possible to allocate the variable at compile time, we 800 // If it was not possible to allocate the variable at compile time, we
803 // need to "declare" it at runtime to make sure it actually exists in the 801 // need to "declare" it at runtime to make sure it actually exists in the
804 // local context. 802 // local context.
805 VariableProxy* proxy = declaration->proxy(); 803 VariableProxy* proxy = declaration->proxy();
806 VariableMode mode = declaration->mode(); 804 VariableMode mode = declaration->mode();
807 Variable* variable = proxy->var(); 805 Variable* variable = proxy->var();
808 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; 806 bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY;
809 switch (variable->location()) { 807 switch (variable->location()) {
810 case Variable::UNALLOCATED: 808 case Variable::UNALLOCATED:
811 globals_->Add(variable->name(), zone()); 809 globals_->Add(variable->name(), zone());
812 globals_->Add(variable->binding_needs_init() 810 globals_->Add(variable->binding_needs_init()
813 ? isolate()->factory()->the_hole_value() 811 ? isolate()->factory()->the_hole_value()
814 : isolate()->factory()->undefined_value(), 812 : isolate()->factory()->undefined_value(),
815 zone()); 813 zone());
816 break; 814 break;
817 815
818 case Variable::PARAMETER: 816 case Variable::PARAMETER:
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
1169 __ jmp(&loop); 1167 __ jmp(&loop);
1170 1168
1171 __ bind(&no_descriptors); 1169 __ bind(&no_descriptors);
1172 __ Drop(1); 1170 __ Drop(1);
1173 __ jmp(&exit); 1171 __ jmp(&exit);
1174 1172
1175 // We got a fixed array in register v0. Iterate through that. 1173 // We got a fixed array in register v0. Iterate through that.
1176 Label non_proxy; 1174 Label non_proxy;
1177 __ bind(&fixed_array); 1175 __ bind(&fixed_array);
1178 1176
1179 Handle<Object> feedback = Handle<Object>(
1180 Smi::FromInt(TypeFeedbackInfo::kForInFastCaseMarker),
1181 isolate());
1182 StoreFeedbackVectorSlot(slot, feedback);
1183 __ li(a1, FeedbackVector()); 1177 __ li(a1, FeedbackVector());
1184 __ li(a2, Operand(Smi::FromInt(TypeFeedbackInfo::kForInSlowCaseMarker))); 1178 __ li(a2, Operand(TypeFeedbackInfo::MegamorphicSentinel(isolate())));
1185 __ sw(a2, FieldMemOperand(a1, FixedArray::OffsetOfElementAt(slot))); 1179 __ sw(a2, FieldMemOperand(a1, FixedArray::OffsetOfElementAt(slot)));
1186 1180
1187 __ li(a1, Operand(Smi::FromInt(1))); // Smi indicates slow check 1181 __ li(a1, Operand(Smi::FromInt(1))); // Smi indicates slow check
1188 __ lw(a2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object 1182 __ lw(a2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object
1189 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); 1183 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
1190 __ GetObjectType(a2, a3, a3); 1184 __ GetObjectType(a2, a3, a3);
1191 __ Branch(&non_proxy, gt, a3, Operand(LAST_JS_PROXY_TYPE)); 1185 __ Branch(&non_proxy, gt, a3, Operand(LAST_JS_PROXY_TYPE));
1192 __ li(a1, Operand(Smi::FromInt(0))); // Zero indicates proxy 1186 __ li(a1, Operand(Smi::FromInt(0))); // Zero indicates proxy
1193 __ bind(&non_proxy); 1187 __ bind(&non_proxy);
1194 __ Push(a1, v0); // Smi and array 1188 __ Push(a1, v0); // Smi and array
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1335 // space for nested functions that don't need literals cloning. If 1329 // space for nested functions that don't need literals cloning. If
1336 // we're running with the --always-opt or the --prepare-always-opt 1330 // we're running with the --always-opt or the --prepare-always-opt
1337 // flag, we need to use the runtime function so that the new function 1331 // flag, we need to use the runtime function so that the new function
1338 // we are creating here gets a chance to have its code optimized and 1332 // we are creating here gets a chance to have its code optimized and
1339 // doesn't just get a copy of the existing unoptimized code. 1333 // doesn't just get a copy of the existing unoptimized code.
1340 if (!FLAG_always_opt && 1334 if (!FLAG_always_opt &&
1341 !FLAG_prepare_always_opt && 1335 !FLAG_prepare_always_opt &&
1342 !pretenure && 1336 !pretenure &&
1343 scope()->is_function_scope() && 1337 scope()->is_function_scope() &&
1344 info->num_literals() == 0) { 1338 info->num_literals() == 0) {
1345 FastNewClosureStub stub(info->language_mode(), info->is_generator()); 1339 FastNewClosureStub stub(info->strict_mode(), info->is_generator());
1346 __ li(a2, Operand(info)); 1340 __ li(a2, Operand(info));
1347 __ CallStub(&stub); 1341 __ CallStub(&stub);
1348 } else { 1342 } else {
1349 __ li(a0, Operand(info)); 1343 __ li(a0, Operand(info));
1350 __ LoadRoot(a1, pretenure ? Heap::kTrueValueRootIndex 1344 __ LoadRoot(a1, pretenure ? Heap::kTrueValueRootIndex
1351 : Heap::kFalseValueRootIndex); 1345 : Heap::kFalseValueRootIndex);
1352 __ Push(cp, a0, a1); 1346 __ Push(cp, a0, a1);
1353 __ CallRuntime(Runtime::kNewClosure, 3); 1347 __ CallRuntime(Runtime::kNewClosure, 3);
1354 } 1348 }
1355 context()->Plug(v0); 1349 context()->Plug(v0);
1356 } 1350 }
1357 1351
1358 1352
1359 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { 1353 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
1360 Comment cmnt(masm_, "[ VariableProxy"); 1354 Comment cmnt(masm_, "[ VariableProxy");
1361 EmitVariableLoad(expr); 1355 EmitVariableLoad(expr);
1362 } 1356 }
1363 1357
1364 1358
1365 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var, 1359 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var,
1366 TypeofState typeof_state, 1360 TypeofState typeof_state,
1367 Label* slow) { 1361 Label* slow) {
1368 Register current = cp; 1362 Register current = cp;
1369 Register next = a1; 1363 Register next = a1;
1370 Register temp = a2; 1364 Register temp = a2;
1371 1365
1372 Scope* s = scope(); 1366 Scope* s = scope();
1373 while (s != NULL) { 1367 while (s != NULL) {
1374 if (s->num_heap_slots() > 0) { 1368 if (s->num_heap_slots() > 0) {
1375 if (s->calls_non_strict_eval()) { 1369 if (s->calls_sloppy_eval()) {
1376 // Check that extension is NULL. 1370 // Check that extension is NULL.
1377 __ lw(temp, ContextOperand(current, Context::EXTENSION_INDEX)); 1371 __ lw(temp, ContextOperand(current, Context::EXTENSION_INDEX));
1378 __ Branch(slow, ne, temp, Operand(zero_reg)); 1372 __ Branch(slow, ne, temp, Operand(zero_reg));
1379 } 1373 }
1380 // Load next context in chain. 1374 // Load next context in chain.
1381 __ lw(next, ContextOperand(current, Context::PREVIOUS_INDEX)); 1375 __ lw(next, ContextOperand(current, Context::PREVIOUS_INDEX));
1382 // Walk the rest of the chain without clobbering cp. 1376 // Walk the rest of the chain without clobbering cp.
1383 current = next; 1377 current = next;
1384 } 1378 }
1385 // If no outer scope calls eval, we do not need to check more 1379 // If no outer scope calls eval, we do not need to check more
1386 // context extensions. 1380 // context extensions.
1387 if (!s->outer_scope_calls_non_strict_eval() || s->is_eval_scope()) break; 1381 if (!s->outer_scope_calls_sloppy_eval() || s->is_eval_scope()) break;
1388 s = s->outer_scope(); 1382 s = s->outer_scope();
1389 } 1383 }
1390 1384
1391 if (s->is_eval_scope()) { 1385 if (s->is_eval_scope()) {
1392 Label loop, fast; 1386 Label loop, fast;
1393 if (!current.is(next)) { 1387 if (!current.is(next)) {
1394 __ Move(next, current); 1388 __ Move(next, current);
1395 } 1389 }
1396 __ bind(&loop); 1390 __ bind(&loop);
1397 // Terminate at native context. 1391 // Terminate at native context.
(...skipping 20 matching lines...) Expand all
1418 1412
1419 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, 1413 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
1420 Label* slow) { 1414 Label* slow) {
1421 ASSERT(var->IsContextSlot()); 1415 ASSERT(var->IsContextSlot());
1422 Register context = cp; 1416 Register context = cp;
1423 Register next = a3; 1417 Register next = a3;
1424 Register temp = t0; 1418 Register temp = t0;
1425 1419
1426 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { 1420 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) {
1427 if (s->num_heap_slots() > 0) { 1421 if (s->num_heap_slots() > 0) {
1428 if (s->calls_non_strict_eval()) { 1422 if (s->calls_sloppy_eval()) {
1429 // Check that extension is NULL. 1423 // Check that extension is NULL.
1430 __ lw(temp, ContextOperand(context, Context::EXTENSION_INDEX)); 1424 __ lw(temp, ContextOperand(context, Context::EXTENSION_INDEX));
1431 __ Branch(slow, ne, temp, Operand(zero_reg)); 1425 __ Branch(slow, ne, temp, Operand(zero_reg));
1432 } 1426 }
1433 __ lw(next, ContextOperand(context, Context::PREVIOUS_INDEX)); 1427 __ lw(next, ContextOperand(context, Context::PREVIOUS_INDEX));
1434 // Walk the rest of the chain without clobbering cp. 1428 // Walk the rest of the chain without clobbering cp.
1435 context = next; 1429 context = next;
1436 } 1430 }
1437 } 1431 }
1438 // Check that last extension is NULL. 1432 // Check that last extension is NULL.
(...skipping 15 matching lines...) Expand all
1454 // eval-introduced variables. Eval is used a lot without 1448 // eval-introduced variables. Eval is used a lot without
1455 // introducing variables. In those cases, we do not want to 1449 // introducing variables. In those cases, we do not want to
1456 // perform a runtime call for all variables in the scope 1450 // perform a runtime call for all variables in the scope
1457 // containing the eval. 1451 // containing the eval.
1458 if (var->mode() == DYNAMIC_GLOBAL) { 1452 if (var->mode() == DYNAMIC_GLOBAL) {
1459 EmitLoadGlobalCheckExtensions(var, typeof_state, slow); 1453 EmitLoadGlobalCheckExtensions(var, typeof_state, slow);
1460 __ Branch(done); 1454 __ Branch(done);
1461 } else if (var->mode() == DYNAMIC_LOCAL) { 1455 } else if (var->mode() == DYNAMIC_LOCAL) {
1462 Variable* local = var->local_if_not_shadowed(); 1456 Variable* local = var->local_if_not_shadowed();
1463 __ lw(v0, ContextSlotOperandCheckExtensions(local, slow)); 1457 __ lw(v0, ContextSlotOperandCheckExtensions(local, slow));
1464 if (local->mode() == LET || 1458 if (local->mode() == LET || local->mode() == CONST ||
1465 local->mode() == CONST || 1459 local->mode() == CONST_LEGACY) {
1466 local->mode() == CONST_HARMONY) {
1467 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 1460 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
1468 __ subu(at, v0, at); // Sub as compare: at == 0 on eq. 1461 __ subu(at, v0, at); // Sub as compare: at == 0 on eq.
1469 if (local->mode() == CONST) { 1462 if (local->mode() == CONST_LEGACY) {
1470 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); 1463 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
1471 __ Movz(v0, a0, at); // Conditional move: return Undefined if TheHole. 1464 __ Movz(v0, a0, at); // Conditional move: return Undefined if TheHole.
1472 } else { // LET || CONST_HARMONY 1465 } else { // LET || CONST
1473 __ Branch(done, ne, at, Operand(zero_reg)); 1466 __ Branch(done, ne, at, Operand(zero_reg));
1474 __ li(a0, Operand(var->name())); 1467 __ li(a0, Operand(var->name()));
1475 __ push(a0); 1468 __ push(a0);
1476 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1469 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1477 } 1470 }
1478 } 1471 }
1479 __ Branch(done); 1472 __ Branch(done);
1480 } 1473 }
1481 } 1474 }
1482 1475
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1529 // binding is initialized: 1522 // binding is initialized:
1530 // function() { f(); let x = 1; function f() { x = 2; } } 1523 // function() { f(); let x = 1; function f() { x = 2; } }
1531 // 1524 //
1532 bool skip_init_check; 1525 bool skip_init_check;
1533 if (var->scope()->DeclarationScope() != scope()->DeclarationScope()) { 1526 if (var->scope()->DeclarationScope() != scope()->DeclarationScope()) {
1534 skip_init_check = false; 1527 skip_init_check = false;
1535 } else { 1528 } else {
1536 // Check that we always have valid source position. 1529 // Check that we always have valid source position.
1537 ASSERT(var->initializer_position() != RelocInfo::kNoPosition); 1530 ASSERT(var->initializer_position() != RelocInfo::kNoPosition);
1538 ASSERT(proxy->position() != RelocInfo::kNoPosition); 1531 ASSERT(proxy->position() != RelocInfo::kNoPosition);
1539 skip_init_check = var->mode() != CONST && 1532 skip_init_check = var->mode() != CONST_LEGACY &&
1540 var->initializer_position() < proxy->position(); 1533 var->initializer_position() < proxy->position();
1541 } 1534 }
1542 1535
1543 if (!skip_init_check) { 1536 if (!skip_init_check) {
1544 // Let and const need a read barrier. 1537 // Let and const need a read barrier.
1545 GetVar(v0, var); 1538 GetVar(v0, var);
1546 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 1539 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
1547 __ subu(at, v0, at); // Sub as compare: at == 0 on eq. 1540 __ subu(at, v0, at); // Sub as compare: at == 0 on eq.
1548 if (var->mode() == LET || var->mode() == CONST_HARMONY) { 1541 if (var->mode() == LET || var->mode() == CONST) {
1549 // Throw a reference error when using an uninitialized let/const 1542 // Throw a reference error when using an uninitialized let/const
1550 // binding in harmony mode. 1543 // binding in harmony mode.
1551 Label done; 1544 Label done;
1552 __ Branch(&done, ne, at, Operand(zero_reg)); 1545 __ Branch(&done, ne, at, Operand(zero_reg));
1553 __ li(a0, Operand(var->name())); 1546 __ li(a0, Operand(var->name()));
1554 __ push(a0); 1547 __ push(a0);
1555 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1548 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1556 __ bind(&done); 1549 __ bind(&done);
1557 } else { 1550 } else {
1558 // Uninitalized const bindings outside of harmony mode are unholed. 1551 // Uninitalized const bindings outside of harmony mode are unholed.
1559 ASSERT(var->mode() == CONST); 1552 ASSERT(var->mode() == CONST_LEGACY);
1560 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); 1553 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
1561 __ Movz(v0, a0, at); // Conditional move: Undefined if TheHole. 1554 __ Movz(v0, a0, at); // Conditional move: Undefined if TheHole.
1562 } 1555 }
1563 context()->Plug(v0); 1556 context()->Plug(v0);
1564 break; 1557 break;
1565 } 1558 }
1566 } 1559 }
1567 context()->Plug(var); 1560 context()->Plug(var);
1568 break; 1561 break;
1569 } 1562 }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1655 __ li(a2, Operand(Smi::FromInt(expr->literal_index()))); 1648 __ li(a2, Operand(Smi::FromInt(expr->literal_index())));
1656 __ li(a1, Operand(constant_properties)); 1649 __ li(a1, Operand(constant_properties));
1657 int flags = expr->fast_elements() 1650 int flags = expr->fast_elements()
1658 ? ObjectLiteral::kFastElements 1651 ? ObjectLiteral::kFastElements
1659 : ObjectLiteral::kNoFlags; 1652 : ObjectLiteral::kNoFlags;
1660 flags |= expr->has_function() 1653 flags |= expr->has_function()
1661 ? ObjectLiteral::kHasFunction 1654 ? ObjectLiteral::kHasFunction
1662 : ObjectLiteral::kNoFlags; 1655 : ObjectLiteral::kNoFlags;
1663 __ li(a0, Operand(Smi::FromInt(flags))); 1656 __ li(a0, Operand(Smi::FromInt(flags)));
1664 int properties_count = constant_properties->length() / 2; 1657 int properties_count = constant_properties->length() / 2;
1665 if ((FLAG_track_double_fields && expr->may_store_doubles()) || 1658 if (expr->may_store_doubles() || expr->depth() > 1 || Serializer::enabled() ||
1666 expr->depth() > 1 || Serializer::enabled() ||
1667 flags != ObjectLiteral::kFastElements || 1659 flags != ObjectLiteral::kFastElements ||
1668 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { 1660 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) {
1669 __ Push(a3, a2, a1, a0); 1661 __ Push(a3, a2, a1, a0);
1670 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); 1662 __ CallRuntime(Runtime::kCreateObjectLiteral, 4);
1671 } else { 1663 } else {
1672 FastCloneShallowObjectStub stub(properties_count); 1664 FastCloneShallowObjectStub stub(properties_count);
1673 __ CallStub(&stub); 1665 __ CallStub(&stub);
1674 } 1666 }
1675 1667
1676 // If result_saved is true the result is on top of the stack. If 1668 // If result_saved is true the result is on top of the stack. If
(...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after
2459 __ li(a2, Operand(prop->key()->AsLiteral()->value())); 2451 __ li(a2, Operand(prop->key()->AsLiteral()->value()));
2460 CallStoreIC(); 2452 CallStoreIC();
2461 break; 2453 break;
2462 } 2454 }
2463 case KEYED_PROPERTY: { 2455 case KEYED_PROPERTY: {
2464 __ push(result_register()); // Preserve value. 2456 __ push(result_register()); // Preserve value.
2465 VisitForStackValue(prop->obj()); 2457 VisitForStackValue(prop->obj());
2466 VisitForAccumulatorValue(prop->key()); 2458 VisitForAccumulatorValue(prop->key());
2467 __ mov(a1, result_register()); 2459 __ mov(a1, result_register());
2468 __ Pop(a0, a2); // a0 = restored value. 2460 __ Pop(a0, a2); // a0 = restored value.
2469 Handle<Code> ic = is_classic_mode() 2461 Handle<Code> ic = strict_mode() == SLOPPY
2470 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2462 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2471 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2463 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2472 CallIC(ic); 2464 CallIC(ic);
2473 break; 2465 break;
2474 } 2466 }
2475 } 2467 }
2476 context()->Plug(v0); 2468 context()->Plug(v0);
2477 } 2469 }
2478 2470
2479 2471
2480 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( 2472 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot(
2481 Variable* var, MemOperand location) { 2473 Variable* var, MemOperand location) {
2482 __ sw(result_register(), location); 2474 __ sw(result_register(), location);
2483 if (var->IsContextSlot()) { 2475 if (var->IsContextSlot()) {
2484 // RecordWrite may destroy all its register arguments. 2476 // RecordWrite may destroy all its register arguments.
2485 __ Move(a3, result_register()); 2477 __ Move(a3, result_register());
2486 int offset = Context::SlotOffset(var->index()); 2478 int offset = Context::SlotOffset(var->index());
2487 __ RecordWriteContextSlot( 2479 __ RecordWriteContextSlot(
2488 a1, offset, a3, a2, kRAHasBeenSaved, kDontSaveFPRegs); 2480 a1, offset, a3, a2, kRAHasBeenSaved, kDontSaveFPRegs);
2489 } 2481 }
2490 } 2482 }
2491 2483
2492 2484
2493 void FullCodeGenerator::EmitCallStoreContextSlot( 2485 void FullCodeGenerator::EmitCallStoreContextSlot(
2494 Handle<String> name, LanguageMode mode) { 2486 Handle<String> name, StrictMode strict_mode) {
2495 __ li(a1, Operand(name)); 2487 __ li(a1, Operand(name));
2496 __ li(a0, Operand(Smi::FromInt(mode))); 2488 __ li(a0, Operand(Smi::FromInt(strict_mode)));
2497 __ Push(v0, cp, a1, a0); // Value, context, name, strict mode. 2489 __ Push(v0, cp, a1, a0); // Value, context, name, strict mode.
2498 __ CallRuntime(Runtime::kStoreContextSlot, 4); 2490 __ CallRuntime(Runtime::kStoreContextSlot, 4);
2499 } 2491 }
2500 2492
2501 2493
2502 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 2494 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) {
2503 Token::Value op) {
2504 if (var->IsUnallocated()) { 2495 if (var->IsUnallocated()) {
2505 // Global var, const, or let. 2496 // Global var, const, or let.
2506 __ mov(a0, result_register()); 2497 __ mov(a0, result_register());
2507 __ li(a2, Operand(var->name())); 2498 __ li(a2, Operand(var->name()));
2508 __ lw(a1, GlobalObjectOperand()); 2499 __ lw(a1, GlobalObjectOperand());
2509 CallStoreIC(); 2500 CallStoreIC();
2510 2501
2511 } else if (op == Token::INIT_CONST) { 2502 } else if (op == Token::INIT_CONST_LEGACY) {
2512 // Const initializers need a write barrier. 2503 // Const initializers need a write barrier.
2513 ASSERT(!var->IsParameter()); // No const parameters. 2504 ASSERT(!var->IsParameter()); // No const parameters.
2514 if (var->IsLookupSlot()) { 2505 if (var->IsLookupSlot()) {
2515 __ li(a0, Operand(var->name())); 2506 __ li(a0, Operand(var->name()));
2516 __ Push(v0, cp, a0); // Context and name. 2507 __ Push(v0, cp, a0); // Context and name.
2517 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); 2508 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
2518 } else { 2509 } else {
2519 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 2510 ASSERT(var->IsStackAllocated() || var->IsContextSlot());
2520 Label skip; 2511 Label skip;
2521 MemOperand location = VarOperand(var, a1); 2512 MemOperand location = VarOperand(var, a1);
2522 __ lw(a2, location); 2513 __ lw(a2, location);
2523 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2514 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2524 __ Branch(&skip, ne, a2, Operand(at)); 2515 __ Branch(&skip, ne, a2, Operand(at));
2525 EmitStoreToStackLocalOrContextSlot(var, location); 2516 EmitStoreToStackLocalOrContextSlot(var, location);
2526 __ bind(&skip); 2517 __ bind(&skip);
2527 } 2518 }
2528 2519
2529 } else if (var->mode() == LET && op != Token::INIT_LET) { 2520 } else if (var->mode() == LET && op != Token::INIT_LET) {
2530 // Non-initializing assignment to let variable needs a write barrier. 2521 // Non-initializing assignment to let variable needs a write barrier.
2531 if (var->IsLookupSlot()) { 2522 if (var->IsLookupSlot()) {
2532 EmitCallStoreContextSlot(var->name(), language_mode()); 2523 EmitCallStoreContextSlot(var->name(), strict_mode());
2533 } else { 2524 } else {
2534 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 2525 ASSERT(var->IsStackAllocated() || var->IsContextSlot());
2535 Label assign; 2526 Label assign;
2536 MemOperand location = VarOperand(var, a1); 2527 MemOperand location = VarOperand(var, a1);
2537 __ lw(a3, location); 2528 __ lw(a3, location);
2538 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); 2529 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
2539 __ Branch(&assign, ne, a3, Operand(t0)); 2530 __ Branch(&assign, ne, a3, Operand(t0));
2540 __ li(a3, Operand(var->name())); 2531 __ li(a3, Operand(var->name()));
2541 __ push(a3); 2532 __ push(a3);
2542 __ CallRuntime(Runtime::kThrowReferenceError, 1); 2533 __ CallRuntime(Runtime::kThrowReferenceError, 1);
2543 // Perform the assignment. 2534 // Perform the assignment.
2544 __ bind(&assign); 2535 __ bind(&assign);
2545 EmitStoreToStackLocalOrContextSlot(var, location); 2536 EmitStoreToStackLocalOrContextSlot(var, location);
2546 } 2537 }
2547 2538
2548 } else if (!var->is_const_mode() || op == Token::INIT_CONST_HARMONY) { 2539 } else if (!var->is_const_mode() || op == Token::INIT_CONST) {
2549 // Assignment to var or initializing assignment to let/const 2540 // Assignment to var or initializing assignment to let/const
2550 // in harmony mode. 2541 // in harmony mode.
2551 if (var->IsLookupSlot()) { 2542 if (var->IsLookupSlot()) {
2552 EmitCallStoreContextSlot(var->name(), language_mode()); 2543 EmitCallStoreContextSlot(var->name(), strict_mode());
2553 } else { 2544 } else {
2554 ASSERT((var->IsStackAllocated() || var->IsContextSlot())); 2545 ASSERT((var->IsStackAllocated() || var->IsContextSlot()));
2555 MemOperand location = VarOperand(var, a1); 2546 MemOperand location = VarOperand(var, a1);
2556 if (generate_debug_code_ && op == Token::INIT_LET) { 2547 if (generate_debug_code_ && op == Token::INIT_LET) {
2557 // Check for an uninitialized let binding. 2548 // Check for an uninitialized let binding.
2558 __ lw(a2, location); 2549 __ lw(a2, location);
2559 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); 2550 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
2560 __ Check(eq, kLetBindingReInitialization, a2, Operand(t0)); 2551 __ Check(eq, kLetBindingReInitialization, a2, Operand(t0));
2561 } 2552 }
2562 EmitStoreToStackLocalOrContextSlot(var, location); 2553 EmitStoreToStackLocalOrContextSlot(var, location);
(...skipping 28 matching lines...) Expand all
2591 // Record source code position before IC call. 2582 // Record source code position before IC call.
2592 SetSourcePosition(expr->position()); 2583 SetSourcePosition(expr->position());
2593 // Call keyed store IC. 2584 // Call keyed store IC.
2594 // The arguments are: 2585 // The arguments are:
2595 // - a0 is the value, 2586 // - a0 is the value,
2596 // - a1 is the key, 2587 // - a1 is the key,
2597 // - a2 is the receiver. 2588 // - a2 is the receiver.
2598 __ mov(a0, result_register()); 2589 __ mov(a0, result_register());
2599 __ Pop(a2, a1); // a1 = key. 2590 __ Pop(a2, a1); // a1 = key.
2600 2591
2601 Handle<Code> ic = is_classic_mode() 2592 Handle<Code> ic = strict_mode() == SLOPPY
2602 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2593 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2603 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2594 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2604 CallIC(ic, expr->AssignmentFeedbackId()); 2595 CallIC(ic, expr->AssignmentFeedbackId());
2605 2596
2606 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2597 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2607 context()->Plug(v0); 2598 context()->Plug(v0);
2608 } 2599 }
2609 2600
2610 2601
2611 void FullCodeGenerator::VisitProperty(Property* expr) { 2602 void FullCodeGenerator::VisitProperty(Property* expr) {
(...skipping 29 matching lines...) Expand all
2641 int arg_count = args->length(); 2632 int arg_count = args->length();
2642 2633
2643 CallFunctionFlags flags; 2634 CallFunctionFlags flags;
2644 // Get the target function. 2635 // Get the target function.
2645 if (callee->IsVariableProxy()) { 2636 if (callee->IsVariableProxy()) {
2646 { StackValueContext context(this); 2637 { StackValueContext context(this);
2647 EmitVariableLoad(callee->AsVariableProxy()); 2638 EmitVariableLoad(callee->AsVariableProxy());
2648 PrepareForBailout(callee, NO_REGISTERS); 2639 PrepareForBailout(callee, NO_REGISTERS);
2649 } 2640 }
2650 // Push undefined as receiver. This is patched in the method prologue if it 2641 // Push undefined as receiver. This is patched in the method prologue if it
2651 // is a classic mode method. 2642 // is a sloppy mode method.
2652 __ Push(isolate()->factory()->undefined_value()); 2643 __ Push(isolate()->factory()->undefined_value());
2653 flags = NO_CALL_FUNCTION_FLAGS; 2644 flags = NO_CALL_FUNCTION_FLAGS;
2654 } else { 2645 } else {
2655 // Load the function from the receiver. 2646 // Load the function from the receiver.
2656 ASSERT(callee->IsProperty()); 2647 ASSERT(callee->IsProperty());
2657 __ lw(v0, MemOperand(sp, 0)); 2648 __ lw(v0, MemOperand(sp, 0));
2658 EmitNamedPropertyLoad(callee->AsProperty()); 2649 EmitNamedPropertyLoad(callee->AsProperty());
2659 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2650 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2660 // Push the target function under the receiver. 2651 // Push the target function under the receiver.
2661 __ lw(at, MemOperand(sp, 0)); 2652 __ lw(at, MemOperand(sp, 0));
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2731 ZoneList<Expression*>* args = expr->arguments(); 2722 ZoneList<Expression*>* args = expr->arguments();
2732 int arg_count = args->length(); 2723 int arg_count = args->length();
2733 { PreservePositionScope scope(masm()->positions_recorder()); 2724 { PreservePositionScope scope(masm()->positions_recorder());
2734 for (int i = 0; i < arg_count; i++) { 2725 for (int i = 0; i < arg_count; i++) {
2735 VisitForStackValue(args->at(i)); 2726 VisitForStackValue(args->at(i));
2736 } 2727 }
2737 } 2728 }
2738 // Record source position for debugger. 2729 // Record source position for debugger.
2739 SetSourcePosition(expr->position()); 2730 SetSourcePosition(expr->position());
2740 2731
2741 Handle<Object> uninitialized =
2742 TypeFeedbackInfo::UninitializedSentinel(isolate());
2743 StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized);
2744 __ li(a2, FeedbackVector()); 2732 __ li(a2, FeedbackVector());
2745 __ li(a3, Operand(Smi::FromInt(expr->CallFeedbackSlot()))); 2733 __ li(a3, Operand(Smi::FromInt(expr->CallFeedbackSlot())));
2746 2734
2747 // Record call targets in unoptimized code. 2735 // Record call targets in unoptimized code.
2748 CallFunctionStub stub(arg_count, RECORD_CALL_TARGET); 2736 CallFunctionStub stub(arg_count, RECORD_CALL_TARGET);
2749 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2737 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2750 __ CallStub(&stub); 2738 __ CallStub(&stub);
2751 RecordJSReturnSite(expr); 2739 RecordJSReturnSite(expr);
2752 // Restore context register. 2740 // Restore context register.
2753 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2741 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2754 context()->DropAndPlug(1, v0); 2742 context()->DropAndPlug(1, v0);
2755 } 2743 }
2756 2744
2757 2745
2758 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { 2746 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
2759 // t2: copy of the first argument or undefined if it doesn't exist. 2747 // t2: copy of the first argument or undefined if it doesn't exist.
2760 if (arg_count > 0) { 2748 if (arg_count > 0) {
2761 __ lw(t2, MemOperand(sp, arg_count * kPointerSize)); 2749 __ lw(t2, MemOperand(sp, arg_count * kPointerSize));
2762 } else { 2750 } else {
2763 __ LoadRoot(t2, Heap::kUndefinedValueRootIndex); 2751 __ LoadRoot(t2, Heap::kUndefinedValueRootIndex);
2764 } 2752 }
2765 2753
2766 // t1: the receiver of the enclosing function. 2754 // t1: the receiver of the enclosing function.
2767 int receiver_offset = 2 + info_->scope()->num_parameters(); 2755 int receiver_offset = 2 + info_->scope()->num_parameters();
2768 __ lw(t1, MemOperand(fp, receiver_offset * kPointerSize)); 2756 __ lw(t1, MemOperand(fp, receiver_offset * kPointerSize));
2769 2757
2770 // t0: the language mode. 2758 // t0: the strict mode.
2771 __ li(t0, Operand(Smi::FromInt(language_mode()))); 2759 __ li(t0, Operand(Smi::FromInt(strict_mode())));
2772 2760
2773 // a1: the start position of the scope the calls resides in. 2761 // a1: the start position of the scope the calls resides in.
2774 __ li(a1, Operand(Smi::FromInt(scope()->start_position()))); 2762 __ li(a1, Operand(Smi::FromInt(scope()->start_position())));
2775 2763
2776 // Do the runtime call. 2764 // Do the runtime call.
2777 __ Push(t2, t1, t0, a1); 2765 __ Push(t2, t1, t0, a1);
2778 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); 2766 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
2779 } 2767 }
2780 2768
2781 2769
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
2918 2906
2919 // Call the construct call builtin that handles allocation and 2907 // Call the construct call builtin that handles allocation and
2920 // constructor invocation. 2908 // constructor invocation.
2921 SetSourcePosition(expr->position()); 2909 SetSourcePosition(expr->position());
2922 2910
2923 // Load function and argument count into a1 and a0. 2911 // Load function and argument count into a1 and a0.
2924 __ li(a0, Operand(arg_count)); 2912 __ li(a0, Operand(arg_count));
2925 __ lw(a1, MemOperand(sp, arg_count * kPointerSize)); 2913 __ lw(a1, MemOperand(sp, arg_count * kPointerSize));
2926 2914
2927 // Record call targets in unoptimized code. 2915 // Record call targets in unoptimized code.
2928 Handle<Object> uninitialized =
2929 TypeFeedbackInfo::UninitializedSentinel(isolate());
2930 StoreFeedbackVectorSlot(expr->CallNewFeedbackSlot(), uninitialized);
2931 __ li(a2, FeedbackVector()); 2916 __ li(a2, FeedbackVector());
2932 __ li(a3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot()))); 2917 __ li(a3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot())));
2933 2918
2934 CallConstructStub stub(RECORD_CALL_TARGET); 2919 CallConstructStub stub(RECORD_CALL_TARGET);
2935 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); 2920 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL);
2936 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2921 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2937 context()->Plug(v0); 2922 context()->Plug(v0);
2938 } 2923 }
2939 2924
2940 2925
(...skipping 1292 matching lines...) Expand 10 before | Expand all | Expand 10 after
4233 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 4218 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
4234 switch (expr->op()) { 4219 switch (expr->op()) {
4235 case Token::DELETE: { 4220 case Token::DELETE: {
4236 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 4221 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
4237 Property* property = expr->expression()->AsProperty(); 4222 Property* property = expr->expression()->AsProperty();
4238 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 4223 VariableProxy* proxy = expr->expression()->AsVariableProxy();
4239 4224
4240 if (property != NULL) { 4225 if (property != NULL) {
4241 VisitForStackValue(property->obj()); 4226 VisitForStackValue(property->obj());
4242 VisitForStackValue(property->key()); 4227 VisitForStackValue(property->key());
4243 StrictModeFlag strict_mode_flag = (language_mode() == CLASSIC_MODE) 4228 __ li(a1, Operand(Smi::FromInt(strict_mode())));
4244 ? kNonStrictMode : kStrictMode;
4245 __ li(a1, Operand(Smi::FromInt(strict_mode_flag)));
4246 __ push(a1); 4229 __ push(a1);
4247 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 4230 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
4248 context()->Plug(v0); 4231 context()->Plug(v0);
4249 } else if (proxy != NULL) { 4232 } else if (proxy != NULL) {
4250 Variable* var = proxy->var(); 4233 Variable* var = proxy->var();
4251 // Delete of an unqualified identifier is disallowed in strict mode 4234 // Delete of an unqualified identifier is disallowed in strict mode
4252 // but "delete this" is allowed. 4235 // but "delete this" is allowed.
4253 ASSERT(language_mode() == CLASSIC_MODE || var->is_this()); 4236 ASSERT(strict_mode() == SLOPPY || var->is_this());
4254 if (var->IsUnallocated()) { 4237 if (var->IsUnallocated()) {
4255 __ lw(a2, GlobalObjectOperand()); 4238 __ lw(a2, GlobalObjectOperand());
4256 __ li(a1, Operand(var->name())); 4239 __ li(a1, Operand(var->name()));
4257 __ li(a0, Operand(Smi::FromInt(kNonStrictMode))); 4240 __ li(a0, Operand(Smi::FromInt(SLOPPY)));
4258 __ Push(a2, a1, a0); 4241 __ Push(a2, a1, a0);
4259 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 4242 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
4260 context()->Plug(v0); 4243 context()->Plug(v0);
4261 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 4244 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
4262 // Result of deleting non-global, non-dynamic variables is false. 4245 // Result of deleting non-global, non-dynamic variables is false.
4263 // The subexpression does not have side effects. 4246 // The subexpression does not have side effects.
4264 context()->Plug(var->is_this()); 4247 context()->Plug(var->is_this());
4265 } else { 4248 } else {
4266 // Non-global variable. Call the runtime to try to delete from the 4249 // Non-global variable. Call the runtime to try to delete from the
4267 // context where the variable was introduced. 4250 // context where the variable was introduced.
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
4506 context()->PlugTOS(); 4489 context()->PlugTOS();
4507 } 4490 }
4508 } else { 4491 } else {
4509 context()->Plug(v0); 4492 context()->Plug(v0);
4510 } 4493 }
4511 break; 4494 break;
4512 } 4495 }
4513 case KEYED_PROPERTY: { 4496 case KEYED_PROPERTY: {
4514 __ mov(a0, result_register()); // Value. 4497 __ mov(a0, result_register()); // Value.
4515 __ Pop(a2, a1); // a1 = key, a2 = receiver. 4498 __ Pop(a2, a1); // a1 = key, a2 = receiver.
4516 Handle<Code> ic = is_classic_mode() 4499 Handle<Code> ic = strict_mode() == SLOPPY
4517 ? isolate()->builtins()->KeyedStoreIC_Initialize() 4500 ? isolate()->builtins()->KeyedStoreIC_Initialize()
4518 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 4501 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
4519 CallIC(ic, expr->CountStoreFeedbackId()); 4502 CallIC(ic, expr->CountStoreFeedbackId());
4520 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4503 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4521 if (expr->is_postfix()) { 4504 if (expr->is_postfix()) {
4522 if (!context()->IsEffect()) { 4505 if (!context()->IsEffect()) {
4523 context()->PlugTOS(); 4506 context()->PlugTOS();
4524 } 4507 }
4525 } else { 4508 } else {
4526 context()->Plug(v0); 4509 context()->Plug(v0);
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
4967 Assembler::target_address_at(pc_immediate_load_address)) == 4950 Assembler::target_address_at(pc_immediate_load_address)) ==
4968 reinterpret_cast<uint32_t>( 4951 reinterpret_cast<uint32_t>(
4969 isolate->builtins()->OsrAfterStackCheck()->entry())); 4952 isolate->builtins()->OsrAfterStackCheck()->entry()));
4970 return OSR_AFTER_STACK_CHECK; 4953 return OSR_AFTER_STACK_CHECK;
4971 } 4954 }
4972 4955
4973 4956
4974 } } // namespace v8::internal 4957 } } // namespace v8::internal
4975 4958
4976 #endif // V8_TARGET_ARCH_MIPS 4959 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/frames-mips.h ('k') | src/mips/ic-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698