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

Side by Side Diff: runtime/vm/code_generator_x64.cc

Issue 9515011: Add support for malformed types and postpone some related errors from compile (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/code_generator_ia32.cc ('k') | runtime/vm/object.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/code_generator.h" 8 #include "vm/code_generator.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 if (num_opt_params == 0) { 417 if (num_opt_params == 0) {
418 __ cmpq(RAX, Immediate(Smi::RawValue(num_fixed_params))); 418 __ cmpq(RAX, Immediate(Smi::RawValue(num_fixed_params)));
419 __ j(EQUAL, &argc_in_range, Assembler::kNearJump); 419 __ j(EQUAL, &argc_in_range, Assembler::kNearJump);
420 } else { 420 } else {
421 __ subq(RAX, Immediate(Smi::RawValue(num_fixed_params))); 421 __ subq(RAX, Immediate(Smi::RawValue(num_fixed_params)));
422 __ cmpq(RAX, Immediate(Smi::RawValue(num_opt_params))); 422 __ cmpq(RAX, Immediate(Smi::RawValue(num_opt_params)));
423 __ j(BELOW_EQUAL, &argc_in_range, Assembler::kNearJump); 423 __ j(BELOW_EQUAL, &argc_in_range, Assembler::kNearJump);
424 } 424 }
425 if (function.IsClosureFunction()) { 425 if (function.IsClosureFunction()) {
426 GenerateCallRuntime(AstNode::kNoId, 426 GenerateCallRuntime(AstNode::kNoId,
427 function.token_index(), 427 0,
428 kClosureArgumentMismatchRuntimeEntry); 428 kClosureArgumentMismatchRuntimeEntry);
429 } else { 429 } else {
430 __ Stop("Wrong number of arguments"); 430 __ Stop("Wrong number of arguments");
431 } 431 }
432 __ Bind(&argc_in_range); 432 __ Bind(&argc_in_range);
433 } 433 }
434 } else { 434 } else {
435 ASSERT(first_param_index == -1); 435 ASSERT(first_param_index == -1);
436 // Copy positional arguments. 436 // Copy positional arguments.
437 // Check that no fewer than num_fixed_params positional arguments are passed 437 // Check that no fewer than num_fixed_params positional arguments are passed
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 delete[] opt_param; 542 delete[] opt_param;
543 delete[] opt_param_position; 543 delete[] opt_param_position;
544 // Check that RDI now points to the null terminator in the array descriptor. 544 // Check that RDI now points to the null terminator in the array descriptor.
545 Label all_arguments_processed; 545 Label all_arguments_processed;
546 __ cmpq(Address(RDI, 0), raw_null); 546 __ cmpq(Address(RDI, 0), raw_null);
547 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); 547 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump);
548 548
549 __ Bind(&wrong_num_arguments); 549 __ Bind(&wrong_num_arguments);
550 if (function.IsClosureFunction()) { 550 if (function.IsClosureFunction()) {
551 GenerateCallRuntime(AstNode::kNoId, 551 GenerateCallRuntime(AstNode::kNoId,
552 function.token_index(), 552 0,
553 kClosureArgumentMismatchRuntimeEntry); 553 kClosureArgumentMismatchRuntimeEntry);
554 } else { 554 } else {
555 // Invoke noSuchMethod function. 555 // Invoke noSuchMethod function.
556 const int kNumArgsChecked = 1; 556 const int kNumArgsChecked = 1;
557 ICData& ic_data = ICData::ZoneHandle(); 557 ICData& ic_data = ICData::ZoneHandle();
558 ic_data = ICData::New(parsed_function().function(), 558 ic_data = ICData::New(parsed_function().function(),
559 String::Handle(function.name()), 559 String::Handle(function.name()),
560 AstNode::kNoId, 560 AstNode::kNoId,
561 kNumArgsChecked); 561 kNumArgsChecked);
562 __ LoadObject(RBX, ic_data); 562 __ LoadObject(RBX, ic_data);
563 // RBP : points to previous frame pointer. 563 // RBP : points to previous frame pointer.
564 // RBP + 8 : points to return address. 564 // RBP + 8 : points to return address.
565 // RBP + 16 : address of last argument (arg n-1). 565 // RBP + 16 : address of last argument (arg n-1).
566 // RSP + 16 + 8*(n-1) : address of first argument (arg 0). 566 // RSP + 16 + 8*(n-1) : address of first argument (arg 0).
567 // RBX : ic-data. 567 // RBX : ic-data.
568 // R10 : arguments descriptor array. 568 // R10 : arguments descriptor array.
569 __ call(&StubCode::CallNoSuchMethodFunctionLabel()); 569 __ call(&StubCode::CallNoSuchMethodFunctionLabel());
570 } 570 }
571 571
572 if (FLAG_trace_functions) { 572 if (FLAG_trace_functions) {
573 __ pushq(RAX); // Preserve result. 573 __ pushq(RAX); // Preserve result.
574 __ PushObject(function); 574 __ PushObject(Function::ZoneHandle(function.raw()));
575 GenerateCallRuntime(AstNode::kNoId, 575 GenerateCallRuntime(AstNode::kNoId,
576 0, 576 0,
577 kTraceFunctionExitRuntimeEntry); 577 kTraceFunctionExitRuntimeEntry);
578 __ popq(RAX); // Remove argument. 578 __ popq(RAX); // Remove argument.
579 __ popq(RAX); // Restore result. 579 __ popq(RAX); // Restore result.
580 } 580 }
581 __ LeaveFrame(); 581 __ LeaveFrame();
582 __ ret(); 582 __ ret();
583 583
584 __ Bind(&all_arguments_processed); 584 __ Bind(&all_arguments_processed);
(...skipping 27 matching lines...) Expand all
612 } 612 }
613 __ movq(Address(RBP, index * kWordSize), RAX); 613 __ movq(Address(RBP, index * kWordSize), RAX);
614 } 614 }
615 615
616 // Generate stack overflow check. 616 // Generate stack overflow check.
617 __ movq(TMP, Immediate(Isolate::Current()->stack_limit_address())); 617 __ movq(TMP, Immediate(Isolate::Current()->stack_limit_address()));
618 __ cmpq(RSP, Address(TMP, 0)); 618 __ cmpq(RSP, Address(TMP, 0));
619 Label no_stack_overflow; 619 Label no_stack_overflow;
620 __ j(ABOVE, &no_stack_overflow); 620 __ j(ABOVE, &no_stack_overflow);
621 GenerateCallRuntime(AstNode::kNoId, 621 GenerateCallRuntime(AstNode::kNoId,
622 function.token_index(), 622 0,
623 kStackOverflowRuntimeEntry); 623 kStackOverflowRuntimeEntry);
624 __ Bind(&no_stack_overflow); 624 __ Bind(&no_stack_overflow);
625 } 625 }
626 626
627 627
628 void CodeGenerator::GenerateReturnEpilog(ReturnNode* node) { 628 void CodeGenerator::GenerateReturnEpilog(ReturnNode* node) {
629 // Unchain the context(s) up to context level 0. 629 // Unchain the context(s) up to context level 0.
630 int context_level = state()->context_level(); 630 int context_level = state()->context_level();
631 ASSERT(context_level >= 0); 631 ASSERT(context_level >= 0);
632 while (context_level-- > 0) { 632 while (context_level-- > 0) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 __ nop(1); 664 __ nop(1);
665 __ nop(1); 665 __ nop(1);
666 __ nop(1); 666 __ nop(1);
667 __ nop(1); 667 __ nop(1);
668 __ nop(1); 668 __ nop(1);
669 __ nop(1); 669 __ nop(1);
670 AddCurrentDescriptor(PcDescriptors::kReturn, 670 AddCurrentDescriptor(PcDescriptors::kReturn,
671 node->id(), 671 node->id(),
672 node->token_index()); 672 node->token_index());
673 673
674
675 #ifdef DEBUG 674 #ifdef DEBUG
676 __ Bind(&wrong_stack); 675 __ Bind(&wrong_stack);
677 __ Stop("Exit stack size does not match the entry stack size."); 676 __ Stop("Exit stack size does not match the entry stack size.");
678 #endif // DEBUG. 677 #endif // DEBUG.
679 } 678 }
680 679
681 680
682 void CodeGenerator::VisitReturnNode(ReturnNode* node) { 681 void CodeGenerator::VisitReturnNode(ReturnNode* node) {
683 ASSERT(!IsResultNeeded(node)); 682 ASSERT(!IsResultNeeded(node));
684 ASSERT(node->value() != NULL); 683 ASSERT(node->value() != NULL);
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
790 } 789 }
791 790
792 791
793 void CodeGenerator::VisitPrimaryNode(PrimaryNode* node) { 792 void CodeGenerator::VisitPrimaryNode(PrimaryNode* node) {
794 // PrimaryNodes are temporary during parsing. 793 // PrimaryNodes are temporary during parsing.
795 UNREACHABLE(); 794 UNREACHABLE();
796 } 795 }
797 796
798 797
799 void CodeGenerator::VisitCloneContextNode(CloneContextNode *node) { 798 void CodeGenerator::VisitCloneContextNode(CloneContextNode *node) {
800 const Context& result = Context::ZoneHandle(); 799 __ PushObject(Object::ZoneHandle()); // Make room for the result.
801 __ PushObject(result);
802 __ pushq(CTX); 800 __ pushq(CTX);
803 GenerateCallRuntime(node->id(), 801 GenerateCallRuntime(node->id(),
804 node->token_index(), kCloneContextRuntimeEntry); 802 node->token_index(), kCloneContextRuntimeEntry);
805 __ popq(RAX); 803 __ popq(RAX);
806 __ popq(CTX); // result: cloned context. Set as current context. 804 __ popq(CTX); // result: cloned context. Set as current context.
807 } 805 }
808 806
809 807
810 void CodeGenerator::VisitSequenceNode(SequenceNode* node_sequence) { 808 void CodeGenerator::VisitSequenceNode(SequenceNode* node_sequence) {
811 CodeGeneratorState codegen_state(this); 809 CodeGeneratorState codegen_state(this);
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after
1293 // - Class equality (only if class is not parameterized). 1291 // - Class equality (only if class is not parameterized).
1294 // Inputs: 1292 // Inputs:
1295 // - RAX: object. 1293 // - RAX: object.
1296 // Destroys RCX. 1294 // Destroys RCX.
1297 // Returns: 1295 // Returns:
1298 // - true or false on stack. 1296 // - true or false on stack.
1299 void CodeGenerator::GenerateInstanceOf(intptr_t node_id, 1297 void CodeGenerator::GenerateInstanceOf(intptr_t node_id,
1300 intptr_t token_index, 1298 intptr_t token_index,
1301 const AbstractType& type, 1299 const AbstractType& type,
1302 bool negate_result) { 1300 bool negate_result) {
1303 ASSERT(type.IsFinalized()); 1301 ASSERT(type.IsFinalized() && !type.IsMalformed());
1304 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 1302 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
1305 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); 1303 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
1306 1304
1307 // All instances are of a subtype of the Object type. 1305 // All instances are of a subtype of the Object type.
1308 const Type& object_type = 1306 const Type& object_type =
1309 Type::Handle(Isolate::Current()->object_store()->object_type()); 1307 Type::Handle(Isolate::Current()->object_store()->object_type());
1310 if (type.IsInstantiated() && object_type.IsSubtypeOf(type)) { 1308 if (type.IsInstantiated() && object_type.IsSubtypeOf(type)) {
1311 __ PushObject(negate_result ? bool_false : bool_true); 1309 __ PushObject(negate_result ? bool_false : bool_true);
1312 return; 1310 return;
1313 } 1311 }
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1401 Label runtime_call; 1399 Label runtime_call;
1402 __ movq(RCX, FieldAddress(RAX, Object::class_offset())); 1400 __ movq(RCX, FieldAddress(RAX, Object::class_offset()));
1403 __ CompareObject(RCX, *compare_class); 1401 __ CompareObject(RCX, *compare_class);
1404 __ j(NOT_EQUAL, &runtime_call, Assembler::kNearJump); 1402 __ j(NOT_EQUAL, &runtime_call, Assembler::kNearJump);
1405 __ PushObject(negate_result ? bool_false : bool_true); 1403 __ PushObject(negate_result ? bool_false : bool_true);
1406 __ jmp(&done, Assembler::kNearJump); 1404 __ jmp(&done, Assembler::kNearJump);
1407 __ Bind(&runtime_call); 1405 __ Bind(&runtime_call);
1408 } 1406 }
1409 } 1407 }
1410 } 1408 }
1411 const Object& result = Object::ZoneHandle(); 1409 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1412 __ PushObject(result); // Make room for the result of the runtime call.
1413 __ pushq(RAX); // Push the instance. 1410 __ pushq(RAX); // Push the instance.
1414 __ PushObject(type); // Push the type. 1411 __ PushObject(type); // Push the type.
1415 if (!type.IsInstantiated()) { 1412 if (!type.IsInstantiated()) {
1416 GenerateInstantiatorTypeArguments(token_index); 1413 GenerateInstantiatorTypeArguments(token_index);
1417 } else { 1414 } else {
1418 __ pushq(raw_null); // Null instantiator. 1415 __ pushq(raw_null); // Null instantiator.
1419 } 1416 }
1420 GenerateCallRuntime(node_id, token_index, kInstanceofRuntimeEntry); 1417 GenerateCallRuntime(node_id, token_index, kInstanceofRuntimeEntry);
1421 // Pop the two parameters supplied to the runtime entry. The result of the 1418 // Pop the two parameters supplied to the runtime entry. The result of the
1422 // instanceof runtime call will be left as the result of the operation. 1419 // instanceof runtime call will be left as the result of the operation.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1455 // - object in RAX for successful assignable check (or throws TypeError). 1452 // - object in RAX for successful assignable check (or throws TypeError).
1456 void CodeGenerator::GenerateAssertAssignable(intptr_t node_id, 1453 void CodeGenerator::GenerateAssertAssignable(intptr_t node_id,
1457 intptr_t token_index, 1454 intptr_t token_index,
1458 const AbstractType& dst_type, 1455 const AbstractType& dst_type,
1459 const String& dst_name) { 1456 const String& dst_name) {
1460 ASSERT(FLAG_enable_type_checks); 1457 ASSERT(FLAG_enable_type_checks);
1461 ASSERT(token_index >= 0); 1458 ASSERT(token_index >= 0);
1462 ASSERT(!dst_type.IsNull()); 1459 ASSERT(!dst_type.IsNull());
1463 ASSERT(dst_type.IsFinalized()); 1460 ASSERT(dst_type.IsFinalized());
1464 1461
1462 // Generate throw new TypeError() if the type is malformed.
1463 if (dst_type.IsMalformed()) {
1464 const Error& error = Error::Handle(dst_type.malformed_error());
1465 const String& error_message = String::ZoneHandle(
1466 String::NewSymbol(error.ToErrorCString()));
1467 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1468 const Immediate location =
1469 Immediate(reinterpret_cast<int64_t>(Smi::New(token_index)));
1470 __ pushq(location); // Push the source location.
1471 __ pushq(RAX); // Push the source object.
1472 __ PushObject(error_message);
1473 GenerateCallRuntime(node_id, token_index, kMalformedTypeErrorRuntimeEntry);
1474 // We should never return here.
1475 __ int3();
1476 return;
1477 }
1478
1465 // Any expression is assignable to the Dynamic type and to the Object type. 1479 // Any expression is assignable to the Dynamic type and to the Object type.
1466 // Skip the test. 1480 // Skip the test.
1467 if (dst_type.IsDynamicType() || dst_type.IsObjectType()) { 1481 if (dst_type.IsDynamicType() || dst_type.IsObjectType()) {
1468 return; 1482 return;
1469 } 1483 }
1470 1484
1471 // It is a compile-time error to explicitly return a value (including null) 1485 // It is a compile-time error to explicitly return a value (including null)
1472 // from a void function. However, functions that do not explicitly return a 1486 // from a void function. However, functions that do not explicitly return a
1473 // value, implicitly return null. This includes void functions. Therefore, we 1487 // value, implicitly return null. This includes void functions. Therefore, we
1474 // skip the type test here and trust the parser to only return null in void 1488 // skip the type test here and trust the parser to only return null in void
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1576 } else if (dst_type.IsFunctionInterface()) { 1590 } else if (dst_type.IsFunctionInterface()) {
1577 __ movq(RCX, FieldAddress(RAX, Object::class_offset())); 1591 __ movq(RCX, FieldAddress(RAX, Object::class_offset()));
1578 __ movq(RCX, FieldAddress(RCX, Class::signature_function_offset())); 1592 __ movq(RCX, FieldAddress(RCX, Class::signature_function_offset()));
1579 __ cmpq(RCX, raw_null); 1593 __ cmpq(RCX, raw_null);
1580 __ j(NOT_EQUAL, &done); 1594 __ j(NOT_EQUAL, &done);
1581 } 1595 }
1582 } 1596 }
1583 } 1597 }
1584 } 1598 }
1585 __ Bind(&runtime_call); 1599 __ Bind(&runtime_call);
1586 const Object& result = Object::ZoneHandle(); 1600 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1587 __ PushObject(result); // Make room for the result of the runtime call.
1588 const Immediate location = 1601 const Immediate location =
1589 Immediate(reinterpret_cast<int64_t>(Smi::New(token_index))); 1602 Immediate(reinterpret_cast<int64_t>(Smi::New(token_index)));
1590 __ pushq(location); // Push the source location. 1603 __ pushq(location); // Push the source location.
1591 __ pushq(RAX); // Push the source object. 1604 __ pushq(RAX); // Push the source object.
1592 __ PushObject(dst_type); // Push the type of the destination. 1605 __ PushObject(dst_type); // Push the type of the destination.
1593 if (!dst_type.IsInstantiated()) { 1606 if (!dst_type.IsInstantiated()) {
1594 GenerateInstantiatorTypeArguments(token_index); 1607 GenerateInstantiatorTypeArguments(token_index);
1595 } else { 1608 } else {
1596 __ pushq(raw_null); // Null instantiator. 1609 __ pushq(raw_null); // Null instantiator.
1597 } 1610 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1643 // This check should pass if the receiver's class implements the interface 1656 // This check should pass if the receiver's class implements the interface
1644 // 'bool'. Check only class 'Bool' since it is the only legal implementation 1657 // 'bool'. Check only class 'Bool' since it is the only legal implementation
1645 // of the interface 'bool'. 1658 // of the interface 'bool'.
1646 const Class& bool_class = 1659 const Class& bool_class =
1647 Class::ZoneHandle(Isolate::Current()->object_store()->bool_class()); 1660 Class::ZoneHandle(Isolate::Current()->object_store()->bool_class());
1648 __ movq(RCX, FieldAddress(RAX, Object::class_offset())); 1661 __ movq(RCX, FieldAddress(RAX, Object::class_offset()));
1649 __ CompareObject(RCX, bool_class); 1662 __ CompareObject(RCX, bool_class);
1650 __ j(EQUAL, &done, Assembler::kNearJump); 1663 __ j(EQUAL, &done, Assembler::kNearJump);
1651 1664
1652 __ Bind(&runtime_call); 1665 __ Bind(&runtime_call);
1653 const Object& result = Object::ZoneHandle();
1654 __ PushObject(result); // Make room for the result of the runtime call.
1655 const Immediate location = 1666 const Immediate location =
1656 Immediate(reinterpret_cast<int64_t>(Smi::New(token_index))); 1667 Immediate(reinterpret_cast<int64_t>(Smi::New(token_index)));
1657 __ pushq(location); // Push the source location. 1668 __ pushq(location); // Push the source location.
1658 __ pushq(RAX); // Push the source object. 1669 __ pushq(RAX); // Push the source object.
1659 GenerateCallRuntime(node_id, token_index, kConditionTypeErrorRuntimeEntry); 1670 GenerateCallRuntime(node_id, token_index, kConditionTypeErrorRuntimeEntry);
1660 // Pop the parameters supplied to the runtime entry. The result of the 1671 // We should never return here.
1661 // type check runtime call is the checked value. 1672 __ int3();
1662 __ addq(RSP, Immediate(3 * kWordSize));
1663 1673
1664 __ Bind(&done); 1674 __ Bind(&done);
1665 } 1675 }
1666 1676
1667 1677
1668 void CodeGenerator::VisitComparisonNode(ComparisonNode* node) { 1678 void CodeGenerator::VisitComparisonNode(ComparisonNode* node) {
1669 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 1679 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
1670 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); 1680 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
1671 node->left()->Visit(this); 1681 node->left()->Visit(this);
1672 1682
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
2091 // Could not concatenate at compile time, generate a call to 2101 // Could not concatenate at compile time, generate a call to
2092 // interpolation function. 2102 // interpolation function.
2093 ArgumentListNode* interpol_arg = new ArgumentListNode(node->token_index()); 2103 ArgumentListNode* interpol_arg = new ArgumentListNode(node->token_index());
2094 interpol_arg->Add(node->values()); 2104 interpol_arg->Add(node->values());
2095 node->values()->Visit(this); 2105 node->values()->Visit(this);
2096 __ LoadObject(RBX, interpol_func); 2106 __ LoadObject(RBX, interpol_func);
2097 __ LoadObject(R10, ArgumentsDescriptor(interpol_arg->length(), 2107 __ LoadObject(R10, ArgumentsDescriptor(interpol_arg->length(),
2098 interpol_arg->names())); 2108 interpol_arg->names()));
2099 GenerateCall(node->token_index(), 2109 GenerateCall(node->token_index(),
2100 &StubCode::CallStaticFunctionLabel(), 2110 &StubCode::CallStaticFunctionLabel(),
2101 PcDescriptors::kOther); 2111 PcDescriptors::kFuncCall);
2102 __ addq(RSP, Immediate(interpol_arg->length() * kWordSize)); 2112 __ addq(RSP, Immediate(interpol_arg->length() * kWordSize));
2103 // Result is in RAX. 2113 // Result is in RAX.
2104 if (IsResultNeeded(node)) { 2114 if (IsResultNeeded(node)) {
2105 __ pushq(RAX); 2115 __ pushq(RAX);
2106 } 2116 }
2107 } 2117 }
2108 2118
2109 2119
2110 void CodeGenerator::VisitInstanceCallNode(InstanceCallNode* node) { 2120 void CodeGenerator::VisitInstanceCallNode(InstanceCallNode* node) {
2111 const int number_of_arguments = node->arguments()->length() + 1; 2121 const int number_of_arguments = node->arguments()->length() + 1;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
2178 // Pushes the type arguments of the instantiator on the stack. 2188 // Pushes the type arguments of the instantiator on the stack.
2179 void CodeGenerator::GenerateInstantiatorTypeArguments(intptr_t token_index) { 2189 void CodeGenerator::GenerateInstantiatorTypeArguments(intptr_t token_index) {
2180 const Class& instantiator_class = Class::Handle( 2190 const Class& instantiator_class = Class::Handle(
2181 parsed_function().function().owner()); 2191 parsed_function().function().owner());
2182 if (instantiator_class.NumTypeParameters() == 0) { 2192 if (instantiator_class.NumTypeParameters() == 0) {
2183 // The type arguments are compile time constants. 2193 // The type arguments are compile time constants.
2184 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); 2194 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle();
2185 // TODO(regis): Temporary type should be allocated in new gen heap. 2195 // TODO(regis): Temporary type should be allocated in new gen heap.
2186 Type& type = Type::Handle( 2196 Type& type = Type::Handle(
2187 Type::New(instantiator_class, type_arguments, token_index)); 2197 Type::New(instantiator_class, type_arguments, token_index));
2188 type ^= ClassFinalizer::FinalizeType(instantiator_class, type); 2198 type ^= ClassFinalizer::FinalizeType(
2199 instantiator_class, type, ClassFinalizer::kFinalizeWellFormed);
2189 type_arguments = type.arguments(); 2200 type_arguments = type.arguments();
2190 __ PushObject(type_arguments); 2201 __ PushObject(type_arguments);
2191 } else { 2202 } else {
2192 ASSERT(parsed_function().instantiator() != NULL); 2203 ASSERT(parsed_function().instantiator() != NULL);
2193 parsed_function().instantiator()->Visit(this); 2204 parsed_function().instantiator()->Visit(this);
2194 Function& outer_function = 2205 Function& outer_function =
2195 Function::Handle(parsed_function().function().raw()); 2206 Function::Handle(parsed_function().function().raw());
2196 while (outer_function.IsLocalFunction()) { 2207 while (outer_function.IsLocalFunction()) {
2197 outer_function = outer_function.parent_function(); 2208 outer_function = outer_function.parent_function();
2198 } 2209 }
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2261 Immediate arguments_length = Immediate(reinterpret_cast<int64_t>( 2272 Immediate arguments_length = Immediate(reinterpret_cast<int64_t>(
2262 Smi::New(node->type_arguments().Length()))); 2273 Smi::New(node->type_arguments().Length())));
2263 __ cmpq(FieldAddress(RAX, TypeArguments::length_offset()), 2274 __ cmpq(FieldAddress(RAX, TypeArguments::length_offset()),
2264 arguments_length); 2275 arguments_length);
2265 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 2276 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
2266 } 2277 }
2267 __ Bind(&type_arguments_uninstantiated); 2278 __ Bind(&type_arguments_uninstantiated);
2268 if (node->constructor().IsFactory()) { 2279 if (node->constructor().IsFactory()) {
2269 // A runtime call to instantiate the type arguments is required before 2280 // A runtime call to instantiate the type arguments is required before
2270 // calling the factory. 2281 // calling the factory.
2271 const Object& result = Object::ZoneHandle(); 2282 __ PushObject(Object::ZoneHandle()); // Make room for the result.
2272 __ PushObject(result); // Make room for the result of the runtime call.
2273 __ PushObject(node->type_arguments()); 2283 __ PushObject(node->type_arguments());
2274 __ pushq(RAX); // Push instantiator type arguments. 2284 __ pushq(RAX); // Push instantiator type arguments.
2275 GenerateCallRuntime(node->id(), 2285 GenerateCallRuntime(node->id(),
2276 node->token_index(), 2286 node->token_index(),
2277 kInstantiateTypeArgumentsRuntimeEntry); 2287 kInstantiateTypeArgumentsRuntimeEntry);
2278 __ popq(RAX); // Pop instantiator type arguments. 2288 __ popq(RAX); // Pop instantiator type arguments.
2279 __ popq(RAX); // Pop uninstantiated type arguments. 2289 __ popq(RAX); // Pop uninstantiated type arguments.
2280 __ popq(RAX); // Pop instantiated type arguments. 2290 __ popq(RAX); // Pop instantiated type arguments.
2281 __ Bind(&type_arguments_instantiated); 2291 __ Bind(&type_arguments_instantiated);
2282 __ pushq(RAX); // Instantiated type arguments. 2292 __ pushq(RAX); // Instantiated type arguments.
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
2596 } 2606 }
2597 2607
2598 // Generate code for the finally block if one exists. 2608 // Generate code for the finally block if one exists.
2599 if (node->finally_block() != NULL) { 2609 if (node->finally_block() != NULL) {
2600 node->finally_block()->Visit(this); 2610 node->finally_block()->Visit(this);
2601 } 2611 }
2602 } 2612 }
2603 2613
2604 2614
2605 void CodeGenerator::VisitThrowNode(ThrowNode* node) { 2615 void CodeGenerator::VisitThrowNode(ThrowNode* node) {
2606 const Object& result = Object::ZoneHandle();
2607 node->exception()->Visit(this); 2616 node->exception()->Visit(this);
2608 __ popq(RAX); // Exception object is now in RAX. 2617 // Exception object is on TOS.
2609 if (node->stacktrace() != NULL) { 2618 if (node->stacktrace() != NULL) {
2610 __ PushObject(result); // Make room for the result of the runtime call.
2611 __ pushq(RAX); // Push the exception object.
2612 node->stacktrace()->Visit(this); 2619 node->stacktrace()->Visit(this);
2613 GenerateCallRuntime(node->id(), node->token_index(), kReThrowRuntimeEntry); 2620 GenerateCallRuntime(node->id(), node->token_index(), kReThrowRuntimeEntry);
2614 } else { 2621 } else {
2615 __ PushObject(result); // Make room for the result of the runtime call.
2616 __ pushq(RAX); // Push the exception object.
2617 GenerateCallRuntime(node->id(), node->token_index(), kThrowRuntimeEntry); 2622 GenerateCallRuntime(node->id(), node->token_index(), kThrowRuntimeEntry);
2618 } 2623 }
2619 // We should never return here. 2624 // We should never return here.
2620 __ int3(); 2625 __ int3();
2621 } 2626 }
2622 2627
2623 2628
2624 void CodeGenerator::VisitInlinedFinallyNode(InlinedFinallyNode* node) { 2629 void CodeGenerator::VisitInlinedFinallyNode(InlinedFinallyNode* node) {
2625 int try_index = state()->try_index(); 2630 int try_index = state()->try_index();
2626 if (try_index >= 0) { 2631 if (try_index >= 0) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2684 const Error& error = Error::Handle( 2689 const Error& error = Error::Handle(
2685 Parser::FormatError(script, token_index, "Error", format, args)); 2690 Parser::FormatError(script, token_index, "Error", format, args));
2686 va_end(args); 2691 va_end(args);
2687 Isolate::Current()->long_jump_base()->Jump(1, error); 2692 Isolate::Current()->long_jump_base()->Jump(1, error);
2688 UNREACHABLE(); 2693 UNREACHABLE();
2689 } 2694 }
2690 2695
2691 } // namespace dart 2696 } // namespace dart
2692 2697
2693 #endif // defined TARGET_ARCH_X64 2698 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/code_generator_ia32.cc ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698