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 |