OLD | NEW |
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_MIPS | 5 #if V8_TARGET_ARCH_MIPS |
6 | 6 |
7 // Note on Mips implementation: | 7 // Note on Mips implementation: |
8 // | 8 // |
9 // The result_register() for mips is the 'v0' register, which is defined | 9 // The result_register() for mips is the 'v0' register, which is defined |
10 // by the ABI to contain function return values. However, the first | 10 // by the ABI to contain function return values. However, the first |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 // the frame (that is done below). | 132 // the frame (that is done below). |
133 FrameScope frame_scope(masm_, StackFrame::MANUAL); | 133 FrameScope frame_scope(masm_, StackFrame::MANUAL); |
134 | 134 |
135 info->set_prologue_offset(masm_->pc_offset()); | 135 info->set_prologue_offset(masm_->pc_offset()); |
136 __ Prologue(info->GeneratePreagedPrologue()); | 136 __ Prologue(info->GeneratePreagedPrologue()); |
137 | 137 |
138 { Comment cmnt(masm_, "[ Allocate locals"); | 138 { Comment cmnt(masm_, "[ Allocate locals"); |
139 int locals_count = info->scope()->num_stack_slots(); | 139 int locals_count = info->scope()->num_stack_slots(); |
140 // Generators allocate locals, if any, in context slots. | 140 // Generators allocate locals, if any, in context slots. |
141 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0); | 141 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0); |
| 142 OperandStackDepthIncrement(locals_count); |
142 if (locals_count > 0) { | 143 if (locals_count > 0) { |
143 if (locals_count >= 128) { | 144 if (locals_count >= 128) { |
144 Label ok; | 145 Label ok; |
145 __ Subu(t5, sp, Operand(locals_count * kPointerSize)); | 146 __ Subu(t5, sp, Operand(locals_count * kPointerSize)); |
146 __ LoadRoot(a2, Heap::kRealStackLimitRootIndex); | 147 __ LoadRoot(a2, Heap::kRealStackLimitRootIndex); |
147 __ Branch(&ok, hs, t5, Operand(a2)); | 148 __ Branch(&ok, hs, t5, Operand(a2)); |
148 __ CallRuntime(Runtime::kThrowStackOverflow); | 149 __ CallRuntime(Runtime::kThrowStackOverflow); |
149 __ bind(&ok); | 150 __ bind(&ok); |
150 } | 151 } |
151 __ LoadRoot(t5, Heap::kUndefinedValueRootIndex); | 152 __ LoadRoot(t5, Heap::kUndefinedValueRootIndex); |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 masm_->Addu(sp, sp, Operand(sp_delta)); | 459 masm_->Addu(sp, sp, Operand(sp_delta)); |
459 masm_->Jump(ra); | 460 masm_->Jump(ra); |
460 } | 461 } |
461 } | 462 } |
462 } | 463 } |
463 | 464 |
464 | 465 |
465 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { | 466 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { |
466 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 467 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
467 codegen()->GetVar(result_register(), var); | 468 codegen()->GetVar(result_register(), var); |
468 __ push(result_register()); | 469 codegen()->PushOperand(result_register()); |
469 } | 470 } |
470 | 471 |
471 | 472 |
472 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { | 473 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { |
473 } | 474 } |
474 | 475 |
475 | 476 |
476 void FullCodeGenerator::AccumulatorValueContext::Plug( | 477 void FullCodeGenerator::AccumulatorValueContext::Plug( |
477 Heap::RootListIndex index) const { | 478 Heap::RootListIndex index) const { |
478 __ LoadRoot(result_register(), index); | 479 __ LoadRoot(result_register(), index); |
479 } | 480 } |
480 | 481 |
481 | 482 |
482 void FullCodeGenerator::StackValueContext::Plug( | 483 void FullCodeGenerator::StackValueContext::Plug( |
483 Heap::RootListIndex index) const { | 484 Heap::RootListIndex index) const { |
484 __ LoadRoot(result_register(), index); | 485 __ LoadRoot(result_register(), index); |
485 __ push(result_register()); | 486 codegen()->PushOperand(result_register()); |
486 } | 487 } |
487 | 488 |
488 | 489 |
489 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const { | 490 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const { |
490 codegen()->PrepareForBailoutBeforeSplit(condition(), | 491 codegen()->PrepareForBailoutBeforeSplit(condition(), |
491 true, | 492 true, |
492 true_label_, | 493 true_label_, |
493 false_label_); | 494 false_label_); |
494 if (index == Heap::kUndefinedValueRootIndex || | 495 if (index == Heap::kUndefinedValueRootIndex || |
495 index == Heap::kNullValueRootIndex || | 496 index == Heap::kNullValueRootIndex || |
(...skipping 14 matching lines...) Expand all Loading... |
510 | 511 |
511 void FullCodeGenerator::AccumulatorValueContext::Plug( | 512 void FullCodeGenerator::AccumulatorValueContext::Plug( |
512 Handle<Object> lit) const { | 513 Handle<Object> lit) const { |
513 __ li(result_register(), Operand(lit)); | 514 __ li(result_register(), Operand(lit)); |
514 } | 515 } |
515 | 516 |
516 | 517 |
517 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { | 518 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { |
518 // Immediates cannot be pushed directly. | 519 // Immediates cannot be pushed directly. |
519 __ li(result_register(), Operand(lit)); | 520 __ li(result_register(), Operand(lit)); |
520 __ push(result_register()); | 521 codegen()->PushOperand(result_register()); |
521 } | 522 } |
522 | 523 |
523 | 524 |
524 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { | 525 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { |
525 codegen()->PrepareForBailoutBeforeSplit(condition(), | 526 codegen()->PrepareForBailoutBeforeSplit(condition(), |
526 true, | 527 true, |
527 true_label_, | 528 true_label_, |
528 false_label_); | 529 false_label_); |
529 DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectableObject()); | 530 DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectableObject()); |
530 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) { | 531 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) { |
(...skipping 13 matching lines...) Expand all Loading... |
544 if (true_label_ != fall_through_) __ Branch(true_label_); | 545 if (true_label_ != fall_through_) __ Branch(true_label_); |
545 } | 546 } |
546 } else { | 547 } else { |
547 // For simplicity we always test the accumulator register. | 548 // For simplicity we always test the accumulator register. |
548 __ li(result_register(), Operand(lit)); | 549 __ li(result_register(), Operand(lit)); |
549 codegen()->DoTest(this); | 550 codegen()->DoTest(this); |
550 } | 551 } |
551 } | 552 } |
552 | 553 |
553 | 554 |
554 void FullCodeGenerator::EffectContext::DropAndPlug(int count, | |
555 Register reg) const { | |
556 DCHECK(count > 0); | |
557 __ Drop(count); | |
558 } | |
559 | |
560 | |
561 void FullCodeGenerator::AccumulatorValueContext::DropAndPlug( | |
562 int count, | |
563 Register reg) const { | |
564 DCHECK(count > 0); | |
565 __ Drop(count); | |
566 __ Move(result_register(), reg); | |
567 } | |
568 | |
569 | |
570 void FullCodeGenerator::StackValueContext::DropAndPlug(int count, | 555 void FullCodeGenerator::StackValueContext::DropAndPlug(int count, |
571 Register reg) const { | 556 Register reg) const { |
572 DCHECK(count > 0); | 557 DCHECK(count > 0); |
573 if (count > 1) __ Drop(count - 1); | 558 if (count > 1) codegen()->DropOperands(count - 1); |
574 __ sw(reg, MemOperand(sp, 0)); | 559 __ sw(reg, MemOperand(sp, 0)); |
575 } | 560 } |
576 | 561 |
577 | 562 |
578 void FullCodeGenerator::TestContext::DropAndPlug(int count, | |
579 Register reg) const { | |
580 DCHECK(count > 0); | |
581 // For simplicity we always test the accumulator register. | |
582 __ Drop(count); | |
583 __ Move(result_register(), reg); | |
584 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); | |
585 codegen()->DoTest(this); | |
586 } | |
587 | |
588 | |
589 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, | 563 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, |
590 Label* materialize_false) const { | 564 Label* materialize_false) const { |
591 DCHECK(materialize_true == materialize_false); | 565 DCHECK(materialize_true == materialize_false); |
592 __ bind(materialize_true); | 566 __ bind(materialize_true); |
593 } | 567 } |
594 | 568 |
595 | 569 |
596 void FullCodeGenerator::AccumulatorValueContext::Plug( | 570 void FullCodeGenerator::AccumulatorValueContext::Plug( |
597 Label* materialize_true, | 571 Label* materialize_true, |
598 Label* materialize_false) const { | 572 Label* materialize_false) const { |
599 Label done; | 573 Label done; |
600 __ bind(materialize_true); | 574 __ bind(materialize_true); |
601 __ LoadRoot(result_register(), Heap::kTrueValueRootIndex); | 575 __ LoadRoot(result_register(), Heap::kTrueValueRootIndex); |
602 __ Branch(&done); | 576 __ Branch(&done); |
603 __ bind(materialize_false); | 577 __ bind(materialize_false); |
604 __ LoadRoot(result_register(), Heap::kFalseValueRootIndex); | 578 __ LoadRoot(result_register(), Heap::kFalseValueRootIndex); |
605 __ bind(&done); | 579 __ bind(&done); |
606 } | 580 } |
607 | 581 |
608 | 582 |
609 void FullCodeGenerator::StackValueContext::Plug( | 583 void FullCodeGenerator::StackValueContext::Plug( |
610 Label* materialize_true, | 584 Label* materialize_true, |
611 Label* materialize_false) const { | 585 Label* materialize_false) const { |
| 586 codegen()->OperandStackDepthIncrement(1); |
612 Label done; | 587 Label done; |
613 __ bind(materialize_true); | 588 __ bind(materialize_true); |
614 __ LoadRoot(at, Heap::kTrueValueRootIndex); | 589 __ LoadRoot(at, Heap::kTrueValueRootIndex); |
615 // Push the value as the following branch can clobber at in long branch mode. | 590 // Push the value as the following branch can clobber at in long branch mode. |
616 __ push(at); | 591 __ push(at); |
617 __ Branch(&done); | 592 __ Branch(&done); |
618 __ bind(materialize_false); | 593 __ bind(materialize_false); |
619 __ LoadRoot(at, Heap::kFalseValueRootIndex); | 594 __ LoadRoot(at, Heap::kFalseValueRootIndex); |
620 __ push(at); | 595 __ push(at); |
621 __ bind(&done); | 596 __ bind(&done); |
(...skipping 11 matching lines...) Expand all Loading... |
633 Heap::RootListIndex value_root_index = | 608 Heap::RootListIndex value_root_index = |
634 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 609 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
635 __ LoadRoot(result_register(), value_root_index); | 610 __ LoadRoot(result_register(), value_root_index); |
636 } | 611 } |
637 | 612 |
638 | 613 |
639 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { | 614 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { |
640 Heap::RootListIndex value_root_index = | 615 Heap::RootListIndex value_root_index = |
641 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 616 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
642 __ LoadRoot(at, value_root_index); | 617 __ LoadRoot(at, value_root_index); |
643 __ push(at); | 618 codegen()->PushOperand(at); |
644 } | 619 } |
645 | 620 |
646 | 621 |
647 void FullCodeGenerator::TestContext::Plug(bool flag) const { | 622 void FullCodeGenerator::TestContext::Plug(bool flag) const { |
648 codegen()->PrepareForBailoutBeforeSplit(condition(), | 623 codegen()->PrepareForBailoutBeforeSplit(condition(), |
649 true, | 624 true, |
650 true_label_, | 625 true_label_, |
651 false_label_); | 626 false_label_); |
652 if (flag) { | 627 if (flag) { |
653 if (true_label_ != fall_through_) __ Branch(true_label_); | 628 if (true_label_ != fall_through_) __ Branch(true_label_); |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
880 kDontSaveFPRegs, | 855 kDontSaveFPRegs, |
881 EMIT_REMEMBERED_SET, | 856 EMIT_REMEMBERED_SET, |
882 OMIT_SMI_CHECK); | 857 OMIT_SMI_CHECK); |
883 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); | 858 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); |
884 break; | 859 break; |
885 } | 860 } |
886 | 861 |
887 case VariableLocation::LOOKUP: { | 862 case VariableLocation::LOOKUP: { |
888 Comment cmnt(masm_, "[ FunctionDeclaration"); | 863 Comment cmnt(masm_, "[ FunctionDeclaration"); |
889 __ li(a2, Operand(variable->name())); | 864 __ li(a2, Operand(variable->name())); |
890 __ Push(a2); | 865 PushOperand(a2); |
891 // Push initial value for function declaration. | 866 // Push initial value for function declaration. |
892 VisitForStackValue(declaration->fun()); | 867 VisitForStackValue(declaration->fun()); |
893 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); | 868 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes())); |
894 __ CallRuntime(Runtime::kDeclareLookupSlot); | 869 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot); |
895 break; | 870 break; |
896 } | 871 } |
897 } | 872 } |
898 } | 873 } |
899 | 874 |
900 | 875 |
901 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 876 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
902 // Call the runtime to declare the globals. | 877 // Call the runtime to declare the globals. |
903 __ li(a1, Operand(pairs)); | 878 __ li(a1, Operand(pairs)); |
904 __ li(a0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); | 879 __ li(a0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
981 __ bind(&skip); | 956 __ bind(&skip); |
982 | 957 |
983 __ Branch(&next_test, ne, v0, Operand(zero_reg)); | 958 __ Branch(&next_test, ne, v0, Operand(zero_reg)); |
984 __ Drop(1); // Switch value is no longer needed. | 959 __ Drop(1); // Switch value is no longer needed. |
985 __ Branch(clause->body_target()); | 960 __ Branch(clause->body_target()); |
986 } | 961 } |
987 | 962 |
988 // Discard the test value and jump to the default if present, otherwise to | 963 // Discard the test value and jump to the default if present, otherwise to |
989 // the end of the statement. | 964 // the end of the statement. |
990 __ bind(&next_test); | 965 __ bind(&next_test); |
991 __ Drop(1); // Switch value is no longer needed. | 966 DropOperands(1); // Switch value is no longer needed. |
992 if (default_clause == NULL) { | 967 if (default_clause == NULL) { |
993 __ Branch(nested_statement.break_label()); | 968 __ Branch(nested_statement.break_label()); |
994 } else { | 969 } else { |
995 __ Branch(default_clause->body_target()); | 970 __ Branch(default_clause->body_target()); |
996 } | 971 } |
997 | 972 |
998 // Compile all the case bodies. | 973 // Compile all the case bodies. |
999 for (int i = 0; i < clauses->length(); i++) { | 974 for (int i = 0; i < clauses->length(); i++) { |
1000 Comment cmnt(masm_, "[ Case body"); | 975 Comment cmnt(masm_, "[ Case body"); |
1001 CaseClause* clause = clauses->at(i); | 976 CaseClause* clause = clauses->at(i); |
(...skipping 14 matching lines...) Expand all Loading... |
1016 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); | 991 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); |
1017 | 992 |
1018 Label loop, exit; | 993 Label loop, exit; |
1019 ForIn loop_statement(this, stmt); | 994 ForIn loop_statement(this, stmt); |
1020 increment_loop_depth(); | 995 increment_loop_depth(); |
1021 | 996 |
1022 // Get the object to enumerate over. | 997 // Get the object to enumerate over. |
1023 SetExpressionAsStatementPosition(stmt->enumerable()); | 998 SetExpressionAsStatementPosition(stmt->enumerable()); |
1024 VisitForAccumulatorValue(stmt->enumerable()); | 999 VisitForAccumulatorValue(stmt->enumerable()); |
1025 __ mov(a0, result_register()); | 1000 __ mov(a0, result_register()); |
| 1001 OperandStackDepthIncrement(ForIn::kElementCount); |
1026 | 1002 |
1027 // If the object is null or undefined, skip over the loop, otherwise convert | 1003 // If the object is null or undefined, skip over the loop, otherwise convert |
1028 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. | 1004 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. |
1029 Label convert, done_convert; | 1005 Label convert, done_convert; |
1030 __ JumpIfSmi(a0, &convert); | 1006 __ JumpIfSmi(a0, &convert); |
1031 __ GetObjectType(a0, a1, a1); | 1007 __ GetObjectType(a0, a1, a1); |
1032 __ Branch(USE_DELAY_SLOT, &done_convert, ge, a1, | 1008 __ Branch(USE_DELAY_SLOT, &done_convert, ge, a1, |
1033 Operand(FIRST_JS_RECEIVER_TYPE)); | 1009 Operand(FIRST_JS_RECEIVER_TYPE)); |
1034 __ LoadRoot(at, Heap::kNullValueRootIndex); // In delay slot. | 1010 __ LoadRoot(at, Heap::kNullValueRootIndex); // In delay slot. |
1035 __ Branch(USE_DELAY_SLOT, &exit, eq, a0, Operand(at)); | 1011 __ Branch(USE_DELAY_SLOT, &exit, eq, a0, Operand(at)); |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1175 __ bind(loop_statement.continue_label()); | 1151 __ bind(loop_statement.continue_label()); |
1176 __ pop(a0); | 1152 __ pop(a0); |
1177 __ Addu(a0, a0, Operand(Smi::FromInt(1))); | 1153 __ Addu(a0, a0, Operand(Smi::FromInt(1))); |
1178 __ push(a0); | 1154 __ push(a0); |
1179 | 1155 |
1180 EmitBackEdgeBookkeeping(stmt, &loop); | 1156 EmitBackEdgeBookkeeping(stmt, &loop); |
1181 __ Branch(&loop); | 1157 __ Branch(&loop); |
1182 | 1158 |
1183 // Remove the pointers stored on the stack. | 1159 // Remove the pointers stored on the stack. |
1184 __ bind(loop_statement.break_label()); | 1160 __ bind(loop_statement.break_label()); |
1185 __ Drop(5); | 1161 DropOperands(5); |
1186 | 1162 |
1187 // Exit and decrement the loop depth. | 1163 // Exit and decrement the loop depth. |
1188 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 1164 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
1189 __ bind(&exit); | 1165 __ bind(&exit); |
1190 decrement_loop_depth(); | 1166 decrement_loop_depth(); |
1191 } | 1167 } |
1192 | 1168 |
1193 | 1169 |
1194 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, | 1170 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, |
1195 bool pretenure) { | 1171 bool pretenure) { |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1451 FastCloneRegExpStub stub(isolate()); | 1427 FastCloneRegExpStub stub(isolate()); |
1452 __ CallStub(&stub); | 1428 __ CallStub(&stub); |
1453 context()->Plug(v0); | 1429 context()->Plug(v0); |
1454 } | 1430 } |
1455 | 1431 |
1456 | 1432 |
1457 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { | 1433 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { |
1458 Expression* expression = (property == NULL) ? NULL : property->value(); | 1434 Expression* expression = (property == NULL) ? NULL : property->value(); |
1459 if (expression == NULL) { | 1435 if (expression == NULL) { |
1460 __ LoadRoot(a1, Heap::kNullValueRootIndex); | 1436 __ LoadRoot(a1, Heap::kNullValueRootIndex); |
1461 __ push(a1); | 1437 PushOperand(a1); |
1462 } else { | 1438 } else { |
1463 VisitForStackValue(expression); | 1439 VisitForStackValue(expression); |
1464 if (NeedsHomeObject(expression)) { | 1440 if (NeedsHomeObject(expression)) { |
1465 DCHECK(property->kind() == ObjectLiteral::Property::GETTER || | 1441 DCHECK(property->kind() == ObjectLiteral::Property::GETTER || |
1466 property->kind() == ObjectLiteral::Property::SETTER); | 1442 property->kind() == ObjectLiteral::Property::SETTER); |
1467 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3; | 1443 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3; |
1468 EmitSetHomeObject(expression, offset, property->GetSlot()); | 1444 EmitSetHomeObject(expression, offset, property->GetSlot()); |
1469 } | 1445 } |
1470 } | 1446 } |
1471 } | 1447 } |
(...skipping 23 matching lines...) Expand all Loading... |
1495 AccessorTable accessor_table(zone()); | 1471 AccessorTable accessor_table(zone()); |
1496 int property_index = 0; | 1472 int property_index = 0; |
1497 for (; property_index < expr->properties()->length(); property_index++) { | 1473 for (; property_index < expr->properties()->length(); property_index++) { |
1498 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1474 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
1499 if (property->is_computed_name()) break; | 1475 if (property->is_computed_name()) break; |
1500 if (property->IsCompileTimeValue()) continue; | 1476 if (property->IsCompileTimeValue()) continue; |
1501 | 1477 |
1502 Literal* key = property->key()->AsLiteral(); | 1478 Literal* key = property->key()->AsLiteral(); |
1503 Expression* value = property->value(); | 1479 Expression* value = property->value(); |
1504 if (!result_saved) { | 1480 if (!result_saved) { |
1505 __ push(v0); // Save result on stack. | 1481 PushOperand(v0); // Save result on stack. |
1506 result_saved = true; | 1482 result_saved = true; |
1507 } | 1483 } |
1508 switch (property->kind()) { | 1484 switch (property->kind()) { |
1509 case ObjectLiteral::Property::CONSTANT: | 1485 case ObjectLiteral::Property::CONSTANT: |
1510 UNREACHABLE(); | 1486 UNREACHABLE(); |
1511 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1487 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1512 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1488 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); |
1513 // Fall through. | 1489 // Fall through. |
1514 case ObjectLiteral::Property::COMPUTED: | 1490 case ObjectLiteral::Property::COMPUTED: |
1515 // It is safe to use [[Put]] here because the boilerplate already | 1491 // It is safe to use [[Put]] here because the boilerplate already |
(...skipping 12 matching lines...) Expand all Loading... |
1528 if (NeedsHomeObject(value)) { | 1504 if (NeedsHomeObject(value)) { |
1529 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); | 1505 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); |
1530 } | 1506 } |
1531 } else { | 1507 } else { |
1532 VisitForEffect(value); | 1508 VisitForEffect(value); |
1533 } | 1509 } |
1534 break; | 1510 break; |
1535 } | 1511 } |
1536 // Duplicate receiver on stack. | 1512 // Duplicate receiver on stack. |
1537 __ lw(a0, MemOperand(sp)); | 1513 __ lw(a0, MemOperand(sp)); |
1538 __ push(a0); | 1514 PushOperand(a0); |
1539 VisitForStackValue(key); | 1515 VisitForStackValue(key); |
1540 VisitForStackValue(value); | 1516 VisitForStackValue(value); |
1541 if (property->emit_store()) { | 1517 if (property->emit_store()) { |
1542 if (NeedsHomeObject(value)) { | 1518 if (NeedsHomeObject(value)) { |
1543 EmitSetHomeObject(value, 2, property->GetSlot()); | 1519 EmitSetHomeObject(value, 2, property->GetSlot()); |
1544 } | 1520 } |
1545 __ li(a0, Operand(Smi::FromInt(SLOPPY))); // PropertyAttributes. | 1521 __ li(a0, Operand(Smi::FromInt(SLOPPY))); // PropertyAttributes. |
1546 __ push(a0); | 1522 PushOperand(a0); |
1547 __ CallRuntime(Runtime::kSetProperty); | 1523 CallRuntimeWithOperands(Runtime::kSetProperty); |
1548 } else { | 1524 } else { |
1549 __ Drop(3); | 1525 DropOperands(3); |
1550 } | 1526 } |
1551 break; | 1527 break; |
1552 case ObjectLiteral::Property::PROTOTYPE: | 1528 case ObjectLiteral::Property::PROTOTYPE: |
1553 // Duplicate receiver on stack. | 1529 // Duplicate receiver on stack. |
1554 __ lw(a0, MemOperand(sp)); | 1530 __ lw(a0, MemOperand(sp)); |
1555 __ push(a0); | 1531 PushOperand(a0); |
1556 VisitForStackValue(value); | 1532 VisitForStackValue(value); |
1557 DCHECK(property->emit_store()); | 1533 DCHECK(property->emit_store()); |
1558 __ CallRuntime(Runtime::kInternalSetPrototype); | 1534 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); |
1559 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), | 1535 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), |
1560 NO_REGISTERS); | 1536 NO_REGISTERS); |
1561 break; | 1537 break; |
1562 case ObjectLiteral::Property::GETTER: | 1538 case ObjectLiteral::Property::GETTER: |
1563 if (property->emit_store()) { | 1539 if (property->emit_store()) { |
1564 accessor_table.lookup(key)->second->getter = property; | 1540 accessor_table.lookup(key)->second->getter = property; |
1565 } | 1541 } |
1566 break; | 1542 break; |
1567 case ObjectLiteral::Property::SETTER: | 1543 case ObjectLiteral::Property::SETTER: |
1568 if (property->emit_store()) { | 1544 if (property->emit_store()) { |
1569 accessor_table.lookup(key)->second->setter = property; | 1545 accessor_table.lookup(key)->second->setter = property; |
1570 } | 1546 } |
1571 break; | 1547 break; |
1572 } | 1548 } |
1573 } | 1549 } |
1574 | 1550 |
1575 // Emit code to define accessors, using only a single call to the runtime for | 1551 // Emit code to define accessors, using only a single call to the runtime for |
1576 // each pair of corresponding getters and setters. | 1552 // each pair of corresponding getters and setters. |
1577 for (AccessorTable::Iterator it = accessor_table.begin(); | 1553 for (AccessorTable::Iterator it = accessor_table.begin(); |
1578 it != accessor_table.end(); | 1554 it != accessor_table.end(); |
1579 ++it) { | 1555 ++it) { |
1580 __ lw(a0, MemOperand(sp)); // Duplicate receiver. | 1556 __ lw(a0, MemOperand(sp)); // Duplicate receiver. |
1581 __ push(a0); | 1557 PushOperand(a0); |
1582 VisitForStackValue(it->first); | 1558 VisitForStackValue(it->first); |
1583 EmitAccessor(it->second->getter); | 1559 EmitAccessor(it->second->getter); |
1584 EmitAccessor(it->second->setter); | 1560 EmitAccessor(it->second->setter); |
1585 __ li(a0, Operand(Smi::FromInt(NONE))); | 1561 __ li(a0, Operand(Smi::FromInt(NONE))); |
1586 __ push(a0); | 1562 PushOperand(a0); |
1587 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked); | 1563 CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked); |
1588 } | 1564 } |
1589 | 1565 |
1590 // Object literals have two parts. The "static" part on the left contains no | 1566 // Object literals have two parts. The "static" part on the left contains no |
1591 // computed property names, and so we can compute its map ahead of time; see | 1567 // computed property names, and so we can compute its map ahead of time; see |
1592 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part | 1568 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part |
1593 // starts with the first computed property name, and continues with all | 1569 // starts with the first computed property name, and continues with all |
1594 // properties to its right. All the code from above initializes the static | 1570 // properties to its right. All the code from above initializes the static |
1595 // component of the object literal, and arranges for the map of the result to | 1571 // component of the object literal, and arranges for the map of the result to |
1596 // reflect the static order in which the keys appear. For the dynamic | 1572 // reflect the static order in which the keys appear. For the dynamic |
1597 // properties, we compile them into a series of "SetOwnProperty" runtime | 1573 // properties, we compile them into a series of "SetOwnProperty" runtime |
1598 // calls. This will preserve insertion order. | 1574 // calls. This will preserve insertion order. |
1599 for (; property_index < expr->properties()->length(); property_index++) { | 1575 for (; property_index < expr->properties()->length(); property_index++) { |
1600 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1576 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
1601 | 1577 |
1602 Expression* value = property->value(); | 1578 Expression* value = property->value(); |
1603 if (!result_saved) { | 1579 if (!result_saved) { |
1604 __ push(v0); // Save result on the stack | 1580 PushOperand(v0); // Save result on the stack |
1605 result_saved = true; | 1581 result_saved = true; |
1606 } | 1582 } |
1607 | 1583 |
1608 __ lw(a0, MemOperand(sp)); // Duplicate receiver. | 1584 __ lw(a0, MemOperand(sp)); // Duplicate receiver. |
1609 __ push(a0); | 1585 PushOperand(a0); |
1610 | 1586 |
1611 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { | 1587 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { |
1612 DCHECK(!property->is_computed_name()); | 1588 DCHECK(!property->is_computed_name()); |
1613 VisitForStackValue(value); | 1589 VisitForStackValue(value); |
1614 DCHECK(property->emit_store()); | 1590 DCHECK(property->emit_store()); |
1615 __ CallRuntime(Runtime::kInternalSetPrototype); | 1591 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); |
1616 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), | 1592 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), |
1617 NO_REGISTERS); | 1593 NO_REGISTERS); |
1618 } else { | 1594 } else { |
1619 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); | 1595 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); |
1620 VisitForStackValue(value); | 1596 VisitForStackValue(value); |
1621 if (NeedsHomeObject(value)) { | 1597 if (NeedsHomeObject(value)) { |
1622 EmitSetHomeObject(value, 2, property->GetSlot()); | 1598 EmitSetHomeObject(value, 2, property->GetSlot()); |
1623 } | 1599 } |
1624 | 1600 |
1625 switch (property->kind()) { | 1601 switch (property->kind()) { |
1626 case ObjectLiteral::Property::CONSTANT: | 1602 case ObjectLiteral::Property::CONSTANT: |
1627 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1603 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1628 case ObjectLiteral::Property::COMPUTED: | 1604 case ObjectLiteral::Property::COMPUTED: |
1629 if (property->emit_store()) { | 1605 if (property->emit_store()) { |
1630 __ Push(Smi::FromInt(NONE)); | 1606 PushOperand(Smi::FromInt(NONE)); |
1631 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); | 1607 PushOperand(Smi::FromInt(property->NeedsSetFunctionName())); |
1632 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); | 1608 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral); |
1633 } else { | 1609 } else { |
1634 __ Drop(3); | 1610 DropOperands(3); |
1635 } | 1611 } |
1636 break; | 1612 break; |
1637 | 1613 |
1638 case ObjectLiteral::Property::PROTOTYPE: | 1614 case ObjectLiteral::Property::PROTOTYPE: |
1639 UNREACHABLE(); | 1615 UNREACHABLE(); |
1640 break; | 1616 break; |
1641 | 1617 |
1642 case ObjectLiteral::Property::GETTER: | 1618 case ObjectLiteral::Property::GETTER: |
1643 __ Push(Smi::FromInt(NONE)); | 1619 PushOperand(Smi::FromInt(NONE)); |
1644 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); | 1620 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked); |
1645 break; | 1621 break; |
1646 | 1622 |
1647 case ObjectLiteral::Property::SETTER: | 1623 case ObjectLiteral::Property::SETTER: |
1648 __ Push(Smi::FromInt(NONE)); | 1624 PushOperand(Smi::FromInt(NONE)); |
1649 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); | 1625 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked); |
1650 break; | 1626 break; |
1651 } | 1627 } |
1652 } | 1628 } |
1653 } | 1629 } |
1654 | 1630 |
1655 if (expr->has_function()) { | 1631 if (expr->has_function()) { |
1656 DCHECK(result_saved); | 1632 DCHECK(result_saved); |
1657 __ lw(a0, MemOperand(sp)); | 1633 __ lw(a0, MemOperand(sp)); |
1658 __ push(a0); | 1634 __ push(a0); |
1659 __ CallRuntime(Runtime::kToFastProperties); | 1635 __ CallRuntime(Runtime::kToFastProperties); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1704 int array_index = 0; | 1680 int array_index = 0; |
1705 for (; array_index < length; array_index++) { | 1681 for (; array_index < length; array_index++) { |
1706 Expression* subexpr = subexprs->at(array_index); | 1682 Expression* subexpr = subexprs->at(array_index); |
1707 DCHECK(!subexpr->IsSpread()); | 1683 DCHECK(!subexpr->IsSpread()); |
1708 | 1684 |
1709 // If the subexpression is a literal or a simple materialized literal it | 1685 // If the subexpression is a literal or a simple materialized literal it |
1710 // is already set in the cloned array. | 1686 // is already set in the cloned array. |
1711 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 1687 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
1712 | 1688 |
1713 if (!result_saved) { | 1689 if (!result_saved) { |
1714 __ push(v0); // array literal | 1690 PushOperand(v0); // array literal |
1715 result_saved = true; | 1691 result_saved = true; |
1716 } | 1692 } |
1717 | 1693 |
1718 VisitForAccumulatorValue(subexpr); | 1694 VisitForAccumulatorValue(subexpr); |
1719 | 1695 |
1720 __ li(StoreDescriptor::NameRegister(), Operand(Smi::FromInt(array_index))); | 1696 __ li(StoreDescriptor::NameRegister(), Operand(Smi::FromInt(array_index))); |
1721 __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp, 0)); | 1697 __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp, 0)); |
1722 __ mov(StoreDescriptor::ValueRegister(), result_register()); | 1698 __ mov(StoreDescriptor::ValueRegister(), result_register()); |
1723 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); | 1699 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); |
1724 Handle<Code> ic = | 1700 Handle<Code> ic = |
1725 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 1701 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
1726 CallIC(ic); | 1702 CallIC(ic); |
1727 | 1703 |
1728 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); | 1704 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); |
1729 } | 1705 } |
1730 | 1706 |
1731 // In case the array literal contains spread expressions it has two parts. The | 1707 // In case the array literal contains spread expressions it has two parts. The |
1732 // first part is the "static" array which has a literal index is handled | 1708 // first part is the "static" array which has a literal index is handled |
1733 // above. The second part is the part after the first spread expression | 1709 // above. The second part is the part after the first spread expression |
1734 // (inclusive) and these elements gets appended to the array. Note that the | 1710 // (inclusive) and these elements gets appended to the array. Note that the |
1735 // number elements an iterable produces is unknown ahead of time. | 1711 // number elements an iterable produces is unknown ahead of time. |
1736 if (array_index < length && result_saved) { | 1712 if (array_index < length && result_saved) { |
1737 __ Pop(v0); | 1713 PopOperand(v0); |
1738 result_saved = false; | 1714 result_saved = false; |
1739 } | 1715 } |
1740 for (; array_index < length; array_index++) { | 1716 for (; array_index < length; array_index++) { |
1741 Expression* subexpr = subexprs->at(array_index); | 1717 Expression* subexpr = subexprs->at(array_index); |
1742 | 1718 |
1743 __ Push(v0); | 1719 PushOperand(v0); |
1744 DCHECK(!subexpr->IsSpread()); | 1720 DCHECK(!subexpr->IsSpread()); |
1745 VisitForStackValue(subexpr); | 1721 VisitForStackValue(subexpr); |
1746 __ CallRuntime(Runtime::kAppendElement); | 1722 CallRuntimeWithOperands(Runtime::kAppendElement); |
1747 | 1723 |
1748 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); | 1724 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); |
1749 } | 1725 } |
1750 | 1726 |
1751 if (result_saved) { | 1727 if (result_saved) { |
1752 context()->PlugTOS(); | 1728 context()->PlugTOS(); |
1753 } else { | 1729 } else { |
1754 context()->Plug(v0); | 1730 context()->Plug(v0); |
1755 } | 1731 } |
1756 } | 1732 } |
(...skipping 20 matching lines...) Expand all Loading... |
1777 __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); | 1753 __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); |
1778 } else { | 1754 } else { |
1779 VisitForStackValue(property->obj()); | 1755 VisitForStackValue(property->obj()); |
1780 } | 1756 } |
1781 break; | 1757 break; |
1782 case NAMED_SUPER_PROPERTY: | 1758 case NAMED_SUPER_PROPERTY: |
1783 VisitForStackValue( | 1759 VisitForStackValue( |
1784 property->obj()->AsSuperPropertyReference()->this_var()); | 1760 property->obj()->AsSuperPropertyReference()->this_var()); |
1785 VisitForAccumulatorValue( | 1761 VisitForAccumulatorValue( |
1786 property->obj()->AsSuperPropertyReference()->home_object()); | 1762 property->obj()->AsSuperPropertyReference()->home_object()); |
1787 __ Push(result_register()); | 1763 PushOperand(result_register()); |
1788 if (expr->is_compound()) { | 1764 if (expr->is_compound()) { |
1789 const Register scratch = a1; | 1765 const Register scratch = a1; |
1790 __ lw(scratch, MemOperand(sp, kPointerSize)); | 1766 __ lw(scratch, MemOperand(sp, kPointerSize)); |
1791 __ Push(scratch, result_register()); | 1767 PushOperands(scratch, result_register()); |
1792 } | 1768 } |
1793 break; | 1769 break; |
1794 case KEYED_SUPER_PROPERTY: { | 1770 case KEYED_SUPER_PROPERTY: { |
1795 const Register scratch = a1; | 1771 const Register scratch = a1; |
1796 VisitForStackValue( | 1772 VisitForStackValue( |
1797 property->obj()->AsSuperPropertyReference()->this_var()); | 1773 property->obj()->AsSuperPropertyReference()->this_var()); |
1798 VisitForAccumulatorValue( | 1774 VisitForAccumulatorValue( |
1799 property->obj()->AsSuperPropertyReference()->home_object()); | 1775 property->obj()->AsSuperPropertyReference()->home_object()); |
1800 __ Move(scratch, result_register()); | 1776 __ Move(scratch, result_register()); |
1801 VisitForAccumulatorValue(property->key()); | 1777 VisitForAccumulatorValue(property->key()); |
1802 __ Push(scratch, result_register()); | 1778 PushOperands(scratch, result_register()); |
1803 if (expr->is_compound()) { | 1779 if (expr->is_compound()) { |
1804 const Register scratch1 = t0; | 1780 const Register scratch1 = t0; |
1805 __ lw(scratch1, MemOperand(sp, 2 * kPointerSize)); | 1781 __ lw(scratch1, MemOperand(sp, 2 * kPointerSize)); |
1806 __ Push(scratch1, scratch, result_register()); | 1782 PushOperands(scratch1, scratch, result_register()); |
1807 } | 1783 } |
1808 break; | 1784 break; |
1809 } | 1785 } |
1810 case KEYED_PROPERTY: | 1786 case KEYED_PROPERTY: |
1811 // We need the key and receiver on both the stack and in v0 and a1. | 1787 // We need the key and receiver on both the stack and in v0 and a1. |
1812 if (expr->is_compound()) { | 1788 if (expr->is_compound()) { |
1813 VisitForStackValue(property->obj()); | 1789 VisitForStackValue(property->obj()); |
1814 VisitForStackValue(property->key()); | 1790 VisitForStackValue(property->key()); |
1815 __ lw(LoadDescriptor::ReceiverRegister(), | 1791 __ lw(LoadDescriptor::ReceiverRegister(), |
1816 MemOperand(sp, 1 * kPointerSize)); | 1792 MemOperand(sp, 1 * kPointerSize)); |
(...skipping 27 matching lines...) Expand all Loading... |
1844 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 1820 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
1845 break; | 1821 break; |
1846 case KEYED_PROPERTY: | 1822 case KEYED_PROPERTY: |
1847 EmitKeyedPropertyLoad(property); | 1823 EmitKeyedPropertyLoad(property); |
1848 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 1824 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
1849 break; | 1825 break; |
1850 } | 1826 } |
1851 } | 1827 } |
1852 | 1828 |
1853 Token::Value op = expr->binary_op(); | 1829 Token::Value op = expr->binary_op(); |
1854 __ push(v0); // Left operand goes on the stack. | 1830 PushOperand(v0); // Left operand goes on the stack. |
1855 VisitForAccumulatorValue(expr->value()); | 1831 VisitForAccumulatorValue(expr->value()); |
1856 | 1832 |
1857 AccumulatorValueContext context(this); | 1833 AccumulatorValueContext context(this); |
1858 if (ShouldInlineSmiCase(op)) { | 1834 if (ShouldInlineSmiCase(op)) { |
1859 EmitInlineSmiBinaryOp(expr->binary_operation(), | 1835 EmitInlineSmiBinaryOp(expr->binary_operation(), |
1860 op, | 1836 op, |
1861 expr->target(), | 1837 expr->target(), |
1862 expr->value()); | 1838 expr->value()); |
1863 } else { | 1839 } else { |
1864 EmitBinaryOp(expr->binary_operation(), op); | 1840 EmitBinaryOp(expr->binary_operation(), op); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1936 __ sw(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset)); | 1912 __ sw(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset)); |
1937 __ mov(a1, cp); | 1913 __ mov(a1, cp); |
1938 __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2, | 1914 __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2, |
1939 kRAHasBeenSaved, kDontSaveFPRegs); | 1915 kRAHasBeenSaved, kDontSaveFPRegs); |
1940 __ Addu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); | 1916 __ Addu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); |
1941 __ Branch(&post_runtime, eq, sp, Operand(a1)); | 1917 __ Branch(&post_runtime, eq, sp, Operand(a1)); |
1942 __ push(v0); // generator object | 1918 __ push(v0); // generator object |
1943 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 1919 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
1944 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1920 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
1945 __ bind(&post_runtime); | 1921 __ bind(&post_runtime); |
1946 __ pop(result_register()); | 1922 PopOperand(result_register()); |
1947 EmitReturnSequence(); | 1923 EmitReturnSequence(); |
1948 | 1924 |
1949 __ bind(&resume); | 1925 __ bind(&resume); |
1950 context()->Plug(result_register()); | 1926 context()->Plug(result_register()); |
1951 break; | 1927 break; |
1952 } | 1928 } |
1953 | 1929 |
1954 case Yield::kFinal: { | 1930 case Yield::kFinal: { |
1955 // Pop value from top-of-stack slot, box result into result register. | 1931 // Pop value from top-of-stack slot, box result into result register. |
| 1932 OperandStackDepthDecrement(1); |
1956 EmitCreateIteratorResult(true); | 1933 EmitCreateIteratorResult(true); |
1957 EmitUnwindAndReturn(); | 1934 EmitUnwindAndReturn(); |
1958 break; | 1935 break; |
1959 } | 1936 } |
1960 | 1937 |
1961 case Yield::kDelegating: | 1938 case Yield::kDelegating: |
1962 UNREACHABLE(); | 1939 UNREACHABLE(); |
1963 } | 1940 } |
1964 } | 1941 } |
1965 | 1942 |
1966 | 1943 |
1967 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 1944 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
1968 Expression *value, | 1945 Expression *value, |
1969 JSGeneratorObject::ResumeMode resume_mode) { | 1946 JSGeneratorObject::ResumeMode resume_mode) { |
1970 // The value stays in a0, and is ultimately read by the resumed generator, as | 1947 // The value stays in a0, and is ultimately read by the resumed generator, as |
1971 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it | 1948 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it |
1972 // is read to throw the value when the resumed generator is already closed. | 1949 // is read to throw the value when the resumed generator is already closed. |
1973 // a1 will hold the generator object until the activation has been resumed. | 1950 // a1 will hold the generator object until the activation has been resumed. |
1974 VisitForStackValue(generator); | 1951 VisitForStackValue(generator); |
1975 VisitForAccumulatorValue(value); | 1952 VisitForAccumulatorValue(value); |
1976 __ pop(a1); | 1953 PopOperand(a1); |
1977 | 1954 |
1978 // Store input value into generator object. | 1955 // Store input value into generator object. |
1979 __ sw(result_register(), | 1956 __ sw(result_register(), |
1980 FieldMemOperand(a1, JSGeneratorObject::kInputOffset)); | 1957 FieldMemOperand(a1, JSGeneratorObject::kInputOffset)); |
1981 __ mov(a2, result_register()); | 1958 __ mov(a2, result_register()); |
1982 __ RecordWriteField(a1, JSGeneratorObject::kInputOffset, a2, a3, | 1959 __ RecordWriteField(a1, JSGeneratorObject::kInputOffset, a2, a3, |
1983 kRAHasBeenSaved, kDontSaveFPRegs); | 1960 kRAHasBeenSaved, kDontSaveFPRegs); |
1984 | 1961 |
1985 // Load suspended function and context. | 1962 // Load suspended function and context. |
1986 __ lw(cp, FieldMemOperand(a1, JSGeneratorObject::kContextOffset)); | 1963 __ lw(cp, FieldMemOperand(a1, JSGeneratorObject::kContextOffset)); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2052 __ Push(a1, result_register()); | 2029 __ Push(a1, result_register()); |
2053 __ Push(Smi::FromInt(resume_mode)); | 2030 __ Push(Smi::FromInt(resume_mode)); |
2054 __ CallRuntime(Runtime::kResumeJSGeneratorObject); | 2031 __ CallRuntime(Runtime::kResumeJSGeneratorObject); |
2055 // Not reached: the runtime call returns elsewhere. | 2032 // Not reached: the runtime call returns elsewhere. |
2056 __ stop("not-reached"); | 2033 __ stop("not-reached"); |
2057 | 2034 |
2058 __ bind(&done); | 2035 __ bind(&done); |
2059 context()->Plug(result_register()); | 2036 context()->Plug(result_register()); |
2060 } | 2037 } |
2061 | 2038 |
| 2039 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) { |
| 2040 OperandStackDepthIncrement(2); |
| 2041 __ Push(reg1, reg2); |
| 2042 } |
| 2043 |
| 2044 void FullCodeGenerator::PushOperands(Register reg1, Register reg2, |
| 2045 Register reg3) { |
| 2046 OperandStackDepthIncrement(3); |
| 2047 __ Push(reg1, reg2, reg3); |
| 2048 } |
| 2049 |
| 2050 void FullCodeGenerator::PushOperands(Register reg1, Register reg2, |
| 2051 Register reg3, Register reg4) { |
| 2052 OperandStackDepthIncrement(4); |
| 2053 __ Push(reg1, reg2, reg3, reg4); |
| 2054 } |
| 2055 |
| 2056 void FullCodeGenerator::PopOperands(Register reg1, Register reg2) { |
| 2057 OperandStackDepthDecrement(2); |
| 2058 __ Pop(reg1, reg2); |
| 2059 } |
| 2060 |
| 2061 void FullCodeGenerator::EmitOperandStackDepthCheck() { |
| 2062 if (FLAG_debug_code) { |
| 2063 int expected_diff = StandardFrameConstants::kFixedFrameSizeFromFp + |
| 2064 operand_stack_depth_ * kPointerSize; |
| 2065 __ Subu(v0, fp, sp); |
| 2066 __ Assert(eq, kUnexpectedStackDepth, v0, Operand(expected_diff)); |
| 2067 } |
| 2068 } |
2062 | 2069 |
2063 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { | 2070 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { |
2064 Label allocate, done_allocate; | 2071 Label allocate, done_allocate; |
2065 | 2072 |
2066 __ Allocate(JSIteratorResult::kSize, v0, a2, a3, &allocate, TAG_OBJECT); | 2073 __ Allocate(JSIteratorResult::kSize, v0, a2, a3, &allocate, TAG_OBJECT); |
2067 __ jmp(&done_allocate); | 2074 __ jmp(&done_allocate); |
2068 | 2075 |
2069 __ bind(&allocate); | 2076 __ bind(&allocate); |
2070 __ Push(Smi::FromInt(JSIteratorResult::kSize)); | 2077 __ Push(Smi::FromInt(JSIteratorResult::kSize)); |
2071 __ CallRuntime(Runtime::kAllocateInNewSpace); | 2078 __ CallRuntime(Runtime::kAllocateInNewSpace); |
(...skipping 18 matching lines...) Expand all Loading... |
2090 Literal* key = prop->key()->AsLiteral(); | 2097 Literal* key = prop->key()->AsLiteral(); |
2091 DCHECK(!prop->IsSuperAccess()); | 2098 DCHECK(!prop->IsSuperAccess()); |
2092 | 2099 |
2093 __ li(LoadDescriptor::NameRegister(), Operand(key->value())); | 2100 __ li(LoadDescriptor::NameRegister(), Operand(key->value())); |
2094 __ li(LoadDescriptor::SlotRegister(), | 2101 __ li(LoadDescriptor::SlotRegister(), |
2095 Operand(SmiFromSlot(prop->PropertyFeedbackSlot()))); | 2102 Operand(SmiFromSlot(prop->PropertyFeedbackSlot()))); |
2096 CallLoadIC(NOT_INSIDE_TYPEOF); | 2103 CallLoadIC(NOT_INSIDE_TYPEOF); |
2097 } | 2104 } |
2098 | 2105 |
2099 | 2106 |
2100 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { | |
2101 // Stack: receiver, home_object. | |
2102 SetExpressionPosition(prop); | |
2103 | |
2104 Literal* key = prop->key()->AsLiteral(); | |
2105 DCHECK(!key->value()->IsSmi()); | |
2106 DCHECK(prop->IsSuperAccess()); | |
2107 | |
2108 __ Push(key->value()); | |
2109 __ CallRuntime(Runtime::kLoadFromSuper); | |
2110 } | |
2111 | |
2112 | |
2113 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | |
2114 SetExpressionPosition(prop); | |
2115 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); | |
2116 __ li(LoadDescriptor::SlotRegister(), | |
2117 Operand(SmiFromSlot(prop->PropertyFeedbackSlot()))); | |
2118 CallIC(ic); | |
2119 } | |
2120 | |
2121 | |
2122 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { | |
2123 // Stack: receiver, home_object, key. | |
2124 SetExpressionPosition(prop); | |
2125 __ CallRuntime(Runtime::kLoadKeyedFromSuper); | |
2126 } | |
2127 | |
2128 | |
2129 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2107 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
2130 Token::Value op, | 2108 Token::Value op, |
2131 Expression* left_expr, | 2109 Expression* left_expr, |
2132 Expression* right_expr) { | 2110 Expression* right_expr) { |
2133 Label done, smi_case, stub_call; | 2111 Label done, smi_case, stub_call; |
2134 | 2112 |
2135 Register scratch1 = a2; | 2113 Register scratch1 = a2; |
2136 Register scratch2 = a3; | 2114 Register scratch2 = a3; |
2137 | 2115 |
2138 // Get the arguments. | 2116 // Get the arguments. |
2139 Register left = a1; | 2117 Register left = a1; |
2140 Register right = a0; | 2118 Register right = a0; |
2141 __ pop(left); | 2119 PopOperand(left); |
2142 __ mov(a0, result_register()); | 2120 __ mov(a0, result_register()); |
2143 | 2121 |
2144 // Perform combined smi check on both operands. | 2122 // Perform combined smi check on both operands. |
2145 __ Or(scratch1, left, Operand(right)); | 2123 __ Or(scratch1, left, Operand(right)); |
2146 STATIC_ASSERT(kSmiTag == 0); | 2124 STATIC_ASSERT(kSmiTag == 0); |
2147 JumpPatchSite patch_site(masm_); | 2125 JumpPatchSite patch_site(masm_); |
2148 patch_site.EmitJumpIfSmi(scratch1, &smi_case); | 2126 patch_site.EmitJumpIfSmi(scratch1, &smi_case); |
2149 | 2127 |
2150 __ bind(&stub_call); | 2128 __ bind(&stub_call); |
2151 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); | 2129 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2220 for (int i = 0; i < lit->properties()->length(); i++) { | 2198 for (int i = 0; i < lit->properties()->length(); i++) { |
2221 ObjectLiteral::Property* property = lit->properties()->at(i); | 2199 ObjectLiteral::Property* property = lit->properties()->at(i); |
2222 Expression* value = property->value(); | 2200 Expression* value = property->value(); |
2223 | 2201 |
2224 Register scratch = a1; | 2202 Register scratch = a1; |
2225 if (property->is_static()) { | 2203 if (property->is_static()) { |
2226 __ lw(scratch, MemOperand(sp, kPointerSize)); // constructor | 2204 __ lw(scratch, MemOperand(sp, kPointerSize)); // constructor |
2227 } else { | 2205 } else { |
2228 __ lw(scratch, MemOperand(sp, 0)); // prototype | 2206 __ lw(scratch, MemOperand(sp, 0)); // prototype |
2229 } | 2207 } |
2230 __ push(scratch); | 2208 PushOperand(scratch); |
2231 EmitPropertyKey(property, lit->GetIdForProperty(i)); | 2209 EmitPropertyKey(property, lit->GetIdForProperty(i)); |
2232 | 2210 |
2233 // The static prototype property is read only. We handle the non computed | 2211 // The static prototype property is read only. We handle the non computed |
2234 // property name case in the parser. Since this is the only case where we | 2212 // property name case in the parser. Since this is the only case where we |
2235 // need to check for an own read only property we special case this so we do | 2213 // need to check for an own read only property we special case this so we do |
2236 // not need to do this for every property. | 2214 // not need to do this for every property. |
2237 if (property->is_static() && property->is_computed_name()) { | 2215 if (property->is_static() && property->is_computed_name()) { |
2238 __ CallRuntime(Runtime::kThrowIfStaticPrototype); | 2216 __ CallRuntime(Runtime::kThrowIfStaticPrototype); |
2239 __ push(v0); | 2217 __ push(v0); |
2240 } | 2218 } |
2241 | 2219 |
2242 VisitForStackValue(value); | 2220 VisitForStackValue(value); |
2243 if (NeedsHomeObject(value)) { | 2221 if (NeedsHomeObject(value)) { |
2244 EmitSetHomeObject(value, 2, property->GetSlot()); | 2222 EmitSetHomeObject(value, 2, property->GetSlot()); |
2245 } | 2223 } |
2246 | 2224 |
2247 switch (property->kind()) { | 2225 switch (property->kind()) { |
2248 case ObjectLiteral::Property::CONSTANT: | 2226 case ObjectLiteral::Property::CONSTANT: |
2249 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 2227 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
2250 case ObjectLiteral::Property::PROTOTYPE: | 2228 case ObjectLiteral::Property::PROTOTYPE: |
2251 UNREACHABLE(); | 2229 UNREACHABLE(); |
2252 case ObjectLiteral::Property::COMPUTED: | 2230 case ObjectLiteral::Property::COMPUTED: |
2253 __ Push(Smi::FromInt(DONT_ENUM)); | 2231 PushOperand(Smi::FromInt(DONT_ENUM)); |
2254 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); | 2232 PushOperand(Smi::FromInt(property->NeedsSetFunctionName())); |
2255 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); | 2233 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral); |
2256 break; | 2234 break; |
2257 | 2235 |
2258 case ObjectLiteral::Property::GETTER: | 2236 case ObjectLiteral::Property::GETTER: |
2259 __ Push(Smi::FromInt(DONT_ENUM)); | 2237 PushOperand(Smi::FromInt(DONT_ENUM)); |
2260 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); | 2238 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked); |
2261 break; | 2239 break; |
2262 | 2240 |
2263 case ObjectLiteral::Property::SETTER: | 2241 case ObjectLiteral::Property::SETTER: |
2264 __ Push(Smi::FromInt(DONT_ENUM)); | 2242 PushOperand(Smi::FromInt(DONT_ENUM)); |
2265 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); | 2243 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked); |
2266 break; | 2244 break; |
2267 | 2245 |
2268 default: | 2246 default: |
2269 UNREACHABLE(); | 2247 UNREACHABLE(); |
2270 } | 2248 } |
2271 } | 2249 } |
2272 } | 2250 } |
2273 | 2251 |
2274 | 2252 |
2275 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { | 2253 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { |
2276 __ mov(a0, result_register()); | 2254 __ mov(a0, result_register()); |
2277 __ pop(a1); | 2255 PopOperand(a1); |
2278 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); | 2256 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); |
2279 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2257 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
2280 CallIC(code, expr->BinaryOperationFeedbackId()); | 2258 CallIC(code, expr->BinaryOperationFeedbackId()); |
2281 patch_site.EmitPatchInfo(); | 2259 patch_site.EmitPatchInfo(); |
2282 context()->Plug(v0); | 2260 context()->Plug(v0); |
2283 } | 2261 } |
2284 | 2262 |
2285 | 2263 |
2286 void FullCodeGenerator::EmitAssignment(Expression* expr, | 2264 void FullCodeGenerator::EmitAssignment(Expression* expr, |
2287 FeedbackVectorSlot slot) { | 2265 FeedbackVectorSlot slot) { |
2288 DCHECK(expr->IsValidReferenceExpressionOrThis()); | 2266 DCHECK(expr->IsValidReferenceExpressionOrThis()); |
2289 | 2267 |
2290 Property* prop = expr->AsProperty(); | 2268 Property* prop = expr->AsProperty(); |
2291 LhsKind assign_type = Property::GetAssignType(prop); | 2269 LhsKind assign_type = Property::GetAssignType(prop); |
2292 | 2270 |
2293 switch (assign_type) { | 2271 switch (assign_type) { |
2294 case VARIABLE: { | 2272 case VARIABLE: { |
2295 Variable* var = expr->AsVariableProxy()->var(); | 2273 Variable* var = expr->AsVariableProxy()->var(); |
2296 EffectContext context(this); | 2274 EffectContext context(this); |
2297 EmitVariableAssignment(var, Token::ASSIGN, slot); | 2275 EmitVariableAssignment(var, Token::ASSIGN, slot); |
2298 break; | 2276 break; |
2299 } | 2277 } |
2300 case NAMED_PROPERTY: { | 2278 case NAMED_PROPERTY: { |
2301 __ push(result_register()); // Preserve value. | 2279 PushOperand(result_register()); // Preserve value. |
2302 VisitForAccumulatorValue(prop->obj()); | 2280 VisitForAccumulatorValue(prop->obj()); |
2303 __ mov(StoreDescriptor::ReceiverRegister(), result_register()); | 2281 __ mov(StoreDescriptor::ReceiverRegister(), result_register()); |
2304 __ pop(StoreDescriptor::ValueRegister()); // Restore value. | 2282 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. |
2305 __ li(StoreDescriptor::NameRegister(), | 2283 __ li(StoreDescriptor::NameRegister(), |
2306 Operand(prop->key()->AsLiteral()->value())); | 2284 Operand(prop->key()->AsLiteral()->value())); |
2307 EmitLoadStoreICSlot(slot); | 2285 EmitLoadStoreICSlot(slot); |
2308 CallStoreIC(); | 2286 CallStoreIC(); |
2309 break; | 2287 break; |
2310 } | 2288 } |
2311 case NAMED_SUPER_PROPERTY: { | 2289 case NAMED_SUPER_PROPERTY: { |
2312 __ Push(v0); | 2290 PushOperand(v0); |
2313 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 2291 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
2314 VisitForAccumulatorValue( | 2292 VisitForAccumulatorValue( |
2315 prop->obj()->AsSuperPropertyReference()->home_object()); | 2293 prop->obj()->AsSuperPropertyReference()->home_object()); |
2316 // stack: value, this; v0: home_object | 2294 // stack: value, this; v0: home_object |
2317 Register scratch = a2; | 2295 Register scratch = a2; |
2318 Register scratch2 = a3; | 2296 Register scratch2 = a3; |
2319 __ mov(scratch, result_register()); // home_object | 2297 __ mov(scratch, result_register()); // home_object |
2320 __ lw(v0, MemOperand(sp, kPointerSize)); // value | 2298 __ lw(v0, MemOperand(sp, kPointerSize)); // value |
2321 __ lw(scratch2, MemOperand(sp, 0)); // this | 2299 __ lw(scratch2, MemOperand(sp, 0)); // this |
2322 __ sw(scratch2, MemOperand(sp, kPointerSize)); // this | 2300 __ sw(scratch2, MemOperand(sp, kPointerSize)); // this |
2323 __ sw(scratch, MemOperand(sp, 0)); // home_object | 2301 __ sw(scratch, MemOperand(sp, 0)); // home_object |
2324 // stack: this, home_object; v0: value | 2302 // stack: this, home_object; v0: value |
2325 EmitNamedSuperPropertyStore(prop); | 2303 EmitNamedSuperPropertyStore(prop); |
2326 break; | 2304 break; |
2327 } | 2305 } |
2328 case KEYED_SUPER_PROPERTY: { | 2306 case KEYED_SUPER_PROPERTY: { |
2329 __ Push(v0); | 2307 PushOperand(v0); |
2330 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 2308 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
2331 VisitForStackValue( | 2309 VisitForStackValue( |
2332 prop->obj()->AsSuperPropertyReference()->home_object()); | 2310 prop->obj()->AsSuperPropertyReference()->home_object()); |
2333 VisitForAccumulatorValue(prop->key()); | 2311 VisitForAccumulatorValue(prop->key()); |
2334 Register scratch = a2; | 2312 Register scratch = a2; |
2335 Register scratch2 = a3; | 2313 Register scratch2 = a3; |
2336 __ lw(scratch2, MemOperand(sp, 2 * kPointerSize)); // value | 2314 __ lw(scratch2, MemOperand(sp, 2 * kPointerSize)); // value |
2337 // stack: value, this, home_object; v0: key, a3: value | 2315 // stack: value, this, home_object; v0: key, a3: value |
2338 __ lw(scratch, MemOperand(sp, kPointerSize)); // this | 2316 __ lw(scratch, MemOperand(sp, kPointerSize)); // this |
2339 __ sw(scratch, MemOperand(sp, 2 * kPointerSize)); | 2317 __ sw(scratch, MemOperand(sp, 2 * kPointerSize)); |
2340 __ lw(scratch, MemOperand(sp, 0)); // home_object | 2318 __ lw(scratch, MemOperand(sp, 0)); // home_object |
2341 __ sw(scratch, MemOperand(sp, kPointerSize)); | 2319 __ sw(scratch, MemOperand(sp, kPointerSize)); |
2342 __ sw(v0, MemOperand(sp, 0)); | 2320 __ sw(v0, MemOperand(sp, 0)); |
2343 __ Move(v0, scratch2); | 2321 __ Move(v0, scratch2); |
2344 // stack: this, home_object, key; v0: value. | 2322 // stack: this, home_object, key; v0: value. |
2345 EmitKeyedSuperPropertyStore(prop); | 2323 EmitKeyedSuperPropertyStore(prop); |
2346 break; | 2324 break; |
2347 } | 2325 } |
2348 case KEYED_PROPERTY: { | 2326 case KEYED_PROPERTY: { |
2349 __ push(result_register()); // Preserve value. | 2327 PushOperand(result_register()); // Preserve value. |
2350 VisitForStackValue(prop->obj()); | 2328 VisitForStackValue(prop->obj()); |
2351 VisitForAccumulatorValue(prop->key()); | 2329 VisitForAccumulatorValue(prop->key()); |
2352 __ mov(StoreDescriptor::NameRegister(), result_register()); | 2330 __ mov(StoreDescriptor::NameRegister(), result_register()); |
2353 __ Pop(StoreDescriptor::ValueRegister(), | 2331 PopOperands(StoreDescriptor::ValueRegister(), |
2354 StoreDescriptor::ReceiverRegister()); | 2332 StoreDescriptor::ReceiverRegister()); |
2355 EmitLoadStoreICSlot(slot); | 2333 EmitLoadStoreICSlot(slot); |
2356 Handle<Code> ic = | 2334 Handle<Code> ic = |
2357 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2335 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
2358 CallIC(ic); | 2336 CallIC(ic); |
2359 break; | 2337 break; |
2360 } | 2338 } |
2361 } | 2339 } |
2362 context()->Plug(v0); | 2340 context()->Plug(v0); |
2363 } | 2341 } |
2364 | 2342 |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2484 | 2462 |
2485 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2463 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
2486 // Assignment to a property, using a named store IC. | 2464 // Assignment to a property, using a named store IC. |
2487 Property* prop = expr->target()->AsProperty(); | 2465 Property* prop = expr->target()->AsProperty(); |
2488 DCHECK(prop != NULL); | 2466 DCHECK(prop != NULL); |
2489 DCHECK(prop->key()->IsLiteral()); | 2467 DCHECK(prop->key()->IsLiteral()); |
2490 | 2468 |
2491 __ mov(StoreDescriptor::ValueRegister(), result_register()); | 2469 __ mov(StoreDescriptor::ValueRegister(), result_register()); |
2492 __ li(StoreDescriptor::NameRegister(), | 2470 __ li(StoreDescriptor::NameRegister(), |
2493 Operand(prop->key()->AsLiteral()->value())); | 2471 Operand(prop->key()->AsLiteral()->value())); |
2494 __ pop(StoreDescriptor::ReceiverRegister()); | 2472 PopOperand(StoreDescriptor::ReceiverRegister()); |
2495 EmitLoadStoreICSlot(expr->AssignmentSlot()); | 2473 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
2496 CallStoreIC(); | 2474 CallStoreIC(); |
2497 | 2475 |
2498 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2476 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2499 context()->Plug(v0); | 2477 context()->Plug(v0); |
2500 } | 2478 } |
2501 | 2479 |
2502 | 2480 |
2503 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { | 2481 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { |
2504 // Assignment to named property of super. | 2482 // Assignment to named property of super. |
2505 // v0 : value | 2483 // v0 : value |
2506 // stack : receiver ('this'), home_object | 2484 // stack : receiver ('this'), home_object |
2507 DCHECK(prop != NULL); | 2485 DCHECK(prop != NULL); |
2508 Literal* key = prop->key()->AsLiteral(); | 2486 Literal* key = prop->key()->AsLiteral(); |
2509 DCHECK(key != NULL); | 2487 DCHECK(key != NULL); |
2510 | 2488 |
2511 __ Push(key->value()); | 2489 PushOperand(key->value()); |
2512 __ Push(v0); | 2490 PushOperand(v0); |
2513 __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict | 2491 CallRuntimeWithOperands(is_strict(language_mode()) |
2514 : Runtime::kStoreToSuper_Sloppy)); | 2492 ? Runtime::kStoreToSuper_Strict |
| 2493 : Runtime::kStoreToSuper_Sloppy); |
2515 } | 2494 } |
2516 | 2495 |
2517 | 2496 |
2518 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { | 2497 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { |
2519 // Assignment to named property of super. | 2498 // Assignment to named property of super. |
2520 // v0 : value | 2499 // v0 : value |
2521 // stack : receiver ('this'), home_object, key | 2500 // stack : receiver ('this'), home_object, key |
2522 DCHECK(prop != NULL); | 2501 DCHECK(prop != NULL); |
2523 | 2502 |
2524 __ Push(v0); | 2503 PushOperand(v0); |
2525 __ CallRuntime((is_strict(language_mode()) | 2504 CallRuntimeWithOperands(is_strict(language_mode()) |
2526 ? Runtime::kStoreKeyedToSuper_Strict | 2505 ? Runtime::kStoreKeyedToSuper_Strict |
2527 : Runtime::kStoreKeyedToSuper_Sloppy)); | 2506 : Runtime::kStoreKeyedToSuper_Sloppy); |
2528 } | 2507 } |
2529 | 2508 |
2530 | 2509 |
2531 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2510 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
2532 // Assignment to a property, using a keyed store IC. | 2511 // Assignment to a property, using a keyed store IC. |
2533 // Call keyed store IC. | 2512 // Call keyed store IC. |
2534 // The arguments are: | 2513 // The arguments are: |
2535 // - a0 is the value, | 2514 // - a0 is the value, |
2536 // - a1 is the key, | 2515 // - a1 is the key, |
2537 // - a2 is the receiver. | 2516 // - a2 is the receiver. |
2538 __ mov(StoreDescriptor::ValueRegister(), result_register()); | 2517 __ mov(StoreDescriptor::ValueRegister(), result_register()); |
2539 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); | 2518 PopOperands(StoreDescriptor::ReceiverRegister(), |
| 2519 StoreDescriptor::NameRegister()); |
2540 DCHECK(StoreDescriptor::ValueRegister().is(a0)); | 2520 DCHECK(StoreDescriptor::ValueRegister().is(a0)); |
2541 | 2521 |
2542 Handle<Code> ic = | 2522 Handle<Code> ic = |
2543 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2523 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
2544 EmitLoadStoreICSlot(expr->AssignmentSlot()); | 2524 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
2545 CallIC(ic); | 2525 CallIC(ic); |
2546 | 2526 |
2547 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2527 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2548 context()->Plug(v0); | 2528 context()->Plug(v0); |
2549 } | 2529 } |
(...skipping 14 matching lines...) Expand all Loading... |
2564 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); | 2544 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); |
2565 VisitForStackValue( | 2545 VisitForStackValue( |
2566 expr->obj()->AsSuperPropertyReference()->home_object()); | 2546 expr->obj()->AsSuperPropertyReference()->home_object()); |
2567 EmitNamedSuperPropertyLoad(expr); | 2547 EmitNamedSuperPropertyLoad(expr); |
2568 } | 2548 } |
2569 } else { | 2549 } else { |
2570 if (!expr->IsSuperAccess()) { | 2550 if (!expr->IsSuperAccess()) { |
2571 VisitForStackValue(expr->obj()); | 2551 VisitForStackValue(expr->obj()); |
2572 VisitForAccumulatorValue(expr->key()); | 2552 VisitForAccumulatorValue(expr->key()); |
2573 __ Move(LoadDescriptor::NameRegister(), v0); | 2553 __ Move(LoadDescriptor::NameRegister(), v0); |
2574 __ pop(LoadDescriptor::ReceiverRegister()); | 2554 PopOperand(LoadDescriptor::ReceiverRegister()); |
2575 EmitKeyedPropertyLoad(expr); | 2555 EmitKeyedPropertyLoad(expr); |
2576 } else { | 2556 } else { |
2577 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); | 2557 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); |
2578 VisitForStackValue( | 2558 VisitForStackValue( |
2579 expr->obj()->AsSuperPropertyReference()->home_object()); | 2559 expr->obj()->AsSuperPropertyReference()->home_object()); |
2580 VisitForStackValue(expr->key()); | 2560 VisitForStackValue(expr->key()); |
2581 EmitKeyedSuperPropertyLoad(expr); | 2561 EmitKeyedSuperPropertyLoad(expr); |
2582 } | 2562 } |
2583 } | 2563 } |
2584 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2564 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
(...skipping 15 matching lines...) Expand all Loading... |
2600 // Get the target function. | 2580 // Get the target function. |
2601 ConvertReceiverMode convert_mode; | 2581 ConvertReceiverMode convert_mode; |
2602 if (callee->IsVariableProxy()) { | 2582 if (callee->IsVariableProxy()) { |
2603 { StackValueContext context(this); | 2583 { StackValueContext context(this); |
2604 EmitVariableLoad(callee->AsVariableProxy()); | 2584 EmitVariableLoad(callee->AsVariableProxy()); |
2605 PrepareForBailout(callee, NO_REGISTERS); | 2585 PrepareForBailout(callee, NO_REGISTERS); |
2606 } | 2586 } |
2607 // Push undefined as receiver. This is patched in the method prologue if it | 2587 // Push undefined as receiver. This is patched in the method prologue if it |
2608 // is a sloppy mode method. | 2588 // is a sloppy mode method. |
2609 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 2589 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
2610 __ push(at); | 2590 PushOperand(at); |
2611 convert_mode = ConvertReceiverMode::kNullOrUndefined; | 2591 convert_mode = ConvertReceiverMode::kNullOrUndefined; |
2612 } else { | 2592 } else { |
2613 // Load the function from the receiver. | 2593 // Load the function from the receiver. |
2614 DCHECK(callee->IsProperty()); | 2594 DCHECK(callee->IsProperty()); |
2615 DCHECK(!callee->AsProperty()->IsSuperAccess()); | 2595 DCHECK(!callee->AsProperty()->IsSuperAccess()); |
2616 __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); | 2596 __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); |
2617 EmitNamedPropertyLoad(callee->AsProperty()); | 2597 EmitNamedPropertyLoad(callee->AsProperty()); |
2618 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2598 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2619 // Push the target function under the receiver. | 2599 // Push the target function under the receiver. |
2620 __ lw(at, MemOperand(sp, 0)); | 2600 __ lw(at, MemOperand(sp, 0)); |
2621 __ push(at); | 2601 PushOperand(at); |
2622 __ sw(v0, MemOperand(sp, kPointerSize)); | 2602 __ sw(v0, MemOperand(sp, kPointerSize)); |
2623 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; | 2603 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; |
2624 } | 2604 } |
2625 | 2605 |
2626 EmitCall(expr, convert_mode); | 2606 EmitCall(expr, convert_mode); |
2627 } | 2607 } |
2628 | 2608 |
2629 | 2609 |
2630 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | 2610 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { |
2631 SetExpressionPosition(expr); | 2611 SetExpressionPosition(expr); |
2632 Expression* callee = expr->expression(); | 2612 Expression* callee = expr->expression(); |
2633 DCHECK(callee->IsProperty()); | 2613 DCHECK(callee->IsProperty()); |
2634 Property* prop = callee->AsProperty(); | 2614 Property* prop = callee->AsProperty(); |
2635 DCHECK(prop->IsSuperAccess()); | 2615 DCHECK(prop->IsSuperAccess()); |
2636 | 2616 |
2637 Literal* key = prop->key()->AsLiteral(); | 2617 Literal* key = prop->key()->AsLiteral(); |
2638 DCHECK(!key->value()->IsSmi()); | 2618 DCHECK(!key->value()->IsSmi()); |
2639 // Load the function from the receiver. | 2619 // Load the function from the receiver. |
2640 const Register scratch = a1; | 2620 const Register scratch = a1; |
2641 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | 2621 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); |
2642 VisitForAccumulatorValue(super_ref->home_object()); | 2622 VisitForAccumulatorValue(super_ref->home_object()); |
2643 __ mov(scratch, v0); | 2623 __ mov(scratch, v0); |
2644 VisitForAccumulatorValue(super_ref->this_var()); | 2624 VisitForAccumulatorValue(super_ref->this_var()); |
2645 __ Push(scratch, v0, v0, scratch); | 2625 PushOperands(scratch, v0, v0, scratch); |
2646 __ Push(key->value()); | 2626 PushOperand(key->value()); |
2647 | 2627 |
2648 // Stack here: | 2628 // Stack here: |
2649 // - home_object | 2629 // - home_object |
2650 // - this (receiver) | 2630 // - this (receiver) |
2651 // - this (receiver) <-- LoadFromSuper will pop here and below. | 2631 // - this (receiver) <-- LoadFromSuper will pop here and below. |
2652 // - home_object | 2632 // - home_object |
2653 // - key | 2633 // - key |
2654 __ CallRuntime(Runtime::kLoadFromSuper); | 2634 CallRuntimeWithOperands(Runtime::kLoadFromSuper); |
2655 | 2635 |
2656 // Replace home_object with target function. | 2636 // Replace home_object with target function. |
2657 __ sw(v0, MemOperand(sp, kPointerSize)); | 2637 __ sw(v0, MemOperand(sp, kPointerSize)); |
2658 | 2638 |
2659 // Stack here: | 2639 // Stack here: |
2660 // - target function | 2640 // - target function |
2661 // - this (receiver) | 2641 // - this (receiver) |
2662 EmitCall(expr); | 2642 EmitCall(expr); |
2663 } | 2643 } |
2664 | 2644 |
2665 | 2645 |
2666 // Code common for calls using the IC. | 2646 // Code common for calls using the IC. |
2667 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 2647 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, |
2668 Expression* key) { | 2648 Expression* key) { |
2669 // Load the key. | 2649 // Load the key. |
2670 VisitForAccumulatorValue(key); | 2650 VisitForAccumulatorValue(key); |
2671 | 2651 |
2672 Expression* callee = expr->expression(); | 2652 Expression* callee = expr->expression(); |
2673 | 2653 |
2674 // Load the function from the receiver. | 2654 // Load the function from the receiver. |
2675 DCHECK(callee->IsProperty()); | 2655 DCHECK(callee->IsProperty()); |
2676 __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); | 2656 __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); |
2677 __ Move(LoadDescriptor::NameRegister(), v0); | 2657 __ Move(LoadDescriptor::NameRegister(), v0); |
2678 EmitKeyedPropertyLoad(callee->AsProperty()); | 2658 EmitKeyedPropertyLoad(callee->AsProperty()); |
2679 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2659 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2680 | 2660 |
2681 // Push the target function under the receiver. | 2661 // Push the target function under the receiver. |
2682 __ lw(at, MemOperand(sp, 0)); | 2662 __ lw(at, MemOperand(sp, 0)); |
2683 __ push(at); | 2663 PushOperand(at); |
2684 __ sw(v0, MemOperand(sp, kPointerSize)); | 2664 __ sw(v0, MemOperand(sp, kPointerSize)); |
2685 | 2665 |
2686 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); | 2666 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); |
2687 } | 2667 } |
2688 | 2668 |
2689 | 2669 |
2690 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | 2670 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { |
2691 Expression* callee = expr->expression(); | 2671 Expression* callee = expr->expression(); |
2692 DCHECK(callee->IsProperty()); | 2672 DCHECK(callee->IsProperty()); |
2693 Property* prop = callee->AsProperty(); | 2673 Property* prop = callee->AsProperty(); |
2694 DCHECK(prop->IsSuperAccess()); | 2674 DCHECK(prop->IsSuperAccess()); |
2695 | 2675 |
2696 SetExpressionPosition(prop); | 2676 SetExpressionPosition(prop); |
2697 // Load the function from the receiver. | 2677 // Load the function from the receiver. |
2698 const Register scratch = a1; | 2678 const Register scratch = a1; |
2699 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | 2679 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); |
2700 VisitForAccumulatorValue(super_ref->home_object()); | 2680 VisitForAccumulatorValue(super_ref->home_object()); |
2701 __ Move(scratch, v0); | 2681 __ Move(scratch, v0); |
2702 VisitForAccumulatorValue(super_ref->this_var()); | 2682 VisitForAccumulatorValue(super_ref->this_var()); |
2703 __ Push(scratch, v0, v0, scratch); | 2683 PushOperands(scratch, v0, v0, scratch); |
2704 VisitForStackValue(prop->key()); | 2684 VisitForStackValue(prop->key()); |
2705 | 2685 |
2706 // Stack here: | 2686 // Stack here: |
2707 // - home_object | 2687 // - home_object |
2708 // - this (receiver) | 2688 // - this (receiver) |
2709 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. | 2689 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. |
2710 // - home_object | 2690 // - home_object |
2711 // - key | 2691 // - key |
2712 __ CallRuntime(Runtime::kLoadKeyedFromSuper); | 2692 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); |
2713 | 2693 |
2714 // Replace home_object with target function. | 2694 // Replace home_object with target function. |
2715 __ sw(v0, MemOperand(sp, kPointerSize)); | 2695 __ sw(v0, MemOperand(sp, kPointerSize)); |
2716 | 2696 |
2717 // Stack here: | 2697 // Stack here: |
2718 // - target function | 2698 // - target function |
2719 // - this (receiver) | 2699 // - this (receiver) |
2720 EmitCall(expr); | 2700 EmitCall(expr); |
2721 } | 2701 } |
2722 | 2702 |
(...skipping 18 matching lines...) Expand all Loading... |
2741 EmitProfilingCounterHandlingForReturnSequence(true); | 2721 EmitProfilingCounterHandlingForReturnSequence(true); |
2742 } | 2722 } |
2743 Handle<Code> ic = | 2723 Handle<Code> ic = |
2744 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) | 2724 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) |
2745 .code(); | 2725 .code(); |
2746 __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackICSlot()))); | 2726 __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackICSlot()))); |
2747 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2727 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
2748 // Don't assign a type feedback id to the IC, since type feedback is provided | 2728 // Don't assign a type feedback id to the IC, since type feedback is provided |
2749 // by the vector above. | 2729 // by the vector above. |
2750 CallIC(ic); | 2730 CallIC(ic); |
| 2731 OperandStackDepthDecrement(arg_count + 1); |
2751 | 2732 |
2752 RecordJSReturnSite(expr); | 2733 RecordJSReturnSite(expr); |
2753 // Restore context register. | 2734 // Restore context register. |
2754 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2735 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2755 context()->DropAndPlug(1, v0); | 2736 context()->DropAndPlug(1, v0); |
2756 } | 2737 } |
2757 | 2738 |
2758 | 2739 |
2759 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { | 2740 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { |
2760 // t3: copy of the first argument or undefined if it doesn't exist. | 2741 // t3: copy of the first argument or undefined if it doesn't exist. |
(...skipping 27 matching lines...) Expand all Loading... |
2788 SetExpressionPosition(callee); | 2769 SetExpressionPosition(callee); |
2789 // Generate code for loading from variables potentially shadowed by | 2770 // Generate code for loading from variables potentially shadowed by |
2790 // eval-introduced variables. | 2771 // eval-introduced variables. |
2791 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); | 2772 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); |
2792 | 2773 |
2793 __ bind(&slow); | 2774 __ bind(&slow); |
2794 // Call the runtime to find the function to call (returned in v0) | 2775 // Call the runtime to find the function to call (returned in v0) |
2795 // and the object holding it (returned in v1). | 2776 // and the object holding it (returned in v1). |
2796 __ Push(callee->name()); | 2777 __ Push(callee->name()); |
2797 __ CallRuntime(Runtime::kLoadLookupSlotForCall); | 2778 __ CallRuntime(Runtime::kLoadLookupSlotForCall); |
2798 __ Push(v0, v1); // Function, receiver. | 2779 PushOperands(v0, v1); // Function, receiver. |
2799 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); | 2780 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); |
2800 | 2781 |
2801 // If fast case code has been generated, emit code to push the | 2782 // If fast case code has been generated, emit code to push the |
2802 // function and receiver and have the slow path jump around this | 2783 // function and receiver and have the slow path jump around this |
2803 // code. | 2784 // code. |
2804 if (done.is_linked()) { | 2785 if (done.is_linked()) { |
2805 Label call; | 2786 Label call; |
2806 __ Branch(&call); | 2787 __ Branch(&call); |
2807 __ bind(&done); | 2788 __ bind(&done); |
2808 // Push function. | 2789 // Push function. |
2809 __ push(v0); | 2790 __ push(v0); |
2810 // The receiver is implicitly the global receiver. Indicate this | 2791 // The receiver is implicitly the global receiver. Indicate this |
2811 // by passing the hole to the call function stub. | 2792 // by passing the hole to the call function stub. |
2812 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex); | 2793 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex); |
2813 __ push(a1); | 2794 __ push(a1); |
2814 __ bind(&call); | 2795 __ bind(&call); |
2815 } | 2796 } |
2816 } else { | 2797 } else { |
2817 VisitForStackValue(callee); | 2798 VisitForStackValue(callee); |
2818 // refEnv.WithBaseObject() | 2799 // refEnv.WithBaseObject() |
2819 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); | 2800 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); |
2820 __ push(a2); // Reserved receiver slot. | 2801 PushOperand(a2); // Reserved receiver slot. |
2821 } | 2802 } |
2822 } | 2803 } |
2823 | 2804 |
2824 | 2805 |
2825 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { | 2806 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { |
2826 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval | 2807 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval |
2827 // to resolve the function we need to call. Then we call the resolved | 2808 // to resolve the function we need to call. Then we call the resolved |
2828 // function using the given arguments. | 2809 // function using the given arguments. |
2829 ZoneList<Expression*>* args = expr->arguments(); | 2810 ZoneList<Expression*>* args = expr->arguments(); |
2830 int arg_count = args->length(); | 2811 int arg_count = args->length(); |
(...skipping 14 matching lines...) Expand all Loading... |
2845 __ sw(v0, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2826 __ sw(v0, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
2846 | 2827 |
2847 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); | 2828 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); |
2848 // Record source position for debugger. | 2829 // Record source position for debugger. |
2849 SetCallPosition(expr); | 2830 SetCallPosition(expr); |
2850 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2831 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
2851 __ li(a0, Operand(arg_count)); | 2832 __ li(a0, Operand(arg_count)); |
2852 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, | 2833 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, |
2853 expr->tail_call_mode()), | 2834 expr->tail_call_mode()), |
2854 RelocInfo::CODE_TARGET); | 2835 RelocInfo::CODE_TARGET); |
| 2836 OperandStackDepthDecrement(arg_count + 1); |
2855 RecordJSReturnSite(expr); | 2837 RecordJSReturnSite(expr); |
2856 // Restore context register. | 2838 // Restore context register. |
2857 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2839 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2858 context()->DropAndPlug(1, v0); | 2840 context()->DropAndPlug(1, v0); |
2859 } | 2841 } |
2860 | 2842 |
2861 | 2843 |
2862 void FullCodeGenerator::VisitCallNew(CallNew* expr) { | 2844 void FullCodeGenerator::VisitCallNew(CallNew* expr) { |
2863 Comment cmnt(masm_, "[ CallNew"); | 2845 Comment cmnt(masm_, "[ CallNew"); |
2864 // According to ECMA-262, section 11.2.2, page 44, the function | 2846 // According to ECMA-262, section 11.2.2, page 44, the function |
(...skipping 20 matching lines...) Expand all Loading... |
2885 // Load function and argument count into a1 and a0. | 2867 // Load function and argument count into a1 and a0. |
2886 __ li(a0, Operand(arg_count)); | 2868 __ li(a0, Operand(arg_count)); |
2887 __ lw(a1, MemOperand(sp, arg_count * kPointerSize)); | 2869 __ lw(a1, MemOperand(sp, arg_count * kPointerSize)); |
2888 | 2870 |
2889 // Record call targets in unoptimized code. | 2871 // Record call targets in unoptimized code. |
2890 __ EmitLoadTypeFeedbackVector(a2); | 2872 __ EmitLoadTypeFeedbackVector(a2); |
2891 __ li(a3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot()))); | 2873 __ li(a3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot()))); |
2892 | 2874 |
2893 CallConstructStub stub(isolate()); | 2875 CallConstructStub stub(isolate()); |
2894 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); | 2876 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); |
| 2877 OperandStackDepthDecrement(arg_count + 1); |
2895 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); | 2878 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); |
2896 // Restore context register. | 2879 // Restore context register. |
2897 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2880 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2898 context()->Plug(v0); | 2881 context()->Plug(v0); |
2899 } | 2882 } |
2900 | 2883 |
2901 | 2884 |
2902 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { | 2885 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { |
2903 SuperCallReference* super_call_ref = | 2886 SuperCallReference* super_call_ref = |
2904 expr->expression()->AsSuperCallReference(); | 2887 expr->expression()->AsSuperCallReference(); |
2905 DCHECK_NOT_NULL(super_call_ref); | 2888 DCHECK_NOT_NULL(super_call_ref); |
2906 | 2889 |
2907 // Push the super constructor target on the stack (may be null, | 2890 // Push the super constructor target on the stack (may be null, |
2908 // but the Construct builtin can deal with that properly). | 2891 // but the Construct builtin can deal with that properly). |
2909 VisitForAccumulatorValue(super_call_ref->this_function_var()); | 2892 VisitForAccumulatorValue(super_call_ref->this_function_var()); |
2910 __ AssertFunction(result_register()); | 2893 __ AssertFunction(result_register()); |
2911 __ lw(result_register(), | 2894 __ lw(result_register(), |
2912 FieldMemOperand(result_register(), HeapObject::kMapOffset)); | 2895 FieldMemOperand(result_register(), HeapObject::kMapOffset)); |
2913 __ lw(result_register(), | 2896 __ lw(result_register(), |
2914 FieldMemOperand(result_register(), Map::kPrototypeOffset)); | 2897 FieldMemOperand(result_register(), Map::kPrototypeOffset)); |
2915 __ Push(result_register()); | 2898 PushOperand(result_register()); |
2916 | 2899 |
2917 // Push the arguments ("left-to-right") on the stack. | 2900 // Push the arguments ("left-to-right") on the stack. |
2918 ZoneList<Expression*>* args = expr->arguments(); | 2901 ZoneList<Expression*>* args = expr->arguments(); |
2919 int arg_count = args->length(); | 2902 int arg_count = args->length(); |
2920 for (int i = 0; i < arg_count; i++) { | 2903 for (int i = 0; i < arg_count; i++) { |
2921 VisitForStackValue(args->at(i)); | 2904 VisitForStackValue(args->at(i)); |
2922 } | 2905 } |
2923 | 2906 |
2924 // Call the construct call builtin that handles allocation and | 2907 // Call the construct call builtin that handles allocation and |
2925 // constructor invocation. | 2908 // constructor invocation. |
2926 SetConstructCallPosition(expr); | 2909 SetConstructCallPosition(expr); |
2927 | 2910 |
2928 // Load new target into a3. | 2911 // Load new target into a3. |
2929 VisitForAccumulatorValue(super_call_ref->new_target_var()); | 2912 VisitForAccumulatorValue(super_call_ref->new_target_var()); |
2930 __ mov(a3, result_register()); | 2913 __ mov(a3, result_register()); |
2931 | 2914 |
2932 // Load function and argument count into a1 and a0. | 2915 // Load function and argument count into a1 and a0. |
2933 __ li(a0, Operand(arg_count)); | 2916 __ li(a0, Operand(arg_count)); |
2934 __ lw(a1, MemOperand(sp, arg_count * kPointerSize)); | 2917 __ lw(a1, MemOperand(sp, arg_count * kPointerSize)); |
2935 | 2918 |
2936 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 2919 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
| 2920 OperandStackDepthDecrement(arg_count + 1); |
2937 | 2921 |
2938 RecordJSReturnSite(expr); | 2922 RecordJSReturnSite(expr); |
2939 | 2923 |
2940 // Restore context register. | 2924 // Restore context register. |
2941 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2925 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2942 context()->Plug(v0); | 2926 context()->Plug(v0); |
2943 } | 2927 } |
2944 | 2928 |
2945 | 2929 |
2946 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 2930 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3149 ZoneList<Expression*>* args = expr->arguments(); | 3133 ZoneList<Expression*>* args = expr->arguments(); |
3150 DCHECK_EQ(3, args->length()); | 3134 DCHECK_EQ(3, args->length()); |
3151 | 3135 |
3152 Register string = v0; | 3136 Register string = v0; |
3153 Register index = a1; | 3137 Register index = a1; |
3154 Register value = a2; | 3138 Register value = a2; |
3155 | 3139 |
3156 VisitForStackValue(args->at(0)); // index | 3140 VisitForStackValue(args->at(0)); // index |
3157 VisitForStackValue(args->at(1)); // value | 3141 VisitForStackValue(args->at(1)); // value |
3158 VisitForAccumulatorValue(args->at(2)); // string | 3142 VisitForAccumulatorValue(args->at(2)); // string |
3159 __ Pop(index, value); | 3143 PopOperands(index, value); |
3160 | 3144 |
3161 if (FLAG_debug_code) { | 3145 if (FLAG_debug_code) { |
3162 __ SmiTst(value, at); | 3146 __ SmiTst(value, at); |
3163 __ Check(eq, kNonSmiValue, at, Operand(zero_reg)); | 3147 __ Check(eq, kNonSmiValue, at, Operand(zero_reg)); |
3164 __ SmiTst(index, at); | 3148 __ SmiTst(index, at); |
3165 __ Check(eq, kNonSmiIndex, at, Operand(zero_reg)); | 3149 __ Check(eq, kNonSmiIndex, at, Operand(zero_reg)); |
3166 __ SmiUntag(index, index); | 3150 __ SmiUntag(index, index); |
3167 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; | 3151 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; |
3168 Register scratch = t5; | 3152 Register scratch = t5; |
3169 __ EmitSeqStringSetCharCheck( | 3153 __ EmitSeqStringSetCharCheck( |
(...skipping 16 matching lines...) Expand all Loading... |
3186 ZoneList<Expression*>* args = expr->arguments(); | 3170 ZoneList<Expression*>* args = expr->arguments(); |
3187 DCHECK_EQ(3, args->length()); | 3171 DCHECK_EQ(3, args->length()); |
3188 | 3172 |
3189 Register string = v0; | 3173 Register string = v0; |
3190 Register index = a1; | 3174 Register index = a1; |
3191 Register value = a2; | 3175 Register value = a2; |
3192 | 3176 |
3193 VisitForStackValue(args->at(0)); // index | 3177 VisitForStackValue(args->at(0)); // index |
3194 VisitForStackValue(args->at(1)); // value | 3178 VisitForStackValue(args->at(1)); // value |
3195 VisitForAccumulatorValue(args->at(2)); // string | 3179 VisitForAccumulatorValue(args->at(2)); // string |
3196 __ Pop(index, value); | 3180 PopOperands(index, value); |
3197 | 3181 |
3198 if (FLAG_debug_code) { | 3182 if (FLAG_debug_code) { |
3199 __ SmiTst(value, at); | 3183 __ SmiTst(value, at); |
3200 __ Check(eq, kNonSmiValue, at, Operand(zero_reg)); | 3184 __ Check(eq, kNonSmiValue, at, Operand(zero_reg)); |
3201 __ SmiTst(index, at); | 3185 __ SmiTst(index, at); |
3202 __ Check(eq, kNonSmiIndex, at, Operand(zero_reg)); | 3186 __ Check(eq, kNonSmiIndex, at, Operand(zero_reg)); |
3203 __ SmiUntag(index, index); | 3187 __ SmiUntag(index, index); |
3204 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; | 3188 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; |
3205 Register scratch = t5; | 3189 Register scratch = t5; |
3206 __ EmitSeqStringSetCharCheck( | 3190 __ EmitSeqStringSetCharCheck( |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3260 DCHECK(args->length() == 2); | 3244 DCHECK(args->length() == 2); |
3261 | 3245 |
3262 VisitForStackValue(args->at(0)); | 3246 VisitForStackValue(args->at(0)); |
3263 VisitForAccumulatorValue(args->at(1)); | 3247 VisitForAccumulatorValue(args->at(1)); |
3264 __ mov(a0, result_register()); | 3248 __ mov(a0, result_register()); |
3265 | 3249 |
3266 Register object = a1; | 3250 Register object = a1; |
3267 Register index = a0; | 3251 Register index = a0; |
3268 Register result = v0; | 3252 Register result = v0; |
3269 | 3253 |
3270 __ pop(object); | 3254 PopOperand(object); |
3271 | 3255 |
3272 Label need_conversion; | 3256 Label need_conversion; |
3273 Label index_out_of_range; | 3257 Label index_out_of_range; |
3274 Label done; | 3258 Label done; |
3275 StringCharCodeAtGenerator generator(object, | 3259 StringCharCodeAtGenerator generator(object, |
3276 index, | 3260 index, |
3277 result, | 3261 result, |
3278 &need_conversion, | 3262 &need_conversion, |
3279 &need_conversion, | 3263 &need_conversion, |
3280 &index_out_of_range, | 3264 &index_out_of_range, |
(...skipping 27 matching lines...) Expand all Loading... |
3308 | 3292 |
3309 VisitForStackValue(args->at(0)); | 3293 VisitForStackValue(args->at(0)); |
3310 VisitForAccumulatorValue(args->at(1)); | 3294 VisitForAccumulatorValue(args->at(1)); |
3311 __ mov(a0, result_register()); | 3295 __ mov(a0, result_register()); |
3312 | 3296 |
3313 Register object = a1; | 3297 Register object = a1; |
3314 Register index = a0; | 3298 Register index = a0; |
3315 Register scratch = a3; | 3299 Register scratch = a3; |
3316 Register result = v0; | 3300 Register result = v0; |
3317 | 3301 |
3318 __ pop(object); | 3302 PopOperand(object); |
3319 | 3303 |
3320 Label need_conversion; | 3304 Label need_conversion; |
3321 Label index_out_of_range; | 3305 Label index_out_of_range; |
3322 Label done; | 3306 Label done; |
3323 StringCharAtGenerator generator(object, | 3307 StringCharAtGenerator generator(object, |
3324 index, | 3308 index, |
3325 scratch, | 3309 scratch, |
3326 result, | 3310 result, |
3327 &need_conversion, | 3311 &need_conversion, |
3328 &need_conversion, | 3312 &need_conversion, |
(...skipping 29 matching lines...) Expand all Loading... |
3358 for (Expression* const arg : *args) { | 3342 for (Expression* const arg : *args) { |
3359 VisitForStackValue(arg); | 3343 VisitForStackValue(arg); |
3360 } | 3344 } |
3361 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 3345 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
3362 // Move target to a1. | 3346 // Move target to a1. |
3363 int const argc = args->length() - 2; | 3347 int const argc = args->length() - 2; |
3364 __ lw(a1, MemOperand(sp, (argc + 1) * kPointerSize)); | 3348 __ lw(a1, MemOperand(sp, (argc + 1) * kPointerSize)); |
3365 // Call the target. | 3349 // Call the target. |
3366 __ li(a0, Operand(argc)); | 3350 __ li(a0, Operand(argc)); |
3367 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 3351 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 3352 OperandStackDepthDecrement(argc + 1); |
3368 // Restore context register. | 3353 // Restore context register. |
3369 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3354 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3370 // Discard the function left on TOS. | 3355 // Discard the function left on TOS. |
3371 context()->DropAndPlug(1, v0); | 3356 context()->DropAndPlug(1, v0); |
3372 } | 3357 } |
3373 | 3358 |
3374 | 3359 |
3375 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { | 3360 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { |
3376 ZoneList<Expression*>* args = expr->arguments(); | 3361 ZoneList<Expression*>* args = expr->arguments(); |
3377 VisitForAccumulatorValue(args->at(0)); | 3362 VisitForAccumulatorValue(args->at(0)); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3443 __ LoadRoot(t0, Heap::kEmptyFixedArrayRootIndex); | 3428 __ LoadRoot(t0, Heap::kEmptyFixedArrayRootIndex); |
3444 __ sw(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); | 3429 __ sw(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); |
3445 __ sw(t0, FieldMemOperand(v0, JSObject::kPropertiesOffset)); | 3430 __ sw(t0, FieldMemOperand(v0, JSObject::kPropertiesOffset)); |
3446 __ sw(t0, FieldMemOperand(v0, JSObject::kElementsOffset)); | 3431 __ sw(t0, FieldMemOperand(v0, JSObject::kElementsOffset)); |
3447 __ sw(a2, FieldMemOperand(v0, JSIteratorResult::kValueOffset)); | 3432 __ sw(a2, FieldMemOperand(v0, JSIteratorResult::kValueOffset)); |
3448 __ sw(a3, FieldMemOperand(v0, JSIteratorResult::kDoneOffset)); | 3433 __ sw(a3, FieldMemOperand(v0, JSIteratorResult::kDoneOffset)); |
3449 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); | 3434 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); |
3450 __ jmp(&done); | 3435 __ jmp(&done); |
3451 | 3436 |
3452 __ bind(&runtime); | 3437 __ bind(&runtime); |
3453 __ CallRuntime(Runtime::kCreateIterResultObject); | 3438 CallRuntimeWithOperands(Runtime::kCreateIterResultObject); |
3454 | 3439 |
3455 __ bind(&done); | 3440 __ bind(&done); |
3456 context()->Plug(v0); | 3441 context()->Plug(v0); |
3457 } | 3442 } |
3458 | 3443 |
3459 | 3444 |
3460 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { | 3445 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
3461 // Push undefined as the receiver. | 3446 // Push undefined as the receiver. |
3462 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); | 3447 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); |
3463 __ push(v0); | 3448 PushOperand(v0); |
3464 | 3449 |
3465 __ LoadNativeContextSlot(expr->context_index(), v0); | 3450 __ LoadNativeContextSlot(expr->context_index(), v0); |
3466 } | 3451 } |
3467 | 3452 |
3468 | 3453 |
3469 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 3454 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
3470 ZoneList<Expression*>* args = expr->arguments(); | 3455 ZoneList<Expression*>* args = expr->arguments(); |
3471 int arg_count = args->length(); | 3456 int arg_count = args->length(); |
3472 | 3457 |
3473 SetCallPosition(expr); | 3458 SetCallPosition(expr); |
3474 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 3459 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
3475 __ li(a0, Operand(arg_count)); | 3460 __ li(a0, Operand(arg_count)); |
3476 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), | 3461 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), |
3477 RelocInfo::CODE_TARGET); | 3462 RelocInfo::CODE_TARGET); |
| 3463 OperandStackDepthDecrement(arg_count + 1); |
3478 } | 3464 } |
3479 | 3465 |
3480 | 3466 |
3481 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 3467 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
3482 ZoneList<Expression*>* args = expr->arguments(); | 3468 ZoneList<Expression*>* args = expr->arguments(); |
3483 int arg_count = args->length(); | 3469 int arg_count = args->length(); |
3484 | 3470 |
3485 if (expr->is_jsruntime()) { | 3471 if (expr->is_jsruntime()) { |
3486 Comment cmnt(masm_, "[ CallRuntime"); | 3472 Comment cmnt(masm_, "[ CallRuntime"); |
3487 EmitLoadJSRuntimeFunction(expr); | 3473 EmitLoadJSRuntimeFunction(expr); |
3488 | 3474 |
3489 // Push the target function under the receiver. | 3475 // Push the target function under the receiver. |
3490 __ lw(at, MemOperand(sp, 0)); | 3476 __ lw(at, MemOperand(sp, 0)); |
3491 __ push(at); | 3477 PushOperand(at); |
3492 __ sw(v0, MemOperand(sp, kPointerSize)); | 3478 __ sw(v0, MemOperand(sp, kPointerSize)); |
3493 | 3479 |
3494 // Push the arguments ("left-to-right"). | 3480 // Push the arguments ("left-to-right"). |
3495 for (int i = 0; i < arg_count; i++) { | 3481 for (int i = 0; i < arg_count; i++) { |
3496 VisitForStackValue(args->at(i)); | 3482 VisitForStackValue(args->at(i)); |
3497 } | 3483 } |
3498 | 3484 |
3499 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 3485 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
3500 EmitCallJSRuntimeFunction(expr); | 3486 EmitCallJSRuntimeFunction(expr); |
3501 | 3487 |
(...skipping 15 matching lines...) Expand all Loading... |
3517 default: { | 3503 default: { |
3518 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic"); | 3504 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic"); |
3519 // Push the arguments ("left-to-right"). | 3505 // Push the arguments ("left-to-right"). |
3520 for (int i = 0; i < arg_count; i++) { | 3506 for (int i = 0; i < arg_count; i++) { |
3521 VisitForStackValue(args->at(i)); | 3507 VisitForStackValue(args->at(i)); |
3522 } | 3508 } |
3523 | 3509 |
3524 // Call the C runtime function. | 3510 // Call the C runtime function. |
3525 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 3511 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
3526 __ CallRuntime(expr->function(), arg_count); | 3512 __ CallRuntime(expr->function(), arg_count); |
| 3513 OperandStackDepthDecrement(arg_count); |
3527 context()->Plug(v0); | 3514 context()->Plug(v0); |
3528 } | 3515 } |
3529 } | 3516 } |
3530 } | 3517 } |
3531 } | 3518 } |
3532 | 3519 |
3533 | 3520 |
3534 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 3521 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
3535 switch (expr->op()) { | 3522 switch (expr->op()) { |
3536 case Token::DELETE: { | 3523 case Token::DELETE: { |
3537 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); | 3524 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); |
3538 Property* property = expr->expression()->AsProperty(); | 3525 Property* property = expr->expression()->AsProperty(); |
3539 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 3526 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
3540 | 3527 |
3541 if (property != NULL) { | 3528 if (property != NULL) { |
3542 VisitForStackValue(property->obj()); | 3529 VisitForStackValue(property->obj()); |
3543 VisitForStackValue(property->key()); | 3530 VisitForStackValue(property->key()); |
3544 __ CallRuntime(is_strict(language_mode()) | 3531 CallRuntimeWithOperands(is_strict(language_mode()) |
3545 ? Runtime::kDeleteProperty_Strict | 3532 ? Runtime::kDeleteProperty_Strict |
3546 : Runtime::kDeleteProperty_Sloppy); | 3533 : Runtime::kDeleteProperty_Sloppy); |
3547 context()->Plug(v0); | 3534 context()->Plug(v0); |
3548 } else if (proxy != NULL) { | 3535 } else if (proxy != NULL) { |
3549 Variable* var = proxy->var(); | 3536 Variable* var = proxy->var(); |
3550 // Delete of an unqualified identifier is disallowed in strict mode but | 3537 // Delete of an unqualified identifier is disallowed in strict mode but |
3551 // "delete this" is allowed. | 3538 // "delete this" is allowed. |
3552 bool is_this = var->HasThisName(isolate()); | 3539 bool is_this = var->HasThisName(isolate()); |
3553 DCHECK(is_sloppy(language_mode()) || is_this); | 3540 DCHECK(is_sloppy(language_mode()) || is_this); |
3554 if (var->IsUnallocatedOrGlobalSlot()) { | 3541 if (var->IsUnallocatedOrGlobalSlot()) { |
3555 __ LoadGlobalObject(a2); | 3542 __ LoadGlobalObject(a2); |
3556 __ li(a1, Operand(var->name())); | 3543 __ li(a1, Operand(var->name())); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3602 // We handle value contexts explicitly rather than simply visiting | 3589 // We handle value contexts explicitly rather than simply visiting |
3603 // for control and plugging the control flow into the context, | 3590 // for control and plugging the control flow into the context, |
3604 // because we need to prepare a pair of extra administrative AST ids | 3591 // because we need to prepare a pair of extra administrative AST ids |
3605 // for the optimizing compiler. | 3592 // for the optimizing compiler. |
3606 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); | 3593 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); |
3607 Label materialize_true, materialize_false, done; | 3594 Label materialize_true, materialize_false, done; |
3608 VisitForControl(expr->expression(), | 3595 VisitForControl(expr->expression(), |
3609 &materialize_false, | 3596 &materialize_false, |
3610 &materialize_true, | 3597 &materialize_true, |
3611 &materialize_true); | 3598 &materialize_true); |
| 3599 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1); |
3612 __ bind(&materialize_true); | 3600 __ bind(&materialize_true); |
3613 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); | 3601 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); |
3614 __ LoadRoot(v0, Heap::kTrueValueRootIndex); | 3602 __ LoadRoot(v0, Heap::kTrueValueRootIndex); |
3615 if (context()->IsStackValue()) __ push(v0); | 3603 if (context()->IsStackValue()) __ push(v0); |
3616 __ jmp(&done); | 3604 __ jmp(&done); |
3617 __ bind(&materialize_false); | 3605 __ bind(&materialize_false); |
3618 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); | 3606 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); |
3619 __ LoadRoot(v0, Heap::kFalseValueRootIndex); | 3607 __ LoadRoot(v0, Heap::kFalseValueRootIndex); |
3620 if (context()->IsStackValue()) __ push(v0); | 3608 if (context()->IsStackValue()) __ push(v0); |
3621 __ bind(&done); | 3609 __ bind(&done); |
(...skipping 30 matching lines...) Expand all Loading... |
3652 | 3640 |
3653 // Evaluate expression and get value. | 3641 // Evaluate expression and get value. |
3654 if (assign_type == VARIABLE) { | 3642 if (assign_type == VARIABLE) { |
3655 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 3643 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
3656 AccumulatorValueContext context(this); | 3644 AccumulatorValueContext context(this); |
3657 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 3645 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
3658 } else { | 3646 } else { |
3659 // Reserve space for result of postfix operation. | 3647 // Reserve space for result of postfix operation. |
3660 if (expr->is_postfix() && !context()->IsEffect()) { | 3648 if (expr->is_postfix() && !context()->IsEffect()) { |
3661 __ li(at, Operand(Smi::FromInt(0))); | 3649 __ li(at, Operand(Smi::FromInt(0))); |
3662 __ push(at); | 3650 PushOperand(at); |
3663 } | 3651 } |
3664 switch (assign_type) { | 3652 switch (assign_type) { |
3665 case NAMED_PROPERTY: { | 3653 case NAMED_PROPERTY: { |
3666 // Put the object both on the stack and in the register. | 3654 // Put the object both on the stack and in the register. |
3667 VisitForStackValue(prop->obj()); | 3655 VisitForStackValue(prop->obj()); |
3668 __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); | 3656 __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); |
3669 EmitNamedPropertyLoad(prop); | 3657 EmitNamedPropertyLoad(prop); |
3670 break; | 3658 break; |
3671 } | 3659 } |
3672 | 3660 |
3673 case NAMED_SUPER_PROPERTY: { | 3661 case NAMED_SUPER_PROPERTY: { |
3674 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 3662 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
3675 VisitForAccumulatorValue( | 3663 VisitForAccumulatorValue( |
3676 prop->obj()->AsSuperPropertyReference()->home_object()); | 3664 prop->obj()->AsSuperPropertyReference()->home_object()); |
3677 __ Push(result_register()); | 3665 PushOperand(result_register()); |
3678 const Register scratch = a1; | 3666 const Register scratch = a1; |
3679 __ lw(scratch, MemOperand(sp, kPointerSize)); | 3667 __ lw(scratch, MemOperand(sp, kPointerSize)); |
3680 __ Push(scratch, result_register()); | 3668 PushOperands(scratch, result_register()); |
3681 EmitNamedSuperPropertyLoad(prop); | 3669 EmitNamedSuperPropertyLoad(prop); |
3682 break; | 3670 break; |
3683 } | 3671 } |
3684 | 3672 |
3685 case KEYED_SUPER_PROPERTY: { | 3673 case KEYED_SUPER_PROPERTY: { |
3686 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 3674 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
3687 VisitForAccumulatorValue( | 3675 VisitForAccumulatorValue( |
3688 prop->obj()->AsSuperPropertyReference()->home_object()); | 3676 prop->obj()->AsSuperPropertyReference()->home_object()); |
3689 const Register scratch = a1; | 3677 const Register scratch = a1; |
3690 const Register scratch1 = t0; | 3678 const Register scratch1 = t0; |
3691 __ Move(scratch, result_register()); | 3679 __ Move(scratch, result_register()); |
3692 VisitForAccumulatorValue(prop->key()); | 3680 VisitForAccumulatorValue(prop->key()); |
3693 __ Push(scratch, result_register()); | 3681 PushOperands(scratch, result_register()); |
3694 __ lw(scratch1, MemOperand(sp, 2 * kPointerSize)); | 3682 __ lw(scratch1, MemOperand(sp, 2 * kPointerSize)); |
3695 __ Push(scratch1, scratch, result_register()); | 3683 PushOperands(scratch1, scratch, result_register()); |
3696 EmitKeyedSuperPropertyLoad(prop); | 3684 EmitKeyedSuperPropertyLoad(prop); |
3697 break; | 3685 break; |
3698 } | 3686 } |
3699 | 3687 |
3700 case KEYED_PROPERTY: { | 3688 case KEYED_PROPERTY: { |
3701 VisitForStackValue(prop->obj()); | 3689 VisitForStackValue(prop->obj()); |
3702 VisitForStackValue(prop->key()); | 3690 VisitForStackValue(prop->key()); |
3703 __ lw(LoadDescriptor::ReceiverRegister(), | 3691 __ lw(LoadDescriptor::ReceiverRegister(), |
3704 MemOperand(sp, 1 * kPointerSize)); | 3692 MemOperand(sp, 1 * kPointerSize)); |
3705 __ lw(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); | 3693 __ lw(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3771 } | 3759 } |
3772 | 3760 |
3773 // Save result for postfix expressions. | 3761 // Save result for postfix expressions. |
3774 if (expr->is_postfix()) { | 3762 if (expr->is_postfix()) { |
3775 if (!context()->IsEffect()) { | 3763 if (!context()->IsEffect()) { |
3776 // Save the result on the stack. If we have a named or keyed property | 3764 // Save the result on the stack. If we have a named or keyed property |
3777 // we store the result under the receiver that is currently on top | 3765 // we store the result under the receiver that is currently on top |
3778 // of the stack. | 3766 // of the stack. |
3779 switch (assign_type) { | 3767 switch (assign_type) { |
3780 case VARIABLE: | 3768 case VARIABLE: |
3781 __ push(v0); | 3769 PushOperand(v0); |
3782 break; | 3770 break; |
3783 case NAMED_PROPERTY: | 3771 case NAMED_PROPERTY: |
3784 __ sw(v0, MemOperand(sp, kPointerSize)); | 3772 __ sw(v0, MemOperand(sp, kPointerSize)); |
3785 break; | 3773 break; |
3786 case NAMED_SUPER_PROPERTY: | 3774 case NAMED_SUPER_PROPERTY: |
3787 __ sw(v0, MemOperand(sp, 2 * kPointerSize)); | 3775 __ sw(v0, MemOperand(sp, 2 * kPointerSize)); |
3788 break; | 3776 break; |
3789 case KEYED_PROPERTY: | 3777 case KEYED_PROPERTY: |
3790 __ sw(v0, MemOperand(sp, 2 * kPointerSize)); | 3778 __ sw(v0, MemOperand(sp, 2 * kPointerSize)); |
3791 break; | 3779 break; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3829 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3817 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
3830 Token::ASSIGN, expr->CountSlot()); | 3818 Token::ASSIGN, expr->CountSlot()); |
3831 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3819 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3832 context()->Plug(v0); | 3820 context()->Plug(v0); |
3833 } | 3821 } |
3834 break; | 3822 break; |
3835 case NAMED_PROPERTY: { | 3823 case NAMED_PROPERTY: { |
3836 __ mov(StoreDescriptor::ValueRegister(), result_register()); | 3824 __ mov(StoreDescriptor::ValueRegister(), result_register()); |
3837 __ li(StoreDescriptor::NameRegister(), | 3825 __ li(StoreDescriptor::NameRegister(), |
3838 Operand(prop->key()->AsLiteral()->value())); | 3826 Operand(prop->key()->AsLiteral()->value())); |
3839 __ pop(StoreDescriptor::ReceiverRegister()); | 3827 PopOperand(StoreDescriptor::ReceiverRegister()); |
3840 EmitLoadStoreICSlot(expr->CountSlot()); | 3828 EmitLoadStoreICSlot(expr->CountSlot()); |
3841 CallStoreIC(); | 3829 CallStoreIC(); |
3842 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3830 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3843 if (expr->is_postfix()) { | 3831 if (expr->is_postfix()) { |
3844 if (!context()->IsEffect()) { | 3832 if (!context()->IsEffect()) { |
3845 context()->PlugTOS(); | 3833 context()->PlugTOS(); |
3846 } | 3834 } |
3847 } else { | 3835 } else { |
3848 context()->Plug(v0); | 3836 context()->Plug(v0); |
3849 } | 3837 } |
(...skipping 16 matching lines...) Expand all Loading... |
3866 if (!context()->IsEffect()) { | 3854 if (!context()->IsEffect()) { |
3867 context()->PlugTOS(); | 3855 context()->PlugTOS(); |
3868 } | 3856 } |
3869 } else { | 3857 } else { |
3870 context()->Plug(v0); | 3858 context()->Plug(v0); |
3871 } | 3859 } |
3872 break; | 3860 break; |
3873 } | 3861 } |
3874 case KEYED_PROPERTY: { | 3862 case KEYED_PROPERTY: { |
3875 __ mov(StoreDescriptor::ValueRegister(), result_register()); | 3863 __ mov(StoreDescriptor::ValueRegister(), result_register()); |
3876 __ Pop(StoreDescriptor::ReceiverRegister(), | 3864 PopOperands(StoreDescriptor::ReceiverRegister(), |
3877 StoreDescriptor::NameRegister()); | 3865 StoreDescriptor::NameRegister()); |
3878 Handle<Code> ic = | 3866 Handle<Code> ic = |
3879 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 3867 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
3880 EmitLoadStoreICSlot(expr->CountSlot()); | 3868 EmitLoadStoreICSlot(expr->CountSlot()); |
3881 CallIC(ic); | 3869 CallIC(ic); |
3882 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3870 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3883 if (expr->is_postfix()) { | 3871 if (expr->is_postfix()) { |
3884 if (!context()->IsEffect()) { | 3872 if (!context()->IsEffect()) { |
3885 context()->PlugTOS(); | 3873 context()->PlugTOS(); |
3886 } | 3874 } |
3887 } else { | 3875 } else { |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3989 Label* if_false = NULL; | 3977 Label* if_false = NULL; |
3990 Label* fall_through = NULL; | 3978 Label* fall_through = NULL; |
3991 context()->PrepareTest(&materialize_true, &materialize_false, | 3979 context()->PrepareTest(&materialize_true, &materialize_false, |
3992 &if_true, &if_false, &fall_through); | 3980 &if_true, &if_false, &fall_through); |
3993 | 3981 |
3994 Token::Value op = expr->op(); | 3982 Token::Value op = expr->op(); |
3995 VisitForStackValue(expr->left()); | 3983 VisitForStackValue(expr->left()); |
3996 switch (op) { | 3984 switch (op) { |
3997 case Token::IN: | 3985 case Token::IN: |
3998 VisitForStackValue(expr->right()); | 3986 VisitForStackValue(expr->right()); |
3999 __ CallRuntime(Runtime::kHasProperty); | 3987 CallRuntimeWithOperands(Runtime::kHasProperty); |
4000 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); | 3988 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); |
4001 __ LoadRoot(t0, Heap::kTrueValueRootIndex); | 3989 __ LoadRoot(t0, Heap::kTrueValueRootIndex); |
4002 Split(eq, v0, Operand(t0), if_true, if_false, fall_through); | 3990 Split(eq, v0, Operand(t0), if_true, if_false, fall_through); |
4003 break; | 3991 break; |
4004 | 3992 |
4005 case Token::INSTANCEOF: { | 3993 case Token::INSTANCEOF: { |
4006 VisitForAccumulatorValue(expr->right()); | 3994 VisitForAccumulatorValue(expr->right()); |
4007 __ mov(a0, result_register()); | 3995 __ mov(a0, result_register()); |
4008 __ pop(a1); | 3996 PopOperand(a1); |
4009 InstanceOfStub stub(isolate()); | 3997 InstanceOfStub stub(isolate()); |
4010 __ CallStub(&stub); | 3998 __ CallStub(&stub); |
4011 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); | 3999 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); |
4012 __ LoadRoot(at, Heap::kTrueValueRootIndex); | 4000 __ LoadRoot(at, Heap::kTrueValueRootIndex); |
4013 Split(eq, v0, Operand(at), if_true, if_false, fall_through); | 4001 Split(eq, v0, Operand(at), if_true, if_false, fall_through); |
4014 break; | 4002 break; |
4015 } | 4003 } |
4016 | 4004 |
4017 default: { | 4005 default: { |
4018 VisitForAccumulatorValue(expr->right()); | 4006 VisitForAccumulatorValue(expr->right()); |
4019 Condition cc = CompareIC::ComputeCondition(op); | 4007 Condition cc = CompareIC::ComputeCondition(op); |
4020 __ mov(a0, result_register()); | 4008 __ mov(a0, result_register()); |
4021 __ pop(a1); | 4009 PopOperand(a1); |
4022 | 4010 |
4023 bool inline_smi_code = ShouldInlineSmiCase(op); | 4011 bool inline_smi_code = ShouldInlineSmiCase(op); |
4024 JumpPatchSite patch_site(masm_); | 4012 JumpPatchSite patch_site(masm_); |
4025 if (inline_smi_code) { | 4013 if (inline_smi_code) { |
4026 Label slow_case; | 4014 Label slow_case; |
4027 __ Or(a2, a0, Operand(a1)); | 4015 __ Or(a2, a0, Operand(a1)); |
4028 patch_site.EmitJumpIfNotSmi(a2, &slow_case); | 4016 patch_site.EmitJumpIfNotSmi(a2, &slow_case); |
4029 Split(cc, a1, Operand(a0), if_true, if_false, NULL); | 4017 Split(cc, a1, Operand(a0), if_true, if_false, NULL); |
4030 __ bind(&slow_case); | 4018 __ bind(&slow_case); |
4031 } | 4019 } |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4110 __ LoadNativeContextSlot(Context::CLOSURE_INDEX, at); | 4098 __ LoadNativeContextSlot(Context::CLOSURE_INDEX, at); |
4111 } else if (closure_scope->is_eval_scope()) { | 4099 } else if (closure_scope->is_eval_scope()) { |
4112 // Contexts created by a call to eval have the same closure as the | 4100 // Contexts created by a call to eval have the same closure as the |
4113 // context calling eval, not the anonymous closure containing the eval | 4101 // context calling eval, not the anonymous closure containing the eval |
4114 // code. Fetch it from the context. | 4102 // code. Fetch it from the context. |
4115 __ lw(at, ContextMemOperand(cp, Context::CLOSURE_INDEX)); | 4103 __ lw(at, ContextMemOperand(cp, Context::CLOSURE_INDEX)); |
4116 } else { | 4104 } else { |
4117 DCHECK(closure_scope->is_function_scope()); | 4105 DCHECK(closure_scope->is_function_scope()); |
4118 __ lw(at, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 4106 __ lw(at, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
4119 } | 4107 } |
4120 __ push(at); | 4108 PushOperand(at); |
4121 } | 4109 } |
4122 | 4110 |
4123 | 4111 |
4124 // ---------------------------------------------------------------------------- | 4112 // ---------------------------------------------------------------------------- |
4125 // Non-local control flow support. | 4113 // Non-local control flow support. |
4126 | 4114 |
4127 void FullCodeGenerator::EnterFinallyBlock() { | 4115 void FullCodeGenerator::EnterFinallyBlock() { |
4128 DCHECK(!result_register().is(a1)); | 4116 DCHECK(!result_register().is(a1)); |
4129 // Store pending message while executing finally block. | 4117 // Store pending message while executing finally block. |
4130 ExternalReference pending_message_obj = | 4118 ExternalReference pending_message_obj = |
4131 ExternalReference::address_of_pending_message_obj(isolate()); | 4119 ExternalReference::address_of_pending_message_obj(isolate()); |
4132 __ li(at, Operand(pending_message_obj)); | 4120 __ li(at, Operand(pending_message_obj)); |
4133 __ lw(a1, MemOperand(at)); | 4121 __ lw(a1, MemOperand(at)); |
4134 __ push(a1); | 4122 PushOperand(a1); |
4135 | 4123 |
4136 ClearPendingMessage(); | 4124 ClearPendingMessage(); |
4137 } | 4125 } |
4138 | 4126 |
4139 | 4127 |
4140 void FullCodeGenerator::ExitFinallyBlock() { | 4128 void FullCodeGenerator::ExitFinallyBlock() { |
4141 DCHECK(!result_register().is(a1)); | 4129 DCHECK(!result_register().is(a1)); |
4142 // Restore pending message from stack. | 4130 // Restore pending message from stack. |
4143 __ pop(a1); | 4131 PopOperand(a1); |
4144 ExternalReference pending_message_obj = | 4132 ExternalReference pending_message_obj = |
4145 ExternalReference::address_of_pending_message_obj(isolate()); | 4133 ExternalReference::address_of_pending_message_obj(isolate()); |
4146 __ li(at, Operand(pending_message_obj)); | 4134 __ li(at, Operand(pending_message_obj)); |
4147 __ sw(a1, MemOperand(at)); | 4135 __ sw(a1, MemOperand(at)); |
4148 } | 4136 } |
4149 | 4137 |
4150 | 4138 |
4151 void FullCodeGenerator::ClearPendingMessage() { | 4139 void FullCodeGenerator::ClearPendingMessage() { |
4152 DCHECK(!result_register().is(a1)); | 4140 DCHECK(!result_register().is(a1)); |
4153 ExternalReference pending_message_obj = | 4141 ExternalReference pending_message_obj = |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4268 reinterpret_cast<uint32_t>( | 4256 reinterpret_cast<uint32_t>( |
4269 isolate->builtins()->OsrAfterStackCheck()->entry())); | 4257 isolate->builtins()->OsrAfterStackCheck()->entry())); |
4270 return OSR_AFTER_STACK_CHECK; | 4258 return OSR_AFTER_STACK_CHECK; |
4271 } | 4259 } |
4272 | 4260 |
4273 | 4261 |
4274 } // namespace internal | 4262 } // namespace internal |
4275 } // namespace v8 | 4263 } // namespace v8 |
4276 | 4264 |
4277 #endif // V8_TARGET_ARCH_MIPS | 4265 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |