| 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 (generate_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 |