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

Side by Side Diff: runtime/vm/code_generator_ia32.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/class_finalizer.cc ('k') | runtime/vm/code_generator_x64.cc » ('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_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 792 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 } 803 }
804 804
805 805
806 void CodeGenerator::VisitPrimaryNode(PrimaryNode* node) { 806 void CodeGenerator::VisitPrimaryNode(PrimaryNode* node) {
807 // PrimaryNodes are temporary during parsing. 807 // PrimaryNodes are temporary during parsing.
808 UNREACHABLE(); 808 UNREACHABLE();
809 } 809 }
810 810
811 811
812 void CodeGenerator::VisitCloneContextNode(CloneContextNode *node) { 812 void CodeGenerator::VisitCloneContextNode(CloneContextNode *node) {
813 const Context& result = Context::ZoneHandle(); 813 __ PushObject(Object::ZoneHandle()); // Make room for the result.
814 __ PushObject(result);
815 __ pushl(CTX); 814 __ pushl(CTX);
816 GenerateCallRuntime(node->id(), 815 GenerateCallRuntime(node->id(),
817 node->token_index(), kCloneContextRuntimeEntry); 816 node->token_index(), kCloneContextRuntimeEntry);
818 __ popl(EAX); 817 __ popl(EAX);
819 __ popl(CTX); // result: cloned context. Set as current context. 818 __ popl(CTX); // result: cloned context. Set as current context.
820 } 819 }
821 820
822 821
823 void CodeGenerator::VisitSequenceNode(SequenceNode* node_sequence) { 822 void CodeGenerator::VisitSequenceNode(SequenceNode* node_sequence) {
824 CodeGeneratorState codegen_state(this); 823 CodeGeneratorState codegen_state(this);
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
1304 // - Class equality (only if class is not parameterized). 1303 // - Class equality (only if class is not parameterized).
1305 // Inputs: 1304 // Inputs:
1306 // - EAX: object. 1305 // - EAX: object.
1307 // Destroys ECX. 1306 // Destroys ECX.
1308 // Returns: 1307 // Returns:
1309 // - true or false on stack. 1308 // - true or false on stack.
1310 void CodeGenerator::GenerateInstanceOf(intptr_t node_id, 1309 void CodeGenerator::GenerateInstanceOf(intptr_t node_id,
1311 intptr_t token_index, 1310 intptr_t token_index,
1312 const AbstractType& type, 1311 const AbstractType& type,
1313 bool negate_result) { 1312 bool negate_result) {
1314 ASSERT(type.IsFinalized()); 1313 ASSERT(type.IsFinalized() && !type.IsMalformed());
1315 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 1314 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
1316 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); 1315 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
1317 1316
1318 // All instances are of a subtype of the Object type. 1317 // All instances are of a subtype of the Object type.
1319 const Type& object_type = 1318 const Type& object_type =
1320 Type::Handle(Isolate::Current()->object_store()->object_type()); 1319 Type::Handle(Isolate::Current()->object_store()->object_type());
1321 if (type.IsInstantiated() && object_type.IsSubtypeOf(type)) { 1320 if (type.IsInstantiated() && object_type.IsSubtypeOf(type)) {
1322 __ PushObject(negate_result ? bool_false : bool_true); 1321 __ PushObject(negate_result ? bool_false : bool_true);
1323 return; 1322 return;
1324 } 1323 }
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1412 Label runtime_call; 1411 Label runtime_call;
1413 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); 1412 __ movl(ECX, FieldAddress(EAX, Object::class_offset()));
1414 __ CompareObject(ECX, *compare_class); 1413 __ CompareObject(ECX, *compare_class);
1415 __ j(NOT_EQUAL, &runtime_call, Assembler::kNearJump); 1414 __ j(NOT_EQUAL, &runtime_call, Assembler::kNearJump);
1416 __ PushObject(negate_result ? bool_false : bool_true); 1415 __ PushObject(negate_result ? bool_false : bool_true);
1417 __ jmp(&done, Assembler::kNearJump); 1416 __ jmp(&done, Assembler::kNearJump);
1418 __ Bind(&runtime_call); 1417 __ Bind(&runtime_call);
1419 } 1418 }
1420 } 1419 }
1421 } 1420 }
1422 const Object& result = Object::ZoneHandle(); 1421 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1423 __ PushObject(result); // Make room for the result of the runtime call.
1424 __ pushl(EAX); // Push the instance. 1422 __ pushl(EAX); // Push the instance.
1425 __ PushObject(type); // Push the type. 1423 __ PushObject(type); // Push the type.
1426 if (!type.IsInstantiated()) { 1424 if (!type.IsInstantiated()) {
1427 GenerateInstantiatorTypeArguments(token_index); 1425 GenerateInstantiatorTypeArguments(token_index);
1428 } else { 1426 } else {
1429 __ pushl(raw_null); // Null instantiator. 1427 __ pushl(raw_null); // Null instantiator.
1430 } 1428 }
1431 GenerateCallRuntime(node_id, token_index, kInstanceofRuntimeEntry); 1429 GenerateCallRuntime(node_id, token_index, kInstanceofRuntimeEntry);
1432 // Pop the two parameters supplied to the runtime entry. The result of the 1430 // Pop the two parameters supplied to the runtime entry. The result of the
1433 // instanceof runtime call will be left as the result of the operation. 1431 // instanceof runtime call will be left as the result of the operation.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1466 // - object in EAX for successful assignable check (or throws TypeError). 1464 // - object in EAX for successful assignable check (or throws TypeError).
1467 void CodeGenerator::GenerateAssertAssignable(intptr_t node_id, 1465 void CodeGenerator::GenerateAssertAssignable(intptr_t node_id,
1468 intptr_t token_index, 1466 intptr_t token_index,
1469 const AbstractType& dst_type, 1467 const AbstractType& dst_type,
1470 const String& dst_name) { 1468 const String& dst_name) {
1471 ASSERT(FLAG_enable_type_checks); 1469 ASSERT(FLAG_enable_type_checks);
1472 ASSERT(token_index >= 0); 1470 ASSERT(token_index >= 0);
1473 ASSERT(!dst_type.IsNull()); 1471 ASSERT(!dst_type.IsNull());
1474 ASSERT(dst_type.IsFinalized()); 1472 ASSERT(dst_type.IsFinalized());
1475 1473
1474 // Generate throw new TypeError() if the type is malformed.
1475 if (dst_type.IsMalformed()) {
1476 const Error& error = Error::Handle(dst_type.malformed_error());
1477 const String& error_message = String::ZoneHandle(
1478 String::NewSymbol(error.ToErrorCString()));
1479 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1480 const Immediate location =
1481 Immediate(reinterpret_cast<int32_t>(Smi::New(token_index)));
1482 __ pushl(location); // Push the source location.
1483 __ pushl(EAX); // Push the source object.
1484 __ PushObject(error_message);
1485 GenerateCallRuntime(node_id, token_index, kMalformedTypeErrorRuntimeEntry);
1486 // We should never return here.
1487 __ int3();
1488 return;
1489 }
1490
1476 // Any expression is assignable to the Dynamic type and to the Object type. 1491 // Any expression is assignable to the Dynamic type and to the Object type.
1477 // Skip the test. 1492 // Skip the test.
1478 if (dst_type.IsDynamicType() || dst_type.IsObjectType()) { 1493 if (dst_type.IsDynamicType() || dst_type.IsObjectType()) {
1479 return; 1494 return;
1480 } 1495 }
1481 1496
1482 // It is a compile-time error to explicitly return a value (including null) 1497 // 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 1498 // from a void function. However, functions that do not explicitly return a
1484 // value, implicitly return null. This includes void functions. Therefore, we 1499 // 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 1500 // 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
1587 } else if (dst_type.IsFunctionInterface()) { 1602 } else if (dst_type.IsFunctionInterface()) {
1588 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); 1603 __ movl(ECX, FieldAddress(EAX, Object::class_offset()));
1589 __ movl(ECX, FieldAddress(ECX, Class::signature_function_offset())); 1604 __ movl(ECX, FieldAddress(ECX, Class::signature_function_offset()));
1590 __ cmpl(ECX, raw_null); 1605 __ cmpl(ECX, raw_null);
1591 __ j(NOT_EQUAL, &done, Assembler::kNearJump); 1606 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
1592 } 1607 }
1593 } 1608 }
1594 } 1609 }
1595 } 1610 }
1596 __ Bind(&runtime_call); 1611 __ Bind(&runtime_call);
1597 const Object& result = Object::ZoneHandle(); 1612 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1598 __ PushObject(result); // Make room for the result of the runtime call.
1599 const Immediate location = 1613 const Immediate location =
1600 Immediate(reinterpret_cast<int32_t>(Smi::New(token_index))); 1614 Immediate(reinterpret_cast<int32_t>(Smi::New(token_index)));
1601 __ pushl(location); // Push the source location. 1615 __ pushl(location); // Push the source location.
1602 __ pushl(EAX); // Push the source object. 1616 __ pushl(EAX); // Push the source object.
1603 __ PushObject(dst_type); // Push the type of the destination. 1617 __ PushObject(dst_type); // Push the type of the destination.
1604 if (!dst_type.IsInstantiated()) { 1618 if (!dst_type.IsInstantiated()) {
1605 GenerateInstantiatorTypeArguments(token_index); 1619 GenerateInstantiatorTypeArguments(token_index);
1606 } else { 1620 } else {
1607 __ pushl(raw_null); // Null instantiator. 1621 __ pushl(raw_null); // Null instantiator.
1608 } 1622 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1654 // This check should pass if the receiver's class implements the interface 1668 // This check should pass if the receiver's class implements the interface
1655 // 'bool'. Check only class 'Bool' since it is the only legal implementation 1669 // 'bool'. Check only class 'Bool' since it is the only legal implementation
1656 // of the interface 'bool'. 1670 // of the interface 'bool'.
1657 const Class& bool_class = 1671 const Class& bool_class =
1658 Class::ZoneHandle(Isolate::Current()->object_store()->bool_class()); 1672 Class::ZoneHandle(Isolate::Current()->object_store()->bool_class());
1659 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); 1673 __ movl(ECX, FieldAddress(EAX, Object::class_offset()));
1660 __ CompareObject(ECX, bool_class); 1674 __ CompareObject(ECX, bool_class);
1661 __ j(EQUAL, &done, Assembler::kNearJump); 1675 __ j(EQUAL, &done, Assembler::kNearJump);
1662 1676
1663 __ Bind(&runtime_call); 1677 __ Bind(&runtime_call);
1664 const Object& result = Object::ZoneHandle();
1665 __ PushObject(result); // Make room for the result of the runtime call.
1666 const Immediate location = 1678 const Immediate location =
1667 Immediate(reinterpret_cast<int32_t>(Smi::New(token_index))); 1679 Immediate(reinterpret_cast<int32_t>(Smi::New(token_index)));
1668 __ pushl(location); // Push the source location. 1680 __ pushl(location); // Push the source location.
1669 __ pushl(EAX); // Push the source object. 1681 __ pushl(EAX); // Push the source object.
1670 GenerateCallRuntime(node_id, token_index, kConditionTypeErrorRuntimeEntry); 1682 GenerateCallRuntime(node_id, token_index, kConditionTypeErrorRuntimeEntry);
1671 // Pop the parameters supplied to the runtime entry. The result of the 1683 // We should never return here.
1672 // type check runtime call is the checked value. 1684 __ int3();
1673 __ addl(ESP, Immediate(3 * kWordSize));
1674 1685
1675 __ Bind(&done); 1686 __ Bind(&done);
1676 } 1687 }
1677 1688
1678 1689
1679 void CodeGenerator::VisitComparisonNode(ComparisonNode* node) { 1690 void CodeGenerator::VisitComparisonNode(ComparisonNode* node) {
1680 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 1691 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
1681 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); 1692 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
1682 node->left()->Visit(this); 1693 node->left()->Visit(this);
1683 1694
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after
2189 // Pushes the type arguments of the instantiator on the stack. 2200 // Pushes the type arguments of the instantiator on the stack.
2190 void CodeGenerator::GenerateInstantiatorTypeArguments(intptr_t token_index) { 2201 void CodeGenerator::GenerateInstantiatorTypeArguments(intptr_t token_index) {
2191 const Class& instantiator_class = Class::Handle( 2202 const Class& instantiator_class = Class::Handle(
2192 parsed_function().function().owner()); 2203 parsed_function().function().owner());
2193 if (instantiator_class.NumTypeParameters() == 0) { 2204 if (instantiator_class.NumTypeParameters() == 0) {
2194 // The type arguments are compile time constants. 2205 // The type arguments are compile time constants.
2195 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); 2206 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle();
2196 // TODO(regis): Temporary type should be allocated in new gen heap. 2207 // TODO(regis): Temporary type should be allocated in new gen heap.
2197 Type& type = Type::Handle( 2208 Type& type = Type::Handle(
2198 Type::New(instantiator_class, type_arguments, token_index)); 2209 Type::New(instantiator_class, type_arguments, token_index));
2199 type ^= ClassFinalizer::FinalizeType(instantiator_class, type); 2210 type ^= ClassFinalizer::FinalizeType(
2211 instantiator_class, type, ClassFinalizer::kFinalizeWellFormed);
2200 type_arguments = type.arguments(); 2212 type_arguments = type.arguments();
2201 __ PushObject(type_arguments); 2213 __ PushObject(type_arguments);
2202 } else { 2214 } else {
2203 ASSERT(parsed_function().instantiator() != NULL); 2215 ASSERT(parsed_function().instantiator() != NULL);
2204 parsed_function().instantiator()->Visit(this); 2216 parsed_function().instantiator()->Visit(this);
2205 Function& outer_function = 2217 Function& outer_function =
2206 Function::Handle(parsed_function().function().raw()); 2218 Function::Handle(parsed_function().function().raw());
2207 while (outer_function.IsLocalFunction()) { 2219 while (outer_function.IsLocalFunction()) {
2208 outer_function = outer_function.parent_function(); 2220 outer_function = outer_function.parent_function();
2209 } 2221 }
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2272 Immediate arguments_length = Immediate(reinterpret_cast<int32_t>( 2284 Immediate arguments_length = Immediate(reinterpret_cast<int32_t>(
2273 Smi::New(node->type_arguments().Length()))); 2285 Smi::New(node->type_arguments().Length())));
2274 __ cmpl(FieldAddress(EAX, TypeArguments::length_offset()), 2286 __ cmpl(FieldAddress(EAX, TypeArguments::length_offset()),
2275 arguments_length); 2287 arguments_length);
2276 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 2288 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
2277 } 2289 }
2278 __ Bind(&type_arguments_uninstantiated); 2290 __ Bind(&type_arguments_uninstantiated);
2279 if (node->constructor().IsFactory()) { 2291 if (node->constructor().IsFactory()) {
2280 // A runtime call to instantiate the type arguments is required before 2292 // A runtime call to instantiate the type arguments is required before
2281 // calling the factory. 2293 // calling the factory.
2282 const Object& result = Object::ZoneHandle(); 2294 __ PushObject(Object::ZoneHandle()); // Make room for the result.
2283 __ PushObject(result); // Make room for the result of the runtime call.
2284 __ PushObject(node->type_arguments()); 2295 __ PushObject(node->type_arguments());
2285 __ pushl(EAX); // Push instantiator type arguments. 2296 __ pushl(EAX); // Push instantiator type arguments.
2286 GenerateCallRuntime(node->id(), 2297 GenerateCallRuntime(node->id(),
2287 node->token_index(), 2298 node->token_index(),
2288 kInstantiateTypeArgumentsRuntimeEntry); 2299 kInstantiateTypeArgumentsRuntimeEntry);
2289 __ popl(EAX); // Pop instantiator type arguments. 2300 __ popl(EAX); // Pop instantiator type arguments.
2290 __ popl(EAX); // Pop uninstantiated type arguments. 2301 __ popl(EAX); // Pop uninstantiated type arguments.
2291 __ popl(EAX); // Pop instantiated type arguments. 2302 __ popl(EAX); // Pop instantiated type arguments.
2292 __ Bind(&type_arguments_instantiated); 2303 __ Bind(&type_arguments_instantiated);
2293 __ pushl(EAX); // Instantiated type arguments. 2304 __ pushl(EAX); // Instantiated type arguments.
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
2607 } 2618 }
2608 2619
2609 // Generate code for the finally block if one exists. 2620 // Generate code for the finally block if one exists.
2610 if (node->finally_block() != NULL) { 2621 if (node->finally_block() != NULL) {
2611 node->finally_block()->Visit(this); 2622 node->finally_block()->Visit(this);
2612 } 2623 }
2613 } 2624 }
2614 2625
2615 2626
2616 void CodeGenerator::VisitThrowNode(ThrowNode* node) { 2627 void CodeGenerator::VisitThrowNode(ThrowNode* node) {
2617 const Object& result = Object::ZoneHandle();
2618 node->exception()->Visit(this); 2628 node->exception()->Visit(this);
2619 __ popl(EAX); // Exception object is now in EAX. 2629 // Exception object is on TOS.
2620 if (node->stacktrace() != NULL) { 2630 if (node->stacktrace() != NULL) {
2621 __ PushObject(result); // Make room for the result of the runtime call.
2622 __ pushl(EAX); // Push the exception object.
2623 node->stacktrace()->Visit(this); 2631 node->stacktrace()->Visit(this);
2624 GenerateCallRuntime(node->id(), node->token_index(), kReThrowRuntimeEntry); 2632 GenerateCallRuntime(node->id(), node->token_index(), kReThrowRuntimeEntry);
2625 } else { 2633 } else {
2626 __ PushObject(result); // Make room for the result of the runtime call.
2627 __ pushl(EAX); // Push the exception object.
2628 GenerateCallRuntime(node->id(), node->token_index(), kThrowRuntimeEntry); 2634 GenerateCallRuntime(node->id(), node->token_index(), kThrowRuntimeEntry);
2629 } 2635 }
2630 // We should never return here. 2636 // We should never return here.
2631 __ int3(); 2637 __ int3();
2632 } 2638 }
2633 2639
2634 2640
2635 void CodeGenerator::VisitInlinedFinallyNode(InlinedFinallyNode* node) { 2641 void CodeGenerator::VisitInlinedFinallyNode(InlinedFinallyNode* node) {
2636 int try_index = state()->try_index(); 2642 int try_index = state()->try_index();
2637 if (try_index >= 0) { 2643 if (try_index >= 0) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2695 const Error& error = Error::Handle( 2701 const Error& error = Error::Handle(
2696 Parser::FormatError(script, token_index, "Error", format, args)); 2702 Parser::FormatError(script, token_index, "Error", format, args));
2697 va_end(args); 2703 va_end(args);
2698 Isolate::Current()->long_jump_base()->Jump(1, error); 2704 Isolate::Current()->long_jump_base()->Jump(1, error);
2699 UNREACHABLE(); 2705 UNREACHABLE();
2700 } 2706 }
2701 2707
2702 } // namespace dart 2708 } // namespace dart
2703 2709
2704 #endif // defined TARGET_ARCH_IA32 2710 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.cc ('k') | runtime/vm/code_generator_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698