OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 // the frame (that is done below). | 112 // the frame (that is done below). |
113 FrameScope frame_scope(masm_, StackFrame::MANUAL); | 113 FrameScope frame_scope(masm_, StackFrame::MANUAL); |
114 | 114 |
115 info->set_prologue_offset(masm_->pc_offset()); | 115 info->set_prologue_offset(masm_->pc_offset()); |
116 __ Prologue(info->GeneratePreagedPrologue()); | 116 __ Prologue(info->GeneratePreagedPrologue()); |
117 | 117 |
118 { Comment cmnt(masm_, "[ Allocate locals"); | 118 { Comment cmnt(masm_, "[ Allocate locals"); |
119 int locals_count = info->scope()->num_stack_slots(); | 119 int locals_count = info->scope()->num_stack_slots(); |
120 // Generators allocate locals, if any, in context slots. | 120 // Generators allocate locals, if any, in context slots. |
121 DCHECK(!IsGeneratorFunction(literal()->kind()) || locals_count == 0); | 121 DCHECK(!IsGeneratorFunction(literal()->kind()) || locals_count == 0); |
| 122 OperandStackDepthIncrement(locals_count); |
122 if (locals_count == 1) { | 123 if (locals_count == 1) { |
123 __ push(Immediate(isolate()->factory()->undefined_value())); | 124 __ push(Immediate(isolate()->factory()->undefined_value())); |
124 } else if (locals_count > 1) { | 125 } else if (locals_count > 1) { |
125 if (locals_count >= 128) { | 126 if (locals_count >= 128) { |
126 Label ok; | 127 Label ok; |
127 __ mov(ecx, esp); | 128 __ mov(ecx, esp); |
128 __ sub(ecx, Immediate(locals_count * kPointerSize)); | 129 __ sub(ecx, Immediate(locals_count * kPointerSize)); |
129 ExternalReference stack_limit = | 130 ExternalReference stack_limit = |
130 ExternalReference::address_of_real_stack_limit(isolate()); | 131 ExternalReference::address_of_real_stack_limit(isolate()); |
131 __ cmp(ecx, Operand::StaticVariable(stack_limit)); | 132 __ cmp(ecx, Operand::StaticVariable(stack_limit)); |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 int arguments_bytes = arg_count * kPointerSize; | 425 int arguments_bytes = arg_count * kPointerSize; |
425 __ Ret(arguments_bytes, ecx); | 426 __ Ret(arguments_bytes, ecx); |
426 } | 427 } |
427 } | 428 } |
428 | 429 |
429 | 430 |
430 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { | 431 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { |
431 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 432 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
432 MemOperand operand = codegen()->VarOperand(var, result_register()); | 433 MemOperand operand = codegen()->VarOperand(var, result_register()); |
433 // Memory operands can be pushed directly. | 434 // Memory operands can be pushed directly. |
434 __ push(operand); | 435 codegen()->PushOperand(operand); |
435 } | 436 } |
436 | 437 |
437 | 438 |
438 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { | 439 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { |
439 UNREACHABLE(); // Not used on IA32. | 440 UNREACHABLE(); // Not used on IA32. |
440 } | 441 } |
441 | 442 |
442 | 443 |
443 void FullCodeGenerator::AccumulatorValueContext::Plug( | 444 void FullCodeGenerator::AccumulatorValueContext::Plug( |
444 Heap::RootListIndex index) const { | 445 Heap::RootListIndex index) const { |
(...skipping 20 matching lines...) Expand all Loading... |
465 Handle<Object> lit) const { | 466 Handle<Object> lit) const { |
466 if (lit->IsSmi()) { | 467 if (lit->IsSmi()) { |
467 __ SafeMove(result_register(), Immediate(lit)); | 468 __ SafeMove(result_register(), Immediate(lit)); |
468 } else { | 469 } else { |
469 __ Move(result_register(), Immediate(lit)); | 470 __ Move(result_register(), Immediate(lit)); |
470 } | 471 } |
471 } | 472 } |
472 | 473 |
473 | 474 |
474 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { | 475 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { |
| 476 codegen()->OperandStackDepthIncrement(1); |
475 if (lit->IsSmi()) { | 477 if (lit->IsSmi()) { |
476 __ SafePush(Immediate(lit)); | 478 __ SafePush(Immediate(lit)); |
477 } else { | 479 } else { |
478 __ push(Immediate(lit)); | 480 __ push(Immediate(lit)); |
479 } | 481 } |
480 } | 482 } |
481 | 483 |
482 | 484 |
483 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { | 485 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { |
484 codegen()->PrepareForBailoutBeforeSplit(condition(), | 486 codegen()->PrepareForBailoutBeforeSplit(condition(), |
(...skipping 18 matching lines...) Expand all Loading... |
503 if (true_label_ != fall_through_) __ jmp(true_label_); | 505 if (true_label_ != fall_through_) __ jmp(true_label_); |
504 } | 506 } |
505 } else { | 507 } else { |
506 // For simplicity we always test the accumulator register. | 508 // For simplicity we always test the accumulator register. |
507 __ mov(result_register(), lit); | 509 __ mov(result_register(), lit); |
508 codegen()->DoTest(this); | 510 codegen()->DoTest(this); |
509 } | 511 } |
510 } | 512 } |
511 | 513 |
512 | 514 |
513 void FullCodeGenerator::EffectContext::DropAndPlug(int count, | |
514 Register reg) const { | |
515 DCHECK(count > 0); | |
516 __ Drop(count); | |
517 } | |
518 | |
519 | |
520 void FullCodeGenerator::AccumulatorValueContext::DropAndPlug( | |
521 int count, | |
522 Register reg) const { | |
523 DCHECK(count > 0); | |
524 __ Drop(count); | |
525 __ Move(result_register(), reg); | |
526 } | |
527 | |
528 | |
529 void FullCodeGenerator::StackValueContext::DropAndPlug(int count, | 515 void FullCodeGenerator::StackValueContext::DropAndPlug(int count, |
530 Register reg) const { | 516 Register reg) const { |
531 DCHECK(count > 0); | 517 DCHECK(count > 0); |
532 if (count > 1) __ Drop(count - 1); | 518 if (count > 1) codegen()->DropOperands(count - 1); |
533 __ mov(Operand(esp, 0), reg); | 519 __ mov(Operand(esp, 0), reg); |
534 } | 520 } |
535 | 521 |
536 | 522 |
537 void FullCodeGenerator::TestContext::DropAndPlug(int count, | |
538 Register reg) const { | |
539 DCHECK(count > 0); | |
540 // For simplicity we always test the accumulator register. | |
541 __ Drop(count); | |
542 __ Move(result_register(), reg); | |
543 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); | |
544 codegen()->DoTest(this); | |
545 } | |
546 | |
547 | |
548 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, | 523 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, |
549 Label* materialize_false) const { | 524 Label* materialize_false) const { |
550 DCHECK(materialize_true == materialize_false); | 525 DCHECK(materialize_true == materialize_false); |
551 __ bind(materialize_true); | 526 __ bind(materialize_true); |
552 } | 527 } |
553 | 528 |
554 | 529 |
555 void FullCodeGenerator::AccumulatorValueContext::Plug( | 530 void FullCodeGenerator::AccumulatorValueContext::Plug( |
556 Label* materialize_true, | 531 Label* materialize_true, |
557 Label* materialize_false) const { | 532 Label* materialize_false) const { |
558 Label done; | 533 Label done; |
559 __ bind(materialize_true); | 534 __ bind(materialize_true); |
560 __ mov(result_register(), isolate()->factory()->true_value()); | 535 __ mov(result_register(), isolate()->factory()->true_value()); |
561 __ jmp(&done, Label::kNear); | 536 __ jmp(&done, Label::kNear); |
562 __ bind(materialize_false); | 537 __ bind(materialize_false); |
563 __ mov(result_register(), isolate()->factory()->false_value()); | 538 __ mov(result_register(), isolate()->factory()->false_value()); |
564 __ bind(&done); | 539 __ bind(&done); |
565 } | 540 } |
566 | 541 |
567 | 542 |
568 void FullCodeGenerator::StackValueContext::Plug( | 543 void FullCodeGenerator::StackValueContext::Plug( |
569 Label* materialize_true, | 544 Label* materialize_true, |
570 Label* materialize_false) const { | 545 Label* materialize_false) const { |
| 546 codegen()->OperandStackDepthIncrement(1); |
571 Label done; | 547 Label done; |
572 __ bind(materialize_true); | 548 __ bind(materialize_true); |
573 __ push(Immediate(isolate()->factory()->true_value())); | 549 __ push(Immediate(isolate()->factory()->true_value())); |
574 __ jmp(&done, Label::kNear); | 550 __ jmp(&done, Label::kNear); |
575 __ bind(materialize_false); | 551 __ bind(materialize_false); |
576 __ push(Immediate(isolate()->factory()->false_value())); | 552 __ push(Immediate(isolate()->factory()->false_value())); |
577 __ bind(&done); | 553 __ bind(&done); |
578 } | 554 } |
579 | 555 |
580 | 556 |
581 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, | 557 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, |
582 Label* materialize_false) const { | 558 Label* materialize_false) const { |
583 DCHECK(materialize_true == true_label_); | 559 DCHECK(materialize_true == true_label_); |
584 DCHECK(materialize_false == false_label_); | 560 DCHECK(materialize_false == false_label_); |
585 } | 561 } |
586 | 562 |
587 | 563 |
588 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { | 564 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { |
589 Handle<Object> value = flag | 565 Handle<Object> value = flag |
590 ? isolate()->factory()->true_value() | 566 ? isolate()->factory()->true_value() |
591 : isolate()->factory()->false_value(); | 567 : isolate()->factory()->false_value(); |
592 __ mov(result_register(), value); | 568 __ mov(result_register(), value); |
593 } | 569 } |
594 | 570 |
595 | 571 |
596 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { | 572 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { |
| 573 codegen()->OperandStackDepthIncrement(1); |
597 Handle<Object> value = flag | 574 Handle<Object> value = flag |
598 ? isolate()->factory()->true_value() | 575 ? isolate()->factory()->true_value() |
599 : isolate()->factory()->false_value(); | 576 : isolate()->factory()->false_value(); |
600 __ push(Immediate(value)); | 577 __ push(Immediate(value)); |
601 } | 578 } |
602 | 579 |
603 | 580 |
604 void FullCodeGenerator::TestContext::Plug(bool flag) const { | 581 void FullCodeGenerator::TestContext::Plug(bool flag) const { |
605 codegen()->PrepareForBailoutBeforeSplit(condition(), | 582 codegen()->PrepareForBailoutBeforeSplit(condition(), |
606 true, | 583 true, |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
824 ecx, | 801 ecx, |
825 kDontSaveFPRegs, | 802 kDontSaveFPRegs, |
826 EMIT_REMEMBERED_SET, | 803 EMIT_REMEMBERED_SET, |
827 OMIT_SMI_CHECK); | 804 OMIT_SMI_CHECK); |
828 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); | 805 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); |
829 break; | 806 break; |
830 } | 807 } |
831 | 808 |
832 case VariableLocation::LOOKUP: { | 809 case VariableLocation::LOOKUP: { |
833 Comment cmnt(masm_, "[ FunctionDeclaration"); | 810 Comment cmnt(masm_, "[ FunctionDeclaration"); |
834 __ push(Immediate(variable->name())); | 811 PushOperand(variable->name()); |
835 VisitForStackValue(declaration->fun()); | 812 VisitForStackValue(declaration->fun()); |
836 __ push( | 813 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes())); |
837 Immediate(Smi::FromInt(variable->DeclarationPropertyAttributes()))); | 814 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot); |
838 __ CallRuntime(Runtime::kDeclareLookupSlot); | |
839 break; | 815 break; |
840 } | 816 } |
841 } | 817 } |
842 } | 818 } |
843 | 819 |
844 | 820 |
845 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 821 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
846 // Call the runtime to declare the globals. | 822 // Call the runtime to declare the globals. |
847 __ Push(pairs); | 823 __ Push(pairs); |
848 __ Push(Smi::FromInt(DeclareGlobalsFlags())); | 824 __ Push(Smi::FromInt(DeclareGlobalsFlags())); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
924 | 900 |
925 __ test(eax, eax); | 901 __ test(eax, eax); |
926 __ j(not_equal, &next_test); | 902 __ j(not_equal, &next_test); |
927 __ Drop(1); // Switch value is no longer needed. | 903 __ Drop(1); // Switch value is no longer needed. |
928 __ jmp(clause->body_target()); | 904 __ jmp(clause->body_target()); |
929 } | 905 } |
930 | 906 |
931 // Discard the test value and jump to the default if present, otherwise to | 907 // Discard the test value and jump to the default if present, otherwise to |
932 // the end of the statement. | 908 // the end of the statement. |
933 __ bind(&next_test); | 909 __ bind(&next_test); |
934 __ Drop(1); // Switch value is no longer needed. | 910 DropOperands(1); // Switch value is no longer needed. |
935 if (default_clause == NULL) { | 911 if (default_clause == NULL) { |
936 __ jmp(nested_statement.break_label()); | 912 __ jmp(nested_statement.break_label()); |
937 } else { | 913 } else { |
938 __ jmp(default_clause->body_target()); | 914 __ jmp(default_clause->body_target()); |
939 } | 915 } |
940 | 916 |
941 // Compile all the case bodies. | 917 // Compile all the case bodies. |
942 for (int i = 0; i < clauses->length(); i++) { | 918 for (int i = 0; i < clauses->length(); i++) { |
943 Comment cmnt(masm_, "[ Case body"); | 919 Comment cmnt(masm_, "[ Case body"); |
944 CaseClause* clause = clauses->at(i); | 920 CaseClause* clause = clauses->at(i); |
(...skipping 13 matching lines...) Expand all Loading... |
958 | 934 |
959 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); | 935 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); |
960 | 936 |
961 Label loop, exit; | 937 Label loop, exit; |
962 ForIn loop_statement(this, stmt); | 938 ForIn loop_statement(this, stmt); |
963 increment_loop_depth(); | 939 increment_loop_depth(); |
964 | 940 |
965 // Get the object to enumerate over. | 941 // Get the object to enumerate over. |
966 SetExpressionAsStatementPosition(stmt->enumerable()); | 942 SetExpressionAsStatementPosition(stmt->enumerable()); |
967 VisitForAccumulatorValue(stmt->enumerable()); | 943 VisitForAccumulatorValue(stmt->enumerable()); |
| 944 OperandStackDepthIncrement(ForIn::kElementCount); |
968 | 945 |
969 // If the object is null or undefined, skip over the loop, otherwise convert | 946 // If the object is null or undefined, skip over the loop, otherwise convert |
970 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. | 947 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. |
971 Label convert, done_convert; | 948 Label convert, done_convert; |
972 __ JumpIfSmi(eax, &convert, Label::kNear); | 949 __ JumpIfSmi(eax, &convert, Label::kNear); |
973 __ CmpObjectType(eax, FIRST_JS_RECEIVER_TYPE, ecx); | 950 __ CmpObjectType(eax, FIRST_JS_RECEIVER_TYPE, ecx); |
974 __ j(above_equal, &done_convert, Label::kNear); | 951 __ j(above_equal, &done_convert, Label::kNear); |
975 __ cmp(eax, isolate()->factory()->undefined_value()); | 952 __ cmp(eax, isolate()->factory()->undefined_value()); |
976 __ j(equal, &exit); | 953 __ j(equal, &exit); |
977 __ cmp(eax, isolate()->factory()->null_value()); | 954 __ cmp(eax, isolate()->factory()->null_value()); |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1106 // index (smi) stored on top of the stack. | 1083 // index (smi) stored on top of the stack. |
1107 __ bind(loop_statement.continue_label()); | 1084 __ bind(loop_statement.continue_label()); |
1108 __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1))); | 1085 __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1))); |
1109 | 1086 |
1110 EmitBackEdgeBookkeeping(stmt, &loop); | 1087 EmitBackEdgeBookkeeping(stmt, &loop); |
1111 __ jmp(&loop); | 1088 __ jmp(&loop); |
1112 | 1089 |
1113 // Remove the pointers stored on the stack. | 1090 // Remove the pointers stored on the stack. |
1114 __ bind(loop_statement.break_label()); | 1091 __ bind(loop_statement.break_label()); |
1115 __ add(esp, Immediate(5 * kPointerSize)); | 1092 __ add(esp, Immediate(5 * kPointerSize)); |
| 1093 OperandStackDepthDecrement(ForIn::kElementCount); |
1116 | 1094 |
1117 // Exit and decrement the loop depth. | 1095 // Exit and decrement the loop depth. |
1118 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 1096 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
1119 __ bind(&exit); | 1097 __ bind(&exit); |
1120 decrement_loop_depth(); | 1098 decrement_loop_depth(); |
1121 } | 1099 } |
1122 | 1100 |
1123 | 1101 |
1124 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, | 1102 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, |
1125 bool pretenure) { | 1103 bool pretenure) { |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1377 __ Move(edx, Immediate(Smi::FromInt(expr->flags()))); | 1355 __ Move(edx, Immediate(Smi::FromInt(expr->flags()))); |
1378 FastCloneRegExpStub stub(isolate()); | 1356 FastCloneRegExpStub stub(isolate()); |
1379 __ CallStub(&stub); | 1357 __ CallStub(&stub); |
1380 context()->Plug(eax); | 1358 context()->Plug(eax); |
1381 } | 1359 } |
1382 | 1360 |
1383 | 1361 |
1384 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { | 1362 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { |
1385 Expression* expression = (property == NULL) ? NULL : property->value(); | 1363 Expression* expression = (property == NULL) ? NULL : property->value(); |
1386 if (expression == NULL) { | 1364 if (expression == NULL) { |
1387 __ push(Immediate(isolate()->factory()->null_value())); | 1365 PushOperand(isolate()->factory()->null_value()); |
1388 } else { | 1366 } else { |
1389 VisitForStackValue(expression); | 1367 VisitForStackValue(expression); |
1390 if (NeedsHomeObject(expression)) { | 1368 if (NeedsHomeObject(expression)) { |
1391 DCHECK(property->kind() == ObjectLiteral::Property::GETTER || | 1369 DCHECK(property->kind() == ObjectLiteral::Property::GETTER || |
1392 property->kind() == ObjectLiteral::Property::SETTER); | 1370 property->kind() == ObjectLiteral::Property::SETTER); |
1393 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3; | 1371 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3; |
1394 EmitSetHomeObject(expression, offset, property->GetSlot()); | 1372 EmitSetHomeObject(expression, offset, property->GetSlot()); |
1395 } | 1373 } |
1396 } | 1374 } |
1397 } | 1375 } |
(...skipping 29 matching lines...) Expand all Loading... |
1427 AccessorTable accessor_table(zone()); | 1405 AccessorTable accessor_table(zone()); |
1428 int property_index = 0; | 1406 int property_index = 0; |
1429 for (; property_index < expr->properties()->length(); property_index++) { | 1407 for (; property_index < expr->properties()->length(); property_index++) { |
1430 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1408 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
1431 if (property->is_computed_name()) break; | 1409 if (property->is_computed_name()) break; |
1432 if (property->IsCompileTimeValue()) continue; | 1410 if (property->IsCompileTimeValue()) continue; |
1433 | 1411 |
1434 Literal* key = property->key()->AsLiteral(); | 1412 Literal* key = property->key()->AsLiteral(); |
1435 Expression* value = property->value(); | 1413 Expression* value = property->value(); |
1436 if (!result_saved) { | 1414 if (!result_saved) { |
1437 __ push(eax); // Save result on the stack | 1415 PushOperand(eax); // Save result on the stack |
1438 result_saved = true; | 1416 result_saved = true; |
1439 } | 1417 } |
1440 switch (property->kind()) { | 1418 switch (property->kind()) { |
1441 case ObjectLiteral::Property::CONSTANT: | 1419 case ObjectLiteral::Property::CONSTANT: |
1442 UNREACHABLE(); | 1420 UNREACHABLE(); |
1443 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1421 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1444 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); | 1422 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); |
1445 // Fall through. | 1423 // Fall through. |
1446 case ObjectLiteral::Property::COMPUTED: | 1424 case ObjectLiteral::Property::COMPUTED: |
1447 // It is safe to use [[Put]] here because the boilerplate already | 1425 // It is safe to use [[Put]] here because the boilerplate already |
1448 // contains computed properties with an uninitialized value. | 1426 // contains computed properties with an uninitialized value. |
1449 if (key->value()->IsInternalizedString()) { | 1427 if (key->value()->IsInternalizedString()) { |
1450 if (property->emit_store()) { | 1428 if (property->emit_store()) { |
1451 VisitForAccumulatorValue(value); | 1429 VisitForAccumulatorValue(value); |
1452 DCHECK(StoreDescriptor::ValueRegister().is(eax)); | 1430 DCHECK(StoreDescriptor::ValueRegister().is(eax)); |
1453 __ mov(StoreDescriptor::NameRegister(), Immediate(key->value())); | 1431 __ mov(StoreDescriptor::NameRegister(), Immediate(key->value())); |
1454 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); | 1432 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); |
1455 EmitLoadStoreICSlot(property->GetSlot(0)); | 1433 EmitLoadStoreICSlot(property->GetSlot(0)); |
1456 CallStoreIC(); | 1434 CallStoreIC(); |
1457 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1435 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
1458 if (NeedsHomeObject(value)) { | 1436 if (NeedsHomeObject(value)) { |
1459 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); | 1437 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); |
1460 } | 1438 } |
1461 } else { | 1439 } else { |
1462 VisitForEffect(value); | 1440 VisitForEffect(value); |
1463 } | 1441 } |
1464 break; | 1442 break; |
1465 } | 1443 } |
1466 __ push(Operand(esp, 0)); // Duplicate receiver. | 1444 PushOperand(Operand(esp, 0)); // Duplicate receiver. |
1467 VisitForStackValue(key); | 1445 VisitForStackValue(key); |
1468 VisitForStackValue(value); | 1446 VisitForStackValue(value); |
1469 if (property->emit_store()) { | 1447 if (property->emit_store()) { |
1470 if (NeedsHomeObject(value)) { | 1448 if (NeedsHomeObject(value)) { |
1471 EmitSetHomeObject(value, 2, property->GetSlot()); | 1449 EmitSetHomeObject(value, 2, property->GetSlot()); |
1472 } | 1450 } |
1473 __ push(Immediate(Smi::FromInt(SLOPPY))); // Language mode | 1451 PushOperand(Smi::FromInt(SLOPPY)); // Language mode |
1474 __ CallRuntime(Runtime::kSetProperty); | 1452 CallRuntimeWithOperands(Runtime::kSetProperty); |
1475 } else { | 1453 } else { |
1476 __ Drop(3); | 1454 DropOperands(3); |
1477 } | 1455 } |
1478 break; | 1456 break; |
1479 case ObjectLiteral::Property::PROTOTYPE: | 1457 case ObjectLiteral::Property::PROTOTYPE: |
1480 __ push(Operand(esp, 0)); // Duplicate receiver. | 1458 PushOperand(Operand(esp, 0)); // Duplicate receiver. |
1481 VisitForStackValue(value); | 1459 VisitForStackValue(value); |
1482 DCHECK(property->emit_store()); | 1460 DCHECK(property->emit_store()); |
1483 __ CallRuntime(Runtime::kInternalSetPrototype); | 1461 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); |
1484 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), | 1462 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), |
1485 NO_REGISTERS); | 1463 NO_REGISTERS); |
1486 break; | 1464 break; |
1487 case ObjectLiteral::Property::GETTER: | 1465 case ObjectLiteral::Property::GETTER: |
1488 if (property->emit_store()) { | 1466 if (property->emit_store()) { |
1489 accessor_table.lookup(key)->second->getter = property; | 1467 accessor_table.lookup(key)->second->getter = property; |
1490 } | 1468 } |
1491 break; | 1469 break; |
1492 case ObjectLiteral::Property::SETTER: | 1470 case ObjectLiteral::Property::SETTER: |
1493 if (property->emit_store()) { | 1471 if (property->emit_store()) { |
1494 accessor_table.lookup(key)->second->setter = property; | 1472 accessor_table.lookup(key)->second->setter = property; |
1495 } | 1473 } |
1496 break; | 1474 break; |
1497 } | 1475 } |
1498 } | 1476 } |
1499 | 1477 |
1500 // Emit code to define accessors, using only a single call to the runtime for | 1478 // Emit code to define accessors, using only a single call to the runtime for |
1501 // each pair of corresponding getters and setters. | 1479 // each pair of corresponding getters and setters. |
1502 for (AccessorTable::Iterator it = accessor_table.begin(); | 1480 for (AccessorTable::Iterator it = accessor_table.begin(); |
1503 it != accessor_table.end(); | 1481 it != accessor_table.end(); |
1504 ++it) { | 1482 ++it) { |
1505 __ push(Operand(esp, 0)); // Duplicate receiver. | 1483 PushOperand(Operand(esp, 0)); // Duplicate receiver. |
1506 VisitForStackValue(it->first); | 1484 VisitForStackValue(it->first); |
1507 | 1485 |
1508 EmitAccessor(it->second->getter); | 1486 EmitAccessor(it->second->getter); |
1509 EmitAccessor(it->second->setter); | 1487 EmitAccessor(it->second->setter); |
1510 | 1488 |
1511 __ push(Immediate(Smi::FromInt(NONE))); | 1489 PushOperand(Smi::FromInt(NONE)); |
1512 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked); | 1490 CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked); |
1513 } | 1491 } |
1514 | 1492 |
1515 // Object literals have two parts. The "static" part on the left contains no | 1493 // Object literals have two parts. The "static" part on the left contains no |
1516 // computed property names, and so we can compute its map ahead of time; see | 1494 // computed property names, and so we can compute its map ahead of time; see |
1517 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part | 1495 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part |
1518 // starts with the first computed property name, and continues with all | 1496 // starts with the first computed property name, and continues with all |
1519 // properties to its right. All the code from above initializes the static | 1497 // properties to its right. All the code from above initializes the static |
1520 // component of the object literal, and arranges for the map of the result to | 1498 // component of the object literal, and arranges for the map of the result to |
1521 // reflect the static order in which the keys appear. For the dynamic | 1499 // reflect the static order in which the keys appear. For the dynamic |
1522 // properties, we compile them into a series of "SetOwnProperty" runtime | 1500 // properties, we compile them into a series of "SetOwnProperty" runtime |
1523 // calls. This will preserve insertion order. | 1501 // calls. This will preserve insertion order. |
1524 for (; property_index < expr->properties()->length(); property_index++) { | 1502 for (; property_index < expr->properties()->length(); property_index++) { |
1525 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1503 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
1526 | 1504 |
1527 Expression* value = property->value(); | 1505 Expression* value = property->value(); |
1528 if (!result_saved) { | 1506 if (!result_saved) { |
1529 __ push(eax); // Save result on the stack | 1507 PushOperand(eax); // Save result on the stack |
1530 result_saved = true; | 1508 result_saved = true; |
1531 } | 1509 } |
1532 | 1510 |
1533 __ push(Operand(esp, 0)); // Duplicate receiver. | 1511 PushOperand(Operand(esp, 0)); // Duplicate receiver. |
1534 | 1512 |
1535 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { | 1513 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { |
1536 DCHECK(!property->is_computed_name()); | 1514 DCHECK(!property->is_computed_name()); |
1537 VisitForStackValue(value); | 1515 VisitForStackValue(value); |
1538 DCHECK(property->emit_store()); | 1516 DCHECK(property->emit_store()); |
1539 __ CallRuntime(Runtime::kInternalSetPrototype); | 1517 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); |
1540 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), | 1518 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), |
1541 NO_REGISTERS); | 1519 NO_REGISTERS); |
1542 } else { | 1520 } else { |
1543 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); | 1521 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); |
1544 VisitForStackValue(value); | 1522 VisitForStackValue(value); |
1545 if (NeedsHomeObject(value)) { | 1523 if (NeedsHomeObject(value)) { |
1546 EmitSetHomeObject(value, 2, property->GetSlot()); | 1524 EmitSetHomeObject(value, 2, property->GetSlot()); |
1547 } | 1525 } |
1548 | 1526 |
1549 switch (property->kind()) { | 1527 switch (property->kind()) { |
1550 case ObjectLiteral::Property::CONSTANT: | 1528 case ObjectLiteral::Property::CONSTANT: |
1551 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1529 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1552 case ObjectLiteral::Property::COMPUTED: | 1530 case ObjectLiteral::Property::COMPUTED: |
1553 if (property->emit_store()) { | 1531 if (property->emit_store()) { |
1554 __ Push(Smi::FromInt(NONE)); | 1532 PushOperand(Smi::FromInt(NONE)); |
1555 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); | 1533 PushOperand(Smi::FromInt(property->NeedsSetFunctionName())); |
1556 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); | 1534 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral); |
1557 } else { | 1535 } else { |
1558 __ Drop(3); | 1536 DropOperands(3); |
1559 } | 1537 } |
1560 break; | 1538 break; |
1561 | 1539 |
1562 case ObjectLiteral::Property::PROTOTYPE: | 1540 case ObjectLiteral::Property::PROTOTYPE: |
1563 UNREACHABLE(); | 1541 UNREACHABLE(); |
1564 break; | 1542 break; |
1565 | 1543 |
1566 case ObjectLiteral::Property::GETTER: | 1544 case ObjectLiteral::Property::GETTER: |
1567 __ Push(Smi::FromInt(NONE)); | 1545 PushOperand(Smi::FromInt(NONE)); |
1568 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); | 1546 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked); |
1569 break; | 1547 break; |
1570 | 1548 |
1571 case ObjectLiteral::Property::SETTER: | 1549 case ObjectLiteral::Property::SETTER: |
1572 __ Push(Smi::FromInt(NONE)); | 1550 PushOperand(Smi::FromInt(NONE)); |
1573 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); | 1551 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked); |
1574 break; | 1552 break; |
1575 } | 1553 } |
1576 } | 1554 } |
1577 } | 1555 } |
1578 | 1556 |
1579 if (expr->has_function()) { | 1557 if (expr->has_function()) { |
1580 DCHECK(result_saved); | 1558 DCHECK(result_saved); |
1581 __ push(Operand(esp, 0)); | 1559 __ push(Operand(esp, 0)); |
1582 __ CallRuntime(Runtime::kToFastProperties); | 1560 __ CallRuntime(Runtime::kToFastProperties); |
1583 } | 1561 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1628 int array_index = 0; | 1606 int array_index = 0; |
1629 for (; array_index < length; array_index++) { | 1607 for (; array_index < length; array_index++) { |
1630 Expression* subexpr = subexprs->at(array_index); | 1608 Expression* subexpr = subexprs->at(array_index); |
1631 DCHECK(!subexpr->IsSpread()); | 1609 DCHECK(!subexpr->IsSpread()); |
1632 | 1610 |
1633 // If the subexpression is a literal or a simple materialized literal it | 1611 // If the subexpression is a literal or a simple materialized literal it |
1634 // is already set in the cloned array. | 1612 // is already set in the cloned array. |
1635 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 1613 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
1636 | 1614 |
1637 if (!result_saved) { | 1615 if (!result_saved) { |
1638 __ push(eax); // array literal. | 1616 PushOperand(eax); // array literal. |
1639 result_saved = true; | 1617 result_saved = true; |
1640 } | 1618 } |
1641 VisitForAccumulatorValue(subexpr); | 1619 VisitForAccumulatorValue(subexpr); |
1642 | 1620 |
1643 __ mov(StoreDescriptor::NameRegister(), | 1621 __ mov(StoreDescriptor::NameRegister(), |
1644 Immediate(Smi::FromInt(array_index))); | 1622 Immediate(Smi::FromInt(array_index))); |
1645 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); | 1623 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); |
1646 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); | 1624 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); |
1647 Handle<Code> ic = | 1625 Handle<Code> ic = |
1648 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 1626 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
1649 CallIC(ic); | 1627 CallIC(ic); |
1650 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); | 1628 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); |
1651 } | 1629 } |
1652 | 1630 |
1653 // In case the array literal contains spread expressions it has two parts. The | 1631 // In case the array literal contains spread expressions it has two parts. The |
1654 // first part is the "static" array which has a literal index is handled | 1632 // first part is the "static" array which has a literal index is handled |
1655 // above. The second part is the part after the first spread expression | 1633 // above. The second part is the part after the first spread expression |
1656 // (inclusive) and these elements gets appended to the array. Note that the | 1634 // (inclusive) and these elements gets appended to the array. Note that the |
1657 // number elements an iterable produces is unknown ahead of time. | 1635 // number elements an iterable produces is unknown ahead of time. |
1658 if (array_index < length && result_saved) { | 1636 if (array_index < length && result_saved) { |
1659 __ Pop(eax); | 1637 PopOperand(eax); |
1660 result_saved = false; | 1638 result_saved = false; |
1661 } | 1639 } |
1662 for (; array_index < length; array_index++) { | 1640 for (; array_index < length; array_index++) { |
1663 Expression* subexpr = subexprs->at(array_index); | 1641 Expression* subexpr = subexprs->at(array_index); |
1664 | 1642 |
1665 __ Push(eax); | 1643 PushOperand(eax); |
1666 DCHECK(!subexpr->IsSpread()); | 1644 DCHECK(!subexpr->IsSpread()); |
1667 VisitForStackValue(subexpr); | 1645 VisitForStackValue(subexpr); |
1668 __ CallRuntime(Runtime::kAppendElement); | 1646 CallRuntimeWithOperands(Runtime::kAppendElement); |
1669 | 1647 |
1670 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); | 1648 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); |
1671 } | 1649 } |
1672 | 1650 |
1673 if (result_saved) { | 1651 if (result_saved) { |
1674 context()->PlugTOS(); | 1652 context()->PlugTOS(); |
1675 } else { | 1653 } else { |
1676 context()->Plug(eax); | 1654 context()->Plug(eax); |
1677 } | 1655 } |
1678 } | 1656 } |
(...skipping 11 matching lines...) Expand all Loading... |
1690 // Evaluate LHS expression. | 1668 // Evaluate LHS expression. |
1691 switch (assign_type) { | 1669 switch (assign_type) { |
1692 case VARIABLE: | 1670 case VARIABLE: |
1693 // Nothing to do here. | 1671 // Nothing to do here. |
1694 break; | 1672 break; |
1695 case NAMED_SUPER_PROPERTY: | 1673 case NAMED_SUPER_PROPERTY: |
1696 VisitForStackValue( | 1674 VisitForStackValue( |
1697 property->obj()->AsSuperPropertyReference()->this_var()); | 1675 property->obj()->AsSuperPropertyReference()->this_var()); |
1698 VisitForAccumulatorValue( | 1676 VisitForAccumulatorValue( |
1699 property->obj()->AsSuperPropertyReference()->home_object()); | 1677 property->obj()->AsSuperPropertyReference()->home_object()); |
1700 __ push(result_register()); | 1678 PushOperand(result_register()); |
1701 if (expr->is_compound()) { | 1679 if (expr->is_compound()) { |
1702 __ push(MemOperand(esp, kPointerSize)); | 1680 PushOperand(MemOperand(esp, kPointerSize)); |
1703 __ push(result_register()); | 1681 PushOperand(result_register()); |
1704 } | 1682 } |
1705 break; | 1683 break; |
1706 case NAMED_PROPERTY: | 1684 case NAMED_PROPERTY: |
1707 if (expr->is_compound()) { | 1685 if (expr->is_compound()) { |
1708 // We need the receiver both on the stack and in the register. | 1686 // We need the receiver both on the stack and in the register. |
1709 VisitForStackValue(property->obj()); | 1687 VisitForStackValue(property->obj()); |
1710 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | 1688 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
1711 } else { | 1689 } else { |
1712 VisitForStackValue(property->obj()); | 1690 VisitForStackValue(property->obj()); |
1713 } | 1691 } |
1714 break; | 1692 break; |
1715 case KEYED_SUPER_PROPERTY: | 1693 case KEYED_SUPER_PROPERTY: |
1716 VisitForStackValue( | 1694 VisitForStackValue( |
1717 property->obj()->AsSuperPropertyReference()->this_var()); | 1695 property->obj()->AsSuperPropertyReference()->this_var()); |
1718 VisitForStackValue( | 1696 VisitForStackValue( |
1719 property->obj()->AsSuperPropertyReference()->home_object()); | 1697 property->obj()->AsSuperPropertyReference()->home_object()); |
1720 VisitForAccumulatorValue(property->key()); | 1698 VisitForAccumulatorValue(property->key()); |
1721 __ Push(result_register()); | 1699 PushOperand(result_register()); |
1722 if (expr->is_compound()) { | 1700 if (expr->is_compound()) { |
1723 __ push(MemOperand(esp, 2 * kPointerSize)); | 1701 PushOperand(MemOperand(esp, 2 * kPointerSize)); |
1724 __ push(MemOperand(esp, 2 * kPointerSize)); | 1702 PushOperand(MemOperand(esp, 2 * kPointerSize)); |
1725 __ push(result_register()); | 1703 PushOperand(result_register()); |
1726 } | 1704 } |
1727 break; | 1705 break; |
1728 case KEYED_PROPERTY: { | 1706 case KEYED_PROPERTY: { |
1729 if (expr->is_compound()) { | 1707 if (expr->is_compound()) { |
1730 VisitForStackValue(property->obj()); | 1708 VisitForStackValue(property->obj()); |
1731 VisitForStackValue(property->key()); | 1709 VisitForStackValue(property->key()); |
1732 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, kPointerSize)); | 1710 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, kPointerSize)); |
1733 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); | 1711 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); |
1734 } else { | 1712 } else { |
1735 VisitForStackValue(property->obj()); | 1713 VisitForStackValue(property->obj()); |
(...skipping 26 matching lines...) Expand all Loading... |
1762 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 1740 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
1763 break; | 1741 break; |
1764 case KEYED_PROPERTY: | 1742 case KEYED_PROPERTY: |
1765 EmitKeyedPropertyLoad(property); | 1743 EmitKeyedPropertyLoad(property); |
1766 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 1744 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
1767 break; | 1745 break; |
1768 } | 1746 } |
1769 } | 1747 } |
1770 | 1748 |
1771 Token::Value op = expr->binary_op(); | 1749 Token::Value op = expr->binary_op(); |
1772 __ push(eax); // Left operand goes on the stack. | 1750 PushOperand(eax); // Left operand goes on the stack. |
1773 VisitForAccumulatorValue(expr->value()); | 1751 VisitForAccumulatorValue(expr->value()); |
1774 | 1752 |
1775 if (ShouldInlineSmiCase(op)) { | 1753 if (ShouldInlineSmiCase(op)) { |
1776 EmitInlineSmiBinaryOp(expr->binary_operation(), | 1754 EmitInlineSmiBinaryOp(expr->binary_operation(), |
1777 op, | 1755 op, |
1778 expr->target(), | 1756 expr->target(), |
1779 expr->value()); | 1757 expr->value()); |
1780 } else { | 1758 } else { |
1781 EmitBinaryOp(expr->binary_operation(), op); | 1759 EmitBinaryOp(expr->binary_operation(), op); |
1782 } | 1760 } |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1855 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, | 1833 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, |
1856 kDontSaveFPRegs); | 1834 kDontSaveFPRegs); |
1857 __ lea(ebx, Operand(ebp, StandardFrameConstants::kExpressionsOffset)); | 1835 __ lea(ebx, Operand(ebp, StandardFrameConstants::kExpressionsOffset)); |
1858 __ cmp(esp, ebx); | 1836 __ cmp(esp, ebx); |
1859 __ j(equal, &post_runtime); | 1837 __ j(equal, &post_runtime); |
1860 __ push(eax); // generator object | 1838 __ push(eax); // generator object |
1861 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 1839 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
1862 __ mov(context_register(), | 1840 __ mov(context_register(), |
1863 Operand(ebp, StandardFrameConstants::kContextOffset)); | 1841 Operand(ebp, StandardFrameConstants::kContextOffset)); |
1864 __ bind(&post_runtime); | 1842 __ bind(&post_runtime); |
1865 __ pop(result_register()); | 1843 PopOperand(result_register()); |
1866 EmitReturnSequence(); | 1844 EmitReturnSequence(); |
1867 | 1845 |
1868 __ bind(&resume); | 1846 __ bind(&resume); |
1869 context()->Plug(result_register()); | 1847 context()->Plug(result_register()); |
1870 break; | 1848 break; |
1871 } | 1849 } |
1872 | 1850 |
1873 case Yield::kFinal: { | 1851 case Yield::kFinal: { |
1874 // Pop value from top-of-stack slot, box result into result register. | 1852 // Pop value from top-of-stack slot, box result into result register. |
| 1853 OperandStackDepthDecrement(1); |
1875 EmitCreateIteratorResult(true); | 1854 EmitCreateIteratorResult(true); |
1876 EmitUnwindAndReturn(); | 1855 EmitUnwindAndReturn(); |
1877 break; | 1856 break; |
1878 } | 1857 } |
1879 | 1858 |
1880 case Yield::kDelegating: | 1859 case Yield::kDelegating: |
1881 UNREACHABLE(); | 1860 UNREACHABLE(); |
1882 } | 1861 } |
1883 } | 1862 } |
1884 | 1863 |
1885 | 1864 |
1886 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 1865 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
1887 Expression *value, | 1866 Expression *value, |
1888 JSGeneratorObject::ResumeMode resume_mode) { | 1867 JSGeneratorObject::ResumeMode resume_mode) { |
1889 // The value stays in eax, and is ultimately read by the resumed generator, as | 1868 // The value stays in eax, and is ultimately read by the resumed generator, as |
1890 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it | 1869 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it |
1891 // is read to throw the value when the resumed generator is already closed. | 1870 // is read to throw the value when the resumed generator is already closed. |
1892 // ebx will hold the generator object until the activation has been resumed. | 1871 // ebx will hold the generator object until the activation has been resumed. |
1893 VisitForStackValue(generator); | 1872 VisitForStackValue(generator); |
1894 VisitForAccumulatorValue(value); | 1873 VisitForAccumulatorValue(value); |
1895 __ pop(ebx); | 1874 PopOperand(ebx); |
1896 | 1875 |
1897 // Store input value into generator object. | 1876 // Store input value into generator object. |
1898 __ mov(FieldOperand(ebx, JSGeneratorObject::kInputOffset), result_register()); | 1877 __ mov(FieldOperand(ebx, JSGeneratorObject::kInputOffset), result_register()); |
1899 __ mov(ecx, result_register()); | 1878 __ mov(ecx, result_register()); |
1900 __ RecordWriteField(ebx, JSGeneratorObject::kInputOffset, ecx, edx, | 1879 __ RecordWriteField(ebx, JSGeneratorObject::kInputOffset, ecx, edx, |
1901 kDontSaveFPRegs); | 1880 kDontSaveFPRegs); |
1902 | 1881 |
1903 // Load suspended function and context. | 1882 // Load suspended function and context. |
1904 __ mov(esi, FieldOperand(ebx, JSGeneratorObject::kContextOffset)); | 1883 __ mov(esi, FieldOperand(ebx, JSGeneratorObject::kContextOffset)); |
1905 __ mov(edi, FieldOperand(ebx, JSGeneratorObject::kFunctionOffset)); | 1884 __ mov(edi, FieldOperand(ebx, JSGeneratorObject::kFunctionOffset)); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1967 __ push(result_register()); | 1946 __ push(result_register()); |
1968 __ Push(Smi::FromInt(resume_mode)); | 1947 __ Push(Smi::FromInt(resume_mode)); |
1969 __ CallRuntime(Runtime::kResumeJSGeneratorObject); | 1948 __ CallRuntime(Runtime::kResumeJSGeneratorObject); |
1970 // Not reached: the runtime call returns elsewhere. | 1949 // Not reached: the runtime call returns elsewhere. |
1971 __ Abort(kGeneratorFailedToResume); | 1950 __ Abort(kGeneratorFailedToResume); |
1972 | 1951 |
1973 __ bind(&done); | 1952 __ bind(&done); |
1974 context()->Plug(result_register()); | 1953 context()->Plug(result_register()); |
1975 } | 1954 } |
1976 | 1955 |
| 1956 void FullCodeGenerator::PushOperand(MemOperand operand) { |
| 1957 OperandStackDepthIncrement(1); |
| 1958 __ Push(operand); |
| 1959 } |
| 1960 |
| 1961 void FullCodeGenerator::EmitOperandStackDepthCheck() { |
| 1962 if (FLAG_debug_code) { |
| 1963 int expected_diff = StandardFrameConstants::kFixedFrameSizeFromFp + |
| 1964 operand_stack_depth_ * kPointerSize; |
| 1965 __ mov(eax, ebp); |
| 1966 __ sub(eax, esp); |
| 1967 __ cmp(eax, Immediate(expected_diff)); |
| 1968 __ Assert(equal, kUnexpectedStackDepth); |
| 1969 } |
| 1970 } |
1977 | 1971 |
1978 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { | 1972 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { |
1979 Label allocate, done_allocate; | 1973 Label allocate, done_allocate; |
1980 | 1974 |
1981 __ Allocate(JSIteratorResult::kSize, eax, ecx, edx, &allocate, TAG_OBJECT); | 1975 __ Allocate(JSIteratorResult::kSize, eax, ecx, edx, &allocate, TAG_OBJECT); |
1982 __ jmp(&done_allocate, Label::kNear); | 1976 __ jmp(&done_allocate, Label::kNear); |
1983 | 1977 |
1984 __ bind(&allocate); | 1978 __ bind(&allocate); |
1985 __ Push(Smi::FromInt(JSIteratorResult::kSize)); | 1979 __ Push(Smi::FromInt(JSIteratorResult::kSize)); |
1986 __ CallRuntime(Runtime::kAllocateInNewSpace); | 1980 __ CallRuntime(Runtime::kAllocateInNewSpace); |
(...skipping 19 matching lines...) Expand all Loading... |
2006 DCHECK(!key->value()->IsSmi()); | 2000 DCHECK(!key->value()->IsSmi()); |
2007 DCHECK(!prop->IsSuperAccess()); | 2001 DCHECK(!prop->IsSuperAccess()); |
2008 | 2002 |
2009 __ mov(LoadDescriptor::NameRegister(), Immediate(key->value())); | 2003 __ mov(LoadDescriptor::NameRegister(), Immediate(key->value())); |
2010 __ mov(LoadDescriptor::SlotRegister(), | 2004 __ mov(LoadDescriptor::SlotRegister(), |
2011 Immediate(SmiFromSlot(prop->PropertyFeedbackSlot()))); | 2005 Immediate(SmiFromSlot(prop->PropertyFeedbackSlot()))); |
2012 CallLoadIC(NOT_INSIDE_TYPEOF); | 2006 CallLoadIC(NOT_INSIDE_TYPEOF); |
2013 } | 2007 } |
2014 | 2008 |
2015 | 2009 |
2016 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { | |
2017 // Stack: receiver, home_object. | |
2018 SetExpressionPosition(prop); | |
2019 Literal* key = prop->key()->AsLiteral(); | |
2020 DCHECK(!key->value()->IsSmi()); | |
2021 DCHECK(prop->IsSuperAccess()); | |
2022 | |
2023 __ push(Immediate(key->value())); | |
2024 __ CallRuntime(Runtime::kLoadFromSuper); | |
2025 } | |
2026 | |
2027 | |
2028 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | |
2029 SetExpressionPosition(prop); | |
2030 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); | |
2031 __ mov(LoadDescriptor::SlotRegister(), | |
2032 Immediate(SmiFromSlot(prop->PropertyFeedbackSlot()))); | |
2033 CallIC(ic); | |
2034 } | |
2035 | |
2036 | |
2037 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { | |
2038 // Stack: receiver, home_object, key. | |
2039 SetExpressionPosition(prop); | |
2040 __ CallRuntime(Runtime::kLoadKeyedFromSuper); | |
2041 } | |
2042 | |
2043 | |
2044 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2010 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
2045 Token::Value op, | 2011 Token::Value op, |
2046 Expression* left, | 2012 Expression* left, |
2047 Expression* right) { | 2013 Expression* right) { |
2048 // Do combined smi check of the operands. Left operand is on the | 2014 // Do combined smi check of the operands. Left operand is on the |
2049 // stack. Right operand is in eax. | 2015 // stack. Right operand is in eax. |
2050 Label smi_case, done, stub_call; | 2016 Label smi_case, done, stub_call; |
2051 __ pop(edx); | 2017 PopOperand(edx); |
2052 __ mov(ecx, eax); | 2018 __ mov(ecx, eax); |
2053 __ or_(eax, edx); | 2019 __ or_(eax, edx); |
2054 JumpPatchSite patch_site(masm_); | 2020 JumpPatchSite patch_site(masm_); |
2055 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); | 2021 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); |
2056 | 2022 |
2057 __ bind(&stub_call); | 2023 __ bind(&stub_call); |
2058 __ mov(eax, ecx); | 2024 __ mov(eax, ecx); |
2059 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); | 2025 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); |
2060 CallIC(code, expr->BinaryOperationFeedbackId()); | 2026 CallIC(code, expr->BinaryOperationFeedbackId()); |
2061 patch_site.EmitPatchInfo(); | 2027 patch_site.EmitPatchInfo(); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2134 context()->Plug(eax); | 2100 context()->Plug(eax); |
2135 } | 2101 } |
2136 | 2102 |
2137 | 2103 |
2138 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) { | 2104 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) { |
2139 for (int i = 0; i < lit->properties()->length(); i++) { | 2105 for (int i = 0; i < lit->properties()->length(); i++) { |
2140 ObjectLiteral::Property* property = lit->properties()->at(i); | 2106 ObjectLiteral::Property* property = lit->properties()->at(i); |
2141 Expression* value = property->value(); | 2107 Expression* value = property->value(); |
2142 | 2108 |
2143 if (property->is_static()) { | 2109 if (property->is_static()) { |
2144 __ push(Operand(esp, kPointerSize)); // constructor | 2110 PushOperand(Operand(esp, kPointerSize)); // constructor |
2145 } else { | 2111 } else { |
2146 __ push(Operand(esp, 0)); // prototype | 2112 PushOperand(Operand(esp, 0)); // prototype |
2147 } | 2113 } |
2148 EmitPropertyKey(property, lit->GetIdForProperty(i)); | 2114 EmitPropertyKey(property, lit->GetIdForProperty(i)); |
2149 | 2115 |
2150 // The static prototype property is read only. We handle the non computed | 2116 // The static prototype property is read only. We handle the non computed |
2151 // property name case in the parser. Since this is the only case where we | 2117 // property name case in the parser. Since this is the only case where we |
2152 // need to check for an own read only property we special case this so we do | 2118 // need to check for an own read only property we special case this so we do |
2153 // not need to do this for every property. | 2119 // not need to do this for every property. |
2154 if (property->is_static() && property->is_computed_name()) { | 2120 if (property->is_static() && property->is_computed_name()) { |
2155 __ CallRuntime(Runtime::kThrowIfStaticPrototype); | 2121 __ CallRuntime(Runtime::kThrowIfStaticPrototype); |
2156 __ push(eax); | 2122 __ push(eax); |
2157 } | 2123 } |
2158 | 2124 |
2159 VisitForStackValue(value); | 2125 VisitForStackValue(value); |
2160 if (NeedsHomeObject(value)) { | 2126 if (NeedsHomeObject(value)) { |
2161 EmitSetHomeObject(value, 2, property->GetSlot()); | 2127 EmitSetHomeObject(value, 2, property->GetSlot()); |
2162 } | 2128 } |
2163 | 2129 |
2164 switch (property->kind()) { | 2130 switch (property->kind()) { |
2165 case ObjectLiteral::Property::CONSTANT: | 2131 case ObjectLiteral::Property::CONSTANT: |
2166 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 2132 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
2167 case ObjectLiteral::Property::PROTOTYPE: | 2133 case ObjectLiteral::Property::PROTOTYPE: |
2168 UNREACHABLE(); | 2134 UNREACHABLE(); |
2169 case ObjectLiteral::Property::COMPUTED: | 2135 case ObjectLiteral::Property::COMPUTED: |
2170 __ Push(Smi::FromInt(DONT_ENUM)); | 2136 PushOperand(Smi::FromInt(DONT_ENUM)); |
2171 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); | 2137 PushOperand(Smi::FromInt(property->NeedsSetFunctionName())); |
2172 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); | 2138 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral); |
2173 break; | 2139 break; |
2174 | 2140 |
2175 case ObjectLiteral::Property::GETTER: | 2141 case ObjectLiteral::Property::GETTER: |
2176 __ Push(Smi::FromInt(DONT_ENUM)); | 2142 PushOperand(Smi::FromInt(DONT_ENUM)); |
2177 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); | 2143 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked); |
2178 break; | 2144 break; |
2179 | 2145 |
2180 case ObjectLiteral::Property::SETTER: | 2146 case ObjectLiteral::Property::SETTER: |
2181 __ Push(Smi::FromInt(DONT_ENUM)); | 2147 PushOperand(Smi::FromInt(DONT_ENUM)); |
2182 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); | 2148 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked); |
2183 break; | 2149 break; |
2184 } | 2150 } |
2185 } | 2151 } |
2186 } | 2152 } |
2187 | 2153 |
2188 | 2154 |
2189 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { | 2155 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { |
2190 __ pop(edx); | 2156 PopOperand(edx); |
2191 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); | 2157 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); |
2192 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2158 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
2193 CallIC(code, expr->BinaryOperationFeedbackId()); | 2159 CallIC(code, expr->BinaryOperationFeedbackId()); |
2194 patch_site.EmitPatchInfo(); | 2160 patch_site.EmitPatchInfo(); |
2195 context()->Plug(eax); | 2161 context()->Plug(eax); |
2196 } | 2162 } |
2197 | 2163 |
2198 | 2164 |
2199 void FullCodeGenerator::EmitAssignment(Expression* expr, | 2165 void FullCodeGenerator::EmitAssignment(Expression* expr, |
2200 FeedbackVectorSlot slot) { | 2166 FeedbackVectorSlot slot) { |
2201 DCHECK(expr->IsValidReferenceExpressionOrThis()); | 2167 DCHECK(expr->IsValidReferenceExpressionOrThis()); |
2202 | 2168 |
2203 Property* prop = expr->AsProperty(); | 2169 Property* prop = expr->AsProperty(); |
2204 LhsKind assign_type = Property::GetAssignType(prop); | 2170 LhsKind assign_type = Property::GetAssignType(prop); |
2205 | 2171 |
2206 switch (assign_type) { | 2172 switch (assign_type) { |
2207 case VARIABLE: { | 2173 case VARIABLE: { |
2208 Variable* var = expr->AsVariableProxy()->var(); | 2174 Variable* var = expr->AsVariableProxy()->var(); |
2209 EffectContext context(this); | 2175 EffectContext context(this); |
2210 EmitVariableAssignment(var, Token::ASSIGN, slot); | 2176 EmitVariableAssignment(var, Token::ASSIGN, slot); |
2211 break; | 2177 break; |
2212 } | 2178 } |
2213 case NAMED_PROPERTY: { | 2179 case NAMED_PROPERTY: { |
2214 __ push(eax); // Preserve value. | 2180 PushOperand(eax); // Preserve value. |
2215 VisitForAccumulatorValue(prop->obj()); | 2181 VisitForAccumulatorValue(prop->obj()); |
2216 __ Move(StoreDescriptor::ReceiverRegister(), eax); | 2182 __ Move(StoreDescriptor::ReceiverRegister(), eax); |
2217 __ pop(StoreDescriptor::ValueRegister()); // Restore value. | 2183 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. |
2218 __ mov(StoreDescriptor::NameRegister(), | 2184 __ mov(StoreDescriptor::NameRegister(), |
2219 prop->key()->AsLiteral()->value()); | 2185 prop->key()->AsLiteral()->value()); |
2220 EmitLoadStoreICSlot(slot); | 2186 EmitLoadStoreICSlot(slot); |
2221 CallStoreIC(); | 2187 CallStoreIC(); |
2222 break; | 2188 break; |
2223 } | 2189 } |
2224 case NAMED_SUPER_PROPERTY: { | 2190 case NAMED_SUPER_PROPERTY: { |
2225 __ push(eax); | 2191 PushOperand(eax); |
2226 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 2192 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
2227 VisitForAccumulatorValue( | 2193 VisitForAccumulatorValue( |
2228 prop->obj()->AsSuperPropertyReference()->home_object()); | 2194 prop->obj()->AsSuperPropertyReference()->home_object()); |
2229 // stack: value, this; eax: home_object | 2195 // stack: value, this; eax: home_object |
2230 Register scratch = ecx; | 2196 Register scratch = ecx; |
2231 Register scratch2 = edx; | 2197 Register scratch2 = edx; |
2232 __ mov(scratch, result_register()); // home_object | 2198 __ mov(scratch, result_register()); // home_object |
2233 __ mov(eax, MemOperand(esp, kPointerSize)); // value | 2199 __ mov(eax, MemOperand(esp, kPointerSize)); // value |
2234 __ mov(scratch2, MemOperand(esp, 0)); // this | 2200 __ mov(scratch2, MemOperand(esp, 0)); // this |
2235 __ mov(MemOperand(esp, kPointerSize), scratch2); // this | 2201 __ mov(MemOperand(esp, kPointerSize), scratch2); // this |
2236 __ mov(MemOperand(esp, 0), scratch); // home_object | 2202 __ mov(MemOperand(esp, 0), scratch); // home_object |
2237 // stack: this, home_object. eax: value | 2203 // stack: this, home_object. eax: value |
2238 EmitNamedSuperPropertyStore(prop); | 2204 EmitNamedSuperPropertyStore(prop); |
2239 break; | 2205 break; |
2240 } | 2206 } |
2241 case KEYED_SUPER_PROPERTY: { | 2207 case KEYED_SUPER_PROPERTY: { |
2242 __ push(eax); | 2208 PushOperand(eax); |
2243 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 2209 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
2244 VisitForStackValue( | 2210 VisitForStackValue( |
2245 prop->obj()->AsSuperPropertyReference()->home_object()); | 2211 prop->obj()->AsSuperPropertyReference()->home_object()); |
2246 VisitForAccumulatorValue(prop->key()); | 2212 VisitForAccumulatorValue(prop->key()); |
2247 Register scratch = ecx; | 2213 Register scratch = ecx; |
2248 Register scratch2 = edx; | 2214 Register scratch2 = edx; |
2249 __ mov(scratch2, MemOperand(esp, 2 * kPointerSize)); // value | 2215 __ mov(scratch2, MemOperand(esp, 2 * kPointerSize)); // value |
2250 // stack: value, this, home_object; eax: key, edx: value | 2216 // stack: value, this, home_object; eax: key, edx: value |
2251 __ mov(scratch, MemOperand(esp, kPointerSize)); // this | 2217 __ mov(scratch, MemOperand(esp, kPointerSize)); // this |
2252 __ mov(MemOperand(esp, 2 * kPointerSize), scratch); | 2218 __ mov(MemOperand(esp, 2 * kPointerSize), scratch); |
2253 __ mov(scratch, MemOperand(esp, 0)); // home_object | 2219 __ mov(scratch, MemOperand(esp, 0)); // home_object |
2254 __ mov(MemOperand(esp, kPointerSize), scratch); | 2220 __ mov(MemOperand(esp, kPointerSize), scratch); |
2255 __ mov(MemOperand(esp, 0), eax); | 2221 __ mov(MemOperand(esp, 0), eax); |
2256 __ mov(eax, scratch2); | 2222 __ mov(eax, scratch2); |
2257 // stack: this, home_object, key; eax: value. | 2223 // stack: this, home_object, key; eax: value. |
2258 EmitKeyedSuperPropertyStore(prop); | 2224 EmitKeyedSuperPropertyStore(prop); |
2259 break; | 2225 break; |
2260 } | 2226 } |
2261 case KEYED_PROPERTY: { | 2227 case KEYED_PROPERTY: { |
2262 __ push(eax); // Preserve value. | 2228 PushOperand(eax); // Preserve value. |
2263 VisitForStackValue(prop->obj()); | 2229 VisitForStackValue(prop->obj()); |
2264 VisitForAccumulatorValue(prop->key()); | 2230 VisitForAccumulatorValue(prop->key()); |
2265 __ Move(StoreDescriptor::NameRegister(), eax); | 2231 __ Move(StoreDescriptor::NameRegister(), eax); |
2266 __ pop(StoreDescriptor::ReceiverRegister()); // Receiver. | 2232 PopOperand(StoreDescriptor::ReceiverRegister()); // Receiver. |
2267 __ pop(StoreDescriptor::ValueRegister()); // Restore value. | 2233 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. |
2268 EmitLoadStoreICSlot(slot); | 2234 EmitLoadStoreICSlot(slot); |
2269 Handle<Code> ic = | 2235 Handle<Code> ic = |
2270 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2236 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
2271 CallIC(ic); | 2237 CallIC(ic); |
2272 break; | 2238 break; |
2273 } | 2239 } |
2274 } | 2240 } |
2275 context()->Plug(eax); | 2241 context()->Plug(eax); |
2276 } | 2242 } |
2277 | 2243 |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2394 | 2360 |
2395 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2361 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
2396 // Assignment to a property, using a named store IC. | 2362 // Assignment to a property, using a named store IC. |
2397 // eax : value | 2363 // eax : value |
2398 // esp[0] : receiver | 2364 // esp[0] : receiver |
2399 Property* prop = expr->target()->AsProperty(); | 2365 Property* prop = expr->target()->AsProperty(); |
2400 DCHECK(prop != NULL); | 2366 DCHECK(prop != NULL); |
2401 DCHECK(prop->key()->IsLiteral()); | 2367 DCHECK(prop->key()->IsLiteral()); |
2402 | 2368 |
2403 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); | 2369 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); |
2404 __ pop(StoreDescriptor::ReceiverRegister()); | 2370 PopOperand(StoreDescriptor::ReceiverRegister()); |
2405 EmitLoadStoreICSlot(expr->AssignmentSlot()); | 2371 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
2406 CallStoreIC(); | 2372 CallStoreIC(); |
2407 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2373 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2408 context()->Plug(eax); | 2374 context()->Plug(eax); |
2409 } | 2375 } |
2410 | 2376 |
2411 | 2377 |
2412 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { | 2378 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { |
2413 // Assignment to named property of super. | 2379 // Assignment to named property of super. |
2414 // eax : value | 2380 // eax : value |
2415 // stack : receiver ('this'), home_object | 2381 // stack : receiver ('this'), home_object |
2416 DCHECK(prop != NULL); | 2382 DCHECK(prop != NULL); |
2417 Literal* key = prop->key()->AsLiteral(); | 2383 Literal* key = prop->key()->AsLiteral(); |
2418 DCHECK(key != NULL); | 2384 DCHECK(key != NULL); |
2419 | 2385 |
2420 __ push(Immediate(key->value())); | 2386 PushOperand(key->value()); |
2421 __ push(eax); | 2387 PushOperand(eax); |
2422 __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict | 2388 CallRuntimeWithOperands(is_strict(language_mode()) |
2423 : Runtime::kStoreToSuper_Sloppy)); | 2389 ? Runtime::kStoreToSuper_Strict |
| 2390 : Runtime::kStoreToSuper_Sloppy); |
2424 } | 2391 } |
2425 | 2392 |
2426 | 2393 |
2427 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { | 2394 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { |
2428 // Assignment to named property of super. | 2395 // Assignment to named property of super. |
2429 // eax : value | 2396 // eax : value |
2430 // stack : receiver ('this'), home_object, key | 2397 // stack : receiver ('this'), home_object, key |
2431 | 2398 |
2432 __ push(eax); | 2399 PushOperand(eax); |
2433 __ CallRuntime((is_strict(language_mode()) | 2400 CallRuntimeWithOperands(is_strict(language_mode()) |
2434 ? Runtime::kStoreKeyedToSuper_Strict | 2401 ? Runtime::kStoreKeyedToSuper_Strict |
2435 : Runtime::kStoreKeyedToSuper_Sloppy)); | 2402 : Runtime::kStoreKeyedToSuper_Sloppy); |
2436 } | 2403 } |
2437 | 2404 |
2438 | 2405 |
2439 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2406 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
2440 // Assignment to a property, using a keyed store IC. | 2407 // Assignment to a property, using a keyed store IC. |
2441 // eax : value | 2408 // eax : value |
2442 // esp[0] : key | 2409 // esp[0] : key |
2443 // esp[kPointerSize] : receiver | 2410 // esp[kPointerSize] : receiver |
2444 | 2411 |
2445 __ pop(StoreDescriptor::NameRegister()); // Key. | 2412 PopOperand(StoreDescriptor::NameRegister()); // Key. |
2446 __ pop(StoreDescriptor::ReceiverRegister()); | 2413 PopOperand(StoreDescriptor::ReceiverRegister()); |
2447 DCHECK(StoreDescriptor::ValueRegister().is(eax)); | 2414 DCHECK(StoreDescriptor::ValueRegister().is(eax)); |
2448 Handle<Code> ic = | 2415 Handle<Code> ic = |
2449 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2416 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
2450 EmitLoadStoreICSlot(expr->AssignmentSlot()); | 2417 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
2451 CallIC(ic); | 2418 CallIC(ic); |
2452 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2419 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2453 context()->Plug(eax); | 2420 context()->Plug(eax); |
2454 } | 2421 } |
2455 | 2422 |
2456 | 2423 |
(...skipping 11 matching lines...) Expand all Loading... |
2468 } else { | 2435 } else { |
2469 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); | 2436 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); |
2470 VisitForStackValue( | 2437 VisitForStackValue( |
2471 expr->obj()->AsSuperPropertyReference()->home_object()); | 2438 expr->obj()->AsSuperPropertyReference()->home_object()); |
2472 EmitNamedSuperPropertyLoad(expr); | 2439 EmitNamedSuperPropertyLoad(expr); |
2473 } | 2440 } |
2474 } else { | 2441 } else { |
2475 if (!expr->IsSuperAccess()) { | 2442 if (!expr->IsSuperAccess()) { |
2476 VisitForStackValue(expr->obj()); | 2443 VisitForStackValue(expr->obj()); |
2477 VisitForAccumulatorValue(expr->key()); | 2444 VisitForAccumulatorValue(expr->key()); |
2478 __ pop(LoadDescriptor::ReceiverRegister()); // Object. | 2445 PopOperand(LoadDescriptor::ReceiverRegister()); // Object. |
2479 __ Move(LoadDescriptor::NameRegister(), result_register()); // Key. | 2446 __ Move(LoadDescriptor::NameRegister(), result_register()); // Key. |
2480 EmitKeyedPropertyLoad(expr); | 2447 EmitKeyedPropertyLoad(expr); |
2481 } else { | 2448 } else { |
2482 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); | 2449 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); |
2483 VisitForStackValue( | 2450 VisitForStackValue( |
2484 expr->obj()->AsSuperPropertyReference()->home_object()); | 2451 expr->obj()->AsSuperPropertyReference()->home_object()); |
2485 VisitForStackValue(expr->key()); | 2452 VisitForStackValue(expr->key()); |
2486 EmitKeyedSuperPropertyLoad(expr); | 2453 EmitKeyedSuperPropertyLoad(expr); |
2487 } | 2454 } |
2488 } | 2455 } |
(...skipping 15 matching lines...) Expand all Loading... |
2504 | 2471 |
2505 // Get the target function. | 2472 // Get the target function. |
2506 ConvertReceiverMode convert_mode; | 2473 ConvertReceiverMode convert_mode; |
2507 if (callee->IsVariableProxy()) { | 2474 if (callee->IsVariableProxy()) { |
2508 { StackValueContext context(this); | 2475 { StackValueContext context(this); |
2509 EmitVariableLoad(callee->AsVariableProxy()); | 2476 EmitVariableLoad(callee->AsVariableProxy()); |
2510 PrepareForBailout(callee, NO_REGISTERS); | 2477 PrepareForBailout(callee, NO_REGISTERS); |
2511 } | 2478 } |
2512 // Push undefined as receiver. This is patched in the method prologue if it | 2479 // Push undefined as receiver. This is patched in the method prologue if it |
2513 // is a sloppy mode method. | 2480 // is a sloppy mode method. |
2514 __ push(Immediate(isolate()->factory()->undefined_value())); | 2481 PushOperand(isolate()->factory()->undefined_value()); |
2515 convert_mode = ConvertReceiverMode::kNullOrUndefined; | 2482 convert_mode = ConvertReceiverMode::kNullOrUndefined; |
2516 } else { | 2483 } else { |
2517 // Load the function from the receiver. | 2484 // Load the function from the receiver. |
2518 DCHECK(callee->IsProperty()); | 2485 DCHECK(callee->IsProperty()); |
2519 DCHECK(!callee->AsProperty()->IsSuperAccess()); | 2486 DCHECK(!callee->AsProperty()->IsSuperAccess()); |
2520 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | 2487 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
2521 EmitNamedPropertyLoad(callee->AsProperty()); | 2488 EmitNamedPropertyLoad(callee->AsProperty()); |
2522 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2489 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2523 // Push the target function under the receiver. | 2490 // Push the target function under the receiver. |
2524 __ push(Operand(esp, 0)); | 2491 PushOperand(Operand(esp, 0)); |
2525 __ mov(Operand(esp, kPointerSize), eax); | 2492 __ mov(Operand(esp, kPointerSize), eax); |
2526 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; | 2493 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; |
2527 } | 2494 } |
2528 | 2495 |
2529 EmitCall(expr, convert_mode); | 2496 EmitCall(expr, convert_mode); |
2530 } | 2497 } |
2531 | 2498 |
2532 | 2499 |
2533 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | 2500 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { |
2534 SetExpressionPosition(expr); | 2501 SetExpressionPosition(expr); |
2535 Expression* callee = expr->expression(); | 2502 Expression* callee = expr->expression(); |
2536 DCHECK(callee->IsProperty()); | 2503 DCHECK(callee->IsProperty()); |
2537 Property* prop = callee->AsProperty(); | 2504 Property* prop = callee->AsProperty(); |
2538 DCHECK(prop->IsSuperAccess()); | 2505 DCHECK(prop->IsSuperAccess()); |
2539 | 2506 |
2540 Literal* key = prop->key()->AsLiteral(); | 2507 Literal* key = prop->key()->AsLiteral(); |
2541 DCHECK(!key->value()->IsSmi()); | 2508 DCHECK(!key->value()->IsSmi()); |
2542 // Load the function from the receiver. | 2509 // Load the function from the receiver. |
2543 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | 2510 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); |
2544 VisitForStackValue(super_ref->home_object()); | 2511 VisitForStackValue(super_ref->home_object()); |
2545 VisitForAccumulatorValue(super_ref->this_var()); | 2512 VisitForAccumulatorValue(super_ref->this_var()); |
2546 __ push(eax); | 2513 PushOperand(eax); |
2547 __ push(eax); | 2514 PushOperand(eax); |
2548 __ push(Operand(esp, kPointerSize * 2)); | 2515 PushOperand(Operand(esp, kPointerSize * 2)); |
2549 __ push(Immediate(key->value())); | 2516 PushOperand(key->value()); |
2550 // Stack here: | 2517 // Stack here: |
2551 // - home_object | 2518 // - home_object |
2552 // - this (receiver) | 2519 // - this (receiver) |
2553 // - this (receiver) <-- LoadFromSuper will pop here and below. | 2520 // - this (receiver) <-- LoadFromSuper will pop here and below. |
2554 // - home_object | 2521 // - home_object |
2555 // - key | 2522 // - key |
2556 __ CallRuntime(Runtime::kLoadFromSuper); | 2523 CallRuntimeWithOperands(Runtime::kLoadFromSuper); |
2557 | 2524 |
2558 // Replace home_object with target function. | 2525 // Replace home_object with target function. |
2559 __ mov(Operand(esp, kPointerSize), eax); | 2526 __ mov(Operand(esp, kPointerSize), eax); |
2560 | 2527 |
2561 // Stack here: | 2528 // Stack here: |
2562 // - target function | 2529 // - target function |
2563 // - this (receiver) | 2530 // - this (receiver) |
2564 EmitCall(expr); | 2531 EmitCall(expr); |
2565 } | 2532 } |
2566 | 2533 |
2567 | 2534 |
2568 // Code common for calls using the IC. | 2535 // Code common for calls using the IC. |
2569 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 2536 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, |
2570 Expression* key) { | 2537 Expression* key) { |
2571 // Load the key. | 2538 // Load the key. |
2572 VisitForAccumulatorValue(key); | 2539 VisitForAccumulatorValue(key); |
2573 | 2540 |
2574 Expression* callee = expr->expression(); | 2541 Expression* callee = expr->expression(); |
2575 | 2542 |
2576 // Load the function from the receiver. | 2543 // Load the function from the receiver. |
2577 DCHECK(callee->IsProperty()); | 2544 DCHECK(callee->IsProperty()); |
2578 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | 2545 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
2579 __ mov(LoadDescriptor::NameRegister(), eax); | 2546 __ mov(LoadDescriptor::NameRegister(), eax); |
2580 EmitKeyedPropertyLoad(callee->AsProperty()); | 2547 EmitKeyedPropertyLoad(callee->AsProperty()); |
2581 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2548 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2582 | 2549 |
2583 // Push the target function under the receiver. | 2550 // Push the target function under the receiver. |
2584 __ push(Operand(esp, 0)); | 2551 PushOperand(Operand(esp, 0)); |
2585 __ mov(Operand(esp, kPointerSize), eax); | 2552 __ mov(Operand(esp, kPointerSize), eax); |
2586 | 2553 |
2587 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); | 2554 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); |
2588 } | 2555 } |
2589 | 2556 |
2590 | 2557 |
2591 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | 2558 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { |
2592 Expression* callee = expr->expression(); | 2559 Expression* callee = expr->expression(); |
2593 DCHECK(callee->IsProperty()); | 2560 DCHECK(callee->IsProperty()); |
2594 Property* prop = callee->AsProperty(); | 2561 Property* prop = callee->AsProperty(); |
2595 DCHECK(prop->IsSuperAccess()); | 2562 DCHECK(prop->IsSuperAccess()); |
2596 | 2563 |
2597 SetExpressionPosition(prop); | 2564 SetExpressionPosition(prop); |
2598 // Load the function from the receiver. | 2565 // Load the function from the receiver. |
2599 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | 2566 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); |
2600 VisitForStackValue(super_ref->home_object()); | 2567 VisitForStackValue(super_ref->home_object()); |
2601 VisitForAccumulatorValue(super_ref->this_var()); | 2568 VisitForAccumulatorValue(super_ref->this_var()); |
2602 __ push(eax); | 2569 PushOperand(eax); |
2603 __ push(eax); | 2570 PushOperand(eax); |
2604 __ push(Operand(esp, kPointerSize * 2)); | 2571 PushOperand(Operand(esp, kPointerSize * 2)); |
2605 VisitForStackValue(prop->key()); | 2572 VisitForStackValue(prop->key()); |
2606 // Stack here: | 2573 // Stack here: |
2607 // - home_object | 2574 // - home_object |
2608 // - this (receiver) | 2575 // - this (receiver) |
2609 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. | 2576 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. |
2610 // - home_object | 2577 // - home_object |
2611 // - key | 2578 // - key |
2612 __ CallRuntime(Runtime::kLoadKeyedFromSuper); | 2579 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); |
2613 | 2580 |
2614 // Replace home_object with target function. | 2581 // Replace home_object with target function. |
2615 __ mov(Operand(esp, kPointerSize), eax); | 2582 __ mov(Operand(esp, kPointerSize), eax); |
2616 | 2583 |
2617 // Stack here: | 2584 // Stack here: |
2618 // - target function | 2585 // - target function |
2619 // - this (receiver) | 2586 // - this (receiver) |
2620 EmitCall(expr); | 2587 EmitCall(expr); |
2621 } | 2588 } |
2622 | 2589 |
(...skipping 17 matching lines...) Expand all Loading... |
2640 EmitProfilingCounterHandlingForReturnSequence(true); | 2607 EmitProfilingCounterHandlingForReturnSequence(true); |
2641 } | 2608 } |
2642 Handle<Code> ic = | 2609 Handle<Code> ic = |
2643 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) | 2610 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) |
2644 .code(); | 2611 .code(); |
2645 __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot()))); | 2612 __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot()))); |
2646 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); | 2613 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); |
2647 // Don't assign a type feedback id to the IC, since type feedback is provided | 2614 // Don't assign a type feedback id to the IC, since type feedback is provided |
2648 // by the vector above. | 2615 // by the vector above. |
2649 CallIC(ic); | 2616 CallIC(ic); |
| 2617 OperandStackDepthDecrement(arg_count + 1); |
2650 | 2618 |
2651 RecordJSReturnSite(expr); | 2619 RecordJSReturnSite(expr); |
2652 | 2620 |
2653 // Restore context register. | 2621 // Restore context register. |
2654 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2622 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
2655 | 2623 |
2656 context()->DropAndPlug(1, eax); | 2624 context()->DropAndPlug(1, eax); |
2657 } | 2625 } |
2658 | 2626 |
2659 | 2627 |
(...skipping 27 matching lines...) Expand all Loading... |
2687 SetExpressionPosition(callee); | 2655 SetExpressionPosition(callee); |
2688 // Generate code for loading from variables potentially shadowed by | 2656 // Generate code for loading from variables potentially shadowed by |
2689 // eval-introduced variables. | 2657 // eval-introduced variables. |
2690 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); | 2658 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); |
2691 | 2659 |
2692 __ bind(&slow); | 2660 __ bind(&slow); |
2693 // Call the runtime to find the function to call (returned in eax) and | 2661 // Call the runtime to find the function to call (returned in eax) and |
2694 // the object holding it (returned in edx). | 2662 // the object holding it (returned in edx). |
2695 __ Push(callee->name()); | 2663 __ Push(callee->name()); |
2696 __ CallRuntime(Runtime::kLoadLookupSlotForCall); | 2664 __ CallRuntime(Runtime::kLoadLookupSlotForCall); |
2697 __ Push(eax); // Function. | 2665 PushOperand(eax); // Function. |
2698 __ Push(edx); // Receiver. | 2666 PushOperand(edx); // Receiver. |
2699 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); | 2667 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); |
2700 | 2668 |
2701 // If fast case code has been generated, emit code to push the function | 2669 // If fast case code has been generated, emit code to push the function |
2702 // and receiver and have the slow path jump around this code. | 2670 // and receiver and have the slow path jump around this code. |
2703 if (done.is_linked()) { | 2671 if (done.is_linked()) { |
2704 Label call; | 2672 Label call; |
2705 __ jmp(&call, Label::kNear); | 2673 __ jmp(&call, Label::kNear); |
2706 __ bind(&done); | 2674 __ bind(&done); |
2707 // Push function. | 2675 // Push function. |
2708 __ push(eax); | 2676 __ push(eax); |
2709 // The receiver is implicitly the global receiver. Indicate this by | 2677 // The receiver is implicitly the global receiver. Indicate this by |
2710 // passing the hole to the call function stub. | 2678 // passing the hole to the call function stub. |
2711 __ push(Immediate(isolate()->factory()->undefined_value())); | 2679 __ push(Immediate(isolate()->factory()->undefined_value())); |
2712 __ bind(&call); | 2680 __ bind(&call); |
2713 } | 2681 } |
2714 } else { | 2682 } else { |
2715 VisitForStackValue(callee); | 2683 VisitForStackValue(callee); |
2716 // refEnv.WithBaseObject() | 2684 // refEnv.WithBaseObject() |
2717 __ push(Immediate(isolate()->factory()->undefined_value())); | 2685 PushOperand(isolate()->factory()->undefined_value()); |
2718 } | 2686 } |
2719 } | 2687 } |
2720 | 2688 |
2721 | 2689 |
2722 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { | 2690 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { |
2723 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval | 2691 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval |
2724 // to resolve the function we need to call. Then we call the resolved | 2692 // to resolve the function we need to call. Then we call the resolved |
2725 // function using the given arguments. | 2693 // function using the given arguments. |
2726 ZoneList<Expression*>* args = expr->arguments(); | 2694 ZoneList<Expression*>* args = expr->arguments(); |
2727 int arg_count = args->length(); | 2695 int arg_count = args->length(); |
(...skipping 14 matching lines...) Expand all Loading... |
2742 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax); | 2710 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax); |
2743 | 2711 |
2744 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); | 2712 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); |
2745 | 2713 |
2746 SetCallPosition(expr); | 2714 SetCallPosition(expr); |
2747 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); | 2715 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); |
2748 __ Set(eax, arg_count); | 2716 __ Set(eax, arg_count); |
2749 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, | 2717 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, |
2750 expr->tail_call_mode()), | 2718 expr->tail_call_mode()), |
2751 RelocInfo::CODE_TARGET); | 2719 RelocInfo::CODE_TARGET); |
| 2720 OperandStackDepthDecrement(arg_count + 1); |
2752 RecordJSReturnSite(expr); | 2721 RecordJSReturnSite(expr); |
2753 // Restore context register. | 2722 // Restore context register. |
2754 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2723 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
2755 context()->DropAndPlug(1, eax); | 2724 context()->DropAndPlug(1, eax); |
2756 } | 2725 } |
2757 | 2726 |
2758 | 2727 |
2759 void FullCodeGenerator::VisitCallNew(CallNew* expr) { | 2728 void FullCodeGenerator::VisitCallNew(CallNew* expr) { |
2760 Comment cmnt(masm_, "[ CallNew"); | 2729 Comment cmnt(masm_, "[ CallNew"); |
2761 // According to ECMA-262, section 11.2.2, page 44, the function | 2730 // According to ECMA-262, section 11.2.2, page 44, the function |
(...skipping 20 matching lines...) Expand all Loading... |
2782 // Load function and argument count into edi and eax. | 2751 // Load function and argument count into edi and eax. |
2783 __ Move(eax, Immediate(arg_count)); | 2752 __ Move(eax, Immediate(arg_count)); |
2784 __ mov(edi, Operand(esp, arg_count * kPointerSize)); | 2753 __ mov(edi, Operand(esp, arg_count * kPointerSize)); |
2785 | 2754 |
2786 // Record call targets in unoptimized code. | 2755 // Record call targets in unoptimized code. |
2787 __ EmitLoadTypeFeedbackVector(ebx); | 2756 __ EmitLoadTypeFeedbackVector(ebx); |
2788 __ mov(edx, Immediate(SmiFromSlot(expr->CallNewFeedbackSlot()))); | 2757 __ mov(edx, Immediate(SmiFromSlot(expr->CallNewFeedbackSlot()))); |
2789 | 2758 |
2790 CallConstructStub stub(isolate()); | 2759 CallConstructStub stub(isolate()); |
2791 __ call(stub.GetCode(), RelocInfo::CODE_TARGET); | 2760 __ call(stub.GetCode(), RelocInfo::CODE_TARGET); |
| 2761 OperandStackDepthDecrement(arg_count + 1); |
2792 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); | 2762 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); |
2793 // Restore context register. | 2763 // Restore context register. |
2794 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2764 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
2795 context()->Plug(eax); | 2765 context()->Plug(eax); |
2796 } | 2766 } |
2797 | 2767 |
2798 | 2768 |
2799 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { | 2769 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { |
2800 SuperCallReference* super_call_ref = | 2770 SuperCallReference* super_call_ref = |
2801 expr->expression()->AsSuperCallReference(); | 2771 expr->expression()->AsSuperCallReference(); |
2802 DCHECK_NOT_NULL(super_call_ref); | 2772 DCHECK_NOT_NULL(super_call_ref); |
2803 | 2773 |
2804 // Push the super constructor target on the stack (may be null, | 2774 // Push the super constructor target on the stack (may be null, |
2805 // but the Construct builtin can deal with that properly). | 2775 // but the Construct builtin can deal with that properly). |
2806 VisitForAccumulatorValue(super_call_ref->this_function_var()); | 2776 VisitForAccumulatorValue(super_call_ref->this_function_var()); |
2807 __ AssertFunction(result_register()); | 2777 __ AssertFunction(result_register()); |
2808 __ mov(result_register(), | 2778 __ mov(result_register(), |
2809 FieldOperand(result_register(), HeapObject::kMapOffset)); | 2779 FieldOperand(result_register(), HeapObject::kMapOffset)); |
2810 __ Push(FieldOperand(result_register(), Map::kPrototypeOffset)); | 2780 PushOperand(FieldOperand(result_register(), Map::kPrototypeOffset)); |
2811 | 2781 |
2812 // Push the arguments ("left-to-right") on the stack. | 2782 // Push the arguments ("left-to-right") on the stack. |
2813 ZoneList<Expression*>* args = expr->arguments(); | 2783 ZoneList<Expression*>* args = expr->arguments(); |
2814 int arg_count = args->length(); | 2784 int arg_count = args->length(); |
2815 for (int i = 0; i < arg_count; i++) { | 2785 for (int i = 0; i < arg_count; i++) { |
2816 VisitForStackValue(args->at(i)); | 2786 VisitForStackValue(args->at(i)); |
2817 } | 2787 } |
2818 | 2788 |
2819 // Call the construct call builtin that handles allocation and | 2789 // Call the construct call builtin that handles allocation and |
2820 // constructor invocation. | 2790 // constructor invocation. |
2821 SetConstructCallPosition(expr); | 2791 SetConstructCallPosition(expr); |
2822 | 2792 |
2823 // Load new target into edx. | 2793 // Load new target into edx. |
2824 VisitForAccumulatorValue(super_call_ref->new_target_var()); | 2794 VisitForAccumulatorValue(super_call_ref->new_target_var()); |
2825 __ mov(edx, result_register()); | 2795 __ mov(edx, result_register()); |
2826 | 2796 |
2827 // Load function and argument count into edi and eax. | 2797 // Load function and argument count into edi and eax. |
2828 __ Move(eax, Immediate(arg_count)); | 2798 __ Move(eax, Immediate(arg_count)); |
2829 __ mov(edi, Operand(esp, arg_count * kPointerSize)); | 2799 __ mov(edi, Operand(esp, arg_count * kPointerSize)); |
2830 | 2800 |
2831 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 2801 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
| 2802 OperandStackDepthDecrement(arg_count + 1); |
2832 | 2803 |
2833 RecordJSReturnSite(expr); | 2804 RecordJSReturnSite(expr); |
2834 | 2805 |
2835 // Restore context register. | 2806 // Restore context register. |
2836 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2807 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
2837 context()->Plug(eax); | 2808 context()->Plug(eax); |
2838 } | 2809 } |
2839 | 2810 |
2840 | 2811 |
2841 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 2812 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3042 DCHECK_EQ(3, args->length()); | 3013 DCHECK_EQ(3, args->length()); |
3043 | 3014 |
3044 Register string = eax; | 3015 Register string = eax; |
3045 Register index = ebx; | 3016 Register index = ebx; |
3046 Register value = ecx; | 3017 Register value = ecx; |
3047 | 3018 |
3048 VisitForStackValue(args->at(0)); // index | 3019 VisitForStackValue(args->at(0)); // index |
3049 VisitForStackValue(args->at(1)); // value | 3020 VisitForStackValue(args->at(1)); // value |
3050 VisitForAccumulatorValue(args->at(2)); // string | 3021 VisitForAccumulatorValue(args->at(2)); // string |
3051 | 3022 |
3052 __ pop(value); | 3023 PopOperand(value); |
3053 __ pop(index); | 3024 PopOperand(index); |
3054 | 3025 |
3055 if (FLAG_debug_code) { | 3026 if (FLAG_debug_code) { |
3056 __ test(value, Immediate(kSmiTagMask)); | 3027 __ test(value, Immediate(kSmiTagMask)); |
3057 __ Check(zero, kNonSmiValue); | 3028 __ Check(zero, kNonSmiValue); |
3058 __ test(index, Immediate(kSmiTagMask)); | 3029 __ test(index, Immediate(kSmiTagMask)); |
3059 __ Check(zero, kNonSmiValue); | 3030 __ Check(zero, kNonSmiValue); |
3060 } | 3031 } |
3061 | 3032 |
3062 __ SmiUntag(value); | 3033 __ SmiUntag(value); |
3063 __ SmiUntag(index); | 3034 __ SmiUntag(index); |
(...skipping 13 matching lines...) Expand all Loading... |
3077 ZoneList<Expression*>* args = expr->arguments(); | 3048 ZoneList<Expression*>* args = expr->arguments(); |
3078 DCHECK_EQ(3, args->length()); | 3049 DCHECK_EQ(3, args->length()); |
3079 | 3050 |
3080 Register string = eax; | 3051 Register string = eax; |
3081 Register index = ebx; | 3052 Register index = ebx; |
3082 Register value = ecx; | 3053 Register value = ecx; |
3083 | 3054 |
3084 VisitForStackValue(args->at(0)); // index | 3055 VisitForStackValue(args->at(0)); // index |
3085 VisitForStackValue(args->at(1)); // value | 3056 VisitForStackValue(args->at(1)); // value |
3086 VisitForAccumulatorValue(args->at(2)); // string | 3057 VisitForAccumulatorValue(args->at(2)); // string |
3087 __ pop(value); | 3058 PopOperand(value); |
3088 __ pop(index); | 3059 PopOperand(index); |
3089 | 3060 |
3090 if (FLAG_debug_code) { | 3061 if (FLAG_debug_code) { |
3091 __ test(value, Immediate(kSmiTagMask)); | 3062 __ test(value, Immediate(kSmiTagMask)); |
3092 __ Check(zero, kNonSmiValue); | 3063 __ Check(zero, kNonSmiValue); |
3093 __ test(index, Immediate(kSmiTagMask)); | 3064 __ test(index, Immediate(kSmiTagMask)); |
3094 __ Check(zero, kNonSmiValue); | 3065 __ Check(zero, kNonSmiValue); |
3095 __ SmiUntag(index); | 3066 __ SmiUntag(index); |
3096 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; | 3067 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; |
3097 __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type); | 3068 __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type); |
3098 __ SmiTag(index); | 3069 __ SmiTag(index); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3146 ZoneList<Expression*>* args = expr->arguments(); | 3117 ZoneList<Expression*>* args = expr->arguments(); |
3147 DCHECK(args->length() == 2); | 3118 DCHECK(args->length() == 2); |
3148 | 3119 |
3149 VisitForStackValue(args->at(0)); | 3120 VisitForStackValue(args->at(0)); |
3150 VisitForAccumulatorValue(args->at(1)); | 3121 VisitForAccumulatorValue(args->at(1)); |
3151 | 3122 |
3152 Register object = ebx; | 3123 Register object = ebx; |
3153 Register index = eax; | 3124 Register index = eax; |
3154 Register result = edx; | 3125 Register result = edx; |
3155 | 3126 |
3156 __ pop(object); | 3127 PopOperand(object); |
3157 | 3128 |
3158 Label need_conversion; | 3129 Label need_conversion; |
3159 Label index_out_of_range; | 3130 Label index_out_of_range; |
3160 Label done; | 3131 Label done; |
3161 StringCharCodeAtGenerator generator(object, | 3132 StringCharCodeAtGenerator generator(object, |
3162 index, | 3133 index, |
3163 result, | 3134 result, |
3164 &need_conversion, | 3135 &need_conversion, |
3165 &need_conversion, | 3136 &need_conversion, |
3166 &index_out_of_range, | 3137 &index_out_of_range, |
(...skipping 26 matching lines...) Expand all Loading... |
3193 DCHECK(args->length() == 2); | 3164 DCHECK(args->length() == 2); |
3194 | 3165 |
3195 VisitForStackValue(args->at(0)); | 3166 VisitForStackValue(args->at(0)); |
3196 VisitForAccumulatorValue(args->at(1)); | 3167 VisitForAccumulatorValue(args->at(1)); |
3197 | 3168 |
3198 Register object = ebx; | 3169 Register object = ebx; |
3199 Register index = eax; | 3170 Register index = eax; |
3200 Register scratch = edx; | 3171 Register scratch = edx; |
3201 Register result = eax; | 3172 Register result = eax; |
3202 | 3173 |
3203 __ pop(object); | 3174 PopOperand(object); |
3204 | 3175 |
3205 Label need_conversion; | 3176 Label need_conversion; |
3206 Label index_out_of_range; | 3177 Label index_out_of_range; |
3207 Label done; | 3178 Label done; |
3208 StringCharAtGenerator generator(object, | 3179 StringCharAtGenerator generator(object, |
3209 index, | 3180 index, |
3210 scratch, | 3181 scratch, |
3211 result, | 3182 result, |
3212 &need_conversion, | 3183 &need_conversion, |
3213 &need_conversion, | 3184 &need_conversion, |
(...skipping 29 matching lines...) Expand all Loading... |
3243 for (Expression* const arg : *args) { | 3214 for (Expression* const arg : *args) { |
3244 VisitForStackValue(arg); | 3215 VisitForStackValue(arg); |
3245 } | 3216 } |
3246 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 3217 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
3247 // Move target to edi. | 3218 // Move target to edi. |
3248 int const argc = args->length() - 2; | 3219 int const argc = args->length() - 2; |
3249 __ mov(edi, Operand(esp, (argc + 1) * kPointerSize)); | 3220 __ mov(edi, Operand(esp, (argc + 1) * kPointerSize)); |
3250 // Call the target. | 3221 // Call the target. |
3251 __ mov(eax, Immediate(argc)); | 3222 __ mov(eax, Immediate(argc)); |
3252 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 3223 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 3224 OperandStackDepthDecrement(argc + 1); |
3253 // Restore context register. | 3225 // Restore context register. |
3254 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 3226 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
3255 // Discard the function left on TOS. | 3227 // Discard the function left on TOS. |
3256 context()->DropAndPlug(1, eax); | 3228 context()->DropAndPlug(1, eax); |
3257 } | 3229 } |
3258 | 3230 |
3259 | 3231 |
3260 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { | 3232 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { |
3261 ZoneList<Expression*>* args = expr->arguments(); | 3233 ZoneList<Expression*>* args = expr->arguments(); |
3262 DCHECK(args->length() == 1); | 3234 DCHECK(args->length() == 1); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3331 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), | 3303 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), |
3332 isolate()->factory()->empty_fixed_array()); | 3304 isolate()->factory()->empty_fixed_array()); |
3333 __ mov(FieldOperand(eax, JSObject::kElementsOffset), | 3305 __ mov(FieldOperand(eax, JSObject::kElementsOffset), |
3334 isolate()->factory()->empty_fixed_array()); | 3306 isolate()->factory()->empty_fixed_array()); |
3335 __ pop(FieldOperand(eax, JSIteratorResult::kDoneOffset)); | 3307 __ pop(FieldOperand(eax, JSIteratorResult::kDoneOffset)); |
3336 __ pop(FieldOperand(eax, JSIteratorResult::kValueOffset)); | 3308 __ pop(FieldOperand(eax, JSIteratorResult::kValueOffset)); |
3337 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); | 3309 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); |
3338 __ jmp(&done, Label::kNear); | 3310 __ jmp(&done, Label::kNear); |
3339 | 3311 |
3340 __ bind(&runtime); | 3312 __ bind(&runtime); |
3341 __ CallRuntime(Runtime::kCreateIterResultObject); | 3313 CallRuntimeWithOperands(Runtime::kCreateIterResultObject); |
3342 | 3314 |
3343 __ bind(&done); | 3315 __ bind(&done); |
3344 context()->Plug(eax); | 3316 context()->Plug(eax); |
3345 } | 3317 } |
3346 | 3318 |
3347 | 3319 |
3348 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { | 3320 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
3349 // Push undefined as receiver. | 3321 // Push undefined as receiver. |
3350 __ push(Immediate(isolate()->factory()->undefined_value())); | 3322 PushOperand(isolate()->factory()->undefined_value()); |
3351 | 3323 |
3352 __ LoadGlobalFunction(expr->context_index(), eax); | 3324 __ LoadGlobalFunction(expr->context_index(), eax); |
3353 } | 3325 } |
3354 | 3326 |
3355 | 3327 |
3356 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 3328 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
3357 ZoneList<Expression*>* args = expr->arguments(); | 3329 ZoneList<Expression*>* args = expr->arguments(); |
3358 int arg_count = args->length(); | 3330 int arg_count = args->length(); |
3359 | 3331 |
3360 SetCallPosition(expr); | 3332 SetCallPosition(expr); |
3361 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); | 3333 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); |
3362 __ Set(eax, arg_count); | 3334 __ Set(eax, arg_count); |
3363 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), | 3335 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), |
3364 RelocInfo::CODE_TARGET); | 3336 RelocInfo::CODE_TARGET); |
| 3337 OperandStackDepthDecrement(arg_count + 1); |
3365 } | 3338 } |
3366 | 3339 |
3367 | 3340 |
3368 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 3341 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
3369 ZoneList<Expression*>* args = expr->arguments(); | 3342 ZoneList<Expression*>* args = expr->arguments(); |
3370 int arg_count = args->length(); | 3343 int arg_count = args->length(); |
3371 | 3344 |
3372 if (expr->is_jsruntime()) { | 3345 if (expr->is_jsruntime()) { |
3373 Comment cmnt(masm_, "[ CallRuntime"); | 3346 Comment cmnt(masm_, "[ CallRuntime"); |
3374 EmitLoadJSRuntimeFunction(expr); | 3347 EmitLoadJSRuntimeFunction(expr); |
3375 | 3348 |
3376 // Push the target function under the receiver. | 3349 // Push the target function under the receiver. |
3377 __ push(Operand(esp, 0)); | 3350 PushOperand(Operand(esp, 0)); |
3378 __ mov(Operand(esp, kPointerSize), eax); | 3351 __ mov(Operand(esp, kPointerSize), eax); |
3379 | 3352 |
3380 // Push the arguments ("left-to-right"). | 3353 // Push the arguments ("left-to-right"). |
3381 for (int i = 0; i < arg_count; i++) { | 3354 for (int i = 0; i < arg_count; i++) { |
3382 VisitForStackValue(args->at(i)); | 3355 VisitForStackValue(args->at(i)); |
3383 } | 3356 } |
3384 | 3357 |
3385 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 3358 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
3386 EmitCallJSRuntimeFunction(expr); | 3359 EmitCallJSRuntimeFunction(expr); |
3387 | 3360 |
(...skipping 14 matching lines...) Expand all Loading... |
3402 default: { | 3375 default: { |
3403 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic"); | 3376 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic"); |
3404 // Push the arguments ("left-to-right"). | 3377 // Push the arguments ("left-to-right"). |
3405 for (int i = 0; i < arg_count; i++) { | 3378 for (int i = 0; i < arg_count; i++) { |
3406 VisitForStackValue(args->at(i)); | 3379 VisitForStackValue(args->at(i)); |
3407 } | 3380 } |
3408 | 3381 |
3409 // Call the C runtime function. | 3382 // Call the C runtime function. |
3410 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 3383 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
3411 __ CallRuntime(expr->function(), arg_count); | 3384 __ CallRuntime(expr->function(), arg_count); |
| 3385 OperandStackDepthDecrement(arg_count); |
3412 context()->Plug(eax); | 3386 context()->Plug(eax); |
3413 } | 3387 } |
3414 } | 3388 } |
3415 } | 3389 } |
3416 } | 3390 } |
3417 | 3391 |
3418 | 3392 |
3419 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 3393 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
3420 switch (expr->op()) { | 3394 switch (expr->op()) { |
3421 case Token::DELETE: { | 3395 case Token::DELETE: { |
3422 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); | 3396 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); |
3423 Property* property = expr->expression()->AsProperty(); | 3397 Property* property = expr->expression()->AsProperty(); |
3424 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 3398 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
3425 | 3399 |
3426 if (property != NULL) { | 3400 if (property != NULL) { |
3427 VisitForStackValue(property->obj()); | 3401 VisitForStackValue(property->obj()); |
3428 VisitForStackValue(property->key()); | 3402 VisitForStackValue(property->key()); |
3429 __ CallRuntime(is_strict(language_mode()) | 3403 CallRuntimeWithOperands(is_strict(language_mode()) |
3430 ? Runtime::kDeleteProperty_Strict | 3404 ? Runtime::kDeleteProperty_Strict |
3431 : Runtime::kDeleteProperty_Sloppy); | 3405 : Runtime::kDeleteProperty_Sloppy); |
3432 context()->Plug(eax); | 3406 context()->Plug(eax); |
3433 } else if (proxy != NULL) { | 3407 } else if (proxy != NULL) { |
3434 Variable* var = proxy->var(); | 3408 Variable* var = proxy->var(); |
3435 // Delete of an unqualified identifier is disallowed in strict mode but | 3409 // Delete of an unqualified identifier is disallowed in strict mode but |
3436 // "delete this" is allowed. | 3410 // "delete this" is allowed. |
3437 bool is_this = var->HasThisName(isolate()); | 3411 bool is_this = var->HasThisName(isolate()); |
3438 DCHECK(is_sloppy(language_mode()) || is_this); | 3412 DCHECK(is_sloppy(language_mode()) || is_this); |
3439 if (var->IsUnallocatedOrGlobalSlot()) { | 3413 if (var->IsUnallocatedOrGlobalSlot()) { |
3440 __ mov(eax, NativeContextOperand()); | 3414 __ mov(eax, NativeContextOperand()); |
3441 __ push(ContextOperand(eax, Context::EXTENSION_INDEX)); | 3415 __ push(ContextOperand(eax, Context::EXTENSION_INDEX)); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3488 // We handle value contexts explicitly rather than simply visiting | 3462 // We handle value contexts explicitly rather than simply visiting |
3489 // for control and plugging the control flow into the context, | 3463 // for control and plugging the control flow into the context, |
3490 // because we need to prepare a pair of extra administrative AST ids | 3464 // because we need to prepare a pair of extra administrative AST ids |
3491 // for the optimizing compiler. | 3465 // for the optimizing compiler. |
3492 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); | 3466 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); |
3493 Label materialize_true, materialize_false, done; | 3467 Label materialize_true, materialize_false, done; |
3494 VisitForControl(expr->expression(), | 3468 VisitForControl(expr->expression(), |
3495 &materialize_false, | 3469 &materialize_false, |
3496 &materialize_true, | 3470 &materialize_true, |
3497 &materialize_true); | 3471 &materialize_true); |
| 3472 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1); |
3498 __ bind(&materialize_true); | 3473 __ bind(&materialize_true); |
3499 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); | 3474 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); |
3500 if (context()->IsAccumulatorValue()) { | 3475 if (context()->IsAccumulatorValue()) { |
3501 __ mov(eax, isolate()->factory()->true_value()); | 3476 __ mov(eax, isolate()->factory()->true_value()); |
3502 } else { | 3477 } else { |
3503 __ Push(isolate()->factory()->true_value()); | 3478 __ Push(isolate()->factory()->true_value()); |
3504 } | 3479 } |
3505 __ jmp(&done, Label::kNear); | 3480 __ jmp(&done, Label::kNear); |
3506 __ bind(&materialize_false); | 3481 __ bind(&materialize_false); |
3507 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); | 3482 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3543 LhsKind assign_type = Property::GetAssignType(prop); | 3518 LhsKind assign_type = Property::GetAssignType(prop); |
3544 | 3519 |
3545 // Evaluate expression and get value. | 3520 // Evaluate expression and get value. |
3546 if (assign_type == VARIABLE) { | 3521 if (assign_type == VARIABLE) { |
3547 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 3522 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
3548 AccumulatorValueContext context(this); | 3523 AccumulatorValueContext context(this); |
3549 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 3524 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
3550 } else { | 3525 } else { |
3551 // Reserve space for result of postfix operation. | 3526 // Reserve space for result of postfix operation. |
3552 if (expr->is_postfix() && !context()->IsEffect()) { | 3527 if (expr->is_postfix() && !context()->IsEffect()) { |
3553 __ push(Immediate(Smi::FromInt(0))); | 3528 PushOperand(Smi::FromInt(0)); |
3554 } | 3529 } |
3555 switch (assign_type) { | 3530 switch (assign_type) { |
3556 case NAMED_PROPERTY: { | 3531 case NAMED_PROPERTY: { |
3557 // Put the object both on the stack and in the register. | 3532 // Put the object both on the stack and in the register. |
3558 VisitForStackValue(prop->obj()); | 3533 VisitForStackValue(prop->obj()); |
3559 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | 3534 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
3560 EmitNamedPropertyLoad(prop); | 3535 EmitNamedPropertyLoad(prop); |
3561 break; | 3536 break; |
3562 } | 3537 } |
3563 | 3538 |
3564 case NAMED_SUPER_PROPERTY: { | 3539 case NAMED_SUPER_PROPERTY: { |
3565 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 3540 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
3566 VisitForAccumulatorValue( | 3541 VisitForAccumulatorValue( |
3567 prop->obj()->AsSuperPropertyReference()->home_object()); | 3542 prop->obj()->AsSuperPropertyReference()->home_object()); |
3568 __ push(result_register()); | 3543 PushOperand(result_register()); |
3569 __ push(MemOperand(esp, kPointerSize)); | 3544 PushOperand(MemOperand(esp, kPointerSize)); |
3570 __ push(result_register()); | 3545 PushOperand(result_register()); |
3571 EmitNamedSuperPropertyLoad(prop); | 3546 EmitNamedSuperPropertyLoad(prop); |
3572 break; | 3547 break; |
3573 } | 3548 } |
3574 | 3549 |
3575 case KEYED_SUPER_PROPERTY: { | 3550 case KEYED_SUPER_PROPERTY: { |
3576 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 3551 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
3577 VisitForStackValue( | 3552 VisitForStackValue( |
3578 prop->obj()->AsSuperPropertyReference()->home_object()); | 3553 prop->obj()->AsSuperPropertyReference()->home_object()); |
3579 VisitForAccumulatorValue(prop->key()); | 3554 VisitForAccumulatorValue(prop->key()); |
3580 __ push(result_register()); | 3555 PushOperand(result_register()); |
3581 __ push(MemOperand(esp, 2 * kPointerSize)); | 3556 PushOperand(MemOperand(esp, 2 * kPointerSize)); |
3582 __ push(MemOperand(esp, 2 * kPointerSize)); | 3557 PushOperand(MemOperand(esp, 2 * kPointerSize)); |
3583 __ push(result_register()); | 3558 PushOperand(result_register()); |
3584 EmitKeyedSuperPropertyLoad(prop); | 3559 EmitKeyedSuperPropertyLoad(prop); |
3585 break; | 3560 break; |
3586 } | 3561 } |
3587 | 3562 |
3588 case KEYED_PROPERTY: { | 3563 case KEYED_PROPERTY: { |
3589 VisitForStackValue(prop->obj()); | 3564 VisitForStackValue(prop->obj()); |
3590 VisitForStackValue(prop->key()); | 3565 VisitForStackValue(prop->key()); |
3591 __ mov(LoadDescriptor::ReceiverRegister(), | 3566 __ mov(LoadDescriptor::ReceiverRegister(), |
3592 Operand(esp, kPointerSize)); // Object. | 3567 Operand(esp, kPointerSize)); // Object. |
3593 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); // Key. | 3568 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); // Key. |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3663 } | 3638 } |
3664 | 3639 |
3665 // Save result for postfix expressions. | 3640 // Save result for postfix expressions. |
3666 if (expr->is_postfix()) { | 3641 if (expr->is_postfix()) { |
3667 if (!context()->IsEffect()) { | 3642 if (!context()->IsEffect()) { |
3668 // Save the result on the stack. If we have a named or keyed property | 3643 // Save the result on the stack. If we have a named or keyed property |
3669 // we store the result under the receiver that is currently on top | 3644 // we store the result under the receiver that is currently on top |
3670 // of the stack. | 3645 // of the stack. |
3671 switch (assign_type) { | 3646 switch (assign_type) { |
3672 case VARIABLE: | 3647 case VARIABLE: |
3673 __ push(eax); | 3648 PushOperand(eax); |
3674 break; | 3649 break; |
3675 case NAMED_PROPERTY: | 3650 case NAMED_PROPERTY: |
3676 __ mov(Operand(esp, kPointerSize), eax); | 3651 __ mov(Operand(esp, kPointerSize), eax); |
3677 break; | 3652 break; |
3678 case NAMED_SUPER_PROPERTY: | 3653 case NAMED_SUPER_PROPERTY: |
3679 __ mov(Operand(esp, 2 * kPointerSize), eax); | 3654 __ mov(Operand(esp, 2 * kPointerSize), eax); |
3680 break; | 3655 break; |
3681 case KEYED_PROPERTY: | 3656 case KEYED_PROPERTY: |
3682 __ mov(Operand(esp, 2 * kPointerSize), eax); | 3657 __ mov(Operand(esp, 2 * kPointerSize), eax); |
3683 break; | 3658 break; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3723 // Perform the assignment as if via '='. | 3698 // Perform the assignment as if via '='. |
3724 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3699 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
3725 Token::ASSIGN, expr->CountSlot()); | 3700 Token::ASSIGN, expr->CountSlot()); |
3726 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3701 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3727 context()->Plug(eax); | 3702 context()->Plug(eax); |
3728 } | 3703 } |
3729 break; | 3704 break; |
3730 case NAMED_PROPERTY: { | 3705 case NAMED_PROPERTY: { |
3731 __ mov(StoreDescriptor::NameRegister(), | 3706 __ mov(StoreDescriptor::NameRegister(), |
3732 prop->key()->AsLiteral()->value()); | 3707 prop->key()->AsLiteral()->value()); |
3733 __ pop(StoreDescriptor::ReceiverRegister()); | 3708 PopOperand(StoreDescriptor::ReceiverRegister()); |
3734 EmitLoadStoreICSlot(expr->CountSlot()); | 3709 EmitLoadStoreICSlot(expr->CountSlot()); |
3735 CallStoreIC(); | 3710 CallStoreIC(); |
3736 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3711 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3737 if (expr->is_postfix()) { | 3712 if (expr->is_postfix()) { |
3738 if (!context()->IsEffect()) { | 3713 if (!context()->IsEffect()) { |
3739 context()->PlugTOS(); | 3714 context()->PlugTOS(); |
3740 } | 3715 } |
3741 } else { | 3716 } else { |
3742 context()->Plug(eax); | 3717 context()->Plug(eax); |
3743 } | 3718 } |
(...skipping 15 matching lines...) Expand all Loading... |
3759 if (expr->is_postfix()) { | 3734 if (expr->is_postfix()) { |
3760 if (!context()->IsEffect()) { | 3735 if (!context()->IsEffect()) { |
3761 context()->PlugTOS(); | 3736 context()->PlugTOS(); |
3762 } | 3737 } |
3763 } else { | 3738 } else { |
3764 context()->Plug(eax); | 3739 context()->Plug(eax); |
3765 } | 3740 } |
3766 break; | 3741 break; |
3767 } | 3742 } |
3768 case KEYED_PROPERTY: { | 3743 case KEYED_PROPERTY: { |
3769 __ pop(StoreDescriptor::NameRegister()); | 3744 PopOperand(StoreDescriptor::NameRegister()); |
3770 __ pop(StoreDescriptor::ReceiverRegister()); | 3745 PopOperand(StoreDescriptor::ReceiverRegister()); |
3771 Handle<Code> ic = | 3746 Handle<Code> ic = |
3772 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 3747 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
3773 EmitLoadStoreICSlot(expr->CountSlot()); | 3748 EmitLoadStoreICSlot(expr->CountSlot()); |
3774 CallIC(ic); | 3749 CallIC(ic); |
3775 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3750 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3776 if (expr->is_postfix()) { | 3751 if (expr->is_postfix()) { |
3777 // Result is on the stack | 3752 // Result is on the stack |
3778 if (!context()->IsEffect()) { | 3753 if (!context()->IsEffect()) { |
3779 context()->PlugTOS(); | 3754 context()->PlugTOS(); |
3780 } | 3755 } |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3881 Label* if_false = NULL; | 3856 Label* if_false = NULL; |
3882 Label* fall_through = NULL; | 3857 Label* fall_through = NULL; |
3883 context()->PrepareTest(&materialize_true, &materialize_false, | 3858 context()->PrepareTest(&materialize_true, &materialize_false, |
3884 &if_true, &if_false, &fall_through); | 3859 &if_true, &if_false, &fall_through); |
3885 | 3860 |
3886 Token::Value op = expr->op(); | 3861 Token::Value op = expr->op(); |
3887 VisitForStackValue(expr->left()); | 3862 VisitForStackValue(expr->left()); |
3888 switch (op) { | 3863 switch (op) { |
3889 case Token::IN: | 3864 case Token::IN: |
3890 VisitForStackValue(expr->right()); | 3865 VisitForStackValue(expr->right()); |
3891 __ CallRuntime(Runtime::kHasProperty); | 3866 CallRuntimeWithOperands(Runtime::kHasProperty); |
3892 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); | 3867 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); |
3893 __ cmp(eax, isolate()->factory()->true_value()); | 3868 __ cmp(eax, isolate()->factory()->true_value()); |
3894 Split(equal, if_true, if_false, fall_through); | 3869 Split(equal, if_true, if_false, fall_through); |
3895 break; | 3870 break; |
3896 | 3871 |
3897 case Token::INSTANCEOF: { | 3872 case Token::INSTANCEOF: { |
3898 VisitForAccumulatorValue(expr->right()); | 3873 VisitForAccumulatorValue(expr->right()); |
3899 __ Pop(edx); | 3874 PopOperand(edx); |
3900 InstanceOfStub stub(isolate()); | 3875 InstanceOfStub stub(isolate()); |
3901 __ CallStub(&stub); | 3876 __ CallStub(&stub); |
3902 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); | 3877 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); |
3903 __ cmp(eax, isolate()->factory()->true_value()); | 3878 __ cmp(eax, isolate()->factory()->true_value()); |
3904 Split(equal, if_true, if_false, fall_through); | 3879 Split(equal, if_true, if_false, fall_through); |
3905 break; | 3880 break; |
3906 } | 3881 } |
3907 | 3882 |
3908 default: { | 3883 default: { |
3909 VisitForAccumulatorValue(expr->right()); | 3884 VisitForAccumulatorValue(expr->right()); |
3910 Condition cc = CompareIC::ComputeCondition(op); | 3885 Condition cc = CompareIC::ComputeCondition(op); |
3911 __ pop(edx); | 3886 PopOperand(edx); |
3912 | 3887 |
3913 bool inline_smi_code = ShouldInlineSmiCase(op); | 3888 bool inline_smi_code = ShouldInlineSmiCase(op); |
3914 JumpPatchSite patch_site(masm_); | 3889 JumpPatchSite patch_site(masm_); |
3915 if (inline_smi_code) { | 3890 if (inline_smi_code) { |
3916 Label slow_case; | 3891 Label slow_case; |
3917 __ mov(ecx, edx); | 3892 __ mov(ecx, edx); |
3918 __ or_(ecx, eax); | 3893 __ or_(ecx, eax); |
3919 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); | 3894 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); |
3920 __ cmp(edx, eax); | 3895 __ cmp(edx, eax); |
3921 Split(cc, if_true, if_false, NULL); | 3896 Split(cc, if_true, if_false, NULL); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3995 | 3970 |
3996 | 3971 |
3997 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() { | 3972 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() { |
3998 Scope* closure_scope = scope()->ClosureScope(); | 3973 Scope* closure_scope = scope()->ClosureScope(); |
3999 if (closure_scope->is_script_scope() || | 3974 if (closure_scope->is_script_scope() || |
4000 closure_scope->is_module_scope()) { | 3975 closure_scope->is_module_scope()) { |
4001 // Contexts nested in the native context have a canonical empty function | 3976 // Contexts nested in the native context have a canonical empty function |
4002 // as their closure, not the anonymous closure containing the global | 3977 // as their closure, not the anonymous closure containing the global |
4003 // code. | 3978 // code. |
4004 __ mov(eax, NativeContextOperand()); | 3979 __ mov(eax, NativeContextOperand()); |
4005 __ push(ContextOperand(eax, Context::CLOSURE_INDEX)); | 3980 PushOperand(ContextOperand(eax, Context::CLOSURE_INDEX)); |
4006 } else if (closure_scope->is_eval_scope()) { | 3981 } else if (closure_scope->is_eval_scope()) { |
4007 // Contexts nested inside eval code have the same closure as the context | 3982 // Contexts nested inside eval code have the same closure as the context |
4008 // calling eval, not the anonymous closure containing the eval code. | 3983 // calling eval, not the anonymous closure containing the eval code. |
4009 // Fetch it from the context. | 3984 // Fetch it from the context. |
4010 __ push(ContextOperand(esi, Context::CLOSURE_INDEX)); | 3985 PushOperand(ContextOperand(esi, Context::CLOSURE_INDEX)); |
4011 } else { | 3986 } else { |
4012 DCHECK(closure_scope->is_function_scope()); | 3987 DCHECK(closure_scope->is_function_scope()); |
4013 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 3988 PushOperand(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
4014 } | 3989 } |
4015 } | 3990 } |
4016 | 3991 |
4017 | 3992 |
4018 // ---------------------------------------------------------------------------- | 3993 // ---------------------------------------------------------------------------- |
4019 // Non-local control flow support. | 3994 // Non-local control flow support. |
4020 | 3995 |
4021 void FullCodeGenerator::EnterFinallyBlock() { | 3996 void FullCodeGenerator::EnterFinallyBlock() { |
4022 // Store pending message while executing finally block. | 3997 // Store pending message while executing finally block. |
4023 ExternalReference pending_message_obj = | 3998 ExternalReference pending_message_obj = |
4024 ExternalReference::address_of_pending_message_obj(isolate()); | 3999 ExternalReference::address_of_pending_message_obj(isolate()); |
4025 __ mov(edx, Operand::StaticVariable(pending_message_obj)); | 4000 __ mov(edx, Operand::StaticVariable(pending_message_obj)); |
4026 __ push(edx); | 4001 PushOperand(edx); |
4027 | 4002 |
4028 ClearPendingMessage(); | 4003 ClearPendingMessage(); |
4029 } | 4004 } |
4030 | 4005 |
4031 | 4006 |
4032 void FullCodeGenerator::ExitFinallyBlock() { | 4007 void FullCodeGenerator::ExitFinallyBlock() { |
4033 DCHECK(!result_register().is(edx)); | 4008 DCHECK(!result_register().is(edx)); |
4034 // Restore pending message from stack. | 4009 // Restore pending message from stack. |
4035 __ pop(edx); | 4010 PopOperand(edx); |
4036 ExternalReference pending_message_obj = | 4011 ExternalReference pending_message_obj = |
4037 ExternalReference::address_of_pending_message_obj(isolate()); | 4012 ExternalReference::address_of_pending_message_obj(isolate()); |
4038 __ mov(Operand::StaticVariable(pending_message_obj), edx); | 4013 __ mov(Operand::StaticVariable(pending_message_obj), edx); |
4039 } | 4014 } |
4040 | 4015 |
4041 | 4016 |
4042 void FullCodeGenerator::ClearPendingMessage() { | 4017 void FullCodeGenerator::ClearPendingMessage() { |
4043 DCHECK(!result_register().is(edx)); | 4018 DCHECK(!result_register().is(edx)); |
4044 ExternalReference pending_message_obj = | 4019 ExternalReference pending_message_obj = |
4045 ExternalReference::address_of_pending_message_obj(isolate()); | 4020 ExternalReference::address_of_pending_message_obj(isolate()); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4158 Assembler::target_address_at(call_target_address, | 4133 Assembler::target_address_at(call_target_address, |
4159 unoptimized_code)); | 4134 unoptimized_code)); |
4160 return OSR_AFTER_STACK_CHECK; | 4135 return OSR_AFTER_STACK_CHECK; |
4161 } | 4136 } |
4162 | 4137 |
4163 | 4138 |
4164 } // namespace internal | 4139 } // namespace internal |
4165 } // namespace v8 | 4140 } // namespace v8 |
4166 | 4141 |
4167 #endif // V8_TARGET_ARCH_IA32 | 4142 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |