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

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

Issue 1706283002: [fullcodegen] Implement operand stack depth tracking. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Turn off verification. Created 4 years, 10 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
« no previous file with comments | « src/full-codegen/full-codegen.cc ('k') | src/full-codegen/mips/full-codegen-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 // 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_IA32 5 #if V8_TARGET_ARCH_IA32
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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 // the frame (that is done below). 112 // the frame (that is done below).
113 FrameScope frame_scope(masm_, StackFrame::MANUAL); 113 FrameScope frame_scope(masm_, StackFrame::MANUAL);
114 114
115 info->set_prologue_offset(masm_->pc_offset()); 115 info->set_prologue_offset(masm_->pc_offset());
116 __ Prologue(info->GeneratePreagedPrologue()); 116 __ Prologue(info->GeneratePreagedPrologue());
117 117
118 { Comment cmnt(masm_, "[ Allocate locals"); 118 { Comment cmnt(masm_, "[ Allocate locals");
119 int locals_count = info->scope()->num_stack_slots(); 119 int locals_count = info->scope()->num_stack_slots();
120 // Generators allocate locals, if any, in context slots. 120 // Generators allocate locals, if any, in context slots.
121 DCHECK(!IsGeneratorFunction(literal()->kind()) || locals_count == 0); 121 DCHECK(!IsGeneratorFunction(literal()->kind()) || locals_count == 0);
122 OperandStackDepthIncrement(locals_count);
122 if (locals_count == 1) { 123 if (locals_count == 1) {
123 __ push(Immediate(isolate()->factory()->undefined_value())); 124 __ push(Immediate(isolate()->factory()->undefined_value()));
124 } else if (locals_count > 1) { 125 } else if (locals_count > 1) {
125 if (locals_count >= 128) { 126 if (locals_count >= 128) {
126 Label ok; 127 Label ok;
127 __ mov(ecx, esp); 128 __ mov(ecx, esp);
128 __ sub(ecx, Immediate(locals_count * kPointerSize)); 129 __ sub(ecx, Immediate(locals_count * kPointerSize));
129 ExternalReference stack_limit = 130 ExternalReference stack_limit =
130 ExternalReference::address_of_real_stack_limit(isolate()); 131 ExternalReference::address_of_real_stack_limit(isolate());
131 __ cmp(ecx, Operand::StaticVariable(stack_limit)); 132 __ cmp(ecx, Operand::StaticVariable(stack_limit));
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 int arguments_bytes = arg_count * kPointerSize; 425 int arguments_bytes = arg_count * kPointerSize;
425 __ Ret(arguments_bytes, ecx); 426 __ Ret(arguments_bytes, ecx);
426 } 427 }
427 } 428 }
428 429
429 430
430 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { 431 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const {
431 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 432 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
432 MemOperand operand = codegen()->VarOperand(var, result_register()); 433 MemOperand operand = codegen()->VarOperand(var, result_register());
433 // Memory operands can be pushed directly. 434 // Memory operands can be pushed directly.
434 __ push(operand); 435 codegen()->PushOperand(operand);
435 } 436 }
436 437
437 438
438 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { 439 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const {
439 UNREACHABLE(); // Not used on IA32. 440 UNREACHABLE(); // Not used on IA32.
440 } 441 }
441 442
442 443
443 void FullCodeGenerator::AccumulatorValueContext::Plug( 444 void FullCodeGenerator::AccumulatorValueContext::Plug(
444 Heap::RootListIndex index) const { 445 Heap::RootListIndex index) const {
(...skipping 20 matching lines...) Expand all
465 Handle<Object> lit) const { 466 Handle<Object> lit) const {
466 if (lit->IsSmi()) { 467 if (lit->IsSmi()) {
467 __ SafeMove(result_register(), Immediate(lit)); 468 __ SafeMove(result_register(), Immediate(lit));
468 } else { 469 } else {
469 __ Move(result_register(), Immediate(lit)); 470 __ Move(result_register(), Immediate(lit));
470 } 471 }
471 } 472 }
472 473
473 474
474 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { 475 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const {
476 codegen()->OperandStackDepthIncrement(1);
475 if (lit->IsSmi()) { 477 if (lit->IsSmi()) {
476 __ SafePush(Immediate(lit)); 478 __ SafePush(Immediate(lit));
477 } else { 479 } else {
478 __ push(Immediate(lit)); 480 __ push(Immediate(lit));
479 } 481 }
480 } 482 }
481 483
482 484
483 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { 485 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
484 codegen()->PrepareForBailoutBeforeSplit(condition(), 486 codegen()->PrepareForBailoutBeforeSplit(condition(),
(...skipping 18 matching lines...) Expand all
503 if (true_label_ != fall_through_) __ jmp(true_label_); 505 if (true_label_ != fall_through_) __ jmp(true_label_);
504 } 506 }
505 } else { 507 } else {
506 // For simplicity we always test the accumulator register. 508 // For simplicity we always test the accumulator register.
507 __ mov(result_register(), lit); 509 __ mov(result_register(), lit);
508 codegen()->DoTest(this); 510 codegen()->DoTest(this);
509 } 511 }
510 } 512 }
511 513
512 514
513 void FullCodeGenerator::EffectContext::DropAndPlug(int count,
514 Register reg) const {
515 DCHECK(count > 0);
516 __ Drop(count);
517 }
518
519
520 void FullCodeGenerator::AccumulatorValueContext::DropAndPlug(
521 int count,
522 Register reg) const {
523 DCHECK(count > 0);
524 __ Drop(count);
525 __ Move(result_register(), reg);
526 }
527
528
529 void FullCodeGenerator::StackValueContext::DropAndPlug(int count, 515 void FullCodeGenerator::StackValueContext::DropAndPlug(int count,
530 Register reg) const { 516 Register reg) const {
531 DCHECK(count > 0); 517 DCHECK(count > 0);
532 if (count > 1) __ Drop(count - 1); 518 if (count > 1) codegen()->DropOperands(count - 1);
533 __ mov(Operand(esp, 0), reg); 519 __ mov(Operand(esp, 0), reg);
534 } 520 }
535 521
536 522
537 void FullCodeGenerator::TestContext::DropAndPlug(int count,
538 Register reg) const {
539 DCHECK(count > 0);
540 // For simplicity we always test the accumulator register.
541 __ Drop(count);
542 __ Move(result_register(), reg);
543 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
544 codegen()->DoTest(this);
545 }
546
547
548 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, 523 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true,
549 Label* materialize_false) const { 524 Label* materialize_false) const {
550 DCHECK(materialize_true == materialize_false); 525 DCHECK(materialize_true == materialize_false);
551 __ bind(materialize_true); 526 __ bind(materialize_true);
552 } 527 }
553 528
554 529
555 void FullCodeGenerator::AccumulatorValueContext::Plug( 530 void FullCodeGenerator::AccumulatorValueContext::Plug(
556 Label* materialize_true, 531 Label* materialize_true,
557 Label* materialize_false) const { 532 Label* materialize_false) const {
558 Label done; 533 Label done;
559 __ bind(materialize_true); 534 __ bind(materialize_true);
560 __ mov(result_register(), isolate()->factory()->true_value()); 535 __ mov(result_register(), isolate()->factory()->true_value());
561 __ jmp(&done, Label::kNear); 536 __ jmp(&done, Label::kNear);
562 __ bind(materialize_false); 537 __ bind(materialize_false);
563 __ mov(result_register(), isolate()->factory()->false_value()); 538 __ mov(result_register(), isolate()->factory()->false_value());
564 __ bind(&done); 539 __ bind(&done);
565 } 540 }
566 541
567 542
568 void FullCodeGenerator::StackValueContext::Plug( 543 void FullCodeGenerator::StackValueContext::Plug(
569 Label* materialize_true, 544 Label* materialize_true,
570 Label* materialize_false) const { 545 Label* materialize_false) const {
546 codegen()->OperandStackDepthIncrement(1);
571 Label done; 547 Label done;
572 __ bind(materialize_true); 548 __ bind(materialize_true);
573 __ push(Immediate(isolate()->factory()->true_value())); 549 __ push(Immediate(isolate()->factory()->true_value()));
574 __ jmp(&done, Label::kNear); 550 __ jmp(&done, Label::kNear);
575 __ bind(materialize_false); 551 __ bind(materialize_false);
576 __ push(Immediate(isolate()->factory()->false_value())); 552 __ push(Immediate(isolate()->factory()->false_value()));
577 __ bind(&done); 553 __ bind(&done);
578 } 554 }
579 555
580 556
581 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, 557 void FullCodeGenerator::TestContext::Plug(Label* materialize_true,
582 Label* materialize_false) const { 558 Label* materialize_false) const {
583 DCHECK(materialize_true == true_label_); 559 DCHECK(materialize_true == true_label_);
584 DCHECK(materialize_false == false_label_); 560 DCHECK(materialize_false == false_label_);
585 } 561 }
586 562
587 563
588 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { 564 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const {
589 Handle<Object> value = flag 565 Handle<Object> value = flag
590 ? isolate()->factory()->true_value() 566 ? isolate()->factory()->true_value()
591 : isolate()->factory()->false_value(); 567 : isolate()->factory()->false_value();
592 __ mov(result_register(), value); 568 __ mov(result_register(), value);
593 } 569 }
594 570
595 571
596 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { 572 void FullCodeGenerator::StackValueContext::Plug(bool flag) const {
573 codegen()->OperandStackDepthIncrement(1);
597 Handle<Object> value = flag 574 Handle<Object> value = flag
598 ? isolate()->factory()->true_value() 575 ? isolate()->factory()->true_value()
599 : isolate()->factory()->false_value(); 576 : isolate()->factory()->false_value();
600 __ push(Immediate(value)); 577 __ push(Immediate(value));
601 } 578 }
602 579
603 580
604 void FullCodeGenerator::TestContext::Plug(bool flag) const { 581 void FullCodeGenerator::TestContext::Plug(bool flag) const {
605 codegen()->PrepareForBailoutBeforeSplit(condition(), 582 codegen()->PrepareForBailoutBeforeSplit(condition(),
606 true, 583 true,
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
824 ecx, 801 ecx,
825 kDontSaveFPRegs, 802 kDontSaveFPRegs,
826 EMIT_REMEMBERED_SET, 803 EMIT_REMEMBERED_SET,
827 OMIT_SMI_CHECK); 804 OMIT_SMI_CHECK);
828 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 805 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
829 break; 806 break;
830 } 807 }
831 808
832 case VariableLocation::LOOKUP: { 809 case VariableLocation::LOOKUP: {
833 Comment cmnt(masm_, "[ FunctionDeclaration"); 810 Comment cmnt(masm_, "[ FunctionDeclaration");
834 __ push(Immediate(variable->name())); 811 PushOperand(variable->name());
835 VisitForStackValue(declaration->fun()); 812 VisitForStackValue(declaration->fun());
836 __ push( 813 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
837 Immediate(Smi::FromInt(variable->DeclarationPropertyAttributes()))); 814 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
838 __ CallRuntime(Runtime::kDeclareLookupSlot);
839 break; 815 break;
840 } 816 }
841 } 817 }
842 } 818 }
843 819
844 820
845 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 821 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
846 // Call the runtime to declare the globals. 822 // Call the runtime to declare the globals.
847 __ Push(pairs); 823 __ Push(pairs);
848 __ Push(Smi::FromInt(DeclareGlobalsFlags())); 824 __ Push(Smi::FromInt(DeclareGlobalsFlags()));
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
924 900
925 __ test(eax, eax); 901 __ test(eax, eax);
926 __ j(not_equal, &next_test); 902 __ j(not_equal, &next_test);
927 __ Drop(1); // Switch value is no longer needed. 903 __ Drop(1); // Switch value is no longer needed.
928 __ jmp(clause->body_target()); 904 __ jmp(clause->body_target());
929 } 905 }
930 906
931 // Discard the test value and jump to the default if present, otherwise to 907 // Discard the test value and jump to the default if present, otherwise to
932 // the end of the statement. 908 // the end of the statement.
933 __ bind(&next_test); 909 __ bind(&next_test);
934 __ Drop(1); // Switch value is no longer needed. 910 DropOperands(1); // Switch value is no longer needed.
935 if (default_clause == NULL) { 911 if (default_clause == NULL) {
936 __ jmp(nested_statement.break_label()); 912 __ jmp(nested_statement.break_label());
937 } else { 913 } else {
938 __ jmp(default_clause->body_target()); 914 __ jmp(default_clause->body_target());
939 } 915 }
940 916
941 // Compile all the case bodies. 917 // Compile all the case bodies.
942 for (int i = 0; i < clauses->length(); i++) { 918 for (int i = 0; i < clauses->length(); i++) {
943 Comment cmnt(masm_, "[ Case body"); 919 Comment cmnt(masm_, "[ Case body");
944 CaseClause* clause = clauses->at(i); 920 CaseClause* clause = clauses->at(i);
(...skipping 13 matching lines...) Expand all
958 934
959 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); 935 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
960 936
961 Label loop, exit; 937 Label loop, exit;
962 ForIn loop_statement(this, stmt); 938 ForIn loop_statement(this, stmt);
963 increment_loop_depth(); 939 increment_loop_depth();
964 940
965 // Get the object to enumerate over. 941 // Get the object to enumerate over.
966 SetExpressionAsStatementPosition(stmt->enumerable()); 942 SetExpressionAsStatementPosition(stmt->enumerable());
967 VisitForAccumulatorValue(stmt->enumerable()); 943 VisitForAccumulatorValue(stmt->enumerable());
944 OperandStackDepthIncrement(ForIn::kElementCount);
968 945
969 // If the object is null or undefined, skip over the loop, otherwise convert 946 // If the object is null or undefined, skip over the loop, otherwise convert
970 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. 947 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4.
971 Label convert, done_convert; 948 Label convert, done_convert;
972 __ JumpIfSmi(eax, &convert, Label::kNear); 949 __ JumpIfSmi(eax, &convert, Label::kNear);
973 __ CmpObjectType(eax, FIRST_JS_RECEIVER_TYPE, ecx); 950 __ CmpObjectType(eax, FIRST_JS_RECEIVER_TYPE, ecx);
974 __ j(above_equal, &done_convert, Label::kNear); 951 __ j(above_equal, &done_convert, Label::kNear);
975 __ cmp(eax, isolate()->factory()->undefined_value()); 952 __ cmp(eax, isolate()->factory()->undefined_value());
976 __ j(equal, &exit); 953 __ j(equal, &exit);
977 __ cmp(eax, isolate()->factory()->null_value()); 954 __ cmp(eax, isolate()->factory()->null_value());
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1106 // index (smi) stored on top of the stack. 1083 // index (smi) stored on top of the stack.
1107 __ bind(loop_statement.continue_label()); 1084 __ bind(loop_statement.continue_label());
1108 __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1))); 1085 __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1)));
1109 1086
1110 EmitBackEdgeBookkeeping(stmt, &loop); 1087 EmitBackEdgeBookkeeping(stmt, &loop);
1111 __ jmp(&loop); 1088 __ jmp(&loop);
1112 1089
1113 // Remove the pointers stored on the stack. 1090 // Remove the pointers stored on the stack.
1114 __ bind(loop_statement.break_label()); 1091 __ bind(loop_statement.break_label());
1115 __ add(esp, Immediate(5 * kPointerSize)); 1092 __ add(esp, Immediate(5 * kPointerSize));
1093 OperandStackDepthDecrement(ForIn::kElementCount);
1116 1094
1117 // Exit and decrement the loop depth. 1095 // Exit and decrement the loop depth.
1118 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1096 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1119 __ bind(&exit); 1097 __ bind(&exit);
1120 decrement_loop_depth(); 1098 decrement_loop_depth();
1121 } 1099 }
1122 1100
1123 1101
1124 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, 1102 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
1125 bool pretenure) { 1103 bool pretenure) {
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
1377 __ Move(edx, Immediate(Smi::FromInt(expr->flags()))); 1355 __ Move(edx, Immediate(Smi::FromInt(expr->flags())));
1378 FastCloneRegExpStub stub(isolate()); 1356 FastCloneRegExpStub stub(isolate());
1379 __ CallStub(&stub); 1357 __ CallStub(&stub);
1380 context()->Plug(eax); 1358 context()->Plug(eax);
1381 } 1359 }
1382 1360
1383 1361
1384 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { 1362 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
1385 Expression* expression = (property == NULL) ? NULL : property->value(); 1363 Expression* expression = (property == NULL) ? NULL : property->value();
1386 if (expression == NULL) { 1364 if (expression == NULL) {
1387 __ push(Immediate(isolate()->factory()->null_value())); 1365 PushOperand(isolate()->factory()->null_value());
1388 } else { 1366 } else {
1389 VisitForStackValue(expression); 1367 VisitForStackValue(expression);
1390 if (NeedsHomeObject(expression)) { 1368 if (NeedsHomeObject(expression)) {
1391 DCHECK(property->kind() == ObjectLiteral::Property::GETTER || 1369 DCHECK(property->kind() == ObjectLiteral::Property::GETTER ||
1392 property->kind() == ObjectLiteral::Property::SETTER); 1370 property->kind() == ObjectLiteral::Property::SETTER);
1393 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3; 1371 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3;
1394 EmitSetHomeObject(expression, offset, property->GetSlot()); 1372 EmitSetHomeObject(expression, offset, property->GetSlot());
1395 } 1373 }
1396 } 1374 }
1397 } 1375 }
(...skipping 29 matching lines...) Expand all
1427 AccessorTable accessor_table(zone()); 1405 AccessorTable accessor_table(zone());
1428 int property_index = 0; 1406 int property_index = 0;
1429 for (; property_index < expr->properties()->length(); property_index++) { 1407 for (; property_index < expr->properties()->length(); property_index++) {
1430 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1408 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1431 if (property->is_computed_name()) break; 1409 if (property->is_computed_name()) break;
1432 if (property->IsCompileTimeValue()) continue; 1410 if (property->IsCompileTimeValue()) continue;
1433 1411
1434 Literal* key = property->key()->AsLiteral(); 1412 Literal* key = property->key()->AsLiteral();
1435 Expression* value = property->value(); 1413 Expression* value = property->value();
1436 if (!result_saved) { 1414 if (!result_saved) {
1437 __ push(eax); // Save result on the stack 1415 PushOperand(eax); // Save result on the stack
1438 result_saved = true; 1416 result_saved = true;
1439 } 1417 }
1440 switch (property->kind()) { 1418 switch (property->kind()) {
1441 case ObjectLiteral::Property::CONSTANT: 1419 case ObjectLiteral::Property::CONSTANT:
1442 UNREACHABLE(); 1420 UNREACHABLE();
1443 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1421 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1444 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); 1422 DCHECK(!CompileTimeValue::IsCompileTimeValue(value));
1445 // Fall through. 1423 // Fall through.
1446 case ObjectLiteral::Property::COMPUTED: 1424 case ObjectLiteral::Property::COMPUTED:
1447 // It is safe to use [[Put]] here because the boilerplate already 1425 // It is safe to use [[Put]] here because the boilerplate already
1448 // contains computed properties with an uninitialized value. 1426 // contains computed properties with an uninitialized value.
1449 if (key->value()->IsInternalizedString()) { 1427 if (key->value()->IsInternalizedString()) {
1450 if (property->emit_store()) { 1428 if (property->emit_store()) {
1451 VisitForAccumulatorValue(value); 1429 VisitForAccumulatorValue(value);
1452 DCHECK(StoreDescriptor::ValueRegister().is(eax)); 1430 DCHECK(StoreDescriptor::ValueRegister().is(eax));
1453 __ mov(StoreDescriptor::NameRegister(), Immediate(key->value())); 1431 __ mov(StoreDescriptor::NameRegister(), Immediate(key->value()));
1454 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); 1432 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0));
1455 EmitLoadStoreICSlot(property->GetSlot(0)); 1433 EmitLoadStoreICSlot(property->GetSlot(0));
1456 CallStoreIC(); 1434 CallStoreIC();
1457 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1435 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1458 if (NeedsHomeObject(value)) { 1436 if (NeedsHomeObject(value)) {
1459 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); 1437 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
1460 } 1438 }
1461 } else { 1439 } else {
1462 VisitForEffect(value); 1440 VisitForEffect(value);
1463 } 1441 }
1464 break; 1442 break;
1465 } 1443 }
1466 __ push(Operand(esp, 0)); // Duplicate receiver. 1444 PushOperand(Operand(esp, 0)); // Duplicate receiver.
1467 VisitForStackValue(key); 1445 VisitForStackValue(key);
1468 VisitForStackValue(value); 1446 VisitForStackValue(value);
1469 if (property->emit_store()) { 1447 if (property->emit_store()) {
1470 if (NeedsHomeObject(value)) { 1448 if (NeedsHomeObject(value)) {
1471 EmitSetHomeObject(value, 2, property->GetSlot()); 1449 EmitSetHomeObject(value, 2, property->GetSlot());
1472 } 1450 }
1473 __ push(Immediate(Smi::FromInt(SLOPPY))); // Language mode 1451 PushOperand(Smi::FromInt(SLOPPY)); // Language mode
1474 __ CallRuntime(Runtime::kSetProperty); 1452 CallRuntimeWithOperands(Runtime::kSetProperty);
1475 } else { 1453 } else {
1476 __ Drop(3); 1454 DropOperands(3);
1477 } 1455 }
1478 break; 1456 break;
1479 case ObjectLiteral::Property::PROTOTYPE: 1457 case ObjectLiteral::Property::PROTOTYPE:
1480 __ push(Operand(esp, 0)); // Duplicate receiver. 1458 PushOperand(Operand(esp, 0)); // Duplicate receiver.
1481 VisitForStackValue(value); 1459 VisitForStackValue(value);
1482 DCHECK(property->emit_store()); 1460 DCHECK(property->emit_store());
1483 __ CallRuntime(Runtime::kInternalSetPrototype); 1461 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1484 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1462 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1485 NO_REGISTERS); 1463 NO_REGISTERS);
1486 break; 1464 break;
1487 case ObjectLiteral::Property::GETTER: 1465 case ObjectLiteral::Property::GETTER:
1488 if (property->emit_store()) { 1466 if (property->emit_store()) {
1489 accessor_table.lookup(key)->second->getter = property; 1467 accessor_table.lookup(key)->second->getter = property;
1490 } 1468 }
1491 break; 1469 break;
1492 case ObjectLiteral::Property::SETTER: 1470 case ObjectLiteral::Property::SETTER:
1493 if (property->emit_store()) { 1471 if (property->emit_store()) {
1494 accessor_table.lookup(key)->second->setter = property; 1472 accessor_table.lookup(key)->second->setter = property;
1495 } 1473 }
1496 break; 1474 break;
1497 } 1475 }
1498 } 1476 }
1499 1477
1500 // Emit code to define accessors, using only a single call to the runtime for 1478 // Emit code to define accessors, using only a single call to the runtime for
1501 // each pair of corresponding getters and setters. 1479 // each pair of corresponding getters and setters.
1502 for (AccessorTable::Iterator it = accessor_table.begin(); 1480 for (AccessorTable::Iterator it = accessor_table.begin();
1503 it != accessor_table.end(); 1481 it != accessor_table.end();
1504 ++it) { 1482 ++it) {
1505 __ push(Operand(esp, 0)); // Duplicate receiver. 1483 PushOperand(Operand(esp, 0)); // Duplicate receiver.
1506 VisitForStackValue(it->first); 1484 VisitForStackValue(it->first);
1507 1485
1508 EmitAccessor(it->second->getter); 1486 EmitAccessor(it->second->getter);
1509 EmitAccessor(it->second->setter); 1487 EmitAccessor(it->second->setter);
1510 1488
1511 __ push(Immediate(Smi::FromInt(NONE))); 1489 PushOperand(Smi::FromInt(NONE));
1512 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked); 1490 CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked);
1513 } 1491 }
1514 1492
1515 // Object literals have two parts. The "static" part on the left contains no 1493 // Object literals have two parts. The "static" part on the left contains no
1516 // computed property names, and so we can compute its map ahead of time; see 1494 // computed property names, and so we can compute its map ahead of time; see
1517 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part 1495 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part
1518 // starts with the first computed property name, and continues with all 1496 // starts with the first computed property name, and continues with all
1519 // properties to its right. All the code from above initializes the static 1497 // properties to its right. All the code from above initializes the static
1520 // component of the object literal, and arranges for the map of the result to 1498 // component of the object literal, and arranges for the map of the result to
1521 // reflect the static order in which the keys appear. For the dynamic 1499 // reflect the static order in which the keys appear. For the dynamic
1522 // properties, we compile them into a series of "SetOwnProperty" runtime 1500 // properties, we compile them into a series of "SetOwnProperty" runtime
1523 // calls. This will preserve insertion order. 1501 // calls. This will preserve insertion order.
1524 for (; property_index < expr->properties()->length(); property_index++) { 1502 for (; property_index < expr->properties()->length(); property_index++) {
1525 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1503 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1526 1504
1527 Expression* value = property->value(); 1505 Expression* value = property->value();
1528 if (!result_saved) { 1506 if (!result_saved) {
1529 __ push(eax); // Save result on the stack 1507 PushOperand(eax); // Save result on the stack
1530 result_saved = true; 1508 result_saved = true;
1531 } 1509 }
1532 1510
1533 __ push(Operand(esp, 0)); // Duplicate receiver. 1511 PushOperand(Operand(esp, 0)); // Duplicate receiver.
1534 1512
1535 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1513 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1536 DCHECK(!property->is_computed_name()); 1514 DCHECK(!property->is_computed_name());
1537 VisitForStackValue(value); 1515 VisitForStackValue(value);
1538 DCHECK(property->emit_store()); 1516 DCHECK(property->emit_store());
1539 __ CallRuntime(Runtime::kInternalSetPrototype); 1517 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1540 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1518 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1541 NO_REGISTERS); 1519 NO_REGISTERS);
1542 } else { 1520 } else {
1543 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); 1521 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
1544 VisitForStackValue(value); 1522 VisitForStackValue(value);
1545 if (NeedsHomeObject(value)) { 1523 if (NeedsHomeObject(value)) {
1546 EmitSetHomeObject(value, 2, property->GetSlot()); 1524 EmitSetHomeObject(value, 2, property->GetSlot());
1547 } 1525 }
1548 1526
1549 switch (property->kind()) { 1527 switch (property->kind()) {
1550 case ObjectLiteral::Property::CONSTANT: 1528 case ObjectLiteral::Property::CONSTANT:
1551 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1529 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1552 case ObjectLiteral::Property::COMPUTED: 1530 case ObjectLiteral::Property::COMPUTED:
1553 if (property->emit_store()) { 1531 if (property->emit_store()) {
1554 __ Push(Smi::FromInt(NONE)); 1532 PushOperand(Smi::FromInt(NONE));
1555 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); 1533 PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
1556 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); 1534 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
1557 } else { 1535 } else {
1558 __ Drop(3); 1536 DropOperands(3);
1559 } 1537 }
1560 break; 1538 break;
1561 1539
1562 case ObjectLiteral::Property::PROTOTYPE: 1540 case ObjectLiteral::Property::PROTOTYPE:
1563 UNREACHABLE(); 1541 UNREACHABLE();
1564 break; 1542 break;
1565 1543
1566 case ObjectLiteral::Property::GETTER: 1544 case ObjectLiteral::Property::GETTER:
1567 __ Push(Smi::FromInt(NONE)); 1545 PushOperand(Smi::FromInt(NONE));
1568 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); 1546 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
1569 break; 1547 break;
1570 1548
1571 case ObjectLiteral::Property::SETTER: 1549 case ObjectLiteral::Property::SETTER:
1572 __ Push(Smi::FromInt(NONE)); 1550 PushOperand(Smi::FromInt(NONE));
1573 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); 1551 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
1574 break; 1552 break;
1575 } 1553 }
1576 } 1554 }
1577 } 1555 }
1578 1556
1579 if (expr->has_function()) { 1557 if (expr->has_function()) {
1580 DCHECK(result_saved); 1558 DCHECK(result_saved);
1581 __ push(Operand(esp, 0)); 1559 __ push(Operand(esp, 0));
1582 __ CallRuntime(Runtime::kToFastProperties); 1560 __ CallRuntime(Runtime::kToFastProperties);
1583 } 1561 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1628 int array_index = 0; 1606 int array_index = 0;
1629 for (; array_index < length; array_index++) { 1607 for (; array_index < length; array_index++) {
1630 Expression* subexpr = subexprs->at(array_index); 1608 Expression* subexpr = subexprs->at(array_index);
1631 DCHECK(!subexpr->IsSpread()); 1609 DCHECK(!subexpr->IsSpread());
1632 1610
1633 // If the subexpression is a literal or a simple materialized literal it 1611 // If the subexpression is a literal or a simple materialized literal it
1634 // is already set in the cloned array. 1612 // is already set in the cloned array.
1635 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 1613 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
1636 1614
1637 if (!result_saved) { 1615 if (!result_saved) {
1638 __ push(eax); // array literal. 1616 PushOperand(eax); // array literal.
1639 result_saved = true; 1617 result_saved = true;
1640 } 1618 }
1641 VisitForAccumulatorValue(subexpr); 1619 VisitForAccumulatorValue(subexpr);
1642 1620
1643 __ mov(StoreDescriptor::NameRegister(), 1621 __ mov(StoreDescriptor::NameRegister(),
1644 Immediate(Smi::FromInt(array_index))); 1622 Immediate(Smi::FromInt(array_index)));
1645 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); 1623 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0));
1646 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); 1624 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot());
1647 Handle<Code> ic = 1625 Handle<Code> ic =
1648 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 1626 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
1649 CallIC(ic); 1627 CallIC(ic);
1650 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1628 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1651 } 1629 }
1652 1630
1653 // In case the array literal contains spread expressions it has two parts. The 1631 // In case the array literal contains spread expressions it has two parts. The
1654 // first part is the "static" array which has a literal index is handled 1632 // first part is the "static" array which has a literal index is handled
1655 // above. The second part is the part after the first spread expression 1633 // above. The second part is the part after the first spread expression
1656 // (inclusive) and these elements gets appended to the array. Note that the 1634 // (inclusive) and these elements gets appended to the array. Note that the
1657 // number elements an iterable produces is unknown ahead of time. 1635 // number elements an iterable produces is unknown ahead of time.
1658 if (array_index < length && result_saved) { 1636 if (array_index < length && result_saved) {
1659 __ Pop(eax); 1637 PopOperand(eax);
1660 result_saved = false; 1638 result_saved = false;
1661 } 1639 }
1662 for (; array_index < length; array_index++) { 1640 for (; array_index < length; array_index++) {
1663 Expression* subexpr = subexprs->at(array_index); 1641 Expression* subexpr = subexprs->at(array_index);
1664 1642
1665 __ Push(eax); 1643 PushOperand(eax);
1666 DCHECK(!subexpr->IsSpread()); 1644 DCHECK(!subexpr->IsSpread());
1667 VisitForStackValue(subexpr); 1645 VisitForStackValue(subexpr);
1668 __ CallRuntime(Runtime::kAppendElement); 1646 CallRuntimeWithOperands(Runtime::kAppendElement);
1669 1647
1670 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1648 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1671 } 1649 }
1672 1650
1673 if (result_saved) { 1651 if (result_saved) {
1674 context()->PlugTOS(); 1652 context()->PlugTOS();
1675 } else { 1653 } else {
1676 context()->Plug(eax); 1654 context()->Plug(eax);
1677 } 1655 }
1678 } 1656 }
(...skipping 11 matching lines...) Expand all
1690 // Evaluate LHS expression. 1668 // Evaluate LHS expression.
1691 switch (assign_type) { 1669 switch (assign_type) {
1692 case VARIABLE: 1670 case VARIABLE:
1693 // Nothing to do here. 1671 // Nothing to do here.
1694 break; 1672 break;
1695 case NAMED_SUPER_PROPERTY: 1673 case NAMED_SUPER_PROPERTY:
1696 VisitForStackValue( 1674 VisitForStackValue(
1697 property->obj()->AsSuperPropertyReference()->this_var()); 1675 property->obj()->AsSuperPropertyReference()->this_var());
1698 VisitForAccumulatorValue( 1676 VisitForAccumulatorValue(
1699 property->obj()->AsSuperPropertyReference()->home_object()); 1677 property->obj()->AsSuperPropertyReference()->home_object());
1700 __ push(result_register()); 1678 PushOperand(result_register());
1701 if (expr->is_compound()) { 1679 if (expr->is_compound()) {
1702 __ push(MemOperand(esp, kPointerSize)); 1680 PushOperand(MemOperand(esp, kPointerSize));
1703 __ push(result_register()); 1681 PushOperand(result_register());
1704 } 1682 }
1705 break; 1683 break;
1706 case NAMED_PROPERTY: 1684 case NAMED_PROPERTY:
1707 if (expr->is_compound()) { 1685 if (expr->is_compound()) {
1708 // We need the receiver both on the stack and in the register. 1686 // We need the receiver both on the stack and in the register.
1709 VisitForStackValue(property->obj()); 1687 VisitForStackValue(property->obj());
1710 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); 1688 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
1711 } else { 1689 } else {
1712 VisitForStackValue(property->obj()); 1690 VisitForStackValue(property->obj());
1713 } 1691 }
1714 break; 1692 break;
1715 case KEYED_SUPER_PROPERTY: 1693 case KEYED_SUPER_PROPERTY:
1716 VisitForStackValue( 1694 VisitForStackValue(
1717 property->obj()->AsSuperPropertyReference()->this_var()); 1695 property->obj()->AsSuperPropertyReference()->this_var());
1718 VisitForStackValue( 1696 VisitForStackValue(
1719 property->obj()->AsSuperPropertyReference()->home_object()); 1697 property->obj()->AsSuperPropertyReference()->home_object());
1720 VisitForAccumulatorValue(property->key()); 1698 VisitForAccumulatorValue(property->key());
1721 __ Push(result_register()); 1699 PushOperand(result_register());
1722 if (expr->is_compound()) { 1700 if (expr->is_compound()) {
1723 __ push(MemOperand(esp, 2 * kPointerSize)); 1701 PushOperand(MemOperand(esp, 2 * kPointerSize));
1724 __ push(MemOperand(esp, 2 * kPointerSize)); 1702 PushOperand(MemOperand(esp, 2 * kPointerSize));
1725 __ push(result_register()); 1703 PushOperand(result_register());
1726 } 1704 }
1727 break; 1705 break;
1728 case KEYED_PROPERTY: { 1706 case KEYED_PROPERTY: {
1729 if (expr->is_compound()) { 1707 if (expr->is_compound()) {
1730 VisitForStackValue(property->obj()); 1708 VisitForStackValue(property->obj());
1731 VisitForStackValue(property->key()); 1709 VisitForStackValue(property->key());
1732 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, kPointerSize)); 1710 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, kPointerSize));
1733 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); 1711 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0));
1734 } else { 1712 } else {
1735 VisitForStackValue(property->obj()); 1713 VisitForStackValue(property->obj());
(...skipping 26 matching lines...) Expand all
1762 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1740 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1763 break; 1741 break;
1764 case KEYED_PROPERTY: 1742 case KEYED_PROPERTY:
1765 EmitKeyedPropertyLoad(property); 1743 EmitKeyedPropertyLoad(property);
1766 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1744 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1767 break; 1745 break;
1768 } 1746 }
1769 } 1747 }
1770 1748
1771 Token::Value op = expr->binary_op(); 1749 Token::Value op = expr->binary_op();
1772 __ push(eax); // Left operand goes on the stack. 1750 PushOperand(eax); // Left operand goes on the stack.
1773 VisitForAccumulatorValue(expr->value()); 1751 VisitForAccumulatorValue(expr->value());
1774 1752
1775 if (ShouldInlineSmiCase(op)) { 1753 if (ShouldInlineSmiCase(op)) {
1776 EmitInlineSmiBinaryOp(expr->binary_operation(), 1754 EmitInlineSmiBinaryOp(expr->binary_operation(),
1777 op, 1755 op,
1778 expr->target(), 1756 expr->target(),
1779 expr->value()); 1757 expr->value());
1780 } else { 1758 } else {
1781 EmitBinaryOp(expr->binary_operation(), op); 1759 EmitBinaryOp(expr->binary_operation(), op);
1782 } 1760 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1855 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, 1833 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx,
1856 kDontSaveFPRegs); 1834 kDontSaveFPRegs);
1857 __ lea(ebx, Operand(ebp, StandardFrameConstants::kExpressionsOffset)); 1835 __ lea(ebx, Operand(ebp, StandardFrameConstants::kExpressionsOffset));
1858 __ cmp(esp, ebx); 1836 __ cmp(esp, ebx);
1859 __ j(equal, &post_runtime); 1837 __ j(equal, &post_runtime);
1860 __ push(eax); // generator object 1838 __ push(eax); // generator object
1861 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 1839 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
1862 __ mov(context_register(), 1840 __ mov(context_register(),
1863 Operand(ebp, StandardFrameConstants::kContextOffset)); 1841 Operand(ebp, StandardFrameConstants::kContextOffset));
1864 __ bind(&post_runtime); 1842 __ bind(&post_runtime);
1865 __ pop(result_register()); 1843 PopOperand(result_register());
1866 EmitReturnSequence(); 1844 EmitReturnSequence();
1867 1845
1868 __ bind(&resume); 1846 __ bind(&resume);
1869 context()->Plug(result_register()); 1847 context()->Plug(result_register());
1870 break; 1848 break;
1871 } 1849 }
1872 1850
1873 case Yield::kFinal: { 1851 case Yield::kFinal: {
1874 // Pop value from top-of-stack slot, box result into result register. 1852 // Pop value from top-of-stack slot, box result into result register.
1853 OperandStackDepthDecrement(1);
1875 EmitCreateIteratorResult(true); 1854 EmitCreateIteratorResult(true);
1876 EmitUnwindAndReturn(); 1855 EmitUnwindAndReturn();
1877 break; 1856 break;
1878 } 1857 }
1879 1858
1880 case Yield::kDelegating: 1859 case Yield::kDelegating:
1881 UNREACHABLE(); 1860 UNREACHABLE();
1882 } 1861 }
1883 } 1862 }
1884 1863
1885 1864
1886 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, 1865 void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
1887 Expression *value, 1866 Expression *value,
1888 JSGeneratorObject::ResumeMode resume_mode) { 1867 JSGeneratorObject::ResumeMode resume_mode) {
1889 // The value stays in eax, and is ultimately read by the resumed generator, as 1868 // The value stays in eax, and is ultimately read by the resumed generator, as
1890 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it 1869 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it
1891 // is read to throw the value when the resumed generator is already closed. 1870 // is read to throw the value when the resumed generator is already closed.
1892 // ebx will hold the generator object until the activation has been resumed. 1871 // ebx will hold the generator object until the activation has been resumed.
1893 VisitForStackValue(generator); 1872 VisitForStackValue(generator);
1894 VisitForAccumulatorValue(value); 1873 VisitForAccumulatorValue(value);
1895 __ pop(ebx); 1874 PopOperand(ebx);
1896 1875
1897 // Store input value into generator object. 1876 // Store input value into generator object.
1898 __ mov(FieldOperand(ebx, JSGeneratorObject::kInputOffset), result_register()); 1877 __ mov(FieldOperand(ebx, JSGeneratorObject::kInputOffset), result_register());
1899 __ mov(ecx, result_register()); 1878 __ mov(ecx, result_register());
1900 __ RecordWriteField(ebx, JSGeneratorObject::kInputOffset, ecx, edx, 1879 __ RecordWriteField(ebx, JSGeneratorObject::kInputOffset, ecx, edx,
1901 kDontSaveFPRegs); 1880 kDontSaveFPRegs);
1902 1881
1903 // Load suspended function and context. 1882 // Load suspended function and context.
1904 __ mov(esi, FieldOperand(ebx, JSGeneratorObject::kContextOffset)); 1883 __ mov(esi, FieldOperand(ebx, JSGeneratorObject::kContextOffset));
1905 __ mov(edi, FieldOperand(ebx, JSGeneratorObject::kFunctionOffset)); 1884 __ mov(edi, FieldOperand(ebx, JSGeneratorObject::kFunctionOffset));
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1967 __ push(result_register()); 1946 __ push(result_register());
1968 __ Push(Smi::FromInt(resume_mode)); 1947 __ Push(Smi::FromInt(resume_mode));
1969 __ CallRuntime(Runtime::kResumeJSGeneratorObject); 1948 __ CallRuntime(Runtime::kResumeJSGeneratorObject);
1970 // Not reached: the runtime call returns elsewhere. 1949 // Not reached: the runtime call returns elsewhere.
1971 __ Abort(kGeneratorFailedToResume); 1950 __ Abort(kGeneratorFailedToResume);
1972 1951
1973 __ bind(&done); 1952 __ bind(&done);
1974 context()->Plug(result_register()); 1953 context()->Plug(result_register());
1975 } 1954 }
1976 1955
1956 void FullCodeGenerator::PushOperand(MemOperand operand) {
1957 OperandStackDepthIncrement(1);
1958 __ Push(operand);
1959 }
1960
1961 void FullCodeGenerator::EmitOperandStackDepthCheck() {
1962 if (FLAG_debug_code) {
1963 int expected_diff = StandardFrameConstants::kFixedFrameSizeFromFp +
1964 operand_stack_depth_ * kPointerSize;
1965 __ mov(eax, ebp);
1966 __ sub(eax, esp);
1967 __ cmp(eax, Immediate(expected_diff));
1968 __ Assert(equal, kUnexpectedStackDepth);
1969 }
1970 }
1977 1971
1978 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { 1972 void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
1979 Label allocate, done_allocate; 1973 Label allocate, done_allocate;
1980 1974
1981 __ Allocate(JSIteratorResult::kSize, eax, ecx, edx, &allocate, TAG_OBJECT); 1975 __ Allocate(JSIteratorResult::kSize, eax, ecx, edx, &allocate, TAG_OBJECT);
1982 __ jmp(&done_allocate, Label::kNear); 1976 __ jmp(&done_allocate, Label::kNear);
1983 1977
1984 __ bind(&allocate); 1978 __ bind(&allocate);
1985 __ Push(Smi::FromInt(JSIteratorResult::kSize)); 1979 __ Push(Smi::FromInt(JSIteratorResult::kSize));
1986 __ CallRuntime(Runtime::kAllocateInNewSpace); 1980 __ CallRuntime(Runtime::kAllocateInNewSpace);
(...skipping 19 matching lines...) Expand all
2006 DCHECK(!key->value()->IsSmi()); 2000 DCHECK(!key->value()->IsSmi());
2007 DCHECK(!prop->IsSuperAccess()); 2001 DCHECK(!prop->IsSuperAccess());
2008 2002
2009 __ mov(LoadDescriptor::NameRegister(), Immediate(key->value())); 2003 __ mov(LoadDescriptor::NameRegister(), Immediate(key->value()));
2010 __ mov(LoadDescriptor::SlotRegister(), 2004 __ mov(LoadDescriptor::SlotRegister(),
2011 Immediate(SmiFromSlot(prop->PropertyFeedbackSlot()))); 2005 Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
2012 CallLoadIC(NOT_INSIDE_TYPEOF); 2006 CallLoadIC(NOT_INSIDE_TYPEOF);
2013 } 2007 }
2014 2008
2015 2009
2016 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
2017 // Stack: receiver, home_object.
2018 SetExpressionPosition(prop);
2019 Literal* key = prop->key()->AsLiteral();
2020 DCHECK(!key->value()->IsSmi());
2021 DCHECK(prop->IsSuperAccess());
2022
2023 __ push(Immediate(key->value()));
2024 __ CallRuntime(Runtime::kLoadFromSuper);
2025 }
2026
2027
2028 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2029 SetExpressionPosition(prop);
2030 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
2031 __ mov(LoadDescriptor::SlotRegister(),
2032 Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
2033 CallIC(ic);
2034 }
2035
2036
2037 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
2038 // Stack: receiver, home_object, key.
2039 SetExpressionPosition(prop);
2040 __ CallRuntime(Runtime::kLoadKeyedFromSuper);
2041 }
2042
2043
2044 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 2010 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
2045 Token::Value op, 2011 Token::Value op,
2046 Expression* left, 2012 Expression* left,
2047 Expression* right) { 2013 Expression* right) {
2048 // Do combined smi check of the operands. Left operand is on the 2014 // Do combined smi check of the operands. Left operand is on the
2049 // stack. Right operand is in eax. 2015 // stack. Right operand is in eax.
2050 Label smi_case, done, stub_call; 2016 Label smi_case, done, stub_call;
2051 __ pop(edx); 2017 PopOperand(edx);
2052 __ mov(ecx, eax); 2018 __ mov(ecx, eax);
2053 __ or_(eax, edx); 2019 __ or_(eax, edx);
2054 JumpPatchSite patch_site(masm_); 2020 JumpPatchSite patch_site(masm_);
2055 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); 2021 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear);
2056 2022
2057 __ bind(&stub_call); 2023 __ bind(&stub_call);
2058 __ mov(eax, ecx); 2024 __ mov(eax, ecx);
2059 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); 2025 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
2060 CallIC(code, expr->BinaryOperationFeedbackId()); 2026 CallIC(code, expr->BinaryOperationFeedbackId());
2061 patch_site.EmitPatchInfo(); 2027 patch_site.EmitPatchInfo();
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
2134 context()->Plug(eax); 2100 context()->Plug(eax);
2135 } 2101 }
2136 2102
2137 2103
2138 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) { 2104 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
2139 for (int i = 0; i < lit->properties()->length(); i++) { 2105 for (int i = 0; i < lit->properties()->length(); i++) {
2140 ObjectLiteral::Property* property = lit->properties()->at(i); 2106 ObjectLiteral::Property* property = lit->properties()->at(i);
2141 Expression* value = property->value(); 2107 Expression* value = property->value();
2142 2108
2143 if (property->is_static()) { 2109 if (property->is_static()) {
2144 __ push(Operand(esp, kPointerSize)); // constructor 2110 PushOperand(Operand(esp, kPointerSize)); // constructor
2145 } else { 2111 } else {
2146 __ push(Operand(esp, 0)); // prototype 2112 PushOperand(Operand(esp, 0)); // prototype
2147 } 2113 }
2148 EmitPropertyKey(property, lit->GetIdForProperty(i)); 2114 EmitPropertyKey(property, lit->GetIdForProperty(i));
2149 2115
2150 // The static prototype property is read only. We handle the non computed 2116 // The static prototype property is read only. We handle the non computed
2151 // property name case in the parser. Since this is the only case where we 2117 // property name case in the parser. Since this is the only case where we
2152 // need to check for an own read only property we special case this so we do 2118 // need to check for an own read only property we special case this so we do
2153 // not need to do this for every property. 2119 // not need to do this for every property.
2154 if (property->is_static() && property->is_computed_name()) { 2120 if (property->is_static() && property->is_computed_name()) {
2155 __ CallRuntime(Runtime::kThrowIfStaticPrototype); 2121 __ CallRuntime(Runtime::kThrowIfStaticPrototype);
2156 __ push(eax); 2122 __ push(eax);
2157 } 2123 }
2158 2124
2159 VisitForStackValue(value); 2125 VisitForStackValue(value);
2160 if (NeedsHomeObject(value)) { 2126 if (NeedsHomeObject(value)) {
2161 EmitSetHomeObject(value, 2, property->GetSlot()); 2127 EmitSetHomeObject(value, 2, property->GetSlot());
2162 } 2128 }
2163 2129
2164 switch (property->kind()) { 2130 switch (property->kind()) {
2165 case ObjectLiteral::Property::CONSTANT: 2131 case ObjectLiteral::Property::CONSTANT:
2166 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 2132 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
2167 case ObjectLiteral::Property::PROTOTYPE: 2133 case ObjectLiteral::Property::PROTOTYPE:
2168 UNREACHABLE(); 2134 UNREACHABLE();
2169 case ObjectLiteral::Property::COMPUTED: 2135 case ObjectLiteral::Property::COMPUTED:
2170 __ Push(Smi::FromInt(DONT_ENUM)); 2136 PushOperand(Smi::FromInt(DONT_ENUM));
2171 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); 2137 PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
2172 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); 2138 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
2173 break; 2139 break;
2174 2140
2175 case ObjectLiteral::Property::GETTER: 2141 case ObjectLiteral::Property::GETTER:
2176 __ Push(Smi::FromInt(DONT_ENUM)); 2142 PushOperand(Smi::FromInt(DONT_ENUM));
2177 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); 2143 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
2178 break; 2144 break;
2179 2145
2180 case ObjectLiteral::Property::SETTER: 2146 case ObjectLiteral::Property::SETTER:
2181 __ Push(Smi::FromInt(DONT_ENUM)); 2147 PushOperand(Smi::FromInt(DONT_ENUM));
2182 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); 2148 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
2183 break; 2149 break;
2184 } 2150 }
2185 } 2151 }
2186 } 2152 }
2187 2153
2188 2154
2189 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { 2155 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
2190 __ pop(edx); 2156 PopOperand(edx);
2191 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); 2157 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
2192 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 2158 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
2193 CallIC(code, expr->BinaryOperationFeedbackId()); 2159 CallIC(code, expr->BinaryOperationFeedbackId());
2194 patch_site.EmitPatchInfo(); 2160 patch_site.EmitPatchInfo();
2195 context()->Plug(eax); 2161 context()->Plug(eax);
2196 } 2162 }
2197 2163
2198 2164
2199 void FullCodeGenerator::EmitAssignment(Expression* expr, 2165 void FullCodeGenerator::EmitAssignment(Expression* expr,
2200 FeedbackVectorSlot slot) { 2166 FeedbackVectorSlot slot) {
2201 DCHECK(expr->IsValidReferenceExpressionOrThis()); 2167 DCHECK(expr->IsValidReferenceExpressionOrThis());
2202 2168
2203 Property* prop = expr->AsProperty(); 2169 Property* prop = expr->AsProperty();
2204 LhsKind assign_type = Property::GetAssignType(prop); 2170 LhsKind assign_type = Property::GetAssignType(prop);
2205 2171
2206 switch (assign_type) { 2172 switch (assign_type) {
2207 case VARIABLE: { 2173 case VARIABLE: {
2208 Variable* var = expr->AsVariableProxy()->var(); 2174 Variable* var = expr->AsVariableProxy()->var();
2209 EffectContext context(this); 2175 EffectContext context(this);
2210 EmitVariableAssignment(var, Token::ASSIGN, slot); 2176 EmitVariableAssignment(var, Token::ASSIGN, slot);
2211 break; 2177 break;
2212 } 2178 }
2213 case NAMED_PROPERTY: { 2179 case NAMED_PROPERTY: {
2214 __ push(eax); // Preserve value. 2180 PushOperand(eax); // Preserve value.
2215 VisitForAccumulatorValue(prop->obj()); 2181 VisitForAccumulatorValue(prop->obj());
2216 __ Move(StoreDescriptor::ReceiverRegister(), eax); 2182 __ Move(StoreDescriptor::ReceiverRegister(), eax);
2217 __ pop(StoreDescriptor::ValueRegister()); // Restore value. 2183 PopOperand(StoreDescriptor::ValueRegister()); // Restore value.
2218 __ mov(StoreDescriptor::NameRegister(), 2184 __ mov(StoreDescriptor::NameRegister(),
2219 prop->key()->AsLiteral()->value()); 2185 prop->key()->AsLiteral()->value());
2220 EmitLoadStoreICSlot(slot); 2186 EmitLoadStoreICSlot(slot);
2221 CallStoreIC(); 2187 CallStoreIC();
2222 break; 2188 break;
2223 } 2189 }
2224 case NAMED_SUPER_PROPERTY: { 2190 case NAMED_SUPER_PROPERTY: {
2225 __ push(eax); 2191 PushOperand(eax);
2226 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 2192 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
2227 VisitForAccumulatorValue( 2193 VisitForAccumulatorValue(
2228 prop->obj()->AsSuperPropertyReference()->home_object()); 2194 prop->obj()->AsSuperPropertyReference()->home_object());
2229 // stack: value, this; eax: home_object 2195 // stack: value, this; eax: home_object
2230 Register scratch = ecx; 2196 Register scratch = ecx;
2231 Register scratch2 = edx; 2197 Register scratch2 = edx;
2232 __ mov(scratch, result_register()); // home_object 2198 __ mov(scratch, result_register()); // home_object
2233 __ mov(eax, MemOperand(esp, kPointerSize)); // value 2199 __ mov(eax, MemOperand(esp, kPointerSize)); // value
2234 __ mov(scratch2, MemOperand(esp, 0)); // this 2200 __ mov(scratch2, MemOperand(esp, 0)); // this
2235 __ mov(MemOperand(esp, kPointerSize), scratch2); // this 2201 __ mov(MemOperand(esp, kPointerSize), scratch2); // this
2236 __ mov(MemOperand(esp, 0), scratch); // home_object 2202 __ mov(MemOperand(esp, 0), scratch); // home_object
2237 // stack: this, home_object. eax: value 2203 // stack: this, home_object. eax: value
2238 EmitNamedSuperPropertyStore(prop); 2204 EmitNamedSuperPropertyStore(prop);
2239 break; 2205 break;
2240 } 2206 }
2241 case KEYED_SUPER_PROPERTY: { 2207 case KEYED_SUPER_PROPERTY: {
2242 __ push(eax); 2208 PushOperand(eax);
2243 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 2209 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
2244 VisitForStackValue( 2210 VisitForStackValue(
2245 prop->obj()->AsSuperPropertyReference()->home_object()); 2211 prop->obj()->AsSuperPropertyReference()->home_object());
2246 VisitForAccumulatorValue(prop->key()); 2212 VisitForAccumulatorValue(prop->key());
2247 Register scratch = ecx; 2213 Register scratch = ecx;
2248 Register scratch2 = edx; 2214 Register scratch2 = edx;
2249 __ mov(scratch2, MemOperand(esp, 2 * kPointerSize)); // value 2215 __ mov(scratch2, MemOperand(esp, 2 * kPointerSize)); // value
2250 // stack: value, this, home_object; eax: key, edx: value 2216 // stack: value, this, home_object; eax: key, edx: value
2251 __ mov(scratch, MemOperand(esp, kPointerSize)); // this 2217 __ mov(scratch, MemOperand(esp, kPointerSize)); // this
2252 __ mov(MemOperand(esp, 2 * kPointerSize), scratch); 2218 __ mov(MemOperand(esp, 2 * kPointerSize), scratch);
2253 __ mov(scratch, MemOperand(esp, 0)); // home_object 2219 __ mov(scratch, MemOperand(esp, 0)); // home_object
2254 __ mov(MemOperand(esp, kPointerSize), scratch); 2220 __ mov(MemOperand(esp, kPointerSize), scratch);
2255 __ mov(MemOperand(esp, 0), eax); 2221 __ mov(MemOperand(esp, 0), eax);
2256 __ mov(eax, scratch2); 2222 __ mov(eax, scratch2);
2257 // stack: this, home_object, key; eax: value. 2223 // stack: this, home_object, key; eax: value.
2258 EmitKeyedSuperPropertyStore(prop); 2224 EmitKeyedSuperPropertyStore(prop);
2259 break; 2225 break;
2260 } 2226 }
2261 case KEYED_PROPERTY: { 2227 case KEYED_PROPERTY: {
2262 __ push(eax); // Preserve value. 2228 PushOperand(eax); // Preserve value.
2263 VisitForStackValue(prop->obj()); 2229 VisitForStackValue(prop->obj());
2264 VisitForAccumulatorValue(prop->key()); 2230 VisitForAccumulatorValue(prop->key());
2265 __ Move(StoreDescriptor::NameRegister(), eax); 2231 __ Move(StoreDescriptor::NameRegister(), eax);
2266 __ pop(StoreDescriptor::ReceiverRegister()); // Receiver. 2232 PopOperand(StoreDescriptor::ReceiverRegister()); // Receiver.
2267 __ pop(StoreDescriptor::ValueRegister()); // Restore value. 2233 PopOperand(StoreDescriptor::ValueRegister()); // Restore value.
2268 EmitLoadStoreICSlot(slot); 2234 EmitLoadStoreICSlot(slot);
2269 Handle<Code> ic = 2235 Handle<Code> ic =
2270 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2236 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2271 CallIC(ic); 2237 CallIC(ic);
2272 break; 2238 break;
2273 } 2239 }
2274 } 2240 }
2275 context()->Plug(eax); 2241 context()->Plug(eax);
2276 } 2242 }
2277 2243
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
2394 2360
2395 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2361 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2396 // Assignment to a property, using a named store IC. 2362 // Assignment to a property, using a named store IC.
2397 // eax : value 2363 // eax : value
2398 // esp[0] : receiver 2364 // esp[0] : receiver
2399 Property* prop = expr->target()->AsProperty(); 2365 Property* prop = expr->target()->AsProperty();
2400 DCHECK(prop != NULL); 2366 DCHECK(prop != NULL);
2401 DCHECK(prop->key()->IsLiteral()); 2367 DCHECK(prop->key()->IsLiteral());
2402 2368
2403 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); 2369 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value());
2404 __ pop(StoreDescriptor::ReceiverRegister()); 2370 PopOperand(StoreDescriptor::ReceiverRegister());
2405 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2371 EmitLoadStoreICSlot(expr->AssignmentSlot());
2406 CallStoreIC(); 2372 CallStoreIC();
2407 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2373 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2408 context()->Plug(eax); 2374 context()->Plug(eax);
2409 } 2375 }
2410 2376
2411 2377
2412 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { 2378 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
2413 // Assignment to named property of super. 2379 // Assignment to named property of super.
2414 // eax : value 2380 // eax : value
2415 // stack : receiver ('this'), home_object 2381 // stack : receiver ('this'), home_object
2416 DCHECK(prop != NULL); 2382 DCHECK(prop != NULL);
2417 Literal* key = prop->key()->AsLiteral(); 2383 Literal* key = prop->key()->AsLiteral();
2418 DCHECK(key != NULL); 2384 DCHECK(key != NULL);
2419 2385
2420 __ push(Immediate(key->value())); 2386 PushOperand(key->value());
2421 __ push(eax); 2387 PushOperand(eax);
2422 __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict 2388 CallRuntimeWithOperands(is_strict(language_mode())
2423 : Runtime::kStoreToSuper_Sloppy)); 2389 ? Runtime::kStoreToSuper_Strict
2390 : Runtime::kStoreToSuper_Sloppy);
2424 } 2391 }
2425 2392
2426 2393
2427 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { 2394 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
2428 // Assignment to named property of super. 2395 // Assignment to named property of super.
2429 // eax : value 2396 // eax : value
2430 // stack : receiver ('this'), home_object, key 2397 // stack : receiver ('this'), home_object, key
2431 2398
2432 __ push(eax); 2399 PushOperand(eax);
2433 __ CallRuntime((is_strict(language_mode()) 2400 CallRuntimeWithOperands(is_strict(language_mode())
2434 ? Runtime::kStoreKeyedToSuper_Strict 2401 ? Runtime::kStoreKeyedToSuper_Strict
2435 : Runtime::kStoreKeyedToSuper_Sloppy)); 2402 : Runtime::kStoreKeyedToSuper_Sloppy);
2436 } 2403 }
2437 2404
2438 2405
2439 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2406 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2440 // Assignment to a property, using a keyed store IC. 2407 // Assignment to a property, using a keyed store IC.
2441 // eax : value 2408 // eax : value
2442 // esp[0] : key 2409 // esp[0] : key
2443 // esp[kPointerSize] : receiver 2410 // esp[kPointerSize] : receiver
2444 2411
2445 __ pop(StoreDescriptor::NameRegister()); // Key. 2412 PopOperand(StoreDescriptor::NameRegister()); // Key.
2446 __ pop(StoreDescriptor::ReceiverRegister()); 2413 PopOperand(StoreDescriptor::ReceiverRegister());
2447 DCHECK(StoreDescriptor::ValueRegister().is(eax)); 2414 DCHECK(StoreDescriptor::ValueRegister().is(eax));
2448 Handle<Code> ic = 2415 Handle<Code> ic =
2449 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2416 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2450 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2417 EmitLoadStoreICSlot(expr->AssignmentSlot());
2451 CallIC(ic); 2418 CallIC(ic);
2452 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2419 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2453 context()->Plug(eax); 2420 context()->Plug(eax);
2454 } 2421 }
2455 2422
2456 2423
(...skipping 11 matching lines...) Expand all
2468 } else { 2435 } else {
2469 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); 2436 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
2470 VisitForStackValue( 2437 VisitForStackValue(
2471 expr->obj()->AsSuperPropertyReference()->home_object()); 2438 expr->obj()->AsSuperPropertyReference()->home_object());
2472 EmitNamedSuperPropertyLoad(expr); 2439 EmitNamedSuperPropertyLoad(expr);
2473 } 2440 }
2474 } else { 2441 } else {
2475 if (!expr->IsSuperAccess()) { 2442 if (!expr->IsSuperAccess()) {
2476 VisitForStackValue(expr->obj()); 2443 VisitForStackValue(expr->obj());
2477 VisitForAccumulatorValue(expr->key()); 2444 VisitForAccumulatorValue(expr->key());
2478 __ pop(LoadDescriptor::ReceiverRegister()); // Object. 2445 PopOperand(LoadDescriptor::ReceiverRegister()); // Object.
2479 __ Move(LoadDescriptor::NameRegister(), result_register()); // Key. 2446 __ Move(LoadDescriptor::NameRegister(), result_register()); // Key.
2480 EmitKeyedPropertyLoad(expr); 2447 EmitKeyedPropertyLoad(expr);
2481 } else { 2448 } else {
2482 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); 2449 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
2483 VisitForStackValue( 2450 VisitForStackValue(
2484 expr->obj()->AsSuperPropertyReference()->home_object()); 2451 expr->obj()->AsSuperPropertyReference()->home_object());
2485 VisitForStackValue(expr->key()); 2452 VisitForStackValue(expr->key());
2486 EmitKeyedSuperPropertyLoad(expr); 2453 EmitKeyedSuperPropertyLoad(expr);
2487 } 2454 }
2488 } 2455 }
(...skipping 15 matching lines...) Expand all
2504 2471
2505 // Get the target function. 2472 // Get the target function.
2506 ConvertReceiverMode convert_mode; 2473 ConvertReceiverMode convert_mode;
2507 if (callee->IsVariableProxy()) { 2474 if (callee->IsVariableProxy()) {
2508 { StackValueContext context(this); 2475 { StackValueContext context(this);
2509 EmitVariableLoad(callee->AsVariableProxy()); 2476 EmitVariableLoad(callee->AsVariableProxy());
2510 PrepareForBailout(callee, NO_REGISTERS); 2477 PrepareForBailout(callee, NO_REGISTERS);
2511 } 2478 }
2512 // Push undefined as receiver. This is patched in the method prologue if it 2479 // Push undefined as receiver. This is patched in the method prologue if it
2513 // is a sloppy mode method. 2480 // is a sloppy mode method.
2514 __ push(Immediate(isolate()->factory()->undefined_value())); 2481 PushOperand(isolate()->factory()->undefined_value());
2515 convert_mode = ConvertReceiverMode::kNullOrUndefined; 2482 convert_mode = ConvertReceiverMode::kNullOrUndefined;
2516 } else { 2483 } else {
2517 // Load the function from the receiver. 2484 // Load the function from the receiver.
2518 DCHECK(callee->IsProperty()); 2485 DCHECK(callee->IsProperty());
2519 DCHECK(!callee->AsProperty()->IsSuperAccess()); 2486 DCHECK(!callee->AsProperty()->IsSuperAccess());
2520 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); 2487 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
2521 EmitNamedPropertyLoad(callee->AsProperty()); 2488 EmitNamedPropertyLoad(callee->AsProperty());
2522 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2489 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2523 // Push the target function under the receiver. 2490 // Push the target function under the receiver.
2524 __ push(Operand(esp, 0)); 2491 PushOperand(Operand(esp, 0));
2525 __ mov(Operand(esp, kPointerSize), eax); 2492 __ mov(Operand(esp, kPointerSize), eax);
2526 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; 2493 convert_mode = ConvertReceiverMode::kNotNullOrUndefined;
2527 } 2494 }
2528 2495
2529 EmitCall(expr, convert_mode); 2496 EmitCall(expr, convert_mode);
2530 } 2497 }
2531 2498
2532 2499
2533 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { 2500 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
2534 SetExpressionPosition(expr); 2501 SetExpressionPosition(expr);
2535 Expression* callee = expr->expression(); 2502 Expression* callee = expr->expression();
2536 DCHECK(callee->IsProperty()); 2503 DCHECK(callee->IsProperty());
2537 Property* prop = callee->AsProperty(); 2504 Property* prop = callee->AsProperty();
2538 DCHECK(prop->IsSuperAccess()); 2505 DCHECK(prop->IsSuperAccess());
2539 2506
2540 Literal* key = prop->key()->AsLiteral(); 2507 Literal* key = prop->key()->AsLiteral();
2541 DCHECK(!key->value()->IsSmi()); 2508 DCHECK(!key->value()->IsSmi());
2542 // Load the function from the receiver. 2509 // Load the function from the receiver.
2543 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); 2510 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
2544 VisitForStackValue(super_ref->home_object()); 2511 VisitForStackValue(super_ref->home_object());
2545 VisitForAccumulatorValue(super_ref->this_var()); 2512 VisitForAccumulatorValue(super_ref->this_var());
2546 __ push(eax); 2513 PushOperand(eax);
2547 __ push(eax); 2514 PushOperand(eax);
2548 __ push(Operand(esp, kPointerSize * 2)); 2515 PushOperand(Operand(esp, kPointerSize * 2));
2549 __ push(Immediate(key->value())); 2516 PushOperand(key->value());
2550 // Stack here: 2517 // Stack here:
2551 // - home_object 2518 // - home_object
2552 // - this (receiver) 2519 // - this (receiver)
2553 // - this (receiver) <-- LoadFromSuper will pop here and below. 2520 // - this (receiver) <-- LoadFromSuper will pop here and below.
2554 // - home_object 2521 // - home_object
2555 // - key 2522 // - key
2556 __ CallRuntime(Runtime::kLoadFromSuper); 2523 CallRuntimeWithOperands(Runtime::kLoadFromSuper);
2557 2524
2558 // Replace home_object with target function. 2525 // Replace home_object with target function.
2559 __ mov(Operand(esp, kPointerSize), eax); 2526 __ mov(Operand(esp, kPointerSize), eax);
2560 2527
2561 // Stack here: 2528 // Stack here:
2562 // - target function 2529 // - target function
2563 // - this (receiver) 2530 // - this (receiver)
2564 EmitCall(expr); 2531 EmitCall(expr);
2565 } 2532 }
2566 2533
2567 2534
2568 // Code common for calls using the IC. 2535 // Code common for calls using the IC.
2569 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2536 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2570 Expression* key) { 2537 Expression* key) {
2571 // Load the key. 2538 // Load the key.
2572 VisitForAccumulatorValue(key); 2539 VisitForAccumulatorValue(key);
2573 2540
2574 Expression* callee = expr->expression(); 2541 Expression* callee = expr->expression();
2575 2542
2576 // Load the function from the receiver. 2543 // Load the function from the receiver.
2577 DCHECK(callee->IsProperty()); 2544 DCHECK(callee->IsProperty());
2578 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); 2545 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
2579 __ mov(LoadDescriptor::NameRegister(), eax); 2546 __ mov(LoadDescriptor::NameRegister(), eax);
2580 EmitKeyedPropertyLoad(callee->AsProperty()); 2547 EmitKeyedPropertyLoad(callee->AsProperty());
2581 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2548 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2582 2549
2583 // Push the target function under the receiver. 2550 // Push the target function under the receiver.
2584 __ push(Operand(esp, 0)); 2551 PushOperand(Operand(esp, 0));
2585 __ mov(Operand(esp, kPointerSize), eax); 2552 __ mov(Operand(esp, kPointerSize), eax);
2586 2553
2587 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); 2554 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined);
2588 } 2555 }
2589 2556
2590 2557
2591 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { 2558 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
2592 Expression* callee = expr->expression(); 2559 Expression* callee = expr->expression();
2593 DCHECK(callee->IsProperty()); 2560 DCHECK(callee->IsProperty());
2594 Property* prop = callee->AsProperty(); 2561 Property* prop = callee->AsProperty();
2595 DCHECK(prop->IsSuperAccess()); 2562 DCHECK(prop->IsSuperAccess());
2596 2563
2597 SetExpressionPosition(prop); 2564 SetExpressionPosition(prop);
2598 // Load the function from the receiver. 2565 // Load the function from the receiver.
2599 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); 2566 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
2600 VisitForStackValue(super_ref->home_object()); 2567 VisitForStackValue(super_ref->home_object());
2601 VisitForAccumulatorValue(super_ref->this_var()); 2568 VisitForAccumulatorValue(super_ref->this_var());
2602 __ push(eax); 2569 PushOperand(eax);
2603 __ push(eax); 2570 PushOperand(eax);
2604 __ push(Operand(esp, kPointerSize * 2)); 2571 PushOperand(Operand(esp, kPointerSize * 2));
2605 VisitForStackValue(prop->key()); 2572 VisitForStackValue(prop->key());
2606 // Stack here: 2573 // Stack here:
2607 // - home_object 2574 // - home_object
2608 // - this (receiver) 2575 // - this (receiver)
2609 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. 2576 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
2610 // - home_object 2577 // - home_object
2611 // - key 2578 // - key
2612 __ CallRuntime(Runtime::kLoadKeyedFromSuper); 2579 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper);
2613 2580
2614 // Replace home_object with target function. 2581 // Replace home_object with target function.
2615 __ mov(Operand(esp, kPointerSize), eax); 2582 __ mov(Operand(esp, kPointerSize), eax);
2616 2583
2617 // Stack here: 2584 // Stack here:
2618 // - target function 2585 // - target function
2619 // - this (receiver) 2586 // - this (receiver)
2620 EmitCall(expr); 2587 EmitCall(expr);
2621 } 2588 }
2622 2589
(...skipping 17 matching lines...) Expand all
2640 EmitProfilingCounterHandlingForReturnSequence(true); 2607 EmitProfilingCounterHandlingForReturnSequence(true);
2641 } 2608 }
2642 Handle<Code> ic = 2609 Handle<Code> ic =
2643 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) 2610 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode())
2644 .code(); 2611 .code();
2645 __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot()))); 2612 __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot())));
2646 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 2613 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
2647 // Don't assign a type feedback id to the IC, since type feedback is provided 2614 // Don't assign a type feedback id to the IC, since type feedback is provided
2648 // by the vector above. 2615 // by the vector above.
2649 CallIC(ic); 2616 CallIC(ic);
2617 OperandStackDepthDecrement(arg_count + 1);
2650 2618
2651 RecordJSReturnSite(expr); 2619 RecordJSReturnSite(expr);
2652 2620
2653 // Restore context register. 2621 // Restore context register.
2654 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2622 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2655 2623
2656 context()->DropAndPlug(1, eax); 2624 context()->DropAndPlug(1, eax);
2657 } 2625 }
2658 2626
2659 2627
(...skipping 27 matching lines...) Expand all
2687 SetExpressionPosition(callee); 2655 SetExpressionPosition(callee);
2688 // Generate code for loading from variables potentially shadowed by 2656 // Generate code for loading from variables potentially shadowed by
2689 // eval-introduced variables. 2657 // eval-introduced variables.
2690 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); 2658 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2691 2659
2692 __ bind(&slow); 2660 __ bind(&slow);
2693 // Call the runtime to find the function to call (returned in eax) and 2661 // Call the runtime to find the function to call (returned in eax) and
2694 // the object holding it (returned in edx). 2662 // the object holding it (returned in edx).
2695 __ Push(callee->name()); 2663 __ Push(callee->name());
2696 __ CallRuntime(Runtime::kLoadLookupSlotForCall); 2664 __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2697 __ Push(eax); // Function. 2665 PushOperand(eax); // Function.
2698 __ Push(edx); // Receiver. 2666 PushOperand(edx); // Receiver.
2699 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); 2667 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
2700 2668
2701 // If fast case code has been generated, emit code to push the function 2669 // If fast case code has been generated, emit code to push the function
2702 // and receiver and have the slow path jump around this code. 2670 // and receiver and have the slow path jump around this code.
2703 if (done.is_linked()) { 2671 if (done.is_linked()) {
2704 Label call; 2672 Label call;
2705 __ jmp(&call, Label::kNear); 2673 __ jmp(&call, Label::kNear);
2706 __ bind(&done); 2674 __ bind(&done);
2707 // Push function. 2675 // Push function.
2708 __ push(eax); 2676 __ push(eax);
2709 // The receiver is implicitly the global receiver. Indicate this by 2677 // The receiver is implicitly the global receiver. Indicate this by
2710 // passing the hole to the call function stub. 2678 // passing the hole to the call function stub.
2711 __ push(Immediate(isolate()->factory()->undefined_value())); 2679 __ push(Immediate(isolate()->factory()->undefined_value()));
2712 __ bind(&call); 2680 __ bind(&call);
2713 } 2681 }
2714 } else { 2682 } else {
2715 VisitForStackValue(callee); 2683 VisitForStackValue(callee);
2716 // refEnv.WithBaseObject() 2684 // refEnv.WithBaseObject()
2717 __ push(Immediate(isolate()->factory()->undefined_value())); 2685 PushOperand(isolate()->factory()->undefined_value());
2718 } 2686 }
2719 } 2687 }
2720 2688
2721 2689
2722 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { 2690 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
2723 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval 2691 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
2724 // to resolve the function we need to call. Then we call the resolved 2692 // to resolve the function we need to call. Then we call the resolved
2725 // function using the given arguments. 2693 // function using the given arguments.
2726 ZoneList<Expression*>* args = expr->arguments(); 2694 ZoneList<Expression*>* args = expr->arguments();
2727 int arg_count = args->length(); 2695 int arg_count = args->length();
(...skipping 14 matching lines...) Expand all
2742 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax); 2710 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
2743 2711
2744 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); 2712 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
2745 2713
2746 SetCallPosition(expr); 2714 SetCallPosition(expr);
2747 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 2715 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
2748 __ Set(eax, arg_count); 2716 __ Set(eax, arg_count);
2749 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, 2717 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2750 expr->tail_call_mode()), 2718 expr->tail_call_mode()),
2751 RelocInfo::CODE_TARGET); 2719 RelocInfo::CODE_TARGET);
2720 OperandStackDepthDecrement(arg_count + 1);
2752 RecordJSReturnSite(expr); 2721 RecordJSReturnSite(expr);
2753 // Restore context register. 2722 // Restore context register.
2754 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2723 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2755 context()->DropAndPlug(1, eax); 2724 context()->DropAndPlug(1, eax);
2756 } 2725 }
2757 2726
2758 2727
2759 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2728 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
2760 Comment cmnt(masm_, "[ CallNew"); 2729 Comment cmnt(masm_, "[ CallNew");
2761 // According to ECMA-262, section 11.2.2, page 44, the function 2730 // According to ECMA-262, section 11.2.2, page 44, the function
(...skipping 20 matching lines...) Expand all
2782 // Load function and argument count into edi and eax. 2751 // Load function and argument count into edi and eax.
2783 __ Move(eax, Immediate(arg_count)); 2752 __ Move(eax, Immediate(arg_count));
2784 __ mov(edi, Operand(esp, arg_count * kPointerSize)); 2753 __ mov(edi, Operand(esp, arg_count * kPointerSize));
2785 2754
2786 // Record call targets in unoptimized code. 2755 // Record call targets in unoptimized code.
2787 __ EmitLoadTypeFeedbackVector(ebx); 2756 __ EmitLoadTypeFeedbackVector(ebx);
2788 __ mov(edx, Immediate(SmiFromSlot(expr->CallNewFeedbackSlot()))); 2757 __ mov(edx, Immediate(SmiFromSlot(expr->CallNewFeedbackSlot())));
2789 2758
2790 CallConstructStub stub(isolate()); 2759 CallConstructStub stub(isolate());
2791 __ call(stub.GetCode(), RelocInfo::CODE_TARGET); 2760 __ call(stub.GetCode(), RelocInfo::CODE_TARGET);
2761 OperandStackDepthDecrement(arg_count + 1);
2792 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2762 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2793 // Restore context register. 2763 // Restore context register.
2794 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2764 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2795 context()->Plug(eax); 2765 context()->Plug(eax);
2796 } 2766 }
2797 2767
2798 2768
2799 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { 2769 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
2800 SuperCallReference* super_call_ref = 2770 SuperCallReference* super_call_ref =
2801 expr->expression()->AsSuperCallReference(); 2771 expr->expression()->AsSuperCallReference();
2802 DCHECK_NOT_NULL(super_call_ref); 2772 DCHECK_NOT_NULL(super_call_ref);
2803 2773
2804 // Push the super constructor target on the stack (may be null, 2774 // Push the super constructor target on the stack (may be null,
2805 // but the Construct builtin can deal with that properly). 2775 // but the Construct builtin can deal with that properly).
2806 VisitForAccumulatorValue(super_call_ref->this_function_var()); 2776 VisitForAccumulatorValue(super_call_ref->this_function_var());
2807 __ AssertFunction(result_register()); 2777 __ AssertFunction(result_register());
2808 __ mov(result_register(), 2778 __ mov(result_register(),
2809 FieldOperand(result_register(), HeapObject::kMapOffset)); 2779 FieldOperand(result_register(), HeapObject::kMapOffset));
2810 __ Push(FieldOperand(result_register(), Map::kPrototypeOffset)); 2780 PushOperand(FieldOperand(result_register(), Map::kPrototypeOffset));
2811 2781
2812 // Push the arguments ("left-to-right") on the stack. 2782 // Push the arguments ("left-to-right") on the stack.
2813 ZoneList<Expression*>* args = expr->arguments(); 2783 ZoneList<Expression*>* args = expr->arguments();
2814 int arg_count = args->length(); 2784 int arg_count = args->length();
2815 for (int i = 0; i < arg_count; i++) { 2785 for (int i = 0; i < arg_count; i++) {
2816 VisitForStackValue(args->at(i)); 2786 VisitForStackValue(args->at(i));
2817 } 2787 }
2818 2788
2819 // Call the construct call builtin that handles allocation and 2789 // Call the construct call builtin that handles allocation and
2820 // constructor invocation. 2790 // constructor invocation.
2821 SetConstructCallPosition(expr); 2791 SetConstructCallPosition(expr);
2822 2792
2823 // Load new target into edx. 2793 // Load new target into edx.
2824 VisitForAccumulatorValue(super_call_ref->new_target_var()); 2794 VisitForAccumulatorValue(super_call_ref->new_target_var());
2825 __ mov(edx, result_register()); 2795 __ mov(edx, result_register());
2826 2796
2827 // Load function and argument count into edi and eax. 2797 // Load function and argument count into edi and eax.
2828 __ Move(eax, Immediate(arg_count)); 2798 __ Move(eax, Immediate(arg_count));
2829 __ mov(edi, Operand(esp, arg_count * kPointerSize)); 2799 __ mov(edi, Operand(esp, arg_count * kPointerSize));
2830 2800
2831 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 2801 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
2802 OperandStackDepthDecrement(arg_count + 1);
2832 2803
2833 RecordJSReturnSite(expr); 2804 RecordJSReturnSite(expr);
2834 2805
2835 // Restore context register. 2806 // Restore context register.
2836 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2807 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2837 context()->Plug(eax); 2808 context()->Plug(eax);
2838 } 2809 }
2839 2810
2840 2811
2841 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2812 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
3042 DCHECK_EQ(3, args->length()); 3013 DCHECK_EQ(3, args->length());
3043 3014
3044 Register string = eax; 3015 Register string = eax;
3045 Register index = ebx; 3016 Register index = ebx;
3046 Register value = ecx; 3017 Register value = ecx;
3047 3018
3048 VisitForStackValue(args->at(0)); // index 3019 VisitForStackValue(args->at(0)); // index
3049 VisitForStackValue(args->at(1)); // value 3020 VisitForStackValue(args->at(1)); // value
3050 VisitForAccumulatorValue(args->at(2)); // string 3021 VisitForAccumulatorValue(args->at(2)); // string
3051 3022
3052 __ pop(value); 3023 PopOperand(value);
3053 __ pop(index); 3024 PopOperand(index);
3054 3025
3055 if (FLAG_debug_code) { 3026 if (FLAG_debug_code) {
3056 __ test(value, Immediate(kSmiTagMask)); 3027 __ test(value, Immediate(kSmiTagMask));
3057 __ Check(zero, kNonSmiValue); 3028 __ Check(zero, kNonSmiValue);
3058 __ test(index, Immediate(kSmiTagMask)); 3029 __ test(index, Immediate(kSmiTagMask));
3059 __ Check(zero, kNonSmiValue); 3030 __ Check(zero, kNonSmiValue);
3060 } 3031 }
3061 3032
3062 __ SmiUntag(value); 3033 __ SmiUntag(value);
3063 __ SmiUntag(index); 3034 __ SmiUntag(index);
(...skipping 13 matching lines...) Expand all
3077 ZoneList<Expression*>* args = expr->arguments(); 3048 ZoneList<Expression*>* args = expr->arguments();
3078 DCHECK_EQ(3, args->length()); 3049 DCHECK_EQ(3, args->length());
3079 3050
3080 Register string = eax; 3051 Register string = eax;
3081 Register index = ebx; 3052 Register index = ebx;
3082 Register value = ecx; 3053 Register value = ecx;
3083 3054
3084 VisitForStackValue(args->at(0)); // index 3055 VisitForStackValue(args->at(0)); // index
3085 VisitForStackValue(args->at(1)); // value 3056 VisitForStackValue(args->at(1)); // value
3086 VisitForAccumulatorValue(args->at(2)); // string 3057 VisitForAccumulatorValue(args->at(2)); // string
3087 __ pop(value); 3058 PopOperand(value);
3088 __ pop(index); 3059 PopOperand(index);
3089 3060
3090 if (FLAG_debug_code) { 3061 if (FLAG_debug_code) {
3091 __ test(value, Immediate(kSmiTagMask)); 3062 __ test(value, Immediate(kSmiTagMask));
3092 __ Check(zero, kNonSmiValue); 3063 __ Check(zero, kNonSmiValue);
3093 __ test(index, Immediate(kSmiTagMask)); 3064 __ test(index, Immediate(kSmiTagMask));
3094 __ Check(zero, kNonSmiValue); 3065 __ Check(zero, kNonSmiValue);
3095 __ SmiUntag(index); 3066 __ SmiUntag(index);
3096 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; 3067 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
3097 __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type); 3068 __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type);
3098 __ SmiTag(index); 3069 __ SmiTag(index);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3146 ZoneList<Expression*>* args = expr->arguments(); 3117 ZoneList<Expression*>* args = expr->arguments();
3147 DCHECK(args->length() == 2); 3118 DCHECK(args->length() == 2);
3148 3119
3149 VisitForStackValue(args->at(0)); 3120 VisitForStackValue(args->at(0));
3150 VisitForAccumulatorValue(args->at(1)); 3121 VisitForAccumulatorValue(args->at(1));
3151 3122
3152 Register object = ebx; 3123 Register object = ebx;
3153 Register index = eax; 3124 Register index = eax;
3154 Register result = edx; 3125 Register result = edx;
3155 3126
3156 __ pop(object); 3127 PopOperand(object);
3157 3128
3158 Label need_conversion; 3129 Label need_conversion;
3159 Label index_out_of_range; 3130 Label index_out_of_range;
3160 Label done; 3131 Label done;
3161 StringCharCodeAtGenerator generator(object, 3132 StringCharCodeAtGenerator generator(object,
3162 index, 3133 index,
3163 result, 3134 result,
3164 &need_conversion, 3135 &need_conversion,
3165 &need_conversion, 3136 &need_conversion,
3166 &index_out_of_range, 3137 &index_out_of_range,
(...skipping 26 matching lines...) Expand all
3193 DCHECK(args->length() == 2); 3164 DCHECK(args->length() == 2);
3194 3165
3195 VisitForStackValue(args->at(0)); 3166 VisitForStackValue(args->at(0));
3196 VisitForAccumulatorValue(args->at(1)); 3167 VisitForAccumulatorValue(args->at(1));
3197 3168
3198 Register object = ebx; 3169 Register object = ebx;
3199 Register index = eax; 3170 Register index = eax;
3200 Register scratch = edx; 3171 Register scratch = edx;
3201 Register result = eax; 3172 Register result = eax;
3202 3173
3203 __ pop(object); 3174 PopOperand(object);
3204 3175
3205 Label need_conversion; 3176 Label need_conversion;
3206 Label index_out_of_range; 3177 Label index_out_of_range;
3207 Label done; 3178 Label done;
3208 StringCharAtGenerator generator(object, 3179 StringCharAtGenerator generator(object,
3209 index, 3180 index,
3210 scratch, 3181 scratch,
3211 result, 3182 result,
3212 &need_conversion, 3183 &need_conversion,
3213 &need_conversion, 3184 &need_conversion,
(...skipping 29 matching lines...) Expand all
3243 for (Expression* const arg : *args) { 3214 for (Expression* const arg : *args) {
3244 VisitForStackValue(arg); 3215 VisitForStackValue(arg);
3245 } 3216 }
3246 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3217 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3247 // Move target to edi. 3218 // Move target to edi.
3248 int const argc = args->length() - 2; 3219 int const argc = args->length() - 2;
3249 __ mov(edi, Operand(esp, (argc + 1) * kPointerSize)); 3220 __ mov(edi, Operand(esp, (argc + 1) * kPointerSize));
3250 // Call the target. 3221 // Call the target.
3251 __ mov(eax, Immediate(argc)); 3222 __ mov(eax, Immediate(argc));
3252 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 3223 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
3224 OperandStackDepthDecrement(argc + 1);
3253 // Restore context register. 3225 // Restore context register.
3254 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3226 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3255 // Discard the function left on TOS. 3227 // Discard the function left on TOS.
3256 context()->DropAndPlug(1, eax); 3228 context()->DropAndPlug(1, eax);
3257 } 3229 }
3258 3230
3259 3231
3260 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { 3232 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) {
3261 ZoneList<Expression*>* args = expr->arguments(); 3233 ZoneList<Expression*>* args = expr->arguments();
3262 DCHECK(args->length() == 1); 3234 DCHECK(args->length() == 1);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
3331 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), 3303 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset),
3332 isolate()->factory()->empty_fixed_array()); 3304 isolate()->factory()->empty_fixed_array());
3333 __ mov(FieldOperand(eax, JSObject::kElementsOffset), 3305 __ mov(FieldOperand(eax, JSObject::kElementsOffset),
3334 isolate()->factory()->empty_fixed_array()); 3306 isolate()->factory()->empty_fixed_array());
3335 __ pop(FieldOperand(eax, JSIteratorResult::kDoneOffset)); 3307 __ pop(FieldOperand(eax, JSIteratorResult::kDoneOffset));
3336 __ pop(FieldOperand(eax, JSIteratorResult::kValueOffset)); 3308 __ pop(FieldOperand(eax, JSIteratorResult::kValueOffset));
3337 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); 3309 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize);
3338 __ jmp(&done, Label::kNear); 3310 __ jmp(&done, Label::kNear);
3339 3311
3340 __ bind(&runtime); 3312 __ bind(&runtime);
3341 __ CallRuntime(Runtime::kCreateIterResultObject); 3313 CallRuntimeWithOperands(Runtime::kCreateIterResultObject);
3342 3314
3343 __ bind(&done); 3315 __ bind(&done);
3344 context()->Plug(eax); 3316 context()->Plug(eax);
3345 } 3317 }
3346 3318
3347 3319
3348 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { 3320 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
3349 // Push undefined as receiver. 3321 // Push undefined as receiver.
3350 __ push(Immediate(isolate()->factory()->undefined_value())); 3322 PushOperand(isolate()->factory()->undefined_value());
3351 3323
3352 __ LoadGlobalFunction(expr->context_index(), eax); 3324 __ LoadGlobalFunction(expr->context_index(), eax);
3353 } 3325 }
3354 3326
3355 3327
3356 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { 3328 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
3357 ZoneList<Expression*>* args = expr->arguments(); 3329 ZoneList<Expression*>* args = expr->arguments();
3358 int arg_count = args->length(); 3330 int arg_count = args->length();
3359 3331
3360 SetCallPosition(expr); 3332 SetCallPosition(expr);
3361 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 3333 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
3362 __ Set(eax, arg_count); 3334 __ Set(eax, arg_count);
3363 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), 3335 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined),
3364 RelocInfo::CODE_TARGET); 3336 RelocInfo::CODE_TARGET);
3337 OperandStackDepthDecrement(arg_count + 1);
3365 } 3338 }
3366 3339
3367 3340
3368 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 3341 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
3369 ZoneList<Expression*>* args = expr->arguments(); 3342 ZoneList<Expression*>* args = expr->arguments();
3370 int arg_count = args->length(); 3343 int arg_count = args->length();
3371 3344
3372 if (expr->is_jsruntime()) { 3345 if (expr->is_jsruntime()) {
3373 Comment cmnt(masm_, "[ CallRuntime"); 3346 Comment cmnt(masm_, "[ CallRuntime");
3374 EmitLoadJSRuntimeFunction(expr); 3347 EmitLoadJSRuntimeFunction(expr);
3375 3348
3376 // Push the target function under the receiver. 3349 // Push the target function under the receiver.
3377 __ push(Operand(esp, 0)); 3350 PushOperand(Operand(esp, 0));
3378 __ mov(Operand(esp, kPointerSize), eax); 3351 __ mov(Operand(esp, kPointerSize), eax);
3379 3352
3380 // Push the arguments ("left-to-right"). 3353 // Push the arguments ("left-to-right").
3381 for (int i = 0; i < arg_count; i++) { 3354 for (int i = 0; i < arg_count; i++) {
3382 VisitForStackValue(args->at(i)); 3355 VisitForStackValue(args->at(i));
3383 } 3356 }
3384 3357
3385 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3358 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3386 EmitCallJSRuntimeFunction(expr); 3359 EmitCallJSRuntimeFunction(expr);
3387 3360
(...skipping 14 matching lines...) Expand all
3402 default: { 3375 default: {
3403 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic"); 3376 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic");
3404 // Push the arguments ("left-to-right"). 3377 // Push the arguments ("left-to-right").
3405 for (int i = 0; i < arg_count; i++) { 3378 for (int i = 0; i < arg_count; i++) {
3406 VisitForStackValue(args->at(i)); 3379 VisitForStackValue(args->at(i));
3407 } 3380 }
3408 3381
3409 // Call the C runtime function. 3382 // Call the C runtime function.
3410 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3383 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3411 __ CallRuntime(expr->function(), arg_count); 3384 __ CallRuntime(expr->function(), arg_count);
3385 OperandStackDepthDecrement(arg_count);
3412 context()->Plug(eax); 3386 context()->Plug(eax);
3413 } 3387 }
3414 } 3388 }
3415 } 3389 }
3416 } 3390 }
3417 3391
3418 3392
3419 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3393 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
3420 switch (expr->op()) { 3394 switch (expr->op()) {
3421 case Token::DELETE: { 3395 case Token::DELETE: {
3422 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3396 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3423 Property* property = expr->expression()->AsProperty(); 3397 Property* property = expr->expression()->AsProperty();
3424 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 3398 VariableProxy* proxy = expr->expression()->AsVariableProxy();
3425 3399
3426 if (property != NULL) { 3400 if (property != NULL) {
3427 VisitForStackValue(property->obj()); 3401 VisitForStackValue(property->obj());
3428 VisitForStackValue(property->key()); 3402 VisitForStackValue(property->key());
3429 __ CallRuntime(is_strict(language_mode()) 3403 CallRuntimeWithOperands(is_strict(language_mode())
3430 ? Runtime::kDeleteProperty_Strict 3404 ? Runtime::kDeleteProperty_Strict
3431 : Runtime::kDeleteProperty_Sloppy); 3405 : Runtime::kDeleteProperty_Sloppy);
3432 context()->Plug(eax); 3406 context()->Plug(eax);
3433 } else if (proxy != NULL) { 3407 } else if (proxy != NULL) {
3434 Variable* var = proxy->var(); 3408 Variable* var = proxy->var();
3435 // Delete of an unqualified identifier is disallowed in strict mode but 3409 // Delete of an unqualified identifier is disallowed in strict mode but
3436 // "delete this" is allowed. 3410 // "delete this" is allowed.
3437 bool is_this = var->HasThisName(isolate()); 3411 bool is_this = var->HasThisName(isolate());
3438 DCHECK(is_sloppy(language_mode()) || is_this); 3412 DCHECK(is_sloppy(language_mode()) || is_this);
3439 if (var->IsUnallocatedOrGlobalSlot()) { 3413 if (var->IsUnallocatedOrGlobalSlot()) {
3440 __ mov(eax, NativeContextOperand()); 3414 __ mov(eax, NativeContextOperand());
3441 __ push(ContextOperand(eax, Context::EXTENSION_INDEX)); 3415 __ push(ContextOperand(eax, Context::EXTENSION_INDEX));
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
3488 // We handle value contexts explicitly rather than simply visiting 3462 // We handle value contexts explicitly rather than simply visiting
3489 // for control and plugging the control flow into the context, 3463 // for control and plugging the control flow into the context,
3490 // because we need to prepare a pair of extra administrative AST ids 3464 // because we need to prepare a pair of extra administrative AST ids
3491 // for the optimizing compiler. 3465 // for the optimizing compiler.
3492 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); 3466 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue());
3493 Label materialize_true, materialize_false, done; 3467 Label materialize_true, materialize_false, done;
3494 VisitForControl(expr->expression(), 3468 VisitForControl(expr->expression(),
3495 &materialize_false, 3469 &materialize_false,
3496 &materialize_true, 3470 &materialize_true,
3497 &materialize_true); 3471 &materialize_true);
3472 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1);
3498 __ bind(&materialize_true); 3473 __ bind(&materialize_true);
3499 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); 3474 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS);
3500 if (context()->IsAccumulatorValue()) { 3475 if (context()->IsAccumulatorValue()) {
3501 __ mov(eax, isolate()->factory()->true_value()); 3476 __ mov(eax, isolate()->factory()->true_value());
3502 } else { 3477 } else {
3503 __ Push(isolate()->factory()->true_value()); 3478 __ Push(isolate()->factory()->true_value());
3504 } 3479 }
3505 __ jmp(&done, Label::kNear); 3480 __ jmp(&done, Label::kNear);
3506 __ bind(&materialize_false); 3481 __ bind(&materialize_false);
3507 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); 3482 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3543 LhsKind assign_type = Property::GetAssignType(prop); 3518 LhsKind assign_type = Property::GetAssignType(prop);
3544 3519
3545 // Evaluate expression and get value. 3520 // Evaluate expression and get value.
3546 if (assign_type == VARIABLE) { 3521 if (assign_type == VARIABLE) {
3547 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); 3522 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL);
3548 AccumulatorValueContext context(this); 3523 AccumulatorValueContext context(this);
3549 EmitVariableLoad(expr->expression()->AsVariableProxy()); 3524 EmitVariableLoad(expr->expression()->AsVariableProxy());
3550 } else { 3525 } else {
3551 // Reserve space for result of postfix operation. 3526 // Reserve space for result of postfix operation.
3552 if (expr->is_postfix() && !context()->IsEffect()) { 3527 if (expr->is_postfix() && !context()->IsEffect()) {
3553 __ push(Immediate(Smi::FromInt(0))); 3528 PushOperand(Smi::FromInt(0));
3554 } 3529 }
3555 switch (assign_type) { 3530 switch (assign_type) {
3556 case NAMED_PROPERTY: { 3531 case NAMED_PROPERTY: {
3557 // Put the object both on the stack and in the register. 3532 // Put the object both on the stack and in the register.
3558 VisitForStackValue(prop->obj()); 3533 VisitForStackValue(prop->obj());
3559 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); 3534 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
3560 EmitNamedPropertyLoad(prop); 3535 EmitNamedPropertyLoad(prop);
3561 break; 3536 break;
3562 } 3537 }
3563 3538
3564 case NAMED_SUPER_PROPERTY: { 3539 case NAMED_SUPER_PROPERTY: {
3565 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 3540 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
3566 VisitForAccumulatorValue( 3541 VisitForAccumulatorValue(
3567 prop->obj()->AsSuperPropertyReference()->home_object()); 3542 prop->obj()->AsSuperPropertyReference()->home_object());
3568 __ push(result_register()); 3543 PushOperand(result_register());
3569 __ push(MemOperand(esp, kPointerSize)); 3544 PushOperand(MemOperand(esp, kPointerSize));
3570 __ push(result_register()); 3545 PushOperand(result_register());
3571 EmitNamedSuperPropertyLoad(prop); 3546 EmitNamedSuperPropertyLoad(prop);
3572 break; 3547 break;
3573 } 3548 }
3574 3549
3575 case KEYED_SUPER_PROPERTY: { 3550 case KEYED_SUPER_PROPERTY: {
3576 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 3551 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
3577 VisitForStackValue( 3552 VisitForStackValue(
3578 prop->obj()->AsSuperPropertyReference()->home_object()); 3553 prop->obj()->AsSuperPropertyReference()->home_object());
3579 VisitForAccumulatorValue(prop->key()); 3554 VisitForAccumulatorValue(prop->key());
3580 __ push(result_register()); 3555 PushOperand(result_register());
3581 __ push(MemOperand(esp, 2 * kPointerSize)); 3556 PushOperand(MemOperand(esp, 2 * kPointerSize));
3582 __ push(MemOperand(esp, 2 * kPointerSize)); 3557 PushOperand(MemOperand(esp, 2 * kPointerSize));
3583 __ push(result_register()); 3558 PushOperand(result_register());
3584 EmitKeyedSuperPropertyLoad(prop); 3559 EmitKeyedSuperPropertyLoad(prop);
3585 break; 3560 break;
3586 } 3561 }
3587 3562
3588 case KEYED_PROPERTY: { 3563 case KEYED_PROPERTY: {
3589 VisitForStackValue(prop->obj()); 3564 VisitForStackValue(prop->obj());
3590 VisitForStackValue(prop->key()); 3565 VisitForStackValue(prop->key());
3591 __ mov(LoadDescriptor::ReceiverRegister(), 3566 __ mov(LoadDescriptor::ReceiverRegister(),
3592 Operand(esp, kPointerSize)); // Object. 3567 Operand(esp, kPointerSize)); // Object.
3593 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); // Key. 3568 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); // Key.
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
3663 } 3638 }
3664 3639
3665 // Save result for postfix expressions. 3640 // Save result for postfix expressions.
3666 if (expr->is_postfix()) { 3641 if (expr->is_postfix()) {
3667 if (!context()->IsEffect()) { 3642 if (!context()->IsEffect()) {
3668 // Save the result on the stack. If we have a named or keyed property 3643 // Save the result on the stack. If we have a named or keyed property
3669 // we store the result under the receiver that is currently on top 3644 // we store the result under the receiver that is currently on top
3670 // of the stack. 3645 // of the stack.
3671 switch (assign_type) { 3646 switch (assign_type) {
3672 case VARIABLE: 3647 case VARIABLE:
3673 __ push(eax); 3648 PushOperand(eax);
3674 break; 3649 break;
3675 case NAMED_PROPERTY: 3650 case NAMED_PROPERTY:
3676 __ mov(Operand(esp, kPointerSize), eax); 3651 __ mov(Operand(esp, kPointerSize), eax);
3677 break; 3652 break;
3678 case NAMED_SUPER_PROPERTY: 3653 case NAMED_SUPER_PROPERTY:
3679 __ mov(Operand(esp, 2 * kPointerSize), eax); 3654 __ mov(Operand(esp, 2 * kPointerSize), eax);
3680 break; 3655 break;
3681 case KEYED_PROPERTY: 3656 case KEYED_PROPERTY:
3682 __ mov(Operand(esp, 2 * kPointerSize), eax); 3657 __ mov(Operand(esp, 2 * kPointerSize), eax);
3683 break; 3658 break;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
3723 // Perform the assignment as if via '='. 3698 // Perform the assignment as if via '='.
3724 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3699 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3725 Token::ASSIGN, expr->CountSlot()); 3700 Token::ASSIGN, expr->CountSlot());
3726 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3701 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3727 context()->Plug(eax); 3702 context()->Plug(eax);
3728 } 3703 }
3729 break; 3704 break;
3730 case NAMED_PROPERTY: { 3705 case NAMED_PROPERTY: {
3731 __ mov(StoreDescriptor::NameRegister(), 3706 __ mov(StoreDescriptor::NameRegister(),
3732 prop->key()->AsLiteral()->value()); 3707 prop->key()->AsLiteral()->value());
3733 __ pop(StoreDescriptor::ReceiverRegister()); 3708 PopOperand(StoreDescriptor::ReceiverRegister());
3734 EmitLoadStoreICSlot(expr->CountSlot()); 3709 EmitLoadStoreICSlot(expr->CountSlot());
3735 CallStoreIC(); 3710 CallStoreIC();
3736 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3711 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3737 if (expr->is_postfix()) { 3712 if (expr->is_postfix()) {
3738 if (!context()->IsEffect()) { 3713 if (!context()->IsEffect()) {
3739 context()->PlugTOS(); 3714 context()->PlugTOS();
3740 } 3715 }
3741 } else { 3716 } else {
3742 context()->Plug(eax); 3717 context()->Plug(eax);
3743 } 3718 }
(...skipping 15 matching lines...) Expand all
3759 if (expr->is_postfix()) { 3734 if (expr->is_postfix()) {
3760 if (!context()->IsEffect()) { 3735 if (!context()->IsEffect()) {
3761 context()->PlugTOS(); 3736 context()->PlugTOS();
3762 } 3737 }
3763 } else { 3738 } else {
3764 context()->Plug(eax); 3739 context()->Plug(eax);
3765 } 3740 }
3766 break; 3741 break;
3767 } 3742 }
3768 case KEYED_PROPERTY: { 3743 case KEYED_PROPERTY: {
3769 __ pop(StoreDescriptor::NameRegister()); 3744 PopOperand(StoreDescriptor::NameRegister());
3770 __ pop(StoreDescriptor::ReceiverRegister()); 3745 PopOperand(StoreDescriptor::ReceiverRegister());
3771 Handle<Code> ic = 3746 Handle<Code> ic =
3772 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 3747 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
3773 EmitLoadStoreICSlot(expr->CountSlot()); 3748 EmitLoadStoreICSlot(expr->CountSlot());
3774 CallIC(ic); 3749 CallIC(ic);
3775 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3750 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3776 if (expr->is_postfix()) { 3751 if (expr->is_postfix()) {
3777 // Result is on the stack 3752 // Result is on the stack
3778 if (!context()->IsEffect()) { 3753 if (!context()->IsEffect()) {
3779 context()->PlugTOS(); 3754 context()->PlugTOS();
3780 } 3755 }
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
3881 Label* if_false = NULL; 3856 Label* if_false = NULL;
3882 Label* fall_through = NULL; 3857 Label* fall_through = NULL;
3883 context()->PrepareTest(&materialize_true, &materialize_false, 3858 context()->PrepareTest(&materialize_true, &materialize_false,
3884 &if_true, &if_false, &fall_through); 3859 &if_true, &if_false, &fall_through);
3885 3860
3886 Token::Value op = expr->op(); 3861 Token::Value op = expr->op();
3887 VisitForStackValue(expr->left()); 3862 VisitForStackValue(expr->left());
3888 switch (op) { 3863 switch (op) {
3889 case Token::IN: 3864 case Token::IN:
3890 VisitForStackValue(expr->right()); 3865 VisitForStackValue(expr->right());
3891 __ CallRuntime(Runtime::kHasProperty); 3866 CallRuntimeWithOperands(Runtime::kHasProperty);
3892 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 3867 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
3893 __ cmp(eax, isolate()->factory()->true_value()); 3868 __ cmp(eax, isolate()->factory()->true_value());
3894 Split(equal, if_true, if_false, fall_through); 3869 Split(equal, if_true, if_false, fall_through);
3895 break; 3870 break;
3896 3871
3897 case Token::INSTANCEOF: { 3872 case Token::INSTANCEOF: {
3898 VisitForAccumulatorValue(expr->right()); 3873 VisitForAccumulatorValue(expr->right());
3899 __ Pop(edx); 3874 PopOperand(edx);
3900 InstanceOfStub stub(isolate()); 3875 InstanceOfStub stub(isolate());
3901 __ CallStub(&stub); 3876 __ CallStub(&stub);
3902 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 3877 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
3903 __ cmp(eax, isolate()->factory()->true_value()); 3878 __ cmp(eax, isolate()->factory()->true_value());
3904 Split(equal, if_true, if_false, fall_through); 3879 Split(equal, if_true, if_false, fall_through);
3905 break; 3880 break;
3906 } 3881 }
3907 3882
3908 default: { 3883 default: {
3909 VisitForAccumulatorValue(expr->right()); 3884 VisitForAccumulatorValue(expr->right());
3910 Condition cc = CompareIC::ComputeCondition(op); 3885 Condition cc = CompareIC::ComputeCondition(op);
3911 __ pop(edx); 3886 PopOperand(edx);
3912 3887
3913 bool inline_smi_code = ShouldInlineSmiCase(op); 3888 bool inline_smi_code = ShouldInlineSmiCase(op);
3914 JumpPatchSite patch_site(masm_); 3889 JumpPatchSite patch_site(masm_);
3915 if (inline_smi_code) { 3890 if (inline_smi_code) {
3916 Label slow_case; 3891 Label slow_case;
3917 __ mov(ecx, edx); 3892 __ mov(ecx, edx);
3918 __ or_(ecx, eax); 3893 __ or_(ecx, eax);
3919 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); 3894 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear);
3920 __ cmp(edx, eax); 3895 __ cmp(edx, eax);
3921 Split(cc, if_true, if_false, NULL); 3896 Split(cc, if_true, if_false, NULL);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
3995 3970
3996 3971
3997 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() { 3972 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
3998 Scope* closure_scope = scope()->ClosureScope(); 3973 Scope* closure_scope = scope()->ClosureScope();
3999 if (closure_scope->is_script_scope() || 3974 if (closure_scope->is_script_scope() ||
4000 closure_scope->is_module_scope()) { 3975 closure_scope->is_module_scope()) {
4001 // Contexts nested in the native context have a canonical empty function 3976 // Contexts nested in the native context have a canonical empty function
4002 // as their closure, not the anonymous closure containing the global 3977 // as their closure, not the anonymous closure containing the global
4003 // code. 3978 // code.
4004 __ mov(eax, NativeContextOperand()); 3979 __ mov(eax, NativeContextOperand());
4005 __ push(ContextOperand(eax, Context::CLOSURE_INDEX)); 3980 PushOperand(ContextOperand(eax, Context::CLOSURE_INDEX));
4006 } else if (closure_scope->is_eval_scope()) { 3981 } else if (closure_scope->is_eval_scope()) {
4007 // Contexts nested inside eval code have the same closure as the context 3982 // Contexts nested inside eval code have the same closure as the context
4008 // calling eval, not the anonymous closure containing the eval code. 3983 // calling eval, not the anonymous closure containing the eval code.
4009 // Fetch it from the context. 3984 // Fetch it from the context.
4010 __ push(ContextOperand(esi, Context::CLOSURE_INDEX)); 3985 PushOperand(ContextOperand(esi, Context::CLOSURE_INDEX));
4011 } else { 3986 } else {
4012 DCHECK(closure_scope->is_function_scope()); 3987 DCHECK(closure_scope->is_function_scope());
4013 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 3988 PushOperand(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
4014 } 3989 }
4015 } 3990 }
4016 3991
4017 3992
4018 // ---------------------------------------------------------------------------- 3993 // ----------------------------------------------------------------------------
4019 // Non-local control flow support. 3994 // Non-local control flow support.
4020 3995
4021 void FullCodeGenerator::EnterFinallyBlock() { 3996 void FullCodeGenerator::EnterFinallyBlock() {
4022 // Store pending message while executing finally block. 3997 // Store pending message while executing finally block.
4023 ExternalReference pending_message_obj = 3998 ExternalReference pending_message_obj =
4024 ExternalReference::address_of_pending_message_obj(isolate()); 3999 ExternalReference::address_of_pending_message_obj(isolate());
4025 __ mov(edx, Operand::StaticVariable(pending_message_obj)); 4000 __ mov(edx, Operand::StaticVariable(pending_message_obj));
4026 __ push(edx); 4001 PushOperand(edx);
4027 4002
4028 ClearPendingMessage(); 4003 ClearPendingMessage();
4029 } 4004 }
4030 4005
4031 4006
4032 void FullCodeGenerator::ExitFinallyBlock() { 4007 void FullCodeGenerator::ExitFinallyBlock() {
4033 DCHECK(!result_register().is(edx)); 4008 DCHECK(!result_register().is(edx));
4034 // Restore pending message from stack. 4009 // Restore pending message from stack.
4035 __ pop(edx); 4010 PopOperand(edx);
4036 ExternalReference pending_message_obj = 4011 ExternalReference pending_message_obj =
4037 ExternalReference::address_of_pending_message_obj(isolate()); 4012 ExternalReference::address_of_pending_message_obj(isolate());
4038 __ mov(Operand::StaticVariable(pending_message_obj), edx); 4013 __ mov(Operand::StaticVariable(pending_message_obj), edx);
4039 } 4014 }
4040 4015
4041 4016
4042 void FullCodeGenerator::ClearPendingMessage() { 4017 void FullCodeGenerator::ClearPendingMessage() {
4043 DCHECK(!result_register().is(edx)); 4018 DCHECK(!result_register().is(edx));
4044 ExternalReference pending_message_obj = 4019 ExternalReference pending_message_obj =
4045 ExternalReference::address_of_pending_message_obj(isolate()); 4020 ExternalReference::address_of_pending_message_obj(isolate());
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
4158 Assembler::target_address_at(call_target_address, 4133 Assembler::target_address_at(call_target_address,
4159 unoptimized_code)); 4134 unoptimized_code));
4160 return OSR_AFTER_STACK_CHECK; 4135 return OSR_AFTER_STACK_CHECK;
4161 } 4136 }
4162 4137
4163 4138
4164 } // namespace internal 4139 } // namespace internal
4165 } // namespace v8 4140 } // namespace v8
4166 4141
4167 #endif // V8_TARGET_ARCH_IA32 4142 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/full-codegen/full-codegen.cc ('k') | src/full-codegen/mips/full-codegen-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698