Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(120)

Side by Side Diff: src/full-codegen/x87/full-codegen-x87.cc

Issue 1728953003: X87: [fullcodegen] Implement operand stack depth tracking. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_X87 5 #if V8_TARGET_ARCH_X87
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
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 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 int arguments_bytes = arg_count * kPointerSize; 422 int arguments_bytes = arg_count * kPointerSize;
422 __ Ret(arguments_bytes, ecx); 423 __ Ret(arguments_bytes, ecx);
423 } 424 }
424 } 425 }
425 426
426 427
427 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { 428 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const {
428 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 429 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
429 MemOperand operand = codegen()->VarOperand(var, result_register()); 430 MemOperand operand = codegen()->VarOperand(var, result_register());
430 // Memory operands can be pushed directly. 431 // Memory operands can be pushed directly.
431 __ push(operand); 432 codegen()->PushOperand(operand);
432 } 433 }
433 434
434 435
435 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { 436 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const {
436 UNREACHABLE(); // Not used on X87. 437 UNREACHABLE(); // Not used on X87.
437 } 438 }
438 439
439 440
440 void FullCodeGenerator::AccumulatorValueContext::Plug( 441 void FullCodeGenerator::AccumulatorValueContext::Plug(
441 Heap::RootListIndex index) const { 442 Heap::RootListIndex index) const {
(...skipping 20 matching lines...) Expand all
462 Handle<Object> lit) const { 463 Handle<Object> lit) const {
463 if (lit->IsSmi()) { 464 if (lit->IsSmi()) {
464 __ SafeMove(result_register(), Immediate(lit)); 465 __ SafeMove(result_register(), Immediate(lit));
465 } else { 466 } else {
466 __ Move(result_register(), Immediate(lit)); 467 __ Move(result_register(), Immediate(lit));
467 } 468 }
468 } 469 }
469 470
470 471
471 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { 472 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const {
473 codegen()->OperandStackDepthIncrement(1);
472 if (lit->IsSmi()) { 474 if (lit->IsSmi()) {
473 __ SafePush(Immediate(lit)); 475 __ SafePush(Immediate(lit));
474 } else { 476 } else {
475 __ push(Immediate(lit)); 477 __ push(Immediate(lit));
476 } 478 }
477 } 479 }
478 480
479 481
480 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { 482 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
481 codegen()->PrepareForBailoutBeforeSplit(condition(), 483 codegen()->PrepareForBailoutBeforeSplit(condition(),
(...skipping 21 matching lines...) Expand all
503 // For simplicity we always test the accumulator register. 505 // For simplicity we always test the accumulator register.
504 __ mov(result_register(), lit); 506 __ mov(result_register(), lit);
505 codegen()->DoTest(this); 507 codegen()->DoTest(this);
506 } 508 }
507 } 509 }
508 510
509 511
510 void FullCodeGenerator::StackValueContext::DropAndPlug(int count, 512 void FullCodeGenerator::StackValueContext::DropAndPlug(int count,
511 Register reg) const { 513 Register reg) const {
512 DCHECK(count > 0); 514 DCHECK(count > 0);
513 if (count > 1) __ Drop(count - 1); 515 if (count > 1) codegen()->DropOperands(count - 1);
514 __ mov(Operand(esp, 0), reg); 516 __ mov(Operand(esp, 0), reg);
515 } 517 }
516 518
517 519
518 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, 520 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true,
519 Label* materialize_false) const { 521 Label* materialize_false) const {
520 DCHECK(materialize_true == materialize_false); 522 DCHECK(materialize_true == materialize_false);
521 __ bind(materialize_true); 523 __ bind(materialize_true);
522 } 524 }
523 525
524 526
525 void FullCodeGenerator::AccumulatorValueContext::Plug( 527 void FullCodeGenerator::AccumulatorValueContext::Plug(
526 Label* materialize_true, 528 Label* materialize_true,
527 Label* materialize_false) const { 529 Label* materialize_false) const {
528 Label done; 530 Label done;
529 __ bind(materialize_true); 531 __ bind(materialize_true);
530 __ mov(result_register(), isolate()->factory()->true_value()); 532 __ mov(result_register(), isolate()->factory()->true_value());
531 __ jmp(&done, Label::kNear); 533 __ jmp(&done, Label::kNear);
532 __ bind(materialize_false); 534 __ bind(materialize_false);
533 __ mov(result_register(), isolate()->factory()->false_value()); 535 __ mov(result_register(), isolate()->factory()->false_value());
534 __ bind(&done); 536 __ bind(&done);
535 } 537 }
536 538
537 539
538 void FullCodeGenerator::StackValueContext::Plug( 540 void FullCodeGenerator::StackValueContext::Plug(
539 Label* materialize_true, 541 Label* materialize_true,
540 Label* materialize_false) const { 542 Label* materialize_false) const {
543 codegen()->OperandStackDepthIncrement(1);
541 Label done; 544 Label done;
542 __ bind(materialize_true); 545 __ bind(materialize_true);
543 __ push(Immediate(isolate()->factory()->true_value())); 546 __ push(Immediate(isolate()->factory()->true_value()));
544 __ jmp(&done, Label::kNear); 547 __ jmp(&done, Label::kNear);
545 __ bind(materialize_false); 548 __ bind(materialize_false);
546 __ push(Immediate(isolate()->factory()->false_value())); 549 __ push(Immediate(isolate()->factory()->false_value()));
547 __ bind(&done); 550 __ bind(&done);
548 } 551 }
549 552
550 553
551 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, 554 void FullCodeGenerator::TestContext::Plug(Label* materialize_true,
552 Label* materialize_false) const { 555 Label* materialize_false) const {
553 DCHECK(materialize_true == true_label_); 556 DCHECK(materialize_true == true_label_);
554 DCHECK(materialize_false == false_label_); 557 DCHECK(materialize_false == false_label_);
555 } 558 }
556 559
557 560
558 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { 561 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const {
559 Handle<Object> value = flag 562 Handle<Object> value = flag
560 ? isolate()->factory()->true_value() 563 ? isolate()->factory()->true_value()
561 : isolate()->factory()->false_value(); 564 : isolate()->factory()->false_value();
562 __ mov(result_register(), value); 565 __ mov(result_register(), value);
563 } 566 }
564 567
565 568
566 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { 569 void FullCodeGenerator::StackValueContext::Plug(bool flag) const {
570 codegen()->OperandStackDepthIncrement(1);
567 Handle<Object> value = flag 571 Handle<Object> value = flag
568 ? isolate()->factory()->true_value() 572 ? isolate()->factory()->true_value()
569 : isolate()->factory()->false_value(); 573 : isolate()->factory()->false_value();
570 __ push(Immediate(value)); 574 __ push(Immediate(value));
571 } 575 }
572 576
573 577
574 void FullCodeGenerator::TestContext::Plug(bool flag) const { 578 void FullCodeGenerator::TestContext::Plug(bool flag) const {
575 codegen()->PrepareForBailoutBeforeSplit(condition(), 579 codegen()->PrepareForBailoutBeforeSplit(condition(),
576 true, 580 true,
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 // We know that we have written a function, which is not a smi. 793 // We know that we have written a function, which is not a smi.
790 __ RecordWriteContextSlot(esi, Context::SlotOffset(variable->index()), 794 __ RecordWriteContextSlot(esi, Context::SlotOffset(variable->index()),
791 result_register(), ecx, kDontSaveFPRegs, 795 result_register(), ecx, kDontSaveFPRegs,
792 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); 796 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
793 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 797 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
794 break; 798 break;
795 } 799 }
796 800
797 case VariableLocation::LOOKUP: { 801 case VariableLocation::LOOKUP: {
798 Comment cmnt(masm_, "[ FunctionDeclaration"); 802 Comment cmnt(masm_, "[ FunctionDeclaration");
799 __ push(Immediate(variable->name())); 803 PushOperand(variable->name());
800 VisitForStackValue(declaration->fun()); 804 VisitForStackValue(declaration->fun());
801 __ push( 805 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
802 Immediate(Smi::FromInt(variable->DeclarationPropertyAttributes()))); 806 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
803 __ CallRuntime(Runtime::kDeclareLookupSlot);
804 break; 807 break;
805 } 808 }
806 } 809 }
807 } 810 }
808 811
809 812
810 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 813 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
811 // Call the runtime to declare the globals. 814 // Call the runtime to declare the globals.
812 __ Push(pairs); 815 __ Push(pairs);
813 __ Push(Smi::FromInt(DeclareGlobalsFlags())); 816 __ Push(Smi::FromInt(DeclareGlobalsFlags()));
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
889 892
890 __ test(eax, eax); 893 __ test(eax, eax);
891 __ j(not_equal, &next_test); 894 __ j(not_equal, &next_test);
892 __ Drop(1); // Switch value is no longer needed. 895 __ Drop(1); // Switch value is no longer needed.
893 __ jmp(clause->body_target()); 896 __ jmp(clause->body_target());
894 } 897 }
895 898
896 // Discard the test value and jump to the default if present, otherwise to 899 // Discard the test value and jump to the default if present, otherwise to
897 // the end of the statement. 900 // the end of the statement.
898 __ bind(&next_test); 901 __ bind(&next_test);
899 __ Drop(1); // Switch value is no longer needed. 902 DropOperands(1); // Switch value is no longer needed.
900 if (default_clause == NULL) { 903 if (default_clause == NULL) {
901 __ jmp(nested_statement.break_label()); 904 __ jmp(nested_statement.break_label());
902 } else { 905 } else {
903 __ jmp(default_clause->body_target()); 906 __ jmp(default_clause->body_target());
904 } 907 }
905 908
906 // Compile all the case bodies. 909 // Compile all the case bodies.
907 for (int i = 0; i < clauses->length(); i++) { 910 for (int i = 0; i < clauses->length(); i++) {
908 Comment cmnt(masm_, "[ Case body"); 911 Comment cmnt(masm_, "[ Case body");
909 CaseClause* clause = clauses->at(i); 912 CaseClause* clause = clauses->at(i);
(...skipping 13 matching lines...) Expand all
923 926
924 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); 927 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
925 928
926 Label loop, exit; 929 Label loop, exit;
927 ForIn loop_statement(this, stmt); 930 ForIn loop_statement(this, stmt);
928 increment_loop_depth(); 931 increment_loop_depth();
929 932
930 // Get the object to enumerate over. 933 // Get the object to enumerate over.
931 SetExpressionAsStatementPosition(stmt->enumerable()); 934 SetExpressionAsStatementPosition(stmt->enumerable());
932 VisitForAccumulatorValue(stmt->enumerable()); 935 VisitForAccumulatorValue(stmt->enumerable());
936 OperandStackDepthIncrement(ForIn::kElementCount);
933 937
934 // If the object is null or undefined, skip over the loop, otherwise convert 938 // If the object is null or undefined, skip over the loop, otherwise convert
935 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. 939 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4.
936 Label convert, done_convert; 940 Label convert, done_convert;
937 __ JumpIfSmi(eax, &convert, Label::kNear); 941 __ JumpIfSmi(eax, &convert, Label::kNear);
938 __ CmpObjectType(eax, FIRST_JS_RECEIVER_TYPE, ecx); 942 __ CmpObjectType(eax, FIRST_JS_RECEIVER_TYPE, ecx);
939 __ j(above_equal, &done_convert, Label::kNear); 943 __ j(above_equal, &done_convert, Label::kNear);
940 __ cmp(eax, isolate()->factory()->undefined_value()); 944 __ cmp(eax, isolate()->factory()->undefined_value());
941 __ j(equal, &exit); 945 __ j(equal, &exit);
942 __ cmp(eax, isolate()->factory()->null_value()); 946 __ cmp(eax, isolate()->factory()->null_value());
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1071 // index (smi) stored on top of the stack. 1075 // index (smi) stored on top of the stack.
1072 __ bind(loop_statement.continue_label()); 1076 __ bind(loop_statement.continue_label());
1073 __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1))); 1077 __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1)));
1074 1078
1075 EmitBackEdgeBookkeeping(stmt, &loop); 1079 EmitBackEdgeBookkeeping(stmt, &loop);
1076 __ jmp(&loop); 1080 __ jmp(&loop);
1077 1081
1078 // Remove the pointers stored on the stack. 1082 // Remove the pointers stored on the stack.
1079 __ bind(loop_statement.break_label()); 1083 __ bind(loop_statement.break_label());
1080 __ add(esp, Immediate(5 * kPointerSize)); 1084 __ add(esp, Immediate(5 * kPointerSize));
1085 OperandStackDepthDecrement(ForIn::kElementCount);
1081 1086
1082 // Exit and decrement the loop depth. 1087 // Exit and decrement the loop depth.
1083 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1088 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1084 __ bind(&exit); 1089 __ bind(&exit);
1085 decrement_loop_depth(); 1090 decrement_loop_depth();
1086 } 1091 }
1087 1092
1088 1093
1089 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, 1094 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
1090 bool pretenure) { 1095 bool pretenure) {
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
1342 __ Move(edx, Immediate(Smi::FromInt(expr->flags()))); 1347 __ Move(edx, Immediate(Smi::FromInt(expr->flags())));
1343 FastCloneRegExpStub stub(isolate()); 1348 FastCloneRegExpStub stub(isolate());
1344 __ CallStub(&stub); 1349 __ CallStub(&stub);
1345 context()->Plug(eax); 1350 context()->Plug(eax);
1346 } 1351 }
1347 1352
1348 1353
1349 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { 1354 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
1350 Expression* expression = (property == NULL) ? NULL : property->value(); 1355 Expression* expression = (property == NULL) ? NULL : property->value();
1351 if (expression == NULL) { 1356 if (expression == NULL) {
1352 __ push(Immediate(isolate()->factory()->null_value())); 1357 PushOperand(isolate()->factory()->null_value());
1353 } else { 1358 } else {
1354 VisitForStackValue(expression); 1359 VisitForStackValue(expression);
1355 if (NeedsHomeObject(expression)) { 1360 if (NeedsHomeObject(expression)) {
1356 DCHECK(property->kind() == ObjectLiteral::Property::GETTER || 1361 DCHECK(property->kind() == ObjectLiteral::Property::GETTER ||
1357 property->kind() == ObjectLiteral::Property::SETTER); 1362 property->kind() == ObjectLiteral::Property::SETTER);
1358 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3; 1363 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3;
1359 EmitSetHomeObject(expression, offset, property->GetSlot()); 1364 EmitSetHomeObject(expression, offset, property->GetSlot());
1360 } 1365 }
1361 } 1366 }
1362 } 1367 }
(...skipping 29 matching lines...) Expand all
1392 AccessorTable accessor_table(zone()); 1397 AccessorTable accessor_table(zone());
1393 int property_index = 0; 1398 int property_index = 0;
1394 for (; property_index < expr->properties()->length(); property_index++) { 1399 for (; property_index < expr->properties()->length(); property_index++) {
1395 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1400 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1396 if (property->is_computed_name()) break; 1401 if (property->is_computed_name()) break;
1397 if (property->IsCompileTimeValue()) continue; 1402 if (property->IsCompileTimeValue()) continue;
1398 1403
1399 Literal* key = property->key()->AsLiteral(); 1404 Literal* key = property->key()->AsLiteral();
1400 Expression* value = property->value(); 1405 Expression* value = property->value();
1401 if (!result_saved) { 1406 if (!result_saved) {
1402 __ push(eax); // Save result on the stack 1407 PushOperand(eax); // Save result on the stack
1403 result_saved = true; 1408 result_saved = true;
1404 } 1409 }
1405 switch (property->kind()) { 1410 switch (property->kind()) {
1406 case ObjectLiteral::Property::CONSTANT: 1411 case ObjectLiteral::Property::CONSTANT:
1407 UNREACHABLE(); 1412 UNREACHABLE();
1408 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1413 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1409 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); 1414 DCHECK(!CompileTimeValue::IsCompileTimeValue(value));
1410 // Fall through. 1415 // Fall through.
1411 case ObjectLiteral::Property::COMPUTED: 1416 case ObjectLiteral::Property::COMPUTED:
1412 // It is safe to use [[Put]] here because the boilerplate already 1417 // It is safe to use [[Put]] here because the boilerplate already
1413 // contains computed properties with an uninitialized value. 1418 // contains computed properties with an uninitialized value.
1414 if (key->value()->IsInternalizedString()) { 1419 if (key->value()->IsInternalizedString()) {
1415 if (property->emit_store()) { 1420 if (property->emit_store()) {
1416 VisitForAccumulatorValue(value); 1421 VisitForAccumulatorValue(value);
1417 DCHECK(StoreDescriptor::ValueRegister().is(eax)); 1422 DCHECK(StoreDescriptor::ValueRegister().is(eax));
1418 __ mov(StoreDescriptor::NameRegister(), Immediate(key->value())); 1423 __ mov(StoreDescriptor::NameRegister(), Immediate(key->value()));
1419 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); 1424 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0));
1420 EmitLoadStoreICSlot(property->GetSlot(0)); 1425 EmitLoadStoreICSlot(property->GetSlot(0));
1421 CallStoreIC(); 1426 CallStoreIC();
1422 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1427 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1423 if (NeedsHomeObject(value)) { 1428 if (NeedsHomeObject(value)) {
1424 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); 1429 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
1425 } 1430 }
1426 } else { 1431 } else {
1427 VisitForEffect(value); 1432 VisitForEffect(value);
1428 } 1433 }
1429 break; 1434 break;
1430 } 1435 }
1431 __ push(Operand(esp, 0)); // Duplicate receiver. 1436 PushOperand(Operand(esp, 0)); // Duplicate receiver.
1432 VisitForStackValue(key); 1437 VisitForStackValue(key);
1433 VisitForStackValue(value); 1438 VisitForStackValue(value);
1434 if (property->emit_store()) { 1439 if (property->emit_store()) {
1435 if (NeedsHomeObject(value)) { 1440 if (NeedsHomeObject(value)) {
1436 EmitSetHomeObject(value, 2, property->GetSlot()); 1441 EmitSetHomeObject(value, 2, property->GetSlot());
1437 } 1442 }
1438 __ push(Immediate(Smi::FromInt(SLOPPY))); // Language mode 1443 PushOperand(Smi::FromInt(SLOPPY)); // Language mode
1439 __ CallRuntime(Runtime::kSetProperty); 1444 CallRuntimeWithOperands(Runtime::kSetProperty);
1440 } else { 1445 } else {
1441 __ Drop(3); 1446 DropOperands(3);
1442 } 1447 }
1443 break; 1448 break;
1444 case ObjectLiteral::Property::PROTOTYPE: 1449 case ObjectLiteral::Property::PROTOTYPE:
1445 __ push(Operand(esp, 0)); // Duplicate receiver. 1450 PushOperand(Operand(esp, 0)); // Duplicate receiver.
1446 VisitForStackValue(value); 1451 VisitForStackValue(value);
1447 DCHECK(property->emit_store()); 1452 DCHECK(property->emit_store());
1448 __ CallRuntime(Runtime::kInternalSetPrototype); 1453 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1449 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1454 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1450 NO_REGISTERS); 1455 NO_REGISTERS);
1451 break; 1456 break;
1452 case ObjectLiteral::Property::GETTER: 1457 case ObjectLiteral::Property::GETTER:
1453 if (property->emit_store()) { 1458 if (property->emit_store()) {
1454 accessor_table.lookup(key)->second->getter = property; 1459 accessor_table.lookup(key)->second->getter = property;
1455 } 1460 }
1456 break; 1461 break;
1457 case ObjectLiteral::Property::SETTER: 1462 case ObjectLiteral::Property::SETTER:
1458 if (property->emit_store()) { 1463 if (property->emit_store()) {
1459 accessor_table.lookup(key)->second->setter = property; 1464 accessor_table.lookup(key)->second->setter = property;
1460 } 1465 }
1461 break; 1466 break;
1462 } 1467 }
1463 } 1468 }
1464 1469
1465 // Emit code to define accessors, using only a single call to the runtime for 1470 // Emit code to define accessors, using only a single call to the runtime for
1466 // each pair of corresponding getters and setters. 1471 // each pair of corresponding getters and setters.
1467 for (AccessorTable::Iterator it = accessor_table.begin(); 1472 for (AccessorTable::Iterator it = accessor_table.begin();
1468 it != accessor_table.end(); 1473 it != accessor_table.end();
1469 ++it) { 1474 ++it) {
1470 __ push(Operand(esp, 0)); // Duplicate receiver. 1475 PushOperand(Operand(esp, 0)); // Duplicate receiver.
1471 VisitForStackValue(it->first); 1476 VisitForStackValue(it->first);
1472 1477
1473 EmitAccessor(it->second->getter); 1478 EmitAccessor(it->second->getter);
1474 EmitAccessor(it->second->setter); 1479 EmitAccessor(it->second->setter);
1475 1480
1476 __ push(Immediate(Smi::FromInt(NONE))); 1481 PushOperand(Smi::FromInt(NONE));
1477 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked); 1482 CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked);
1478 } 1483 }
1479 1484
1480 // Object literals have two parts. The "static" part on the left contains no 1485 // Object literals have two parts. The "static" part on the left contains no
1481 // computed property names, and so we can compute its map ahead of time; see 1486 // computed property names, and so we can compute its map ahead of time; see
1482 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part 1487 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part
1483 // starts with the first computed property name, and continues with all 1488 // starts with the first computed property name, and continues with all
1484 // properties to its right. All the code from above initializes the static 1489 // properties to its right. All the code from above initializes the static
1485 // component of the object literal, and arranges for the map of the result to 1490 // component of the object literal, and arranges for the map of the result to
1486 // reflect the static order in which the keys appear. For the dynamic 1491 // reflect the static order in which the keys appear. For the dynamic
1487 // properties, we compile them into a series of "SetOwnProperty" runtime 1492 // properties, we compile them into a series of "SetOwnProperty" runtime
1488 // calls. This will preserve insertion order. 1493 // calls. This will preserve insertion order.
1489 for (; property_index < expr->properties()->length(); property_index++) { 1494 for (; property_index < expr->properties()->length(); property_index++) {
1490 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1495 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1491 1496
1492 Expression* value = property->value(); 1497 Expression* value = property->value();
1493 if (!result_saved) { 1498 if (!result_saved) {
1494 __ push(eax); // Save result on the stack 1499 PushOperand(eax); // Save result on the stack
1495 result_saved = true; 1500 result_saved = true;
1496 } 1501 }
1497 1502
1498 __ push(Operand(esp, 0)); // Duplicate receiver. 1503 PushOperand(Operand(esp, 0)); // Duplicate receiver.
1499 1504
1500 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1505 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1501 DCHECK(!property->is_computed_name()); 1506 DCHECK(!property->is_computed_name());
1502 VisitForStackValue(value); 1507 VisitForStackValue(value);
1503 DCHECK(property->emit_store()); 1508 DCHECK(property->emit_store());
1504 __ CallRuntime(Runtime::kInternalSetPrototype); 1509 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1505 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1510 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1506 NO_REGISTERS); 1511 NO_REGISTERS);
1507 } else { 1512 } else {
1508 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); 1513 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
1509 VisitForStackValue(value); 1514 VisitForStackValue(value);
1510 if (NeedsHomeObject(value)) { 1515 if (NeedsHomeObject(value)) {
1511 EmitSetHomeObject(value, 2, property->GetSlot()); 1516 EmitSetHomeObject(value, 2, property->GetSlot());
1512 } 1517 }
1513 1518
1514 switch (property->kind()) { 1519 switch (property->kind()) {
1515 case ObjectLiteral::Property::CONSTANT: 1520 case ObjectLiteral::Property::CONSTANT:
1516 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1521 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1517 case ObjectLiteral::Property::COMPUTED: 1522 case ObjectLiteral::Property::COMPUTED:
1518 if (property->emit_store()) { 1523 if (property->emit_store()) {
1519 __ Push(Smi::FromInt(NONE)); 1524 PushOperand(Smi::FromInt(NONE));
1520 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); 1525 PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
1521 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); 1526 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
1522 } else { 1527 } else {
1523 __ Drop(3); 1528 DropOperands(3);
1524 } 1529 }
1525 break; 1530 break;
1526 1531
1527 case ObjectLiteral::Property::PROTOTYPE: 1532 case ObjectLiteral::Property::PROTOTYPE:
1528 UNREACHABLE(); 1533 UNREACHABLE();
1529 break; 1534 break;
1530 1535
1531 case ObjectLiteral::Property::GETTER: 1536 case ObjectLiteral::Property::GETTER:
1532 __ Push(Smi::FromInt(NONE)); 1537 PushOperand(Smi::FromInt(NONE));
1533 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); 1538 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
1534 break; 1539 break;
1535 1540
1536 case ObjectLiteral::Property::SETTER: 1541 case ObjectLiteral::Property::SETTER:
1537 __ Push(Smi::FromInt(NONE)); 1542 PushOperand(Smi::FromInt(NONE));
1538 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); 1543 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
1539 break; 1544 break;
1540 } 1545 }
1541 } 1546 }
1542 } 1547 }
1543 1548
1544 if (expr->has_function()) { 1549 if (expr->has_function()) {
1545 DCHECK(result_saved); 1550 DCHECK(result_saved);
1546 __ push(Operand(esp, 0)); 1551 __ push(Operand(esp, 0));
1547 __ CallRuntime(Runtime::kToFastProperties); 1552 __ CallRuntime(Runtime::kToFastProperties);
1548 } 1553 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1593 int array_index = 0; 1598 int array_index = 0;
1594 for (; array_index < length; array_index++) { 1599 for (; array_index < length; array_index++) {
1595 Expression* subexpr = subexprs->at(array_index); 1600 Expression* subexpr = subexprs->at(array_index);
1596 DCHECK(!subexpr->IsSpread()); 1601 DCHECK(!subexpr->IsSpread());
1597 1602
1598 // If the subexpression is a literal or a simple materialized literal it 1603 // If the subexpression is a literal or a simple materialized literal it
1599 // is already set in the cloned array. 1604 // is already set in the cloned array.
1600 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 1605 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
1601 1606
1602 if (!result_saved) { 1607 if (!result_saved) {
1603 __ push(eax); // array literal. 1608 PushOperand(eax); // array literal.
1604 result_saved = true; 1609 result_saved = true;
1605 } 1610 }
1606 VisitForAccumulatorValue(subexpr); 1611 VisitForAccumulatorValue(subexpr);
1607 1612
1608 __ mov(StoreDescriptor::NameRegister(), 1613 __ mov(StoreDescriptor::NameRegister(),
1609 Immediate(Smi::FromInt(array_index))); 1614 Immediate(Smi::FromInt(array_index)));
1610 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); 1615 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0));
1611 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); 1616 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot());
1612 Handle<Code> ic = 1617 Handle<Code> ic =
1613 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 1618 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
1614 CallIC(ic); 1619 CallIC(ic);
1615 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1620 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1616 } 1621 }
1617 1622
1618 // In case the array literal contains spread expressions it has two parts. The 1623 // In case the array literal contains spread expressions it has two parts. The
1619 // first part is the "static" array which has a literal index is handled 1624 // first part is the "static" array which has a literal index is handled
1620 // above. The second part is the part after the first spread expression 1625 // above. The second part is the part after the first spread expression
1621 // (inclusive) and these elements gets appended to the array. Note that the 1626 // (inclusive) and these elements gets appended to the array. Note that the
1622 // number elements an iterable produces is unknown ahead of time. 1627 // number elements an iterable produces is unknown ahead of time.
1623 if (array_index < length && result_saved) { 1628 if (array_index < length && result_saved) {
1624 __ Pop(eax); 1629 PopOperand(eax);
1625 result_saved = false; 1630 result_saved = false;
1626 } 1631 }
1627 for (; array_index < length; array_index++) { 1632 for (; array_index < length; array_index++) {
1628 Expression* subexpr = subexprs->at(array_index); 1633 Expression* subexpr = subexprs->at(array_index);
1629 1634
1630 __ Push(eax); 1635 PushOperand(eax);
1631 DCHECK(!subexpr->IsSpread()); 1636 DCHECK(!subexpr->IsSpread());
1632 VisitForStackValue(subexpr); 1637 VisitForStackValue(subexpr);
1633 __ CallRuntime(Runtime::kAppendElement); 1638 CallRuntimeWithOperands(Runtime::kAppendElement);
1634 1639
1635 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1640 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1636 } 1641 }
1637 1642
1638 if (result_saved) { 1643 if (result_saved) {
1639 context()->PlugTOS(); 1644 context()->PlugTOS();
1640 } else { 1645 } else {
1641 context()->Plug(eax); 1646 context()->Plug(eax);
1642 } 1647 }
1643 } 1648 }
(...skipping 11 matching lines...) Expand all
1655 // Evaluate LHS expression. 1660 // Evaluate LHS expression.
1656 switch (assign_type) { 1661 switch (assign_type) {
1657 case VARIABLE: 1662 case VARIABLE:
1658 // Nothing to do here. 1663 // Nothing to do here.
1659 break; 1664 break;
1660 case NAMED_SUPER_PROPERTY: 1665 case NAMED_SUPER_PROPERTY:
1661 VisitForStackValue( 1666 VisitForStackValue(
1662 property->obj()->AsSuperPropertyReference()->this_var()); 1667 property->obj()->AsSuperPropertyReference()->this_var());
1663 VisitForAccumulatorValue( 1668 VisitForAccumulatorValue(
1664 property->obj()->AsSuperPropertyReference()->home_object()); 1669 property->obj()->AsSuperPropertyReference()->home_object());
1665 __ push(result_register()); 1670 PushOperand(result_register());
1666 if (expr->is_compound()) { 1671 if (expr->is_compound()) {
1667 __ push(MemOperand(esp, kPointerSize)); 1672 PushOperand(MemOperand(esp, kPointerSize));
1668 __ push(result_register()); 1673 PushOperand(result_register());
1669 } 1674 }
1670 break; 1675 break;
1671 case NAMED_PROPERTY: 1676 case NAMED_PROPERTY:
1672 if (expr->is_compound()) { 1677 if (expr->is_compound()) {
1673 // We need the receiver both on the stack and in the register. 1678 // We need the receiver both on the stack and in the register.
1674 VisitForStackValue(property->obj()); 1679 VisitForStackValue(property->obj());
1675 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); 1680 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
1676 } else { 1681 } else {
1677 VisitForStackValue(property->obj()); 1682 VisitForStackValue(property->obj());
1678 } 1683 }
1679 break; 1684 break;
1680 case KEYED_SUPER_PROPERTY: 1685 case KEYED_SUPER_PROPERTY:
1681 VisitForStackValue( 1686 VisitForStackValue(
1682 property->obj()->AsSuperPropertyReference()->this_var()); 1687 property->obj()->AsSuperPropertyReference()->this_var());
1683 VisitForStackValue( 1688 VisitForStackValue(
1684 property->obj()->AsSuperPropertyReference()->home_object()); 1689 property->obj()->AsSuperPropertyReference()->home_object());
1685 VisitForAccumulatorValue(property->key()); 1690 VisitForAccumulatorValue(property->key());
1686 __ Push(result_register()); 1691 PushOperand(result_register());
1687 if (expr->is_compound()) { 1692 if (expr->is_compound()) {
1688 __ push(MemOperand(esp, 2 * kPointerSize)); 1693 PushOperand(MemOperand(esp, 2 * kPointerSize));
1689 __ push(MemOperand(esp, 2 * kPointerSize)); 1694 PushOperand(MemOperand(esp, 2 * kPointerSize));
1690 __ push(result_register()); 1695 PushOperand(result_register());
1691 } 1696 }
1692 break; 1697 break;
1693 case KEYED_PROPERTY: { 1698 case KEYED_PROPERTY: {
1694 if (expr->is_compound()) { 1699 if (expr->is_compound()) {
1695 VisitForStackValue(property->obj()); 1700 VisitForStackValue(property->obj());
1696 VisitForStackValue(property->key()); 1701 VisitForStackValue(property->key());
1697 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, kPointerSize)); 1702 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, kPointerSize));
1698 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); 1703 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0));
1699 } else { 1704 } else {
1700 VisitForStackValue(property->obj()); 1705 VisitForStackValue(property->obj());
(...skipping 26 matching lines...) Expand all
1727 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1732 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1728 break; 1733 break;
1729 case KEYED_PROPERTY: 1734 case KEYED_PROPERTY:
1730 EmitKeyedPropertyLoad(property); 1735 EmitKeyedPropertyLoad(property);
1731 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1736 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1732 break; 1737 break;
1733 } 1738 }
1734 } 1739 }
1735 1740
1736 Token::Value op = expr->binary_op(); 1741 Token::Value op = expr->binary_op();
1737 __ push(eax); // Left operand goes on the stack. 1742 PushOperand(eax); // Left operand goes on the stack.
1738 VisitForAccumulatorValue(expr->value()); 1743 VisitForAccumulatorValue(expr->value());
1739 1744
1740 if (ShouldInlineSmiCase(op)) { 1745 if (ShouldInlineSmiCase(op)) {
1741 EmitInlineSmiBinaryOp(expr->binary_operation(), 1746 EmitInlineSmiBinaryOp(expr->binary_operation(),
1742 op, 1747 op,
1743 expr->target(), 1748 expr->target(),
1744 expr->value()); 1749 expr->value());
1745 } else { 1750 } else {
1746 EmitBinaryOp(expr->binary_operation(), op); 1751 EmitBinaryOp(expr->binary_operation(), op);
1747 } 1752 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1820 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, 1825 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx,
1821 kDontSaveFPRegs); 1826 kDontSaveFPRegs);
1822 __ lea(ebx, Operand(ebp, StandardFrameConstants::kExpressionsOffset)); 1827 __ lea(ebx, Operand(ebp, StandardFrameConstants::kExpressionsOffset));
1823 __ cmp(esp, ebx); 1828 __ cmp(esp, ebx);
1824 __ j(equal, &post_runtime); 1829 __ j(equal, &post_runtime);
1825 __ push(eax); // generator object 1830 __ push(eax); // generator object
1826 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 1831 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
1827 __ mov(context_register(), 1832 __ mov(context_register(),
1828 Operand(ebp, StandardFrameConstants::kContextOffset)); 1833 Operand(ebp, StandardFrameConstants::kContextOffset));
1829 __ bind(&post_runtime); 1834 __ bind(&post_runtime);
1830 __ pop(result_register()); 1835 PopOperand(result_register());
1831 EmitReturnSequence(); 1836 EmitReturnSequence();
1832 1837
1833 __ bind(&resume); 1838 __ bind(&resume);
1834 context()->Plug(result_register()); 1839 context()->Plug(result_register());
1835 break; 1840 break;
1836 } 1841 }
1837 1842
1838 case Yield::kFinal: { 1843 case Yield::kFinal: {
1839 // Pop value from top-of-stack slot, box result into result register. 1844 // Pop value from top-of-stack slot, box result into result register.
1845 OperandStackDepthDecrement(1);
1840 EmitCreateIteratorResult(true); 1846 EmitCreateIteratorResult(true);
1841 EmitUnwindAndReturn(); 1847 EmitUnwindAndReturn();
1842 break; 1848 break;
1843 } 1849 }
1844 1850
1845 case Yield::kDelegating: 1851 case Yield::kDelegating:
1846 UNREACHABLE(); 1852 UNREACHABLE();
1847 } 1853 }
1848 } 1854 }
1849 1855
1850 1856
1851 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, 1857 void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
1852 Expression *value, 1858 Expression *value,
1853 JSGeneratorObject::ResumeMode resume_mode) { 1859 JSGeneratorObject::ResumeMode resume_mode) {
1854 // The value stays in eax, and is ultimately read by the resumed generator, as 1860 // The value stays in eax, and is ultimately read by the resumed generator, as
1855 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it 1861 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it
1856 // is read to throw the value when the resumed generator is already closed. 1862 // is read to throw the value when the resumed generator is already closed.
1857 // ebx will hold the generator object until the activation has been resumed. 1863 // ebx will hold the generator object until the activation has been resumed.
1858 VisitForStackValue(generator); 1864 VisitForStackValue(generator);
1859 VisitForAccumulatorValue(value); 1865 VisitForAccumulatorValue(value);
1860 __ pop(ebx); 1866 PopOperand(ebx);
1861 1867
1862 // Store input value into generator object. 1868 // Store input value into generator object.
1863 __ mov(FieldOperand(ebx, JSGeneratorObject::kInputOffset), result_register()); 1869 __ mov(FieldOperand(ebx, JSGeneratorObject::kInputOffset), result_register());
1864 __ mov(ecx, result_register()); 1870 __ mov(ecx, result_register());
1865 __ RecordWriteField(ebx, JSGeneratorObject::kInputOffset, ecx, edx, 1871 __ RecordWriteField(ebx, JSGeneratorObject::kInputOffset, ecx, edx,
1866 kDontSaveFPRegs); 1872 kDontSaveFPRegs);
1867 1873
1868 // Load suspended function and context. 1874 // Load suspended function and context.
1869 __ mov(esi, FieldOperand(ebx, JSGeneratorObject::kContextOffset)); 1875 __ mov(esi, FieldOperand(ebx, JSGeneratorObject::kContextOffset));
1870 __ mov(edi, FieldOperand(ebx, JSGeneratorObject::kFunctionOffset)); 1876 __ mov(edi, FieldOperand(ebx, JSGeneratorObject::kFunctionOffset));
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1932 __ push(result_register()); 1938 __ push(result_register());
1933 __ Push(Smi::FromInt(resume_mode)); 1939 __ Push(Smi::FromInt(resume_mode));
1934 __ CallRuntime(Runtime::kResumeJSGeneratorObject); 1940 __ CallRuntime(Runtime::kResumeJSGeneratorObject);
1935 // Not reached: the runtime call returns elsewhere. 1941 // Not reached: the runtime call returns elsewhere.
1936 __ Abort(kGeneratorFailedToResume); 1942 __ Abort(kGeneratorFailedToResume);
1937 1943
1938 __ bind(&done); 1944 __ bind(&done);
1939 context()->Plug(result_register()); 1945 context()->Plug(result_register());
1940 } 1946 }
1941 1947
1948 void FullCodeGenerator::PushOperand(MemOperand operand) {
1949 OperandStackDepthIncrement(1);
1950 __ Push(operand);
1951 }
1952
1953 void FullCodeGenerator::EmitOperandStackDepthCheck() {
1954 if (FLAG_debug_code) {
1955 int expected_diff = StandardFrameConstants::kFixedFrameSizeFromFp +
1956 operand_stack_depth_ * kPointerSize;
1957 __ mov(eax, ebp);
1958 __ sub(eax, esp);
1959 __ cmp(eax, Immediate(expected_diff));
1960 __ Assert(equal, kUnexpectedStackDepth);
1961 }
1962 }
1942 1963
1943 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { 1964 void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
1944 Label allocate, done_allocate; 1965 Label allocate, done_allocate;
1945 1966
1946 __ Allocate(JSIteratorResult::kSize, eax, ecx, edx, &allocate, TAG_OBJECT); 1967 __ Allocate(JSIteratorResult::kSize, eax, ecx, edx, &allocate, TAG_OBJECT);
1947 __ jmp(&done_allocate, Label::kNear); 1968 __ jmp(&done_allocate, Label::kNear);
1948 1969
1949 __ bind(&allocate); 1970 __ bind(&allocate);
1950 __ Push(Smi::FromInt(JSIteratorResult::kSize)); 1971 __ Push(Smi::FromInt(JSIteratorResult::kSize));
1951 __ CallRuntime(Runtime::kAllocateInNewSpace); 1972 __ CallRuntime(Runtime::kAllocateInNewSpace);
(...skipping 26 matching lines...) Expand all
1978 } 1999 }
1979 2000
1980 2001
1981 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 2002 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
1982 Token::Value op, 2003 Token::Value op,
1983 Expression* left, 2004 Expression* left,
1984 Expression* right) { 2005 Expression* right) {
1985 // Do combined smi check of the operands. Left operand is on the 2006 // Do combined smi check of the operands. Left operand is on the
1986 // stack. Right operand is in eax. 2007 // stack. Right operand is in eax.
1987 Label smi_case, done, stub_call; 2008 Label smi_case, done, stub_call;
1988 __ pop(edx); 2009 PopOperand(edx);
1989 __ mov(ecx, eax); 2010 __ mov(ecx, eax);
1990 __ or_(eax, edx); 2011 __ or_(eax, edx);
1991 JumpPatchSite patch_site(masm_); 2012 JumpPatchSite patch_site(masm_);
1992 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); 2013 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear);
1993 2014
1994 __ bind(&stub_call); 2015 __ bind(&stub_call);
1995 __ mov(eax, ecx); 2016 __ mov(eax, ecx);
1996 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); 2017 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
1997 CallIC(code, expr->BinaryOperationFeedbackId()); 2018 CallIC(code, expr->BinaryOperationFeedbackId());
1998 patch_site.EmitPatchInfo(); 2019 patch_site.EmitPatchInfo();
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
2071 context()->Plug(eax); 2092 context()->Plug(eax);
2072 } 2093 }
2073 2094
2074 2095
2075 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) { 2096 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
2076 for (int i = 0; i < lit->properties()->length(); i++) { 2097 for (int i = 0; i < lit->properties()->length(); i++) {
2077 ObjectLiteral::Property* property = lit->properties()->at(i); 2098 ObjectLiteral::Property* property = lit->properties()->at(i);
2078 Expression* value = property->value(); 2099 Expression* value = property->value();
2079 2100
2080 if (property->is_static()) { 2101 if (property->is_static()) {
2081 __ push(Operand(esp, kPointerSize)); // constructor 2102 PushOperand(Operand(esp, kPointerSize)); // constructor
2082 } else { 2103 } else {
2083 __ push(Operand(esp, 0)); // prototype 2104 PushOperand(Operand(esp, 0)); // prototype
2084 } 2105 }
2085 EmitPropertyKey(property, lit->GetIdForProperty(i)); 2106 EmitPropertyKey(property, lit->GetIdForProperty(i));
2086 2107
2087 // The static prototype property is read only. We handle the non computed 2108 // The static prototype property is read only. We handle the non computed
2088 // property name case in the parser. Since this is the only case where we 2109 // property name case in the parser. Since this is the only case where we
2089 // need to check for an own read only property we special case this so we do 2110 // need to check for an own read only property we special case this so we do
2090 // not need to do this for every property. 2111 // not need to do this for every property.
2091 if (property->is_static() && property->is_computed_name()) { 2112 if (property->is_static() && property->is_computed_name()) {
2092 __ CallRuntime(Runtime::kThrowIfStaticPrototype); 2113 __ CallRuntime(Runtime::kThrowIfStaticPrototype);
2093 __ push(eax); 2114 __ push(eax);
2094 } 2115 }
2095 2116
2096 VisitForStackValue(value); 2117 VisitForStackValue(value);
2097 if (NeedsHomeObject(value)) { 2118 if (NeedsHomeObject(value)) {
2098 EmitSetHomeObject(value, 2, property->GetSlot()); 2119 EmitSetHomeObject(value, 2, property->GetSlot());
2099 } 2120 }
2100 2121
2101 switch (property->kind()) { 2122 switch (property->kind()) {
2102 case ObjectLiteral::Property::CONSTANT: 2123 case ObjectLiteral::Property::CONSTANT:
2103 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 2124 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
2104 case ObjectLiteral::Property::PROTOTYPE: 2125 case ObjectLiteral::Property::PROTOTYPE:
2105 UNREACHABLE(); 2126 UNREACHABLE();
2106 case ObjectLiteral::Property::COMPUTED: 2127 case ObjectLiteral::Property::COMPUTED:
2107 __ Push(Smi::FromInt(DONT_ENUM)); 2128 PushOperand(Smi::FromInt(DONT_ENUM));
2108 __ Push(Smi::FromInt(property->NeedsSetFunctionName())); 2129 PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
2109 __ CallRuntime(Runtime::kDefineDataPropertyInLiteral); 2130 CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
2110 break; 2131 break;
2111 2132
2112 case ObjectLiteral::Property::GETTER: 2133 case ObjectLiteral::Property::GETTER:
2113 __ Push(Smi::FromInt(DONT_ENUM)); 2134 PushOperand(Smi::FromInt(DONT_ENUM));
2114 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked); 2135 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
2115 break; 2136 break;
2116 2137
2117 case ObjectLiteral::Property::SETTER: 2138 case ObjectLiteral::Property::SETTER:
2118 __ Push(Smi::FromInt(DONT_ENUM)); 2139 PushOperand(Smi::FromInt(DONT_ENUM));
2119 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked); 2140 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
2120 break; 2141 break;
2121 } 2142 }
2122 } 2143 }
2123 } 2144 }
2124 2145
2125 2146
2126 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { 2147 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
2127 __ pop(edx); 2148 PopOperand(edx);
2128 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); 2149 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
2129 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 2150 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
2130 CallIC(code, expr->BinaryOperationFeedbackId()); 2151 CallIC(code, expr->BinaryOperationFeedbackId());
2131 patch_site.EmitPatchInfo(); 2152 patch_site.EmitPatchInfo();
2132 context()->Plug(eax); 2153 context()->Plug(eax);
2133 } 2154 }
2134 2155
2135 2156
2136 void FullCodeGenerator::EmitAssignment(Expression* expr, 2157 void FullCodeGenerator::EmitAssignment(Expression* expr,
2137 FeedbackVectorSlot slot) { 2158 FeedbackVectorSlot slot) {
2138 DCHECK(expr->IsValidReferenceExpressionOrThis()); 2159 DCHECK(expr->IsValidReferenceExpressionOrThis());
2139 2160
2140 Property* prop = expr->AsProperty(); 2161 Property* prop = expr->AsProperty();
2141 LhsKind assign_type = Property::GetAssignType(prop); 2162 LhsKind assign_type = Property::GetAssignType(prop);
2142 2163
2143 switch (assign_type) { 2164 switch (assign_type) {
2144 case VARIABLE: { 2165 case VARIABLE: {
2145 Variable* var = expr->AsVariableProxy()->var(); 2166 Variable* var = expr->AsVariableProxy()->var();
2146 EffectContext context(this); 2167 EffectContext context(this);
2147 EmitVariableAssignment(var, Token::ASSIGN, slot); 2168 EmitVariableAssignment(var, Token::ASSIGN, slot);
2148 break; 2169 break;
2149 } 2170 }
2150 case NAMED_PROPERTY: { 2171 case NAMED_PROPERTY: {
2151 __ push(eax); // Preserve value. 2172 PushOperand(eax); // Preserve value.
2152 VisitForAccumulatorValue(prop->obj()); 2173 VisitForAccumulatorValue(prop->obj());
2153 __ Move(StoreDescriptor::ReceiverRegister(), eax); 2174 __ Move(StoreDescriptor::ReceiverRegister(), eax);
2154 __ pop(StoreDescriptor::ValueRegister()); // Restore value. 2175 PopOperand(StoreDescriptor::ValueRegister()); // Restore value.
2155 __ mov(StoreDescriptor::NameRegister(), 2176 __ mov(StoreDescriptor::NameRegister(),
2156 prop->key()->AsLiteral()->value()); 2177 prop->key()->AsLiteral()->value());
2157 EmitLoadStoreICSlot(slot); 2178 EmitLoadStoreICSlot(slot);
2158 CallStoreIC(); 2179 CallStoreIC();
2159 break; 2180 break;
2160 } 2181 }
2161 case NAMED_SUPER_PROPERTY: { 2182 case NAMED_SUPER_PROPERTY: {
2162 __ push(eax); 2183 PushOperand(eax);
2163 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 2184 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
2164 VisitForAccumulatorValue( 2185 VisitForAccumulatorValue(
2165 prop->obj()->AsSuperPropertyReference()->home_object()); 2186 prop->obj()->AsSuperPropertyReference()->home_object());
2166 // stack: value, this; eax: home_object 2187 // stack: value, this; eax: home_object
2167 Register scratch = ecx; 2188 Register scratch = ecx;
2168 Register scratch2 = edx; 2189 Register scratch2 = edx;
2169 __ mov(scratch, result_register()); // home_object 2190 __ mov(scratch, result_register()); // home_object
2170 __ mov(eax, MemOperand(esp, kPointerSize)); // value 2191 __ mov(eax, MemOperand(esp, kPointerSize)); // value
2171 __ mov(scratch2, MemOperand(esp, 0)); // this 2192 __ mov(scratch2, MemOperand(esp, 0)); // this
2172 __ mov(MemOperand(esp, kPointerSize), scratch2); // this 2193 __ mov(MemOperand(esp, kPointerSize), scratch2); // this
2173 __ mov(MemOperand(esp, 0), scratch); // home_object 2194 __ mov(MemOperand(esp, 0), scratch); // home_object
2174 // stack: this, home_object. eax: value 2195 // stack: this, home_object. eax: value
2175 EmitNamedSuperPropertyStore(prop); 2196 EmitNamedSuperPropertyStore(prop);
2176 break; 2197 break;
2177 } 2198 }
2178 case KEYED_SUPER_PROPERTY: { 2199 case KEYED_SUPER_PROPERTY: {
2179 __ push(eax); 2200 PushOperand(eax);
2180 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 2201 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
2181 VisitForStackValue( 2202 VisitForStackValue(
2182 prop->obj()->AsSuperPropertyReference()->home_object()); 2203 prop->obj()->AsSuperPropertyReference()->home_object());
2183 VisitForAccumulatorValue(prop->key()); 2204 VisitForAccumulatorValue(prop->key());
2184 Register scratch = ecx; 2205 Register scratch = ecx;
2185 Register scratch2 = edx; 2206 Register scratch2 = edx;
2186 __ mov(scratch2, MemOperand(esp, 2 * kPointerSize)); // value 2207 __ mov(scratch2, MemOperand(esp, 2 * kPointerSize)); // value
2187 // stack: value, this, home_object; eax: key, edx: value 2208 // stack: value, this, home_object; eax: key, edx: value
2188 __ mov(scratch, MemOperand(esp, kPointerSize)); // this 2209 __ mov(scratch, MemOperand(esp, kPointerSize)); // this
2189 __ mov(MemOperand(esp, 2 * kPointerSize), scratch); 2210 __ mov(MemOperand(esp, 2 * kPointerSize), scratch);
2190 __ mov(scratch, MemOperand(esp, 0)); // home_object 2211 __ mov(scratch, MemOperand(esp, 0)); // home_object
2191 __ mov(MemOperand(esp, kPointerSize), scratch); 2212 __ mov(MemOperand(esp, kPointerSize), scratch);
2192 __ mov(MemOperand(esp, 0), eax); 2213 __ mov(MemOperand(esp, 0), eax);
2193 __ mov(eax, scratch2); 2214 __ mov(eax, scratch2);
2194 // stack: this, home_object, key; eax: value. 2215 // stack: this, home_object, key; eax: value.
2195 EmitKeyedSuperPropertyStore(prop); 2216 EmitKeyedSuperPropertyStore(prop);
2196 break; 2217 break;
2197 } 2218 }
2198 case KEYED_PROPERTY: { 2219 case KEYED_PROPERTY: {
2199 __ push(eax); // Preserve value. 2220 PushOperand(eax); // Preserve value.
2200 VisitForStackValue(prop->obj()); 2221 VisitForStackValue(prop->obj());
2201 VisitForAccumulatorValue(prop->key()); 2222 VisitForAccumulatorValue(prop->key());
2202 __ Move(StoreDescriptor::NameRegister(), eax); 2223 __ Move(StoreDescriptor::NameRegister(), eax);
2203 __ pop(StoreDescriptor::ReceiverRegister()); // Receiver. 2224 PopOperand(StoreDescriptor::ReceiverRegister()); // Receiver.
2204 __ pop(StoreDescriptor::ValueRegister()); // Restore value. 2225 PopOperand(StoreDescriptor::ValueRegister()); // Restore value.
2205 EmitLoadStoreICSlot(slot); 2226 EmitLoadStoreICSlot(slot);
2206 Handle<Code> ic = 2227 Handle<Code> ic =
2207 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2228 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2208 CallIC(ic); 2229 CallIC(ic);
2209 break; 2230 break;
2210 } 2231 }
2211 } 2232 }
2212 context()->Plug(eax); 2233 context()->Plug(eax);
2213 } 2234 }
2214 2235
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
2331 2352
2332 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2353 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2333 // Assignment to a property, using a named store IC. 2354 // Assignment to a property, using a named store IC.
2334 // eax : value 2355 // eax : value
2335 // esp[0] : receiver 2356 // esp[0] : receiver
2336 Property* prop = expr->target()->AsProperty(); 2357 Property* prop = expr->target()->AsProperty();
2337 DCHECK(prop != NULL); 2358 DCHECK(prop != NULL);
2338 DCHECK(prop->key()->IsLiteral()); 2359 DCHECK(prop->key()->IsLiteral());
2339 2360
2340 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); 2361 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value());
2341 __ pop(StoreDescriptor::ReceiverRegister()); 2362 PopOperand(StoreDescriptor::ReceiverRegister());
2342 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2363 EmitLoadStoreICSlot(expr->AssignmentSlot());
2343 CallStoreIC(); 2364 CallStoreIC();
2344 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2365 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2345 context()->Plug(eax); 2366 context()->Plug(eax);
2346 } 2367 }
2347 2368
2348 2369
2349 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { 2370 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
2350 // Assignment to named property of super. 2371 // Assignment to named property of super.
2351 // eax : value 2372 // eax : value
2352 // stack : receiver ('this'), home_object 2373 // stack : receiver ('this'), home_object
2353 DCHECK(prop != NULL); 2374 DCHECK(prop != NULL);
2354 Literal* key = prop->key()->AsLiteral(); 2375 Literal* key = prop->key()->AsLiteral();
2355 DCHECK(key != NULL); 2376 DCHECK(key != NULL);
2356 2377
2357 __ push(Immediate(key->value())); 2378 PushOperand(key->value());
2358 __ push(eax); 2379 PushOperand(eax);
2359 __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict 2380 CallRuntimeWithOperands(is_strict(language_mode())
2360 : Runtime::kStoreToSuper_Sloppy)); 2381 ? Runtime::kStoreToSuper_Strict
2382 : Runtime::kStoreToSuper_Sloppy);
2361 } 2383 }
2362 2384
2363 2385
2364 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { 2386 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
2365 // Assignment to named property of super. 2387 // Assignment to named property of super.
2366 // eax : value 2388 // eax : value
2367 // stack : receiver ('this'), home_object, key 2389 // stack : receiver ('this'), home_object, key
2368 2390
2369 __ push(eax); 2391 PushOperand(eax);
2370 __ CallRuntime((is_strict(language_mode()) 2392 CallRuntimeWithOperands(is_strict(language_mode())
2371 ? Runtime::kStoreKeyedToSuper_Strict 2393 ? Runtime::kStoreKeyedToSuper_Strict
2372 : Runtime::kStoreKeyedToSuper_Sloppy)); 2394 : Runtime::kStoreKeyedToSuper_Sloppy);
2373 } 2395 }
2374 2396
2375 2397
2376 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2398 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2377 // Assignment to a property, using a keyed store IC. 2399 // Assignment to a property, using a keyed store IC.
2378 // eax : value 2400 // eax : value
2379 // esp[0] : key 2401 // esp[0] : key
2380 // esp[kPointerSize] : receiver 2402 // esp[kPointerSize] : receiver
2381 2403
2382 __ pop(StoreDescriptor::NameRegister()); // Key. 2404 PopOperand(StoreDescriptor::NameRegister()); // Key.
2383 __ pop(StoreDescriptor::ReceiverRegister()); 2405 PopOperand(StoreDescriptor::ReceiverRegister());
2384 DCHECK(StoreDescriptor::ValueRegister().is(eax)); 2406 DCHECK(StoreDescriptor::ValueRegister().is(eax));
2385 Handle<Code> ic = 2407 Handle<Code> ic =
2386 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2408 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2387 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2409 EmitLoadStoreICSlot(expr->AssignmentSlot());
2388 CallIC(ic); 2410 CallIC(ic);
2389 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2411 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2390 context()->Plug(eax); 2412 context()->Plug(eax);
2391 } 2413 }
2392 2414
2393 2415
(...skipping 11 matching lines...) Expand all
2405 } else { 2427 } else {
2406 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); 2428 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
2407 VisitForStackValue( 2429 VisitForStackValue(
2408 expr->obj()->AsSuperPropertyReference()->home_object()); 2430 expr->obj()->AsSuperPropertyReference()->home_object());
2409 EmitNamedSuperPropertyLoad(expr); 2431 EmitNamedSuperPropertyLoad(expr);
2410 } 2432 }
2411 } else { 2433 } else {
2412 if (!expr->IsSuperAccess()) { 2434 if (!expr->IsSuperAccess()) {
2413 VisitForStackValue(expr->obj()); 2435 VisitForStackValue(expr->obj());
2414 VisitForAccumulatorValue(expr->key()); 2436 VisitForAccumulatorValue(expr->key());
2415 __ pop(LoadDescriptor::ReceiverRegister()); // Object. 2437 PopOperand(LoadDescriptor::ReceiverRegister()); // Object.
2416 __ Move(LoadDescriptor::NameRegister(), result_register()); // Key. 2438 __ Move(LoadDescriptor::NameRegister(), result_register()); // Key.
2417 EmitKeyedPropertyLoad(expr); 2439 EmitKeyedPropertyLoad(expr);
2418 } else { 2440 } else {
2419 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); 2441 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
2420 VisitForStackValue( 2442 VisitForStackValue(
2421 expr->obj()->AsSuperPropertyReference()->home_object()); 2443 expr->obj()->AsSuperPropertyReference()->home_object());
2422 VisitForStackValue(expr->key()); 2444 VisitForStackValue(expr->key());
2423 EmitKeyedSuperPropertyLoad(expr); 2445 EmitKeyedSuperPropertyLoad(expr);
2424 } 2446 }
2425 } 2447 }
(...skipping 15 matching lines...) Expand all
2441 2463
2442 // Get the target function. 2464 // Get the target function.
2443 ConvertReceiverMode convert_mode; 2465 ConvertReceiverMode convert_mode;
2444 if (callee->IsVariableProxy()) { 2466 if (callee->IsVariableProxy()) {
2445 { StackValueContext context(this); 2467 { StackValueContext context(this);
2446 EmitVariableLoad(callee->AsVariableProxy()); 2468 EmitVariableLoad(callee->AsVariableProxy());
2447 PrepareForBailout(callee, NO_REGISTERS); 2469 PrepareForBailout(callee, NO_REGISTERS);
2448 } 2470 }
2449 // Push undefined as receiver. This is patched in the method prologue if it 2471 // Push undefined as receiver. This is patched in the method prologue if it
2450 // is a sloppy mode method. 2472 // is a sloppy mode method.
2451 __ push(Immediate(isolate()->factory()->undefined_value())); 2473 PushOperand(isolate()->factory()->undefined_value());
2452 convert_mode = ConvertReceiverMode::kNullOrUndefined; 2474 convert_mode = ConvertReceiverMode::kNullOrUndefined;
2453 } else { 2475 } else {
2454 // Load the function from the receiver. 2476 // Load the function from the receiver.
2455 DCHECK(callee->IsProperty()); 2477 DCHECK(callee->IsProperty());
2456 DCHECK(!callee->AsProperty()->IsSuperAccess()); 2478 DCHECK(!callee->AsProperty()->IsSuperAccess());
2457 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); 2479 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
2458 EmitNamedPropertyLoad(callee->AsProperty()); 2480 EmitNamedPropertyLoad(callee->AsProperty());
2459 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2481 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2460 // Push the target function under the receiver. 2482 // Push the target function under the receiver.
2461 __ push(Operand(esp, 0)); 2483 PushOperand(Operand(esp, 0));
2462 __ mov(Operand(esp, kPointerSize), eax); 2484 __ mov(Operand(esp, kPointerSize), eax);
2463 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; 2485 convert_mode = ConvertReceiverMode::kNotNullOrUndefined;
2464 } 2486 }
2465 2487
2466 EmitCall(expr, convert_mode); 2488 EmitCall(expr, convert_mode);
2467 } 2489 }
2468 2490
2469 2491
2470 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { 2492 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
2471 SetExpressionPosition(expr); 2493 SetExpressionPosition(expr);
2472 Expression* callee = expr->expression(); 2494 Expression* callee = expr->expression();
2473 DCHECK(callee->IsProperty()); 2495 DCHECK(callee->IsProperty());
2474 Property* prop = callee->AsProperty(); 2496 Property* prop = callee->AsProperty();
2475 DCHECK(prop->IsSuperAccess()); 2497 DCHECK(prop->IsSuperAccess());
2476 2498
2477 Literal* key = prop->key()->AsLiteral(); 2499 Literal* key = prop->key()->AsLiteral();
2478 DCHECK(!key->value()->IsSmi()); 2500 DCHECK(!key->value()->IsSmi());
2479 // Load the function from the receiver. 2501 // Load the function from the receiver.
2480 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); 2502 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
2481 VisitForStackValue(super_ref->home_object()); 2503 VisitForStackValue(super_ref->home_object());
2482 VisitForAccumulatorValue(super_ref->this_var()); 2504 VisitForAccumulatorValue(super_ref->this_var());
2483 __ push(eax); 2505 PushOperand(eax);
2484 __ push(eax); 2506 PushOperand(eax);
2485 __ push(Operand(esp, kPointerSize * 2)); 2507 PushOperand(Operand(esp, kPointerSize * 2));
2486 __ push(Immediate(key->value())); 2508 PushOperand(key->value());
2487 // Stack here: 2509 // Stack here:
2488 // - home_object 2510 // - home_object
2489 // - this (receiver) 2511 // - this (receiver)
2490 // - this (receiver) <-- LoadFromSuper will pop here and below. 2512 // - this (receiver) <-- LoadFromSuper will pop here and below.
2491 // - home_object 2513 // - home_object
2492 // - key 2514 // - key
2493 __ CallRuntime(Runtime::kLoadFromSuper); 2515 CallRuntimeWithOperands(Runtime::kLoadFromSuper);
2494 2516
2495 // Replace home_object with target function. 2517 // Replace home_object with target function.
2496 __ mov(Operand(esp, kPointerSize), eax); 2518 __ mov(Operand(esp, kPointerSize), eax);
2497 2519
2498 // Stack here: 2520 // Stack here:
2499 // - target function 2521 // - target function
2500 // - this (receiver) 2522 // - this (receiver)
2501 EmitCall(expr); 2523 EmitCall(expr);
2502 } 2524 }
2503 2525
2504 2526
2505 // Code common for calls using the IC. 2527 // Code common for calls using the IC.
2506 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2528 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2507 Expression* key) { 2529 Expression* key) {
2508 // Load the key. 2530 // Load the key.
2509 VisitForAccumulatorValue(key); 2531 VisitForAccumulatorValue(key);
2510 2532
2511 Expression* callee = expr->expression(); 2533 Expression* callee = expr->expression();
2512 2534
2513 // Load the function from the receiver. 2535 // Load the function from the receiver.
2514 DCHECK(callee->IsProperty()); 2536 DCHECK(callee->IsProperty());
2515 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); 2537 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
2516 __ mov(LoadDescriptor::NameRegister(), eax); 2538 __ mov(LoadDescriptor::NameRegister(), eax);
2517 EmitKeyedPropertyLoad(callee->AsProperty()); 2539 EmitKeyedPropertyLoad(callee->AsProperty());
2518 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2540 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2519 2541
2520 // Push the target function under the receiver. 2542 // Push the target function under the receiver.
2521 __ push(Operand(esp, 0)); 2543 PushOperand(Operand(esp, 0));
2522 __ mov(Operand(esp, kPointerSize), eax); 2544 __ mov(Operand(esp, kPointerSize), eax);
2523 2545
2524 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); 2546 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined);
2525 } 2547 }
2526 2548
2527 2549
2528 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { 2550 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
2529 Expression* callee = expr->expression(); 2551 Expression* callee = expr->expression();
2530 DCHECK(callee->IsProperty()); 2552 DCHECK(callee->IsProperty());
2531 Property* prop = callee->AsProperty(); 2553 Property* prop = callee->AsProperty();
2532 DCHECK(prop->IsSuperAccess()); 2554 DCHECK(prop->IsSuperAccess());
2533 2555
2534 SetExpressionPosition(prop); 2556 SetExpressionPosition(prop);
2535 // Load the function from the receiver. 2557 // Load the function from the receiver.
2536 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); 2558 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
2537 VisitForStackValue(super_ref->home_object()); 2559 VisitForStackValue(super_ref->home_object());
2538 VisitForAccumulatorValue(super_ref->this_var()); 2560 VisitForAccumulatorValue(super_ref->this_var());
2539 __ push(eax); 2561 PushOperand(eax);
2540 __ push(eax); 2562 PushOperand(eax);
2541 __ push(Operand(esp, kPointerSize * 2)); 2563 PushOperand(Operand(esp, kPointerSize * 2));
2542 VisitForStackValue(prop->key()); 2564 VisitForStackValue(prop->key());
2543 // Stack here: 2565 // Stack here:
2544 // - home_object 2566 // - home_object
2545 // - this (receiver) 2567 // - this (receiver)
2546 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. 2568 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
2547 // - home_object 2569 // - home_object
2548 // - key 2570 // - key
2549 __ CallRuntime(Runtime::kLoadKeyedFromSuper); 2571 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper);
2550 2572
2551 // Replace home_object with target function. 2573 // Replace home_object with target function.
2552 __ mov(Operand(esp, kPointerSize), eax); 2574 __ mov(Operand(esp, kPointerSize), eax);
2553 2575
2554 // Stack here: 2576 // Stack here:
2555 // - target function 2577 // - target function
2556 // - this (receiver) 2578 // - this (receiver)
2557 EmitCall(expr); 2579 EmitCall(expr);
2558 } 2580 }
2559 2581
(...skipping 17 matching lines...) Expand all
2577 EmitProfilingCounterHandlingForReturnSequence(true); 2599 EmitProfilingCounterHandlingForReturnSequence(true);
2578 } 2600 }
2579 Handle<Code> ic = 2601 Handle<Code> ic =
2580 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) 2602 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode())
2581 .code(); 2603 .code();
2582 __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot()))); 2604 __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot())));
2583 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 2605 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
2584 // Don't assign a type feedback id to the IC, since type feedback is provided 2606 // Don't assign a type feedback id to the IC, since type feedback is provided
2585 // by the vector above. 2607 // by the vector above.
2586 CallIC(ic); 2608 CallIC(ic);
2609 OperandStackDepthDecrement(arg_count + 1);
2587 2610
2588 RecordJSReturnSite(expr); 2611 RecordJSReturnSite(expr);
2589 2612
2590 // Restore context register. 2613 // Restore context register.
2591 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2614 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2592 2615
2593 context()->DropAndPlug(1, eax); 2616 context()->DropAndPlug(1, eax);
2594 } 2617 }
2595 2618
2596 2619
(...skipping 27 matching lines...) Expand all
2624 SetExpressionPosition(callee); 2647 SetExpressionPosition(callee);
2625 // Generate code for loading from variables potentially shadowed by 2648 // Generate code for loading from variables potentially shadowed by
2626 // eval-introduced variables. 2649 // eval-introduced variables.
2627 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); 2650 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2628 2651
2629 __ bind(&slow); 2652 __ bind(&slow);
2630 // Call the runtime to find the function to call (returned in eax) and 2653 // Call the runtime to find the function to call (returned in eax) and
2631 // the object holding it (returned in edx). 2654 // the object holding it (returned in edx).
2632 __ Push(callee->name()); 2655 __ Push(callee->name());
2633 __ CallRuntime(Runtime::kLoadLookupSlotForCall); 2656 __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2634 __ Push(eax); // Function. 2657 PushOperand(eax); // Function.
2635 __ Push(edx); // Receiver. 2658 PushOperand(edx); // Receiver.
2636 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); 2659 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
2637 2660
2638 // If fast case code has been generated, emit code to push the function 2661 // If fast case code has been generated, emit code to push the function
2639 // and receiver and have the slow path jump around this code. 2662 // and receiver and have the slow path jump around this code.
2640 if (done.is_linked()) { 2663 if (done.is_linked()) {
2641 Label call; 2664 Label call;
2642 __ jmp(&call, Label::kNear); 2665 __ jmp(&call, Label::kNear);
2643 __ bind(&done); 2666 __ bind(&done);
2644 // Push function. 2667 // Push function.
2645 __ push(eax); 2668 __ push(eax);
2646 // The receiver is implicitly the global receiver. Indicate this by 2669 // The receiver is implicitly the global receiver. Indicate this by
2647 // passing the hole to the call function stub. 2670 // passing the hole to the call function stub.
2648 __ push(Immediate(isolate()->factory()->undefined_value())); 2671 __ push(Immediate(isolate()->factory()->undefined_value()));
2649 __ bind(&call); 2672 __ bind(&call);
2650 } 2673 }
2651 } else { 2674 } else {
2652 VisitForStackValue(callee); 2675 VisitForStackValue(callee);
2653 // refEnv.WithBaseObject() 2676 // refEnv.WithBaseObject()
2654 __ push(Immediate(isolate()->factory()->undefined_value())); 2677 PushOperand(isolate()->factory()->undefined_value());
2655 } 2678 }
2656 } 2679 }
2657 2680
2658 2681
2659 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { 2682 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
2660 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval 2683 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
2661 // to resolve the function we need to call. Then we call the resolved 2684 // to resolve the function we need to call. Then we call the resolved
2662 // function using the given arguments. 2685 // function using the given arguments.
2663 ZoneList<Expression*>* args = expr->arguments(); 2686 ZoneList<Expression*>* args = expr->arguments();
2664 int arg_count = args->length(); 2687 int arg_count = args->length();
(...skipping 14 matching lines...) Expand all
2679 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax); 2702 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
2680 2703
2681 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); 2704 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
2682 2705
2683 SetCallPosition(expr); 2706 SetCallPosition(expr);
2684 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 2707 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
2685 __ Set(eax, arg_count); 2708 __ Set(eax, arg_count);
2686 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, 2709 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2687 expr->tail_call_mode()), 2710 expr->tail_call_mode()),
2688 RelocInfo::CODE_TARGET); 2711 RelocInfo::CODE_TARGET);
2712 OperandStackDepthDecrement(arg_count + 1);
2689 RecordJSReturnSite(expr); 2713 RecordJSReturnSite(expr);
2690 // Restore context register. 2714 // Restore context register.
2691 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2715 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2692 context()->DropAndPlug(1, eax); 2716 context()->DropAndPlug(1, eax);
2693 } 2717 }
2694 2718
2695 2719
2696 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2720 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
2697 Comment cmnt(masm_, "[ CallNew"); 2721 Comment cmnt(masm_, "[ CallNew");
2698 // According to ECMA-262, section 11.2.2, page 44, the function 2722 // According to ECMA-262, section 11.2.2, page 44, the function
(...skipping 20 matching lines...) Expand all
2719 // Load function and argument count into edi and eax. 2743 // Load function and argument count into edi and eax.
2720 __ Move(eax, Immediate(arg_count)); 2744 __ Move(eax, Immediate(arg_count));
2721 __ mov(edi, Operand(esp, arg_count * kPointerSize)); 2745 __ mov(edi, Operand(esp, arg_count * kPointerSize));
2722 2746
2723 // Record call targets in unoptimized code. 2747 // Record call targets in unoptimized code.
2724 __ EmitLoadTypeFeedbackVector(ebx); 2748 __ EmitLoadTypeFeedbackVector(ebx);
2725 __ mov(edx, Immediate(SmiFromSlot(expr->CallNewFeedbackSlot()))); 2749 __ mov(edx, Immediate(SmiFromSlot(expr->CallNewFeedbackSlot())));
2726 2750
2727 CallConstructStub stub(isolate()); 2751 CallConstructStub stub(isolate());
2728 __ call(stub.GetCode(), RelocInfo::CODE_TARGET); 2752 __ call(stub.GetCode(), RelocInfo::CODE_TARGET);
2753 OperandStackDepthDecrement(arg_count + 1);
2729 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2754 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2730 // Restore context register. 2755 // Restore context register.
2731 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2756 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2732 context()->Plug(eax); 2757 context()->Plug(eax);
2733 } 2758 }
2734 2759
2735 2760
2736 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { 2761 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
2737 SuperCallReference* super_call_ref = 2762 SuperCallReference* super_call_ref =
2738 expr->expression()->AsSuperCallReference(); 2763 expr->expression()->AsSuperCallReference();
2739 DCHECK_NOT_NULL(super_call_ref); 2764 DCHECK_NOT_NULL(super_call_ref);
2740 2765
2741 // Push the super constructor target on the stack (may be null, 2766 // Push the super constructor target on the stack (may be null,
2742 // but the Construct builtin can deal with that properly). 2767 // but the Construct builtin can deal with that properly).
2743 VisitForAccumulatorValue(super_call_ref->this_function_var()); 2768 VisitForAccumulatorValue(super_call_ref->this_function_var());
2744 __ AssertFunction(result_register()); 2769 __ AssertFunction(result_register());
2745 __ mov(result_register(), 2770 __ mov(result_register(),
2746 FieldOperand(result_register(), HeapObject::kMapOffset)); 2771 FieldOperand(result_register(), HeapObject::kMapOffset));
2747 __ Push(FieldOperand(result_register(), Map::kPrototypeOffset)); 2772 PushOperand(FieldOperand(result_register(), Map::kPrototypeOffset));
2748 2773
2749 // Push the arguments ("left-to-right") on the stack. 2774 // Push the arguments ("left-to-right") on the stack.
2750 ZoneList<Expression*>* args = expr->arguments(); 2775 ZoneList<Expression*>* args = expr->arguments();
2751 int arg_count = args->length(); 2776 int arg_count = args->length();
2752 for (int i = 0; i < arg_count; i++) { 2777 for (int i = 0; i < arg_count; i++) {
2753 VisitForStackValue(args->at(i)); 2778 VisitForStackValue(args->at(i));
2754 } 2779 }
2755 2780
2756 // Call the construct call builtin that handles allocation and 2781 // Call the construct call builtin that handles allocation and
2757 // constructor invocation. 2782 // constructor invocation.
2758 SetConstructCallPosition(expr); 2783 SetConstructCallPosition(expr);
2759 2784
2760 // Load new target into edx. 2785 // Load new target into edx.
2761 VisitForAccumulatorValue(super_call_ref->new_target_var()); 2786 VisitForAccumulatorValue(super_call_ref->new_target_var());
2762 __ mov(edx, result_register()); 2787 __ mov(edx, result_register());
2763 2788
2764 // Load function and argument count into edi and eax. 2789 // Load function and argument count into edi and eax.
2765 __ Move(eax, Immediate(arg_count)); 2790 __ Move(eax, Immediate(arg_count));
2766 __ mov(edi, Operand(esp, arg_count * kPointerSize)); 2791 __ mov(edi, Operand(esp, arg_count * kPointerSize));
2767 2792
2768 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 2793 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
2794 OperandStackDepthDecrement(arg_count + 1);
2769 2795
2770 RecordJSReturnSite(expr); 2796 RecordJSReturnSite(expr);
2771 2797
2772 // Restore context register. 2798 // Restore context register.
2773 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2799 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2774 context()->Plug(eax); 2800 context()->Plug(eax);
2775 } 2801 }
2776 2802
2777 2803
2778 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2804 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
2979 DCHECK_EQ(3, args->length()); 3005 DCHECK_EQ(3, args->length());
2980 3006
2981 Register string = eax; 3007 Register string = eax;
2982 Register index = ebx; 3008 Register index = ebx;
2983 Register value = ecx; 3009 Register value = ecx;
2984 3010
2985 VisitForStackValue(args->at(0)); // index 3011 VisitForStackValue(args->at(0)); // index
2986 VisitForStackValue(args->at(1)); // value 3012 VisitForStackValue(args->at(1)); // value
2987 VisitForAccumulatorValue(args->at(2)); // string 3013 VisitForAccumulatorValue(args->at(2)); // string
2988 3014
2989 __ pop(value); 3015 PopOperand(value);
2990 __ pop(index); 3016 PopOperand(index);
2991 3017
2992 if (FLAG_debug_code) { 3018 if (FLAG_debug_code) {
2993 __ test(value, Immediate(kSmiTagMask)); 3019 __ test(value, Immediate(kSmiTagMask));
2994 __ Check(zero, kNonSmiValue); 3020 __ Check(zero, kNonSmiValue);
2995 __ test(index, Immediate(kSmiTagMask)); 3021 __ test(index, Immediate(kSmiTagMask));
2996 __ Check(zero, kNonSmiValue); 3022 __ Check(zero, kNonSmiValue);
2997 } 3023 }
2998 3024
2999 __ SmiUntag(value); 3025 __ SmiUntag(value);
3000 __ SmiUntag(index); 3026 __ SmiUntag(index);
(...skipping 13 matching lines...) Expand all
3014 ZoneList<Expression*>* args = expr->arguments(); 3040 ZoneList<Expression*>* args = expr->arguments();
3015 DCHECK_EQ(3, args->length()); 3041 DCHECK_EQ(3, args->length());
3016 3042
3017 Register string = eax; 3043 Register string = eax;
3018 Register index = ebx; 3044 Register index = ebx;
3019 Register value = ecx; 3045 Register value = ecx;
3020 3046
3021 VisitForStackValue(args->at(0)); // index 3047 VisitForStackValue(args->at(0)); // index
3022 VisitForStackValue(args->at(1)); // value 3048 VisitForStackValue(args->at(1)); // value
3023 VisitForAccumulatorValue(args->at(2)); // string 3049 VisitForAccumulatorValue(args->at(2)); // string
3024 __ pop(value); 3050 PopOperand(value);
3025 __ pop(index); 3051 PopOperand(index);
3026 3052
3027 if (FLAG_debug_code) { 3053 if (FLAG_debug_code) {
3028 __ test(value, Immediate(kSmiTagMask)); 3054 __ test(value, Immediate(kSmiTagMask));
3029 __ Check(zero, kNonSmiValue); 3055 __ Check(zero, kNonSmiValue);
3030 __ test(index, Immediate(kSmiTagMask)); 3056 __ test(index, Immediate(kSmiTagMask));
3031 __ Check(zero, kNonSmiValue); 3057 __ Check(zero, kNonSmiValue);
3032 __ SmiUntag(index); 3058 __ SmiUntag(index);
3033 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; 3059 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
3034 __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type); 3060 __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type);
3035 __ SmiTag(index); 3061 __ SmiTag(index);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3083 ZoneList<Expression*>* args = expr->arguments(); 3109 ZoneList<Expression*>* args = expr->arguments();
3084 DCHECK(args->length() == 2); 3110 DCHECK(args->length() == 2);
3085 3111
3086 VisitForStackValue(args->at(0)); 3112 VisitForStackValue(args->at(0));
3087 VisitForAccumulatorValue(args->at(1)); 3113 VisitForAccumulatorValue(args->at(1));
3088 3114
3089 Register object = ebx; 3115 Register object = ebx;
3090 Register index = eax; 3116 Register index = eax;
3091 Register result = edx; 3117 Register result = edx;
3092 3118
3093 __ pop(object); 3119 PopOperand(object);
3094 3120
3095 Label need_conversion; 3121 Label need_conversion;
3096 Label index_out_of_range; 3122 Label index_out_of_range;
3097 Label done; 3123 Label done;
3098 StringCharCodeAtGenerator generator(object, 3124 StringCharCodeAtGenerator generator(object,
3099 index, 3125 index,
3100 result, 3126 result,
3101 &need_conversion, 3127 &need_conversion,
3102 &need_conversion, 3128 &need_conversion,
3103 &index_out_of_range, 3129 &index_out_of_range,
(...skipping 26 matching lines...) Expand all
3130 DCHECK(args->length() == 2); 3156 DCHECK(args->length() == 2);
3131 3157
3132 VisitForStackValue(args->at(0)); 3158 VisitForStackValue(args->at(0));
3133 VisitForAccumulatorValue(args->at(1)); 3159 VisitForAccumulatorValue(args->at(1));
3134 3160
3135 Register object = ebx; 3161 Register object = ebx;
3136 Register index = eax; 3162 Register index = eax;
3137 Register scratch = edx; 3163 Register scratch = edx;
3138 Register result = eax; 3164 Register result = eax;
3139 3165
3140 __ pop(object); 3166 PopOperand(object);
3141 3167
3142 Label need_conversion; 3168 Label need_conversion;
3143 Label index_out_of_range; 3169 Label index_out_of_range;
3144 Label done; 3170 Label done;
3145 StringCharAtGenerator generator(object, 3171 StringCharAtGenerator generator(object,
3146 index, 3172 index,
3147 scratch, 3173 scratch,
3148 result, 3174 result,
3149 &need_conversion, 3175 &need_conversion,
3150 &need_conversion, 3176 &need_conversion,
(...skipping 29 matching lines...) Expand all
3180 for (Expression* const arg : *args) { 3206 for (Expression* const arg : *args) {
3181 VisitForStackValue(arg); 3207 VisitForStackValue(arg);
3182 } 3208 }
3183 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3209 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3184 // Move target to edi. 3210 // Move target to edi.
3185 int const argc = args->length() - 2; 3211 int const argc = args->length() - 2;
3186 __ mov(edi, Operand(esp, (argc + 1) * kPointerSize)); 3212 __ mov(edi, Operand(esp, (argc + 1) * kPointerSize));
3187 // Call the target. 3213 // Call the target.
3188 __ mov(eax, Immediate(argc)); 3214 __ mov(eax, Immediate(argc));
3189 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 3215 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
3216 OperandStackDepthDecrement(argc + 1);
3190 // Restore context register. 3217 // Restore context register.
3191 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3218 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3192 // Discard the function left on TOS. 3219 // Discard the function left on TOS.
3193 context()->DropAndPlug(1, eax); 3220 context()->DropAndPlug(1, eax);
3194 } 3221 }
3195 3222
3196 3223
3197 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { 3224 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) {
3198 ZoneList<Expression*>* args = expr->arguments(); 3225 ZoneList<Expression*>* args = expr->arguments();
3199 DCHECK(args->length() == 1); 3226 DCHECK(args->length() == 1);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
3268 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), 3295 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset),
3269 isolate()->factory()->empty_fixed_array()); 3296 isolate()->factory()->empty_fixed_array());
3270 __ mov(FieldOperand(eax, JSObject::kElementsOffset), 3297 __ mov(FieldOperand(eax, JSObject::kElementsOffset),
3271 isolate()->factory()->empty_fixed_array()); 3298 isolate()->factory()->empty_fixed_array());
3272 __ pop(FieldOperand(eax, JSIteratorResult::kDoneOffset)); 3299 __ pop(FieldOperand(eax, JSIteratorResult::kDoneOffset));
3273 __ pop(FieldOperand(eax, JSIteratorResult::kValueOffset)); 3300 __ pop(FieldOperand(eax, JSIteratorResult::kValueOffset));
3274 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); 3301 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize);
3275 __ jmp(&done, Label::kNear); 3302 __ jmp(&done, Label::kNear);
3276 3303
3277 __ bind(&runtime); 3304 __ bind(&runtime);
3278 __ CallRuntime(Runtime::kCreateIterResultObject); 3305 CallRuntimeWithOperands(Runtime::kCreateIterResultObject);
3279 3306
3280 __ bind(&done); 3307 __ bind(&done);
3281 context()->Plug(eax); 3308 context()->Plug(eax);
3282 } 3309 }
3283 3310
3284 3311
3285 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { 3312 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
3286 // Push undefined as receiver. 3313 // Push undefined as receiver.
3287 __ push(Immediate(isolate()->factory()->undefined_value())); 3314 PushOperand(isolate()->factory()->undefined_value());
3288 3315
3289 __ LoadGlobalFunction(expr->context_index(), eax); 3316 __ LoadGlobalFunction(expr->context_index(), eax);
3290 } 3317 }
3291 3318
3292 3319
3293 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { 3320 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
3294 ZoneList<Expression*>* args = expr->arguments(); 3321 ZoneList<Expression*>* args = expr->arguments();
3295 int arg_count = args->length(); 3322 int arg_count = args->length();
3296 3323
3297 SetCallPosition(expr); 3324 SetCallPosition(expr);
3298 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 3325 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
3299 __ Set(eax, arg_count); 3326 __ Set(eax, arg_count);
3300 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), 3327 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined),
3301 RelocInfo::CODE_TARGET); 3328 RelocInfo::CODE_TARGET);
3329 OperandStackDepthDecrement(arg_count + 1);
3302 } 3330 }
3303 3331
3304 3332
3305 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 3333 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
3306 ZoneList<Expression*>* args = expr->arguments(); 3334 ZoneList<Expression*>* args = expr->arguments();
3307 int arg_count = args->length(); 3335 int arg_count = args->length();
3308 3336
3309 if (expr->is_jsruntime()) { 3337 if (expr->is_jsruntime()) {
3310 Comment cmnt(masm_, "[ CallRuntime"); 3338 Comment cmnt(masm_, "[ CallRuntime");
3311 EmitLoadJSRuntimeFunction(expr); 3339 EmitLoadJSRuntimeFunction(expr);
3312 3340
3313 // Push the target function under the receiver. 3341 // Push the target function under the receiver.
3314 __ push(Operand(esp, 0)); 3342 PushOperand(Operand(esp, 0));
3315 __ mov(Operand(esp, kPointerSize), eax); 3343 __ mov(Operand(esp, kPointerSize), eax);
3316 3344
3317 // Push the arguments ("left-to-right"). 3345 // Push the arguments ("left-to-right").
3318 for (int i = 0; i < arg_count; i++) { 3346 for (int i = 0; i < arg_count; i++) {
3319 VisitForStackValue(args->at(i)); 3347 VisitForStackValue(args->at(i));
3320 } 3348 }
3321 3349
3322 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3350 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3323 EmitCallJSRuntimeFunction(expr); 3351 EmitCallJSRuntimeFunction(expr);
3324 3352
(...skipping 14 matching lines...) Expand all
3339 default: { 3367 default: {
3340 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic"); 3368 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic");
3341 // Push the arguments ("left-to-right"). 3369 // Push the arguments ("left-to-right").
3342 for (int i = 0; i < arg_count; i++) { 3370 for (int i = 0; i < arg_count; i++) {
3343 VisitForStackValue(args->at(i)); 3371 VisitForStackValue(args->at(i));
3344 } 3372 }
3345 3373
3346 // Call the C runtime function. 3374 // Call the C runtime function.
3347 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3375 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3348 __ CallRuntime(expr->function(), arg_count); 3376 __ CallRuntime(expr->function(), arg_count);
3377 OperandStackDepthDecrement(arg_count);
3349 context()->Plug(eax); 3378 context()->Plug(eax);
3350 } 3379 }
3351 } 3380 }
3352 } 3381 }
3353 } 3382 }
3354 3383
3355 3384
3356 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3385 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
3357 switch (expr->op()) { 3386 switch (expr->op()) {
3358 case Token::DELETE: { 3387 case Token::DELETE: {
3359 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3388 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3360 Property* property = expr->expression()->AsProperty(); 3389 Property* property = expr->expression()->AsProperty();
3361 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 3390 VariableProxy* proxy = expr->expression()->AsVariableProxy();
3362 3391
3363 if (property != NULL) { 3392 if (property != NULL) {
3364 VisitForStackValue(property->obj()); 3393 VisitForStackValue(property->obj());
3365 VisitForStackValue(property->key()); 3394 VisitForStackValue(property->key());
3366 __ CallRuntime(is_strict(language_mode()) 3395 CallRuntimeWithOperands(is_strict(language_mode())
3367 ? Runtime::kDeleteProperty_Strict 3396 ? Runtime::kDeleteProperty_Strict
3368 : Runtime::kDeleteProperty_Sloppy); 3397 : Runtime::kDeleteProperty_Sloppy);
3369 context()->Plug(eax); 3398 context()->Plug(eax);
3370 } else if (proxy != NULL) { 3399 } else if (proxy != NULL) {
3371 Variable* var = proxy->var(); 3400 Variable* var = proxy->var();
3372 // Delete of an unqualified identifier is disallowed in strict mode but 3401 // Delete of an unqualified identifier is disallowed in strict mode but
3373 // "delete this" is allowed. 3402 // "delete this" is allowed.
3374 bool is_this = var->HasThisName(isolate()); 3403 bool is_this = var->HasThisName(isolate());
3375 DCHECK(is_sloppy(language_mode()) || is_this); 3404 DCHECK(is_sloppy(language_mode()) || is_this);
3376 if (var->IsUnallocatedOrGlobalSlot()) { 3405 if (var->IsUnallocatedOrGlobalSlot()) {
3377 __ mov(eax, NativeContextOperand()); 3406 __ mov(eax, NativeContextOperand());
3378 __ push(ContextOperand(eax, Context::EXTENSION_INDEX)); 3407 __ push(ContextOperand(eax, Context::EXTENSION_INDEX));
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
3425 // We handle value contexts explicitly rather than simply visiting 3454 // We handle value contexts explicitly rather than simply visiting
3426 // for control and plugging the control flow into the context, 3455 // for control and plugging the control flow into the context,
3427 // because we need to prepare a pair of extra administrative AST ids 3456 // because we need to prepare a pair of extra administrative AST ids
3428 // for the optimizing compiler. 3457 // for the optimizing compiler.
3429 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); 3458 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue());
3430 Label materialize_true, materialize_false, done; 3459 Label materialize_true, materialize_false, done;
3431 VisitForControl(expr->expression(), 3460 VisitForControl(expr->expression(),
3432 &materialize_false, 3461 &materialize_false,
3433 &materialize_true, 3462 &materialize_true,
3434 &materialize_true); 3463 &materialize_true);
3464 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1);
3435 __ bind(&materialize_true); 3465 __ bind(&materialize_true);
3436 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); 3466 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS);
3437 if (context()->IsAccumulatorValue()) { 3467 if (context()->IsAccumulatorValue()) {
3438 __ mov(eax, isolate()->factory()->true_value()); 3468 __ mov(eax, isolate()->factory()->true_value());
3439 } else { 3469 } else {
3440 __ Push(isolate()->factory()->true_value()); 3470 __ Push(isolate()->factory()->true_value());
3441 } 3471 }
3442 __ jmp(&done, Label::kNear); 3472 __ jmp(&done, Label::kNear);
3443 __ bind(&materialize_false); 3473 __ bind(&materialize_false);
3444 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); 3474 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3480 LhsKind assign_type = Property::GetAssignType(prop); 3510 LhsKind assign_type = Property::GetAssignType(prop);
3481 3511
3482 // Evaluate expression and get value. 3512 // Evaluate expression and get value.
3483 if (assign_type == VARIABLE) { 3513 if (assign_type == VARIABLE) {
3484 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); 3514 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL);
3485 AccumulatorValueContext context(this); 3515 AccumulatorValueContext context(this);
3486 EmitVariableLoad(expr->expression()->AsVariableProxy()); 3516 EmitVariableLoad(expr->expression()->AsVariableProxy());
3487 } else { 3517 } else {
3488 // Reserve space for result of postfix operation. 3518 // Reserve space for result of postfix operation.
3489 if (expr->is_postfix() && !context()->IsEffect()) { 3519 if (expr->is_postfix() && !context()->IsEffect()) {
3490 __ push(Immediate(Smi::FromInt(0))); 3520 PushOperand(Smi::FromInt(0));
3491 } 3521 }
3492 switch (assign_type) { 3522 switch (assign_type) {
3493 case NAMED_PROPERTY: { 3523 case NAMED_PROPERTY: {
3494 // Put the object both on the stack and in the register. 3524 // Put the object both on the stack and in the register.
3495 VisitForStackValue(prop->obj()); 3525 VisitForStackValue(prop->obj());
3496 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); 3526 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
3497 EmitNamedPropertyLoad(prop); 3527 EmitNamedPropertyLoad(prop);
3498 break; 3528 break;
3499 } 3529 }
3500 3530
3501 case NAMED_SUPER_PROPERTY: { 3531 case NAMED_SUPER_PROPERTY: {
3502 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 3532 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
3503 VisitForAccumulatorValue( 3533 VisitForAccumulatorValue(
3504 prop->obj()->AsSuperPropertyReference()->home_object()); 3534 prop->obj()->AsSuperPropertyReference()->home_object());
3505 __ push(result_register()); 3535 PushOperand(result_register());
3506 __ push(MemOperand(esp, kPointerSize)); 3536 PushOperand(MemOperand(esp, kPointerSize));
3507 __ push(result_register()); 3537 PushOperand(result_register());
3508 EmitNamedSuperPropertyLoad(prop); 3538 EmitNamedSuperPropertyLoad(prop);
3509 break; 3539 break;
3510 } 3540 }
3511 3541
3512 case KEYED_SUPER_PROPERTY: { 3542 case KEYED_SUPER_PROPERTY: {
3513 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); 3543 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
3514 VisitForStackValue( 3544 VisitForStackValue(
3515 prop->obj()->AsSuperPropertyReference()->home_object()); 3545 prop->obj()->AsSuperPropertyReference()->home_object());
3516 VisitForAccumulatorValue(prop->key()); 3546 VisitForAccumulatorValue(prop->key());
3517 __ push(result_register()); 3547 PushOperand(result_register());
3518 __ push(MemOperand(esp, 2 * kPointerSize)); 3548 PushOperand(MemOperand(esp, 2 * kPointerSize));
3519 __ push(MemOperand(esp, 2 * kPointerSize)); 3549 PushOperand(MemOperand(esp, 2 * kPointerSize));
3520 __ push(result_register()); 3550 PushOperand(result_register());
3521 EmitKeyedSuperPropertyLoad(prop); 3551 EmitKeyedSuperPropertyLoad(prop);
3522 break; 3552 break;
3523 } 3553 }
3524 3554
3525 case KEYED_PROPERTY: { 3555 case KEYED_PROPERTY: {
3526 VisitForStackValue(prop->obj()); 3556 VisitForStackValue(prop->obj());
3527 VisitForStackValue(prop->key()); 3557 VisitForStackValue(prop->key());
3528 __ mov(LoadDescriptor::ReceiverRegister(), 3558 __ mov(LoadDescriptor::ReceiverRegister(),
3529 Operand(esp, kPointerSize)); // Object. 3559 Operand(esp, kPointerSize)); // Object.
3530 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); // Key. 3560 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); // Key.
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
3600 } 3630 }
3601 3631
3602 // Save result for postfix expressions. 3632 // Save result for postfix expressions.
3603 if (expr->is_postfix()) { 3633 if (expr->is_postfix()) {
3604 if (!context()->IsEffect()) { 3634 if (!context()->IsEffect()) {
3605 // Save the result on the stack. If we have a named or keyed property 3635 // Save the result on the stack. If we have a named or keyed property
3606 // we store the result under the receiver that is currently on top 3636 // we store the result under the receiver that is currently on top
3607 // of the stack. 3637 // of the stack.
3608 switch (assign_type) { 3638 switch (assign_type) {
3609 case VARIABLE: 3639 case VARIABLE:
3610 __ push(eax); 3640 PushOperand(eax);
3611 break; 3641 break;
3612 case NAMED_PROPERTY: 3642 case NAMED_PROPERTY:
3613 __ mov(Operand(esp, kPointerSize), eax); 3643 __ mov(Operand(esp, kPointerSize), eax);
3614 break; 3644 break;
3615 case NAMED_SUPER_PROPERTY: 3645 case NAMED_SUPER_PROPERTY:
3616 __ mov(Operand(esp, 2 * kPointerSize), eax); 3646 __ mov(Operand(esp, 2 * kPointerSize), eax);
3617 break; 3647 break;
3618 case KEYED_PROPERTY: 3648 case KEYED_PROPERTY:
3619 __ mov(Operand(esp, 2 * kPointerSize), eax); 3649 __ mov(Operand(esp, 2 * kPointerSize), eax);
3620 break; 3650 break;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
3660 // Perform the assignment as if via '='. 3690 // Perform the assignment as if via '='.
3661 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3691 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3662 Token::ASSIGN, expr->CountSlot()); 3692 Token::ASSIGN, expr->CountSlot());
3663 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3693 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3664 context()->Plug(eax); 3694 context()->Plug(eax);
3665 } 3695 }
3666 break; 3696 break;
3667 case NAMED_PROPERTY: { 3697 case NAMED_PROPERTY: {
3668 __ mov(StoreDescriptor::NameRegister(), 3698 __ mov(StoreDescriptor::NameRegister(),
3669 prop->key()->AsLiteral()->value()); 3699 prop->key()->AsLiteral()->value());
3670 __ pop(StoreDescriptor::ReceiverRegister()); 3700 PopOperand(StoreDescriptor::ReceiverRegister());
3671 EmitLoadStoreICSlot(expr->CountSlot()); 3701 EmitLoadStoreICSlot(expr->CountSlot());
3672 CallStoreIC(); 3702 CallStoreIC();
3673 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3703 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3674 if (expr->is_postfix()) { 3704 if (expr->is_postfix()) {
3675 if (!context()->IsEffect()) { 3705 if (!context()->IsEffect()) {
3676 context()->PlugTOS(); 3706 context()->PlugTOS();
3677 } 3707 }
3678 } else { 3708 } else {
3679 context()->Plug(eax); 3709 context()->Plug(eax);
3680 } 3710 }
(...skipping 15 matching lines...) Expand all
3696 if (expr->is_postfix()) { 3726 if (expr->is_postfix()) {
3697 if (!context()->IsEffect()) { 3727 if (!context()->IsEffect()) {
3698 context()->PlugTOS(); 3728 context()->PlugTOS();
3699 } 3729 }
3700 } else { 3730 } else {
3701 context()->Plug(eax); 3731 context()->Plug(eax);
3702 } 3732 }
3703 break; 3733 break;
3704 } 3734 }
3705 case KEYED_PROPERTY: { 3735 case KEYED_PROPERTY: {
3706 __ pop(StoreDescriptor::NameRegister()); 3736 PopOperand(StoreDescriptor::NameRegister());
3707 __ pop(StoreDescriptor::ReceiverRegister()); 3737 PopOperand(StoreDescriptor::ReceiverRegister());
3708 Handle<Code> ic = 3738 Handle<Code> ic =
3709 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 3739 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
3710 EmitLoadStoreICSlot(expr->CountSlot()); 3740 EmitLoadStoreICSlot(expr->CountSlot());
3711 CallIC(ic); 3741 CallIC(ic);
3712 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3742 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3713 if (expr->is_postfix()) { 3743 if (expr->is_postfix()) {
3714 // Result is on the stack 3744 // Result is on the stack
3715 if (!context()->IsEffect()) { 3745 if (!context()->IsEffect()) {
3716 context()->PlugTOS(); 3746 context()->PlugTOS();
3717 } 3747 }
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
3818 Label* if_false = NULL; 3848 Label* if_false = NULL;
3819 Label* fall_through = NULL; 3849 Label* fall_through = NULL;
3820 context()->PrepareTest(&materialize_true, &materialize_false, 3850 context()->PrepareTest(&materialize_true, &materialize_false,
3821 &if_true, &if_false, &fall_through); 3851 &if_true, &if_false, &fall_through);
3822 3852
3823 Token::Value op = expr->op(); 3853 Token::Value op = expr->op();
3824 VisitForStackValue(expr->left()); 3854 VisitForStackValue(expr->left());
3825 switch (op) { 3855 switch (op) {
3826 case Token::IN: 3856 case Token::IN:
3827 VisitForStackValue(expr->right()); 3857 VisitForStackValue(expr->right());
3828 __ CallRuntime(Runtime::kHasProperty); 3858 CallRuntimeWithOperands(Runtime::kHasProperty);
3829 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 3859 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
3830 __ cmp(eax, isolate()->factory()->true_value()); 3860 __ cmp(eax, isolate()->factory()->true_value());
3831 Split(equal, if_true, if_false, fall_through); 3861 Split(equal, if_true, if_false, fall_through);
3832 break; 3862 break;
3833 3863
3834 case Token::INSTANCEOF: { 3864 case Token::INSTANCEOF: {
3835 VisitForAccumulatorValue(expr->right()); 3865 VisitForAccumulatorValue(expr->right());
3836 __ Pop(edx); 3866 PopOperand(edx);
3837 InstanceOfStub stub(isolate()); 3867 InstanceOfStub stub(isolate());
3838 __ CallStub(&stub); 3868 __ CallStub(&stub);
3839 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 3869 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
3840 __ cmp(eax, isolate()->factory()->true_value()); 3870 __ cmp(eax, isolate()->factory()->true_value());
3841 Split(equal, if_true, if_false, fall_through); 3871 Split(equal, if_true, if_false, fall_through);
3842 break; 3872 break;
3843 } 3873 }
3844 3874
3845 default: { 3875 default: {
3846 VisitForAccumulatorValue(expr->right()); 3876 VisitForAccumulatorValue(expr->right());
3847 Condition cc = CompareIC::ComputeCondition(op); 3877 Condition cc = CompareIC::ComputeCondition(op);
3848 __ pop(edx); 3878 PopOperand(edx);
3849 3879
3850 bool inline_smi_code = ShouldInlineSmiCase(op); 3880 bool inline_smi_code = ShouldInlineSmiCase(op);
3851 JumpPatchSite patch_site(masm_); 3881 JumpPatchSite patch_site(masm_);
3852 if (inline_smi_code) { 3882 if (inline_smi_code) {
3853 Label slow_case; 3883 Label slow_case;
3854 __ mov(ecx, edx); 3884 __ mov(ecx, edx);
3855 __ or_(ecx, eax); 3885 __ or_(ecx, eax);
3856 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); 3886 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear);
3857 __ cmp(edx, eax); 3887 __ cmp(edx, eax);
3858 Split(cc, if_true, if_false, NULL); 3888 Split(cc, if_true, if_false, NULL);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
3932 3962
3933 3963
3934 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() { 3964 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
3935 Scope* closure_scope = scope()->ClosureScope(); 3965 Scope* closure_scope = scope()->ClosureScope();
3936 if (closure_scope->is_script_scope() || 3966 if (closure_scope->is_script_scope() ||
3937 closure_scope->is_module_scope()) { 3967 closure_scope->is_module_scope()) {
3938 // Contexts nested in the native context have a canonical empty function 3968 // Contexts nested in the native context have a canonical empty function
3939 // as their closure, not the anonymous closure containing the global 3969 // as their closure, not the anonymous closure containing the global
3940 // code. 3970 // code.
3941 __ mov(eax, NativeContextOperand()); 3971 __ mov(eax, NativeContextOperand());
3942 __ push(ContextOperand(eax, Context::CLOSURE_INDEX)); 3972 PushOperand(ContextOperand(eax, Context::CLOSURE_INDEX));
3943 } else if (closure_scope->is_eval_scope()) { 3973 } else if (closure_scope->is_eval_scope()) {
3944 // Contexts nested inside eval code have the same closure as the context 3974 // Contexts nested inside eval code have the same closure as the context
3945 // calling eval, not the anonymous closure containing the eval code. 3975 // calling eval, not the anonymous closure containing the eval code.
3946 // Fetch it from the context. 3976 // Fetch it from the context.
3947 __ push(ContextOperand(esi, Context::CLOSURE_INDEX)); 3977 PushOperand(ContextOperand(esi, Context::CLOSURE_INDEX));
3948 } else { 3978 } else {
3949 DCHECK(closure_scope->is_function_scope()); 3979 DCHECK(closure_scope->is_function_scope());
3950 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 3980 PushOperand(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
3951 } 3981 }
3952 } 3982 }
3953 3983
3954 3984
3955 // ---------------------------------------------------------------------------- 3985 // ----------------------------------------------------------------------------
3956 // Non-local control flow support. 3986 // Non-local control flow support.
3957 3987
3958 void FullCodeGenerator::EnterFinallyBlock() { 3988 void FullCodeGenerator::EnterFinallyBlock() {
3959 // Store pending message while executing finally block. 3989 // Store pending message while executing finally block.
3960 ExternalReference pending_message_obj = 3990 ExternalReference pending_message_obj =
3961 ExternalReference::address_of_pending_message_obj(isolate()); 3991 ExternalReference::address_of_pending_message_obj(isolate());
3962 __ mov(edx, Operand::StaticVariable(pending_message_obj)); 3992 __ mov(edx, Operand::StaticVariable(pending_message_obj));
3963 __ push(edx); 3993 PushOperand(edx);
3964 3994
3965 ClearPendingMessage(); 3995 ClearPendingMessage();
3966 } 3996 }
3967 3997
3968 3998
3969 void FullCodeGenerator::ExitFinallyBlock() { 3999 void FullCodeGenerator::ExitFinallyBlock() {
3970 DCHECK(!result_register().is(edx)); 4000 DCHECK(!result_register().is(edx));
3971 // Restore pending message from stack. 4001 // Restore pending message from stack.
3972 __ pop(edx); 4002 PopOperand(edx);
3973 ExternalReference pending_message_obj = 4003 ExternalReference pending_message_obj =
3974 ExternalReference::address_of_pending_message_obj(isolate()); 4004 ExternalReference::address_of_pending_message_obj(isolate());
3975 __ mov(Operand::StaticVariable(pending_message_obj), edx); 4005 __ mov(Operand::StaticVariable(pending_message_obj), edx);
3976 } 4006 }
3977 4007
3978 4008
3979 void FullCodeGenerator::ClearPendingMessage() { 4009 void FullCodeGenerator::ClearPendingMessage() {
3980 DCHECK(!result_register().is(edx)); 4010 DCHECK(!result_register().is(edx));
3981 ExternalReference pending_message_obj = 4011 ExternalReference pending_message_obj =
3982 ExternalReference::address_of_pending_message_obj(isolate()); 4012 ExternalReference::address_of_pending_message_obj(isolate());
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
4095 Assembler::target_address_at(call_target_address, 4125 Assembler::target_address_at(call_target_address,
4096 unoptimized_code)); 4126 unoptimized_code));
4097 return OSR_AFTER_STACK_CHECK; 4127 return OSR_AFTER_STACK_CHECK;
4098 } 4128 }
4099 4129
4100 4130
4101 } // namespace internal 4131 } // namespace internal
4102 } // namespace v8 4132 } // namespace v8
4103 4133
4104 #endif // V8_TARGET_ARCH_X87 4134 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698