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

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: 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
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 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 __ leave(); 422 __ leave();
422 423
423 int arg_count = info_->scope()->num_parameters() + 1; 424 int arg_count = info_->scope()->num_parameters() + 1;
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 {
432 codegen()->OperandStackDepthIncrement(1);
431 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 433 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
432 MemOperand operand = codegen()->VarOperand(var, result_register()); 434 MemOperand operand = codegen()->VarOperand(var, result_register());
433 // Memory operands can be pushed directly. 435 // Memory operands can be pushed directly.
434 __ push(operand); 436 __ push(operand);
435 } 437 }
436 438
437 439
438 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { 440 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const {
439 UNREACHABLE(); // Not used on IA32. 441 UNREACHABLE(); // Not used on IA32.
440 } 442 }
(...skipping 24 matching lines...) Expand all
465 Handle<Object> lit) const { 467 Handle<Object> lit) const {
466 if (lit->IsSmi()) { 468 if (lit->IsSmi()) {
467 __ SafeMove(result_register(), Immediate(lit)); 469 __ SafeMove(result_register(), Immediate(lit));
468 } else { 470 } else {
469 __ Move(result_register(), Immediate(lit)); 471 __ Move(result_register(), Immediate(lit));
470 } 472 }
471 } 473 }
472 474
473 475
474 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { 476 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const {
477 codegen()->OperandStackDepthIncrement(1);
475 if (lit->IsSmi()) { 478 if (lit->IsSmi()) {
476 __ SafePush(Immediate(lit)); 479 __ SafePush(Immediate(lit));
477 } else { 480 } else {
478 __ push(Immediate(lit)); 481 __ push(Immediate(lit));
479 } 482 }
480 } 483 }
481 484
482 485
483 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { 486 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
484 codegen()->PrepareForBailoutBeforeSplit(condition(), 487 codegen()->PrepareForBailoutBeforeSplit(condition(),
(...skipping 20 matching lines...) Expand all
505 } else { 508 } else {
506 // For simplicity we always test the accumulator register. 509 // For simplicity we always test the accumulator register.
507 __ mov(result_register(), lit); 510 __ mov(result_register(), lit);
508 codegen()->DoTest(this); 511 codegen()->DoTest(this);
509 } 512 }
510 } 513 }
511 514
512 515
513 void FullCodeGenerator::EffectContext::DropAndPlug(int count, 516 void FullCodeGenerator::EffectContext::DropAndPlug(int count,
514 Register reg) const { 517 Register reg) const {
518 codegen()->OperandStackDepthDecrement(count);
515 DCHECK(count > 0); 519 DCHECK(count > 0);
516 __ Drop(count); 520 __ Drop(count);
517 } 521 }
518 522
519 523
520 void FullCodeGenerator::AccumulatorValueContext::DropAndPlug( 524 void FullCodeGenerator::AccumulatorValueContext::DropAndPlug(
521 int count, 525 int count,
522 Register reg) const { 526 Register reg) const {
527 codegen()->OperandStackDepthDecrement(count);
523 DCHECK(count > 0); 528 DCHECK(count > 0);
524 __ Drop(count); 529 __ Drop(count);
525 __ Move(result_register(), reg); 530 __ Move(result_register(), reg);
526 } 531 }
527 532
528 533
529 void FullCodeGenerator::StackValueContext::DropAndPlug(int count, 534 void FullCodeGenerator::StackValueContext::DropAndPlug(int count,
530 Register reg) const { 535 Register reg) const {
536 codegen()->OperandStackDepthDecrement(count - 1);
531 DCHECK(count > 0); 537 DCHECK(count > 0);
532 if (count > 1) __ Drop(count - 1); 538 if (count > 1) __ Drop(count - 1);
533 __ mov(Operand(esp, 0), reg); 539 __ mov(Operand(esp, 0), reg);
534 } 540 }
535 541
536 542
537 void FullCodeGenerator::TestContext::DropAndPlug(int count, 543 void FullCodeGenerator::TestContext::DropAndPlug(int count,
538 Register reg) const { 544 Register reg) const {
545 codegen()->OperandStackDepthDecrement(count);
539 DCHECK(count > 0); 546 DCHECK(count > 0);
540 // For simplicity we always test the accumulator register. 547 // For simplicity we always test the accumulator register.
541 __ Drop(count); 548 __ Drop(count);
542 __ Move(result_register(), reg); 549 __ Move(result_register(), reg);
543 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); 550 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
544 codegen()->DoTest(this); 551 codegen()->DoTest(this);
545 } 552 }
546 553
547 554
548 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, 555 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true,
(...skipping 12 matching lines...) Expand all
561 __ jmp(&done, Label::kNear); 568 __ jmp(&done, Label::kNear);
562 __ bind(materialize_false); 569 __ bind(materialize_false);
563 __ mov(result_register(), isolate()->factory()->false_value()); 570 __ mov(result_register(), isolate()->factory()->false_value());
564 __ bind(&done); 571 __ bind(&done);
565 } 572 }
566 573
567 574
568 void FullCodeGenerator::StackValueContext::Plug( 575 void FullCodeGenerator::StackValueContext::Plug(
569 Label* materialize_true, 576 Label* materialize_true,
570 Label* materialize_false) const { 577 Label* materialize_false) const {
578 codegen()->OperandStackDepthIncrement(1);
571 Label done; 579 Label done;
572 __ bind(materialize_true); 580 __ bind(materialize_true);
573 __ push(Immediate(isolate()->factory()->true_value())); 581 __ push(Immediate(isolate()->factory()->true_value()));
574 __ jmp(&done, Label::kNear); 582 __ jmp(&done, Label::kNear);
575 __ bind(materialize_false); 583 __ bind(materialize_false);
576 __ push(Immediate(isolate()->factory()->false_value())); 584 __ push(Immediate(isolate()->factory()->false_value()));
577 __ bind(&done); 585 __ bind(&done);
578 } 586 }
579 587
580 588
581 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, 589 void FullCodeGenerator::TestContext::Plug(Label* materialize_true,
582 Label* materialize_false) const { 590 Label* materialize_false) const {
583 DCHECK(materialize_true == true_label_); 591 DCHECK(materialize_true == true_label_);
584 DCHECK(materialize_false == false_label_); 592 DCHECK(materialize_false == false_label_);
585 } 593 }
586 594
587 595
588 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { 596 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const {
589 Handle<Object> value = flag 597 Handle<Object> value = flag
590 ? isolate()->factory()->true_value() 598 ? isolate()->factory()->true_value()
591 : isolate()->factory()->false_value(); 599 : isolate()->factory()->false_value();
592 __ mov(result_register(), value); 600 __ mov(result_register(), value);
593 } 601 }
594 602
595 603
596 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { 604 void FullCodeGenerator::StackValueContext::Plug(bool flag) const {
605 codegen()->OperandStackDepthIncrement(1);
597 Handle<Object> value = flag 606 Handle<Object> value = flag
598 ? isolate()->factory()->true_value() 607 ? isolate()->factory()->true_value()
599 : isolate()->factory()->false_value(); 608 : isolate()->factory()->false_value();
600 __ push(Immediate(value)); 609 __ push(Immediate(value));
601 } 610 }
602 611
603 612
604 void FullCodeGenerator::TestContext::Plug(bool flag) const { 613 void FullCodeGenerator::TestContext::Plug(bool flag) const {
605 codegen()->PrepareForBailoutBeforeSplit(condition(), 614 codegen()->PrepareForBailoutBeforeSplit(condition(),
606 true, 615 true,
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
824 ecx, 833 ecx,
825 kDontSaveFPRegs, 834 kDontSaveFPRegs,
826 EMIT_REMEMBERED_SET, 835 EMIT_REMEMBERED_SET,
827 OMIT_SMI_CHECK); 836 OMIT_SMI_CHECK);
828 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 837 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
829 break; 838 break;
830 } 839 }
831 840
832 case VariableLocation::LOOKUP: { 841 case VariableLocation::LOOKUP: {
833 Comment cmnt(masm_, "[ FunctionDeclaration"); 842 Comment cmnt(masm_, "[ FunctionDeclaration");
834 __ push(Immediate(variable->name())); 843 PushOperand(variable->name());
835 VisitForStackValue(declaration->fun()); 844 VisitForStackValue(declaration->fun());
836 __ push( 845 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
837 Immediate(Smi::FromInt(variable->DeclarationPropertyAttributes()))); 846 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
838 __ CallRuntime(Runtime::kDeclareLookupSlot);
839 break; 847 break;
840 } 848 }
841 } 849 }
842 } 850 }
843 851
844 852
845 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 853 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
846 // Call the runtime to declare the globals. 854 // Call the runtime to declare the globals.
847 __ Push(pairs); 855 __ Push(pairs);
848 __ Push(Smi::FromInt(DeclareGlobalsFlags())); 856 __ Push(Smi::FromInt(DeclareGlobalsFlags()));
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
924 932
925 __ test(eax, eax); 933 __ test(eax, eax);
926 __ j(not_equal, &next_test); 934 __ j(not_equal, &next_test);
927 __ Drop(1); // Switch value is no longer needed. 935 __ Drop(1); // Switch value is no longer needed.
928 __ jmp(clause->body_target()); 936 __ jmp(clause->body_target());
929 } 937 }
930 938
931 // Discard the test value and jump to the default if present, otherwise to 939 // Discard the test value and jump to the default if present, otherwise to
932 // the end of the statement. 940 // the end of the statement.
933 __ bind(&next_test); 941 __ bind(&next_test);
934 __ Drop(1); // Switch value is no longer needed. 942 DropOperands(1); // Switch value is no longer needed.
935 if (default_clause == NULL) { 943 if (default_clause == NULL) {
936 __ jmp(nested_statement.break_label()); 944 __ jmp(nested_statement.break_label());
937 } else { 945 } else {
938 __ jmp(default_clause->body_target()); 946 __ jmp(default_clause->body_target());
939 } 947 }
940 948
941 // Compile all the case bodies. 949 // Compile all the case bodies.
942 for (int i = 0; i < clauses->length(); i++) { 950 for (int i = 0; i < clauses->length(); i++) {
943 Comment cmnt(masm_, "[ Case body"); 951 Comment cmnt(masm_, "[ Case body");
944 CaseClause* clause = clauses->at(i); 952 CaseClause* clause = clauses->at(i);
(...skipping 13 matching lines...) Expand all
958 966
959 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); 967 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
960 968
961 Label loop, exit; 969 Label loop, exit;
962 ForIn loop_statement(this, stmt); 970 ForIn loop_statement(this, stmt);
963 increment_loop_depth(); 971 increment_loop_depth();
964 972
965 // Get the object to enumerate over. 973 // Get the object to enumerate over.
966 SetExpressionAsStatementPosition(stmt->enumerable()); 974 SetExpressionAsStatementPosition(stmt->enumerable());
967 VisitForAccumulatorValue(stmt->enumerable()); 975 VisitForAccumulatorValue(stmt->enumerable());
976 OperandStackDepthIncrement(ForIn::kElementCount);
968 977
969 // If the object is null or undefined, skip over the loop, otherwise convert 978 // 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. 979 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4.
971 Label convert, done_convert; 980 Label convert, done_convert;
972 __ JumpIfSmi(eax, &convert, Label::kNear); 981 __ JumpIfSmi(eax, &convert, Label::kNear);
973 __ CmpObjectType(eax, FIRST_JS_RECEIVER_TYPE, ecx); 982 __ CmpObjectType(eax, FIRST_JS_RECEIVER_TYPE, ecx);
974 __ j(above_equal, &done_convert, Label::kNear); 983 __ j(above_equal, &done_convert, Label::kNear);
975 __ cmp(eax, isolate()->factory()->undefined_value()); 984 __ cmp(eax, isolate()->factory()->undefined_value());
976 __ j(equal, &exit); 985 __ j(equal, &exit);
977 __ cmp(eax, isolate()->factory()->null_value()); 986 __ 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. 1115 // index (smi) stored on top of the stack.
1107 __ bind(loop_statement.continue_label()); 1116 __ bind(loop_statement.continue_label());
1108 __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1))); 1117 __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1)));
1109 1118
1110 EmitBackEdgeBookkeeping(stmt, &loop); 1119 EmitBackEdgeBookkeeping(stmt, &loop);
1111 __ jmp(&loop); 1120 __ jmp(&loop);
1112 1121
1113 // Remove the pointers stored on the stack. 1122 // Remove the pointers stored on the stack.
1114 __ bind(loop_statement.break_label()); 1123 __ bind(loop_statement.break_label());
1115 __ add(esp, Immediate(5 * kPointerSize)); 1124 __ add(esp, Immediate(5 * kPointerSize));
1125 OperandStackDepthDecrement(ForIn::kElementCount);
1116 1126
1117 // Exit and decrement the loop depth. 1127 // Exit and decrement the loop depth.
1118 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1128 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1119 __ bind(&exit); 1129 __ bind(&exit);
1120 decrement_loop_depth(); 1130 decrement_loop_depth();
1121 } 1131 }
1122 1132
1123 1133
1124 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, 1134 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
1125 bool pretenure) { 1135 bool pretenure) {
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
1377 __ Move(edx, Immediate(Smi::FromInt(expr->flags()))); 1387 __ Move(edx, Immediate(Smi::FromInt(expr->flags())));
1378 FastCloneRegExpStub stub(isolate()); 1388 FastCloneRegExpStub stub(isolate());
1379 __ CallStub(&stub); 1389 __ CallStub(&stub);
1380 context()->Plug(eax); 1390 context()->Plug(eax);
1381 } 1391 }
1382 1392
1383 1393
1384 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { 1394 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
1385 Expression* expression = (property == NULL) ? NULL : property->value(); 1395 Expression* expression = (property == NULL) ? NULL : property->value();
1386 if (expression == NULL) { 1396 if (expression == NULL) {
1387 __ push(Immediate(isolate()->factory()->null_value())); 1397 PushOperand(isolate()->factory()->null_value());
1388 } else { 1398 } else {
1389 VisitForStackValue(expression); 1399 VisitForStackValue(expression);
1390 if (NeedsHomeObject(expression)) { 1400 if (NeedsHomeObject(expression)) {
1391 DCHECK(property->kind() == ObjectLiteral::Property::GETTER || 1401 DCHECK(property->kind() == ObjectLiteral::Property::GETTER ||
1392 property->kind() == ObjectLiteral::Property::SETTER); 1402 property->kind() == ObjectLiteral::Property::SETTER);
1393 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3; 1403 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3;
1394 EmitSetHomeObject(expression, offset, property->GetSlot()); 1404 EmitSetHomeObject(expression, offset, property->GetSlot());
1395 } 1405 }
1396 } 1406 }
1397 } 1407 }
(...skipping 29 matching lines...) Expand all
1427 AccessorTable accessor_table(zone()); 1437 AccessorTable accessor_table(zone());
1428 int property_index = 0; 1438 int property_index = 0;
1429 for (; property_index < expr->properties()->length(); property_index++) { 1439 for (; property_index < expr->properties()->length(); property_index++) {
1430 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1440 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1431 if (property->is_computed_name()) break; 1441 if (property->is_computed_name()) break;
1432 if (property->IsCompileTimeValue()) continue; 1442 if (property->IsCompileTimeValue()) continue;
1433 1443
1434 Literal* key = property->key()->AsLiteral(); 1444 Literal* key = property->key()->AsLiteral();
1435 Expression* value = property->value(); 1445 Expression* value = property->value();
1436 if (!result_saved) { 1446 if (!result_saved) {
1437 __ push(eax); // Save result on the stack 1447 PushOperand(eax); // Save result on the stack
1438 result_saved = true; 1448 result_saved = true;
1439 } 1449 }
1440 switch (property->kind()) { 1450 switch (property->kind()) {
1441 case ObjectLiteral::Property::CONSTANT: 1451 case ObjectLiteral::Property::CONSTANT:
1442 UNREACHABLE(); 1452 UNREACHABLE();
1443 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1453 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1444 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); 1454 DCHECK(!CompileTimeValue::IsCompileTimeValue(value));
1445 // Fall through. 1455 // Fall through.
1446 case ObjectLiteral::Property::COMPUTED: 1456 case ObjectLiteral::Property::COMPUTED:
1447 // It is safe to use [[Put]] here because the boilerplate already 1457 // It is safe to use [[Put]] here because the boilerplate already
1448 // contains computed properties with an uninitialized value. 1458 // contains computed properties with an uninitialized value.
1449 if (key->value()->IsInternalizedString()) { 1459 if (key->value()->IsInternalizedString()) {
1450 if (property->emit_store()) { 1460 if (property->emit_store()) {
1451 VisitForAccumulatorValue(value); 1461 VisitForAccumulatorValue(value);
1452 DCHECK(StoreDescriptor::ValueRegister().is(eax)); 1462 DCHECK(StoreDescriptor::ValueRegister().is(eax));
1453 __ mov(StoreDescriptor::NameRegister(), Immediate(key->value())); 1463 __ mov(StoreDescriptor::NameRegister(), Immediate(key->value()));
1454 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); 1464 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0));
1455 EmitLoadStoreICSlot(property->GetSlot(0)); 1465 EmitLoadStoreICSlot(property->GetSlot(0));
1456 CallStoreIC(); 1466 CallStoreIC();
1457 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1467 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1458 if (NeedsHomeObject(value)) { 1468 if (NeedsHomeObject(value)) {
1459 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); 1469 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
1460 } 1470 }
1461 } else { 1471 } else {
1462 VisitForEffect(value); 1472 VisitForEffect(value);
1463 } 1473 }
1464 break; 1474 break;
1465 } 1475 }
1466 __ push(Operand(esp, 0)); // Duplicate receiver. 1476 PushOperand(Operand(esp, 0)); // Duplicate receiver.
1467 VisitForStackValue(key); 1477 VisitForStackValue(key);
1468 VisitForStackValue(value); 1478 VisitForStackValue(value);
1469 if (property->emit_store()) { 1479 if (property->emit_store()) {
1470 if (NeedsHomeObject(value)) { 1480 if (NeedsHomeObject(value)) {
1471 EmitSetHomeObject(value, 2, property->GetSlot()); 1481 EmitSetHomeObject(value, 2, property->GetSlot());
1472 } 1482 }
1473 __ push(Immediate(Smi::FromInt(SLOPPY))); // Language mode 1483 PushOperand(Smi::FromInt(SLOPPY)); // Language mode
1474 __ CallRuntime(Runtime::kSetProperty); 1484 CallRuntimeWithOperands(Runtime::kSetProperty);
1475 } else { 1485 } else {
1476 __ Drop(3); 1486 DropOperands(3);
1477 } 1487 }
1478 break; 1488 break;
1479 case ObjectLiteral::Property::PROTOTYPE: 1489 case ObjectLiteral::Property::PROTOTYPE:
1480 __ push(Operand(esp, 0)); // Duplicate receiver. 1490 PushOperand(Operand(esp, 0)); // Duplicate receiver.
1481 VisitForStackValue(value); 1491 VisitForStackValue(value);
1482 DCHECK(property->emit_store()); 1492 DCHECK(property->emit_store());
1483 __ CallRuntime(Runtime::kInternalSetPrototype); 1493 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1484 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1494 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1485 NO_REGISTERS); 1495 NO_REGISTERS);
1486 break; 1496 break;
1487 case ObjectLiteral::Property::GETTER: 1497 case ObjectLiteral::Property::GETTER:
1488 if (property->emit_store()) { 1498 if (property->emit_store()) {
1489 accessor_table.lookup(key)->second->getter = property; 1499 accessor_table.lookup(key)->second->getter = property;
1490 } 1500 }
1491 break; 1501 break;
1492 case ObjectLiteral::Property::SETTER: 1502 case ObjectLiteral::Property::SETTER:
1493 if (property->emit_store()) { 1503 if (property->emit_store()) {
1494 accessor_table.lookup(key)->second->setter = property; 1504 accessor_table.lookup(key)->second->setter = property;
1495 } 1505 }
1496 break; 1506 break;
1497 } 1507 }
1498 } 1508 }
1499 1509
1500 // Emit code to define accessors, using only a single call to the runtime for 1510 // Emit code to define accessors, using only a single call to the runtime for
1501 // each pair of corresponding getters and setters. 1511 // each pair of corresponding getters and setters.
1502 for (AccessorTable::Iterator it = accessor_table.begin(); 1512 for (AccessorTable::Iterator it = accessor_table.begin();
1503 it != accessor_table.end(); 1513 it != accessor_table.end();
1504 ++it) { 1514 ++it) {
1505 __ push(Operand(esp, 0)); // Duplicate receiver. 1515 PushOperand(Operand(esp, 0)); // Duplicate receiver.
1506 VisitForStackValue(it->first); 1516 VisitForStackValue(it->first);
1507 1517
1508 EmitAccessor(it->second->getter); 1518 EmitAccessor(it->second->getter);
1509 EmitAccessor(it->second->setter); 1519 EmitAccessor(it->second->setter);
1510 1520
1511 __ push(Immediate(Smi::FromInt(NONE))); 1521 PushOperand(Smi::FromInt(NONE));
1512 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked); 1522 CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked);
1513 } 1523 }
1514 1524
1515 // Object literals have two parts. The "static" part on the left contains no 1525 // 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 1526 // computed property names, and so we can compute its map ahead of time; see
1517 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part 1527 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part
1518 // starts with the first computed property name, and continues with all 1528 // starts with the first computed property name, and continues with all
1519 // properties to its right. All the code from above initializes the static 1529 // 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 1530 // 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 1531 // reflect the static order in which the keys appear. For the dynamic
1522 // properties, we compile them into a series of "SetOwnProperty" runtime 1532 // properties, we compile them into a series of "SetOwnProperty" runtime
1523 // calls. This will preserve insertion order. 1533 // calls. This will preserve insertion order.
1524 for (; property_index < expr->properties()->length(); property_index++) { 1534 for (; property_index < expr->properties()->length(); property_index++) {
1525 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1535 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1526 1536
1527 Expression* value = property->value(); 1537 Expression* value = property->value();
1528 if (!result_saved) { 1538 if (!result_saved) {
1529 __ push(eax); // Save result on the stack 1539 PushOperand(eax); // Save result on the stack
1530 result_saved = true; 1540 result_saved = true;
1531 } 1541 }
1532 1542
1533 __ push(Operand(esp, 0)); // Duplicate receiver. 1543 PushOperand(Operand(esp, 0)); // Duplicate receiver.
1534 1544
1535 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1545 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1536 DCHECK(!property->is_computed_name()); 1546 DCHECK(!property->is_computed_name());
1537 VisitForStackValue(value); 1547 VisitForStackValue(value);
1538 DCHECK(property->emit_store()); 1548 DCHECK(property->emit_store());
1539 __ CallRuntime(Runtime::kInternalSetPrototype); 1549 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1540 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1550 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1541 NO_REGISTERS); 1551 NO_REGISTERS);
1542 } else { 1552 } else {
1543 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); 1553 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
1544 VisitForStackValue(value); 1554 VisitForStackValue(value);
1545 if (NeedsHomeObject(value)) { 1555 if (NeedsHomeObject(value)) {
1546 EmitSetHomeObject(value, 2, property->GetSlot()); 1556 EmitSetHomeObject(value, 2, property->GetSlot());
1547 } 1557 }
1548 1558
1549 switch (property->kind()) { 1559 switch (property->kind()) {
1550 case ObjectLiteral::Property::CONSTANT: 1560 case ObjectLiteral::Property::CONSTANT:
1551 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1561 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1552 case ObjectLiteral::Property::COMPUTED: 1562 case ObjectLiteral::Property::COMPUTED:
1553 if (property->emit_store()) { 1563 if (property->emit_store()) {
1554 __ Push(Smi::FromInt(NONE)); 1564 PushOperand(Smi::FromInt(NONE));
1555 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); 1565 PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
1556 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); 1566 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
1557 } else { 1567 } else {
1558 __ Drop(3); 1568 DropOperands(3);
1559 } 1569 }
1560 break; 1570 break;
1561 1571
1562 case ObjectLiteral::Property::PROTOTYPE: 1572 case ObjectLiteral::Property::PROTOTYPE:
1563 UNREACHABLE(); 1573 UNREACHABLE();
1564 break; 1574 break;
1565 1575
1566 case ObjectLiteral::Property::GETTER: 1576 case ObjectLiteral::Property::GETTER:
1567 __ Push(Smi::FromInt(NONE)); 1577 PushOperand(Smi::FromInt(NONE));
1568 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); 1578 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
1569 break; 1579 break;
1570 1580
1571 case ObjectLiteral::Property::SETTER: 1581 case ObjectLiteral::Property::SETTER:
1572 __ Push(Smi::FromInt(NONE)); 1582 PushOperand(Smi::FromInt(NONE));
1573 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); 1583 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
1574 break; 1584 break;
1575 } 1585 }
1576 } 1586 }
1577 } 1587 }
1578 1588
1579 if (expr->has_function()) { 1589 if (expr->has_function()) {
1580 DCHECK(result_saved); 1590 DCHECK(result_saved);
1581 __ push(Operand(esp, 0)); 1591 __ push(Operand(esp, 0));
1582 __ CallRuntime(Runtime::kToFastProperties); 1592 __ CallRuntime(Runtime::kToFastProperties);
1583 } 1593 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1628 int array_index = 0; 1638 int array_index = 0;
1629 for (; array_index < length; array_index++) { 1639 for (; array_index < length; array_index++) {
1630 Expression* subexpr = subexprs->at(array_index); 1640 Expression* subexpr = subexprs->at(array_index);
1631 DCHECK(!subexpr->IsSpread()); 1641 DCHECK(!subexpr->IsSpread());
1632 1642
1633 // If the subexpression is a literal or a simple materialized literal it 1643 // If the subexpression is a literal or a simple materialized literal it
1634 // is already set in the cloned array. 1644 // is already set in the cloned array.
1635 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 1645 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
1636 1646
1637 if (!result_saved) { 1647 if (!result_saved) {
1638 __ push(eax); // array literal. 1648 PushOperand(eax); // array literal.
1639 result_saved = true; 1649 result_saved = true;
1640 } 1650 }
1641 VisitForAccumulatorValue(subexpr); 1651 VisitForAccumulatorValue(subexpr);
1642 1652
1643 __ mov(StoreDescriptor::NameRegister(), 1653 __ mov(StoreDescriptor::NameRegister(),
1644 Immediate(Smi::FromInt(array_index))); 1654 Immediate(Smi::FromInt(array_index)));
1645 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); 1655 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0));
1646 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); 1656 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot());
1647 Handle<Code> ic = 1657 Handle<Code> ic =
1648 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 1658 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
1649 CallIC(ic); 1659 CallIC(ic);
1650 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1660 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1651 } 1661 }
1652 1662
1653 // In case the array literal contains spread expressions it has two parts. The 1663 // 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 1664 // 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 1665 // 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 1666 // (inclusive) and these elements gets appended to the array. Note that the
1657 // number elements an iterable produces is unknown ahead of time. 1667 // number elements an iterable produces is unknown ahead of time.
1658 if (array_index < length && result_saved) { 1668 if (array_index < length && result_saved) {
1659 __ Pop(eax); 1669 PopOperand(eax);
1660 result_saved = false; 1670 result_saved = false;
1661 } 1671 }
1662 for (; array_index < length; array_index++) { 1672 for (; array_index < length; array_index++) {
1663 Expression* subexpr = subexprs->at(array_index); 1673 Expression* subexpr = subexprs->at(array_index);
1664 1674
1665 __ Push(eax); 1675 PushOperand(eax);
1666 DCHECK(!subexpr->IsSpread()); 1676 DCHECK(!subexpr->IsSpread());
1667 VisitForStackValue(subexpr); 1677 VisitForStackValue(subexpr);
1668 __ CallRuntime(Runtime::kAppendElement); 1678 CallRuntimeWithOperands(Runtime::kAppendElement);
1669 1679
1670 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1680 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1671 } 1681 }
1672 1682
1673 if (result_saved) { 1683 if (result_saved) {
1674 context()->PlugTOS(); 1684 context()->PlugTOS();
1675 } else { 1685 } else {
1676 context()->Plug(eax); 1686 context()->Plug(eax);
1677 } 1687 }
1678 } 1688 }
(...skipping 11 matching lines...) Expand all
1690 // Evaluate LHS expression. 1700 // Evaluate LHS expression.
1691 switch (assign_type) { 1701 switch (assign_type) {
1692 case VARIABLE: 1702 case VARIABLE:
1693 // Nothing to do here. 1703 // Nothing to do here.
1694 break; 1704 break;
1695 case NAMED_SUPER_PROPERTY: 1705 case NAMED_SUPER_PROPERTY:
1696 VisitForStackValue( 1706 VisitForStackValue(
1697 property->obj()->AsSuperPropertyReference()->this_var()); 1707 property->obj()->AsSuperPropertyReference()->this_var());
1698 VisitForAccumulatorValue( 1708 VisitForAccumulatorValue(
1699 property->obj()->AsSuperPropertyReference()->home_object()); 1709 property->obj()->AsSuperPropertyReference()->home_object());
1700 __ push(result_register()); 1710 PushOperand(result_register());
1701 if (expr->is_compound()) { 1711 if (expr->is_compound()) {
1702 __ push(MemOperand(esp, kPointerSize)); 1712 PushOperand(MemOperand(esp, kPointerSize));
1703 __ push(result_register()); 1713 PushOperand(result_register());
1704 } 1714 }
1705 break; 1715 break;
1706 case NAMED_PROPERTY: 1716 case NAMED_PROPERTY:
1707 if (expr->is_compound()) { 1717 if (expr->is_compound()) {
1708 // We need the receiver both on the stack and in the register. 1718 // We need the receiver both on the stack and in the register.
1709 VisitForStackValue(property->obj()); 1719 VisitForStackValue(property->obj());
1710 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); 1720 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
1711 } else { 1721 } else {
1712 VisitForStackValue(property->obj()); 1722 VisitForStackValue(property->obj());
1713 } 1723 }
1714 break; 1724 break;
1715 case KEYED_SUPER_PROPERTY: 1725 case KEYED_SUPER_PROPERTY:
1716 VisitForStackValue( 1726 VisitForStackValue(
1717 property->obj()->AsSuperPropertyReference()->this_var()); 1727 property->obj()->AsSuperPropertyReference()->this_var());
1718 VisitForStackValue( 1728 VisitForStackValue(
1719 property->obj()->AsSuperPropertyReference()->home_object()); 1729 property->obj()->AsSuperPropertyReference()->home_object());
1720 VisitForAccumulatorValue(property->key()); 1730 VisitForAccumulatorValue(property->key());
1721 __ Push(result_register()); 1731 PushOperand(result_register());
1722 if (expr->is_compound()) { 1732 if (expr->is_compound()) {
1723 __ push(MemOperand(esp, 2 * kPointerSize)); 1733 PushOperand(MemOperand(esp, 2 * kPointerSize));
1724 __ push(MemOperand(esp, 2 * kPointerSize)); 1734 PushOperand(MemOperand(esp, 2 * kPointerSize));
1725 __ push(result_register()); 1735 PushOperand(result_register());
1726 } 1736 }
1727 break; 1737 break;
1728 case KEYED_PROPERTY: { 1738 case KEYED_PROPERTY: {
1729 if (expr->is_compound()) { 1739 if (expr->is_compound()) {
1730 VisitForStackValue(property->obj()); 1740 VisitForStackValue(property->obj());
1731 VisitForStackValue(property->key()); 1741 VisitForStackValue(property->key());
1732 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, kPointerSize)); 1742 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, kPointerSize));
1733 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); 1743 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0));
1734 } else { 1744 } else {
1735 VisitForStackValue(property->obj()); 1745 VisitForStackValue(property->obj());
(...skipping 26 matching lines...) Expand all
1762 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1772 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1763 break; 1773 break;
1764 case KEYED_PROPERTY: 1774 case KEYED_PROPERTY:
1765 EmitKeyedPropertyLoad(property); 1775 EmitKeyedPropertyLoad(property);
1766 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1776 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1767 break; 1777 break;
1768 } 1778 }
1769 } 1779 }
1770 1780
1771 Token::Value op = expr->binary_op(); 1781 Token::Value op = expr->binary_op();
1772 __ push(eax); // Left operand goes on the stack. 1782 PushOperand(eax); // Left operand goes on the stack.
1773 VisitForAccumulatorValue(expr->value()); 1783 VisitForAccumulatorValue(expr->value());
1774 1784
1775 if (ShouldInlineSmiCase(op)) { 1785 if (ShouldInlineSmiCase(op)) {
1776 EmitInlineSmiBinaryOp(expr->binary_operation(), 1786 EmitInlineSmiBinaryOp(expr->binary_operation(),
1777 op, 1787 op,
1778 expr->target(), 1788 expr->target(),
1779 expr->value()); 1789 expr->value());
1780 } else { 1790 } else {
1781 EmitBinaryOp(expr->binary_operation(), op); 1791 EmitBinaryOp(expr->binary_operation(), op);
1782 } 1792 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1855 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, 1865 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx,
1856 kDontSaveFPRegs); 1866 kDontSaveFPRegs);
1857 __ lea(ebx, Operand(ebp, StandardFrameConstants::kExpressionsOffset)); 1867 __ lea(ebx, Operand(ebp, StandardFrameConstants::kExpressionsOffset));
1858 __ cmp(esp, ebx); 1868 __ cmp(esp, ebx);
1859 __ j(equal, &post_runtime); 1869 __ j(equal, &post_runtime);
1860 __ push(eax); // generator object 1870 __ push(eax); // generator object
1861 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 1871 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
1862 __ mov(context_register(), 1872 __ mov(context_register(),
1863 Operand(ebp, StandardFrameConstants::kContextOffset)); 1873 Operand(ebp, StandardFrameConstants::kContextOffset));
1864 __ bind(&post_runtime); 1874 __ bind(&post_runtime);
1865 __ pop(result_register()); 1875 PopOperand(result_register());
1866 EmitReturnSequence(); 1876 EmitReturnSequence();
1867 1877
1868 __ bind(&resume); 1878 __ bind(&resume);
1869 context()->Plug(result_register()); 1879 context()->Plug(result_register());
1870 break; 1880 break;
1871 } 1881 }
1872 1882
1873 case Yield::kFinal: { 1883 case Yield::kFinal: {
1874 // Pop value from top-of-stack slot, box result into result register. 1884 // Pop value from top-of-stack slot, box result into result register.
1885 OperandStackDepthDecrement(1);
1875 EmitCreateIteratorResult(true); 1886 EmitCreateIteratorResult(true);
1876 EmitUnwindAndReturn(); 1887 EmitUnwindAndReturn();
1877 break; 1888 break;
1878 } 1889 }
1879 1890
1880 case Yield::kDelegating: 1891 case Yield::kDelegating:
1881 UNREACHABLE(); 1892 UNREACHABLE();
1882 } 1893 }
1883 } 1894 }
1884 1895
1885 1896
1886 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, 1897 void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
1887 Expression *value, 1898 Expression *value,
1888 JSGeneratorObject::ResumeMode resume_mode) { 1899 JSGeneratorObject::ResumeMode resume_mode) {
1889 // The value stays in eax, and is ultimately read by the resumed generator, as 1900 // The value stays in eax, and is ultimately read by the resumed generator, as
1890 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it 1901 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it
1891 // is read to throw the value when the resumed generator is already closed. 1902 // 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. 1903 // ebx will hold the generator object until the activation has been resumed.
1893 VisitForStackValue(generator); 1904 VisitForStackValue(generator);
1894 VisitForAccumulatorValue(value); 1905 VisitForAccumulatorValue(value);
1895 __ pop(ebx); 1906 PopOperand(ebx);
1896 1907
1897 // Store input value into generator object. 1908 // Store input value into generator object.
1898 __ mov(FieldOperand(ebx, JSGeneratorObject::kInputOffset), result_register()); 1909 __ mov(FieldOperand(ebx, JSGeneratorObject::kInputOffset), result_register());
1899 __ mov(ecx, result_register()); 1910 __ mov(ecx, result_register());
1900 __ RecordWriteField(ebx, JSGeneratorObject::kInputOffset, ecx, edx, 1911 __ RecordWriteField(ebx, JSGeneratorObject::kInputOffset, ecx, edx,
1901 kDontSaveFPRegs); 1912 kDontSaveFPRegs);
1902 1913
1903 // Load suspended function and context. 1914 // Load suspended function and context.
1904 __ mov(esi, FieldOperand(ebx, JSGeneratorObject::kContextOffset)); 1915 __ mov(esi, FieldOperand(ebx, JSGeneratorObject::kContextOffset));
1905 __ mov(edi, FieldOperand(ebx, JSGeneratorObject::kFunctionOffset)); 1916 __ mov(edi, FieldOperand(ebx, JSGeneratorObject::kFunctionOffset));
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1967 __ push(result_register()); 1978 __ push(result_register());
1968 __ Push(Smi::FromInt(resume_mode)); 1979 __ Push(Smi::FromInt(resume_mode));
1969 __ CallRuntime(Runtime::kResumeJSGeneratorObject); 1980 __ CallRuntime(Runtime::kResumeJSGeneratorObject);
1970 // Not reached: the runtime call returns elsewhere. 1981 // Not reached: the runtime call returns elsewhere.
1971 __ Abort(kGeneratorFailedToResume); 1982 __ Abort(kGeneratorFailedToResume);
1972 1983
1973 __ bind(&done); 1984 __ bind(&done);
1974 context()->Plug(result_register()); 1985 context()->Plug(result_register());
1975 } 1986 }
1976 1987
1988 void FullCodeGenerator::EmitOperandStackDepthCheck() {
1989 if (generate_debug_code_) {
1990 Vector<char> buf = Vector<char>::New(50);
1991 SNPrintF(buf, " > depth=%d", operand_stack_depth_);
1992 Comment cmnt(masm(), buf.start());
1993 int expected_diff = StandardFrameConstants::kFixedFrameSizeFromFp +
1994 operand_stack_depth_ * kPointerSize;
1995 __ mov(eax, ebp);
1996 __ sub(eax, esp);
1997 __ cmp(eax, Immediate(expected_diff));
1998 __ Assert(equal, kUnexpectedStackDepth);
Jarin 2016/02/19 06:52:04 Hmm, just wondering: is it ok to clobber eax here?
Michael Starzinger 2016/02/19 09:24:04 Acknowledged. As discussed offline: We are current
1999 }
2000 }
1977 2001
1978 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { 2002 void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
1979 Label allocate, done_allocate; 2003 Label allocate, done_allocate;
1980 2004
1981 __ Allocate(JSIteratorResult::kSize, eax, ecx, edx, &allocate, TAG_OBJECT); 2005 __ Allocate(JSIteratorResult::kSize, eax, ecx, edx, &allocate, TAG_OBJECT);
1982 __ jmp(&done_allocate, Label::kNear); 2006 __ jmp(&done_allocate, Label::kNear);
1983 2007
1984 __ bind(&allocate); 2008 __ bind(&allocate);
1985 __ Push(Smi::FromInt(JSIteratorResult::kSize)); 2009 __ Push(Smi::FromInt(JSIteratorResult::kSize));
1986 __ CallRuntime(Runtime::kAllocateInNewSpace); 2010 __ CallRuntime(Runtime::kAllocateInNewSpace);
(...skipping 26 matching lines...) Expand all
2013 } 2037 }
2014 2038
2015 2039
2016 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { 2040 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
2017 // Stack: receiver, home_object. 2041 // Stack: receiver, home_object.
2018 SetExpressionPosition(prop); 2042 SetExpressionPosition(prop);
2019 Literal* key = prop->key()->AsLiteral(); 2043 Literal* key = prop->key()->AsLiteral();
2020 DCHECK(!key->value()->IsSmi()); 2044 DCHECK(!key->value()->IsSmi());
2021 DCHECK(prop->IsSuperAccess()); 2045 DCHECK(prop->IsSuperAccess());
2022 2046
2023 __ push(Immediate(key->value())); 2047 PushOperand(key->value());
2024 __ CallRuntime(Runtime::kLoadFromSuper); 2048 CallRuntimeWithOperands(Runtime::kLoadFromSuper);
2025 } 2049 }
2026 2050
2027 2051
2028 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 2052 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2029 SetExpressionPosition(prop); 2053 SetExpressionPosition(prop);
2030 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); 2054 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
2031 __ mov(LoadDescriptor::SlotRegister(), 2055 __ mov(LoadDescriptor::SlotRegister(),
2032 Immediate(SmiFromSlot(prop->PropertyFeedbackSlot()))); 2056 Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
2033 CallIC(ic); 2057 CallIC(ic);
2034 } 2058 }
2035 2059
2036 2060
2037 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { 2061 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
2038 // Stack: receiver, home_object, key. 2062 // Stack: receiver, home_object, key.
2039 SetExpressionPosition(prop); 2063 SetExpressionPosition(prop);
2040 __ CallRuntime(Runtime::kLoadKeyedFromSuper); 2064 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper);
2041 } 2065 }
2042 2066
2043 2067
2044 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 2068 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
2045 Token::Value op, 2069 Token::Value op,
2046 Expression* left, 2070 Expression* left,
2047 Expression* right) { 2071 Expression* right) {
2048 // Do combined smi check of the operands. Left operand is on the 2072 // Do combined smi check of the operands. Left operand is on the
2049 // stack. Right operand is in eax. 2073 // stack. Right operand is in eax.
2050 Label smi_case, done, stub_call; 2074 Label smi_case, done, stub_call;
2051 __ pop(edx); 2075 PopOperand(edx);
2052 __ mov(ecx, eax); 2076 __ mov(ecx, eax);
2053 __ or_(eax, edx); 2077 __ or_(eax, edx);
2054 JumpPatchSite patch_site(masm_); 2078 JumpPatchSite patch_site(masm_);
2055 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); 2079 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear);
2056 2080
2057 __ bind(&stub_call); 2081 __ bind(&stub_call);
2058 __ mov(eax, ecx); 2082 __ mov(eax, ecx);
2059 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); 2083 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
2060 CallIC(code, expr->BinaryOperationFeedbackId()); 2084 CallIC(code, expr->BinaryOperationFeedbackId());
2061 patch_site.EmitPatchInfo(); 2085 patch_site.EmitPatchInfo();
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
2134 context()->Plug(eax); 2158 context()->Plug(eax);
2135 } 2159 }
2136 2160
2137 2161
2138 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) { 2162 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
2139 for (int i = 0; i < lit->properties()->length(); i++) { 2163 for (int i = 0; i < lit->properties()->length(); i++) {
2140 ObjectLiteral::Property* property = lit->properties()->at(i); 2164 ObjectLiteral::Property* property = lit->properties()->at(i);
2141 Expression* value = property->value(); 2165 Expression* value = property->value();
2142 2166
2143 if (property->is_static()) { 2167 if (property->is_static()) {
2144 __ push(Operand(esp, kPointerSize)); // constructor 2168 PushOperand(Operand(esp, kPointerSize)); // constructor
2145 } else { 2169 } else {
2146 __ push(Operand(esp, 0)); // prototype 2170 PushOperand(Operand(esp, 0)); // prototype
2147 } 2171 }
2148 EmitPropertyKey(property, lit->GetIdForProperty(i)); 2172 EmitPropertyKey(property, lit->GetIdForProperty(i));
2149 2173
2150 // The static prototype property is read only. We handle the non computed 2174 // 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 2175 // 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 2176 // 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. 2177 // not need to do this for every property.
2154 if (property->is_static() && property->is_computed_name()) { 2178 if (property->is_static() && property->is_computed_name()) {
2155 __ CallRuntime(Runtime::kThrowIfStaticPrototype); 2179 __ CallRuntime(Runtime::kThrowIfStaticPrototype);
2156 __ push(eax); 2180 __ push(eax);
2157 } 2181 }
2158 2182
2159 VisitForStackValue(value); 2183 VisitForStackValue(value);
2160 if (NeedsHomeObject(value)) { 2184 if (NeedsHomeObject(value)) {
2161 EmitSetHomeObject(value, 2, property->GetSlot()); 2185 EmitSetHomeObject(value, 2, property->GetSlot());
2162 } 2186 }
2163 2187
2164 switch (property->kind()) { 2188 switch (property->kind()) {
2165 case ObjectLiteral::Property::CONSTANT: 2189 case ObjectLiteral::Property::CONSTANT:
2166 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 2190 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
2167 case ObjectLiteral::Property::PROTOTYPE: 2191 case ObjectLiteral::Property::PROTOTYPE:
2168 UNREACHABLE(); 2192 UNREACHABLE();
2169 case ObjectLiteral::Property::COMPUTED: 2193 case ObjectLiteral::Property::COMPUTED:
2170 __ Push(Smi::FromInt(DONT_ENUM)); 2194 PushOperand(Smi::FromInt(DONT_ENUM));
2171 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); 2195 PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
2172 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); 2196 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
2173 break; 2197 break;
2174 2198
2175 case ObjectLiteral::Property::GETTER: 2199 case ObjectLiteral::Property::GETTER:
2176 __ Push(Smi::FromInt(DONT_ENUM)); 2200 PushOperand(Smi::FromInt(DONT_ENUM));
2177 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); 2201 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
2178 break; 2202 break;
2179 2203
2180 case ObjectLiteral::Property::SETTER: 2204 case ObjectLiteral::Property::SETTER:
2181 __ Push(Smi::FromInt(DONT_ENUM)); 2205 PushOperand(Smi::FromInt(DONT_ENUM));
2182 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); 2206 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
2183 break; 2207 break;
2184 } 2208 }
2185 } 2209 }
2186 } 2210 }
2187 2211
2188 2212
2189 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { 2213 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
2190 __ pop(edx); 2214 PopOperand(edx);
2191 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); 2215 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
2192 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 2216 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
2193 CallIC(code, expr->BinaryOperationFeedbackId()); 2217 CallIC(code, expr->BinaryOperationFeedbackId());
2194 patch_site.EmitPatchInfo(); 2218 patch_site.EmitPatchInfo();
2195 context()->Plug(eax); 2219 context()->Plug(eax);
2196 } 2220 }
2197 2221
2198 2222
2199 void FullCodeGenerator::EmitAssignment(Expression* expr, 2223 void FullCodeGenerator::EmitAssignment(Expression* expr,
2200 FeedbackVectorSlot slot) { 2224 FeedbackVectorSlot slot) {
2201 DCHECK(expr->IsValidReferenceExpressionOrThis()); 2225 DCHECK(expr->IsValidReferenceExpressionOrThis());
2202 2226
2203 Property* prop = expr->AsProperty(); 2227 Property* prop = expr->AsProperty();
2204 LhsKind assign_type = Property::GetAssignType(prop); 2228 LhsKind assign_type = Property::GetAssignType(prop);
2205 2229
2206 switch (assign_type) { 2230 switch (assign_type) {
2207 case VARIABLE: { 2231 case VARIABLE: {
2208 Variable* var = expr->AsVariableProxy()->var(); 2232 Variable* var = expr->AsVariableProxy()->var();
2209 EffectContext context(this); 2233 EffectContext context(this);
2210 EmitVariableAssignment(var, Token::ASSIGN, slot); 2234 EmitVariableAssignment(var, Token::ASSIGN, slot);
2211 break; 2235 break;
2212 } 2236 }
2213 case NAMED_PROPERTY: { 2237 case NAMED_PROPERTY: {
2214 __ push(eax); // Preserve value. 2238 PushOperand(eax); // Preserve value.
2215 VisitForAccumulatorValue(prop->obj()); 2239 VisitForAccumulatorValue(prop->obj());
2216 __ Move(StoreDescriptor::ReceiverRegister(), eax); 2240 __ Move(StoreDescriptor::ReceiverRegister(), eax);
2217 __ pop(StoreDescriptor::ValueRegister()); // Restore value. 2241 PopOperand(StoreDescriptor::ValueRegister()); // Restore value.
2218 __ mov(StoreDescriptor::NameRegister(), 2242 __ mov(StoreDescriptor::NameRegister(),
2219 prop->key()->AsLiteral()->value()); 2243 prop->key()->AsLiteral()->value());
2220 EmitLoadStoreICSlot(slot); 2244 EmitLoadStoreICSlot(slot);
2221 CallStoreIC(); 2245 CallStoreIC();
2222 break; 2246 break;
2223 } 2247 }
2224 case NAMED_SUPER_PROPERTY: { 2248 case NAMED_SUPER_PROPERTY: {
2225 __ push(eax); 2249 PushOperand(eax);
2226 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 2250 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
2227 VisitForAccumulatorValue( 2251 VisitForAccumulatorValue(
2228 prop->obj()->AsSuperPropertyReference()->home_object()); 2252 prop->obj()->AsSuperPropertyReference()->home_object());
2229 // stack: value, this; eax: home_object 2253 // stack: value, this; eax: home_object
2230 Register scratch = ecx; 2254 Register scratch = ecx;
2231 Register scratch2 = edx; 2255 Register scratch2 = edx;
2232 __ mov(scratch, result_register()); // home_object 2256 __ mov(scratch, result_register()); // home_object
2233 __ mov(eax, MemOperand(esp, kPointerSize)); // value 2257 __ mov(eax, MemOperand(esp, kPointerSize)); // value
2234 __ mov(scratch2, MemOperand(esp, 0)); // this 2258 __ mov(scratch2, MemOperand(esp, 0)); // this
2235 __ mov(MemOperand(esp, kPointerSize), scratch2); // this 2259 __ mov(MemOperand(esp, kPointerSize), scratch2); // this
2236 __ mov(MemOperand(esp, 0), scratch); // home_object 2260 __ mov(MemOperand(esp, 0), scratch); // home_object
2237 // stack: this, home_object. eax: value 2261 // stack: this, home_object. eax: value
2238 EmitNamedSuperPropertyStore(prop); 2262 EmitNamedSuperPropertyStore(prop);
2239 break; 2263 break;
2240 } 2264 }
2241 case KEYED_SUPER_PROPERTY: { 2265 case KEYED_SUPER_PROPERTY: {
2242 __ push(eax); 2266 PushOperand(eax);
2243 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 2267 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
2244 VisitForStackValue( 2268 VisitForStackValue(
2245 prop->obj()->AsSuperPropertyReference()->home_object()); 2269 prop->obj()->AsSuperPropertyReference()->home_object());
2246 VisitForAccumulatorValue(prop->key()); 2270 VisitForAccumulatorValue(prop->key());
2247 Register scratch = ecx; 2271 Register scratch = ecx;
2248 Register scratch2 = edx; 2272 Register scratch2 = edx;
2249 __ mov(scratch2, MemOperand(esp, 2 * kPointerSize)); // value 2273 __ mov(scratch2, MemOperand(esp, 2 * kPointerSize)); // value
2250 // stack: value, this, home_object; eax: key, edx: value 2274 // stack: value, this, home_object; eax: key, edx: value
2251 __ mov(scratch, MemOperand(esp, kPointerSize)); // this 2275 __ mov(scratch, MemOperand(esp, kPointerSize)); // this
2252 __ mov(MemOperand(esp, 2 * kPointerSize), scratch); 2276 __ mov(MemOperand(esp, 2 * kPointerSize), scratch);
2253 __ mov(scratch, MemOperand(esp, 0)); // home_object 2277 __ mov(scratch, MemOperand(esp, 0)); // home_object
2254 __ mov(MemOperand(esp, kPointerSize), scratch); 2278 __ mov(MemOperand(esp, kPointerSize), scratch);
2255 __ mov(MemOperand(esp, 0), eax); 2279 __ mov(MemOperand(esp, 0), eax);
2256 __ mov(eax, scratch2); 2280 __ mov(eax, scratch2);
2257 // stack: this, home_object, key; eax: value. 2281 // stack: this, home_object, key; eax: value.
2258 EmitKeyedSuperPropertyStore(prop); 2282 EmitKeyedSuperPropertyStore(prop);
2259 break; 2283 break;
2260 } 2284 }
2261 case KEYED_PROPERTY: { 2285 case KEYED_PROPERTY: {
2262 __ push(eax); // Preserve value. 2286 PushOperand(eax); // Preserve value.
2263 VisitForStackValue(prop->obj()); 2287 VisitForStackValue(prop->obj());
2264 VisitForAccumulatorValue(prop->key()); 2288 VisitForAccumulatorValue(prop->key());
2265 __ Move(StoreDescriptor::NameRegister(), eax); 2289 __ Move(StoreDescriptor::NameRegister(), eax);
2266 __ pop(StoreDescriptor::ReceiverRegister()); // Receiver. 2290 PopOperand(StoreDescriptor::ReceiverRegister()); // Receiver.
2267 __ pop(StoreDescriptor::ValueRegister()); // Restore value. 2291 PopOperand(StoreDescriptor::ValueRegister()); // Restore value.
2268 EmitLoadStoreICSlot(slot); 2292 EmitLoadStoreICSlot(slot);
2269 Handle<Code> ic = 2293 Handle<Code> ic =
2270 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2294 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2271 CallIC(ic); 2295 CallIC(ic);
2272 break; 2296 break;
2273 } 2297 }
2274 } 2298 }
2275 context()->Plug(eax); 2299 context()->Plug(eax);
2276 } 2300 }
2277 2301
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
2394 2418
2395 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2419 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2396 // Assignment to a property, using a named store IC. 2420 // Assignment to a property, using a named store IC.
2397 // eax : value 2421 // eax : value
2398 // esp[0] : receiver 2422 // esp[0] : receiver
2399 Property* prop = expr->target()->AsProperty(); 2423 Property* prop = expr->target()->AsProperty();
2400 DCHECK(prop != NULL); 2424 DCHECK(prop != NULL);
2401 DCHECK(prop->key()->IsLiteral()); 2425 DCHECK(prop->key()->IsLiteral());
2402 2426
2403 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); 2427 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value());
2404 __ pop(StoreDescriptor::ReceiverRegister()); 2428 PopOperand(StoreDescriptor::ReceiverRegister());
2405 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2429 EmitLoadStoreICSlot(expr->AssignmentSlot());
2406 CallStoreIC(); 2430 CallStoreIC();
2407 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2431 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2408 context()->Plug(eax); 2432 context()->Plug(eax);
2409 } 2433 }
2410 2434
2411 2435
2412 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { 2436 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
2413 // Assignment to named property of super. 2437 // Assignment to named property of super.
2414 // eax : value 2438 // eax : value
2415 // stack : receiver ('this'), home_object 2439 // stack : receiver ('this'), home_object
2416 DCHECK(prop != NULL); 2440 DCHECK(prop != NULL);
2417 Literal* key = prop->key()->AsLiteral(); 2441 Literal* key = prop->key()->AsLiteral();
2418 DCHECK(key != NULL); 2442 DCHECK(key != NULL);
2419 2443
2420 __ push(Immediate(key->value())); 2444 PushOperand(key->value());
2421 __ push(eax); 2445 PushOperand(eax);
2422 __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict 2446 CallRuntimeWithOperands(is_strict(language_mode())
2423 : Runtime::kStoreToSuper_Sloppy)); 2447 ? Runtime::kStoreToSuper_Strict
2448 : Runtime::kStoreToSuper_Sloppy);
2424 } 2449 }
2425 2450
2426 2451
2427 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { 2452 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
2428 // Assignment to named property of super. 2453 // Assignment to named property of super.
2429 // eax : value 2454 // eax : value
2430 // stack : receiver ('this'), home_object, key 2455 // stack : receiver ('this'), home_object, key
2431 2456
2432 __ push(eax); 2457 PushOperand(eax);
2433 __ CallRuntime((is_strict(language_mode()) 2458 CallRuntimeWithOperands(is_strict(language_mode())
2434 ? Runtime::kStoreKeyedToSuper_Strict 2459 ? Runtime::kStoreKeyedToSuper_Strict
2435 : Runtime::kStoreKeyedToSuper_Sloppy)); 2460 : Runtime::kStoreKeyedToSuper_Sloppy);
2436 } 2461 }
2437 2462
2438 2463
2439 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2464 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2440 // Assignment to a property, using a keyed store IC. 2465 // Assignment to a property, using a keyed store IC.
2441 // eax : value 2466 // eax : value
2442 // esp[0] : key 2467 // esp[0] : key
2443 // esp[kPointerSize] : receiver 2468 // esp[kPointerSize] : receiver
2444 2469
2445 __ pop(StoreDescriptor::NameRegister()); // Key. 2470 PopOperand(StoreDescriptor::NameRegister()); // Key.
2446 __ pop(StoreDescriptor::ReceiverRegister()); 2471 PopOperand(StoreDescriptor::ReceiverRegister());
2447 DCHECK(StoreDescriptor::ValueRegister().is(eax)); 2472 DCHECK(StoreDescriptor::ValueRegister().is(eax));
2448 Handle<Code> ic = 2473 Handle<Code> ic =
2449 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2474 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2450 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2475 EmitLoadStoreICSlot(expr->AssignmentSlot());
2451 CallIC(ic); 2476 CallIC(ic);
2452 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2477 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2453 context()->Plug(eax); 2478 context()->Plug(eax);
2454 } 2479 }
2455 2480
2456 2481
(...skipping 11 matching lines...) Expand all
2468 } else { 2493 } else {
2469 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); 2494 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
2470 VisitForStackValue( 2495 VisitForStackValue(
2471 expr->obj()->AsSuperPropertyReference()->home_object()); 2496 expr->obj()->AsSuperPropertyReference()->home_object());
2472 EmitNamedSuperPropertyLoad(expr); 2497 EmitNamedSuperPropertyLoad(expr);
2473 } 2498 }
2474 } else { 2499 } else {
2475 if (!expr->IsSuperAccess()) { 2500 if (!expr->IsSuperAccess()) {
2476 VisitForStackValue(expr->obj()); 2501 VisitForStackValue(expr->obj());
2477 VisitForAccumulatorValue(expr->key()); 2502 VisitForAccumulatorValue(expr->key());
2478 __ pop(LoadDescriptor::ReceiverRegister()); // Object. 2503 PopOperand(LoadDescriptor::ReceiverRegister()); // Object.
2479 __ Move(LoadDescriptor::NameRegister(), result_register()); // Key. 2504 __ Move(LoadDescriptor::NameRegister(), result_register()); // Key.
2480 EmitKeyedPropertyLoad(expr); 2505 EmitKeyedPropertyLoad(expr);
2481 } else { 2506 } else {
2482 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); 2507 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
2483 VisitForStackValue( 2508 VisitForStackValue(
2484 expr->obj()->AsSuperPropertyReference()->home_object()); 2509 expr->obj()->AsSuperPropertyReference()->home_object());
2485 VisitForStackValue(expr->key()); 2510 VisitForStackValue(expr->key());
2486 EmitKeyedSuperPropertyLoad(expr); 2511 EmitKeyedSuperPropertyLoad(expr);
2487 } 2512 }
2488 } 2513 }
(...skipping 15 matching lines...) Expand all
2504 2529
2505 // Get the target function. 2530 // Get the target function.
2506 ConvertReceiverMode convert_mode; 2531 ConvertReceiverMode convert_mode;
2507 if (callee->IsVariableProxy()) { 2532 if (callee->IsVariableProxy()) {
2508 { StackValueContext context(this); 2533 { StackValueContext context(this);
2509 EmitVariableLoad(callee->AsVariableProxy()); 2534 EmitVariableLoad(callee->AsVariableProxy());
2510 PrepareForBailout(callee, NO_REGISTERS); 2535 PrepareForBailout(callee, NO_REGISTERS);
2511 } 2536 }
2512 // Push undefined as receiver. This is patched in the method prologue if it 2537 // Push undefined as receiver. This is patched in the method prologue if it
2513 // is a sloppy mode method. 2538 // is a sloppy mode method.
2514 __ push(Immediate(isolate()->factory()->undefined_value())); 2539 PushOperand(isolate()->factory()->undefined_value());
2515 convert_mode = ConvertReceiverMode::kNullOrUndefined; 2540 convert_mode = ConvertReceiverMode::kNullOrUndefined;
2516 } else { 2541 } else {
2517 // Load the function from the receiver. 2542 // Load the function from the receiver.
2518 DCHECK(callee->IsProperty()); 2543 DCHECK(callee->IsProperty());
2519 DCHECK(!callee->AsProperty()->IsSuperAccess()); 2544 DCHECK(!callee->AsProperty()->IsSuperAccess());
2520 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); 2545 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
2521 EmitNamedPropertyLoad(callee->AsProperty()); 2546 EmitNamedPropertyLoad(callee->AsProperty());
2522 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2547 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2523 // Push the target function under the receiver. 2548 // Push the target function under the receiver.
2524 __ push(Operand(esp, 0)); 2549 PushOperand(Operand(esp, 0));
2525 __ mov(Operand(esp, kPointerSize), eax); 2550 __ mov(Operand(esp, kPointerSize), eax);
2526 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; 2551 convert_mode = ConvertReceiverMode::kNotNullOrUndefined;
2527 } 2552 }
2528 2553
2529 EmitCall(expr, convert_mode); 2554 EmitCall(expr, convert_mode);
2530 } 2555 }
2531 2556
2532 2557
2533 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { 2558 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
2534 SetExpressionPosition(expr); 2559 SetExpressionPosition(expr);
2535 Expression* callee = expr->expression(); 2560 Expression* callee = expr->expression();
2536 DCHECK(callee->IsProperty()); 2561 DCHECK(callee->IsProperty());
2537 Property* prop = callee->AsProperty(); 2562 Property* prop = callee->AsProperty();
2538 DCHECK(prop->IsSuperAccess()); 2563 DCHECK(prop->IsSuperAccess());
2539 2564
2540 Literal* key = prop->key()->AsLiteral(); 2565 Literal* key = prop->key()->AsLiteral();
2541 DCHECK(!key->value()->IsSmi()); 2566 DCHECK(!key->value()->IsSmi());
2542 // Load the function from the receiver. 2567 // Load the function from the receiver.
2543 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); 2568 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
2544 VisitForStackValue(super_ref->home_object()); 2569 VisitForStackValue(super_ref->home_object());
2545 VisitForAccumulatorValue(super_ref->this_var()); 2570 VisitForAccumulatorValue(super_ref->this_var());
2546 __ push(eax); 2571 PushOperand(eax);
2547 __ push(eax); 2572 PushOperand(eax);
2548 __ push(Operand(esp, kPointerSize * 2)); 2573 PushOperand(Operand(esp, kPointerSize * 2));
2549 __ push(Immediate(key->value())); 2574 PushOperand(key->value());
2550 // Stack here: 2575 // Stack here:
2551 // - home_object 2576 // - home_object
2552 // - this (receiver) 2577 // - this (receiver)
2553 // - this (receiver) <-- LoadFromSuper will pop here and below. 2578 // - this (receiver) <-- LoadFromSuper will pop here and below.
2554 // - home_object 2579 // - home_object
2555 // - key 2580 // - key
2556 __ CallRuntime(Runtime::kLoadFromSuper); 2581 CallRuntimeWithOperands(Runtime::kLoadFromSuper);
2557 2582
2558 // Replace home_object with target function. 2583 // Replace home_object with target function.
2559 __ mov(Operand(esp, kPointerSize), eax); 2584 __ mov(Operand(esp, kPointerSize), eax);
2560 2585
2561 // Stack here: 2586 // Stack here:
2562 // - target function 2587 // - target function
2563 // - this (receiver) 2588 // - this (receiver)
2564 EmitCall(expr); 2589 EmitCall(expr);
2565 } 2590 }
2566 2591
2567 2592
2568 // Code common for calls using the IC. 2593 // Code common for calls using the IC.
2569 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2594 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2570 Expression* key) { 2595 Expression* key) {
2571 // Load the key. 2596 // Load the key.
2572 VisitForAccumulatorValue(key); 2597 VisitForAccumulatorValue(key);
2573 2598
2574 Expression* callee = expr->expression(); 2599 Expression* callee = expr->expression();
2575 2600
2576 // Load the function from the receiver. 2601 // Load the function from the receiver.
2577 DCHECK(callee->IsProperty()); 2602 DCHECK(callee->IsProperty());
2578 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); 2603 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
2579 __ mov(LoadDescriptor::NameRegister(), eax); 2604 __ mov(LoadDescriptor::NameRegister(), eax);
2580 EmitKeyedPropertyLoad(callee->AsProperty()); 2605 EmitKeyedPropertyLoad(callee->AsProperty());
2581 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2606 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2582 2607
2583 // Push the target function under the receiver. 2608 // Push the target function under the receiver.
2584 __ push(Operand(esp, 0)); 2609 PushOperand(Operand(esp, 0));
2585 __ mov(Operand(esp, kPointerSize), eax); 2610 __ mov(Operand(esp, kPointerSize), eax);
2586 2611
2587 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); 2612 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined);
2588 } 2613 }
2589 2614
2590 2615
2591 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { 2616 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
2592 Expression* callee = expr->expression(); 2617 Expression* callee = expr->expression();
2593 DCHECK(callee->IsProperty()); 2618 DCHECK(callee->IsProperty());
2594 Property* prop = callee->AsProperty(); 2619 Property* prop = callee->AsProperty();
2595 DCHECK(prop->IsSuperAccess()); 2620 DCHECK(prop->IsSuperAccess());
2596 2621
2597 SetExpressionPosition(prop); 2622 SetExpressionPosition(prop);
2598 // Load the function from the receiver. 2623 // Load the function from the receiver.
2599 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); 2624 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
2600 VisitForStackValue(super_ref->home_object()); 2625 VisitForStackValue(super_ref->home_object());
2601 VisitForAccumulatorValue(super_ref->this_var()); 2626 VisitForAccumulatorValue(super_ref->this_var());
2602 __ push(eax); 2627 PushOperand(eax);
2603 __ push(eax); 2628 PushOperand(eax);
2604 __ push(Operand(esp, kPointerSize * 2)); 2629 PushOperand(Operand(esp, kPointerSize * 2));
2605 VisitForStackValue(prop->key()); 2630 VisitForStackValue(prop->key());
2606 // Stack here: 2631 // Stack here:
2607 // - home_object 2632 // - home_object
2608 // - this (receiver) 2633 // - this (receiver)
2609 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. 2634 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
2610 // - home_object 2635 // - home_object
2611 // - key 2636 // - key
2612 __ CallRuntime(Runtime::kLoadKeyedFromSuper); 2637 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper);
2613 2638
2614 // Replace home_object with target function. 2639 // Replace home_object with target function.
2615 __ mov(Operand(esp, kPointerSize), eax); 2640 __ mov(Operand(esp, kPointerSize), eax);
2616 2641
2617 // Stack here: 2642 // Stack here:
2618 // - target function 2643 // - target function
2619 // - this (receiver) 2644 // - this (receiver)
2620 EmitCall(expr); 2645 EmitCall(expr);
2621 } 2646 }
2622 2647
(...skipping 17 matching lines...) Expand all
2640 EmitProfilingCounterHandlingForReturnSequence(true); 2665 EmitProfilingCounterHandlingForReturnSequence(true);
2641 } 2666 }
2642 Handle<Code> ic = 2667 Handle<Code> ic =
2643 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) 2668 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode())
2644 .code(); 2669 .code();
2645 __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot()))); 2670 __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot())));
2646 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 2671 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
2647 // Don't assign a type feedback id to the IC, since type feedback is provided 2672 // Don't assign a type feedback id to the IC, since type feedback is provided
2648 // by the vector above. 2673 // by the vector above.
2649 CallIC(ic); 2674 CallIC(ic);
2675 OperandStackDepthDecrement(arg_count + 1);
2650 2676
2651 RecordJSReturnSite(expr); 2677 RecordJSReturnSite(expr);
2652 2678
2653 // Restore context register. 2679 // Restore context register.
2654 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2680 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2655 2681
2656 context()->DropAndPlug(1, eax); 2682 context()->DropAndPlug(1, eax);
2657 } 2683 }
2658 2684
2659 2685
(...skipping 27 matching lines...) Expand all
2687 SetExpressionPosition(callee); 2713 SetExpressionPosition(callee);
2688 // Generate code for loading from variables potentially shadowed by 2714 // Generate code for loading from variables potentially shadowed by
2689 // eval-introduced variables. 2715 // eval-introduced variables.
2690 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); 2716 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2691 2717
2692 __ bind(&slow); 2718 __ bind(&slow);
2693 // Call the runtime to find the function to call (returned in eax) and 2719 // Call the runtime to find the function to call (returned in eax) and
2694 // the object holding it (returned in edx). 2720 // the object holding it (returned in edx).
2695 __ Push(callee->name()); 2721 __ Push(callee->name());
2696 __ CallRuntime(Runtime::kLoadLookupSlotForCall); 2722 __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2697 __ Push(eax); // Function. 2723 PushOperand(eax); // Function.
2698 __ Push(edx); // Receiver. 2724 PushOperand(edx); // Receiver.
2699 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); 2725 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
2700 2726
2701 // If fast case code has been generated, emit code to push the function 2727 // 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. 2728 // and receiver and have the slow path jump around this code.
2703 if (done.is_linked()) { 2729 if (done.is_linked()) {
2704 Label call; 2730 Label call;
2705 __ jmp(&call, Label::kNear); 2731 __ jmp(&call, Label::kNear);
2706 __ bind(&done); 2732 __ bind(&done);
2707 // Push function. 2733 // Push function.
2708 __ push(eax); 2734 __ push(eax);
2709 // The receiver is implicitly the global receiver. Indicate this by 2735 // The receiver is implicitly the global receiver. Indicate this by
2710 // passing the hole to the call function stub. 2736 // passing the hole to the call function stub.
2711 __ push(Immediate(isolate()->factory()->undefined_value())); 2737 __ push(Immediate(isolate()->factory()->undefined_value()));
2712 __ bind(&call); 2738 __ bind(&call);
2713 } 2739 }
2714 } else { 2740 } else {
2715 VisitForStackValue(callee); 2741 VisitForStackValue(callee);
2716 // refEnv.WithBaseObject() 2742 // refEnv.WithBaseObject()
2717 __ push(Immediate(isolate()->factory()->undefined_value())); 2743 PushOperand(isolate()->factory()->undefined_value());
2718 } 2744 }
2719 } 2745 }
2720 2746
2721 2747
2722 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { 2748 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
2723 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval 2749 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
2724 // to resolve the function we need to call. Then we call the resolved 2750 // to resolve the function we need to call. Then we call the resolved
2725 // function using the given arguments. 2751 // function using the given arguments.
2726 ZoneList<Expression*>* args = expr->arguments(); 2752 ZoneList<Expression*>* args = expr->arguments();
2727 int arg_count = args->length(); 2753 int arg_count = args->length();
(...skipping 12 matching lines...) Expand all
2740 2766
2741 // Touch up the stack with the resolved function. 2767 // Touch up the stack with the resolved function.
2742 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax); 2768 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
2743 2769
2744 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); 2770 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
2745 2771
2746 SetCallPosition(expr); 2772 SetCallPosition(expr);
2747 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 2773 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
2748 __ Set(eax, arg_count); 2774 __ Set(eax, arg_count);
2749 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 2775 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
2776 OperandStackDepthDecrement(arg_count + 1);
2750 RecordJSReturnSite(expr); 2777 RecordJSReturnSite(expr);
2751 // Restore context register. 2778 // Restore context register.
2752 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2779 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2753 context()->DropAndPlug(1, eax); 2780 context()->DropAndPlug(1, eax);
2754 } 2781 }
2755 2782
2756 2783
2757 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2784 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
2758 Comment cmnt(masm_, "[ CallNew"); 2785 Comment cmnt(masm_, "[ CallNew");
2759 // According to ECMA-262, section 11.2.2, page 44, the function 2786 // According to ECMA-262, section 11.2.2, page 44, the function
(...skipping 20 matching lines...) Expand all
2780 // Load function and argument count into edi and eax. 2807 // Load function and argument count into edi and eax.
2781 __ Move(eax, Immediate(arg_count)); 2808 __ Move(eax, Immediate(arg_count));
2782 __ mov(edi, Operand(esp, arg_count * kPointerSize)); 2809 __ mov(edi, Operand(esp, arg_count * kPointerSize));
2783 2810
2784 // Record call targets in unoptimized code. 2811 // Record call targets in unoptimized code.
2785 __ EmitLoadTypeFeedbackVector(ebx); 2812 __ EmitLoadTypeFeedbackVector(ebx);
2786 __ mov(edx, Immediate(SmiFromSlot(expr->CallNewFeedbackSlot()))); 2813 __ mov(edx, Immediate(SmiFromSlot(expr->CallNewFeedbackSlot())));
2787 2814
2788 CallConstructStub stub(isolate()); 2815 CallConstructStub stub(isolate());
2789 __ call(stub.GetCode(), RelocInfo::CODE_TARGET); 2816 __ call(stub.GetCode(), RelocInfo::CODE_TARGET);
2817 OperandStackDepthDecrement(arg_count + 1);
2790 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2818 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2791 // Restore context register. 2819 // Restore context register.
2792 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2820 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2793 context()->Plug(eax); 2821 context()->Plug(eax);
2794 } 2822 }
2795 2823
2796 2824
2797 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { 2825 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
2798 SuperCallReference* super_call_ref = 2826 SuperCallReference* super_call_ref =
2799 expr->expression()->AsSuperCallReference(); 2827 expr->expression()->AsSuperCallReference();
2800 DCHECK_NOT_NULL(super_call_ref); 2828 DCHECK_NOT_NULL(super_call_ref);
2801 2829
2802 // Push the super constructor target on the stack (may be null, 2830 // Push the super constructor target on the stack (may be null,
2803 // but the Construct builtin can deal with that properly). 2831 // but the Construct builtin can deal with that properly).
2804 VisitForAccumulatorValue(super_call_ref->this_function_var()); 2832 VisitForAccumulatorValue(super_call_ref->this_function_var());
2805 __ AssertFunction(result_register()); 2833 __ AssertFunction(result_register());
2806 __ mov(result_register(), 2834 __ mov(result_register(),
2807 FieldOperand(result_register(), HeapObject::kMapOffset)); 2835 FieldOperand(result_register(), HeapObject::kMapOffset));
2808 __ Push(FieldOperand(result_register(), Map::kPrototypeOffset)); 2836 PushOperand(FieldOperand(result_register(), Map::kPrototypeOffset));
2809 2837
2810 // Push the arguments ("left-to-right") on the stack. 2838 // Push the arguments ("left-to-right") on the stack.
2811 ZoneList<Expression*>* args = expr->arguments(); 2839 ZoneList<Expression*>* args = expr->arguments();
2812 int arg_count = args->length(); 2840 int arg_count = args->length();
2813 for (int i = 0; i < arg_count; i++) { 2841 for (int i = 0; i < arg_count; i++) {
2814 VisitForStackValue(args->at(i)); 2842 VisitForStackValue(args->at(i));
2815 } 2843 }
2816 2844
2817 // Call the construct call builtin that handles allocation and 2845 // Call the construct call builtin that handles allocation and
2818 // constructor invocation. 2846 // constructor invocation.
2819 SetConstructCallPosition(expr); 2847 SetConstructCallPosition(expr);
2820 2848
2821 // Load new target into edx. 2849 // Load new target into edx.
2822 VisitForAccumulatorValue(super_call_ref->new_target_var()); 2850 VisitForAccumulatorValue(super_call_ref->new_target_var());
2823 __ mov(edx, result_register()); 2851 __ mov(edx, result_register());
2824 2852
2825 // Load function and argument count into edi and eax. 2853 // Load function and argument count into edi and eax.
2826 __ Move(eax, Immediate(arg_count)); 2854 __ Move(eax, Immediate(arg_count));
2827 __ mov(edi, Operand(esp, arg_count * kPointerSize)); 2855 __ mov(edi, Operand(esp, arg_count * kPointerSize));
2828 2856
2829 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 2857 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
2858 OperandStackDepthDecrement(arg_count + 1);
2830 2859
2831 RecordJSReturnSite(expr); 2860 RecordJSReturnSite(expr);
2832 2861
2833 // Restore context register. 2862 // Restore context register.
2834 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2863 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2835 context()->Plug(eax); 2864 context()->Plug(eax);
2836 } 2865 }
2837 2866
2838 2867
2839 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2868 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
3040 DCHECK_EQ(3, args->length()); 3069 DCHECK_EQ(3, args->length());
3041 3070
3042 Register string = eax; 3071 Register string = eax;
3043 Register index = ebx; 3072 Register index = ebx;
3044 Register value = ecx; 3073 Register value = ecx;
3045 3074
3046 VisitForStackValue(args->at(0)); // index 3075 VisitForStackValue(args->at(0)); // index
3047 VisitForStackValue(args->at(1)); // value 3076 VisitForStackValue(args->at(1)); // value
3048 VisitForAccumulatorValue(args->at(2)); // string 3077 VisitForAccumulatorValue(args->at(2)); // string
3049 3078
3050 __ pop(value); 3079 PopOperand(value);
3051 __ pop(index); 3080 PopOperand(index);
3052 3081
3053 if (FLAG_debug_code) { 3082 if (FLAG_debug_code) {
3054 __ test(value, Immediate(kSmiTagMask)); 3083 __ test(value, Immediate(kSmiTagMask));
3055 __ Check(zero, kNonSmiValue); 3084 __ Check(zero, kNonSmiValue);
3056 __ test(index, Immediate(kSmiTagMask)); 3085 __ test(index, Immediate(kSmiTagMask));
3057 __ Check(zero, kNonSmiValue); 3086 __ Check(zero, kNonSmiValue);
3058 } 3087 }
3059 3088
3060 __ SmiUntag(value); 3089 __ SmiUntag(value);
3061 __ SmiUntag(index); 3090 __ SmiUntag(index);
(...skipping 13 matching lines...) Expand all
3075 ZoneList<Expression*>* args = expr->arguments(); 3104 ZoneList<Expression*>* args = expr->arguments();
3076 DCHECK_EQ(3, args->length()); 3105 DCHECK_EQ(3, args->length());
3077 3106
3078 Register string = eax; 3107 Register string = eax;
3079 Register index = ebx; 3108 Register index = ebx;
3080 Register value = ecx; 3109 Register value = ecx;
3081 3110
3082 VisitForStackValue(args->at(0)); // index 3111 VisitForStackValue(args->at(0)); // index
3083 VisitForStackValue(args->at(1)); // value 3112 VisitForStackValue(args->at(1)); // value
3084 VisitForAccumulatorValue(args->at(2)); // string 3113 VisitForAccumulatorValue(args->at(2)); // string
3085 __ pop(value); 3114 PopOperand(value);
3086 __ pop(index); 3115 PopOperand(index);
3087 3116
3088 if (FLAG_debug_code) { 3117 if (FLAG_debug_code) {
3089 __ test(value, Immediate(kSmiTagMask)); 3118 __ test(value, Immediate(kSmiTagMask));
3090 __ Check(zero, kNonSmiValue); 3119 __ Check(zero, kNonSmiValue);
3091 __ test(index, Immediate(kSmiTagMask)); 3120 __ test(index, Immediate(kSmiTagMask));
3092 __ Check(zero, kNonSmiValue); 3121 __ Check(zero, kNonSmiValue);
3093 __ SmiUntag(index); 3122 __ SmiUntag(index);
3094 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; 3123 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
3095 __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type); 3124 __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type);
3096 __ SmiTag(index); 3125 __ SmiTag(index);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3144 ZoneList<Expression*>* args = expr->arguments(); 3173 ZoneList<Expression*>* args = expr->arguments();
3145 DCHECK(args->length() == 2); 3174 DCHECK(args->length() == 2);
3146 3175
3147 VisitForStackValue(args->at(0)); 3176 VisitForStackValue(args->at(0));
3148 VisitForAccumulatorValue(args->at(1)); 3177 VisitForAccumulatorValue(args->at(1));
3149 3178
3150 Register object = ebx; 3179 Register object = ebx;
3151 Register index = eax; 3180 Register index = eax;
3152 Register result = edx; 3181 Register result = edx;
3153 3182
3154 __ pop(object); 3183 PopOperand(object);
3155 3184
3156 Label need_conversion; 3185 Label need_conversion;
3157 Label index_out_of_range; 3186 Label index_out_of_range;
3158 Label done; 3187 Label done;
3159 StringCharCodeAtGenerator generator(object, 3188 StringCharCodeAtGenerator generator(object,
3160 index, 3189 index,
3161 result, 3190 result,
3162 &need_conversion, 3191 &need_conversion,
3163 &need_conversion, 3192 &need_conversion,
3164 &index_out_of_range, 3193 &index_out_of_range,
(...skipping 26 matching lines...) Expand all
3191 DCHECK(args->length() == 2); 3220 DCHECK(args->length() == 2);
3192 3221
3193 VisitForStackValue(args->at(0)); 3222 VisitForStackValue(args->at(0));
3194 VisitForAccumulatorValue(args->at(1)); 3223 VisitForAccumulatorValue(args->at(1));
3195 3224
3196 Register object = ebx; 3225 Register object = ebx;
3197 Register index = eax; 3226 Register index = eax;
3198 Register scratch = edx; 3227 Register scratch = edx;
3199 Register result = eax; 3228 Register result = eax;
3200 3229
3201 __ pop(object); 3230 PopOperand(object);
3202 3231
3203 Label need_conversion; 3232 Label need_conversion;
3204 Label index_out_of_range; 3233 Label index_out_of_range;
3205 Label done; 3234 Label done;
3206 StringCharAtGenerator generator(object, 3235 StringCharAtGenerator generator(object,
3207 index, 3236 index,
3208 scratch, 3237 scratch,
3209 result, 3238 result,
3210 &need_conversion, 3239 &need_conversion,
3211 &need_conversion, 3240 &need_conversion,
(...skipping 29 matching lines...) Expand all
3241 for (Expression* const arg : *args) { 3270 for (Expression* const arg : *args) {
3242 VisitForStackValue(arg); 3271 VisitForStackValue(arg);
3243 } 3272 }
3244 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3273 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3245 // Move target to edi. 3274 // Move target to edi.
3246 int const argc = args->length() - 2; 3275 int const argc = args->length() - 2;
3247 __ mov(edi, Operand(esp, (argc + 1) * kPointerSize)); 3276 __ mov(edi, Operand(esp, (argc + 1) * kPointerSize));
3248 // Call the target. 3277 // Call the target.
3249 __ mov(eax, Immediate(argc)); 3278 __ mov(eax, Immediate(argc));
3250 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 3279 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
3280 OperandStackDepthDecrement(argc + 1);
3251 // Restore context register. 3281 // Restore context register.
3252 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3282 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3253 // Discard the function left on TOS. 3283 // Discard the function left on TOS.
3254 context()->DropAndPlug(1, eax); 3284 context()->DropAndPlug(1, eax);
3255 } 3285 }
3256 3286
3257 3287
3258 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { 3288 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) {
3259 ZoneList<Expression*>* args = expr->arguments(); 3289 ZoneList<Expression*>* args = expr->arguments();
3260 DCHECK(args->length() == 1); 3290 DCHECK(args->length() == 1);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
3327 3357
3328 Register scratch = ebx; 3358 Register scratch = ebx;
3329 3359
3330 Register array_length = edi; 3360 Register array_length = edi;
3331 Register result_pos = no_reg; // Will be edi. 3361 Register result_pos = no_reg; // Will be edi.
3332 3362
3333 // Separator operand is already pushed. 3363 // Separator operand is already pushed.
3334 Operand separator_operand = Operand(esp, 2 * kPointerSize); 3364 Operand separator_operand = Operand(esp, 2 * kPointerSize);
3335 Operand result_operand = Operand(esp, 1 * kPointerSize); 3365 Operand result_operand = Operand(esp, 1 * kPointerSize);
3336 Operand array_length_operand = Operand(esp, 0); 3366 Operand array_length_operand = Operand(esp, 0);
3367 OperandStackDepthIncrement(2);
3337 __ sub(esp, Immediate(2 * kPointerSize)); 3368 __ sub(esp, Immediate(2 * kPointerSize));
3338 __ cld(); 3369 __ cld();
3339 // Check that the array is a JSArray 3370 // Check that the array is a JSArray
3340 __ JumpIfSmi(array, &bailout); 3371 __ JumpIfSmi(array, &bailout);
3341 __ CmpObjectType(array, JS_ARRAY_TYPE, scratch); 3372 __ CmpObjectType(array, JS_ARRAY_TYPE, scratch);
3342 __ j(not_equal, &bailout); 3373 __ j(not_equal, &bailout);
3343 3374
3344 // Check that the array has fast elements. 3375 // Check that the array has fast elements.
3345 __ CheckFastElements(scratch, &bailout); 3376 __ CheckFastElements(scratch, &bailout);
3346 3377
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
3559 __ cmp(index, array_length_operand); 3590 __ cmp(index, array_length_operand);
3560 __ j(less, &loop_3); // End while (index < length). 3591 __ j(less, &loop_3); // End while (index < length).
3561 __ jmp(&done); 3592 __ jmp(&done);
3562 3593
3563 3594
3564 __ bind(&bailout); 3595 __ bind(&bailout);
3565 __ mov(result_operand, isolate()->factory()->undefined_value()); 3596 __ mov(result_operand, isolate()->factory()->undefined_value());
3566 __ bind(&done); 3597 __ bind(&done);
3567 __ mov(eax, result_operand); 3598 __ mov(eax, result_operand);
3568 // Drop temp values from the stack, and restore context register. 3599 // Drop temp values from the stack, and restore context register.
3600 OperandStackDepthDecrement(3);
3569 __ add(esp, Immediate(3 * kPointerSize)); 3601 __ add(esp, Immediate(3 * kPointerSize));
3570 3602
3571 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3603 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3572 context()->Plug(eax); 3604 context()->Plug(eax);
3573 } 3605 }
3574 3606
3575 3607
3576 void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) { 3608 void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
3577 DCHECK(expr->arguments()->length() == 0); 3609 DCHECK(expr->arguments()->length() == 0);
3578 ExternalReference debug_is_active = 3610 ExternalReference debug_is_active =
(...skipping 19 matching lines...) Expand all
3598 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), 3630 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset),
3599 isolate()->factory()->empty_fixed_array()); 3631 isolate()->factory()->empty_fixed_array());
3600 __ mov(FieldOperand(eax, JSObject::kElementsOffset), 3632 __ mov(FieldOperand(eax, JSObject::kElementsOffset),
3601 isolate()->factory()->empty_fixed_array()); 3633 isolate()->factory()->empty_fixed_array());
3602 __ pop(FieldOperand(eax, JSIteratorResult::kDoneOffset)); 3634 __ pop(FieldOperand(eax, JSIteratorResult::kDoneOffset));
3603 __ pop(FieldOperand(eax, JSIteratorResult::kValueOffset)); 3635 __ pop(FieldOperand(eax, JSIteratorResult::kValueOffset));
3604 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); 3636 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize);
3605 __ jmp(&done, Label::kNear); 3637 __ jmp(&done, Label::kNear);
3606 3638
3607 __ bind(&runtime); 3639 __ bind(&runtime);
3608 __ CallRuntime(Runtime::kCreateIterResultObject); 3640 CallRuntimeWithOperands(Runtime::kCreateIterResultObject);
3609 3641
3610 __ bind(&done); 3642 __ bind(&done);
3611 context()->Plug(eax); 3643 context()->Plug(eax);
3612 } 3644 }
3613 3645
3614 3646
3615 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { 3647 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
3616 // Push undefined as receiver. 3648 // Push undefined as receiver.
3617 __ push(Immediate(isolate()->factory()->undefined_value())); 3649 PushOperand(isolate()->factory()->undefined_value());
3618 3650
3619 __ LoadGlobalFunction(expr->context_index(), eax); 3651 __ LoadGlobalFunction(expr->context_index(), eax);
3620 } 3652 }
3621 3653
3622 3654
3623 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { 3655 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
3624 ZoneList<Expression*>* args = expr->arguments(); 3656 ZoneList<Expression*>* args = expr->arguments();
3625 int arg_count = args->length(); 3657 int arg_count = args->length();
3626 3658
3627 SetCallPosition(expr); 3659 SetCallPosition(expr);
3628 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 3660 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
3629 __ Set(eax, arg_count); 3661 __ Set(eax, arg_count);
3630 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), 3662 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined),
3631 RelocInfo::CODE_TARGET); 3663 RelocInfo::CODE_TARGET);
3664 OperandStackDepthDecrement(arg_count + 1);
3632 } 3665 }
3633 3666
3634 3667
3635 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 3668 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
3636 ZoneList<Expression*>* args = expr->arguments(); 3669 ZoneList<Expression*>* args = expr->arguments();
3637 int arg_count = args->length(); 3670 int arg_count = args->length();
3638 3671
3639 if (expr->is_jsruntime()) { 3672 if (expr->is_jsruntime()) {
3640 Comment cmnt(masm_, "[ CallRuntime"); 3673 Comment cmnt(masm_, "[ CallRuntime");
3641 EmitLoadJSRuntimeFunction(expr); 3674 EmitLoadJSRuntimeFunction(expr);
3642 3675
3643 // Push the target function under the receiver. 3676 // Push the target function under the receiver.
3644 __ push(Operand(esp, 0)); 3677 PushOperand(Operand(esp, 0));
3645 __ mov(Operand(esp, kPointerSize), eax); 3678 __ mov(Operand(esp, kPointerSize), eax);
3646 3679
3647 // Push the arguments ("left-to-right"). 3680 // Push the arguments ("left-to-right").
3648 for (int i = 0; i < arg_count; i++) { 3681 for (int i = 0; i < arg_count; i++) {
3649 VisitForStackValue(args->at(i)); 3682 VisitForStackValue(args->at(i));
3650 } 3683 }
3651 3684
3652 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3685 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3653 EmitCallJSRuntimeFunction(expr); 3686 EmitCallJSRuntimeFunction(expr);
3654 3687
(...skipping 14 matching lines...) Expand all
3669 default: { 3702 default: {
3670 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic"); 3703 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic");
3671 // Push the arguments ("left-to-right"). 3704 // Push the arguments ("left-to-right").
3672 for (int i = 0; i < arg_count; i++) { 3705 for (int i = 0; i < arg_count; i++) {
3673 VisitForStackValue(args->at(i)); 3706 VisitForStackValue(args->at(i));
3674 } 3707 }
3675 3708
3676 // Call the C runtime function. 3709 // Call the C runtime function.
3677 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3710 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3678 __ CallRuntime(expr->function(), arg_count); 3711 __ CallRuntime(expr->function(), arg_count);
3712 OperandStackDepthDecrement(arg_count);
3679 context()->Plug(eax); 3713 context()->Plug(eax);
3680 } 3714 }
3681 } 3715 }
3682 } 3716 }
3683 } 3717 }
3684 3718
3685 3719
3686 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3720 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
3687 switch (expr->op()) { 3721 switch (expr->op()) {
3688 case Token::DELETE: { 3722 case Token::DELETE: {
3689 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3723 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3690 Property* property = expr->expression()->AsProperty(); 3724 Property* property = expr->expression()->AsProperty();
3691 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 3725 VariableProxy* proxy = expr->expression()->AsVariableProxy();
3692 3726
3693 if (property != NULL) { 3727 if (property != NULL) {
3694 VisitForStackValue(property->obj()); 3728 VisitForStackValue(property->obj());
3695 VisitForStackValue(property->key()); 3729 VisitForStackValue(property->key());
3696 __ CallRuntime(is_strict(language_mode()) 3730 CallRuntimeWithOperands(is_strict(language_mode())
3697 ? Runtime::kDeleteProperty_Strict 3731 ? Runtime::kDeleteProperty_Strict
3698 : Runtime::kDeleteProperty_Sloppy); 3732 : Runtime::kDeleteProperty_Sloppy);
3699 context()->Plug(eax); 3733 context()->Plug(eax);
3700 } else if (proxy != NULL) { 3734 } else if (proxy != NULL) {
3701 Variable* var = proxy->var(); 3735 Variable* var = proxy->var();
3702 // Delete of an unqualified identifier is disallowed in strict mode but 3736 // Delete of an unqualified identifier is disallowed in strict mode but
3703 // "delete this" is allowed. 3737 // "delete this" is allowed.
3704 bool is_this = var->HasThisName(isolate()); 3738 bool is_this = var->HasThisName(isolate());
3705 DCHECK(is_sloppy(language_mode()) || is_this); 3739 DCHECK(is_sloppy(language_mode()) || is_this);
3706 if (var->IsUnallocatedOrGlobalSlot()) { 3740 if (var->IsUnallocatedOrGlobalSlot()) {
3707 __ mov(eax, NativeContextOperand()); 3741 __ mov(eax, NativeContextOperand());
3708 __ push(ContextOperand(eax, Context::EXTENSION_INDEX)); 3742 __ push(ContextOperand(eax, Context::EXTENSION_INDEX));
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3756 // for control and plugging the control flow into the context, 3790 // for control and plugging the control flow into the context,
3757 // because we need to prepare a pair of extra administrative AST ids 3791 // because we need to prepare a pair of extra administrative AST ids
3758 // for the optimizing compiler. 3792 // for the optimizing compiler.
3759 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); 3793 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue());
3760 Label materialize_true, materialize_false, done; 3794 Label materialize_true, materialize_false, done;
3761 VisitForControl(expr->expression(), 3795 VisitForControl(expr->expression(),
3762 &materialize_false, 3796 &materialize_false,
3763 &materialize_true, 3797 &materialize_true,
3764 &materialize_true); 3798 &materialize_true);
3765 __ bind(&materialize_true); 3799 __ bind(&materialize_true);
3800 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1);
3766 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); 3801 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS);
3767 if (context()->IsAccumulatorValue()) { 3802 if (context()->IsAccumulatorValue()) {
3768 __ mov(eax, isolate()->factory()->true_value()); 3803 __ mov(eax, isolate()->factory()->true_value());
3769 } else { 3804 } else {
3770 __ Push(isolate()->factory()->true_value()); 3805 __ Push(isolate()->factory()->true_value());
3771 } 3806 }
3772 __ jmp(&done, Label::kNear); 3807 __ jmp(&done, Label::kNear);
3773 __ bind(&materialize_false); 3808 __ bind(&materialize_false);
3774 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); 3809 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS);
3775 if (context()->IsAccumulatorValue()) { 3810 if (context()->IsAccumulatorValue()) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
3810 LhsKind assign_type = Property::GetAssignType(prop); 3845 LhsKind assign_type = Property::GetAssignType(prop);
3811 3846
3812 // Evaluate expression and get value. 3847 // Evaluate expression and get value.
3813 if (assign_type == VARIABLE) { 3848 if (assign_type == VARIABLE) {
3814 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); 3849 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL);
3815 AccumulatorValueContext context(this); 3850 AccumulatorValueContext context(this);
3816 EmitVariableLoad(expr->expression()->AsVariableProxy()); 3851 EmitVariableLoad(expr->expression()->AsVariableProxy());
3817 } else { 3852 } else {
3818 // Reserve space for result of postfix operation. 3853 // Reserve space for result of postfix operation.
3819 if (expr->is_postfix() && !context()->IsEffect()) { 3854 if (expr->is_postfix() && !context()->IsEffect()) {
3820 __ push(Immediate(Smi::FromInt(0))); 3855 PushOperand(Smi::FromInt(0));
3821 } 3856 }
3822 switch (assign_type) { 3857 switch (assign_type) {
3823 case NAMED_PROPERTY: { 3858 case NAMED_PROPERTY: {
3824 // Put the object both on the stack and in the register. 3859 // Put the object both on the stack and in the register.
3825 VisitForStackValue(prop->obj()); 3860 VisitForStackValue(prop->obj());
3826 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); 3861 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
3827 EmitNamedPropertyLoad(prop); 3862 EmitNamedPropertyLoad(prop);
3828 break; 3863 break;
3829 } 3864 }
3830 3865
3831 case NAMED_SUPER_PROPERTY: { 3866 case NAMED_SUPER_PROPERTY: {
3832 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 3867 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
3833 VisitForAccumulatorValue( 3868 VisitForAccumulatorValue(
3834 prop->obj()->AsSuperPropertyReference()->home_object()); 3869 prop->obj()->AsSuperPropertyReference()->home_object());
3835 __ push(result_register()); 3870 PushOperand(result_register());
3836 __ push(MemOperand(esp, kPointerSize)); 3871 PushOperand(MemOperand(esp, kPointerSize));
3837 __ push(result_register()); 3872 PushOperand(result_register());
3838 EmitNamedSuperPropertyLoad(prop); 3873 EmitNamedSuperPropertyLoad(prop);
3839 break; 3874 break;
3840 } 3875 }
3841 3876
3842 case KEYED_SUPER_PROPERTY: { 3877 case KEYED_SUPER_PROPERTY: {
3843 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 3878 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
3844 VisitForStackValue( 3879 VisitForStackValue(
3845 prop->obj()->AsSuperPropertyReference()->home_object()); 3880 prop->obj()->AsSuperPropertyReference()->home_object());
3846 VisitForAccumulatorValue(prop->key()); 3881 VisitForAccumulatorValue(prop->key());
3847 __ push(result_register()); 3882 PushOperand(result_register());
3848 __ push(MemOperand(esp, 2 * kPointerSize)); 3883 PushOperand(MemOperand(esp, 2 * kPointerSize));
3849 __ push(MemOperand(esp, 2 * kPointerSize)); 3884 PushOperand(MemOperand(esp, 2 * kPointerSize));
3850 __ push(result_register()); 3885 PushOperand(result_register());
3851 EmitKeyedSuperPropertyLoad(prop); 3886 EmitKeyedSuperPropertyLoad(prop);
3852 break; 3887 break;
3853 } 3888 }
3854 3889
3855 case KEYED_PROPERTY: { 3890 case KEYED_PROPERTY: {
3856 VisitForStackValue(prop->obj()); 3891 VisitForStackValue(prop->obj());
3857 VisitForStackValue(prop->key()); 3892 VisitForStackValue(prop->key());
3858 __ mov(LoadDescriptor::ReceiverRegister(), 3893 __ mov(LoadDescriptor::ReceiverRegister(),
3859 Operand(esp, kPointerSize)); // Object. 3894 Operand(esp, kPointerSize)); // Object.
3860 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); // Key. 3895 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); // Key.
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
3930 } 3965 }
3931 3966
3932 // Save result for postfix expressions. 3967 // Save result for postfix expressions.
3933 if (expr->is_postfix()) { 3968 if (expr->is_postfix()) {
3934 if (!context()->IsEffect()) { 3969 if (!context()->IsEffect()) {
3935 // Save the result on the stack. If we have a named or keyed property 3970 // Save the result on the stack. If we have a named or keyed property
3936 // we store the result under the receiver that is currently on top 3971 // we store the result under the receiver that is currently on top
3937 // of the stack. 3972 // of the stack.
3938 switch (assign_type) { 3973 switch (assign_type) {
3939 case VARIABLE: 3974 case VARIABLE:
3940 __ push(eax); 3975 PushOperand(eax);
3941 break; 3976 break;
3942 case NAMED_PROPERTY: 3977 case NAMED_PROPERTY:
3943 __ mov(Operand(esp, kPointerSize), eax); 3978 __ mov(Operand(esp, kPointerSize), eax);
3944 break; 3979 break;
3945 case NAMED_SUPER_PROPERTY: 3980 case NAMED_SUPER_PROPERTY:
3946 __ mov(Operand(esp, 2 * kPointerSize), eax); 3981 __ mov(Operand(esp, 2 * kPointerSize), eax);
3947 break; 3982 break;
3948 case KEYED_PROPERTY: 3983 case KEYED_PROPERTY:
3949 __ mov(Operand(esp, 2 * kPointerSize), eax); 3984 __ mov(Operand(esp, 2 * kPointerSize), eax);
3950 break; 3985 break;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
3990 // Perform the assignment as if via '='. 4025 // Perform the assignment as if via '='.
3991 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 4026 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3992 Token::ASSIGN, expr->CountSlot()); 4027 Token::ASSIGN, expr->CountSlot());
3993 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4028 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3994 context()->Plug(eax); 4029 context()->Plug(eax);
3995 } 4030 }
3996 break; 4031 break;
3997 case NAMED_PROPERTY: { 4032 case NAMED_PROPERTY: {
3998 __ mov(StoreDescriptor::NameRegister(), 4033 __ mov(StoreDescriptor::NameRegister(),
3999 prop->key()->AsLiteral()->value()); 4034 prop->key()->AsLiteral()->value());
4000 __ pop(StoreDescriptor::ReceiverRegister()); 4035 PopOperand(StoreDescriptor::ReceiverRegister());
4001 EmitLoadStoreICSlot(expr->CountSlot()); 4036 EmitLoadStoreICSlot(expr->CountSlot());
4002 CallStoreIC(); 4037 CallStoreIC();
4003 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4038 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4004 if (expr->is_postfix()) { 4039 if (expr->is_postfix()) {
4005 if (!context()->IsEffect()) { 4040 if (!context()->IsEffect()) {
4006 context()->PlugTOS(); 4041 context()->PlugTOS();
4007 } 4042 }
4008 } else { 4043 } else {
4009 context()->Plug(eax); 4044 context()->Plug(eax);
4010 } 4045 }
(...skipping 15 matching lines...) Expand all
4026 if (expr->is_postfix()) { 4061 if (expr->is_postfix()) {
4027 if (!context()->IsEffect()) { 4062 if (!context()->IsEffect()) {
4028 context()->PlugTOS(); 4063 context()->PlugTOS();
4029 } 4064 }
4030 } else { 4065 } else {
4031 context()->Plug(eax); 4066 context()->Plug(eax);
4032 } 4067 }
4033 break; 4068 break;
4034 } 4069 }
4035 case KEYED_PROPERTY: { 4070 case KEYED_PROPERTY: {
4036 __ pop(StoreDescriptor::NameRegister()); 4071 PopOperand(StoreDescriptor::NameRegister());
4037 __ pop(StoreDescriptor::ReceiverRegister()); 4072 PopOperand(StoreDescriptor::ReceiverRegister());
4038 Handle<Code> ic = 4073 Handle<Code> ic =
4039 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 4074 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
4040 EmitLoadStoreICSlot(expr->CountSlot()); 4075 EmitLoadStoreICSlot(expr->CountSlot());
4041 CallIC(ic); 4076 CallIC(ic);
4042 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4077 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4043 if (expr->is_postfix()) { 4078 if (expr->is_postfix()) {
4044 // Result is on the stack 4079 // Result is on the stack
4045 if (!context()->IsEffect()) { 4080 if (!context()->IsEffect()) {
4046 context()->PlugTOS(); 4081 context()->PlugTOS();
4047 } 4082 }
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
4148 Label* if_false = NULL; 4183 Label* if_false = NULL;
4149 Label* fall_through = NULL; 4184 Label* fall_through = NULL;
4150 context()->PrepareTest(&materialize_true, &materialize_false, 4185 context()->PrepareTest(&materialize_true, &materialize_false,
4151 &if_true, &if_false, &fall_through); 4186 &if_true, &if_false, &fall_through);
4152 4187
4153 Token::Value op = expr->op(); 4188 Token::Value op = expr->op();
4154 VisitForStackValue(expr->left()); 4189 VisitForStackValue(expr->left());
4155 switch (op) { 4190 switch (op) {
4156 case Token::IN: 4191 case Token::IN:
4157 VisitForStackValue(expr->right()); 4192 VisitForStackValue(expr->right());
4158 __ CallRuntime(Runtime::kHasProperty); 4193 CallRuntimeWithOperands(Runtime::kHasProperty);
4159 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 4194 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
4160 __ cmp(eax, isolate()->factory()->true_value()); 4195 __ cmp(eax, isolate()->factory()->true_value());
4161 Split(equal, if_true, if_false, fall_through); 4196 Split(equal, if_true, if_false, fall_through);
4162 break; 4197 break;
4163 4198
4164 case Token::INSTANCEOF: { 4199 case Token::INSTANCEOF: {
4165 VisitForAccumulatorValue(expr->right()); 4200 VisitForAccumulatorValue(expr->right());
4166 __ Pop(edx); 4201 PopOperand(edx);
4167 InstanceOfStub stub(isolate()); 4202 InstanceOfStub stub(isolate());
4168 __ CallStub(&stub); 4203 __ CallStub(&stub);
4169 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 4204 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
4170 __ cmp(eax, isolate()->factory()->true_value()); 4205 __ cmp(eax, isolate()->factory()->true_value());
4171 Split(equal, if_true, if_false, fall_through); 4206 Split(equal, if_true, if_false, fall_through);
4172 break; 4207 break;
4173 } 4208 }
4174 4209
4175 default: { 4210 default: {
4176 VisitForAccumulatorValue(expr->right()); 4211 VisitForAccumulatorValue(expr->right());
4177 Condition cc = CompareIC::ComputeCondition(op); 4212 Condition cc = CompareIC::ComputeCondition(op);
4178 __ pop(edx); 4213 PopOperand(edx);
4179 4214
4180 bool inline_smi_code = ShouldInlineSmiCase(op); 4215 bool inline_smi_code = ShouldInlineSmiCase(op);
4181 JumpPatchSite patch_site(masm_); 4216 JumpPatchSite patch_site(masm_);
4182 if (inline_smi_code) { 4217 if (inline_smi_code) {
4183 Label slow_case; 4218 Label slow_case;
4184 __ mov(ecx, edx); 4219 __ mov(ecx, edx);
4185 __ or_(ecx, eax); 4220 __ or_(ecx, eax);
4186 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); 4221 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear);
4187 __ cmp(edx, eax); 4222 __ cmp(edx, eax);
4188 Split(cc, if_true, if_false, NULL); 4223 Split(cc, if_true, if_false, NULL);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
4262 4297
4263 4298
4264 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() { 4299 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
4265 Scope* closure_scope = scope()->ClosureScope(); 4300 Scope* closure_scope = scope()->ClosureScope();
4266 if (closure_scope->is_script_scope() || 4301 if (closure_scope->is_script_scope() ||
4267 closure_scope->is_module_scope()) { 4302 closure_scope->is_module_scope()) {
4268 // Contexts nested in the native context have a canonical empty function 4303 // Contexts nested in the native context have a canonical empty function
4269 // as their closure, not the anonymous closure containing the global 4304 // as their closure, not the anonymous closure containing the global
4270 // code. 4305 // code.
4271 __ mov(eax, NativeContextOperand()); 4306 __ mov(eax, NativeContextOperand());
4272 __ push(ContextOperand(eax, Context::CLOSURE_INDEX)); 4307 PushOperand(ContextOperand(eax, Context::CLOSURE_INDEX));
4273 } else if (closure_scope->is_eval_scope()) { 4308 } else if (closure_scope->is_eval_scope()) {
4274 // Contexts nested inside eval code have the same closure as the context 4309 // Contexts nested inside eval code have the same closure as the context
4275 // calling eval, not the anonymous closure containing the eval code. 4310 // calling eval, not the anonymous closure containing the eval code.
4276 // Fetch it from the context. 4311 // Fetch it from the context.
4277 __ push(ContextOperand(esi, Context::CLOSURE_INDEX)); 4312 PushOperand(ContextOperand(esi, Context::CLOSURE_INDEX));
4278 } else { 4313 } else {
4279 DCHECK(closure_scope->is_function_scope()); 4314 DCHECK(closure_scope->is_function_scope());
4280 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 4315 PushOperand(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
4281 } 4316 }
4282 } 4317 }
4283 4318
4284 4319
4285 // ---------------------------------------------------------------------------- 4320 // ----------------------------------------------------------------------------
4286 // Non-local control flow support. 4321 // Non-local control flow support.
4287 4322
4288 void FullCodeGenerator::EnterFinallyBlock() { 4323 void FullCodeGenerator::EnterFinallyBlock() {
4289 // Store pending message while executing finally block. 4324 // Store pending message while executing finally block.
4290 ExternalReference pending_message_obj = 4325 ExternalReference pending_message_obj =
4291 ExternalReference::address_of_pending_message_obj(isolate()); 4326 ExternalReference::address_of_pending_message_obj(isolate());
4292 __ mov(edx, Operand::StaticVariable(pending_message_obj)); 4327 __ mov(edx, Operand::StaticVariable(pending_message_obj));
4293 __ push(edx); 4328 PushOperand(edx);
4294 4329
4295 ClearPendingMessage(); 4330 ClearPendingMessage();
4296 } 4331 }
4297 4332
4298 4333
4299 void FullCodeGenerator::ExitFinallyBlock() { 4334 void FullCodeGenerator::ExitFinallyBlock() {
4300 DCHECK(!result_register().is(edx)); 4335 DCHECK(!result_register().is(edx));
4301 // Restore pending message from stack. 4336 // Restore pending message from stack.
4302 __ pop(edx); 4337 PopOperand(edx);
4303 ExternalReference pending_message_obj = 4338 ExternalReference pending_message_obj =
4304 ExternalReference::address_of_pending_message_obj(isolate()); 4339 ExternalReference::address_of_pending_message_obj(isolate());
4305 __ mov(Operand::StaticVariable(pending_message_obj), edx); 4340 __ mov(Operand::StaticVariable(pending_message_obj), edx);
4306 } 4341 }
4307 4342
4308 4343
4309 void FullCodeGenerator::ClearPendingMessage() { 4344 void FullCodeGenerator::ClearPendingMessage() {
4310 DCHECK(!result_register().is(edx)); 4345 DCHECK(!result_register().is(edx));
4311 ExternalReference pending_message_obj = 4346 ExternalReference pending_message_obj =
4312 ExternalReference::address_of_pending_message_obj(isolate()); 4347 ExternalReference::address_of_pending_message_obj(isolate());
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
4425 Assembler::target_address_at(call_target_address, 4460 Assembler::target_address_at(call_target_address,
4426 unoptimized_code)); 4461 unoptimized_code));
4427 return OSR_AFTER_STACK_CHECK; 4462 return OSR_AFTER_STACK_CHECK;
4428 } 4463 }
4429 4464
4430 4465
4431 } // namespace internal 4466 } // namespace internal
4432 } // namespace v8 4467 } // namespace v8
4433 4468
4434 #endif // V8_TARGET_ARCH_IA32 4469 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698