| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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_PPC | 5 #if V8_TARGET_ARCH_PPC |
| 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 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 __ addi(ip, ip, Operand(prologue_offset)); | 129 __ addi(ip, ip, Operand(prologue_offset)); |
| 130 } | 130 } |
| 131 info->set_prologue_offset(prologue_offset); | 131 info->set_prologue_offset(prologue_offset); |
| 132 __ Prologue(info->GeneratePreagedPrologue(), ip, prologue_offset); | 132 __ Prologue(info->GeneratePreagedPrologue(), ip, prologue_offset); |
| 133 | 133 |
| 134 { | 134 { |
| 135 Comment cmnt(masm_, "[ Allocate locals"); | 135 Comment cmnt(masm_, "[ Allocate locals"); |
| 136 int locals_count = info->scope()->num_stack_slots(); | 136 int locals_count = info->scope()->num_stack_slots(); |
| 137 // Generators allocate locals, if any, in context slots. | 137 // Generators allocate locals, if any, in context slots. |
| 138 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0); | 138 DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0); |
| 139 OperandStackDepthIncrement(locals_count); |
| 139 if (locals_count > 0) { | 140 if (locals_count > 0) { |
| 140 if (locals_count >= 128) { | 141 if (locals_count >= 128) { |
| 141 Label ok; | 142 Label ok; |
| 142 __ Add(ip, sp, -(locals_count * kPointerSize), r0); | 143 __ Add(ip, sp, -(locals_count * kPointerSize), r0); |
| 143 __ LoadRoot(r5, Heap::kRealStackLimitRootIndex); | 144 __ LoadRoot(r5, Heap::kRealStackLimitRootIndex); |
| 144 __ cmpl(ip, r5); | 145 __ cmpl(ip, r5); |
| 145 __ bc_short(ge, &ok); | 146 __ bc_short(ge, &ok); |
| 146 __ CallRuntime(Runtime::kThrowStackOverflow); | 147 __ CallRuntime(Runtime::kThrowStackOverflow); |
| 147 __ bind(&ok); | 148 __ bind(&ok); |
| 148 } | 149 } |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 453 __ LeaveFrame(StackFrame::JAVA_SCRIPT, sp_delta); | 454 __ LeaveFrame(StackFrame::JAVA_SCRIPT, sp_delta); |
| 454 __ blr(); | 455 __ blr(); |
| 455 } | 456 } |
| 456 } | 457 } |
| 457 } | 458 } |
| 458 | 459 |
| 459 | 460 |
| 460 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { | 461 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { |
| 461 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 462 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 462 codegen()->GetVar(result_register(), var); | 463 codegen()->GetVar(result_register(), var); |
| 463 __ push(result_register()); | 464 codegen()->PushOperand(result_register()); |
| 464 } | 465 } |
| 465 | 466 |
| 466 | 467 |
| 467 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const {} | 468 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const {} |
| 468 | 469 |
| 469 | 470 |
| 470 void FullCodeGenerator::AccumulatorValueContext::Plug( | 471 void FullCodeGenerator::AccumulatorValueContext::Plug( |
| 471 Heap::RootListIndex index) const { | 472 Heap::RootListIndex index) const { |
| 472 __ LoadRoot(result_register(), index); | 473 __ LoadRoot(result_register(), index); |
| 473 } | 474 } |
| 474 | 475 |
| 475 | 476 |
| 476 void FullCodeGenerator::StackValueContext::Plug( | 477 void FullCodeGenerator::StackValueContext::Plug( |
| 477 Heap::RootListIndex index) const { | 478 Heap::RootListIndex index) const { |
| 478 __ LoadRoot(result_register(), index); | 479 __ LoadRoot(result_register(), index); |
| 479 __ push(result_register()); | 480 codegen()->PushOperand(result_register()); |
| 480 } | 481 } |
| 481 | 482 |
| 482 | 483 |
| 483 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const { | 484 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const { |
| 484 codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_, | 485 codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_, |
| 485 false_label_); | 486 false_label_); |
| 486 if (index == Heap::kUndefinedValueRootIndex || | 487 if (index == Heap::kUndefinedValueRootIndex || |
| 487 index == Heap::kNullValueRootIndex || | 488 index == Heap::kNullValueRootIndex || |
| 488 index == Heap::kFalseValueRootIndex) { | 489 index == Heap::kFalseValueRootIndex) { |
| 489 if (false_label_ != fall_through_) __ b(false_label_); | 490 if (false_label_ != fall_through_) __ b(false_label_); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 501 | 502 |
| 502 void FullCodeGenerator::AccumulatorValueContext::Plug( | 503 void FullCodeGenerator::AccumulatorValueContext::Plug( |
| 503 Handle<Object> lit) const { | 504 Handle<Object> lit) const { |
| 504 __ mov(result_register(), Operand(lit)); | 505 __ mov(result_register(), Operand(lit)); |
| 505 } | 506 } |
| 506 | 507 |
| 507 | 508 |
| 508 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { | 509 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { |
| 509 // Immediates cannot be pushed directly. | 510 // Immediates cannot be pushed directly. |
| 510 __ mov(result_register(), Operand(lit)); | 511 __ mov(result_register(), Operand(lit)); |
| 511 __ push(result_register()); | 512 codegen()->PushOperand(result_register()); |
| 512 } | 513 } |
| 513 | 514 |
| 514 | 515 |
| 515 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { | 516 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { |
| 516 codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_, | 517 codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_, |
| 517 false_label_); | 518 false_label_); |
| 518 DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectableObject()); | 519 DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectableObject()); |
| 519 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) { | 520 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) { |
| 520 if (false_label_ != fall_through_) __ b(false_label_); | 521 if (false_label_ != fall_through_) __ b(false_label_); |
| 521 } else if (lit->IsTrue() || lit->IsJSObject()) { | 522 } else if (lit->IsTrue() || lit->IsJSObject()) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 536 // For simplicity we always test the accumulator register. | 537 // For simplicity we always test the accumulator register. |
| 537 __ mov(result_register(), Operand(lit)); | 538 __ mov(result_register(), Operand(lit)); |
| 538 codegen()->DoTest(this); | 539 codegen()->DoTest(this); |
| 539 } | 540 } |
| 540 } | 541 } |
| 541 | 542 |
| 542 | 543 |
| 543 void FullCodeGenerator::StackValueContext::DropAndPlug(int count, | 544 void FullCodeGenerator::StackValueContext::DropAndPlug(int count, |
| 544 Register reg) const { | 545 Register reg) const { |
| 545 DCHECK(count > 0); | 546 DCHECK(count > 0); |
| 546 if (count > 1) __ Drop(count - 1); | 547 if (count > 1) codegen()->DropOperands(count - 1); |
| 547 __ StoreP(reg, MemOperand(sp, 0)); | 548 __ StoreP(reg, MemOperand(sp, 0)); |
| 548 } | 549 } |
| 549 | 550 |
| 550 | 551 |
| 551 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, | 552 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, |
| 552 Label* materialize_false) const { | 553 Label* materialize_false) const { |
| 553 DCHECK(materialize_true == materialize_false); | 554 DCHECK(materialize_true == materialize_false); |
| 554 __ bind(materialize_true); | 555 __ bind(materialize_true); |
| 555 } | 556 } |
| 556 | 557 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 569 | 570 |
| 570 void FullCodeGenerator::StackValueContext::Plug( | 571 void FullCodeGenerator::StackValueContext::Plug( |
| 571 Label* materialize_true, Label* materialize_false) const { | 572 Label* materialize_true, Label* materialize_false) const { |
| 572 Label done; | 573 Label done; |
| 573 __ bind(materialize_true); | 574 __ bind(materialize_true); |
| 574 __ LoadRoot(ip, Heap::kTrueValueRootIndex); | 575 __ LoadRoot(ip, Heap::kTrueValueRootIndex); |
| 575 __ b(&done); | 576 __ b(&done); |
| 576 __ bind(materialize_false); | 577 __ bind(materialize_false); |
| 577 __ LoadRoot(ip, Heap::kFalseValueRootIndex); | 578 __ LoadRoot(ip, Heap::kFalseValueRootIndex); |
| 578 __ bind(&done); | 579 __ bind(&done); |
| 579 __ push(ip); | 580 codegen()->PushOperand(ip); |
| 580 } | 581 } |
| 581 | 582 |
| 582 | 583 |
| 583 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, | 584 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, |
| 584 Label* materialize_false) const { | 585 Label* materialize_false) const { |
| 585 DCHECK(materialize_true == true_label_); | 586 DCHECK(materialize_true == true_label_); |
| 586 DCHECK(materialize_false == false_label_); | 587 DCHECK(materialize_false == false_label_); |
| 587 } | 588 } |
| 588 | 589 |
| 589 | 590 |
| 590 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { | 591 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { |
| 591 Heap::RootListIndex value_root_index = | 592 Heap::RootListIndex value_root_index = |
| 592 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 593 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
| 593 __ LoadRoot(result_register(), value_root_index); | 594 __ LoadRoot(result_register(), value_root_index); |
| 594 } | 595 } |
| 595 | 596 |
| 596 | 597 |
| 597 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { | 598 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { |
| 598 Heap::RootListIndex value_root_index = | 599 Heap::RootListIndex value_root_index = |
| 599 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 600 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
| 600 __ LoadRoot(ip, value_root_index); | 601 __ LoadRoot(ip, value_root_index); |
| 601 __ push(ip); | 602 codegen()->PushOperand(ip); |
| 602 } | 603 } |
| 603 | 604 |
| 604 | 605 |
| 605 void FullCodeGenerator::TestContext::Plug(bool flag) const { | 606 void FullCodeGenerator::TestContext::Plug(bool flag) const { |
| 606 codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_, | 607 codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_, |
| 607 false_label_); | 608 false_label_); |
| 608 if (flag) { | 609 if (flag) { |
| 609 if (true_label_ != fall_through_) __ b(true_label_); | 610 if (true_label_ != fall_through_) __ b(true_label_); |
| 610 } else { | 611 } else { |
| 611 if (false_label_ != fall_through_) __ b(false_label_); | 612 if (false_label_ != fall_through_) __ b(false_label_); |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 818 __ RecordWriteContextSlot(cp, offset, result_register(), r5, | 819 __ RecordWriteContextSlot(cp, offset, result_register(), r5, |
| 819 kLRHasBeenSaved, kDontSaveFPRegs, | 820 kLRHasBeenSaved, kDontSaveFPRegs, |
| 820 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); | 821 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |
| 821 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); | 822 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); |
| 822 break; | 823 break; |
| 823 } | 824 } |
| 824 | 825 |
| 825 case VariableLocation::LOOKUP: { | 826 case VariableLocation::LOOKUP: { |
| 826 Comment cmnt(masm_, "[ FunctionDeclaration"); | 827 Comment cmnt(masm_, "[ FunctionDeclaration"); |
| 827 __ mov(r5, Operand(variable->name())); | 828 __ mov(r5, Operand(variable->name())); |
| 828 __ Push(r5); | 829 PushOperand(r5); |
| 829 // Push initial value for function declaration. | 830 // Push initial value for function declaration. |
| 830 VisitForStackValue(declaration->fun()); | 831 VisitForStackValue(declaration->fun()); |
| 831 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); | 832 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes())); |
| 832 __ CallRuntime(Runtime::kDeclareLookupSlot); | 833 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot); |
| 833 break; | 834 break; |
| 834 } | 835 } |
| 835 } | 836 } |
| 836 } | 837 } |
| 837 | 838 |
| 838 | 839 |
| 839 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 840 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
| 840 // Call the runtime to declare the globals. | 841 // Call the runtime to declare the globals. |
| 841 __ mov(r4, Operand(pairs)); | 842 __ mov(r4, Operand(pairs)); |
| 842 __ LoadSmiLiteral(r3, Smi::FromInt(DeclareGlobalsFlags())); | 843 __ LoadSmiLiteral(r3, Smi::FromInt(DeclareGlobalsFlags())); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 920 | 921 |
| 921 __ cmpi(r3, Operand::Zero()); | 922 __ cmpi(r3, Operand::Zero()); |
| 922 __ bne(&next_test); | 923 __ bne(&next_test); |
| 923 __ Drop(1); // Switch value is no longer needed. | 924 __ Drop(1); // Switch value is no longer needed. |
| 924 __ b(clause->body_target()); | 925 __ b(clause->body_target()); |
| 925 } | 926 } |
| 926 | 927 |
| 927 // Discard the test value and jump to the default if present, otherwise to | 928 // Discard the test value and jump to the default if present, otherwise to |
| 928 // the end of the statement. | 929 // the end of the statement. |
| 929 __ bind(&next_test); | 930 __ bind(&next_test); |
| 930 __ Drop(1); // Switch value is no longer needed. | 931 DropOperands(1); // Switch value is no longer needed. |
| 931 if (default_clause == NULL) { | 932 if (default_clause == NULL) { |
| 932 __ b(nested_statement.break_label()); | 933 __ b(nested_statement.break_label()); |
| 933 } else { | 934 } else { |
| 934 __ b(default_clause->body_target()); | 935 __ b(default_clause->body_target()); |
| 935 } | 936 } |
| 936 | 937 |
| 937 // Compile all the case bodies. | 938 // Compile all the case bodies. |
| 938 for (int i = 0; i < clauses->length(); i++) { | 939 for (int i = 0; i < clauses->length(); i++) { |
| 939 Comment cmnt(masm_, "[ Case body"); | 940 Comment cmnt(masm_, "[ Case body"); |
| 940 CaseClause* clause = clauses->at(i); | 941 CaseClause* clause = clauses->at(i); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 954 | 955 |
| 955 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); | 956 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); |
| 956 | 957 |
| 957 Label loop, exit; | 958 Label loop, exit; |
| 958 ForIn loop_statement(this, stmt); | 959 ForIn loop_statement(this, stmt); |
| 959 increment_loop_depth(); | 960 increment_loop_depth(); |
| 960 | 961 |
| 961 // Get the object to enumerate over. | 962 // Get the object to enumerate over. |
| 962 SetExpressionAsStatementPosition(stmt->enumerable()); | 963 SetExpressionAsStatementPosition(stmt->enumerable()); |
| 963 VisitForAccumulatorValue(stmt->enumerable()); | 964 VisitForAccumulatorValue(stmt->enumerable()); |
| 965 OperandStackDepthIncrement(ForIn::kElementCount); |
| 964 | 966 |
| 965 // If the object is null or undefined, skip over the loop, otherwise convert | 967 // If the object is null or undefined, skip over the loop, otherwise convert |
| 966 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. | 968 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. |
| 967 Label convert, done_convert; | 969 Label convert, done_convert; |
| 968 __ JumpIfSmi(r3, &convert); | 970 __ JumpIfSmi(r3, &convert); |
| 969 __ CompareObjectType(r3, r4, r4, FIRST_JS_RECEIVER_TYPE); | 971 __ CompareObjectType(r3, r4, r4, FIRST_JS_RECEIVER_TYPE); |
| 970 __ bge(&done_convert); | 972 __ bge(&done_convert); |
| 971 __ CompareRoot(r3, Heap::kNullValueRootIndex); | 973 __ CompareRoot(r3, Heap::kNullValueRootIndex); |
| 972 __ beq(&exit); | 974 __ beq(&exit); |
| 973 __ CompareRoot(r3, Heap::kUndefinedValueRootIndex); | 975 __ CompareRoot(r3, Heap::kUndefinedValueRootIndex); |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1120 __ bind(loop_statement.continue_label()); | 1122 __ bind(loop_statement.continue_label()); |
| 1121 __ pop(r3); | 1123 __ pop(r3); |
| 1122 __ AddSmiLiteral(r3, r3, Smi::FromInt(1), r0); | 1124 __ AddSmiLiteral(r3, r3, Smi::FromInt(1), r0); |
| 1123 __ push(r3); | 1125 __ push(r3); |
| 1124 | 1126 |
| 1125 EmitBackEdgeBookkeeping(stmt, &loop); | 1127 EmitBackEdgeBookkeeping(stmt, &loop); |
| 1126 __ b(&loop); | 1128 __ b(&loop); |
| 1127 | 1129 |
| 1128 // Remove the pointers stored on the stack. | 1130 // Remove the pointers stored on the stack. |
| 1129 __ bind(loop_statement.break_label()); | 1131 __ bind(loop_statement.break_label()); |
| 1130 __ Drop(5); | 1132 DropOperands(5); |
| 1131 | 1133 |
| 1132 // Exit and decrement the loop depth. | 1134 // Exit and decrement the loop depth. |
| 1133 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 1135 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
| 1134 __ bind(&exit); | 1136 __ bind(&exit); |
| 1135 decrement_loop_depth(); | 1137 decrement_loop_depth(); |
| 1136 } | 1138 } |
| 1137 | 1139 |
| 1138 | 1140 |
| 1139 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, | 1141 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, |
| 1140 bool pretenure) { | 1142 bool pretenure) { |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1390 FastCloneRegExpStub stub(isolate()); | 1392 FastCloneRegExpStub stub(isolate()); |
| 1391 __ CallStub(&stub); | 1393 __ CallStub(&stub); |
| 1392 context()->Plug(r3); | 1394 context()->Plug(r3); |
| 1393 } | 1395 } |
| 1394 | 1396 |
| 1395 | 1397 |
| 1396 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { | 1398 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { |
| 1397 Expression* expression = (property == NULL) ? NULL : property->value(); | 1399 Expression* expression = (property == NULL) ? NULL : property->value(); |
| 1398 if (expression == NULL) { | 1400 if (expression == NULL) { |
| 1399 __ LoadRoot(r4, Heap::kNullValueRootIndex); | 1401 __ LoadRoot(r4, Heap::kNullValueRootIndex); |
| 1400 __ push(r4); | 1402 PushOperand(r4); |
| 1401 } else { | 1403 } else { |
| 1402 VisitForStackValue(expression); | 1404 VisitForStackValue(expression); |
| 1403 if (NeedsHomeObject(expression)) { | 1405 if (NeedsHomeObject(expression)) { |
| 1404 DCHECK(property->kind() == ObjectLiteral::Property::GETTER || | 1406 DCHECK(property->kind() == ObjectLiteral::Property::GETTER || |
| 1405 property->kind() == ObjectLiteral::Property::SETTER); | 1407 property->kind() == ObjectLiteral::Property::SETTER); |
| 1406 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3; | 1408 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3; |
| 1407 EmitSetHomeObject(expression, offset, property->GetSlot()); | 1409 EmitSetHomeObject(expression, offset, property->GetSlot()); |
| 1408 } | 1410 } |
| 1409 } | 1411 } |
| 1410 } | 1412 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1435 AccessorTable accessor_table(zone()); | 1437 AccessorTable accessor_table(zone()); |
| 1436 int property_index = 0; | 1438 int property_index = 0; |
| 1437 for (; property_index < expr->properties()->length(); property_index++) { | 1439 for (; property_index < expr->properties()->length(); property_index++) { |
| 1438 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1440 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
| 1439 if (property->is_computed_name()) break; | 1441 if (property->is_computed_name()) break; |
| 1440 if (property->IsCompileTimeValue()) continue; | 1442 if (property->IsCompileTimeValue()) continue; |
| 1441 | 1443 |
| 1442 Literal* key = property->key()->AsLiteral(); | 1444 Literal* key = property->key()->AsLiteral(); |
| 1443 Expression* value = property->value(); | 1445 Expression* value = property->value(); |
| 1444 if (!result_saved) { | 1446 if (!result_saved) { |
| 1445 __ push(r3); // Save result on stack | 1447 PushOperand(r3); // Save result on stack |
| 1446 result_saved = true; | 1448 result_saved = true; |
| 1447 } | 1449 } |
| 1448 switch (property->kind()) { | 1450 switch (property->kind()) { |
| 1449 case ObjectLiteral::Property::CONSTANT: | 1451 case ObjectLiteral::Property::CONSTANT: |
| 1450 UNREACHABLE(); | 1452 UNREACHABLE(); |
| 1451 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1453 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1452 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1454 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); |
| 1453 // Fall through. | 1455 // Fall through. |
| 1454 case ObjectLiteral::Property::COMPUTED: | 1456 case ObjectLiteral::Property::COMPUTED: |
| 1455 // It is safe to use [[Put]] here because the boilerplate already | 1457 // It is safe to use [[Put]] here because the boilerplate already |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1467 if (NeedsHomeObject(value)) { | 1469 if (NeedsHomeObject(value)) { |
| 1468 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); | 1470 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); |
| 1469 } | 1471 } |
| 1470 } else { | 1472 } else { |
| 1471 VisitForEffect(value); | 1473 VisitForEffect(value); |
| 1472 } | 1474 } |
| 1473 break; | 1475 break; |
| 1474 } | 1476 } |
| 1475 // Duplicate receiver on stack. | 1477 // Duplicate receiver on stack. |
| 1476 __ LoadP(r3, MemOperand(sp)); | 1478 __ LoadP(r3, MemOperand(sp)); |
| 1477 __ push(r3); | 1479 PushOperand(r3); |
| 1478 VisitForStackValue(key); | 1480 VisitForStackValue(key); |
| 1479 VisitForStackValue(value); | 1481 VisitForStackValue(value); |
| 1480 if (property->emit_store()) { | 1482 if (property->emit_store()) { |
| 1481 if (NeedsHomeObject(value)) { | 1483 if (NeedsHomeObject(value)) { |
| 1482 EmitSetHomeObject(value, 2, property->GetSlot()); | 1484 EmitSetHomeObject(value, 2, property->GetSlot()); |
| 1483 } | 1485 } |
| 1484 __ LoadSmiLiteral(r3, Smi::FromInt(SLOPPY)); // PropertyAttributes | 1486 __ LoadSmiLiteral(r3, Smi::FromInt(SLOPPY)); // PropertyAttributes |
| 1485 __ push(r3); | 1487 PushOperand(r3); |
| 1486 __ CallRuntime(Runtime::kSetProperty); | 1488 CallRuntimeWithOperands(Runtime::kSetProperty); |
| 1487 } else { | 1489 } else { |
| 1488 __ Drop(3); | 1490 DropOperands(3); |
| 1489 } | 1491 } |
| 1490 break; | 1492 break; |
| 1491 case ObjectLiteral::Property::PROTOTYPE: | 1493 case ObjectLiteral::Property::PROTOTYPE: |
| 1492 // Duplicate receiver on stack. | 1494 // Duplicate receiver on stack. |
| 1493 __ LoadP(r3, MemOperand(sp)); | 1495 __ LoadP(r3, MemOperand(sp)); |
| 1494 __ push(r3); | 1496 PushOperand(r3); |
| 1495 VisitForStackValue(value); | 1497 VisitForStackValue(value); |
| 1496 DCHECK(property->emit_store()); | 1498 DCHECK(property->emit_store()); |
| 1497 __ CallRuntime(Runtime::kInternalSetPrototype); | 1499 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); |
| 1498 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), | 1500 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), |
| 1499 NO_REGISTERS); | 1501 NO_REGISTERS); |
| 1500 break; | 1502 break; |
| 1501 case ObjectLiteral::Property::GETTER: | 1503 case ObjectLiteral::Property::GETTER: |
| 1502 if (property->emit_store()) { | 1504 if (property->emit_store()) { |
| 1503 accessor_table.lookup(key)->second->getter = property; | 1505 accessor_table.lookup(key)->second->getter = property; |
| 1504 } | 1506 } |
| 1505 break; | 1507 break; |
| 1506 case ObjectLiteral::Property::SETTER: | 1508 case ObjectLiteral::Property::SETTER: |
| 1507 if (property->emit_store()) { | 1509 if (property->emit_store()) { |
| 1508 accessor_table.lookup(key)->second->setter = property; | 1510 accessor_table.lookup(key)->second->setter = property; |
| 1509 } | 1511 } |
| 1510 break; | 1512 break; |
| 1511 } | 1513 } |
| 1512 } | 1514 } |
| 1513 | 1515 |
| 1514 // Emit code to define accessors, using only a single call to the runtime for | 1516 // Emit code to define accessors, using only a single call to the runtime for |
| 1515 // each pair of corresponding getters and setters. | 1517 // each pair of corresponding getters and setters. |
| 1516 for (AccessorTable::Iterator it = accessor_table.begin(); | 1518 for (AccessorTable::Iterator it = accessor_table.begin(); |
| 1517 it != accessor_table.end(); ++it) { | 1519 it != accessor_table.end(); ++it) { |
| 1518 __ LoadP(r3, MemOperand(sp)); // Duplicate receiver. | 1520 __ LoadP(r3, MemOperand(sp)); // Duplicate receiver. |
| 1519 __ push(r3); | 1521 PushOperand(r3); |
| 1520 VisitForStackValue(it->first); | 1522 VisitForStackValue(it->first); |
| 1521 EmitAccessor(it->second->getter); | 1523 EmitAccessor(it->second->getter); |
| 1522 EmitAccessor(it->second->setter); | 1524 EmitAccessor(it->second->setter); |
| 1523 __ LoadSmiLiteral(r3, Smi::FromInt(NONE)); | 1525 __ LoadSmiLiteral(r3, Smi::FromInt(NONE)); |
| 1524 __ push(r3); | 1526 PushOperand(r3); |
| 1525 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked); | 1527 CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked); |
| 1526 } | 1528 } |
| 1527 | 1529 |
| 1528 // Object literals have two parts. The "static" part on the left contains no | 1530 // Object literals have two parts. The "static" part on the left contains no |
| 1529 // computed property names, and so we can compute its map ahead of time; see | 1531 // computed property names, and so we can compute its map ahead of time; see |
| 1530 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part | 1532 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part |
| 1531 // starts with the first computed property name, and continues with all | 1533 // starts with the first computed property name, and continues with all |
| 1532 // properties to its right. All the code from above initializes the static | 1534 // properties to its right. All the code from above initializes the static |
| 1533 // component of the object literal, and arranges for the map of the result to | 1535 // component of the object literal, and arranges for the map of the result to |
| 1534 // reflect the static order in which the keys appear. For the dynamic | 1536 // reflect the static order in which the keys appear. For the dynamic |
| 1535 // properties, we compile them into a series of "SetOwnProperty" runtime | 1537 // properties, we compile them into a series of "SetOwnProperty" runtime |
| 1536 // calls. This will preserve insertion order. | 1538 // calls. This will preserve insertion order. |
| 1537 for (; property_index < expr->properties()->length(); property_index++) { | 1539 for (; property_index < expr->properties()->length(); property_index++) { |
| 1538 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1540 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
| 1539 | 1541 |
| 1540 Expression* value = property->value(); | 1542 Expression* value = property->value(); |
| 1541 if (!result_saved) { | 1543 if (!result_saved) { |
| 1542 __ push(r3); // Save result on the stack | 1544 PushOperand(r3); // Save result on the stack |
| 1543 result_saved = true; | 1545 result_saved = true; |
| 1544 } | 1546 } |
| 1545 | 1547 |
| 1546 __ LoadP(r3, MemOperand(sp)); // Duplicate receiver. | 1548 __ LoadP(r3, MemOperand(sp)); // Duplicate receiver. |
| 1547 __ push(r3); | 1549 PushOperand(r3); |
| 1548 | 1550 |
| 1549 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { | 1551 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { |
| 1550 DCHECK(!property->is_computed_name()); | 1552 DCHECK(!property->is_computed_name()); |
| 1551 VisitForStackValue(value); | 1553 VisitForStackValue(value); |
| 1552 DCHECK(property->emit_store()); | 1554 DCHECK(property->emit_store()); |
| 1553 __ CallRuntime(Runtime::kInternalSetPrototype); | 1555 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); |
| 1554 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), | 1556 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), |
| 1555 NO_REGISTERS); | 1557 NO_REGISTERS); |
| 1556 } else { | 1558 } else { |
| 1557 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); | 1559 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); |
| 1558 VisitForStackValue(value); | 1560 VisitForStackValue(value); |
| 1559 if (NeedsHomeObject(value)) { | 1561 if (NeedsHomeObject(value)) { |
| 1560 EmitSetHomeObject(value, 2, property->GetSlot()); | 1562 EmitSetHomeObject(value, 2, property->GetSlot()); |
| 1561 } | 1563 } |
| 1562 | 1564 |
| 1563 switch (property->kind()) { | 1565 switch (property->kind()) { |
| 1564 case ObjectLiteral::Property::CONSTANT: | 1566 case ObjectLiteral::Property::CONSTANT: |
| 1565 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1567 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1566 case ObjectLiteral::Property::COMPUTED: | 1568 case ObjectLiteral::Property::COMPUTED: |
| 1567 if (property->emit_store()) { | 1569 if (property->emit_store()) { |
| 1568 __ Push(Smi::FromInt(NONE)); | 1570 PushOperand(Smi::FromInt(NONE)); |
| 1569 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); | 1571 PushOperand(Smi::FromInt(property->NeedsSetFunctionName())); |
| 1570 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); | 1572 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral); |
| 1571 } else { | 1573 } else { |
| 1572 __ Drop(3); | 1574 DropOperands(3); |
| 1573 } | 1575 } |
| 1574 break; | 1576 break; |
| 1575 | 1577 |
| 1576 case ObjectLiteral::Property::PROTOTYPE: | 1578 case ObjectLiteral::Property::PROTOTYPE: |
| 1577 UNREACHABLE(); | 1579 UNREACHABLE(); |
| 1578 break; | 1580 break; |
| 1579 | 1581 |
| 1580 case ObjectLiteral::Property::GETTER: | 1582 case ObjectLiteral::Property::GETTER: |
| 1581 __ Push(Smi::FromInt(NONE)); | 1583 PushOperand(Smi::FromInt(NONE)); |
| 1582 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); | 1584 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked); |
| 1583 break; | 1585 break; |
| 1584 | 1586 |
| 1585 case ObjectLiteral::Property::SETTER: | 1587 case ObjectLiteral::Property::SETTER: |
| 1586 __ Push(Smi::FromInt(NONE)); | 1588 PushOperand(Smi::FromInt(NONE)); |
| 1587 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); | 1589 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked); |
| 1588 break; | 1590 break; |
| 1589 } | 1591 } |
| 1590 } | 1592 } |
| 1591 } | 1593 } |
| 1592 | 1594 |
| 1593 if (expr->has_function()) { | 1595 if (expr->has_function()) { |
| 1594 DCHECK(result_saved); | 1596 DCHECK(result_saved); |
| 1595 __ LoadP(r3, MemOperand(sp)); | 1597 __ LoadP(r3, MemOperand(sp)); |
| 1596 __ push(r3); | 1598 __ push(r3); |
| 1597 __ CallRuntime(Runtime::kToFastProperties); | 1599 __ CallRuntime(Runtime::kToFastProperties); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1642 // them into the newly cloned array. | 1644 // them into the newly cloned array. |
| 1643 int array_index = 0; | 1645 int array_index = 0; |
| 1644 for (; array_index < length; array_index++) { | 1646 for (; array_index < length; array_index++) { |
| 1645 Expression* subexpr = subexprs->at(array_index); | 1647 Expression* subexpr = subexprs->at(array_index); |
| 1646 DCHECK(!subexpr->IsSpread()); | 1648 DCHECK(!subexpr->IsSpread()); |
| 1647 // If the subexpression is a literal or a simple materialized literal it | 1649 // If the subexpression is a literal or a simple materialized literal it |
| 1648 // is already set in the cloned array. | 1650 // is already set in the cloned array. |
| 1649 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 1651 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
| 1650 | 1652 |
| 1651 if (!result_saved) { | 1653 if (!result_saved) { |
| 1652 __ push(r3); | 1654 PushOperand(r3); |
| 1653 result_saved = true; | 1655 result_saved = true; |
| 1654 } | 1656 } |
| 1655 VisitForAccumulatorValue(subexpr); | 1657 VisitForAccumulatorValue(subexpr); |
| 1656 | 1658 |
| 1657 __ LoadSmiLiteral(StoreDescriptor::NameRegister(), | 1659 __ LoadSmiLiteral(StoreDescriptor::NameRegister(), |
| 1658 Smi::FromInt(array_index)); | 1660 Smi::FromInt(array_index)); |
| 1659 __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp, 0)); | 1661 __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp, 0)); |
| 1660 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); | 1662 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); |
| 1661 Handle<Code> ic = | 1663 Handle<Code> ic = |
| 1662 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 1664 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 1663 CallIC(ic); | 1665 CallIC(ic); |
| 1664 | 1666 |
| 1665 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); | 1667 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); |
| 1666 } | 1668 } |
| 1667 | 1669 |
| 1668 // In case the array literal contains spread expressions it has two parts. The | 1670 // In case the array literal contains spread expressions it has two parts. The |
| 1669 // first part is the "static" array which has a literal index is handled | 1671 // first part is the "static" array which has a literal index is handled |
| 1670 // above. The second part is the part after the first spread expression | 1672 // above. The second part is the part after the first spread expression |
| 1671 // (inclusive) and these elements gets appended to the array. Note that the | 1673 // (inclusive) and these elements gets appended to the array. Note that the |
| 1672 // number elements an iterable produces is unknown ahead of time. | 1674 // number elements an iterable produces is unknown ahead of time. |
| 1673 if (array_index < length && result_saved) { | 1675 if (array_index < length && result_saved) { |
| 1674 __ Pop(r3); | 1676 PopOperand(r3); |
| 1675 result_saved = false; | 1677 result_saved = false; |
| 1676 } | 1678 } |
| 1677 for (; array_index < length; array_index++) { | 1679 for (; array_index < length; array_index++) { |
| 1678 Expression* subexpr = subexprs->at(array_index); | 1680 Expression* subexpr = subexprs->at(array_index); |
| 1679 | 1681 |
| 1680 __ Push(r3); | 1682 PushOperand(r3); |
| 1681 DCHECK(!subexpr->IsSpread()); | 1683 DCHECK(!subexpr->IsSpread()); |
| 1682 VisitForStackValue(subexpr); | 1684 VisitForStackValue(subexpr); |
| 1683 __ CallRuntime(Runtime::kAppendElement); | 1685 CallRuntimeWithOperands(Runtime::kAppendElement); |
| 1684 | 1686 |
| 1685 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); | 1687 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); |
| 1686 } | 1688 } |
| 1687 | 1689 |
| 1688 if (result_saved) { | 1690 if (result_saved) { |
| 1689 context()->PlugTOS(); | 1691 context()->PlugTOS(); |
| 1690 } else { | 1692 } else { |
| 1691 context()->Plug(r3); | 1693 context()->Plug(r3); |
| 1692 } | 1694 } |
| 1693 } | 1695 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1714 __ LoadP(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); | 1716 __ LoadP(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); |
| 1715 } else { | 1717 } else { |
| 1716 VisitForStackValue(property->obj()); | 1718 VisitForStackValue(property->obj()); |
| 1717 } | 1719 } |
| 1718 break; | 1720 break; |
| 1719 case NAMED_SUPER_PROPERTY: | 1721 case NAMED_SUPER_PROPERTY: |
| 1720 VisitForStackValue( | 1722 VisitForStackValue( |
| 1721 property->obj()->AsSuperPropertyReference()->this_var()); | 1723 property->obj()->AsSuperPropertyReference()->this_var()); |
| 1722 VisitForAccumulatorValue( | 1724 VisitForAccumulatorValue( |
| 1723 property->obj()->AsSuperPropertyReference()->home_object()); | 1725 property->obj()->AsSuperPropertyReference()->home_object()); |
| 1724 __ Push(result_register()); | 1726 PushOperand(result_register()); |
| 1725 if (expr->is_compound()) { | 1727 if (expr->is_compound()) { |
| 1726 const Register scratch = r4; | 1728 const Register scratch = r4; |
| 1727 __ LoadP(scratch, MemOperand(sp, kPointerSize)); | 1729 __ LoadP(scratch, MemOperand(sp, kPointerSize)); |
| 1728 __ Push(scratch, result_register()); | 1730 PushOperands(scratch, result_register()); |
| 1729 } | 1731 } |
| 1730 break; | 1732 break; |
| 1731 case KEYED_SUPER_PROPERTY: { | 1733 case KEYED_SUPER_PROPERTY: { |
| 1732 const Register scratch = r4; | 1734 const Register scratch = r4; |
| 1733 VisitForStackValue( | 1735 VisitForStackValue( |
| 1734 property->obj()->AsSuperPropertyReference()->this_var()); | 1736 property->obj()->AsSuperPropertyReference()->this_var()); |
| 1735 VisitForAccumulatorValue( | 1737 VisitForAccumulatorValue( |
| 1736 property->obj()->AsSuperPropertyReference()->home_object()); | 1738 property->obj()->AsSuperPropertyReference()->home_object()); |
| 1737 __ mr(scratch, result_register()); | 1739 __ mr(scratch, result_register()); |
| 1738 VisitForAccumulatorValue(property->key()); | 1740 VisitForAccumulatorValue(property->key()); |
| 1739 __ Push(scratch, result_register()); | 1741 PushOperands(scratch, result_register()); |
| 1740 if (expr->is_compound()) { | 1742 if (expr->is_compound()) { |
| 1741 const Register scratch1 = r5; | 1743 const Register scratch1 = r5; |
| 1742 __ LoadP(scratch1, MemOperand(sp, 2 * kPointerSize)); | 1744 __ LoadP(scratch1, MemOperand(sp, 2 * kPointerSize)); |
| 1743 __ Push(scratch1, scratch, result_register()); | 1745 PushOperands(scratch1, scratch, result_register()); |
| 1744 } | 1746 } |
| 1745 break; | 1747 break; |
| 1746 } | 1748 } |
| 1747 case KEYED_PROPERTY: | 1749 case KEYED_PROPERTY: |
| 1748 if (expr->is_compound()) { | 1750 if (expr->is_compound()) { |
| 1749 VisitForStackValue(property->obj()); | 1751 VisitForStackValue(property->obj()); |
| 1750 VisitForStackValue(property->key()); | 1752 VisitForStackValue(property->key()); |
| 1751 __ LoadP(LoadDescriptor::ReceiverRegister(), | 1753 __ LoadP(LoadDescriptor::ReceiverRegister(), |
| 1752 MemOperand(sp, 1 * kPointerSize)); | 1754 MemOperand(sp, 1 * kPointerSize)); |
| 1753 __ LoadP(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); | 1755 __ LoadP(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1781 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 1783 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
| 1782 break; | 1784 break; |
| 1783 case KEYED_PROPERTY: | 1785 case KEYED_PROPERTY: |
| 1784 EmitKeyedPropertyLoad(property); | 1786 EmitKeyedPropertyLoad(property); |
| 1785 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 1787 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
| 1786 break; | 1788 break; |
| 1787 } | 1789 } |
| 1788 } | 1790 } |
| 1789 | 1791 |
| 1790 Token::Value op = expr->binary_op(); | 1792 Token::Value op = expr->binary_op(); |
| 1791 __ push(r3); // Left operand goes on the stack. | 1793 PushOperand(r3); // Left operand goes on the stack. |
| 1792 VisitForAccumulatorValue(expr->value()); | 1794 VisitForAccumulatorValue(expr->value()); |
| 1793 | 1795 |
| 1794 AccumulatorValueContext context(this); | 1796 AccumulatorValueContext context(this); |
| 1795 if (ShouldInlineSmiCase(op)) { | 1797 if (ShouldInlineSmiCase(op)) { |
| 1796 EmitInlineSmiBinaryOp(expr->binary_operation(), op, expr->target(), | 1798 EmitInlineSmiBinaryOp(expr->binary_operation(), op, expr->target(), |
| 1797 expr->value()); | 1799 expr->value()); |
| 1798 } else { | 1800 } else { |
| 1799 EmitBinaryOp(expr->binary_operation(), op); | 1801 EmitBinaryOp(expr->binary_operation(), op); |
| 1800 } | 1802 } |
| 1801 | 1803 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1873 __ mr(r4, cp); | 1875 __ mr(r4, cp); |
| 1874 __ RecordWriteField(r3, JSGeneratorObject::kContextOffset, r4, r5, | 1876 __ RecordWriteField(r3, JSGeneratorObject::kContextOffset, r4, r5, |
| 1875 kLRHasBeenSaved, kDontSaveFPRegs); | 1877 kLRHasBeenSaved, kDontSaveFPRegs); |
| 1876 __ addi(r4, fp, Operand(StandardFrameConstants::kExpressionsOffset)); | 1878 __ addi(r4, fp, Operand(StandardFrameConstants::kExpressionsOffset)); |
| 1877 __ cmp(sp, r4); | 1879 __ cmp(sp, r4); |
| 1878 __ beq(&post_runtime); | 1880 __ beq(&post_runtime); |
| 1879 __ push(r3); // generator object | 1881 __ push(r3); // generator object |
| 1880 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 1882 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
| 1881 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1883 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 1882 __ bind(&post_runtime); | 1884 __ bind(&post_runtime); |
| 1883 __ pop(result_register()); | 1885 PopOperand(result_register()); |
| 1884 EmitReturnSequence(); | 1886 EmitReturnSequence(); |
| 1885 | 1887 |
| 1886 __ bind(&resume); | 1888 __ bind(&resume); |
| 1887 context()->Plug(result_register()); | 1889 context()->Plug(result_register()); |
| 1888 break; | 1890 break; |
| 1889 } | 1891 } |
| 1890 | 1892 |
| 1891 case Yield::kFinal: { | 1893 case Yield::kFinal: { |
| 1892 // Pop value from top-of-stack slot, box result into result register. | 1894 // Pop value from top-of-stack slot, box result into result register. |
| 1895 OperandStackDepthDecrement(1); |
| 1893 EmitCreateIteratorResult(true); | 1896 EmitCreateIteratorResult(true); |
| 1894 EmitUnwindAndReturn(); | 1897 EmitUnwindAndReturn(); |
| 1895 break; | 1898 break; |
| 1896 } | 1899 } |
| 1897 | 1900 |
| 1898 case Yield::kDelegating: | 1901 case Yield::kDelegating: |
| 1899 UNREACHABLE(); | 1902 UNREACHABLE(); |
| 1900 } | 1903 } |
| 1901 } | 1904 } |
| 1902 | 1905 |
| 1903 | 1906 |
| 1904 void FullCodeGenerator::EmitGeneratorResume( | 1907 void FullCodeGenerator::EmitGeneratorResume( |
| 1905 Expression* generator, Expression* value, | 1908 Expression* generator, Expression* value, |
| 1906 JSGeneratorObject::ResumeMode resume_mode) { | 1909 JSGeneratorObject::ResumeMode resume_mode) { |
| 1907 // The value stays in r3, and is ultimately read by the resumed generator, as | 1910 // The value stays in r3, and is ultimately read by the resumed generator, as |
| 1908 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it | 1911 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it |
| 1909 // is read to throw the value when the resumed generator is already closed. | 1912 // is read to throw the value when the resumed generator is already closed. |
| 1910 // r4 will hold the generator object until the activation has been resumed. | 1913 // r4 will hold the generator object until the activation has been resumed. |
| 1911 VisitForStackValue(generator); | 1914 VisitForStackValue(generator); |
| 1912 VisitForAccumulatorValue(value); | 1915 VisitForAccumulatorValue(value); |
| 1913 __ pop(r4); | 1916 PopOperand(r4); |
| 1914 | 1917 |
| 1915 // Store input value into generator object. | 1918 // Store input value into generator object. |
| 1916 __ StoreP(result_register(), | 1919 __ StoreP(result_register(), |
| 1917 FieldMemOperand(r4, JSGeneratorObject::kInputOffset), r0); | 1920 FieldMemOperand(r4, JSGeneratorObject::kInputOffset), r0); |
| 1918 __ mr(r5, result_register()); | 1921 __ mr(r5, result_register()); |
| 1919 __ RecordWriteField(r4, JSGeneratorObject::kInputOffset, r5, r6, | 1922 __ RecordWriteField(r4, JSGeneratorObject::kInputOffset, r5, r6, |
| 1920 kLRHasBeenSaved, kDontSaveFPRegs); | 1923 kLRHasBeenSaved, kDontSaveFPRegs); |
| 1921 | 1924 |
| 1922 // Load suspended function and context. | 1925 // Load suspended function and context. |
| 1923 __ LoadP(cp, FieldMemOperand(r4, JSGeneratorObject::kContextOffset)); | 1926 __ LoadP(cp, FieldMemOperand(r4, JSGeneratorObject::kContextOffset)); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2006 __ Push(r4, result_register()); | 2009 __ Push(r4, result_register()); |
| 2007 __ Push(Smi::FromInt(resume_mode)); | 2010 __ Push(Smi::FromInt(resume_mode)); |
| 2008 __ CallRuntime(Runtime::kResumeJSGeneratorObject); | 2011 __ CallRuntime(Runtime::kResumeJSGeneratorObject); |
| 2009 // Not reached: the runtime call returns elsewhere. | 2012 // Not reached: the runtime call returns elsewhere. |
| 2010 __ stop("not-reached"); | 2013 __ stop("not-reached"); |
| 2011 | 2014 |
| 2012 __ bind(&done); | 2015 __ bind(&done); |
| 2013 context()->Plug(result_register()); | 2016 context()->Plug(result_register()); |
| 2014 } | 2017 } |
| 2015 | 2018 |
| 2019 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) { |
| 2020 OperandStackDepthIncrement(2); |
| 2021 __ Push(reg1, reg2); |
| 2022 } |
| 2023 |
| 2024 void FullCodeGenerator::PushOperands(Register reg1, Register reg2, |
| 2025 Register reg3) { |
| 2026 OperandStackDepthIncrement(3); |
| 2027 __ Push(reg1, reg2, reg3); |
| 2028 } |
| 2029 |
| 2030 void FullCodeGenerator::PushOperands(Register reg1, Register reg2, |
| 2031 Register reg3, Register reg4) { |
| 2032 OperandStackDepthIncrement(4); |
| 2033 __ Push(reg1, reg2, reg3, reg4); |
| 2034 } |
| 2035 |
| 2036 void FullCodeGenerator::PopOperands(Register reg1, Register reg2) { |
| 2037 OperandStackDepthDecrement(2); |
| 2038 __ Pop(reg1, reg2); |
| 2039 } |
| 2040 |
| 2041 void FullCodeGenerator::EmitOperandStackDepthCheck() { |
| 2042 if (FLAG_debug_code) { |
| 2043 int expected_diff = StandardFrameConstants::kFixedFrameSizeFromFp + |
| 2044 operand_stack_depth_ * kPointerSize; |
| 2045 __ sub(r3, fp, sp); |
| 2046 __ cmpi(r3, Operand(expected_diff)); |
| 2047 __ Assert(eq, kUnexpectedStackDepth); |
| 2048 } |
| 2049 } |
| 2016 | 2050 |
| 2017 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { | 2051 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { |
| 2018 Label allocate, done_allocate; | 2052 Label allocate, done_allocate; |
| 2019 | 2053 |
| 2020 __ Allocate(JSIteratorResult::kSize, r3, r5, r6, &allocate, TAG_OBJECT); | 2054 __ Allocate(JSIteratorResult::kSize, r3, r5, r6, &allocate, TAG_OBJECT); |
| 2021 __ b(&done_allocate); | 2055 __ b(&done_allocate); |
| 2022 | 2056 |
| 2023 __ bind(&allocate); | 2057 __ bind(&allocate); |
| 2024 __ Push(Smi::FromInt(JSIteratorResult::kSize)); | 2058 __ Push(Smi::FromInt(JSIteratorResult::kSize)); |
| 2025 __ CallRuntime(Runtime::kAllocateInNewSpace); | 2059 __ CallRuntime(Runtime::kAllocateInNewSpace); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2055 Expression* left_expr, | 2089 Expression* left_expr, |
| 2056 Expression* right_expr) { | 2090 Expression* right_expr) { |
| 2057 Label done, smi_case, stub_call; | 2091 Label done, smi_case, stub_call; |
| 2058 | 2092 |
| 2059 Register scratch1 = r5; | 2093 Register scratch1 = r5; |
| 2060 Register scratch2 = r6; | 2094 Register scratch2 = r6; |
| 2061 | 2095 |
| 2062 // Get the arguments. | 2096 // Get the arguments. |
| 2063 Register left = r4; | 2097 Register left = r4; |
| 2064 Register right = r3; | 2098 Register right = r3; |
| 2065 __ pop(left); | 2099 PopOperand(left); |
| 2066 | 2100 |
| 2067 // Perform combined smi check on both operands. | 2101 // Perform combined smi check on both operands. |
| 2068 __ orx(scratch1, left, right); | 2102 __ orx(scratch1, left, right); |
| 2069 STATIC_ASSERT(kSmiTag == 0); | 2103 STATIC_ASSERT(kSmiTag == 0); |
| 2070 JumpPatchSite patch_site(masm_); | 2104 JumpPatchSite patch_site(masm_); |
| 2071 patch_site.EmitJumpIfSmi(scratch1, &smi_case); | 2105 patch_site.EmitJumpIfSmi(scratch1, &smi_case); |
| 2072 | 2106 |
| 2073 __ bind(&stub_call); | 2107 __ bind(&stub_call); |
| 2074 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); | 2108 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); |
| 2075 CallIC(code, expr->BinaryOperationFeedbackId()); | 2109 CallIC(code, expr->BinaryOperationFeedbackId()); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2179 for (int i = 0; i < lit->properties()->length(); i++) { | 2213 for (int i = 0; i < lit->properties()->length(); i++) { |
| 2180 ObjectLiteral::Property* property = lit->properties()->at(i); | 2214 ObjectLiteral::Property* property = lit->properties()->at(i); |
| 2181 Expression* value = property->value(); | 2215 Expression* value = property->value(); |
| 2182 | 2216 |
| 2183 Register scratch = r4; | 2217 Register scratch = r4; |
| 2184 if (property->is_static()) { | 2218 if (property->is_static()) { |
| 2185 __ LoadP(scratch, MemOperand(sp, kPointerSize)); // constructor | 2219 __ LoadP(scratch, MemOperand(sp, kPointerSize)); // constructor |
| 2186 } else { | 2220 } else { |
| 2187 __ LoadP(scratch, MemOperand(sp, 0)); // prototype | 2221 __ LoadP(scratch, MemOperand(sp, 0)); // prototype |
| 2188 } | 2222 } |
| 2189 __ push(scratch); | 2223 PushOperand(scratch); |
| 2190 EmitPropertyKey(property, lit->GetIdForProperty(i)); | 2224 EmitPropertyKey(property, lit->GetIdForProperty(i)); |
| 2191 | 2225 |
| 2192 // The static prototype property is read only. We handle the non computed | 2226 // The static prototype property is read only. We handle the non computed |
| 2193 // property name case in the parser. Since this is the only case where we | 2227 // property name case in the parser. Since this is the only case where we |
| 2194 // need to check for an own read only property we special case this so we do | 2228 // need to check for an own read only property we special case this so we do |
| 2195 // not need to do this for every property. | 2229 // not need to do this for every property. |
| 2196 if (property->is_static() && property->is_computed_name()) { | 2230 if (property->is_static() && property->is_computed_name()) { |
| 2197 __ CallRuntime(Runtime::kThrowIfStaticPrototype); | 2231 __ CallRuntime(Runtime::kThrowIfStaticPrototype); |
| 2198 __ push(r3); | 2232 __ push(r3); |
| 2199 } | 2233 } |
| 2200 | 2234 |
| 2201 VisitForStackValue(value); | 2235 VisitForStackValue(value); |
| 2202 if (NeedsHomeObject(value)) { | 2236 if (NeedsHomeObject(value)) { |
| 2203 EmitSetHomeObject(value, 2, property->GetSlot()); | 2237 EmitSetHomeObject(value, 2, property->GetSlot()); |
| 2204 } | 2238 } |
| 2205 | 2239 |
| 2206 switch (property->kind()) { | 2240 switch (property->kind()) { |
| 2207 case ObjectLiteral::Property::CONSTANT: | 2241 case ObjectLiteral::Property::CONSTANT: |
| 2208 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 2242 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 2209 case ObjectLiteral::Property::PROTOTYPE: | 2243 case ObjectLiteral::Property::PROTOTYPE: |
| 2210 UNREACHABLE(); | 2244 UNREACHABLE(); |
| 2211 case ObjectLiteral::Property::COMPUTED: | 2245 case ObjectLiteral::Property::COMPUTED: |
| 2212 __ Push(Smi::FromInt(DONT_ENUM)); | 2246 PushOperand(Smi::FromInt(DONT_ENUM)); |
| 2213 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); | 2247 PushOperand(Smi::FromInt(property->NeedsSetFunctionName())); |
| 2214 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); | 2248 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral); |
| 2215 break; | 2249 break; |
| 2216 | 2250 |
| 2217 case ObjectLiteral::Property::GETTER: | 2251 case ObjectLiteral::Property::GETTER: |
| 2218 __ Push(Smi::FromInt(DONT_ENUM)); | 2252 PushOperand(Smi::FromInt(DONT_ENUM)); |
| 2219 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); | 2253 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked); |
| 2220 break; | 2254 break; |
| 2221 | 2255 |
| 2222 case ObjectLiteral::Property::SETTER: | 2256 case ObjectLiteral::Property::SETTER: |
| 2223 __ Push(Smi::FromInt(DONT_ENUM)); | 2257 PushOperand(Smi::FromInt(DONT_ENUM)); |
| 2224 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); | 2258 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked); |
| 2225 break; | 2259 break; |
| 2226 | 2260 |
| 2227 default: | 2261 default: |
| 2228 UNREACHABLE(); | 2262 UNREACHABLE(); |
| 2229 } | 2263 } |
| 2230 } | 2264 } |
| 2231 } | 2265 } |
| 2232 | 2266 |
| 2233 | 2267 |
| 2234 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { | 2268 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { |
| 2235 __ pop(r4); | 2269 PopOperand(r4); |
| 2236 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); | 2270 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); |
| 2237 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2271 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
| 2238 CallIC(code, expr->BinaryOperationFeedbackId()); | 2272 CallIC(code, expr->BinaryOperationFeedbackId()); |
| 2239 patch_site.EmitPatchInfo(); | 2273 patch_site.EmitPatchInfo(); |
| 2240 context()->Plug(r3); | 2274 context()->Plug(r3); |
| 2241 } | 2275 } |
| 2242 | 2276 |
| 2243 | 2277 |
| 2244 void FullCodeGenerator::EmitAssignment(Expression* expr, | 2278 void FullCodeGenerator::EmitAssignment(Expression* expr, |
| 2245 FeedbackVectorSlot slot) { | 2279 FeedbackVectorSlot slot) { |
| 2246 DCHECK(expr->IsValidReferenceExpressionOrThis()); | 2280 DCHECK(expr->IsValidReferenceExpressionOrThis()); |
| 2247 | 2281 |
| 2248 Property* prop = expr->AsProperty(); | 2282 Property* prop = expr->AsProperty(); |
| 2249 LhsKind assign_type = Property::GetAssignType(prop); | 2283 LhsKind assign_type = Property::GetAssignType(prop); |
| 2250 | 2284 |
| 2251 switch (assign_type) { | 2285 switch (assign_type) { |
| 2252 case VARIABLE: { | 2286 case VARIABLE: { |
| 2253 Variable* var = expr->AsVariableProxy()->var(); | 2287 Variable* var = expr->AsVariableProxy()->var(); |
| 2254 EffectContext context(this); | 2288 EffectContext context(this); |
| 2255 EmitVariableAssignment(var, Token::ASSIGN, slot); | 2289 EmitVariableAssignment(var, Token::ASSIGN, slot); |
| 2256 break; | 2290 break; |
| 2257 } | 2291 } |
| 2258 case NAMED_PROPERTY: { | 2292 case NAMED_PROPERTY: { |
| 2259 __ push(r3); // Preserve value. | 2293 PushOperand(r3); // Preserve value. |
| 2260 VisitForAccumulatorValue(prop->obj()); | 2294 VisitForAccumulatorValue(prop->obj()); |
| 2261 __ Move(StoreDescriptor::ReceiverRegister(), r3); | 2295 __ Move(StoreDescriptor::ReceiverRegister(), r3); |
| 2262 __ pop(StoreDescriptor::ValueRegister()); // Restore value. | 2296 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. |
| 2263 __ mov(StoreDescriptor::NameRegister(), | 2297 __ mov(StoreDescriptor::NameRegister(), |
| 2264 Operand(prop->key()->AsLiteral()->value())); | 2298 Operand(prop->key()->AsLiteral()->value())); |
| 2265 EmitLoadStoreICSlot(slot); | 2299 EmitLoadStoreICSlot(slot); |
| 2266 CallStoreIC(); | 2300 CallStoreIC(); |
| 2267 break; | 2301 break; |
| 2268 } | 2302 } |
| 2269 case NAMED_SUPER_PROPERTY: { | 2303 case NAMED_SUPER_PROPERTY: { |
| 2270 __ Push(r3); | 2304 PushOperand(r3); |
| 2271 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 2305 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
| 2272 VisitForAccumulatorValue( | 2306 VisitForAccumulatorValue( |
| 2273 prop->obj()->AsSuperPropertyReference()->home_object()); | 2307 prop->obj()->AsSuperPropertyReference()->home_object()); |
| 2274 // stack: value, this; r3: home_object | 2308 // stack: value, this; r3: home_object |
| 2275 Register scratch = r5; | 2309 Register scratch = r5; |
| 2276 Register scratch2 = r6; | 2310 Register scratch2 = r6; |
| 2277 __ mr(scratch, result_register()); // home_object | 2311 __ mr(scratch, result_register()); // home_object |
| 2278 __ LoadP(r3, MemOperand(sp, kPointerSize)); // value | 2312 __ LoadP(r3, MemOperand(sp, kPointerSize)); // value |
| 2279 __ LoadP(scratch2, MemOperand(sp, 0)); // this | 2313 __ LoadP(scratch2, MemOperand(sp, 0)); // this |
| 2280 __ StoreP(scratch2, MemOperand(sp, kPointerSize)); // this | 2314 __ StoreP(scratch2, MemOperand(sp, kPointerSize)); // this |
| 2281 __ StoreP(scratch, MemOperand(sp, 0)); // home_object | 2315 __ StoreP(scratch, MemOperand(sp, 0)); // home_object |
| 2282 // stack: this, home_object; r3: value | 2316 // stack: this, home_object; r3: value |
| 2283 EmitNamedSuperPropertyStore(prop); | 2317 EmitNamedSuperPropertyStore(prop); |
| 2284 break; | 2318 break; |
| 2285 } | 2319 } |
| 2286 case KEYED_SUPER_PROPERTY: { | 2320 case KEYED_SUPER_PROPERTY: { |
| 2287 __ Push(r3); | 2321 PushOperand(r3); |
| 2288 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 2322 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
| 2289 VisitForStackValue( | 2323 VisitForStackValue( |
| 2290 prop->obj()->AsSuperPropertyReference()->home_object()); | 2324 prop->obj()->AsSuperPropertyReference()->home_object()); |
| 2291 VisitForAccumulatorValue(prop->key()); | 2325 VisitForAccumulatorValue(prop->key()); |
| 2292 Register scratch = r5; | 2326 Register scratch = r5; |
| 2293 Register scratch2 = r6; | 2327 Register scratch2 = r6; |
| 2294 __ LoadP(scratch2, MemOperand(sp, 2 * kPointerSize)); // value | 2328 __ LoadP(scratch2, MemOperand(sp, 2 * kPointerSize)); // value |
| 2295 // stack: value, this, home_object; r3: key, r6: value | 2329 // stack: value, this, home_object; r3: key, r6: value |
| 2296 __ LoadP(scratch, MemOperand(sp, kPointerSize)); // this | 2330 __ LoadP(scratch, MemOperand(sp, kPointerSize)); // this |
| 2297 __ StoreP(scratch, MemOperand(sp, 2 * kPointerSize)); | 2331 __ StoreP(scratch, MemOperand(sp, 2 * kPointerSize)); |
| 2298 __ LoadP(scratch, MemOperand(sp, 0)); // home_object | 2332 __ LoadP(scratch, MemOperand(sp, 0)); // home_object |
| 2299 __ StoreP(scratch, MemOperand(sp, kPointerSize)); | 2333 __ StoreP(scratch, MemOperand(sp, kPointerSize)); |
| 2300 __ StoreP(r3, MemOperand(sp, 0)); | 2334 __ StoreP(r3, MemOperand(sp, 0)); |
| 2301 __ Move(r3, scratch2); | 2335 __ Move(r3, scratch2); |
| 2302 // stack: this, home_object, key; r3: value. | 2336 // stack: this, home_object, key; r3: value. |
| 2303 EmitKeyedSuperPropertyStore(prop); | 2337 EmitKeyedSuperPropertyStore(prop); |
| 2304 break; | 2338 break; |
| 2305 } | 2339 } |
| 2306 case KEYED_PROPERTY: { | 2340 case KEYED_PROPERTY: { |
| 2307 __ push(r3); // Preserve value. | 2341 PushOperand(r3); // Preserve value. |
| 2308 VisitForStackValue(prop->obj()); | 2342 VisitForStackValue(prop->obj()); |
| 2309 VisitForAccumulatorValue(prop->key()); | 2343 VisitForAccumulatorValue(prop->key()); |
| 2310 __ Move(StoreDescriptor::NameRegister(), r3); | 2344 __ Move(StoreDescriptor::NameRegister(), r3); |
| 2311 __ Pop(StoreDescriptor::ValueRegister(), | 2345 PopOperands(StoreDescriptor::ValueRegister(), |
| 2312 StoreDescriptor::ReceiverRegister()); | 2346 StoreDescriptor::ReceiverRegister()); |
| 2313 EmitLoadStoreICSlot(slot); | 2347 EmitLoadStoreICSlot(slot); |
| 2314 Handle<Code> ic = | 2348 Handle<Code> ic = |
| 2315 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2349 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 2316 CallIC(ic); | 2350 CallIC(ic); |
| 2317 break; | 2351 break; |
| 2318 } | 2352 } |
| 2319 } | 2353 } |
| 2320 context()->Plug(r3); | 2354 context()->Plug(r3); |
| 2321 } | 2355 } |
| 2322 | 2356 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2440 | 2474 |
| 2441 | 2475 |
| 2442 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2476 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
| 2443 // Assignment to a property, using a named store IC. | 2477 // Assignment to a property, using a named store IC. |
| 2444 Property* prop = expr->target()->AsProperty(); | 2478 Property* prop = expr->target()->AsProperty(); |
| 2445 DCHECK(prop != NULL); | 2479 DCHECK(prop != NULL); |
| 2446 DCHECK(prop->key()->IsLiteral()); | 2480 DCHECK(prop->key()->IsLiteral()); |
| 2447 | 2481 |
| 2448 __ mov(StoreDescriptor::NameRegister(), | 2482 __ mov(StoreDescriptor::NameRegister(), |
| 2449 Operand(prop->key()->AsLiteral()->value())); | 2483 Operand(prop->key()->AsLiteral()->value())); |
| 2450 __ pop(StoreDescriptor::ReceiverRegister()); | 2484 PopOperand(StoreDescriptor::ReceiverRegister()); |
| 2451 EmitLoadStoreICSlot(expr->AssignmentSlot()); | 2485 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2452 CallStoreIC(); | 2486 CallStoreIC(); |
| 2453 | 2487 |
| 2454 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2488 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2455 context()->Plug(r3); | 2489 context()->Plug(r3); |
| 2456 } | 2490 } |
| 2457 | 2491 |
| 2458 | 2492 |
| 2459 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { | 2493 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { |
| 2460 // Assignment to named property of super. | 2494 // Assignment to named property of super. |
| 2461 // r3 : value | 2495 // r3 : value |
| 2462 // stack : receiver ('this'), home_object | 2496 // stack : receiver ('this'), home_object |
| 2463 DCHECK(prop != NULL); | 2497 DCHECK(prop != NULL); |
| 2464 Literal* key = prop->key()->AsLiteral(); | 2498 Literal* key = prop->key()->AsLiteral(); |
| 2465 DCHECK(key != NULL); | 2499 DCHECK(key != NULL); |
| 2466 | 2500 |
| 2467 __ Push(key->value()); | 2501 PushOperand(key->value()); |
| 2468 __ Push(r3); | 2502 PushOperand(r3); |
| 2469 __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict | 2503 CallRuntimeWithOperands((is_strict(language_mode()) |
| 2470 : Runtime::kStoreToSuper_Sloppy)); | 2504 ? Runtime::kStoreToSuper_Strict |
| 2505 : Runtime::kStoreToSuper_Sloppy)); |
| 2471 } | 2506 } |
| 2472 | 2507 |
| 2473 | 2508 |
| 2474 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { | 2509 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { |
| 2475 // Assignment to named property of super. | 2510 // Assignment to named property of super. |
| 2476 // r3 : value | 2511 // r3 : value |
| 2477 // stack : receiver ('this'), home_object, key | 2512 // stack : receiver ('this'), home_object, key |
| 2478 DCHECK(prop != NULL); | 2513 DCHECK(prop != NULL); |
| 2479 | 2514 |
| 2480 __ Push(r3); | 2515 PushOperand(r3); |
| 2481 __ CallRuntime((is_strict(language_mode()) | 2516 CallRuntimeWithOperands((is_strict(language_mode()) |
| 2482 ? Runtime::kStoreKeyedToSuper_Strict | 2517 ? Runtime::kStoreKeyedToSuper_Strict |
| 2483 : Runtime::kStoreKeyedToSuper_Sloppy)); | 2518 : Runtime::kStoreKeyedToSuper_Sloppy)); |
| 2484 } | 2519 } |
| 2485 | 2520 |
| 2486 | 2521 |
| 2487 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2522 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
| 2488 // Assignment to a property, using a keyed store IC. | 2523 // Assignment to a property, using a keyed store IC. |
| 2489 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); | 2524 PopOperands(StoreDescriptor::ReceiverRegister(), |
| 2525 StoreDescriptor::NameRegister()); |
| 2490 DCHECK(StoreDescriptor::ValueRegister().is(r3)); | 2526 DCHECK(StoreDescriptor::ValueRegister().is(r3)); |
| 2491 | 2527 |
| 2492 Handle<Code> ic = | 2528 Handle<Code> ic = |
| 2493 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2529 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 2494 EmitLoadStoreICSlot(expr->AssignmentSlot()); | 2530 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2495 CallIC(ic); | 2531 CallIC(ic); |
| 2496 | 2532 |
| 2497 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2533 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2498 context()->Plug(r3); | 2534 context()->Plug(r3); |
| 2499 } | 2535 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2514 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); | 2550 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); |
| 2515 VisitForStackValue( | 2551 VisitForStackValue( |
| 2516 expr->obj()->AsSuperPropertyReference()->home_object()); | 2552 expr->obj()->AsSuperPropertyReference()->home_object()); |
| 2517 EmitNamedSuperPropertyLoad(expr); | 2553 EmitNamedSuperPropertyLoad(expr); |
| 2518 } | 2554 } |
| 2519 } else { | 2555 } else { |
| 2520 if (!expr->IsSuperAccess()) { | 2556 if (!expr->IsSuperAccess()) { |
| 2521 VisitForStackValue(expr->obj()); | 2557 VisitForStackValue(expr->obj()); |
| 2522 VisitForAccumulatorValue(expr->key()); | 2558 VisitForAccumulatorValue(expr->key()); |
| 2523 __ Move(LoadDescriptor::NameRegister(), r3); | 2559 __ Move(LoadDescriptor::NameRegister(), r3); |
| 2524 __ pop(LoadDescriptor::ReceiverRegister()); | 2560 PopOperand(LoadDescriptor::ReceiverRegister()); |
| 2525 EmitKeyedPropertyLoad(expr); | 2561 EmitKeyedPropertyLoad(expr); |
| 2526 } else { | 2562 } else { |
| 2527 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); | 2563 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); |
| 2528 VisitForStackValue( | 2564 VisitForStackValue( |
| 2529 expr->obj()->AsSuperPropertyReference()->home_object()); | 2565 expr->obj()->AsSuperPropertyReference()->home_object()); |
| 2530 VisitForStackValue(expr->key()); | 2566 VisitForStackValue(expr->key()); |
| 2531 EmitKeyedSuperPropertyLoad(expr); | 2567 EmitKeyedSuperPropertyLoad(expr); |
| 2532 } | 2568 } |
| 2533 } | 2569 } |
| 2534 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2570 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2550 ConvertReceiverMode convert_mode; | 2586 ConvertReceiverMode convert_mode; |
| 2551 if (callee->IsVariableProxy()) { | 2587 if (callee->IsVariableProxy()) { |
| 2552 { | 2588 { |
| 2553 StackValueContext context(this); | 2589 StackValueContext context(this); |
| 2554 EmitVariableLoad(callee->AsVariableProxy()); | 2590 EmitVariableLoad(callee->AsVariableProxy()); |
| 2555 PrepareForBailout(callee, NO_REGISTERS); | 2591 PrepareForBailout(callee, NO_REGISTERS); |
| 2556 } | 2592 } |
| 2557 // Push undefined as receiver. This is patched in the method prologue if it | 2593 // Push undefined as receiver. This is patched in the method prologue if it |
| 2558 // is a sloppy mode method. | 2594 // is a sloppy mode method. |
| 2559 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); | 2595 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); |
| 2560 __ push(r0); | 2596 PushOperand(r0); |
| 2561 convert_mode = ConvertReceiverMode::kNullOrUndefined; | 2597 convert_mode = ConvertReceiverMode::kNullOrUndefined; |
| 2562 } else { | 2598 } else { |
| 2563 // Load the function from the receiver. | 2599 // Load the function from the receiver. |
| 2564 DCHECK(callee->IsProperty()); | 2600 DCHECK(callee->IsProperty()); |
| 2565 DCHECK(!callee->AsProperty()->IsSuperAccess()); | 2601 DCHECK(!callee->AsProperty()->IsSuperAccess()); |
| 2566 __ LoadP(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); | 2602 __ LoadP(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); |
| 2567 EmitNamedPropertyLoad(callee->AsProperty()); | 2603 EmitNamedPropertyLoad(callee->AsProperty()); |
| 2568 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2604 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
| 2569 // Push the target function under the receiver. | 2605 // Push the target function under the receiver. |
| 2570 __ LoadP(r0, MemOperand(sp, 0)); | 2606 __ LoadP(r0, MemOperand(sp, 0)); |
| 2571 __ push(r0); | 2607 PushOperand(r0); |
| 2572 __ StoreP(r3, MemOperand(sp, kPointerSize)); | 2608 __ StoreP(r3, MemOperand(sp, kPointerSize)); |
| 2573 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; | 2609 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; |
| 2574 } | 2610 } |
| 2575 | 2611 |
| 2576 EmitCall(expr, convert_mode); | 2612 EmitCall(expr, convert_mode); |
| 2577 } | 2613 } |
| 2578 | 2614 |
| 2579 | 2615 |
| 2580 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | 2616 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { |
| 2581 Expression* callee = expr->expression(); | 2617 Expression* callee = expr->expression(); |
| 2582 DCHECK(callee->IsProperty()); | 2618 DCHECK(callee->IsProperty()); |
| 2583 Property* prop = callee->AsProperty(); | 2619 Property* prop = callee->AsProperty(); |
| 2584 DCHECK(prop->IsSuperAccess()); | 2620 DCHECK(prop->IsSuperAccess()); |
| 2585 SetExpressionPosition(prop); | 2621 SetExpressionPosition(prop); |
| 2586 | 2622 |
| 2587 Literal* key = prop->key()->AsLiteral(); | 2623 Literal* key = prop->key()->AsLiteral(); |
| 2588 DCHECK(!key->value()->IsSmi()); | 2624 DCHECK(!key->value()->IsSmi()); |
| 2589 // Load the function from the receiver. | 2625 // Load the function from the receiver. |
| 2590 const Register scratch = r4; | 2626 const Register scratch = r4; |
| 2591 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | 2627 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); |
| 2592 VisitForAccumulatorValue(super_ref->home_object()); | 2628 VisitForAccumulatorValue(super_ref->home_object()); |
| 2593 __ mr(scratch, r3); | 2629 __ mr(scratch, r3); |
| 2594 VisitForAccumulatorValue(super_ref->this_var()); | 2630 VisitForAccumulatorValue(super_ref->this_var()); |
| 2595 __ Push(scratch, r3, r3, scratch); | 2631 PushOperands(scratch, r3, r3, scratch); |
| 2596 __ Push(key->value()); | 2632 PushOperand(key->value()); |
| 2597 | 2633 |
| 2598 // Stack here: | 2634 // Stack here: |
| 2599 // - home_object | 2635 // - home_object |
| 2600 // - this (receiver) | 2636 // - this (receiver) |
| 2601 // - this (receiver) <-- LoadFromSuper will pop here and below. | 2637 // - this (receiver) <-- LoadFromSuper will pop here and below. |
| 2602 // - home_object | 2638 // - home_object |
| 2603 // - key | 2639 // - key |
| 2604 __ CallRuntime(Runtime::kLoadFromSuper); | 2640 CallRuntimeWithOperands(Runtime::kLoadFromSuper); |
| 2605 | 2641 |
| 2606 // Replace home_object with target function. | 2642 // Replace home_object with target function. |
| 2607 __ StoreP(r3, MemOperand(sp, kPointerSize)); | 2643 __ StoreP(r3, MemOperand(sp, kPointerSize)); |
| 2608 | 2644 |
| 2609 // Stack here: | 2645 // Stack here: |
| 2610 // - target function | 2646 // - target function |
| 2611 // - this (receiver) | 2647 // - this (receiver) |
| 2612 EmitCall(expr); | 2648 EmitCall(expr); |
| 2613 } | 2649 } |
| 2614 | 2650 |
| 2615 | 2651 |
| 2616 // Code common for calls using the IC. | 2652 // Code common for calls using the IC. |
| 2617 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, Expression* key) { | 2653 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, Expression* key) { |
| 2618 // Load the key. | 2654 // Load the key. |
| 2619 VisitForAccumulatorValue(key); | 2655 VisitForAccumulatorValue(key); |
| 2620 | 2656 |
| 2621 Expression* callee = expr->expression(); | 2657 Expression* callee = expr->expression(); |
| 2622 | 2658 |
| 2623 // Load the function from the receiver. | 2659 // Load the function from the receiver. |
| 2624 DCHECK(callee->IsProperty()); | 2660 DCHECK(callee->IsProperty()); |
| 2625 __ LoadP(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); | 2661 __ LoadP(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); |
| 2626 __ Move(LoadDescriptor::NameRegister(), r3); | 2662 __ Move(LoadDescriptor::NameRegister(), r3); |
| 2627 EmitKeyedPropertyLoad(callee->AsProperty()); | 2663 EmitKeyedPropertyLoad(callee->AsProperty()); |
| 2628 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2664 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
| 2629 | 2665 |
| 2630 // Push the target function under the receiver. | 2666 // Push the target function under the receiver. |
| 2631 __ LoadP(ip, MemOperand(sp, 0)); | 2667 __ LoadP(ip, MemOperand(sp, 0)); |
| 2632 __ push(ip); | 2668 PushOperand(ip); |
| 2633 __ StoreP(r3, MemOperand(sp, kPointerSize)); | 2669 __ StoreP(r3, MemOperand(sp, kPointerSize)); |
| 2634 | 2670 |
| 2635 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); | 2671 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); |
| 2636 } | 2672 } |
| 2637 | 2673 |
| 2638 | 2674 |
| 2639 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | 2675 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { |
| 2640 Expression* callee = expr->expression(); | 2676 Expression* callee = expr->expression(); |
| 2641 DCHECK(callee->IsProperty()); | 2677 DCHECK(callee->IsProperty()); |
| 2642 Property* prop = callee->AsProperty(); | 2678 Property* prop = callee->AsProperty(); |
| 2643 DCHECK(prop->IsSuperAccess()); | 2679 DCHECK(prop->IsSuperAccess()); |
| 2644 | 2680 |
| 2645 SetExpressionPosition(prop); | 2681 SetExpressionPosition(prop); |
| 2646 // Load the function from the receiver. | 2682 // Load the function from the receiver. |
| 2647 const Register scratch = r4; | 2683 const Register scratch = r4; |
| 2648 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | 2684 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); |
| 2649 VisitForAccumulatorValue(super_ref->home_object()); | 2685 VisitForAccumulatorValue(super_ref->home_object()); |
| 2650 __ mr(scratch, r3); | 2686 __ mr(scratch, r3); |
| 2651 VisitForAccumulatorValue(super_ref->this_var()); | 2687 VisitForAccumulatorValue(super_ref->this_var()); |
| 2652 __ Push(scratch, r3, r3, scratch); | 2688 PushOperands(scratch, r3, r3, scratch); |
| 2653 VisitForStackValue(prop->key()); | 2689 VisitForStackValue(prop->key()); |
| 2654 | 2690 |
| 2655 // Stack here: | 2691 // Stack here: |
| 2656 // - home_object | 2692 // - home_object |
| 2657 // - this (receiver) | 2693 // - this (receiver) |
| 2658 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. | 2694 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. |
| 2659 // - home_object | 2695 // - home_object |
| 2660 // - key | 2696 // - key |
| 2661 __ CallRuntime(Runtime::kLoadKeyedFromSuper); | 2697 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); |
| 2662 | 2698 |
| 2663 // Replace home_object with target function. | 2699 // Replace home_object with target function. |
| 2664 __ StoreP(r3, MemOperand(sp, kPointerSize)); | 2700 __ StoreP(r3, MemOperand(sp, kPointerSize)); |
| 2665 | 2701 |
| 2666 // Stack here: | 2702 // Stack here: |
| 2667 // - target function | 2703 // - target function |
| 2668 // - this (receiver) | 2704 // - this (receiver) |
| 2669 EmitCall(expr); | 2705 EmitCall(expr); |
| 2670 } | 2706 } |
| 2671 | 2707 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2689 EmitProfilingCounterHandlingForReturnSequence(true); | 2725 EmitProfilingCounterHandlingForReturnSequence(true); |
| 2690 } | 2726 } |
| 2691 Handle<Code> ic = | 2727 Handle<Code> ic = |
| 2692 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) | 2728 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) |
| 2693 .code(); | 2729 .code(); |
| 2694 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackICSlot())); | 2730 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackICSlot())); |
| 2695 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); | 2731 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); |
| 2696 // Don't assign a type feedback id to the IC, since type feedback is provided | 2732 // Don't assign a type feedback id to the IC, since type feedback is provided |
| 2697 // by the vector above. | 2733 // by the vector above. |
| 2698 CallIC(ic); | 2734 CallIC(ic); |
| 2735 OperandStackDepthDecrement(arg_count + 1); |
| 2699 | 2736 |
| 2700 RecordJSReturnSite(expr); | 2737 RecordJSReturnSite(expr); |
| 2701 // Restore context register. | 2738 // Restore context register. |
| 2702 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2739 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2703 context()->DropAndPlug(1, r3); | 2740 context()->DropAndPlug(1, r3); |
| 2704 } | 2741 } |
| 2705 | 2742 |
| 2706 | 2743 |
| 2707 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { | 2744 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { |
| 2708 // r7: copy of the first argument or undefined if it doesn't exist. | 2745 // r7: copy of the first argument or undefined if it doesn't exist. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2735 SetExpressionPosition(callee); | 2772 SetExpressionPosition(callee); |
| 2736 // Generate code for loading from variables potentially shadowed by | 2773 // Generate code for loading from variables potentially shadowed by |
| 2737 // eval-introduced variables. | 2774 // eval-introduced variables. |
| 2738 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); | 2775 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); |
| 2739 | 2776 |
| 2740 __ bind(&slow); | 2777 __ bind(&slow); |
| 2741 // Call the runtime to find the function to call (returned in r3) and | 2778 // Call the runtime to find the function to call (returned in r3) and |
| 2742 // the object holding it (returned in r4). | 2779 // the object holding it (returned in r4). |
| 2743 __ Push(callee->name()); | 2780 __ Push(callee->name()); |
| 2744 __ CallRuntime(Runtime::kLoadLookupSlotForCall); | 2781 __ CallRuntime(Runtime::kLoadLookupSlotForCall); |
| 2745 __ Push(r3, r4); // Function, receiver. | 2782 PushOperands(r3, r4); // Function, receiver. |
| 2746 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); | 2783 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); |
| 2747 | 2784 |
| 2748 // If fast case code has been generated, emit code to push the function | 2785 // If fast case code has been generated, emit code to push the function |
| 2749 // and receiver and have the slow path jump around this code. | 2786 // and receiver and have the slow path jump around this code. |
| 2750 if (done.is_linked()) { | 2787 if (done.is_linked()) { |
| 2751 Label call; | 2788 Label call; |
| 2752 __ b(&call); | 2789 __ b(&call); |
| 2753 __ bind(&done); | 2790 __ bind(&done); |
| 2754 // Push function. | 2791 // Push function. |
| 2755 __ push(r3); | 2792 __ push(r3); |
| 2756 // Pass undefined as the receiver, which is the WithBaseObject of a | 2793 // Pass undefined as the receiver, which is the WithBaseObject of a |
| 2757 // non-object environment record. If the callee is sloppy, it will patch | 2794 // non-object environment record. If the callee is sloppy, it will patch |
| 2758 // it up to be the global receiver. | 2795 // it up to be the global receiver. |
| 2759 __ LoadRoot(r4, Heap::kUndefinedValueRootIndex); | 2796 __ LoadRoot(r4, Heap::kUndefinedValueRootIndex); |
| 2760 __ push(r4); | 2797 __ push(r4); |
| 2761 __ bind(&call); | 2798 __ bind(&call); |
| 2762 } | 2799 } |
| 2763 } else { | 2800 } else { |
| 2764 VisitForStackValue(callee); | 2801 VisitForStackValue(callee); |
| 2765 // refEnv.WithBaseObject() | 2802 // refEnv.WithBaseObject() |
| 2766 __ LoadRoot(r5, Heap::kUndefinedValueRootIndex); | 2803 __ LoadRoot(r5, Heap::kUndefinedValueRootIndex); |
| 2767 __ push(r5); // Reserved receiver slot. | 2804 PushOperand(r5); // Reserved receiver slot. |
| 2768 } | 2805 } |
| 2769 } | 2806 } |
| 2770 | 2807 |
| 2771 | 2808 |
| 2772 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { | 2809 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { |
| 2773 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval | 2810 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval |
| 2774 // to resolve the function we need to call. Then we call the resolved | 2811 // to resolve the function we need to call. Then we call the resolved |
| 2775 // function using the given arguments. | 2812 // function using the given arguments. |
| 2776 ZoneList<Expression*>* args = expr->arguments(); | 2813 ZoneList<Expression*>* args = expr->arguments(); |
| 2777 int arg_count = args->length(); | 2814 int arg_count = args->length(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2794 | 2831 |
| 2795 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); | 2832 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); |
| 2796 | 2833 |
| 2797 // Record source position for debugger. | 2834 // Record source position for debugger. |
| 2798 SetCallPosition(expr); | 2835 SetCallPosition(expr); |
| 2799 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); | 2836 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); |
| 2800 __ mov(r3, Operand(arg_count)); | 2837 __ mov(r3, Operand(arg_count)); |
| 2801 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, | 2838 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, |
| 2802 expr->tail_call_mode()), | 2839 expr->tail_call_mode()), |
| 2803 RelocInfo::CODE_TARGET); | 2840 RelocInfo::CODE_TARGET); |
| 2841 OperandStackDepthDecrement(arg_count + 1); |
| 2804 RecordJSReturnSite(expr); | 2842 RecordJSReturnSite(expr); |
| 2805 // Restore context register. | 2843 // Restore context register. |
| 2806 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2844 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2807 context()->DropAndPlug(1, r3); | 2845 context()->DropAndPlug(1, r3); |
| 2808 } | 2846 } |
| 2809 | 2847 |
| 2810 | 2848 |
| 2811 void FullCodeGenerator::VisitCallNew(CallNew* expr) { | 2849 void FullCodeGenerator::VisitCallNew(CallNew* expr) { |
| 2812 Comment cmnt(masm_, "[ CallNew"); | 2850 Comment cmnt(masm_, "[ CallNew"); |
| 2813 // According to ECMA-262, section 11.2.2, page 44, the function | 2851 // According to ECMA-262, section 11.2.2, page 44, the function |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2834 // Load function and argument count into r4 and r3. | 2872 // Load function and argument count into r4 and r3. |
| 2835 __ mov(r3, Operand(arg_count)); | 2873 __ mov(r3, Operand(arg_count)); |
| 2836 __ LoadP(r4, MemOperand(sp, arg_count * kPointerSize), r0); | 2874 __ LoadP(r4, MemOperand(sp, arg_count * kPointerSize), r0); |
| 2837 | 2875 |
| 2838 // Record call targets in unoptimized code. | 2876 // Record call targets in unoptimized code. |
| 2839 __ EmitLoadTypeFeedbackVector(r5); | 2877 __ EmitLoadTypeFeedbackVector(r5); |
| 2840 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallNewFeedbackSlot())); | 2878 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallNewFeedbackSlot())); |
| 2841 | 2879 |
| 2842 CallConstructStub stub(isolate()); | 2880 CallConstructStub stub(isolate()); |
| 2843 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); | 2881 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); |
| 2882 OperandStackDepthDecrement(arg_count + 1); |
| 2844 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); | 2883 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); |
| 2845 // Restore context register. | 2884 // Restore context register. |
| 2846 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2885 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2847 context()->Plug(r3); | 2886 context()->Plug(r3); |
| 2848 } | 2887 } |
| 2849 | 2888 |
| 2850 | 2889 |
| 2851 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { | 2890 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { |
| 2852 SuperCallReference* super_call_ref = | 2891 SuperCallReference* super_call_ref = |
| 2853 expr->expression()->AsSuperCallReference(); | 2892 expr->expression()->AsSuperCallReference(); |
| 2854 DCHECK_NOT_NULL(super_call_ref); | 2893 DCHECK_NOT_NULL(super_call_ref); |
| 2855 | 2894 |
| 2856 // Push the super constructor target on the stack (may be null, | 2895 // Push the super constructor target on the stack (may be null, |
| 2857 // but the Construct builtin can deal with that properly). | 2896 // but the Construct builtin can deal with that properly). |
| 2858 VisitForAccumulatorValue(super_call_ref->this_function_var()); | 2897 VisitForAccumulatorValue(super_call_ref->this_function_var()); |
| 2859 __ AssertFunction(result_register()); | 2898 __ AssertFunction(result_register()); |
| 2860 __ LoadP(result_register(), | 2899 __ LoadP(result_register(), |
| 2861 FieldMemOperand(result_register(), HeapObject::kMapOffset)); | 2900 FieldMemOperand(result_register(), HeapObject::kMapOffset)); |
| 2862 __ LoadP(result_register(), | 2901 __ LoadP(result_register(), |
| 2863 FieldMemOperand(result_register(), Map::kPrototypeOffset)); | 2902 FieldMemOperand(result_register(), Map::kPrototypeOffset)); |
| 2864 __ Push(result_register()); | 2903 PushOperand(result_register()); |
| 2865 | 2904 |
| 2866 // Push the arguments ("left-to-right") on the stack. | 2905 // Push the arguments ("left-to-right") on the stack. |
| 2867 ZoneList<Expression*>* args = expr->arguments(); | 2906 ZoneList<Expression*>* args = expr->arguments(); |
| 2868 int arg_count = args->length(); | 2907 int arg_count = args->length(); |
| 2869 for (int i = 0; i < arg_count; i++) { | 2908 for (int i = 0; i < arg_count; i++) { |
| 2870 VisitForStackValue(args->at(i)); | 2909 VisitForStackValue(args->at(i)); |
| 2871 } | 2910 } |
| 2872 | 2911 |
| 2873 // Call the construct call builtin that handles allocation and | 2912 // Call the construct call builtin that handles allocation and |
| 2874 // constructor invocation. | 2913 // constructor invocation. |
| 2875 SetConstructCallPosition(expr); | 2914 SetConstructCallPosition(expr); |
| 2876 | 2915 |
| 2877 // Load new target into r6. | 2916 // Load new target into r6. |
| 2878 VisitForAccumulatorValue(super_call_ref->new_target_var()); | 2917 VisitForAccumulatorValue(super_call_ref->new_target_var()); |
| 2879 __ mr(r6, result_register()); | 2918 __ mr(r6, result_register()); |
| 2880 | 2919 |
| 2881 // Load function and argument count into r1 and r0. | 2920 // Load function and argument count into r1 and r0. |
| 2882 __ mov(r3, Operand(arg_count)); | 2921 __ mov(r3, Operand(arg_count)); |
| 2883 __ LoadP(r4, MemOperand(sp, arg_count * kPointerSize)); | 2922 __ LoadP(r4, MemOperand(sp, arg_count * kPointerSize)); |
| 2884 | 2923 |
| 2885 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 2924 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
| 2925 OperandStackDepthDecrement(arg_count + 1); |
| 2886 | 2926 |
| 2887 RecordJSReturnSite(expr); | 2927 RecordJSReturnSite(expr); |
| 2888 | 2928 |
| 2889 // Restore context register. | 2929 // Restore context register. |
| 2890 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2930 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2891 context()->Plug(r3); | 2931 context()->Plug(r3); |
| 2892 } | 2932 } |
| 2893 | 2933 |
| 2894 | 2934 |
| 2895 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 2935 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3097 ZoneList<Expression*>* args = expr->arguments(); | 3137 ZoneList<Expression*>* args = expr->arguments(); |
| 3098 DCHECK_EQ(3, args->length()); | 3138 DCHECK_EQ(3, args->length()); |
| 3099 | 3139 |
| 3100 Register string = r3; | 3140 Register string = r3; |
| 3101 Register index = r4; | 3141 Register index = r4; |
| 3102 Register value = r5; | 3142 Register value = r5; |
| 3103 | 3143 |
| 3104 VisitForStackValue(args->at(0)); // index | 3144 VisitForStackValue(args->at(0)); // index |
| 3105 VisitForStackValue(args->at(1)); // value | 3145 VisitForStackValue(args->at(1)); // value |
| 3106 VisitForAccumulatorValue(args->at(2)); // string | 3146 VisitForAccumulatorValue(args->at(2)); // string |
| 3107 __ Pop(index, value); | 3147 PopOperands(index, value); |
| 3108 | 3148 |
| 3109 if (FLAG_debug_code) { | 3149 if (FLAG_debug_code) { |
| 3110 __ TestIfSmi(value, r0); | 3150 __ TestIfSmi(value, r0); |
| 3111 __ Check(eq, kNonSmiValue, cr0); | 3151 __ Check(eq, kNonSmiValue, cr0); |
| 3112 __ TestIfSmi(index, r0); | 3152 __ TestIfSmi(index, r0); |
| 3113 __ Check(eq, kNonSmiIndex, cr0); | 3153 __ Check(eq, kNonSmiIndex, cr0); |
| 3114 __ SmiUntag(index, index); | 3154 __ SmiUntag(index, index); |
| 3115 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; | 3155 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; |
| 3116 __ EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type); | 3156 __ EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type); |
| 3117 __ SmiTag(index, index); | 3157 __ SmiTag(index, index); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3129 ZoneList<Expression*>* args = expr->arguments(); | 3169 ZoneList<Expression*>* args = expr->arguments(); |
| 3130 DCHECK_EQ(3, args->length()); | 3170 DCHECK_EQ(3, args->length()); |
| 3131 | 3171 |
| 3132 Register string = r3; | 3172 Register string = r3; |
| 3133 Register index = r4; | 3173 Register index = r4; |
| 3134 Register value = r5; | 3174 Register value = r5; |
| 3135 | 3175 |
| 3136 VisitForStackValue(args->at(0)); // index | 3176 VisitForStackValue(args->at(0)); // index |
| 3137 VisitForStackValue(args->at(1)); // value | 3177 VisitForStackValue(args->at(1)); // value |
| 3138 VisitForAccumulatorValue(args->at(2)); // string | 3178 VisitForAccumulatorValue(args->at(2)); // string |
| 3139 __ Pop(index, value); | 3179 PopOperands(index, value); |
| 3140 | 3180 |
| 3141 if (FLAG_debug_code) { | 3181 if (FLAG_debug_code) { |
| 3142 __ TestIfSmi(value, r0); | 3182 __ TestIfSmi(value, r0); |
| 3143 __ Check(eq, kNonSmiValue, cr0); | 3183 __ Check(eq, kNonSmiValue, cr0); |
| 3144 __ TestIfSmi(index, r0); | 3184 __ TestIfSmi(index, r0); |
| 3145 __ Check(eq, kNonSmiIndex, cr0); | 3185 __ Check(eq, kNonSmiIndex, cr0); |
| 3146 __ SmiUntag(index, index); | 3186 __ SmiUntag(index, index); |
| 3147 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; | 3187 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; |
| 3148 __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type); | 3188 __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type); |
| 3149 __ SmiTag(index, index); | 3189 __ SmiTag(index, index); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3195 void FullCodeGenerator::EmitStringCharCodeAt(CallRuntime* expr) { | 3235 void FullCodeGenerator::EmitStringCharCodeAt(CallRuntime* expr) { |
| 3196 ZoneList<Expression*>* args = expr->arguments(); | 3236 ZoneList<Expression*>* args = expr->arguments(); |
| 3197 DCHECK(args->length() == 2); | 3237 DCHECK(args->length() == 2); |
| 3198 VisitForStackValue(args->at(0)); | 3238 VisitForStackValue(args->at(0)); |
| 3199 VisitForAccumulatorValue(args->at(1)); | 3239 VisitForAccumulatorValue(args->at(1)); |
| 3200 | 3240 |
| 3201 Register object = r4; | 3241 Register object = r4; |
| 3202 Register index = r3; | 3242 Register index = r3; |
| 3203 Register result = r6; | 3243 Register result = r6; |
| 3204 | 3244 |
| 3205 __ pop(object); | 3245 PopOperand(object); |
| 3206 | 3246 |
| 3207 Label need_conversion; | 3247 Label need_conversion; |
| 3208 Label index_out_of_range; | 3248 Label index_out_of_range; |
| 3209 Label done; | 3249 Label done; |
| 3210 StringCharCodeAtGenerator generator(object, index, result, &need_conversion, | 3250 StringCharCodeAtGenerator generator(object, index, result, &need_conversion, |
| 3211 &need_conversion, &index_out_of_range, | 3251 &need_conversion, &index_out_of_range, |
| 3212 STRING_INDEX_IS_NUMBER); | 3252 STRING_INDEX_IS_NUMBER); |
| 3213 generator.GenerateFast(masm_); | 3253 generator.GenerateFast(masm_); |
| 3214 __ b(&done); | 3254 __ b(&done); |
| 3215 | 3255 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 3237 ZoneList<Expression*>* args = expr->arguments(); | 3277 ZoneList<Expression*>* args = expr->arguments(); |
| 3238 DCHECK(args->length() == 2); | 3278 DCHECK(args->length() == 2); |
| 3239 VisitForStackValue(args->at(0)); | 3279 VisitForStackValue(args->at(0)); |
| 3240 VisitForAccumulatorValue(args->at(1)); | 3280 VisitForAccumulatorValue(args->at(1)); |
| 3241 | 3281 |
| 3242 Register object = r4; | 3282 Register object = r4; |
| 3243 Register index = r3; | 3283 Register index = r3; |
| 3244 Register scratch = r6; | 3284 Register scratch = r6; |
| 3245 Register result = r3; | 3285 Register result = r3; |
| 3246 | 3286 |
| 3247 __ pop(object); | 3287 PopOperand(object); |
| 3248 | 3288 |
| 3249 Label need_conversion; | 3289 Label need_conversion; |
| 3250 Label index_out_of_range; | 3290 Label index_out_of_range; |
| 3251 Label done; | 3291 Label done; |
| 3252 StringCharAtGenerator generator(object, index, scratch, result, | 3292 StringCharAtGenerator generator(object, index, scratch, result, |
| 3253 &need_conversion, &need_conversion, | 3293 &need_conversion, &need_conversion, |
| 3254 &index_out_of_range, STRING_INDEX_IS_NUMBER); | 3294 &index_out_of_range, STRING_INDEX_IS_NUMBER); |
| 3255 generator.GenerateFast(masm_); | 3295 generator.GenerateFast(masm_); |
| 3256 __ b(&done); | 3296 __ b(&done); |
| 3257 | 3297 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3282 for (Expression* const arg : *args) { | 3322 for (Expression* const arg : *args) { |
| 3283 VisitForStackValue(arg); | 3323 VisitForStackValue(arg); |
| 3284 } | 3324 } |
| 3285 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 3325 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
| 3286 // Move target to r4. | 3326 // Move target to r4. |
| 3287 int const argc = args->length() - 2; | 3327 int const argc = args->length() - 2; |
| 3288 __ LoadP(r4, MemOperand(sp, (argc + 1) * kPointerSize)); | 3328 __ LoadP(r4, MemOperand(sp, (argc + 1) * kPointerSize)); |
| 3289 // Call the target. | 3329 // Call the target. |
| 3290 __ mov(r3, Operand(argc)); | 3330 __ mov(r3, Operand(argc)); |
| 3291 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 3331 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 3332 OperandStackDepthDecrement(argc + 1); |
| 3292 // Restore context register. | 3333 // Restore context register. |
| 3293 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3334 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 3294 // Discard the function left on TOS. | 3335 // Discard the function left on TOS. |
| 3295 context()->DropAndPlug(1, r3); | 3336 context()->DropAndPlug(1, r3); |
| 3296 } | 3337 } |
| 3297 | 3338 |
| 3298 | 3339 |
| 3299 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { | 3340 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { |
| 3300 ZoneList<Expression*>* args = expr->arguments(); | 3341 ZoneList<Expression*>* args = expr->arguments(); |
| 3301 VisitForAccumulatorValue(args->at(0)); | 3342 VisitForAccumulatorValue(args->at(0)); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3368 __ LoadRoot(r7, Heap::kEmptyFixedArrayRootIndex); | 3409 __ LoadRoot(r7, Heap::kEmptyFixedArrayRootIndex); |
| 3369 __ StoreP(r4, FieldMemOperand(r3, HeapObject::kMapOffset), r0); | 3410 __ StoreP(r4, FieldMemOperand(r3, HeapObject::kMapOffset), r0); |
| 3370 __ StoreP(r7, FieldMemOperand(r3, JSObject::kPropertiesOffset), r0); | 3411 __ StoreP(r7, FieldMemOperand(r3, JSObject::kPropertiesOffset), r0); |
| 3371 __ StoreP(r7, FieldMemOperand(r3, JSObject::kElementsOffset), r0); | 3412 __ StoreP(r7, FieldMemOperand(r3, JSObject::kElementsOffset), r0); |
| 3372 __ StoreP(r5, FieldMemOperand(r3, JSIteratorResult::kValueOffset), r0); | 3413 __ StoreP(r5, FieldMemOperand(r3, JSIteratorResult::kValueOffset), r0); |
| 3373 __ StoreP(r6, FieldMemOperand(r3, JSIteratorResult::kDoneOffset), r0); | 3414 __ StoreP(r6, FieldMemOperand(r3, JSIteratorResult::kDoneOffset), r0); |
| 3374 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); | 3415 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); |
| 3375 __ b(&done); | 3416 __ b(&done); |
| 3376 | 3417 |
| 3377 __ bind(&runtime); | 3418 __ bind(&runtime); |
| 3378 __ CallRuntime(Runtime::kCreateIterResultObject); | 3419 CallRuntimeWithOperands(Runtime::kCreateIterResultObject); |
| 3379 | 3420 |
| 3380 __ bind(&done); | 3421 __ bind(&done); |
| 3381 context()->Plug(r3); | 3422 context()->Plug(r3); |
| 3382 } | 3423 } |
| 3383 | 3424 |
| 3384 | 3425 |
| 3385 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { | 3426 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
| 3386 // Push undefined as the receiver. | 3427 // Push undefined as the receiver. |
| 3387 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex); | 3428 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex); |
| 3388 __ push(r3); | 3429 PushOperand(r3); |
| 3389 | 3430 |
| 3390 __ LoadNativeContextSlot(expr->context_index(), r3); | 3431 __ LoadNativeContextSlot(expr->context_index(), r3); |
| 3391 } | 3432 } |
| 3392 | 3433 |
| 3393 | 3434 |
| 3394 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 3435 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
| 3395 ZoneList<Expression*>* args = expr->arguments(); | 3436 ZoneList<Expression*>* args = expr->arguments(); |
| 3396 int arg_count = args->length(); | 3437 int arg_count = args->length(); |
| 3397 | 3438 |
| 3398 SetCallPosition(expr); | 3439 SetCallPosition(expr); |
| 3399 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); | 3440 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); |
| 3400 __ mov(r3, Operand(arg_count)); | 3441 __ mov(r3, Operand(arg_count)); |
| 3401 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), | 3442 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), |
| 3402 RelocInfo::CODE_TARGET); | 3443 RelocInfo::CODE_TARGET); |
| 3444 OperandStackDepthDecrement(arg_count + 1); |
| 3403 } | 3445 } |
| 3404 | 3446 |
| 3405 | 3447 |
| 3406 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 3448 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
| 3407 ZoneList<Expression*>* args = expr->arguments(); | 3449 ZoneList<Expression*>* args = expr->arguments(); |
| 3408 int arg_count = args->length(); | 3450 int arg_count = args->length(); |
| 3409 | 3451 |
| 3410 if (expr->is_jsruntime()) { | 3452 if (expr->is_jsruntime()) { |
| 3411 Comment cmnt(masm_, "[ CallRuntime"); | 3453 Comment cmnt(masm_, "[ CallRuntime"); |
| 3412 EmitLoadJSRuntimeFunction(expr); | 3454 EmitLoadJSRuntimeFunction(expr); |
| 3413 | 3455 |
| 3414 // Push the target function under the receiver. | 3456 // Push the target function under the receiver. |
| 3415 __ LoadP(ip, MemOperand(sp, 0)); | 3457 __ LoadP(ip, MemOperand(sp, 0)); |
| 3416 __ push(ip); | 3458 PushOperand(ip); |
| 3417 __ StoreP(r3, MemOperand(sp, kPointerSize)); | 3459 __ StoreP(r3, MemOperand(sp, kPointerSize)); |
| 3418 | 3460 |
| 3419 // Push the arguments ("left-to-right"). | 3461 // Push the arguments ("left-to-right"). |
| 3420 for (int i = 0; i < arg_count; i++) { | 3462 for (int i = 0; i < arg_count; i++) { |
| 3421 VisitForStackValue(args->at(i)); | 3463 VisitForStackValue(args->at(i)); |
| 3422 } | 3464 } |
| 3423 | 3465 |
| 3424 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 3466 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
| 3425 EmitCallJSRuntimeFunction(expr); | 3467 EmitCallJSRuntimeFunction(expr); |
| 3426 | 3468 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3442 default: { | 3484 default: { |
| 3443 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic"); | 3485 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic"); |
| 3444 // Push the arguments ("left-to-right"). | 3486 // Push the arguments ("left-to-right"). |
| 3445 for (int i = 0; i < arg_count; i++) { | 3487 for (int i = 0; i < arg_count; i++) { |
| 3446 VisitForStackValue(args->at(i)); | 3488 VisitForStackValue(args->at(i)); |
| 3447 } | 3489 } |
| 3448 | 3490 |
| 3449 // Call the C runtime function. | 3491 // Call the C runtime function. |
| 3450 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 3492 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
| 3451 __ CallRuntime(expr->function(), arg_count); | 3493 __ CallRuntime(expr->function(), arg_count); |
| 3494 OperandStackDepthDecrement(arg_count); |
| 3452 context()->Plug(r3); | 3495 context()->Plug(r3); |
| 3453 } | 3496 } |
| 3454 } | 3497 } |
| 3455 } | 3498 } |
| 3456 } | 3499 } |
| 3457 | 3500 |
| 3458 | 3501 |
| 3459 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 3502 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
| 3460 switch (expr->op()) { | 3503 switch (expr->op()) { |
| 3461 case Token::DELETE: { | 3504 case Token::DELETE: { |
| 3462 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); | 3505 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); |
| 3463 Property* property = expr->expression()->AsProperty(); | 3506 Property* property = expr->expression()->AsProperty(); |
| 3464 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 3507 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 3465 | 3508 |
| 3466 if (property != NULL) { | 3509 if (property != NULL) { |
| 3467 VisitForStackValue(property->obj()); | 3510 VisitForStackValue(property->obj()); |
| 3468 VisitForStackValue(property->key()); | 3511 VisitForStackValue(property->key()); |
| 3469 __ CallRuntime(is_strict(language_mode()) | 3512 CallRuntimeWithOperands(is_strict(language_mode()) |
| 3470 ? Runtime::kDeleteProperty_Strict | 3513 ? Runtime::kDeleteProperty_Strict |
| 3471 : Runtime::kDeleteProperty_Sloppy); | 3514 : Runtime::kDeleteProperty_Sloppy); |
| 3472 context()->Plug(r3); | 3515 context()->Plug(r3); |
| 3473 } else if (proxy != NULL) { | 3516 } else if (proxy != NULL) { |
| 3474 Variable* var = proxy->var(); | 3517 Variable* var = proxy->var(); |
| 3475 // Delete of an unqualified identifier is disallowed in strict mode but | 3518 // Delete of an unqualified identifier is disallowed in strict mode but |
| 3476 // "delete this" is allowed. | 3519 // "delete this" is allowed. |
| 3477 bool is_this = var->HasThisName(isolate()); | 3520 bool is_this = var->HasThisName(isolate()); |
| 3478 DCHECK(is_sloppy(language_mode()) || is_this); | 3521 DCHECK(is_sloppy(language_mode()) || is_this); |
| 3479 if (var->IsUnallocatedOrGlobalSlot()) { | 3522 if (var->IsUnallocatedOrGlobalSlot()) { |
| 3480 __ LoadGlobalObject(r5); | 3523 __ LoadGlobalObject(r5); |
| 3481 __ mov(r4, Operand(var->name())); | 3524 __ mov(r4, Operand(var->name())); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3523 context()->Plug(test->true_label(), test->false_label()); | 3566 context()->Plug(test->true_label(), test->false_label()); |
| 3524 } else { | 3567 } else { |
| 3525 // We handle value contexts explicitly rather than simply visiting | 3568 // We handle value contexts explicitly rather than simply visiting |
| 3526 // for control and plugging the control flow into the context, | 3569 // for control and plugging the control flow into the context, |
| 3527 // because we need to prepare a pair of extra administrative AST ids | 3570 // because we need to prepare a pair of extra administrative AST ids |
| 3528 // for the optimizing compiler. | 3571 // for the optimizing compiler. |
| 3529 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); | 3572 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); |
| 3530 Label materialize_true, materialize_false, done; | 3573 Label materialize_true, materialize_false, done; |
| 3531 VisitForControl(expr->expression(), &materialize_false, | 3574 VisitForControl(expr->expression(), &materialize_false, |
| 3532 &materialize_true, &materialize_true); | 3575 &materialize_true, &materialize_true); |
| 3576 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1); |
| 3533 __ bind(&materialize_true); | 3577 __ bind(&materialize_true); |
| 3534 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); | 3578 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); |
| 3535 __ LoadRoot(r3, Heap::kTrueValueRootIndex); | 3579 __ LoadRoot(r3, Heap::kTrueValueRootIndex); |
| 3536 if (context()->IsStackValue()) __ push(r3); | 3580 if (context()->IsStackValue()) __ push(r3); |
| 3537 __ b(&done); | 3581 __ b(&done); |
| 3538 __ bind(&materialize_false); | 3582 __ bind(&materialize_false); |
| 3539 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); | 3583 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); |
| 3540 __ LoadRoot(r3, Heap::kFalseValueRootIndex); | 3584 __ LoadRoot(r3, Heap::kFalseValueRootIndex); |
| 3541 if (context()->IsStackValue()) __ push(r3); | 3585 if (context()->IsStackValue()) __ push(r3); |
| 3542 __ bind(&done); | 3586 __ bind(&done); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 3573 | 3617 |
| 3574 // Evaluate expression and get value. | 3618 // Evaluate expression and get value. |
| 3575 if (assign_type == VARIABLE) { | 3619 if (assign_type == VARIABLE) { |
| 3576 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 3620 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
| 3577 AccumulatorValueContext context(this); | 3621 AccumulatorValueContext context(this); |
| 3578 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 3622 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
| 3579 } else { | 3623 } else { |
| 3580 // Reserve space for result of postfix operation. | 3624 // Reserve space for result of postfix operation. |
| 3581 if (expr->is_postfix() && !context()->IsEffect()) { | 3625 if (expr->is_postfix() && !context()->IsEffect()) { |
| 3582 __ LoadSmiLiteral(ip, Smi::FromInt(0)); | 3626 __ LoadSmiLiteral(ip, Smi::FromInt(0)); |
| 3583 __ push(ip); | 3627 PushOperand(ip); |
| 3584 } | 3628 } |
| 3585 switch (assign_type) { | 3629 switch (assign_type) { |
| 3586 case NAMED_PROPERTY: { | 3630 case NAMED_PROPERTY: { |
| 3587 // Put the object both on the stack and in the register. | 3631 // Put the object both on the stack and in the register. |
| 3588 VisitForStackValue(prop->obj()); | 3632 VisitForStackValue(prop->obj()); |
| 3589 __ LoadP(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); | 3633 __ LoadP(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); |
| 3590 EmitNamedPropertyLoad(prop); | 3634 EmitNamedPropertyLoad(prop); |
| 3591 break; | 3635 break; |
| 3592 } | 3636 } |
| 3593 | 3637 |
| 3594 case NAMED_SUPER_PROPERTY: { | 3638 case NAMED_SUPER_PROPERTY: { |
| 3595 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 3639 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
| 3596 VisitForAccumulatorValue( | 3640 VisitForAccumulatorValue( |
| 3597 prop->obj()->AsSuperPropertyReference()->home_object()); | 3641 prop->obj()->AsSuperPropertyReference()->home_object()); |
| 3598 __ Push(result_register()); | 3642 PushOperand(result_register()); |
| 3599 const Register scratch = r4; | 3643 const Register scratch = r4; |
| 3600 __ LoadP(scratch, MemOperand(sp, kPointerSize)); | 3644 __ LoadP(scratch, MemOperand(sp, kPointerSize)); |
| 3601 __ Push(scratch, result_register()); | 3645 PushOperands(scratch, result_register()); |
| 3602 EmitNamedSuperPropertyLoad(prop); | 3646 EmitNamedSuperPropertyLoad(prop); |
| 3603 break; | 3647 break; |
| 3604 } | 3648 } |
| 3605 | 3649 |
| 3606 case KEYED_SUPER_PROPERTY: { | 3650 case KEYED_SUPER_PROPERTY: { |
| 3607 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 3651 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
| 3608 VisitForAccumulatorValue( | 3652 VisitForAccumulatorValue( |
| 3609 prop->obj()->AsSuperPropertyReference()->home_object()); | 3653 prop->obj()->AsSuperPropertyReference()->home_object()); |
| 3610 const Register scratch = r4; | 3654 const Register scratch = r4; |
| 3611 const Register scratch1 = r5; | 3655 const Register scratch1 = r5; |
| 3612 __ mr(scratch, result_register()); | 3656 __ mr(scratch, result_register()); |
| 3613 VisitForAccumulatorValue(prop->key()); | 3657 VisitForAccumulatorValue(prop->key()); |
| 3614 __ Push(scratch, result_register()); | 3658 PushOperands(scratch, result_register()); |
| 3615 __ LoadP(scratch1, MemOperand(sp, 2 * kPointerSize)); | 3659 __ LoadP(scratch1, MemOperand(sp, 2 * kPointerSize)); |
| 3616 __ Push(scratch1, scratch, result_register()); | 3660 PushOperands(scratch1, scratch, result_register()); |
| 3617 EmitKeyedSuperPropertyLoad(prop); | 3661 EmitKeyedSuperPropertyLoad(prop); |
| 3618 break; | 3662 break; |
| 3619 } | 3663 } |
| 3620 | 3664 |
| 3621 case KEYED_PROPERTY: { | 3665 case KEYED_PROPERTY: { |
| 3622 VisitForStackValue(prop->obj()); | 3666 VisitForStackValue(prop->obj()); |
| 3623 VisitForStackValue(prop->key()); | 3667 VisitForStackValue(prop->key()); |
| 3624 __ LoadP(LoadDescriptor::ReceiverRegister(), | 3668 __ LoadP(LoadDescriptor::ReceiverRegister(), |
| 3625 MemOperand(sp, 1 * kPointerSize)); | 3669 MemOperand(sp, 1 * kPointerSize)); |
| 3626 __ LoadP(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); | 3670 __ LoadP(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3693 } | 3737 } |
| 3694 | 3738 |
| 3695 // Save result for postfix expressions. | 3739 // Save result for postfix expressions. |
| 3696 if (expr->is_postfix()) { | 3740 if (expr->is_postfix()) { |
| 3697 if (!context()->IsEffect()) { | 3741 if (!context()->IsEffect()) { |
| 3698 // Save the result on the stack. If we have a named or keyed property | 3742 // Save the result on the stack. If we have a named or keyed property |
| 3699 // we store the result under the receiver that is currently on top | 3743 // we store the result under the receiver that is currently on top |
| 3700 // of the stack. | 3744 // of the stack. |
| 3701 switch (assign_type) { | 3745 switch (assign_type) { |
| 3702 case VARIABLE: | 3746 case VARIABLE: |
| 3703 __ push(r3); | 3747 PushOperand(r3); |
| 3704 break; | 3748 break; |
| 3705 case NAMED_PROPERTY: | 3749 case NAMED_PROPERTY: |
| 3706 __ StoreP(r3, MemOperand(sp, kPointerSize)); | 3750 __ StoreP(r3, MemOperand(sp, kPointerSize)); |
| 3707 break; | 3751 break; |
| 3708 case NAMED_SUPER_PROPERTY: | 3752 case NAMED_SUPER_PROPERTY: |
| 3709 __ StoreP(r3, MemOperand(sp, 2 * kPointerSize)); | 3753 __ StoreP(r3, MemOperand(sp, 2 * kPointerSize)); |
| 3710 break; | 3754 break; |
| 3711 case KEYED_PROPERTY: | 3755 case KEYED_PROPERTY: |
| 3712 __ StoreP(r3, MemOperand(sp, 2 * kPointerSize)); | 3756 __ StoreP(r3, MemOperand(sp, 2 * kPointerSize)); |
| 3713 break; | 3757 break; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3751 } else { | 3795 } else { |
| 3752 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3796 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 3753 Token::ASSIGN, expr->CountSlot()); | 3797 Token::ASSIGN, expr->CountSlot()); |
| 3754 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3798 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3755 context()->Plug(r3); | 3799 context()->Plug(r3); |
| 3756 } | 3800 } |
| 3757 break; | 3801 break; |
| 3758 case NAMED_PROPERTY: { | 3802 case NAMED_PROPERTY: { |
| 3759 __ mov(StoreDescriptor::NameRegister(), | 3803 __ mov(StoreDescriptor::NameRegister(), |
| 3760 Operand(prop->key()->AsLiteral()->value())); | 3804 Operand(prop->key()->AsLiteral()->value())); |
| 3761 __ pop(StoreDescriptor::ReceiverRegister()); | 3805 PopOperand(StoreDescriptor::ReceiverRegister()); |
| 3762 EmitLoadStoreICSlot(expr->CountSlot()); | 3806 EmitLoadStoreICSlot(expr->CountSlot()); |
| 3763 CallStoreIC(); | 3807 CallStoreIC(); |
| 3764 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3808 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3765 if (expr->is_postfix()) { | 3809 if (expr->is_postfix()) { |
| 3766 if (!context()->IsEffect()) { | 3810 if (!context()->IsEffect()) { |
| 3767 context()->PlugTOS(); | 3811 context()->PlugTOS(); |
| 3768 } | 3812 } |
| 3769 } else { | 3813 } else { |
| 3770 context()->Plug(r3); | 3814 context()->Plug(r3); |
| 3771 } | 3815 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3787 if (expr->is_postfix()) { | 3831 if (expr->is_postfix()) { |
| 3788 if (!context()->IsEffect()) { | 3832 if (!context()->IsEffect()) { |
| 3789 context()->PlugTOS(); | 3833 context()->PlugTOS(); |
| 3790 } | 3834 } |
| 3791 } else { | 3835 } else { |
| 3792 context()->Plug(r3); | 3836 context()->Plug(r3); |
| 3793 } | 3837 } |
| 3794 break; | 3838 break; |
| 3795 } | 3839 } |
| 3796 case KEYED_PROPERTY: { | 3840 case KEYED_PROPERTY: { |
| 3797 __ Pop(StoreDescriptor::ReceiverRegister(), | 3841 PopOperands(StoreDescriptor::ReceiverRegister(), |
| 3798 StoreDescriptor::NameRegister()); | 3842 StoreDescriptor::NameRegister()); |
| 3799 Handle<Code> ic = | 3843 Handle<Code> ic = |
| 3800 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 3844 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 3801 EmitLoadStoreICSlot(expr->CountSlot()); | 3845 EmitLoadStoreICSlot(expr->CountSlot()); |
| 3802 CallIC(ic); | 3846 CallIC(ic); |
| 3803 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3847 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3804 if (expr->is_postfix()) { | 3848 if (expr->is_postfix()) { |
| 3805 if (!context()->IsEffect()) { | 3849 if (!context()->IsEffect()) { |
| 3806 context()->PlugTOS(); | 3850 context()->PlugTOS(); |
| 3807 } | 3851 } |
| 3808 } else { | 3852 } else { |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3912 Label* if_false = NULL; | 3956 Label* if_false = NULL; |
| 3913 Label* fall_through = NULL; | 3957 Label* fall_through = NULL; |
| 3914 context()->PrepareTest(&materialize_true, &materialize_false, &if_true, | 3958 context()->PrepareTest(&materialize_true, &materialize_false, &if_true, |
| 3915 &if_false, &fall_through); | 3959 &if_false, &fall_through); |
| 3916 | 3960 |
| 3917 Token::Value op = expr->op(); | 3961 Token::Value op = expr->op(); |
| 3918 VisitForStackValue(expr->left()); | 3962 VisitForStackValue(expr->left()); |
| 3919 switch (op) { | 3963 switch (op) { |
| 3920 case Token::IN: | 3964 case Token::IN: |
| 3921 VisitForStackValue(expr->right()); | 3965 VisitForStackValue(expr->right()); |
| 3922 __ CallRuntime(Runtime::kHasProperty); | 3966 CallRuntimeWithOperands(Runtime::kHasProperty); |
| 3923 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); | 3967 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); |
| 3924 __ CompareRoot(r3, Heap::kTrueValueRootIndex); | 3968 __ CompareRoot(r3, Heap::kTrueValueRootIndex); |
| 3925 Split(eq, if_true, if_false, fall_through); | 3969 Split(eq, if_true, if_false, fall_through); |
| 3926 break; | 3970 break; |
| 3927 | 3971 |
| 3928 case Token::INSTANCEOF: { | 3972 case Token::INSTANCEOF: { |
| 3929 VisitForAccumulatorValue(expr->right()); | 3973 VisitForAccumulatorValue(expr->right()); |
| 3930 __ pop(r4); | 3974 PopOperand(r4); |
| 3931 InstanceOfStub stub(isolate()); | 3975 InstanceOfStub stub(isolate()); |
| 3932 __ CallStub(&stub); | 3976 __ CallStub(&stub); |
| 3933 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); | 3977 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); |
| 3934 __ CompareRoot(r3, Heap::kTrueValueRootIndex); | 3978 __ CompareRoot(r3, Heap::kTrueValueRootIndex); |
| 3935 Split(eq, if_true, if_false, fall_through); | 3979 Split(eq, if_true, if_false, fall_through); |
| 3936 break; | 3980 break; |
| 3937 } | 3981 } |
| 3938 | 3982 |
| 3939 default: { | 3983 default: { |
| 3940 VisitForAccumulatorValue(expr->right()); | 3984 VisitForAccumulatorValue(expr->right()); |
| 3941 Condition cond = CompareIC::ComputeCondition(op); | 3985 Condition cond = CompareIC::ComputeCondition(op); |
| 3942 __ pop(r4); | 3986 PopOperand(r4); |
| 3943 | 3987 |
| 3944 bool inline_smi_code = ShouldInlineSmiCase(op); | 3988 bool inline_smi_code = ShouldInlineSmiCase(op); |
| 3945 JumpPatchSite patch_site(masm_); | 3989 JumpPatchSite patch_site(masm_); |
| 3946 if (inline_smi_code) { | 3990 if (inline_smi_code) { |
| 3947 Label slow_case; | 3991 Label slow_case; |
| 3948 __ orx(r5, r3, r4); | 3992 __ orx(r5, r3, r4); |
| 3949 patch_site.EmitJumpIfNotSmi(r5, &slow_case); | 3993 patch_site.EmitJumpIfNotSmi(r5, &slow_case); |
| 3950 __ cmp(r4, r3); | 3994 __ cmp(r4, r3); |
| 3951 Split(cond, if_true, if_false, NULL); | 3995 Split(cond, if_true, if_false, NULL); |
| 3952 __ bind(&slow_case); | 3996 __ bind(&slow_case); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4029 __ LoadNativeContextSlot(Context::CLOSURE_INDEX, ip); | 4073 __ LoadNativeContextSlot(Context::CLOSURE_INDEX, ip); |
| 4030 } else if (closure_scope->is_eval_scope()) { | 4074 } else if (closure_scope->is_eval_scope()) { |
| 4031 // Contexts created by a call to eval have the same closure as the | 4075 // Contexts created by a call to eval have the same closure as the |
| 4032 // context calling eval, not the anonymous closure containing the eval | 4076 // context calling eval, not the anonymous closure containing the eval |
| 4033 // code. Fetch it from the context. | 4077 // code. Fetch it from the context. |
| 4034 __ LoadP(ip, ContextMemOperand(cp, Context::CLOSURE_INDEX)); | 4078 __ LoadP(ip, ContextMemOperand(cp, Context::CLOSURE_INDEX)); |
| 4035 } else { | 4079 } else { |
| 4036 DCHECK(closure_scope->is_function_scope()); | 4080 DCHECK(closure_scope->is_function_scope()); |
| 4037 __ LoadP(ip, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 4081 __ LoadP(ip, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 4038 } | 4082 } |
| 4039 __ push(ip); | 4083 PushOperand(ip); |
| 4040 } | 4084 } |
| 4041 | 4085 |
| 4042 | 4086 |
| 4043 // ---------------------------------------------------------------------------- | 4087 // ---------------------------------------------------------------------------- |
| 4044 // Non-local control flow support. | 4088 // Non-local control flow support. |
| 4045 | 4089 |
| 4046 void FullCodeGenerator::EnterFinallyBlock() { | 4090 void FullCodeGenerator::EnterFinallyBlock() { |
| 4047 DCHECK(!result_register().is(r4)); | 4091 DCHECK(!result_register().is(r4)); |
| 4048 // Store pending message while executing finally block. | 4092 // Store pending message while executing finally block. |
| 4049 ExternalReference pending_message_obj = | 4093 ExternalReference pending_message_obj = |
| 4050 ExternalReference::address_of_pending_message_obj(isolate()); | 4094 ExternalReference::address_of_pending_message_obj(isolate()); |
| 4051 __ mov(ip, Operand(pending_message_obj)); | 4095 __ mov(ip, Operand(pending_message_obj)); |
| 4052 __ LoadP(r4, MemOperand(ip)); | 4096 __ LoadP(r4, MemOperand(ip)); |
| 4053 __ push(r4); | 4097 PushOperand(r4); |
| 4054 | 4098 |
| 4055 ClearPendingMessage(); | 4099 ClearPendingMessage(); |
| 4056 } | 4100 } |
| 4057 | 4101 |
| 4058 | 4102 |
| 4059 void FullCodeGenerator::ExitFinallyBlock() { | 4103 void FullCodeGenerator::ExitFinallyBlock() { |
| 4060 DCHECK(!result_register().is(r4)); | 4104 DCHECK(!result_register().is(r4)); |
| 4061 // Restore pending message from stack. | 4105 // Restore pending message from stack. |
| 4062 __ pop(r4); | 4106 PopOperand(r4); |
| 4063 ExternalReference pending_message_obj = | 4107 ExternalReference pending_message_obj = |
| 4064 ExternalReference::address_of_pending_message_obj(isolate()); | 4108 ExternalReference::address_of_pending_message_obj(isolate()); |
| 4065 __ mov(ip, Operand(pending_message_obj)); | 4109 __ mov(ip, Operand(pending_message_obj)); |
| 4066 __ StoreP(r4, MemOperand(ip)); | 4110 __ StoreP(r4, MemOperand(ip)); |
| 4067 } | 4111 } |
| 4068 | 4112 |
| 4069 | 4113 |
| 4070 void FullCodeGenerator::ClearPendingMessage() { | 4114 void FullCodeGenerator::ClearPendingMessage() { |
| 4071 DCHECK(!result_register().is(r4)); | 4115 DCHECK(!result_register().is(r4)); |
| 4072 ExternalReference pending_message_obj = | 4116 ExternalReference pending_message_obj = |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4178 return ON_STACK_REPLACEMENT; | 4222 return ON_STACK_REPLACEMENT; |
| 4179 } | 4223 } |
| 4180 | 4224 |
| 4181 DCHECK(interrupt_address == | 4225 DCHECK(interrupt_address == |
| 4182 isolate->builtins()->OsrAfterStackCheck()->entry()); | 4226 isolate->builtins()->OsrAfterStackCheck()->entry()); |
| 4183 return OSR_AFTER_STACK_CHECK; | 4227 return OSR_AFTER_STACK_CHECK; |
| 4184 } | 4228 } |
| 4185 } // namespace internal | 4229 } // namespace internal |
| 4186 } // namespace v8 | 4230 } // namespace v8 |
| 4187 #endif // V8_TARGET_ARCH_PPC | 4231 #endif // V8_TARGET_ARCH_PPC |
| OLD | NEW |