| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
| 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 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 // Push(lr, fp, cp, x1); | 128 // Push(lr, fp, cp, x1); |
| 129 // Add(fp, jssp, 2 * kPointerSize); | 129 // Add(fp, jssp, 2 * kPointerSize); |
| 130 info->set_prologue_offset(masm_->pc_offset()); | 130 info->set_prologue_offset(masm_->pc_offset()); |
| 131 __ Prologue(info->GeneratePreagedPrologue()); | 131 __ Prologue(info->GeneratePreagedPrologue()); |
| 132 | 132 |
| 133 // Reserve space on the stack for locals. | 133 // Reserve space on the stack for locals. |
| 134 { Comment cmnt(masm_, "[ Allocate locals"); | 134 { Comment cmnt(masm_, "[ Allocate locals"); |
| 135 int locals_count = info->scope()->num_stack_slots(); | 135 int locals_count = info->scope()->num_stack_slots(); |
| 136 // Generators allocate locals, if any, in context slots. | 136 // Generators allocate locals, if any, in context slots. |
| 137 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0); | 137 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0); |
| 138 | 138 OperandStackDepthIncrement(locals_count); |
| 139 if (locals_count > 0) { | 139 if (locals_count > 0) { |
| 140 if (locals_count >= 128) { | 140 if (locals_count >= 128) { |
| 141 Label ok; | 141 Label ok; |
| 142 DCHECK(jssp.Is(__ StackPointer())); | 142 DCHECK(jssp.Is(__ StackPointer())); |
| 143 __ Sub(x10, jssp, locals_count * kPointerSize); | 143 __ Sub(x10, jssp, locals_count * kPointerSize); |
| 144 __ CompareRoot(x10, Heap::kRealStackLimitRootIndex); | 144 __ CompareRoot(x10, Heap::kRealStackLimitRootIndex); |
| 145 __ B(hs, &ok); | 145 __ B(hs, &ok); |
| 146 __ CallRuntime(Runtime::kThrowStackOverflow); | 146 __ CallRuntime(Runtime::kThrowStackOverflow); |
| 147 __ Bind(&ok); | 147 __ Bind(&ok); |
| 148 } | 148 } |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 __ Ret(); | 463 __ Ret(); |
| 464 int32_t arg_count = info_->scope()->num_parameters() + 1; | 464 int32_t arg_count = info_->scope()->num_parameters() + 1; |
| 465 __ dc64(kXRegSize * arg_count); | 465 __ dc64(kXRegSize * arg_count); |
| 466 } | 466 } |
| 467 } | 467 } |
| 468 | 468 |
| 469 | 469 |
| 470 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { | 470 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { |
| 471 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 471 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 472 codegen()->GetVar(result_register(), var); | 472 codegen()->GetVar(result_register(), var); |
| 473 __ Push(result_register()); | 473 codegen()->PushOperand(result_register()); |
| 474 } | 474 } |
| 475 | 475 |
| 476 | 476 |
| 477 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { | 477 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { |
| 478 // Root values have no side effects. | 478 // Root values have no side effects. |
| 479 } | 479 } |
| 480 | 480 |
| 481 | 481 |
| 482 void FullCodeGenerator::AccumulatorValueContext::Plug( | 482 void FullCodeGenerator::AccumulatorValueContext::Plug( |
| 483 Heap::RootListIndex index) const { | 483 Heap::RootListIndex index) const { |
| 484 __ LoadRoot(result_register(), index); | 484 __ LoadRoot(result_register(), index); |
| 485 } | 485 } |
| 486 | 486 |
| 487 | 487 |
| 488 void FullCodeGenerator::StackValueContext::Plug( | 488 void FullCodeGenerator::StackValueContext::Plug( |
| 489 Heap::RootListIndex index) const { | 489 Heap::RootListIndex index) const { |
| 490 __ LoadRoot(result_register(), index); | 490 __ LoadRoot(result_register(), index); |
| 491 __ Push(result_register()); | 491 codegen()->PushOperand(result_register()); |
| 492 } | 492 } |
| 493 | 493 |
| 494 | 494 |
| 495 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const { | 495 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const { |
| 496 codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_, | 496 codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_, |
| 497 false_label_); | 497 false_label_); |
| 498 if (index == Heap::kUndefinedValueRootIndex || | 498 if (index == Heap::kUndefinedValueRootIndex || |
| 499 index == Heap::kNullValueRootIndex || | 499 index == Heap::kNullValueRootIndex || |
| 500 index == Heap::kFalseValueRootIndex) { | 500 index == Heap::kFalseValueRootIndex) { |
| 501 if (false_label_ != fall_through_) __ B(false_label_); | 501 if (false_label_ != fall_through_) __ B(false_label_); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 514 | 514 |
| 515 void FullCodeGenerator::AccumulatorValueContext::Plug( | 515 void FullCodeGenerator::AccumulatorValueContext::Plug( |
| 516 Handle<Object> lit) const { | 516 Handle<Object> lit) const { |
| 517 __ Mov(result_register(), Operand(lit)); | 517 __ Mov(result_register(), Operand(lit)); |
| 518 } | 518 } |
| 519 | 519 |
| 520 | 520 |
| 521 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { | 521 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { |
| 522 // Immediates cannot be pushed directly. | 522 // Immediates cannot be pushed directly. |
| 523 __ Mov(result_register(), Operand(lit)); | 523 __ Mov(result_register(), Operand(lit)); |
| 524 __ Push(result_register()); | 524 codegen()->PushOperand(result_register()); |
| 525 } | 525 } |
| 526 | 526 |
| 527 | 527 |
| 528 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { | 528 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { |
| 529 codegen()->PrepareForBailoutBeforeSplit(condition(), | 529 codegen()->PrepareForBailoutBeforeSplit(condition(), |
| 530 true, | 530 true, |
| 531 true_label_, | 531 true_label_, |
| 532 false_label_); | 532 false_label_); |
| 533 DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectableObject()); | 533 DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectableObject()); |
| 534 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) { | 534 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 548 if (true_label_ != fall_through_) __ B(true_label_); | 548 if (true_label_ != fall_through_) __ B(true_label_); |
| 549 } | 549 } |
| 550 } else { | 550 } else { |
| 551 // For simplicity we always test the accumulator register. | 551 // For simplicity we always test the accumulator register. |
| 552 __ Mov(result_register(), Operand(lit)); | 552 __ Mov(result_register(), Operand(lit)); |
| 553 codegen()->DoTest(this); | 553 codegen()->DoTest(this); |
| 554 } | 554 } |
| 555 } | 555 } |
| 556 | 556 |
| 557 | 557 |
| 558 void FullCodeGenerator::EffectContext::DropAndPlug(int count, | |
| 559 Register reg) const { | |
| 560 DCHECK(count > 0); | |
| 561 __ Drop(count); | |
| 562 } | |
| 563 | |
| 564 | |
| 565 void FullCodeGenerator::AccumulatorValueContext::DropAndPlug( | |
| 566 int count, | |
| 567 Register reg) const { | |
| 568 DCHECK(count > 0); | |
| 569 __ Drop(count); | |
| 570 __ Move(result_register(), reg); | |
| 571 } | |
| 572 | |
| 573 | |
| 574 void FullCodeGenerator::StackValueContext::DropAndPlug(int count, | 558 void FullCodeGenerator::StackValueContext::DropAndPlug(int count, |
| 575 Register reg) const { | 559 Register reg) const { |
| 576 DCHECK(count > 0); | 560 DCHECK(count > 0); |
| 577 if (count > 1) __ Drop(count - 1); | 561 if (count > 1) codegen()->DropOperands(count - 1); |
| 578 __ Poke(reg, 0); | 562 __ Poke(reg, 0); |
| 579 } | 563 } |
| 580 | 564 |
| 581 | 565 |
| 582 void FullCodeGenerator::TestContext::DropAndPlug(int count, | |
| 583 Register reg) const { | |
| 584 DCHECK(count > 0); | |
| 585 // For simplicity we always test the accumulator register. | |
| 586 __ Drop(count); | |
| 587 __ Mov(result_register(), reg); | |
| 588 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); | |
| 589 codegen()->DoTest(this); | |
| 590 } | |
| 591 | |
| 592 | |
| 593 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, | 566 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, |
| 594 Label* materialize_false) const { | 567 Label* materialize_false) const { |
| 595 DCHECK(materialize_true == materialize_false); | 568 DCHECK(materialize_true == materialize_false); |
| 596 __ Bind(materialize_true); | 569 __ Bind(materialize_true); |
| 597 } | 570 } |
| 598 | 571 |
| 599 | 572 |
| 600 void FullCodeGenerator::AccumulatorValueContext::Plug( | 573 void FullCodeGenerator::AccumulatorValueContext::Plug( |
| 601 Label* materialize_true, | 574 Label* materialize_true, |
| 602 Label* materialize_false) const { | 575 Label* materialize_false) const { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 613 void FullCodeGenerator::StackValueContext::Plug( | 586 void FullCodeGenerator::StackValueContext::Plug( |
| 614 Label* materialize_true, | 587 Label* materialize_true, |
| 615 Label* materialize_false) const { | 588 Label* materialize_false) const { |
| 616 Label done; | 589 Label done; |
| 617 __ Bind(materialize_true); | 590 __ Bind(materialize_true); |
| 618 __ LoadRoot(x10, Heap::kTrueValueRootIndex); | 591 __ LoadRoot(x10, Heap::kTrueValueRootIndex); |
| 619 __ B(&done); | 592 __ B(&done); |
| 620 __ Bind(materialize_false); | 593 __ Bind(materialize_false); |
| 621 __ LoadRoot(x10, Heap::kFalseValueRootIndex); | 594 __ LoadRoot(x10, Heap::kFalseValueRootIndex); |
| 622 __ Bind(&done); | 595 __ Bind(&done); |
| 623 __ Push(x10); | 596 codegen()->PushOperand(x10); |
| 624 } | 597 } |
| 625 | 598 |
| 626 | 599 |
| 627 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, | 600 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, |
| 628 Label* materialize_false) const { | 601 Label* materialize_false) const { |
| 629 DCHECK(materialize_true == true_label_); | 602 DCHECK(materialize_true == true_label_); |
| 630 DCHECK(materialize_false == false_label_); | 603 DCHECK(materialize_false == false_label_); |
| 631 } | 604 } |
| 632 | 605 |
| 633 | 606 |
| 634 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { | 607 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { |
| 635 Heap::RootListIndex value_root_index = | 608 Heap::RootListIndex value_root_index = |
| 636 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 609 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
| 637 __ LoadRoot(result_register(), value_root_index); | 610 __ LoadRoot(result_register(), value_root_index); |
| 638 } | 611 } |
| 639 | 612 |
| 640 | 613 |
| 641 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { | 614 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { |
| 642 Heap::RootListIndex value_root_index = | 615 Heap::RootListIndex value_root_index = |
| 643 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 616 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
| 644 __ LoadRoot(x10, value_root_index); | 617 __ LoadRoot(x10, value_root_index); |
| 645 __ Push(x10); | 618 codegen()->PushOperand(x10); |
| 646 } | 619 } |
| 647 | 620 |
| 648 | 621 |
| 649 void FullCodeGenerator::TestContext::Plug(bool flag) const { | 622 void FullCodeGenerator::TestContext::Plug(bool flag) const { |
| 650 codegen()->PrepareForBailoutBeforeSplit(condition(), | 623 codegen()->PrepareForBailoutBeforeSplit(condition(), |
| 651 true, | 624 true, |
| 652 true_label_, | 625 true_label_, |
| 653 false_label_); | 626 false_label_); |
| 654 if (flag) { | 627 if (flag) { |
| 655 if (true_label_ != fall_through_) { | 628 if (true_label_ != fall_through_) { |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 885 kDontSaveFPRegs, | 858 kDontSaveFPRegs, |
| 886 EMIT_REMEMBERED_SET, | 859 EMIT_REMEMBERED_SET, |
| 887 OMIT_SMI_CHECK); | 860 OMIT_SMI_CHECK); |
| 888 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); | 861 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); |
| 889 break; | 862 break; |
| 890 } | 863 } |
| 891 | 864 |
| 892 case VariableLocation::LOOKUP: { | 865 case VariableLocation::LOOKUP: { |
| 893 Comment cmnt(masm_, "[ Function Declaration"); | 866 Comment cmnt(masm_, "[ Function Declaration"); |
| 894 __ Mov(x2, Operand(variable->name())); | 867 __ Mov(x2, Operand(variable->name())); |
| 895 __ Push(x2); | 868 PushOperand(x2); |
| 896 // Push initial value for function declaration. | 869 // Push initial value for function declaration. |
| 897 VisitForStackValue(declaration->fun()); | 870 VisitForStackValue(declaration->fun()); |
| 898 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); | 871 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes())); |
| 899 __ CallRuntime(Runtime::kDeclareLookupSlot); | 872 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot); |
| 900 break; | 873 break; |
| 901 } | 874 } |
| 902 } | 875 } |
| 903 } | 876 } |
| 904 | 877 |
| 905 | 878 |
| 906 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 879 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
| 907 // Call the runtime to declare the globals. | 880 // Call the runtime to declare the globals. |
| 908 __ Mov(x11, Operand(pairs)); | 881 __ Mov(x11, Operand(pairs)); |
| 909 Register flags = xzr; | 882 Register flags = xzr; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 987 __ Bind(&skip); | 960 __ Bind(&skip); |
| 988 | 961 |
| 989 __ Cbnz(x0, &next_test); | 962 __ Cbnz(x0, &next_test); |
| 990 __ Drop(1); // Switch value is no longer needed. | 963 __ Drop(1); // Switch value is no longer needed. |
| 991 __ B(clause->body_target()); | 964 __ B(clause->body_target()); |
| 992 } | 965 } |
| 993 | 966 |
| 994 // 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 |
| 995 // the end of the statement. | 968 // the end of the statement. |
| 996 __ Bind(&next_test); | 969 __ Bind(&next_test); |
| 997 __ Drop(1); // Switch value is no longer needed. | 970 DropOperands(1); // Switch value is no longer needed. |
| 998 if (default_clause == NULL) { | 971 if (default_clause == NULL) { |
| 999 __ B(nested_statement.break_label()); | 972 __ B(nested_statement.break_label()); |
| 1000 } else { | 973 } else { |
| 1001 __ B(default_clause->body_target()); | 974 __ B(default_clause->body_target()); |
| 1002 } | 975 } |
| 1003 | 976 |
| 1004 // Compile all the case bodies. | 977 // Compile all the case bodies. |
| 1005 for (int i = 0; i < clauses->length(); i++) { | 978 for (int i = 0; i < clauses->length(); i++) { |
| 1006 Comment cmnt(masm_, "[ Case body"); | 979 Comment cmnt(masm_, "[ Case body"); |
| 1007 CaseClause* clause = clauses->at(i); | 980 CaseClause* clause = clauses->at(i); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1024 | 997 |
| 1025 // TODO(all): This visitor probably needs better comments and a revisit. | 998 // TODO(all): This visitor probably needs better comments and a revisit. |
| 1026 | 999 |
| 1027 Label loop, exit; | 1000 Label loop, exit; |
| 1028 ForIn loop_statement(this, stmt); | 1001 ForIn loop_statement(this, stmt); |
| 1029 increment_loop_depth(); | 1002 increment_loop_depth(); |
| 1030 | 1003 |
| 1031 // Get the object to enumerate over. | 1004 // Get the object to enumerate over. |
| 1032 SetExpressionAsStatementPosition(stmt->enumerable()); | 1005 SetExpressionAsStatementPosition(stmt->enumerable()); |
| 1033 VisitForAccumulatorValue(stmt->enumerable()); | 1006 VisitForAccumulatorValue(stmt->enumerable()); |
| 1007 OperandStackDepthIncrement(ForIn::kElementCount); |
| 1034 | 1008 |
| 1035 // If the object is null or undefined, skip over the loop, otherwise convert | 1009 // If the object is null or undefined, skip over the loop, otherwise convert |
| 1036 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. | 1010 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. |
| 1037 Label convert, done_convert; | 1011 Label convert, done_convert; |
| 1038 __ JumpIfSmi(x0, &convert); | 1012 __ JumpIfSmi(x0, &convert); |
| 1039 __ JumpIfObjectType(x0, x10, x11, FIRST_JS_RECEIVER_TYPE, &done_convert, ge); | 1013 __ JumpIfObjectType(x0, x10, x11, FIRST_JS_RECEIVER_TYPE, &done_convert, ge); |
| 1040 __ JumpIfRoot(x0, Heap::kNullValueRootIndex, &exit); | 1014 __ JumpIfRoot(x0, Heap::kNullValueRootIndex, &exit); |
| 1041 __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, &exit); | 1015 __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, &exit); |
| 1042 __ Bind(&convert); | 1016 __ Bind(&convert); |
| 1043 ToObjectStub stub(isolate()); | 1017 ToObjectStub stub(isolate()); |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1175 // TODO(all): We could use a callee saved register to avoid popping. | 1149 // TODO(all): We could use a callee saved register to avoid popping. |
| 1176 __ Pop(x0); | 1150 __ Pop(x0); |
| 1177 __ Add(x0, x0, Smi::FromInt(1)); | 1151 __ Add(x0, x0, Smi::FromInt(1)); |
| 1178 __ Push(x0); | 1152 __ Push(x0); |
| 1179 | 1153 |
| 1180 EmitBackEdgeBookkeeping(stmt, &loop); | 1154 EmitBackEdgeBookkeeping(stmt, &loop); |
| 1181 __ B(&loop); | 1155 __ B(&loop); |
| 1182 | 1156 |
| 1183 // Remove the pointers stored on the stack. | 1157 // Remove the pointers stored on the stack. |
| 1184 __ Bind(loop_statement.break_label()); | 1158 __ Bind(loop_statement.break_label()); |
| 1185 __ Drop(5); | 1159 DropOperands(5); |
| 1186 | 1160 |
| 1187 // Exit and decrement the loop depth. | 1161 // Exit and decrement the loop depth. |
| 1188 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 1162 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
| 1189 __ Bind(&exit); | 1163 __ Bind(&exit); |
| 1190 decrement_loop_depth(); | 1164 decrement_loop_depth(); |
| 1191 } | 1165 } |
| 1192 | 1166 |
| 1193 | 1167 |
| 1194 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, | 1168 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, |
| 1195 bool pretenure) { | 1169 bool pretenure) { |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1444 FastCloneRegExpStub stub(isolate()); | 1418 FastCloneRegExpStub stub(isolate()); |
| 1445 __ CallStub(&stub); | 1419 __ CallStub(&stub); |
| 1446 context()->Plug(x0); | 1420 context()->Plug(x0); |
| 1447 } | 1421 } |
| 1448 | 1422 |
| 1449 | 1423 |
| 1450 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { | 1424 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { |
| 1451 Expression* expression = (property == NULL) ? NULL : property->value(); | 1425 Expression* expression = (property == NULL) ? NULL : property->value(); |
| 1452 if (expression == NULL) { | 1426 if (expression == NULL) { |
| 1453 __ LoadRoot(x10, Heap::kNullValueRootIndex); | 1427 __ LoadRoot(x10, Heap::kNullValueRootIndex); |
| 1454 __ Push(x10); | 1428 PushOperand(x10); |
| 1455 } else { | 1429 } else { |
| 1456 VisitForStackValue(expression); | 1430 VisitForStackValue(expression); |
| 1457 if (NeedsHomeObject(expression)) { | 1431 if (NeedsHomeObject(expression)) { |
| 1458 DCHECK(property->kind() == ObjectLiteral::Property::GETTER || | 1432 DCHECK(property->kind() == ObjectLiteral::Property::GETTER || |
| 1459 property->kind() == ObjectLiteral::Property::SETTER); | 1433 property->kind() == ObjectLiteral::Property::SETTER); |
| 1460 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3; | 1434 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3; |
| 1461 EmitSetHomeObject(expression, offset, property->GetSlot()); | 1435 EmitSetHomeObject(expression, offset, property->GetSlot()); |
| 1462 } | 1436 } |
| 1463 } | 1437 } |
| 1464 } | 1438 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1489 AccessorTable accessor_table(zone()); | 1463 AccessorTable accessor_table(zone()); |
| 1490 int property_index = 0; | 1464 int property_index = 0; |
| 1491 for (; property_index < expr->properties()->length(); property_index++) { | 1465 for (; property_index < expr->properties()->length(); property_index++) { |
| 1492 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1466 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
| 1493 if (property->is_computed_name()) break; | 1467 if (property->is_computed_name()) break; |
| 1494 if (property->IsCompileTimeValue()) continue; | 1468 if (property->IsCompileTimeValue()) continue; |
| 1495 | 1469 |
| 1496 Literal* key = property->key()->AsLiteral(); | 1470 Literal* key = property->key()->AsLiteral(); |
| 1497 Expression* value = property->value(); | 1471 Expression* value = property->value(); |
| 1498 if (!result_saved) { | 1472 if (!result_saved) { |
| 1499 __ Push(x0); // Save result on stack | 1473 PushOperand(x0); // Save result on stack |
| 1500 result_saved = true; | 1474 result_saved = true; |
| 1501 } | 1475 } |
| 1502 switch (property->kind()) { | 1476 switch (property->kind()) { |
| 1503 case ObjectLiteral::Property::CONSTANT: | 1477 case ObjectLiteral::Property::CONSTANT: |
| 1504 UNREACHABLE(); | 1478 UNREACHABLE(); |
| 1505 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1479 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1506 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1480 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); |
| 1507 // Fall through. | 1481 // Fall through. |
| 1508 case ObjectLiteral::Property::COMPUTED: | 1482 case ObjectLiteral::Property::COMPUTED: |
| 1509 // It is safe to use [[Put]] here because the boilerplate already | 1483 // It is safe to use [[Put]] here because the boilerplate already |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1520 | 1494 |
| 1521 if (NeedsHomeObject(value)) { | 1495 if (NeedsHomeObject(value)) { |
| 1522 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); | 1496 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); |
| 1523 } | 1497 } |
| 1524 } else { | 1498 } else { |
| 1525 VisitForEffect(value); | 1499 VisitForEffect(value); |
| 1526 } | 1500 } |
| 1527 break; | 1501 break; |
| 1528 } | 1502 } |
| 1529 __ Peek(x0, 0); | 1503 __ Peek(x0, 0); |
| 1530 __ Push(x0); | 1504 PushOperand(x0); |
| 1531 VisitForStackValue(key); | 1505 VisitForStackValue(key); |
| 1532 VisitForStackValue(value); | 1506 VisitForStackValue(value); |
| 1533 if (property->emit_store()) { | 1507 if (property->emit_store()) { |
| 1534 if (NeedsHomeObject(value)) { | 1508 if (NeedsHomeObject(value)) { |
| 1535 EmitSetHomeObject(value, 2, property->GetSlot()); | 1509 EmitSetHomeObject(value, 2, property->GetSlot()); |
| 1536 } | 1510 } |
| 1537 __ Mov(x0, Smi::FromInt(SLOPPY)); // Language mode | 1511 __ Mov(x0, Smi::FromInt(SLOPPY)); // Language mode |
| 1538 __ Push(x0); | 1512 PushOperand(x0); |
| 1539 __ CallRuntime(Runtime::kSetProperty); | 1513 CallRuntimeWithOperands(Runtime::kSetProperty); |
| 1540 } else { | 1514 } else { |
| 1541 __ Drop(3); | 1515 DropOperands(3); |
| 1542 } | 1516 } |
| 1543 break; | 1517 break; |
| 1544 case ObjectLiteral::Property::PROTOTYPE: | 1518 case ObjectLiteral::Property::PROTOTYPE: |
| 1545 DCHECK(property->emit_store()); | 1519 DCHECK(property->emit_store()); |
| 1546 // Duplicate receiver on stack. | 1520 // Duplicate receiver on stack. |
| 1547 __ Peek(x0, 0); | 1521 __ Peek(x0, 0); |
| 1548 __ Push(x0); | 1522 PushOperand(x0); |
| 1549 VisitForStackValue(value); | 1523 VisitForStackValue(value); |
| 1550 __ CallRuntime(Runtime::kInternalSetPrototype); | 1524 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); |
| 1551 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), | 1525 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), |
| 1552 NO_REGISTERS); | 1526 NO_REGISTERS); |
| 1553 break; | 1527 break; |
| 1554 case ObjectLiteral::Property::GETTER: | 1528 case ObjectLiteral::Property::GETTER: |
| 1555 if (property->emit_store()) { | 1529 if (property->emit_store()) { |
| 1556 accessor_table.lookup(key)->second->getter = property; | 1530 accessor_table.lookup(key)->second->getter = property; |
| 1557 } | 1531 } |
| 1558 break; | 1532 break; |
| 1559 case ObjectLiteral::Property::SETTER: | 1533 case ObjectLiteral::Property::SETTER: |
| 1560 if (property->emit_store()) { | 1534 if (property->emit_store()) { |
| 1561 accessor_table.lookup(key)->second->setter = property; | 1535 accessor_table.lookup(key)->second->setter = property; |
| 1562 } | 1536 } |
| 1563 break; | 1537 break; |
| 1564 } | 1538 } |
| 1565 } | 1539 } |
| 1566 | 1540 |
| 1567 // Emit code to define accessors, using only a single call to the runtime for | 1541 // Emit code to define accessors, using only a single call to the runtime for |
| 1568 // each pair of corresponding getters and setters. | 1542 // each pair of corresponding getters and setters. |
| 1569 for (AccessorTable::Iterator it = accessor_table.begin(); | 1543 for (AccessorTable::Iterator it = accessor_table.begin(); |
| 1570 it != accessor_table.end(); | 1544 it != accessor_table.end(); |
| 1571 ++it) { | 1545 ++it) { |
| 1572 __ Peek(x10, 0); // Duplicate receiver. | 1546 __ Peek(x10, 0); // Duplicate receiver. |
| 1573 __ Push(x10); | 1547 PushOperand(x10); |
| 1574 VisitForStackValue(it->first); | 1548 VisitForStackValue(it->first); |
| 1575 EmitAccessor(it->second->getter); | 1549 EmitAccessor(it->second->getter); |
| 1576 EmitAccessor(it->second->setter); | 1550 EmitAccessor(it->second->setter); |
| 1577 __ Mov(x10, Smi::FromInt(NONE)); | 1551 __ Mov(x10, Smi::FromInt(NONE)); |
| 1578 __ Push(x10); | 1552 PushOperand(x10); |
| 1579 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked); | 1553 CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked); |
| 1580 } | 1554 } |
| 1581 | 1555 |
| 1582 // Object literals have two parts. The "static" part on the left contains no | 1556 // Object literals have two parts. The "static" part on the left contains no |
| 1583 // computed property names, and so we can compute its map ahead of time; see | 1557 // computed property names, and so we can compute its map ahead of time; see |
| 1584 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part | 1558 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part |
| 1585 // starts with the first computed property name, and continues with all | 1559 // starts with the first computed property name, and continues with all |
| 1586 // properties to its right. All the code from above initializes the static | 1560 // properties to its right. All the code from above initializes the static |
| 1587 // component of the object literal, and arranges for the map of the result to | 1561 // component of the object literal, and arranges for the map of the result to |
| 1588 // reflect the static order in which the keys appear. For the dynamic | 1562 // reflect the static order in which the keys appear. For the dynamic |
| 1589 // properties, we compile them into a series of "SetOwnProperty" runtime | 1563 // properties, we compile them into a series of "SetOwnProperty" runtime |
| 1590 // calls. This will preserve insertion order. | 1564 // calls. This will preserve insertion order. |
| 1591 for (; property_index < expr->properties()->length(); property_index++) { | 1565 for (; property_index < expr->properties()->length(); property_index++) { |
| 1592 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1566 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
| 1593 | 1567 |
| 1594 Expression* value = property->value(); | 1568 Expression* value = property->value(); |
| 1595 if (!result_saved) { | 1569 if (!result_saved) { |
| 1596 __ Push(x0); // Save result on stack | 1570 PushOperand(x0); // Save result on stack |
| 1597 result_saved = true; | 1571 result_saved = true; |
| 1598 } | 1572 } |
| 1599 | 1573 |
| 1600 __ Peek(x10, 0); // Duplicate receiver. | 1574 __ Peek(x10, 0); // Duplicate receiver. |
| 1601 __ Push(x10); | 1575 PushOperand(x10); |
| 1602 | 1576 |
| 1603 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { | 1577 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { |
| 1604 DCHECK(!property->is_computed_name()); | 1578 DCHECK(!property->is_computed_name()); |
| 1605 VisitForStackValue(value); | 1579 VisitForStackValue(value); |
| 1606 DCHECK(property->emit_store()); | 1580 DCHECK(property->emit_store()); |
| 1607 __ CallRuntime(Runtime::kInternalSetPrototype); | 1581 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); |
| 1608 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), | 1582 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), |
| 1609 NO_REGISTERS); | 1583 NO_REGISTERS); |
| 1610 } else { | 1584 } else { |
| 1611 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); | 1585 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); |
| 1612 VisitForStackValue(value); | 1586 VisitForStackValue(value); |
| 1613 if (NeedsHomeObject(value)) { | 1587 if (NeedsHomeObject(value)) { |
| 1614 EmitSetHomeObject(value, 2, property->GetSlot()); | 1588 EmitSetHomeObject(value, 2, property->GetSlot()); |
| 1615 } | 1589 } |
| 1616 | 1590 |
| 1617 switch (property->kind()) { | 1591 switch (property->kind()) { |
| 1618 case ObjectLiteral::Property::CONSTANT: | 1592 case ObjectLiteral::Property::CONSTANT: |
| 1619 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1593 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1620 case ObjectLiteral::Property::COMPUTED: | 1594 case ObjectLiteral::Property::COMPUTED: |
| 1621 if (property->emit_store()) { | 1595 if (property->emit_store()) { |
| 1622 __ Push(Smi::FromInt(NONE)); | 1596 PushOperand(Smi::FromInt(NONE)); |
| 1623 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); | 1597 PushOperand(Smi::FromInt(property->NeedsSetFunctionName())); |
| 1624 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); | 1598 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral); |
| 1625 } else { | 1599 } else { |
| 1626 __ Drop(3); | 1600 DropOperands(3); |
| 1627 } | 1601 } |
| 1628 break; | 1602 break; |
| 1629 | 1603 |
| 1630 case ObjectLiteral::Property::PROTOTYPE: | 1604 case ObjectLiteral::Property::PROTOTYPE: |
| 1631 UNREACHABLE(); | 1605 UNREACHABLE(); |
| 1632 break; | 1606 break; |
| 1633 | 1607 |
| 1634 case ObjectLiteral::Property::GETTER: | 1608 case ObjectLiteral::Property::GETTER: |
| 1635 __ Push(Smi::FromInt(NONE)); | 1609 PushOperand(Smi::FromInt(NONE)); |
| 1636 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); | 1610 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked); |
| 1637 break; | 1611 break; |
| 1638 | 1612 |
| 1639 case ObjectLiteral::Property::SETTER: | 1613 case ObjectLiteral::Property::SETTER: |
| 1640 __ Push(Smi::FromInt(NONE)); | 1614 PushOperand(Smi::FromInt(NONE)); |
| 1641 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); | 1615 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked); |
| 1642 break; | 1616 break; |
| 1643 } | 1617 } |
| 1644 } | 1618 } |
| 1645 } | 1619 } |
| 1646 | 1620 |
| 1647 if (expr->has_function()) { | 1621 if (expr->has_function()) { |
| 1648 DCHECK(result_saved); | 1622 DCHECK(result_saved); |
| 1649 __ Peek(x0, 0); | 1623 __ Peek(x0, 0); |
| 1650 __ Push(x0); | 1624 __ Push(x0); |
| 1651 __ CallRuntime(Runtime::kToFastProperties); | 1625 __ CallRuntime(Runtime::kToFastProperties); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1695 int array_index = 0; | 1669 int array_index = 0; |
| 1696 for (; array_index < length; array_index++) { | 1670 for (; array_index < length; array_index++) { |
| 1697 Expression* subexpr = subexprs->at(array_index); | 1671 Expression* subexpr = subexprs->at(array_index); |
| 1698 DCHECK(!subexpr->IsSpread()); | 1672 DCHECK(!subexpr->IsSpread()); |
| 1699 | 1673 |
| 1700 // If the subexpression is a literal or a simple materialized literal it | 1674 // If the subexpression is a literal or a simple materialized literal it |
| 1701 // is already set in the cloned array. | 1675 // is already set in the cloned array. |
| 1702 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 1676 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
| 1703 | 1677 |
| 1704 if (!result_saved) { | 1678 if (!result_saved) { |
| 1705 __ Push(x0); | 1679 PushOperand(x0); |
| 1706 result_saved = true; | 1680 result_saved = true; |
| 1707 } | 1681 } |
| 1708 VisitForAccumulatorValue(subexpr); | 1682 VisitForAccumulatorValue(subexpr); |
| 1709 | 1683 |
| 1710 __ Mov(StoreDescriptor::NameRegister(), Smi::FromInt(array_index)); | 1684 __ Mov(StoreDescriptor::NameRegister(), Smi::FromInt(array_index)); |
| 1711 __ Peek(StoreDescriptor::ReceiverRegister(), 0); | 1685 __ Peek(StoreDescriptor::ReceiverRegister(), 0); |
| 1712 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); | 1686 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); |
| 1713 Handle<Code> ic = | 1687 Handle<Code> ic = |
| 1714 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 1688 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 1715 CallIC(ic); | 1689 CallIC(ic); |
| 1716 | 1690 |
| 1717 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); | 1691 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); |
| 1718 } | 1692 } |
| 1719 | 1693 |
| 1720 // In case the array literal contains spread expressions it has two parts. The | 1694 // In case the array literal contains spread expressions it has two parts. The |
| 1721 // first part is the "static" array which has a literal index is handled | 1695 // first part is the "static" array which has a literal index is handled |
| 1722 // above. The second part is the part after the first spread expression | 1696 // above. The second part is the part after the first spread expression |
| 1723 // (inclusive) and these elements gets appended to the array. Note that the | 1697 // (inclusive) and these elements gets appended to the array. Note that the |
| 1724 // number elements an iterable produces is unknown ahead of time. | 1698 // number elements an iterable produces is unknown ahead of time. |
| 1725 if (array_index < length && result_saved) { | 1699 if (array_index < length && result_saved) { |
| 1726 __ Pop(x0); | 1700 PopOperand(x0); |
| 1727 result_saved = false; | 1701 result_saved = false; |
| 1728 } | 1702 } |
| 1729 for (; array_index < length; array_index++) { | 1703 for (; array_index < length; array_index++) { |
| 1730 Expression* subexpr = subexprs->at(array_index); | 1704 Expression* subexpr = subexprs->at(array_index); |
| 1731 | 1705 |
| 1732 __ Push(x0); | 1706 PushOperand(x0); |
| 1733 DCHECK(!subexpr->IsSpread()); | 1707 DCHECK(!subexpr->IsSpread()); |
| 1734 VisitForStackValue(subexpr); | 1708 VisitForStackValue(subexpr); |
| 1735 __ CallRuntime(Runtime::kAppendElement); | 1709 CallRuntimeWithOperands(Runtime::kAppendElement); |
| 1736 | 1710 |
| 1737 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); | 1711 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); |
| 1738 } | 1712 } |
| 1739 | 1713 |
| 1740 if (result_saved) { | 1714 if (result_saved) { |
| 1741 context()->PlugTOS(); | 1715 context()->PlugTOS(); |
| 1742 } else { | 1716 } else { |
| 1743 context()->Plug(x0); | 1717 context()->Plug(x0); |
| 1744 } | 1718 } |
| 1745 } | 1719 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1766 __ Peek(LoadDescriptor::ReceiverRegister(), 0); | 1740 __ Peek(LoadDescriptor::ReceiverRegister(), 0); |
| 1767 } else { | 1741 } else { |
| 1768 VisitForStackValue(property->obj()); | 1742 VisitForStackValue(property->obj()); |
| 1769 } | 1743 } |
| 1770 break; | 1744 break; |
| 1771 case NAMED_SUPER_PROPERTY: | 1745 case NAMED_SUPER_PROPERTY: |
| 1772 VisitForStackValue( | 1746 VisitForStackValue( |
| 1773 property->obj()->AsSuperPropertyReference()->this_var()); | 1747 property->obj()->AsSuperPropertyReference()->this_var()); |
| 1774 VisitForAccumulatorValue( | 1748 VisitForAccumulatorValue( |
| 1775 property->obj()->AsSuperPropertyReference()->home_object()); | 1749 property->obj()->AsSuperPropertyReference()->home_object()); |
| 1776 __ Push(result_register()); | 1750 PushOperand(result_register()); |
| 1777 if (expr->is_compound()) { | 1751 if (expr->is_compound()) { |
| 1778 const Register scratch = x10; | 1752 const Register scratch = x10; |
| 1779 __ Peek(scratch, kPointerSize); | 1753 __ Peek(scratch, kPointerSize); |
| 1780 __ Push(scratch, result_register()); | 1754 PushOperands(scratch, result_register()); |
| 1781 } | 1755 } |
| 1782 break; | 1756 break; |
| 1783 case KEYED_SUPER_PROPERTY: | 1757 case KEYED_SUPER_PROPERTY: |
| 1784 VisitForStackValue( | 1758 VisitForStackValue( |
| 1785 property->obj()->AsSuperPropertyReference()->this_var()); | 1759 property->obj()->AsSuperPropertyReference()->this_var()); |
| 1786 VisitForStackValue( | 1760 VisitForStackValue( |
| 1787 property->obj()->AsSuperPropertyReference()->home_object()); | 1761 property->obj()->AsSuperPropertyReference()->home_object()); |
| 1788 VisitForAccumulatorValue(property->key()); | 1762 VisitForAccumulatorValue(property->key()); |
| 1789 __ Push(result_register()); | 1763 PushOperand(result_register()); |
| 1790 if (expr->is_compound()) { | 1764 if (expr->is_compound()) { |
| 1791 const Register scratch1 = x10; | 1765 const Register scratch1 = x10; |
| 1792 const Register scratch2 = x11; | 1766 const Register scratch2 = x11; |
| 1793 __ Peek(scratch1, 2 * kPointerSize); | 1767 __ Peek(scratch1, 2 * kPointerSize); |
| 1794 __ Peek(scratch2, kPointerSize); | 1768 __ Peek(scratch2, kPointerSize); |
| 1795 __ Push(scratch1, scratch2, result_register()); | 1769 PushOperands(scratch1, scratch2, result_register()); |
| 1796 } | 1770 } |
| 1797 break; | 1771 break; |
| 1798 case KEYED_PROPERTY: | 1772 case KEYED_PROPERTY: |
| 1799 if (expr->is_compound()) { | 1773 if (expr->is_compound()) { |
| 1800 VisitForStackValue(property->obj()); | 1774 VisitForStackValue(property->obj()); |
| 1801 VisitForStackValue(property->key()); | 1775 VisitForStackValue(property->key()); |
| 1802 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize); | 1776 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize); |
| 1803 __ Peek(LoadDescriptor::NameRegister(), 0); | 1777 __ Peek(LoadDescriptor::NameRegister(), 0); |
| 1804 } else { | 1778 } else { |
| 1805 VisitForStackValue(property->obj()); | 1779 VisitForStackValue(property->obj()); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1830 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 1804 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
| 1831 break; | 1805 break; |
| 1832 case KEYED_PROPERTY: | 1806 case KEYED_PROPERTY: |
| 1833 EmitKeyedPropertyLoad(property); | 1807 EmitKeyedPropertyLoad(property); |
| 1834 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 1808 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
| 1835 break; | 1809 break; |
| 1836 } | 1810 } |
| 1837 } | 1811 } |
| 1838 | 1812 |
| 1839 Token::Value op = expr->binary_op(); | 1813 Token::Value op = expr->binary_op(); |
| 1840 __ Push(x0); // Left operand goes on the stack. | 1814 PushOperand(x0); // Left operand goes on the stack. |
| 1841 VisitForAccumulatorValue(expr->value()); | 1815 VisitForAccumulatorValue(expr->value()); |
| 1842 | 1816 |
| 1843 AccumulatorValueContext context(this); | 1817 AccumulatorValueContext context(this); |
| 1844 if (ShouldInlineSmiCase(op)) { | 1818 if (ShouldInlineSmiCase(op)) { |
| 1845 EmitInlineSmiBinaryOp(expr->binary_operation(), | 1819 EmitInlineSmiBinaryOp(expr->binary_operation(), |
| 1846 op, | 1820 op, |
| 1847 expr->target(), | 1821 expr->target(), |
| 1848 expr->value()); | 1822 expr->value()); |
| 1849 } else { | 1823 } else { |
| 1850 EmitBinaryOp(expr->binary_operation(), op); | 1824 EmitBinaryOp(expr->binary_operation(), op); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1889 Literal* key = prop->key()->AsLiteral(); | 1863 Literal* key = prop->key()->AsLiteral(); |
| 1890 DCHECK(!prop->IsSuperAccess()); | 1864 DCHECK(!prop->IsSuperAccess()); |
| 1891 | 1865 |
| 1892 __ Mov(LoadDescriptor::NameRegister(), Operand(key->value())); | 1866 __ Mov(LoadDescriptor::NameRegister(), Operand(key->value())); |
| 1893 __ Mov(LoadDescriptor::SlotRegister(), | 1867 __ Mov(LoadDescriptor::SlotRegister(), |
| 1894 SmiFromSlot(prop->PropertyFeedbackSlot())); | 1868 SmiFromSlot(prop->PropertyFeedbackSlot())); |
| 1895 CallLoadIC(NOT_INSIDE_TYPEOF); | 1869 CallLoadIC(NOT_INSIDE_TYPEOF); |
| 1896 } | 1870 } |
| 1897 | 1871 |
| 1898 | 1872 |
| 1899 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { | |
| 1900 // Stack: receiver, home_object. | |
| 1901 SetExpressionPosition(prop); | |
| 1902 Literal* key = prop->key()->AsLiteral(); | |
| 1903 DCHECK(!key->value()->IsSmi()); | |
| 1904 DCHECK(prop->IsSuperAccess()); | |
| 1905 | |
| 1906 __ Push(key->value()); | |
| 1907 __ CallRuntime(Runtime::kLoadFromSuper); | |
| 1908 } | |
| 1909 | |
| 1910 | |
| 1911 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | |
| 1912 SetExpressionPosition(prop); | |
| 1913 // Call keyed load IC. It has arguments key and receiver in x0 and x1. | |
| 1914 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); | |
| 1915 __ Mov(LoadDescriptor::SlotRegister(), | |
| 1916 SmiFromSlot(prop->PropertyFeedbackSlot())); | |
| 1917 CallIC(ic); | |
| 1918 } | |
| 1919 | |
| 1920 | |
| 1921 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { | |
| 1922 // Stack: receiver, home_object, key. | |
| 1923 SetExpressionPosition(prop); | |
| 1924 __ CallRuntime(Runtime::kLoadKeyedFromSuper); | |
| 1925 } | |
| 1926 | |
| 1927 | |
| 1928 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 1873 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
| 1929 Token::Value op, | 1874 Token::Value op, |
| 1930 Expression* left_expr, | 1875 Expression* left_expr, |
| 1931 Expression* right_expr) { | 1876 Expression* right_expr) { |
| 1932 Label done, both_smis, stub_call; | 1877 Label done, both_smis, stub_call; |
| 1933 | 1878 |
| 1934 // Get the arguments. | 1879 // Get the arguments. |
| 1935 Register left = x1; | 1880 Register left = x1; |
| 1936 Register right = x0; | 1881 Register right = x0; |
| 1937 Register result = x0; | 1882 Register result = x0; |
| 1938 __ Pop(left); | 1883 PopOperand(left); |
| 1939 | 1884 |
| 1940 // Perform combined smi check on both operands. | 1885 // Perform combined smi check on both operands. |
| 1941 __ Orr(x10, left, right); | 1886 __ Orr(x10, left, right); |
| 1942 JumpPatchSite patch_site(masm_); | 1887 JumpPatchSite patch_site(masm_); |
| 1943 patch_site.EmitJumpIfSmi(x10, &both_smis); | 1888 patch_site.EmitJumpIfSmi(x10, &both_smis); |
| 1944 | 1889 |
| 1945 __ Bind(&stub_call); | 1890 __ Bind(&stub_call); |
| 1946 | 1891 |
| 1947 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); | 1892 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); |
| 1948 { | 1893 { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2018 default: | 1963 default: |
| 2019 UNREACHABLE(); | 1964 UNREACHABLE(); |
| 2020 } | 1965 } |
| 2021 | 1966 |
| 2022 __ Bind(&done); | 1967 __ Bind(&done); |
| 2023 context()->Plug(x0); | 1968 context()->Plug(x0); |
| 2024 } | 1969 } |
| 2025 | 1970 |
| 2026 | 1971 |
| 2027 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { | 1972 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { |
| 2028 __ Pop(x1); | 1973 PopOperand(x1); |
| 2029 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); | 1974 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); |
| 2030 JumpPatchSite patch_site(masm_); // Unbound, signals no inlined smi code. | 1975 JumpPatchSite patch_site(masm_); // Unbound, signals no inlined smi code. |
| 2031 { | 1976 { |
| 2032 Assembler::BlockPoolsScope scope(masm_); | 1977 Assembler::BlockPoolsScope scope(masm_); |
| 2033 CallIC(code, expr->BinaryOperationFeedbackId()); | 1978 CallIC(code, expr->BinaryOperationFeedbackId()); |
| 2034 patch_site.EmitPatchInfo(); | 1979 patch_site.EmitPatchInfo(); |
| 2035 } | 1980 } |
| 2036 context()->Plug(x0); | 1981 context()->Plug(x0); |
| 2037 } | 1982 } |
| 2038 | 1983 |
| 2039 | 1984 |
| 2040 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) { | 1985 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) { |
| 2041 for (int i = 0; i < lit->properties()->length(); i++) { | 1986 for (int i = 0; i < lit->properties()->length(); i++) { |
| 2042 ObjectLiteral::Property* property = lit->properties()->at(i); | 1987 ObjectLiteral::Property* property = lit->properties()->at(i); |
| 2043 Expression* value = property->value(); | 1988 Expression* value = property->value(); |
| 2044 | 1989 |
| 2045 Register scratch = x1; | 1990 Register scratch = x1; |
| 2046 if (property->is_static()) { | 1991 if (property->is_static()) { |
| 2047 __ Peek(scratch, kPointerSize); // constructor | 1992 __ Peek(scratch, kPointerSize); // constructor |
| 2048 } else { | 1993 } else { |
| 2049 __ Peek(scratch, 0); // prototype | 1994 __ Peek(scratch, 0); // prototype |
| 2050 } | 1995 } |
| 2051 __ Push(scratch); | 1996 PushOperand(scratch); |
| 2052 EmitPropertyKey(property, lit->GetIdForProperty(i)); | 1997 EmitPropertyKey(property, lit->GetIdForProperty(i)); |
| 2053 | 1998 |
| 2054 // The static prototype property is read only. We handle the non computed | 1999 // The static prototype property is read only. We handle the non computed |
| 2055 // property name case in the parser. Since this is the only case where we | 2000 // property name case in the parser. Since this is the only case where we |
| 2056 // need to check for an own read only property we special case this so we do | 2001 // need to check for an own read only property we special case this so we do |
| 2057 // not need to do this for every property. | 2002 // not need to do this for every property. |
| 2058 if (property->is_static() && property->is_computed_name()) { | 2003 if (property->is_static() && property->is_computed_name()) { |
| 2059 __ CallRuntime(Runtime::kThrowIfStaticPrototype); | 2004 __ CallRuntime(Runtime::kThrowIfStaticPrototype); |
| 2060 __ Push(x0); | 2005 __ Push(x0); |
| 2061 } | 2006 } |
| 2062 | 2007 |
| 2063 VisitForStackValue(value); | 2008 VisitForStackValue(value); |
| 2064 if (NeedsHomeObject(value)) { | 2009 if (NeedsHomeObject(value)) { |
| 2065 EmitSetHomeObject(value, 2, property->GetSlot()); | 2010 EmitSetHomeObject(value, 2, property->GetSlot()); |
| 2066 } | 2011 } |
| 2067 | 2012 |
| 2068 switch (property->kind()) { | 2013 switch (property->kind()) { |
| 2069 case ObjectLiteral::Property::CONSTANT: | 2014 case ObjectLiteral::Property::CONSTANT: |
| 2070 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 2015 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 2071 case ObjectLiteral::Property::PROTOTYPE: | 2016 case ObjectLiteral::Property::PROTOTYPE: |
| 2072 UNREACHABLE(); | 2017 UNREACHABLE(); |
| 2073 case ObjectLiteral::Property::COMPUTED: | 2018 case ObjectLiteral::Property::COMPUTED: |
| 2074 __ Push(Smi::FromInt(DONT_ENUM)); | 2019 PushOperand(Smi::FromInt(DONT_ENUM)); |
| 2075 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); | 2020 PushOperand(Smi::FromInt(property->NeedsSetFunctionName())); |
| 2076 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); | 2021 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral); |
| 2077 break; | 2022 break; |
| 2078 | 2023 |
| 2079 case ObjectLiteral::Property::GETTER: | 2024 case ObjectLiteral::Property::GETTER: |
| 2080 __ Push(Smi::FromInt(DONT_ENUM)); | 2025 PushOperand(Smi::FromInt(DONT_ENUM)); |
| 2081 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); | 2026 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked); |
| 2082 break; | 2027 break; |
| 2083 | 2028 |
| 2084 case ObjectLiteral::Property::SETTER: | 2029 case ObjectLiteral::Property::SETTER: |
| 2085 __ Push(Smi::FromInt(DONT_ENUM)); | 2030 PushOperand(Smi::FromInt(DONT_ENUM)); |
| 2086 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); | 2031 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked); |
| 2087 break; | 2032 break; |
| 2088 | 2033 |
| 2089 default: | 2034 default: |
| 2090 UNREACHABLE(); | 2035 UNREACHABLE(); |
| 2091 } | 2036 } |
| 2092 } | 2037 } |
| 2093 } | 2038 } |
| 2094 | 2039 |
| 2095 | 2040 |
| 2096 void FullCodeGenerator::EmitAssignment(Expression* expr, | 2041 void FullCodeGenerator::EmitAssignment(Expression* expr, |
| 2097 FeedbackVectorSlot slot) { | 2042 FeedbackVectorSlot slot) { |
| 2098 DCHECK(expr->IsValidReferenceExpressionOrThis()); | 2043 DCHECK(expr->IsValidReferenceExpressionOrThis()); |
| 2099 | 2044 |
| 2100 Property* prop = expr->AsProperty(); | 2045 Property* prop = expr->AsProperty(); |
| 2101 LhsKind assign_type = Property::GetAssignType(prop); | 2046 LhsKind assign_type = Property::GetAssignType(prop); |
| 2102 | 2047 |
| 2103 switch (assign_type) { | 2048 switch (assign_type) { |
| 2104 case VARIABLE: { | 2049 case VARIABLE: { |
| 2105 Variable* var = expr->AsVariableProxy()->var(); | 2050 Variable* var = expr->AsVariableProxy()->var(); |
| 2106 EffectContext context(this); | 2051 EffectContext context(this); |
| 2107 EmitVariableAssignment(var, Token::ASSIGN, slot); | 2052 EmitVariableAssignment(var, Token::ASSIGN, slot); |
| 2108 break; | 2053 break; |
| 2109 } | 2054 } |
| 2110 case NAMED_PROPERTY: { | 2055 case NAMED_PROPERTY: { |
| 2111 __ Push(x0); // Preserve value. | 2056 PushOperand(x0); // Preserve value. |
| 2112 VisitForAccumulatorValue(prop->obj()); | 2057 VisitForAccumulatorValue(prop->obj()); |
| 2113 // TODO(all): We could introduce a VisitForRegValue(reg, expr) to avoid | 2058 // TODO(all): We could introduce a VisitForRegValue(reg, expr) to avoid |
| 2114 // this copy. | 2059 // this copy. |
| 2115 __ Mov(StoreDescriptor::ReceiverRegister(), x0); | 2060 __ Mov(StoreDescriptor::ReceiverRegister(), x0); |
| 2116 __ Pop(StoreDescriptor::ValueRegister()); // Restore value. | 2061 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. |
| 2117 __ Mov(StoreDescriptor::NameRegister(), | 2062 __ Mov(StoreDescriptor::NameRegister(), |
| 2118 Operand(prop->key()->AsLiteral()->value())); | 2063 Operand(prop->key()->AsLiteral()->value())); |
| 2119 EmitLoadStoreICSlot(slot); | 2064 EmitLoadStoreICSlot(slot); |
| 2120 CallStoreIC(); | 2065 CallStoreIC(); |
| 2121 break; | 2066 break; |
| 2122 } | 2067 } |
| 2123 case NAMED_SUPER_PROPERTY: { | 2068 case NAMED_SUPER_PROPERTY: { |
| 2124 __ Push(x0); | 2069 PushOperand(x0); |
| 2125 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 2070 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
| 2126 VisitForAccumulatorValue( | 2071 VisitForAccumulatorValue( |
| 2127 prop->obj()->AsSuperPropertyReference()->home_object()); | 2072 prop->obj()->AsSuperPropertyReference()->home_object()); |
| 2128 // stack: value, this; x0: home_object | 2073 // stack: value, this; x0: home_object |
| 2129 Register scratch = x10; | 2074 Register scratch = x10; |
| 2130 Register scratch2 = x11; | 2075 Register scratch2 = x11; |
| 2131 __ mov(scratch, result_register()); // home_object | 2076 __ mov(scratch, result_register()); // home_object |
| 2132 __ Peek(x0, kPointerSize); // value | 2077 __ Peek(x0, kPointerSize); // value |
| 2133 __ Peek(scratch2, 0); // this | 2078 __ Peek(scratch2, 0); // this |
| 2134 __ Poke(scratch2, kPointerSize); // this | 2079 __ Poke(scratch2, kPointerSize); // this |
| 2135 __ Poke(scratch, 0); // home_object | 2080 __ Poke(scratch, 0); // home_object |
| 2136 // stack: this, home_object; x0: value | 2081 // stack: this, home_object; x0: value |
| 2137 EmitNamedSuperPropertyStore(prop); | 2082 EmitNamedSuperPropertyStore(prop); |
| 2138 break; | 2083 break; |
| 2139 } | 2084 } |
| 2140 case KEYED_SUPER_PROPERTY: { | 2085 case KEYED_SUPER_PROPERTY: { |
| 2141 __ Push(x0); | 2086 PushOperand(x0); |
| 2142 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 2087 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
| 2143 VisitForStackValue( | 2088 VisitForStackValue( |
| 2144 prop->obj()->AsSuperPropertyReference()->home_object()); | 2089 prop->obj()->AsSuperPropertyReference()->home_object()); |
| 2145 VisitForAccumulatorValue(prop->key()); | 2090 VisitForAccumulatorValue(prop->key()); |
| 2146 Register scratch = x10; | 2091 Register scratch = x10; |
| 2147 Register scratch2 = x11; | 2092 Register scratch2 = x11; |
| 2148 __ Peek(scratch2, 2 * kPointerSize); // value | 2093 __ Peek(scratch2, 2 * kPointerSize); // value |
| 2149 // stack: value, this, home_object; x0: key, x11: value | 2094 // stack: value, this, home_object; x0: key, x11: value |
| 2150 __ Peek(scratch, kPointerSize); // this | 2095 __ Peek(scratch, kPointerSize); // this |
| 2151 __ Poke(scratch, 2 * kPointerSize); | 2096 __ Poke(scratch, 2 * kPointerSize); |
| 2152 __ Peek(scratch, 0); // home_object | 2097 __ Peek(scratch, 0); // home_object |
| 2153 __ Poke(scratch, kPointerSize); | 2098 __ Poke(scratch, kPointerSize); |
| 2154 __ Poke(x0, 0); | 2099 __ Poke(x0, 0); |
| 2155 __ Move(x0, scratch2); | 2100 __ Move(x0, scratch2); |
| 2156 // stack: this, home_object, key; x0: value. | 2101 // stack: this, home_object, key; x0: value. |
| 2157 EmitKeyedSuperPropertyStore(prop); | 2102 EmitKeyedSuperPropertyStore(prop); |
| 2158 break; | 2103 break; |
| 2159 } | 2104 } |
| 2160 case KEYED_PROPERTY: { | 2105 case KEYED_PROPERTY: { |
| 2161 __ Push(x0); // Preserve value. | 2106 PushOperand(x0); // Preserve value. |
| 2162 VisitForStackValue(prop->obj()); | 2107 VisitForStackValue(prop->obj()); |
| 2163 VisitForAccumulatorValue(prop->key()); | 2108 VisitForAccumulatorValue(prop->key()); |
| 2164 __ Mov(StoreDescriptor::NameRegister(), x0); | 2109 __ Mov(StoreDescriptor::NameRegister(), x0); |
| 2165 __ Pop(StoreDescriptor::ReceiverRegister(), | 2110 PopOperands(StoreDescriptor::ReceiverRegister(), |
| 2166 StoreDescriptor::ValueRegister()); | 2111 StoreDescriptor::ValueRegister()); |
| 2167 EmitLoadStoreICSlot(slot); | 2112 EmitLoadStoreICSlot(slot); |
| 2168 Handle<Code> ic = | 2113 Handle<Code> ic = |
| 2169 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2114 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 2170 CallIC(ic); | 2115 CallIC(ic); |
| 2171 break; | 2116 break; |
| 2172 } | 2117 } |
| 2173 } | 2118 } |
| 2174 context()->Plug(x0); | 2119 context()->Plug(x0); |
| 2175 } | 2120 } |
| 2176 | 2121 |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2291 | 2236 |
| 2292 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2237 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
| 2293 ASM_LOCATION("FullCodeGenerator::EmitNamedPropertyAssignment"); | 2238 ASM_LOCATION("FullCodeGenerator::EmitNamedPropertyAssignment"); |
| 2294 // Assignment to a property, using a named store IC. | 2239 // Assignment to a property, using a named store IC. |
| 2295 Property* prop = expr->target()->AsProperty(); | 2240 Property* prop = expr->target()->AsProperty(); |
| 2296 DCHECK(prop != NULL); | 2241 DCHECK(prop != NULL); |
| 2297 DCHECK(prop->key()->IsLiteral()); | 2242 DCHECK(prop->key()->IsLiteral()); |
| 2298 | 2243 |
| 2299 __ Mov(StoreDescriptor::NameRegister(), | 2244 __ Mov(StoreDescriptor::NameRegister(), |
| 2300 Operand(prop->key()->AsLiteral()->value())); | 2245 Operand(prop->key()->AsLiteral()->value())); |
| 2301 __ Pop(StoreDescriptor::ReceiverRegister()); | 2246 PopOperand(StoreDescriptor::ReceiverRegister()); |
| 2302 EmitLoadStoreICSlot(expr->AssignmentSlot()); | 2247 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2303 CallStoreIC(); | 2248 CallStoreIC(); |
| 2304 | 2249 |
| 2305 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2250 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2306 context()->Plug(x0); | 2251 context()->Plug(x0); |
| 2307 } | 2252 } |
| 2308 | 2253 |
| 2309 | 2254 |
| 2310 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { | 2255 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { |
| 2311 // Assignment to named property of super. | 2256 // Assignment to named property of super. |
| 2312 // x0 : value | 2257 // x0 : value |
| 2313 // stack : receiver ('this'), home_object | 2258 // stack : receiver ('this'), home_object |
| 2314 DCHECK(prop != NULL); | 2259 DCHECK(prop != NULL); |
| 2315 Literal* key = prop->key()->AsLiteral(); | 2260 Literal* key = prop->key()->AsLiteral(); |
| 2316 DCHECK(key != NULL); | 2261 DCHECK(key != NULL); |
| 2317 | 2262 |
| 2318 __ Push(key->value()); | 2263 PushOperand(key->value()); |
| 2319 __ Push(x0); | 2264 PushOperand(x0); |
| 2320 __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict | 2265 CallRuntimeWithOperands(is_strict(language_mode()) |
| 2321 : Runtime::kStoreToSuper_Sloppy)); | 2266 ? Runtime::kStoreToSuper_Strict |
| 2267 : Runtime::kStoreToSuper_Sloppy); |
| 2322 } | 2268 } |
| 2323 | 2269 |
| 2324 | 2270 |
| 2325 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { | 2271 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { |
| 2326 // Assignment to named property of super. | 2272 // Assignment to named property of super. |
| 2327 // x0 : value | 2273 // x0 : value |
| 2328 // stack : receiver ('this'), home_object, key | 2274 // stack : receiver ('this'), home_object, key |
| 2329 DCHECK(prop != NULL); | 2275 DCHECK(prop != NULL); |
| 2330 | 2276 |
| 2331 __ Push(x0); | 2277 PushOperand(x0); |
| 2332 __ CallRuntime((is_strict(language_mode()) | 2278 CallRuntimeWithOperands(is_strict(language_mode()) |
| 2333 ? Runtime::kStoreKeyedToSuper_Strict | 2279 ? Runtime::kStoreKeyedToSuper_Strict |
| 2334 : Runtime::kStoreKeyedToSuper_Sloppy)); | 2280 : Runtime::kStoreKeyedToSuper_Sloppy); |
| 2335 } | 2281 } |
| 2336 | 2282 |
| 2337 | 2283 |
| 2338 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2284 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
| 2339 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment"); | 2285 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment"); |
| 2340 // Assignment to a property, using a keyed store IC. | 2286 // Assignment to a property, using a keyed store IC. |
| 2341 | 2287 |
| 2342 // TODO(all): Could we pass this in registers rather than on the stack? | 2288 // TODO(all): Could we pass this in registers rather than on the stack? |
| 2343 __ Pop(StoreDescriptor::NameRegister(), StoreDescriptor::ReceiverRegister()); | 2289 PopOperands(StoreDescriptor::NameRegister(), |
| 2290 StoreDescriptor::ReceiverRegister()); |
| 2344 DCHECK(StoreDescriptor::ValueRegister().is(x0)); | 2291 DCHECK(StoreDescriptor::ValueRegister().is(x0)); |
| 2345 | 2292 |
| 2346 Handle<Code> ic = | 2293 Handle<Code> ic = |
| 2347 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2294 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 2348 EmitLoadStoreICSlot(expr->AssignmentSlot()); | 2295 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2349 CallIC(ic); | 2296 CallIC(ic); |
| 2350 | 2297 |
| 2351 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2298 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2352 context()->Plug(x0); | 2299 context()->Plug(x0); |
| 2353 } | 2300 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2367 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); | 2314 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); |
| 2368 VisitForStackValue( | 2315 VisitForStackValue( |
| 2369 expr->obj()->AsSuperPropertyReference()->home_object()); | 2316 expr->obj()->AsSuperPropertyReference()->home_object()); |
| 2370 EmitNamedSuperPropertyLoad(expr); | 2317 EmitNamedSuperPropertyLoad(expr); |
| 2371 } | 2318 } |
| 2372 } else { | 2319 } else { |
| 2373 if (!expr->IsSuperAccess()) { | 2320 if (!expr->IsSuperAccess()) { |
| 2374 VisitForStackValue(expr->obj()); | 2321 VisitForStackValue(expr->obj()); |
| 2375 VisitForAccumulatorValue(expr->key()); | 2322 VisitForAccumulatorValue(expr->key()); |
| 2376 __ Move(LoadDescriptor::NameRegister(), x0); | 2323 __ Move(LoadDescriptor::NameRegister(), x0); |
| 2377 __ Pop(LoadDescriptor::ReceiverRegister()); | 2324 PopOperand(LoadDescriptor::ReceiverRegister()); |
| 2378 EmitKeyedPropertyLoad(expr); | 2325 EmitKeyedPropertyLoad(expr); |
| 2379 } else { | 2326 } else { |
| 2380 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); | 2327 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); |
| 2381 VisitForStackValue( | 2328 VisitForStackValue( |
| 2382 expr->obj()->AsSuperPropertyReference()->home_object()); | 2329 expr->obj()->AsSuperPropertyReference()->home_object()); |
| 2383 VisitForStackValue(expr->key()); | 2330 VisitForStackValue(expr->key()); |
| 2384 EmitKeyedSuperPropertyLoad(expr); | 2331 EmitKeyedSuperPropertyLoad(expr); |
| 2385 } | 2332 } |
| 2386 } | 2333 } |
| 2387 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2334 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2409 { StackValueContext context(this); | 2356 { StackValueContext context(this); |
| 2410 EmitVariableLoad(callee->AsVariableProxy()); | 2357 EmitVariableLoad(callee->AsVariableProxy()); |
| 2411 PrepareForBailout(callee, NO_REGISTERS); | 2358 PrepareForBailout(callee, NO_REGISTERS); |
| 2412 } | 2359 } |
| 2413 // Push undefined as receiver. This is patched in the method prologue if it | 2360 // Push undefined as receiver. This is patched in the method prologue if it |
| 2414 // is a sloppy mode method. | 2361 // is a sloppy mode method. |
| 2415 { | 2362 { |
| 2416 UseScratchRegisterScope temps(masm_); | 2363 UseScratchRegisterScope temps(masm_); |
| 2417 Register temp = temps.AcquireX(); | 2364 Register temp = temps.AcquireX(); |
| 2418 __ LoadRoot(temp, Heap::kUndefinedValueRootIndex); | 2365 __ LoadRoot(temp, Heap::kUndefinedValueRootIndex); |
| 2419 __ Push(temp); | 2366 PushOperand(temp); |
| 2420 } | 2367 } |
| 2421 convert_mode = ConvertReceiverMode::kNullOrUndefined; | 2368 convert_mode = ConvertReceiverMode::kNullOrUndefined; |
| 2422 } else { | 2369 } else { |
| 2423 // Load the function from the receiver. | 2370 // Load the function from the receiver. |
| 2424 DCHECK(callee->IsProperty()); | 2371 DCHECK(callee->IsProperty()); |
| 2425 DCHECK(!callee->AsProperty()->IsSuperAccess()); | 2372 DCHECK(!callee->AsProperty()->IsSuperAccess()); |
| 2426 __ Peek(LoadDescriptor::ReceiverRegister(), 0); | 2373 __ Peek(LoadDescriptor::ReceiverRegister(), 0); |
| 2427 EmitNamedPropertyLoad(callee->AsProperty()); | 2374 EmitNamedPropertyLoad(callee->AsProperty()); |
| 2428 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2375 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
| 2429 // Push the target function under the receiver. | 2376 // Push the target function under the receiver. |
| 2430 __ Pop(x10); | 2377 PopOperand(x10); |
| 2431 __ Push(x0, x10); | 2378 PushOperands(x0, x10); |
| 2432 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; | 2379 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; |
| 2433 } | 2380 } |
| 2434 | 2381 |
| 2435 EmitCall(expr, convert_mode); | 2382 EmitCall(expr, convert_mode); |
| 2436 } | 2383 } |
| 2437 | 2384 |
| 2438 | 2385 |
| 2439 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | 2386 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { |
| 2440 ASM_LOCATION("FullCodeGenerator::EmitSuperCallWithLoadIC"); | 2387 ASM_LOCATION("FullCodeGenerator::EmitSuperCallWithLoadIC"); |
| 2441 Expression* callee = expr->expression(); | 2388 Expression* callee = expr->expression(); |
| 2442 DCHECK(callee->IsProperty()); | 2389 DCHECK(callee->IsProperty()); |
| 2443 Property* prop = callee->AsProperty(); | 2390 Property* prop = callee->AsProperty(); |
| 2444 DCHECK(prop->IsSuperAccess()); | 2391 DCHECK(prop->IsSuperAccess()); |
| 2445 SetExpressionPosition(prop); | 2392 SetExpressionPosition(prop); |
| 2446 | 2393 |
| 2447 Literal* key = prop->key()->AsLiteral(); | 2394 Literal* key = prop->key()->AsLiteral(); |
| 2448 DCHECK(!key->value()->IsSmi()); | 2395 DCHECK(!key->value()->IsSmi()); |
| 2449 | 2396 |
| 2450 // Load the function from the receiver. | 2397 // Load the function from the receiver. |
| 2451 const Register scratch = x10; | 2398 const Register scratch = x10; |
| 2452 SuperPropertyReference* super_ref = | 2399 SuperPropertyReference* super_ref = |
| 2453 callee->AsProperty()->obj()->AsSuperPropertyReference(); | 2400 callee->AsProperty()->obj()->AsSuperPropertyReference(); |
| 2454 VisitForStackValue(super_ref->home_object()); | 2401 VisitForStackValue(super_ref->home_object()); |
| 2455 VisitForAccumulatorValue(super_ref->this_var()); | 2402 VisitForAccumulatorValue(super_ref->this_var()); |
| 2456 __ Push(x0); | 2403 PushOperand(x0); |
| 2457 __ Peek(scratch, kPointerSize); | 2404 __ Peek(scratch, kPointerSize); |
| 2458 __ Push(x0, scratch); | 2405 PushOperands(x0, scratch); |
| 2459 __ Push(key->value()); | 2406 PushOperand(key->value()); |
| 2460 | 2407 |
| 2461 // Stack here: | 2408 // Stack here: |
| 2462 // - home_object | 2409 // - home_object |
| 2463 // - this (receiver) | 2410 // - this (receiver) |
| 2464 // - this (receiver) <-- LoadFromSuper will pop here and below. | 2411 // - this (receiver) <-- LoadFromSuper will pop here and below. |
| 2465 // - home_object | 2412 // - home_object |
| 2466 __ CallRuntime(Runtime::kLoadFromSuper); | 2413 // - key |
| 2414 CallRuntimeWithOperands(Runtime::kLoadFromSuper); |
| 2467 | 2415 |
| 2468 // Replace home_object with target function. | 2416 // Replace home_object with target function. |
| 2469 __ Poke(x0, kPointerSize); | 2417 __ Poke(x0, kPointerSize); |
| 2470 | 2418 |
| 2471 // Stack here: | 2419 // Stack here: |
| 2472 // - target function | 2420 // - target function |
| 2473 // - this (receiver) | 2421 // - this (receiver) |
| 2474 EmitCall(expr); | 2422 EmitCall(expr); |
| 2475 } | 2423 } |
| 2476 | 2424 |
| 2477 | 2425 |
| 2478 // Code common for calls using the IC. | 2426 // Code common for calls using the IC. |
| 2479 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 2427 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, |
| 2480 Expression* key) { | 2428 Expression* key) { |
| 2481 ASM_LOCATION("FullCodeGenerator::EmitKeyedCallWithLoadIC"); | 2429 ASM_LOCATION("FullCodeGenerator::EmitKeyedCallWithLoadIC"); |
| 2482 // Load the key. | 2430 // Load the key. |
| 2483 VisitForAccumulatorValue(key); | 2431 VisitForAccumulatorValue(key); |
| 2484 | 2432 |
| 2485 Expression* callee = expr->expression(); | 2433 Expression* callee = expr->expression(); |
| 2486 | 2434 |
| 2487 // Load the function from the receiver. | 2435 // Load the function from the receiver. |
| 2488 DCHECK(callee->IsProperty()); | 2436 DCHECK(callee->IsProperty()); |
| 2489 __ Peek(LoadDescriptor::ReceiverRegister(), 0); | 2437 __ Peek(LoadDescriptor::ReceiverRegister(), 0); |
| 2490 __ Move(LoadDescriptor::NameRegister(), x0); | 2438 __ Move(LoadDescriptor::NameRegister(), x0); |
| 2491 EmitKeyedPropertyLoad(callee->AsProperty()); | 2439 EmitKeyedPropertyLoad(callee->AsProperty()); |
| 2492 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2440 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
| 2493 | 2441 |
| 2494 // Push the target function under the receiver. | 2442 // Push the target function under the receiver. |
| 2495 __ Pop(x10); | 2443 PopOperand(x10); |
| 2496 __ Push(x0, x10); | 2444 PushOperands(x0, x10); |
| 2497 | 2445 |
| 2498 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); | 2446 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); |
| 2499 } | 2447 } |
| 2500 | 2448 |
| 2501 | 2449 |
| 2502 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | 2450 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { |
| 2503 ASM_LOCATION("FullCodeGenerator::EmitKeyedSuperCallWithLoadIC"); | 2451 ASM_LOCATION("FullCodeGenerator::EmitKeyedSuperCallWithLoadIC"); |
| 2504 Expression* callee = expr->expression(); | 2452 Expression* callee = expr->expression(); |
| 2505 DCHECK(callee->IsProperty()); | 2453 DCHECK(callee->IsProperty()); |
| 2506 Property* prop = callee->AsProperty(); | 2454 Property* prop = callee->AsProperty(); |
| 2507 DCHECK(prop->IsSuperAccess()); | 2455 DCHECK(prop->IsSuperAccess()); |
| 2508 SetExpressionPosition(prop); | 2456 SetExpressionPosition(prop); |
| 2509 | 2457 |
| 2510 // Load the function from the receiver. | 2458 // Load the function from the receiver. |
| 2511 const Register scratch = x10; | 2459 const Register scratch = x10; |
| 2512 SuperPropertyReference* super_ref = | 2460 SuperPropertyReference* super_ref = |
| 2513 callee->AsProperty()->obj()->AsSuperPropertyReference(); | 2461 callee->AsProperty()->obj()->AsSuperPropertyReference(); |
| 2514 VisitForStackValue(super_ref->home_object()); | 2462 VisitForStackValue(super_ref->home_object()); |
| 2515 VisitForAccumulatorValue(super_ref->this_var()); | 2463 VisitForAccumulatorValue(super_ref->this_var()); |
| 2516 __ Push(x0); | 2464 PushOperand(x0); |
| 2517 __ Peek(scratch, kPointerSize); | 2465 __ Peek(scratch, kPointerSize); |
| 2518 __ Push(x0, scratch); | 2466 PushOperands(x0, scratch); |
| 2519 VisitForStackValue(prop->key()); | 2467 VisitForStackValue(prop->key()); |
| 2520 | 2468 |
| 2521 // Stack here: | 2469 // Stack here: |
| 2522 // - home_object | 2470 // - home_object |
| 2523 // - this (receiver) | 2471 // - this (receiver) |
| 2524 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. | 2472 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. |
| 2525 // - home_object | 2473 // - home_object |
| 2526 // - key | 2474 // - key |
| 2527 __ CallRuntime(Runtime::kLoadKeyedFromSuper); | 2475 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); |
| 2528 | 2476 |
| 2529 // Replace home_object with target function. | 2477 // Replace home_object with target function. |
| 2530 __ Poke(x0, kPointerSize); | 2478 __ Poke(x0, kPointerSize); |
| 2531 | 2479 |
| 2532 // Stack here: | 2480 // Stack here: |
| 2533 // - target function | 2481 // - target function |
| 2534 // - this (receiver) | 2482 // - this (receiver) |
| 2535 EmitCall(expr); | 2483 EmitCall(expr); |
| 2536 } | 2484 } |
| 2537 | 2485 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2556 EmitProfilingCounterHandlingForReturnSequence(true); | 2504 EmitProfilingCounterHandlingForReturnSequence(true); |
| 2557 } | 2505 } |
| 2558 Handle<Code> ic = | 2506 Handle<Code> ic = |
| 2559 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) | 2507 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) |
| 2560 .code(); | 2508 .code(); |
| 2561 __ Mov(x3, SmiFromSlot(expr->CallFeedbackICSlot())); | 2509 __ Mov(x3, SmiFromSlot(expr->CallFeedbackICSlot())); |
| 2562 __ Peek(x1, (arg_count + 1) * kXRegSize); | 2510 __ Peek(x1, (arg_count + 1) * kXRegSize); |
| 2563 // Don't assign a type feedback id to the IC, since type feedback is provided | 2511 // Don't assign a type feedback id to the IC, since type feedback is provided |
| 2564 // by the vector above. | 2512 // by the vector above. |
| 2565 CallIC(ic); | 2513 CallIC(ic); |
| 2514 OperandStackDepthDecrement(arg_count + 1); |
| 2566 | 2515 |
| 2567 RecordJSReturnSite(expr); | 2516 RecordJSReturnSite(expr); |
| 2568 // Restore context register. | 2517 // Restore context register. |
| 2569 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2518 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2570 context()->DropAndPlug(1, x0); | 2519 context()->DropAndPlug(1, x0); |
| 2571 } | 2520 } |
| 2572 | 2521 |
| 2573 | 2522 |
| 2574 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { | 2523 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { |
| 2575 ASM_LOCATION("FullCodeGenerator::EmitResolvePossiblyDirectEval"); | 2524 ASM_LOCATION("FullCodeGenerator::EmitResolvePossiblyDirectEval"); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2604 SetExpressionPosition(callee); | 2553 SetExpressionPosition(callee); |
| 2605 // Generate code for loading from variables potentially shadowed | 2554 // Generate code for loading from variables potentially shadowed |
| 2606 // by eval-introduced variables. | 2555 // by eval-introduced variables. |
| 2607 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); | 2556 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); |
| 2608 | 2557 |
| 2609 __ Bind(&slow); | 2558 __ Bind(&slow); |
| 2610 // Call the runtime to find the function to call (returned in x0) | 2559 // Call the runtime to find the function to call (returned in x0) |
| 2611 // and the object holding it (returned in x1). | 2560 // and the object holding it (returned in x1). |
| 2612 __ Push(callee->name()); | 2561 __ Push(callee->name()); |
| 2613 __ CallRuntime(Runtime::kLoadLookupSlotForCall); | 2562 __ CallRuntime(Runtime::kLoadLookupSlotForCall); |
| 2614 __ Push(x0, x1); // Receiver, function. | 2563 PushOperands(x0, x1); // Receiver, function. |
| 2615 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); | 2564 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); |
| 2616 | 2565 |
| 2617 // If fast case code has been generated, emit code to push the | 2566 // If fast case code has been generated, emit code to push the |
| 2618 // function and receiver and have the slow path jump around this | 2567 // function and receiver and have the slow path jump around this |
| 2619 // code. | 2568 // code. |
| 2620 if (done.is_linked()) { | 2569 if (done.is_linked()) { |
| 2621 Label call; | 2570 Label call; |
| 2622 __ B(&call); | 2571 __ B(&call); |
| 2623 __ Bind(&done); | 2572 __ Bind(&done); |
| 2624 // Push function. | 2573 // Push function. |
| 2625 // The receiver is implicitly the global receiver. Indicate this | 2574 // The receiver is implicitly the global receiver. Indicate this |
| 2626 // by passing the undefined to the call function stub. | 2575 // by passing the undefined to the call function stub. |
| 2627 __ LoadRoot(x1, Heap::kUndefinedValueRootIndex); | 2576 __ LoadRoot(x1, Heap::kUndefinedValueRootIndex); |
| 2628 __ Push(x0, x1); | 2577 __ Push(x0, x1); |
| 2629 __ Bind(&call); | 2578 __ Bind(&call); |
| 2630 } | 2579 } |
| 2631 } else { | 2580 } else { |
| 2632 VisitForStackValue(callee); | 2581 VisitForStackValue(callee); |
| 2633 // refEnv.WithBaseObject() | 2582 // refEnv.WithBaseObject() |
| 2634 __ LoadRoot(x10, Heap::kUndefinedValueRootIndex); | 2583 __ LoadRoot(x10, Heap::kUndefinedValueRootIndex); |
| 2635 __ Push(x10); // Reserved receiver slot. | 2584 PushOperand(x10); // Reserved receiver slot. |
| 2636 } | 2585 } |
| 2637 } | 2586 } |
| 2638 | 2587 |
| 2639 | 2588 |
| 2640 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { | 2589 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { |
| 2641 ASM_LOCATION("FullCodeGenerator::EmitPossiblyEvalCall"); | 2590 ASM_LOCATION("FullCodeGenerator::EmitPossiblyEvalCall"); |
| 2642 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval | 2591 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval |
| 2643 // to resolve the function we need to call. Then we call the resolved | 2592 // to resolve the function we need to call. Then we call the resolved |
| 2644 // function using the given arguments. | 2593 // function using the given arguments. |
| 2645 ZoneList<Expression*>* args = expr->arguments(); | 2594 ZoneList<Expression*>* args = expr->arguments(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2665 | 2614 |
| 2666 // Record source position for debugger. | 2615 // Record source position for debugger. |
| 2667 SetCallPosition(expr); | 2616 SetCallPosition(expr); |
| 2668 | 2617 |
| 2669 // Call the evaluated function. | 2618 // Call the evaluated function. |
| 2670 __ Peek(x1, (arg_count + 1) * kXRegSize); | 2619 __ Peek(x1, (arg_count + 1) * kXRegSize); |
| 2671 __ Mov(x0, arg_count); | 2620 __ Mov(x0, arg_count); |
| 2672 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, | 2621 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, |
| 2673 expr->tail_call_mode()), | 2622 expr->tail_call_mode()), |
| 2674 RelocInfo::CODE_TARGET); | 2623 RelocInfo::CODE_TARGET); |
| 2624 OperandStackDepthDecrement(arg_count + 1); |
| 2675 RecordJSReturnSite(expr); | 2625 RecordJSReturnSite(expr); |
| 2676 // Restore context register. | 2626 // Restore context register. |
| 2677 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2627 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2678 context()->DropAndPlug(1, x0); | 2628 context()->DropAndPlug(1, x0); |
| 2679 } | 2629 } |
| 2680 | 2630 |
| 2681 | 2631 |
| 2682 void FullCodeGenerator::VisitCallNew(CallNew* expr) { | 2632 void FullCodeGenerator::VisitCallNew(CallNew* expr) { |
| 2683 Comment cmnt(masm_, "[ CallNew"); | 2633 Comment cmnt(masm_, "[ CallNew"); |
| 2684 // According to ECMA-262, section 11.2.2, page 44, the function | 2634 // According to ECMA-262, section 11.2.2, page 44, the function |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2705 // Load function and argument count into x1 and x0. | 2655 // Load function and argument count into x1 and x0. |
| 2706 __ Mov(x0, arg_count); | 2656 __ Mov(x0, arg_count); |
| 2707 __ Peek(x1, arg_count * kXRegSize); | 2657 __ Peek(x1, arg_count * kXRegSize); |
| 2708 | 2658 |
| 2709 // Record call targets in unoptimized code. | 2659 // Record call targets in unoptimized code. |
| 2710 __ EmitLoadTypeFeedbackVector(x2); | 2660 __ EmitLoadTypeFeedbackVector(x2); |
| 2711 __ Mov(x3, SmiFromSlot(expr->CallNewFeedbackSlot())); | 2661 __ Mov(x3, SmiFromSlot(expr->CallNewFeedbackSlot())); |
| 2712 | 2662 |
| 2713 CallConstructStub stub(isolate()); | 2663 CallConstructStub stub(isolate()); |
| 2714 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); | 2664 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); |
| 2665 OperandStackDepthDecrement(arg_count + 1); |
| 2715 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); | 2666 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); |
| 2716 // Restore context register. | 2667 // Restore context register. |
| 2717 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2668 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2718 context()->Plug(x0); | 2669 context()->Plug(x0); |
| 2719 } | 2670 } |
| 2720 | 2671 |
| 2721 | 2672 |
| 2722 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { | 2673 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { |
| 2723 ASM_LOCATION("FullCodeGenerator::EmitSuperConstructorCall"); | 2674 ASM_LOCATION("FullCodeGenerator::EmitSuperConstructorCall"); |
| 2724 SuperCallReference* super_call_ref = | 2675 SuperCallReference* super_call_ref = |
| 2725 expr->expression()->AsSuperCallReference(); | 2676 expr->expression()->AsSuperCallReference(); |
| 2726 DCHECK_NOT_NULL(super_call_ref); | 2677 DCHECK_NOT_NULL(super_call_ref); |
| 2727 | 2678 |
| 2728 // Push the super constructor target on the stack (may be null, | 2679 // Push the super constructor target on the stack (may be null, |
| 2729 // but the Construct builtin can deal with that properly). | 2680 // but the Construct builtin can deal with that properly). |
| 2730 VisitForAccumulatorValue(super_call_ref->this_function_var()); | 2681 VisitForAccumulatorValue(super_call_ref->this_function_var()); |
| 2731 __ AssertFunction(result_register()); | 2682 __ AssertFunction(result_register()); |
| 2732 __ Ldr(result_register(), | 2683 __ Ldr(result_register(), |
| 2733 FieldMemOperand(result_register(), HeapObject::kMapOffset)); | 2684 FieldMemOperand(result_register(), HeapObject::kMapOffset)); |
| 2734 __ Ldr(result_register(), | 2685 __ Ldr(result_register(), |
| 2735 FieldMemOperand(result_register(), Map::kPrototypeOffset)); | 2686 FieldMemOperand(result_register(), Map::kPrototypeOffset)); |
| 2736 __ Push(result_register()); | 2687 PushOperand(result_register()); |
| 2737 | 2688 |
| 2738 // Push the arguments ("left-to-right") on the stack. | 2689 // Push the arguments ("left-to-right") on the stack. |
| 2739 ZoneList<Expression*>* args = expr->arguments(); | 2690 ZoneList<Expression*>* args = expr->arguments(); |
| 2740 int arg_count = args->length(); | 2691 int arg_count = args->length(); |
| 2741 for (int i = 0; i < arg_count; i++) { | 2692 for (int i = 0; i < arg_count; i++) { |
| 2742 VisitForStackValue(args->at(i)); | 2693 VisitForStackValue(args->at(i)); |
| 2743 } | 2694 } |
| 2744 | 2695 |
| 2745 // Call the construct call builtin that handles allocation and | 2696 // Call the construct call builtin that handles allocation and |
| 2746 // constructor invocation. | 2697 // constructor invocation. |
| 2747 SetConstructCallPosition(expr); | 2698 SetConstructCallPosition(expr); |
| 2748 | 2699 |
| 2749 // Load new target into x3. | 2700 // Load new target into x3. |
| 2750 VisitForAccumulatorValue(super_call_ref->new_target_var()); | 2701 VisitForAccumulatorValue(super_call_ref->new_target_var()); |
| 2751 __ Mov(x3, result_register()); | 2702 __ Mov(x3, result_register()); |
| 2752 | 2703 |
| 2753 // Load function and argument count into x1 and x0. | 2704 // Load function and argument count into x1 and x0. |
| 2754 __ Mov(x0, arg_count); | 2705 __ Mov(x0, arg_count); |
| 2755 __ Peek(x1, arg_count * kXRegSize); | 2706 __ Peek(x1, arg_count * kXRegSize); |
| 2756 | 2707 |
| 2757 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 2708 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
| 2709 OperandStackDepthDecrement(arg_count + 1); |
| 2758 | 2710 |
| 2759 RecordJSReturnSite(expr); | 2711 RecordJSReturnSite(expr); |
| 2760 | 2712 |
| 2761 // Restore context register. | 2713 // Restore context register. |
| 2762 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2714 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2763 context()->Plug(x0); | 2715 context()->Plug(x0); |
| 2764 } | 2716 } |
| 2765 | 2717 |
| 2766 | 2718 |
| 2767 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 2719 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2971 DCHECK_EQ(3, args->length()); | 2923 DCHECK_EQ(3, args->length()); |
| 2972 | 2924 |
| 2973 Register string = x0; | 2925 Register string = x0; |
| 2974 Register index = x1; | 2926 Register index = x1; |
| 2975 Register value = x2; | 2927 Register value = x2; |
| 2976 Register scratch = x10; | 2928 Register scratch = x10; |
| 2977 | 2929 |
| 2978 VisitForStackValue(args->at(0)); // index | 2930 VisitForStackValue(args->at(0)); // index |
| 2979 VisitForStackValue(args->at(1)); // value | 2931 VisitForStackValue(args->at(1)); // value |
| 2980 VisitForAccumulatorValue(args->at(2)); // string | 2932 VisitForAccumulatorValue(args->at(2)); // string |
| 2981 __ Pop(value, index); | 2933 PopOperands(value, index); |
| 2982 | 2934 |
| 2983 if (FLAG_debug_code) { | 2935 if (FLAG_debug_code) { |
| 2984 __ AssertSmi(value, kNonSmiValue); | 2936 __ AssertSmi(value, kNonSmiValue); |
| 2985 __ AssertSmi(index, kNonSmiIndex); | 2937 __ AssertSmi(index, kNonSmiIndex); |
| 2986 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; | 2938 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; |
| 2987 __ EmitSeqStringSetCharCheck(string, index, kIndexIsSmi, scratch, | 2939 __ EmitSeqStringSetCharCheck(string, index, kIndexIsSmi, scratch, |
| 2988 one_byte_seq_type); | 2940 one_byte_seq_type); |
| 2989 } | 2941 } |
| 2990 | 2942 |
| 2991 __ Add(scratch, string, SeqOneByteString::kHeaderSize - kHeapObjectTag); | 2943 __ Add(scratch, string, SeqOneByteString::kHeaderSize - kHeapObjectTag); |
| 2992 __ SmiUntag(value); | 2944 __ SmiUntag(value); |
| 2993 __ SmiUntag(index); | 2945 __ SmiUntag(index); |
| 2994 __ Strb(value, MemOperand(scratch, index)); | 2946 __ Strb(value, MemOperand(scratch, index)); |
| 2995 context()->Plug(string); | 2947 context()->Plug(string); |
| 2996 } | 2948 } |
| 2997 | 2949 |
| 2998 | 2950 |
| 2999 void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) { | 2951 void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) { |
| 3000 ZoneList<Expression*>* args = expr->arguments(); | 2952 ZoneList<Expression*>* args = expr->arguments(); |
| 3001 DCHECK_EQ(3, args->length()); | 2953 DCHECK_EQ(3, args->length()); |
| 3002 | 2954 |
| 3003 Register string = x0; | 2955 Register string = x0; |
| 3004 Register index = x1; | 2956 Register index = x1; |
| 3005 Register value = x2; | 2957 Register value = x2; |
| 3006 Register scratch = x10; | 2958 Register scratch = x10; |
| 3007 | 2959 |
| 3008 VisitForStackValue(args->at(0)); // index | 2960 VisitForStackValue(args->at(0)); // index |
| 3009 VisitForStackValue(args->at(1)); // value | 2961 VisitForStackValue(args->at(1)); // value |
| 3010 VisitForAccumulatorValue(args->at(2)); // string | 2962 VisitForAccumulatorValue(args->at(2)); // string |
| 3011 __ Pop(value, index); | 2963 PopOperands(value, index); |
| 3012 | 2964 |
| 3013 if (FLAG_debug_code) { | 2965 if (FLAG_debug_code) { |
| 3014 __ AssertSmi(value, kNonSmiValue); | 2966 __ AssertSmi(value, kNonSmiValue); |
| 3015 __ AssertSmi(index, kNonSmiIndex); | 2967 __ AssertSmi(index, kNonSmiIndex); |
| 3016 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; | 2968 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; |
| 3017 __ EmitSeqStringSetCharCheck(string, index, kIndexIsSmi, scratch, | 2969 __ EmitSeqStringSetCharCheck(string, index, kIndexIsSmi, scratch, |
| 3018 two_byte_seq_type); | 2970 two_byte_seq_type); |
| 3019 } | 2971 } |
| 3020 | 2972 |
| 3021 __ Add(scratch, string, SeqTwoByteString::kHeaderSize - kHeapObjectTag); | 2973 __ Add(scratch, string, SeqTwoByteString::kHeaderSize - kHeapObjectTag); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3069 ZoneList<Expression*>* args = expr->arguments(); | 3021 ZoneList<Expression*>* args = expr->arguments(); |
| 3070 DCHECK(args->length() == 2); | 3022 DCHECK(args->length() == 2); |
| 3071 | 3023 |
| 3072 VisitForStackValue(args->at(0)); | 3024 VisitForStackValue(args->at(0)); |
| 3073 VisitForAccumulatorValue(args->at(1)); | 3025 VisitForAccumulatorValue(args->at(1)); |
| 3074 | 3026 |
| 3075 Register object = x1; | 3027 Register object = x1; |
| 3076 Register index = x0; | 3028 Register index = x0; |
| 3077 Register result = x3; | 3029 Register result = x3; |
| 3078 | 3030 |
| 3079 __ Pop(object); | 3031 PopOperand(object); |
| 3080 | 3032 |
| 3081 Label need_conversion; | 3033 Label need_conversion; |
| 3082 Label index_out_of_range; | 3034 Label index_out_of_range; |
| 3083 Label done; | 3035 Label done; |
| 3084 StringCharCodeAtGenerator generator(object, | 3036 StringCharCodeAtGenerator generator(object, |
| 3085 index, | 3037 index, |
| 3086 result, | 3038 result, |
| 3087 &need_conversion, | 3039 &need_conversion, |
| 3088 &need_conversion, | 3040 &need_conversion, |
| 3089 &index_out_of_range, | 3041 &index_out_of_range, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3114 ZoneList<Expression*>* args = expr->arguments(); | 3066 ZoneList<Expression*>* args = expr->arguments(); |
| 3115 DCHECK(args->length() == 2); | 3067 DCHECK(args->length() == 2); |
| 3116 | 3068 |
| 3117 VisitForStackValue(args->at(0)); | 3069 VisitForStackValue(args->at(0)); |
| 3118 VisitForAccumulatorValue(args->at(1)); | 3070 VisitForAccumulatorValue(args->at(1)); |
| 3119 | 3071 |
| 3120 Register object = x1; | 3072 Register object = x1; |
| 3121 Register index = x0; | 3073 Register index = x0; |
| 3122 Register result = x0; | 3074 Register result = x0; |
| 3123 | 3075 |
| 3124 __ Pop(object); | 3076 PopOperand(object); |
| 3125 | 3077 |
| 3126 Label need_conversion; | 3078 Label need_conversion; |
| 3127 Label index_out_of_range; | 3079 Label index_out_of_range; |
| 3128 Label done; | 3080 Label done; |
| 3129 StringCharAtGenerator generator(object, | 3081 StringCharAtGenerator generator(object, |
| 3130 index, | 3082 index, |
| 3131 x3, | 3083 x3, |
| 3132 result, | 3084 result, |
| 3133 &need_conversion, | 3085 &need_conversion, |
| 3134 &need_conversion, | 3086 &need_conversion, |
| (...skipping 29 matching lines...) Expand all Loading... |
| 3164 for (Expression* const arg : *args) { | 3116 for (Expression* const arg : *args) { |
| 3165 VisitForStackValue(arg); | 3117 VisitForStackValue(arg); |
| 3166 } | 3118 } |
| 3167 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 3119 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
| 3168 // Move target to x1. | 3120 // Move target to x1. |
| 3169 int const argc = args->length() - 2; | 3121 int const argc = args->length() - 2; |
| 3170 __ Peek(x1, (argc + 1) * kXRegSize); | 3122 __ Peek(x1, (argc + 1) * kXRegSize); |
| 3171 // Call the target. | 3123 // Call the target. |
| 3172 __ Mov(x0, argc); | 3124 __ Mov(x0, argc); |
| 3173 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 3125 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 3126 OperandStackDepthDecrement(argc + 1); |
| 3174 // Restore context register. | 3127 // Restore context register. |
| 3175 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3128 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 3176 // Discard the function left on TOS. | 3129 // Discard the function left on TOS. |
| 3177 context()->DropAndPlug(1, x0); | 3130 context()->DropAndPlug(1, x0); |
| 3178 } | 3131 } |
| 3179 | 3132 |
| 3180 | 3133 |
| 3181 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { | 3134 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { |
| 3182 ZoneList<Expression*>* args = expr->arguments(); | 3135 ZoneList<Expression*>* args = expr->arguments(); |
| 3183 VisitForAccumulatorValue(args->at(0)); | 3136 VisitForAccumulatorValue(args->at(0)); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3260 __ ObjectUntag(untagged_result, result); | 3213 __ ObjectUntag(untagged_result, result); |
| 3261 __ Str(map_reg, MemOperand(untagged_result, HeapObject::kMapOffset)); | 3214 __ Str(map_reg, MemOperand(untagged_result, HeapObject::kMapOffset)); |
| 3262 __ Stp(empty_fixed_array, empty_fixed_array, | 3215 __ Stp(empty_fixed_array, empty_fixed_array, |
| 3263 MemOperand(untagged_result, JSObject::kPropertiesOffset)); | 3216 MemOperand(untagged_result, JSObject::kPropertiesOffset)); |
| 3264 __ Stp(result_value, boolean_done, | 3217 __ Stp(result_value, boolean_done, |
| 3265 MemOperand(untagged_result, JSIteratorResult::kValueOffset)); | 3218 MemOperand(untagged_result, JSIteratorResult::kValueOffset)); |
| 3266 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); | 3219 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); |
| 3267 __ B(&done); | 3220 __ B(&done); |
| 3268 | 3221 |
| 3269 __ Bind(&runtime); | 3222 __ Bind(&runtime); |
| 3270 __ CallRuntime(Runtime::kCreateIterResultObject); | 3223 CallRuntimeWithOperands(Runtime::kCreateIterResultObject); |
| 3271 | 3224 |
| 3272 __ Bind(&done); | 3225 __ Bind(&done); |
| 3273 context()->Plug(x0); | 3226 context()->Plug(x0); |
| 3274 } | 3227 } |
| 3275 | 3228 |
| 3276 | 3229 |
| 3277 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { | 3230 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
| 3278 // Push undefined as the receiver. | 3231 // Push undefined as the receiver. |
| 3279 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); | 3232 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); |
| 3280 __ Push(x0); | 3233 PushOperand(x0); |
| 3281 | 3234 |
| 3282 __ LoadNativeContextSlot(expr->context_index(), x0); | 3235 __ LoadNativeContextSlot(expr->context_index(), x0); |
| 3283 } | 3236 } |
| 3284 | 3237 |
| 3285 | 3238 |
| 3286 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 3239 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
| 3287 ZoneList<Expression*>* args = expr->arguments(); | 3240 ZoneList<Expression*>* args = expr->arguments(); |
| 3288 int arg_count = args->length(); | 3241 int arg_count = args->length(); |
| 3289 | 3242 |
| 3290 SetCallPosition(expr); | 3243 SetCallPosition(expr); |
| 3291 __ Peek(x1, (arg_count + 1) * kPointerSize); | 3244 __ Peek(x1, (arg_count + 1) * kPointerSize); |
| 3292 __ Mov(x0, arg_count); | 3245 __ Mov(x0, arg_count); |
| 3293 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), | 3246 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), |
| 3294 RelocInfo::CODE_TARGET); | 3247 RelocInfo::CODE_TARGET); |
| 3248 OperandStackDepthDecrement(arg_count + 1); |
| 3295 } | 3249 } |
| 3296 | 3250 |
| 3297 | 3251 |
| 3298 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 3252 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
| 3299 ZoneList<Expression*>* args = expr->arguments(); | 3253 ZoneList<Expression*>* args = expr->arguments(); |
| 3300 int arg_count = args->length(); | 3254 int arg_count = args->length(); |
| 3301 | 3255 |
| 3302 if (expr->is_jsruntime()) { | 3256 if (expr->is_jsruntime()) { |
| 3303 Comment cmnt(masm_, "[ CallRunTime"); | 3257 Comment cmnt(masm_, "[ CallRunTime"); |
| 3304 EmitLoadJSRuntimeFunction(expr); | 3258 EmitLoadJSRuntimeFunction(expr); |
| 3305 | 3259 |
| 3306 // Push the target function under the receiver. | 3260 // Push the target function under the receiver. |
| 3307 __ Pop(x10); | 3261 PopOperand(x10); |
| 3308 __ Push(x0, x10); | 3262 PushOperands(x0, x10); |
| 3309 | 3263 |
| 3310 for (int i = 0; i < arg_count; i++) { | 3264 for (int i = 0; i < arg_count; i++) { |
| 3311 VisitForStackValue(args->at(i)); | 3265 VisitForStackValue(args->at(i)); |
| 3312 } | 3266 } |
| 3313 | 3267 |
| 3314 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 3268 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
| 3315 EmitCallJSRuntimeFunction(expr); | 3269 EmitCallJSRuntimeFunction(expr); |
| 3316 | 3270 |
| 3317 // Restore context register. | 3271 // Restore context register. |
| 3318 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3272 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3332 default: { | 3286 default: { |
| 3333 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic"); | 3287 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic"); |
| 3334 // Push the arguments ("left-to-right"). | 3288 // Push the arguments ("left-to-right"). |
| 3335 for (int i = 0; i < arg_count; i++) { | 3289 for (int i = 0; i < arg_count; i++) { |
| 3336 VisitForStackValue(args->at(i)); | 3290 VisitForStackValue(args->at(i)); |
| 3337 } | 3291 } |
| 3338 | 3292 |
| 3339 // Call the C runtime function. | 3293 // Call the C runtime function. |
| 3340 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 3294 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
| 3341 __ CallRuntime(expr->function(), arg_count); | 3295 __ CallRuntime(expr->function(), arg_count); |
| 3296 OperandStackDepthDecrement(arg_count); |
| 3342 context()->Plug(x0); | 3297 context()->Plug(x0); |
| 3343 } | 3298 } |
| 3344 } | 3299 } |
| 3345 } | 3300 } |
| 3346 } | 3301 } |
| 3347 | 3302 |
| 3348 | 3303 |
| 3349 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 3304 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
| 3350 switch (expr->op()) { | 3305 switch (expr->op()) { |
| 3351 case Token::DELETE: { | 3306 case Token::DELETE: { |
| 3352 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); | 3307 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); |
| 3353 Property* property = expr->expression()->AsProperty(); | 3308 Property* property = expr->expression()->AsProperty(); |
| 3354 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 3309 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 3355 | 3310 |
| 3356 if (property != NULL) { | 3311 if (property != NULL) { |
| 3357 VisitForStackValue(property->obj()); | 3312 VisitForStackValue(property->obj()); |
| 3358 VisitForStackValue(property->key()); | 3313 VisitForStackValue(property->key()); |
| 3359 __ CallRuntime(is_strict(language_mode()) | 3314 CallRuntimeWithOperands(is_strict(language_mode()) |
| 3360 ? Runtime::kDeleteProperty_Strict | 3315 ? Runtime::kDeleteProperty_Strict |
| 3361 : Runtime::kDeleteProperty_Sloppy); | 3316 : Runtime::kDeleteProperty_Sloppy); |
| 3362 context()->Plug(x0); | 3317 context()->Plug(x0); |
| 3363 } else if (proxy != NULL) { | 3318 } else if (proxy != NULL) { |
| 3364 Variable* var = proxy->var(); | 3319 Variable* var = proxy->var(); |
| 3365 // Delete of an unqualified identifier is disallowed in strict mode but | 3320 // Delete of an unqualified identifier is disallowed in strict mode but |
| 3366 // "delete this" is allowed. | 3321 // "delete this" is allowed. |
| 3367 bool is_this = var->HasThisName(isolate()); | 3322 bool is_this = var->HasThisName(isolate()); |
| 3368 DCHECK(is_sloppy(language_mode()) || is_this); | 3323 DCHECK(is_sloppy(language_mode()) || is_this); |
| 3369 if (var->IsUnallocatedOrGlobalSlot()) { | 3324 if (var->IsUnallocatedOrGlobalSlot()) { |
| 3370 __ LoadGlobalObject(x12); | 3325 __ LoadGlobalObject(x12); |
| 3371 __ Mov(x11, Operand(var->name())); | 3326 __ Mov(x11, Operand(var->name())); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3414 context()->Plug(test->true_label(), test->false_label()); | 3369 context()->Plug(test->true_label(), test->false_label()); |
| 3415 } else { | 3370 } else { |
| 3416 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); | 3371 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); |
| 3417 // TODO(jbramley): This could be much more efficient using (for | 3372 // TODO(jbramley): This could be much more efficient using (for |
| 3418 // example) the CSEL instruction. | 3373 // example) the CSEL instruction. |
| 3419 Label materialize_true, materialize_false, done; | 3374 Label materialize_true, materialize_false, done; |
| 3420 VisitForControl(expr->expression(), | 3375 VisitForControl(expr->expression(), |
| 3421 &materialize_false, | 3376 &materialize_false, |
| 3422 &materialize_true, | 3377 &materialize_true, |
| 3423 &materialize_true); | 3378 &materialize_true); |
| 3379 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1); |
| 3424 | 3380 |
| 3425 __ Bind(&materialize_true); | 3381 __ Bind(&materialize_true); |
| 3426 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); | 3382 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); |
| 3427 __ LoadRoot(result_register(), Heap::kTrueValueRootIndex); | 3383 __ LoadRoot(result_register(), Heap::kTrueValueRootIndex); |
| 3428 __ B(&done); | 3384 __ B(&done); |
| 3429 | 3385 |
| 3430 __ Bind(&materialize_false); | 3386 __ Bind(&materialize_false); |
| 3431 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); | 3387 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); |
| 3432 __ LoadRoot(result_register(), Heap::kFalseValueRootIndex); | 3388 __ LoadRoot(result_register(), Heap::kFalseValueRootIndex); |
| 3433 __ B(&done); | 3389 __ B(&done); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3466 LhsKind assign_type = Property::GetAssignType(prop); | 3422 LhsKind assign_type = Property::GetAssignType(prop); |
| 3467 | 3423 |
| 3468 // Evaluate expression and get value. | 3424 // Evaluate expression and get value. |
| 3469 if (assign_type == VARIABLE) { | 3425 if (assign_type == VARIABLE) { |
| 3470 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 3426 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
| 3471 AccumulatorValueContext context(this); | 3427 AccumulatorValueContext context(this); |
| 3472 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 3428 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
| 3473 } else { | 3429 } else { |
| 3474 // Reserve space for result of postfix operation. | 3430 // Reserve space for result of postfix operation. |
| 3475 if (expr->is_postfix() && !context()->IsEffect()) { | 3431 if (expr->is_postfix() && !context()->IsEffect()) { |
| 3476 __ Push(xzr); | 3432 PushOperand(xzr); |
| 3477 } | 3433 } |
| 3478 switch (assign_type) { | 3434 switch (assign_type) { |
| 3479 case NAMED_PROPERTY: { | 3435 case NAMED_PROPERTY: { |
| 3480 // Put the object both on the stack and in the register. | 3436 // Put the object both on the stack and in the register. |
| 3481 VisitForStackValue(prop->obj()); | 3437 VisitForStackValue(prop->obj()); |
| 3482 __ Peek(LoadDescriptor::ReceiverRegister(), 0); | 3438 __ Peek(LoadDescriptor::ReceiverRegister(), 0); |
| 3483 EmitNamedPropertyLoad(prop); | 3439 EmitNamedPropertyLoad(prop); |
| 3484 break; | 3440 break; |
| 3485 } | 3441 } |
| 3486 | 3442 |
| 3487 case NAMED_SUPER_PROPERTY: { | 3443 case NAMED_SUPER_PROPERTY: { |
| 3488 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 3444 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
| 3489 VisitForAccumulatorValue( | 3445 VisitForAccumulatorValue( |
| 3490 prop->obj()->AsSuperPropertyReference()->home_object()); | 3446 prop->obj()->AsSuperPropertyReference()->home_object()); |
| 3491 __ Push(result_register()); | 3447 PushOperand(result_register()); |
| 3492 const Register scratch = x10; | 3448 const Register scratch = x10; |
| 3493 __ Peek(scratch, kPointerSize); | 3449 __ Peek(scratch, kPointerSize); |
| 3494 __ Push(scratch, result_register()); | 3450 PushOperands(scratch, result_register()); |
| 3495 EmitNamedSuperPropertyLoad(prop); | 3451 EmitNamedSuperPropertyLoad(prop); |
| 3496 break; | 3452 break; |
| 3497 } | 3453 } |
| 3498 | 3454 |
| 3499 case KEYED_SUPER_PROPERTY: { | 3455 case KEYED_SUPER_PROPERTY: { |
| 3500 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 3456 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
| 3501 VisitForStackValue( | 3457 VisitForStackValue( |
| 3502 prop->obj()->AsSuperPropertyReference()->home_object()); | 3458 prop->obj()->AsSuperPropertyReference()->home_object()); |
| 3503 VisitForAccumulatorValue(prop->key()); | 3459 VisitForAccumulatorValue(prop->key()); |
| 3504 __ Push(result_register()); | 3460 PushOperand(result_register()); |
| 3505 const Register scratch1 = x10; | 3461 const Register scratch1 = x10; |
| 3506 const Register scratch2 = x11; | 3462 const Register scratch2 = x11; |
| 3507 __ Peek(scratch1, 2 * kPointerSize); | 3463 __ Peek(scratch1, 2 * kPointerSize); |
| 3508 __ Peek(scratch2, kPointerSize); | 3464 __ Peek(scratch2, kPointerSize); |
| 3509 __ Push(scratch1, scratch2, result_register()); | 3465 PushOperands(scratch1, scratch2, result_register()); |
| 3510 EmitKeyedSuperPropertyLoad(prop); | 3466 EmitKeyedSuperPropertyLoad(prop); |
| 3511 break; | 3467 break; |
| 3512 } | 3468 } |
| 3513 | 3469 |
| 3514 case KEYED_PROPERTY: { | 3470 case KEYED_PROPERTY: { |
| 3515 VisitForStackValue(prop->obj()); | 3471 VisitForStackValue(prop->obj()); |
| 3516 VisitForStackValue(prop->key()); | 3472 VisitForStackValue(prop->key()); |
| 3517 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize); | 3473 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize); |
| 3518 __ Peek(LoadDescriptor::NameRegister(), 0); | 3474 __ Peek(LoadDescriptor::NameRegister(), 0); |
| 3519 EmitKeyedPropertyLoad(prop); | 3475 EmitKeyedPropertyLoad(prop); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3582 } | 3538 } |
| 3583 | 3539 |
| 3584 // Save result for postfix expressions. | 3540 // Save result for postfix expressions. |
| 3585 if (expr->is_postfix()) { | 3541 if (expr->is_postfix()) { |
| 3586 if (!context()->IsEffect()) { | 3542 if (!context()->IsEffect()) { |
| 3587 // Save the result on the stack. If we have a named or keyed property | 3543 // Save the result on the stack. If we have a named or keyed property |
| 3588 // we store the result under the receiver that is currently on top | 3544 // we store the result under the receiver that is currently on top |
| 3589 // of the stack. | 3545 // of the stack. |
| 3590 switch (assign_type) { | 3546 switch (assign_type) { |
| 3591 case VARIABLE: | 3547 case VARIABLE: |
| 3592 __ Push(x0); | 3548 PushOperand(x0); |
| 3593 break; | 3549 break; |
| 3594 case NAMED_PROPERTY: | 3550 case NAMED_PROPERTY: |
| 3595 __ Poke(x0, kXRegSize); | 3551 __ Poke(x0, kXRegSize); |
| 3596 break; | 3552 break; |
| 3597 case NAMED_SUPER_PROPERTY: | 3553 case NAMED_SUPER_PROPERTY: |
| 3598 __ Poke(x0, 2 * kXRegSize); | 3554 __ Poke(x0, 2 * kXRegSize); |
| 3599 break; | 3555 break; |
| 3600 case KEYED_PROPERTY: | 3556 case KEYED_PROPERTY: |
| 3601 __ Poke(x0, 2 * kXRegSize); | 3557 __ Poke(x0, 2 * kXRegSize); |
| 3602 break; | 3558 break; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3642 } else { | 3598 } else { |
| 3643 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3599 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 3644 Token::ASSIGN, expr->CountSlot()); | 3600 Token::ASSIGN, expr->CountSlot()); |
| 3645 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3601 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3646 context()->Plug(x0); | 3602 context()->Plug(x0); |
| 3647 } | 3603 } |
| 3648 break; | 3604 break; |
| 3649 case NAMED_PROPERTY: { | 3605 case NAMED_PROPERTY: { |
| 3650 __ Mov(StoreDescriptor::NameRegister(), | 3606 __ Mov(StoreDescriptor::NameRegister(), |
| 3651 Operand(prop->key()->AsLiteral()->value())); | 3607 Operand(prop->key()->AsLiteral()->value())); |
| 3652 __ Pop(StoreDescriptor::ReceiverRegister()); | 3608 PopOperand(StoreDescriptor::ReceiverRegister()); |
| 3653 EmitLoadStoreICSlot(expr->CountSlot()); | 3609 EmitLoadStoreICSlot(expr->CountSlot()); |
| 3654 CallStoreIC(); | 3610 CallStoreIC(); |
| 3655 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3611 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3656 if (expr->is_postfix()) { | 3612 if (expr->is_postfix()) { |
| 3657 if (!context()->IsEffect()) { | 3613 if (!context()->IsEffect()) { |
| 3658 context()->PlugTOS(); | 3614 context()->PlugTOS(); |
| 3659 } | 3615 } |
| 3660 } else { | 3616 } else { |
| 3661 context()->Plug(x0); | 3617 context()->Plug(x0); |
| 3662 } | 3618 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3678 if (expr->is_postfix()) { | 3634 if (expr->is_postfix()) { |
| 3679 if (!context()->IsEffect()) { | 3635 if (!context()->IsEffect()) { |
| 3680 context()->PlugTOS(); | 3636 context()->PlugTOS(); |
| 3681 } | 3637 } |
| 3682 } else { | 3638 } else { |
| 3683 context()->Plug(x0); | 3639 context()->Plug(x0); |
| 3684 } | 3640 } |
| 3685 break; | 3641 break; |
| 3686 } | 3642 } |
| 3687 case KEYED_PROPERTY: { | 3643 case KEYED_PROPERTY: { |
| 3688 __ Pop(StoreDescriptor::NameRegister()); | 3644 PopOperand(StoreDescriptor::NameRegister()); |
| 3689 __ Pop(StoreDescriptor::ReceiverRegister()); | 3645 PopOperand(StoreDescriptor::ReceiverRegister()); |
| 3690 Handle<Code> ic = | 3646 Handle<Code> ic = |
| 3691 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 3647 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 3692 EmitLoadStoreICSlot(expr->CountSlot()); | 3648 EmitLoadStoreICSlot(expr->CountSlot()); |
| 3693 CallIC(ic); | 3649 CallIC(ic); |
| 3694 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3650 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3695 if (expr->is_postfix()) { | 3651 if (expr->is_postfix()) { |
| 3696 if (!context()->IsEffect()) { | 3652 if (!context()->IsEffect()) { |
| 3697 context()->PlugTOS(); | 3653 context()->PlugTOS(); |
| 3698 } | 3654 } |
| 3699 } else { | 3655 } else { |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3810 Label* if_false = NULL; | 3766 Label* if_false = NULL; |
| 3811 Label* fall_through = NULL; | 3767 Label* fall_through = NULL; |
| 3812 context()->PrepareTest(&materialize_true, &materialize_false, | 3768 context()->PrepareTest(&materialize_true, &materialize_false, |
| 3813 &if_true, &if_false, &fall_through); | 3769 &if_true, &if_false, &fall_through); |
| 3814 | 3770 |
| 3815 Token::Value op = expr->op(); | 3771 Token::Value op = expr->op(); |
| 3816 VisitForStackValue(expr->left()); | 3772 VisitForStackValue(expr->left()); |
| 3817 switch (op) { | 3773 switch (op) { |
| 3818 case Token::IN: | 3774 case Token::IN: |
| 3819 VisitForStackValue(expr->right()); | 3775 VisitForStackValue(expr->right()); |
| 3820 __ CallRuntime(Runtime::kHasProperty); | 3776 CallRuntimeWithOperands(Runtime::kHasProperty); |
| 3821 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); | 3777 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); |
| 3822 __ CompareRoot(x0, Heap::kTrueValueRootIndex); | 3778 __ CompareRoot(x0, Heap::kTrueValueRootIndex); |
| 3823 Split(eq, if_true, if_false, fall_through); | 3779 Split(eq, if_true, if_false, fall_through); |
| 3824 break; | 3780 break; |
| 3825 | 3781 |
| 3826 case Token::INSTANCEOF: { | 3782 case Token::INSTANCEOF: { |
| 3827 VisitForAccumulatorValue(expr->right()); | 3783 VisitForAccumulatorValue(expr->right()); |
| 3828 __ Pop(x1); | 3784 PopOperand(x1); |
| 3829 InstanceOfStub stub(isolate()); | 3785 InstanceOfStub stub(isolate()); |
| 3830 __ CallStub(&stub); | 3786 __ CallStub(&stub); |
| 3831 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); | 3787 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); |
| 3832 __ CompareRoot(x0, Heap::kTrueValueRootIndex); | 3788 __ CompareRoot(x0, Heap::kTrueValueRootIndex); |
| 3833 Split(eq, if_true, if_false, fall_through); | 3789 Split(eq, if_true, if_false, fall_through); |
| 3834 break; | 3790 break; |
| 3835 } | 3791 } |
| 3836 | 3792 |
| 3837 default: { | 3793 default: { |
| 3838 VisitForAccumulatorValue(expr->right()); | 3794 VisitForAccumulatorValue(expr->right()); |
| 3839 Condition cond = CompareIC::ComputeCondition(op); | 3795 Condition cond = CompareIC::ComputeCondition(op); |
| 3840 | 3796 |
| 3841 // Pop the stack value. | 3797 // Pop the stack value. |
| 3842 __ Pop(x1); | 3798 PopOperand(x1); |
| 3843 | 3799 |
| 3844 JumpPatchSite patch_site(masm_); | 3800 JumpPatchSite patch_site(masm_); |
| 3845 if (ShouldInlineSmiCase(op)) { | 3801 if (ShouldInlineSmiCase(op)) { |
| 3846 Label slow_case; | 3802 Label slow_case; |
| 3847 patch_site.EmitJumpIfEitherNotSmi(x0, x1, &slow_case); | 3803 patch_site.EmitJumpIfEitherNotSmi(x0, x1, &slow_case); |
| 3848 __ Cmp(x1, x0); | 3804 __ Cmp(x1, x0); |
| 3849 Split(cond, if_true, if_false, NULL); | 3805 Split(cond, if_true, if_false, NULL); |
| 3850 __ Bind(&slow_case); | 3806 __ Bind(&slow_case); |
| 3851 } | 3807 } |
| 3852 | 3808 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3947 __ Mov(x1, cp); | 3903 __ Mov(x1, cp); |
| 3948 __ RecordWriteField(x0, JSGeneratorObject::kContextOffset, x1, x2, | 3904 __ RecordWriteField(x0, JSGeneratorObject::kContextOffset, x1, x2, |
| 3949 kLRHasBeenSaved, kDontSaveFPRegs); | 3905 kLRHasBeenSaved, kDontSaveFPRegs); |
| 3950 __ Add(x1, fp, StandardFrameConstants::kExpressionsOffset); | 3906 __ Add(x1, fp, StandardFrameConstants::kExpressionsOffset); |
| 3951 __ Cmp(__ StackPointer(), x1); | 3907 __ Cmp(__ StackPointer(), x1); |
| 3952 __ B(eq, &post_runtime); | 3908 __ B(eq, &post_runtime); |
| 3953 __ Push(x0); // generator object | 3909 __ Push(x0); // generator object |
| 3954 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 3910 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
| 3955 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3911 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 3956 __ Bind(&post_runtime); | 3912 __ Bind(&post_runtime); |
| 3957 __ Pop(result_register()); | 3913 PopOperand(result_register()); |
| 3958 EmitReturnSequence(); | 3914 EmitReturnSequence(); |
| 3959 | 3915 |
| 3960 __ Bind(&resume); | 3916 __ Bind(&resume); |
| 3961 context()->Plug(result_register()); | 3917 context()->Plug(result_register()); |
| 3962 break; | 3918 break; |
| 3963 } | 3919 } |
| 3964 | 3920 |
| 3965 case Yield::kFinal: { | 3921 case Yield::kFinal: { |
| 3966 // Pop value from top-of-stack slot, box result into result register. | 3922 // Pop value from top-of-stack slot, box result into result register. |
| 3923 OperandStackDepthDecrement(1); |
| 3967 EmitCreateIteratorResult(true); | 3924 EmitCreateIteratorResult(true); |
| 3968 EmitUnwindAndReturn(); | 3925 EmitUnwindAndReturn(); |
| 3969 break; | 3926 break; |
| 3970 } | 3927 } |
| 3971 | 3928 |
| 3972 case Yield::kDelegating: | 3929 case Yield::kDelegating: |
| 3973 UNREACHABLE(); | 3930 UNREACHABLE(); |
| 3974 } | 3931 } |
| 3975 } | 3932 } |
| 3976 | 3933 |
| 3977 | 3934 |
| 3978 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 3935 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
| 3979 Expression *value, | 3936 Expression *value, |
| 3980 JSGeneratorObject::ResumeMode resume_mode) { | 3937 JSGeneratorObject::ResumeMode resume_mode) { |
| 3981 ASM_LOCATION("FullCodeGenerator::EmitGeneratorResume"); | 3938 ASM_LOCATION("FullCodeGenerator::EmitGeneratorResume"); |
| 3982 Register generator_object = x1; | 3939 Register generator_object = x1; |
| 3983 Register the_hole = x2; | 3940 Register the_hole = x2; |
| 3984 Register operand_stack_size = w3; | 3941 Register operand_stack_size = w3; |
| 3985 Register function = x4; | 3942 Register function = x4; |
| 3986 | 3943 |
| 3987 // The value stays in x0, and is ultimately read by the resumed generator, as | 3944 // The value stays in x0, and is ultimately read by the resumed generator, as |
| 3988 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it | 3945 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it |
| 3989 // is read to throw the value when the resumed generator is already closed. x1 | 3946 // is read to throw the value when the resumed generator is already closed. x1 |
| 3990 // will hold the generator object until the activation has been resumed. | 3947 // will hold the generator object until the activation has been resumed. |
| 3991 VisitForStackValue(generator); | 3948 VisitForStackValue(generator); |
| 3992 VisitForAccumulatorValue(value); | 3949 VisitForAccumulatorValue(value); |
| 3993 __ Pop(generator_object); | 3950 PopOperand(generator_object); |
| 3994 | 3951 |
| 3995 // Store input value into generator object. | 3952 // Store input value into generator object. |
| 3996 __ Str(result_register(), | 3953 __ Str(result_register(), |
| 3997 FieldMemOperand(x1, JSGeneratorObject::kInputOffset)); | 3954 FieldMemOperand(x1, JSGeneratorObject::kInputOffset)); |
| 3998 __ Mov(x2, result_register()); | 3955 __ Mov(x2, result_register()); |
| 3999 __ RecordWriteField(x1, JSGeneratorObject::kInputOffset, x2, x3, | 3956 __ RecordWriteField(x1, JSGeneratorObject::kInputOffset, x2, x3, |
| 4000 kLRHasBeenSaved, kDontSaveFPRegs); | 3957 kLRHasBeenSaved, kDontSaveFPRegs); |
| 4001 | 3958 |
| 4002 // Load suspended function and context. | 3959 // Load suspended function and context. |
| 4003 __ Ldr(cp, FieldMemOperand(generator_object, | 3960 __ Ldr(cp, FieldMemOperand(generator_object, |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4068 __ Push(Smi::FromInt(resume_mode)); // Consumed in continuation. | 4025 __ Push(Smi::FromInt(resume_mode)); // Consumed in continuation. |
| 4069 __ Push(generator_object, result_register(), x10); | 4026 __ Push(generator_object, result_register(), x10); |
| 4070 __ CallRuntime(Runtime::kResumeJSGeneratorObject); | 4027 __ CallRuntime(Runtime::kResumeJSGeneratorObject); |
| 4071 // Not reached: the runtime call returns elsewhere. | 4028 // Not reached: the runtime call returns elsewhere. |
| 4072 __ Unreachable(); | 4029 __ Unreachable(); |
| 4073 | 4030 |
| 4074 __ Bind(&done); | 4031 __ Bind(&done); |
| 4075 context()->Plug(result_register()); | 4032 context()->Plug(result_register()); |
| 4076 } | 4033 } |
| 4077 | 4034 |
| 4035 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) { |
| 4036 OperandStackDepthIncrement(2); |
| 4037 __ Push(reg1, reg2); |
| 4038 } |
| 4039 |
| 4040 void FullCodeGenerator::PushOperands(Register reg1, Register reg2, |
| 4041 Register reg3) { |
| 4042 OperandStackDepthIncrement(3); |
| 4043 __ Push(reg1, reg2, reg3); |
| 4044 } |
| 4045 |
| 4046 void FullCodeGenerator::PopOperands(Register reg1, Register reg2) { |
| 4047 OperandStackDepthDecrement(2); |
| 4048 __ Pop(reg1, reg2); |
| 4049 } |
| 4050 |
| 4051 void FullCodeGenerator::EmitOperandStackDepthCheck() { |
| 4052 if (FLAG_debug_code) { |
| 4053 int expected_diff = StandardFrameConstants::kFixedFrameSizeFromFp + |
| 4054 operand_stack_depth_ * kPointerSize; |
| 4055 __ Sub(x0, fp, jssp); |
| 4056 __ Cmp(x0, Operand(expected_diff)); |
| 4057 __ Assert(eq, kUnexpectedStackDepth); |
| 4058 } |
| 4059 } |
| 4078 | 4060 |
| 4079 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { | 4061 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { |
| 4080 Label allocate, done_allocate; | 4062 Label allocate, done_allocate; |
| 4081 | 4063 |
| 4082 // Allocate and populate an object with this form: { value: VAL, done: DONE } | 4064 // Allocate and populate an object with this form: { value: VAL, done: DONE } |
| 4083 | 4065 |
| 4084 Register result = x0; | 4066 Register result = x0; |
| 4085 __ Allocate(JSIteratorResult::kSize, result, x10, x11, &allocate, TAG_OBJECT); | 4067 __ Allocate(JSIteratorResult::kSize, result, x10, x11, &allocate, TAG_OBJECT); |
| 4086 __ B(&done_allocate); | 4068 __ B(&done_allocate); |
| 4087 | 4069 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4155 __ LoadNativeContextSlot(Context::CLOSURE_INDEX, x10); | 4137 __ LoadNativeContextSlot(Context::CLOSURE_INDEX, x10); |
| 4156 } else if (closure_scope->is_eval_scope()) { | 4138 } else if (closure_scope->is_eval_scope()) { |
| 4157 // Contexts created by a call to eval have the same closure as the | 4139 // Contexts created by a call to eval have the same closure as the |
| 4158 // context calling eval, not the anonymous closure containing the eval | 4140 // context calling eval, not the anonymous closure containing the eval |
| 4159 // code. Fetch it from the context. | 4141 // code. Fetch it from the context. |
| 4160 __ Ldr(x10, ContextMemOperand(cp, Context::CLOSURE_INDEX)); | 4142 __ Ldr(x10, ContextMemOperand(cp, Context::CLOSURE_INDEX)); |
| 4161 } else { | 4143 } else { |
| 4162 DCHECK(closure_scope->is_function_scope()); | 4144 DCHECK(closure_scope->is_function_scope()); |
| 4163 __ Ldr(x10, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 4145 __ Ldr(x10, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 4164 } | 4146 } |
| 4165 __ Push(x10); | 4147 PushOperand(x10); |
| 4166 } | 4148 } |
| 4167 | 4149 |
| 4168 | 4150 |
| 4169 void FullCodeGenerator::EnterFinallyBlock() { | 4151 void FullCodeGenerator::EnterFinallyBlock() { |
| 4170 ASM_LOCATION("FullCodeGenerator::EnterFinallyBlock"); | 4152 ASM_LOCATION("FullCodeGenerator::EnterFinallyBlock"); |
| 4171 DCHECK(!result_register().is(x10)); | 4153 DCHECK(!result_register().is(x10)); |
| 4172 // Store pending message while executing finally block. | 4154 // Store pending message while executing finally block. |
| 4173 ExternalReference pending_message_obj = | 4155 ExternalReference pending_message_obj = |
| 4174 ExternalReference::address_of_pending_message_obj(isolate()); | 4156 ExternalReference::address_of_pending_message_obj(isolate()); |
| 4175 __ Mov(x10, pending_message_obj); | 4157 __ Mov(x10, pending_message_obj); |
| 4176 __ Ldr(x10, MemOperand(x10)); | 4158 __ Ldr(x10, MemOperand(x10)); |
| 4177 __ Push(x10); | 4159 PushOperand(x10); |
| 4178 | 4160 |
| 4179 ClearPendingMessage(); | 4161 ClearPendingMessage(); |
| 4180 } | 4162 } |
| 4181 | 4163 |
| 4182 | 4164 |
| 4183 void FullCodeGenerator::ExitFinallyBlock() { | 4165 void FullCodeGenerator::ExitFinallyBlock() { |
| 4184 ASM_LOCATION("FullCodeGenerator::ExitFinallyBlock"); | 4166 ASM_LOCATION("FullCodeGenerator::ExitFinallyBlock"); |
| 4185 DCHECK(!result_register().is(x10)); | 4167 DCHECK(!result_register().is(x10)); |
| 4186 | 4168 |
| 4187 // Restore pending message from stack. | 4169 // Restore pending message from stack. |
| 4188 __ Pop(x10); | 4170 PopOperand(x10); |
| 4189 ExternalReference pending_message_obj = | 4171 ExternalReference pending_message_obj = |
| 4190 ExternalReference::address_of_pending_message_obj(isolate()); | 4172 ExternalReference::address_of_pending_message_obj(isolate()); |
| 4191 __ Mov(x13, pending_message_obj); | 4173 __ Mov(x13, pending_message_obj); |
| 4192 __ Str(x10, MemOperand(x13)); | 4174 __ Str(x10, MemOperand(x13)); |
| 4193 } | 4175 } |
| 4194 | 4176 |
| 4195 | 4177 |
| 4196 void FullCodeGenerator::ClearPendingMessage() { | 4178 void FullCodeGenerator::ClearPendingMessage() { |
| 4197 DCHECK(!result_register().is(x10)); | 4179 DCHECK(!result_register().is(x10)); |
| 4198 ExternalReference pending_message_obj = | 4180 ExternalReference pending_message_obj = |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4321 } | 4303 } |
| 4322 | 4304 |
| 4323 return INTERRUPT; | 4305 return INTERRUPT; |
| 4324 } | 4306 } |
| 4325 | 4307 |
| 4326 | 4308 |
| 4327 } // namespace internal | 4309 } // namespace internal |
| 4328 } // namespace v8 | 4310 } // namespace v8 |
| 4329 | 4311 |
| 4330 #endif // V8_TARGET_ARCH_ARM64 | 4312 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |