| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #if V8_TARGET_ARCH_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 Loading... |
| 112 // the frame (that is done below). | 112 // the frame (that is done below). |
| 113 FrameScope frame_scope(masm_, StackFrame::MANUAL); | 113 FrameScope frame_scope(masm_, StackFrame::MANUAL); |
| 114 | 114 |
| 115 info->set_prologue_offset(masm_->pc_offset()); | 115 info->set_prologue_offset(masm_->pc_offset()); |
| 116 __ Prologue(info->GeneratePreagedPrologue()); | 116 __ Prologue(info->GeneratePreagedPrologue()); |
| 117 | 117 |
| 118 { Comment cmnt(masm_, "[ Allocate locals"); | 118 { Comment cmnt(masm_, "[ Allocate locals"); |
| 119 int locals_count = info->scope()->num_stack_slots(); | 119 int locals_count = info->scope()->num_stack_slots(); |
| 120 // Generators allocate locals, if any, in context slots. | 120 // Generators allocate locals, if any, in context slots. |
| 121 DCHECK(!IsGeneratorFunction(literal()->kind()) || locals_count == 0); | 121 DCHECK(!IsGeneratorFunction(literal()->kind()) || locals_count == 0); |
| 122 OperandStackDepthIncrement(locals_count); |
| 122 if (locals_count == 1) { | 123 if (locals_count == 1) { |
| 123 __ push(Immediate(isolate()->factory()->undefined_value())); | 124 __ push(Immediate(isolate()->factory()->undefined_value())); |
| 124 } else if (locals_count > 1) { | 125 } else if (locals_count > 1) { |
| 125 if (locals_count >= 128) { | 126 if (locals_count >= 128) { |
| 126 Label ok; | 127 Label ok; |
| 127 __ mov(ecx, esp); | 128 __ mov(ecx, esp); |
| 128 __ sub(ecx, Immediate(locals_count * kPointerSize)); | 129 __ sub(ecx, Immediate(locals_count * kPointerSize)); |
| 129 ExternalReference stack_limit = | 130 ExternalReference stack_limit = |
| 130 ExternalReference::address_of_real_stack_limit(isolate()); | 131 ExternalReference::address_of_real_stack_limit(isolate()); |
| 131 __ cmp(ecx, Operand::StaticVariable(stack_limit)); | 132 __ cmp(ecx, Operand::StaticVariable(stack_limit)); |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |