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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 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 1293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1304 // - Class equality (only if class is not parameterized). | 1304 // - Class equality (only if class is not parameterized). |
| 1305 // Inputs: | 1305 // Inputs: |
| 1306 // - EAX: object. | 1306 // - EAX: object. |
| 1307 // Destroys ECX. | 1307 // Destroys ECX. |
| 1308 // Returns: | 1308 // Returns: |
| 1309 // - true or false on stack. | 1309 // - true or false on stack. |
| 1310 void CodeGenerator::GenerateInstanceOf(intptr_t node_id, | 1310 void CodeGenerator::GenerateInstanceOf(intptr_t node_id, |
| 1311 intptr_t token_index, | 1311 intptr_t token_index, |
| 1312 const AbstractType& type, | 1312 const AbstractType& type, |
| 1313 bool negate_result) { | 1313 bool negate_result) { |
| 1314 ASSERT(type.IsFinalized()); | 1314 ASSERT(type.IsFinalized() && !type.IsMalformed()); |
| 1315 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 1315 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 1316 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | 1316 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
| 1317 | 1317 |
| 1318 // All instances are of a subtype of the Object type. | 1318 // All instances are of a subtype of the Object type. |
| 1319 const Type& object_type = | 1319 const Type& object_type = |
| 1320 Type::Handle(Isolate::Current()->object_store()->object_type()); | 1320 Type::Handle(Isolate::Current()->object_store()->object_type()); |
| 1321 if (type.IsInstantiated() && object_type.IsSubtypeOf(type)) { | 1321 if (type.IsInstantiated() && object_type.IsSubtypeOf(type)) { |
| 1322 __ PushObject(negate_result ? bool_false : bool_true); | 1322 __ PushObject(negate_result ? bool_false : bool_true); |
| 1323 return; | 1323 return; |
| 1324 } | 1324 } |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1466 // - object in EAX for successful assignable check (or throws TypeError). | 1466 // - object in EAX for successful assignable check (or throws TypeError). |
| 1467 void CodeGenerator::GenerateAssertAssignable(intptr_t node_id, | 1467 void CodeGenerator::GenerateAssertAssignable(intptr_t node_id, |
| 1468 intptr_t token_index, | 1468 intptr_t token_index, |
| 1469 const AbstractType& dst_type, | 1469 const AbstractType& dst_type, |
| 1470 const String& dst_name) { | 1470 const String& dst_name) { |
| 1471 ASSERT(FLAG_enable_type_checks); | 1471 ASSERT(FLAG_enable_type_checks); |
| 1472 ASSERT(token_index >= 0); | 1472 ASSERT(token_index >= 0); |
| 1473 ASSERT(!dst_type.IsNull()); | 1473 ASSERT(!dst_type.IsNull()); |
| 1474 ASSERT(dst_type.IsFinalized()); | 1474 ASSERT(dst_type.IsFinalized()); |
| 1475 | 1475 |
| 1476 // Generate throw new TypeError() if the type is malformed. | |
| 1477 if (dst_type.IsMalformed()) { | |
| 1478 const Error& error = Error::Handle(dst_type.malformed_error()); | |
| 1479 const String& error_message = String::ZoneHandle( | |
| 1480 String::NewSymbol(error.ToErrorCString())); | |
| 1481 | |
| 1482 const Object& result = Object::ZoneHandle(); | |
| 1483 __ PushObject(result); // Make room for the result of the runtime call. | |
|
srdjan
2012/02/29 00:15:54
__ PushObject(Object::ZoneHandle());
srdjan
2012/02/29 00:15:54
Is this precaution to push a dummy for result? Mal
regis
2012/02/29 02:10:01
Correct. No result is returned, but we always rese
regis
2012/02/29 02:10:01
Done here and in other places.
| |
| 1484 const Immediate location = | |
| 1485 Immediate(reinterpret_cast<int32_t>(Smi::New(token_index))); | |
| 1486 __ pushl(location); // Push the source location. | |
| 1487 __ pushl(EAX); // Push the source object. | |
| 1488 __ PushObject(error_message); | |
| 1489 GenerateCallRuntime(node_id, token_index, kMalformedTypeErrorRuntimeEntry); | |
| 1490 // We should never return here. | |
| 1491 __ int3(); | |
| 1492 return; | |
| 1493 } | |
| 1494 | |
| 1476 // Any expression is assignable to the Dynamic type and to the Object type. | 1495 // Any expression is assignable to the Dynamic type and to the Object type. |
| 1477 // Skip the test. | 1496 // Skip the test. |
| 1478 if (dst_type.IsDynamicType() || dst_type.IsObjectType()) { | 1497 if (dst_type.IsDynamicType() || dst_type.IsObjectType()) { |
| 1479 return; | 1498 return; |
| 1480 } | 1499 } |
| 1481 | 1500 |
| 1482 // It is a compile-time error to explicitly return a value (including null) | 1501 // It is a compile-time error to explicitly return a value (including null) |
| 1483 // from a void function. However, functions that do not explicitly return a | 1502 // from a void function. However, functions that do not explicitly return a |
| 1484 // value, implicitly return null. This includes void functions. Therefore, we | 1503 // value, implicitly return null. This includes void functions. Therefore, we |
| 1485 // skip the type test here and trust the parser to only return null in void | 1504 // 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... | |
| 1661 __ j(EQUAL, &done, Assembler::kNearJump); | 1680 __ j(EQUAL, &done, Assembler::kNearJump); |
| 1662 | 1681 |
| 1663 __ Bind(&runtime_call); | 1682 __ Bind(&runtime_call); |
| 1664 const Object& result = Object::ZoneHandle(); | 1683 const Object& result = Object::ZoneHandle(); |
| 1665 __ PushObject(result); // Make room for the result of the runtime call. | 1684 __ PushObject(result); // Make room for the result of the runtime call. |
| 1666 const Immediate location = | 1685 const Immediate location = |
| 1667 Immediate(reinterpret_cast<int32_t>(Smi::New(token_index))); | 1686 Immediate(reinterpret_cast<int32_t>(Smi::New(token_index))); |
| 1668 __ pushl(location); // Push the source location. | 1687 __ pushl(location); // Push the source location. |
| 1669 __ pushl(EAX); // Push the source object. | 1688 __ pushl(EAX); // Push the source object. |
| 1670 GenerateCallRuntime(node_id, token_index, kConditionTypeErrorRuntimeEntry); | 1689 GenerateCallRuntime(node_id, token_index, kConditionTypeErrorRuntimeEntry); |
| 1671 // Pop the parameters supplied to the runtime entry. The result of the | 1690 // We should never return here. |
| 1672 // type check runtime call is the checked value. | 1691 __ int3(); |
| 1673 __ addl(ESP, Immediate(3 * kWordSize)); | |
| 1674 | 1692 |
| 1675 __ Bind(&done); | 1693 __ Bind(&done); |
| 1676 } | 1694 } |
| 1677 | 1695 |
| 1678 | 1696 |
| 1679 void CodeGenerator::VisitComparisonNode(ComparisonNode* node) { | 1697 void CodeGenerator::VisitComparisonNode(ComparisonNode* node) { |
| 1680 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 1698 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 1681 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | 1699 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
| 1682 node->left()->Visit(this); | 1700 node->left()->Visit(this); |
| 1683 | 1701 |
| (...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2189 // Pushes the type arguments of the instantiator on the stack. | 2207 // Pushes the type arguments of the instantiator on the stack. |
| 2190 void CodeGenerator::GenerateInstantiatorTypeArguments(intptr_t token_index) { | 2208 void CodeGenerator::GenerateInstantiatorTypeArguments(intptr_t token_index) { |
| 2191 const Class& instantiator_class = Class::Handle( | 2209 const Class& instantiator_class = Class::Handle( |
| 2192 parsed_function().function().owner()); | 2210 parsed_function().function().owner()); |
| 2193 if (instantiator_class.NumTypeParameters() == 0) { | 2211 if (instantiator_class.NumTypeParameters() == 0) { |
| 2194 // The type arguments are compile time constants. | 2212 // The type arguments are compile time constants. |
| 2195 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); | 2213 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); |
| 2196 // TODO(regis): Temporary type should be allocated in new gen heap. | 2214 // TODO(regis): Temporary type should be allocated in new gen heap. |
| 2197 Type& type = Type::Handle( | 2215 Type& type = Type::Handle( |
| 2198 Type::New(instantiator_class, type_arguments, token_index)); | 2216 Type::New(instantiator_class, type_arguments, token_index)); |
| 2199 type ^= ClassFinalizer::FinalizeType(instantiator_class, type); | 2217 type ^= ClassFinalizer::FinalizeType( |
| 2218 instantiator_class, type, ClassFinalizer::kFinalizeWellFormed); | |
| 2200 type_arguments = type.arguments(); | 2219 type_arguments = type.arguments(); |
| 2201 __ PushObject(type_arguments); | 2220 __ PushObject(type_arguments); |
| 2202 } else { | 2221 } else { |
| 2203 ASSERT(parsed_function().instantiator() != NULL); | 2222 ASSERT(parsed_function().instantiator() != NULL); |
| 2204 parsed_function().instantiator()->Visit(this); | 2223 parsed_function().instantiator()->Visit(this); |
| 2205 Function& outer_function = | 2224 Function& outer_function = |
| 2206 Function::Handle(parsed_function().function().raw()); | 2225 Function::Handle(parsed_function().function().raw()); |
| 2207 while (outer_function.IsLocalFunction()) { | 2226 while (outer_function.IsLocalFunction()) { |
| 2208 outer_function = outer_function.parent_function(); | 2227 outer_function = outer_function.parent_function(); |
| 2209 } | 2228 } |
| (...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2695 const Error& error = Error::Handle( | 2714 const Error& error = Error::Handle( |
| 2696 Parser::FormatError(script, token_index, "Error", format, args)); | 2715 Parser::FormatError(script, token_index, "Error", format, args)); |
| 2697 va_end(args); | 2716 va_end(args); |
| 2698 Isolate::Current()->long_jump_base()->Jump(1, error); | 2717 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2699 UNREACHABLE(); | 2718 UNREACHABLE(); |
| 2700 } | 2719 } |
| 2701 | 2720 |
| 2702 } // namespace dart | 2721 } // namespace dart |
| 2703 | 2722 |
| 2704 #endif // defined TARGET_ARCH_IA32 | 2723 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |