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