Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 1282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1293 // - Class equality (only if class is not parameterized). | 1293 // - Class equality (only if class is not parameterized). |
| 1294 // Inputs: | 1294 // Inputs: |
| 1295 // - RAX: object. | 1295 // - RAX: object. |
| 1296 // Destroys RCX. | 1296 // Destroys RCX. |
| 1297 // Returns: | 1297 // Returns: |
| 1298 // - true or false on stack. | 1298 // - true or false on stack. |
| 1299 void CodeGenerator::GenerateInstanceOf(intptr_t node_id, | 1299 void CodeGenerator::GenerateInstanceOf(intptr_t node_id, |
| 1300 intptr_t token_index, | 1300 intptr_t token_index, |
| 1301 const AbstractType& type, | 1301 const AbstractType& type, |
| 1302 bool negate_result) { | 1302 bool negate_result) { |
| 1303 ASSERT(type.IsFinalized()); | 1303 ASSERT(type.IsFinalized() && !type.IsMalformed()); |
| 1304 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 1304 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 1305 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | 1305 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
| 1306 | 1306 |
| 1307 // All instances are of a subtype of the Object type. | 1307 // All instances are of a subtype of the Object type. |
| 1308 const Type& object_type = | 1308 const Type& object_type = |
| 1309 Type::Handle(Isolate::Current()->object_store()->object_type()); | 1309 Type::Handle(Isolate::Current()->object_store()->object_type()); |
| 1310 if (type.IsInstantiated() && object_type.IsSubtypeOf(type)) { | 1310 if (type.IsInstantiated() && object_type.IsSubtypeOf(type)) { |
| 1311 __ PushObject(negate_result ? bool_false : bool_true); | 1311 __ PushObject(negate_result ? bool_false : bool_true); |
| 1312 return; | 1312 return; |
| 1313 } | 1313 } |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1455 // - object in RAX for successful assignable check (or throws TypeError). | 1455 // - object in RAX for successful assignable check (or throws TypeError). |
| 1456 void CodeGenerator::GenerateAssertAssignable(intptr_t node_id, | 1456 void CodeGenerator::GenerateAssertAssignable(intptr_t node_id, |
| 1457 intptr_t token_index, | 1457 intptr_t token_index, |
| 1458 const AbstractType& dst_type, | 1458 const AbstractType& dst_type, |
| 1459 const String& dst_name) { | 1459 const String& dst_name) { |
| 1460 ASSERT(FLAG_enable_type_checks); | 1460 ASSERT(FLAG_enable_type_checks); |
| 1461 ASSERT(token_index >= 0); | 1461 ASSERT(token_index >= 0); |
| 1462 ASSERT(!dst_type.IsNull()); | 1462 ASSERT(!dst_type.IsNull()); |
| 1463 ASSERT(dst_type.IsFinalized()); | 1463 ASSERT(dst_type.IsFinalized()); |
| 1464 | 1464 |
| 1465 // Generate throw new TypeError() if the type is malformed. | |
| 1466 if (dst_type.IsMalformed()) { | |
| 1467 const Error& error = Error::Handle(dst_type.malformed_error()); | |
| 1468 const String& error_message = String::ZoneHandle( | |
| 1469 String::NewSymbol(error.ToErrorCString())); | |
| 1470 | |
| 1471 const Object& result = Object::ZoneHandle(); | |
| 1472 __ PushObject(result); // Make room for the result of the runtime call. | |
|
srdjan
2012/02/29 00:15:54
ditto
regis
2012/02/29 02:10:01
Done.
| |
| 1473 const Immediate location = | |
| 1474 Immediate(reinterpret_cast<int64_t>(Smi::New(token_index))); | |
| 1475 __ pushq(location); // Push the source location. | |
| 1476 __ pushq(RAX); // Push the source object. | |
| 1477 __ PushObject(error_message); | |
| 1478 GenerateCallRuntime(node_id, token_index, kMalformedTypeErrorRuntimeEntry); | |
| 1479 // We should never return here. | |
| 1480 __ int3(); | |
| 1481 return; | |
| 1482 } | |
| 1483 | |
| 1465 // Any expression is assignable to the Dynamic type and to the Object type. | 1484 // Any expression is assignable to the Dynamic type and to the Object type. |
| 1466 // Skip the test. | 1485 // Skip the test. |
| 1467 if (dst_type.IsDynamicType() || dst_type.IsObjectType()) { | 1486 if (dst_type.IsDynamicType() || dst_type.IsObjectType()) { |
| 1468 return; | 1487 return; |
| 1469 } | 1488 } |
| 1470 | 1489 |
| 1471 // It is a compile-time error to explicitly return a value (including null) | 1490 // 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 | 1491 // from a void function. However, functions that do not explicitly return a |
| 1473 // value, implicitly return null. This includes void functions. Therefore, we | 1492 // 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 | 1493 // skip the type test here and trust the parser to only return null in void |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1650 __ j(EQUAL, &done, Assembler::kNearJump); | 1669 __ j(EQUAL, &done, Assembler::kNearJump); |
| 1651 | 1670 |
| 1652 __ Bind(&runtime_call); | 1671 __ Bind(&runtime_call); |
| 1653 const Object& result = Object::ZoneHandle(); | 1672 const Object& result = Object::ZoneHandle(); |
| 1654 __ PushObject(result); // Make room for the result of the runtime call. | 1673 __ PushObject(result); // Make room for the result of the runtime call. |
| 1655 const Immediate location = | 1674 const Immediate location = |
| 1656 Immediate(reinterpret_cast<int64_t>(Smi::New(token_index))); | 1675 Immediate(reinterpret_cast<int64_t>(Smi::New(token_index))); |
| 1657 __ pushq(location); // Push the source location. | 1676 __ pushq(location); // Push the source location. |
| 1658 __ pushq(RAX); // Push the source object. | 1677 __ pushq(RAX); // Push the source object. |
| 1659 GenerateCallRuntime(node_id, token_index, kConditionTypeErrorRuntimeEntry); | 1678 GenerateCallRuntime(node_id, token_index, kConditionTypeErrorRuntimeEntry); |
| 1660 // Pop the parameters supplied to the runtime entry. The result of the | 1679 // We should never return here. |
| 1661 // type check runtime call is the checked value. | 1680 __ int3(); |
| 1662 __ addq(RSP, Immediate(3 * kWordSize)); | |
| 1663 | 1681 |
| 1664 __ Bind(&done); | 1682 __ Bind(&done); |
| 1665 } | 1683 } |
| 1666 | 1684 |
| 1667 | 1685 |
| 1668 void CodeGenerator::VisitComparisonNode(ComparisonNode* node) { | 1686 void CodeGenerator::VisitComparisonNode(ComparisonNode* node) { |
| 1669 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 1687 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 1670 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | 1688 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
| 1671 node->left()->Visit(this); | 1689 node->left()->Visit(this); |
| 1672 | 1690 |
| (...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2178 // Pushes the type arguments of the instantiator on the stack. | 2196 // Pushes the type arguments of the instantiator on the stack. |
| 2179 void CodeGenerator::GenerateInstantiatorTypeArguments(intptr_t token_index) { | 2197 void CodeGenerator::GenerateInstantiatorTypeArguments(intptr_t token_index) { |
| 2180 const Class& instantiator_class = Class::Handle( | 2198 const Class& instantiator_class = Class::Handle( |
| 2181 parsed_function().function().owner()); | 2199 parsed_function().function().owner()); |
| 2182 if (instantiator_class.NumTypeParameters() == 0) { | 2200 if (instantiator_class.NumTypeParameters() == 0) { |
| 2183 // The type arguments are compile time constants. | 2201 // The type arguments are compile time constants. |
| 2184 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); | 2202 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); |
| 2185 // TODO(regis): Temporary type should be allocated in new gen heap. | 2203 // TODO(regis): Temporary type should be allocated in new gen heap. |
| 2186 Type& type = Type::Handle( | 2204 Type& type = Type::Handle( |
| 2187 Type::New(instantiator_class, type_arguments, token_index)); | 2205 Type::New(instantiator_class, type_arguments, token_index)); |
| 2188 type ^= ClassFinalizer::FinalizeType(instantiator_class, type); | 2206 type ^= ClassFinalizer::FinalizeType( |
| 2207 instantiator_class, type, ClassFinalizer::kFinalizeWellFormed); | |
| 2189 type_arguments = type.arguments(); | 2208 type_arguments = type.arguments(); |
| 2190 __ PushObject(type_arguments); | 2209 __ PushObject(type_arguments); |
| 2191 } else { | 2210 } else { |
| 2192 ASSERT(parsed_function().instantiator() != NULL); | 2211 ASSERT(parsed_function().instantiator() != NULL); |
| 2193 parsed_function().instantiator()->Visit(this); | 2212 parsed_function().instantiator()->Visit(this); |
| 2194 Function& outer_function = | 2213 Function& outer_function = |
| 2195 Function::Handle(parsed_function().function().raw()); | 2214 Function::Handle(parsed_function().function().raw()); |
| 2196 while (outer_function.IsLocalFunction()) { | 2215 while (outer_function.IsLocalFunction()) { |
| 2197 outer_function = outer_function.parent_function(); | 2216 outer_function = outer_function.parent_function(); |
| 2198 } | 2217 } |
| (...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2684 const Error& error = Error::Handle( | 2703 const Error& error = Error::Handle( |
| 2685 Parser::FormatError(script, token_index, "Error", format, args)); | 2704 Parser::FormatError(script, token_index, "Error", format, args)); |
| 2686 va_end(args); | 2705 va_end(args); |
| 2687 Isolate::Current()->long_jump_base()->Jump(1, error); | 2706 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2688 UNREACHABLE(); | 2707 UNREACHABLE(); |
| 2689 } | 2708 } |
| 2690 | 2709 |
| 2691 } // namespace dart | 2710 } // namespace dart |
| 2692 | 2711 |
| 2693 #endif // defined TARGET_ARCH_X64 | 2712 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |