| 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 1165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1176 | 1176 |
| 1177 | 1177 |
| 1178 void CodeGenerator::VisitIncrOpLocalNode(IncrOpLocalNode* node) { | 1178 void CodeGenerator::VisitIncrOpLocalNode(IncrOpLocalNode* node) { |
| 1179 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); | 1179 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); |
| 1180 MarkDeoptPoint(node->id(), node->token_index()); | 1180 MarkDeoptPoint(node->id(), node->token_index()); |
| 1181 GenerateLoadVariable(EAX, node->local()); | 1181 GenerateLoadVariable(EAX, node->local()); |
| 1182 if (!node->prefix() && IsResultNeeded(node)) { | 1182 if (!node->prefix() && IsResultNeeded(node)) { |
| 1183 // Preserve as result. | 1183 // Preserve as result. |
| 1184 __ pushl(EAX); | 1184 __ pushl(EAX); |
| 1185 } | 1185 } |
| 1186 const Immediate value = Immediate(reinterpret_cast<int32_t>(Smi::New(1))); | |
| 1187 const char* operator_name = (node->kind() == Token::kINCR) ? "+" : "-"; | 1186 const char* operator_name = (node->kind() == Token::kINCR) ? "+" : "-"; |
| 1188 __ pushl(EAX); | 1187 __ pushl(EAX); |
| 1189 __ pushl(value); | 1188 __ pushl(Immediate(Smi::RawValue(1))); |
| 1190 GenerateBinaryOperatorCall(node->id(), node->token_index(), operator_name); | 1189 GenerateBinaryOperatorCall(node->id(), node->token_index(), operator_name); |
| 1191 // result is in EAX. | 1190 // result is in EAX. |
| 1192 if (FLAG_enable_type_checks) { | 1191 if (FLAG_enable_type_checks) { |
| 1193 GenerateAssertAssignable(node->id(), | 1192 GenerateAssertAssignable(node->id(), |
| 1194 node->token_index(), | 1193 node->token_index(), |
| 1195 NULL, | 1194 NULL, |
| 1196 node->local().type(), | 1195 node->local().type(), |
| 1197 node->local().name()); | 1196 node->local().name()); |
| 1198 } | 1197 } |
| 1199 GenerateStoreVariable(node->local(), EAX, EDX); | 1198 GenerateStoreVariable(node->local(), EAX, EDX); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1211 MarkDeoptPoint(node->getter_id(), node->token_index()); | 1210 MarkDeoptPoint(node->getter_id(), node->token_index()); |
| 1212 GenerateInstanceGetterCall(node->getter_id(), | 1211 GenerateInstanceGetterCall(node->getter_id(), |
| 1213 node->token_index(), | 1212 node->token_index(), |
| 1214 node->field_name()); | 1213 node->field_name()); |
| 1215 // result is in EAX. | 1214 // result is in EAX. |
| 1216 __ popl(EDX); // Get receiver. | 1215 __ popl(EDX); // Get receiver. |
| 1217 if (!node->prefix() && IsResultNeeded(node)) { | 1216 if (!node->prefix() && IsResultNeeded(node)) { |
| 1218 // Preserve as result. | 1217 // Preserve as result. |
| 1219 __ pushl(EAX); // Preserve value as result. | 1218 __ pushl(EAX); // Preserve value as result. |
| 1220 } | 1219 } |
| 1221 const Immediate one_value = Immediate(reinterpret_cast<int32_t>(Smi::New(1))); | |
| 1222 const char* operator_name = (node->kind() == Token::kINCR) ? "+" : "-"; | 1220 const char* operator_name = (node->kind() == Token::kINCR) ? "+" : "-"; |
| 1223 // EAX: Value. | 1221 // EAX: Value. |
| 1224 // EDX: Receiver. | 1222 // EDX: Receiver. |
| 1225 __ pushl(EDX); // Preserve receiver. | 1223 __ pushl(EDX); // Preserve receiver. |
| 1226 __ pushl(EAX); // Left operand. | 1224 __ pushl(EAX); // Left operand. |
| 1227 __ pushl(one_value); // Right operand. | 1225 __ pushl(Immediate(Smi::RawValue(1))); // Right operand. |
| 1228 GenerateBinaryOperatorCall(node->operator_id(), | 1226 GenerateBinaryOperatorCall(node->operator_id(), |
| 1229 node->token_index(), | 1227 node->token_index(), |
| 1230 operator_name); | 1228 operator_name); |
| 1231 __ popl(EDX); // Restore receiver. | 1229 __ popl(EDX); // Restore receiver. |
| 1232 if (IsResultNeeded(node) && node->prefix()) { | 1230 if (IsResultNeeded(node) && node->prefix()) { |
| 1233 // Value stored into field is the result. | 1231 // Value stored into field is the result. |
| 1234 __ pushl(EAX); | 1232 __ pushl(EAX); |
| 1235 } | 1233 } |
| 1236 __ pushl(EDX); // Receiver. | 1234 __ pushl(EDX); // Receiver. |
| 1237 __ pushl(EAX); // Value. | 1235 __ pushl(EAX); // Value. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1254 GenerateLoadIndexed(node->load_id(), node->token_index()); | 1252 GenerateLoadIndexed(node->load_id(), node->token_index()); |
| 1255 // Result is in EAX. | 1253 // Result is in EAX. |
| 1256 if (!node->prefix() && IsResultNeeded(node)) { | 1254 if (!node->prefix() && IsResultNeeded(node)) { |
| 1257 // Preserve EAX as result. | 1255 // Preserve EAX as result. |
| 1258 __ popl(EDX); // Preserved index -> EDX. | 1256 __ popl(EDX); // Preserved index -> EDX. |
| 1259 __ popl(ECX); // Preserved array -> ECX. | 1257 __ popl(ECX); // Preserved array -> ECX. |
| 1260 __ pushl(EAX); // Preserve original value from indexed load. | 1258 __ pushl(EAX); // Preserve original value from indexed load. |
| 1261 __ pushl(ECX); // Array. | 1259 __ pushl(ECX); // Array. |
| 1262 __ pushl(EDX); // Index. | 1260 __ pushl(EDX); // Index. |
| 1263 } | 1261 } |
| 1264 const Immediate value = Immediate(reinterpret_cast<int32_t>(Smi::New(1))); | |
| 1265 const char* operator_name = (node->kind() == Token::kINCR) ? "+" : "-"; | 1262 const char* operator_name = (node->kind() == Token::kINCR) ? "+" : "-"; |
| 1266 __ pushl(EAX); // Left operand. | 1263 __ pushl(EAX); // Left operand. |
| 1267 __ pushl(value); // Right operand. | 1264 __ pushl(Immediate(Smi::RawValue(1))); // Right operand. |
| 1268 GenerateBinaryOperatorCall(node->operator_id(), | 1265 GenerateBinaryOperatorCall(node->operator_id(), |
| 1269 node->token_index(), | 1266 node->token_index(), |
| 1270 operator_name); | 1267 operator_name); |
| 1271 __ pushl(EAX); | 1268 __ pushl(EAX); |
| 1272 // TOS(0): value, TOS(1): index, TOS(2): array. | 1269 // TOS(0): value, TOS(1): index, TOS(2): array. |
| 1273 GenerateStoreIndexed(node->store_id(), | 1270 GenerateStoreIndexed(node->store_id(), |
| 1274 node->token_index(), | 1271 node->token_index(), |
| 1275 node->prefix() && IsResultNeeded(node)); | 1272 node->prefix() && IsResultNeeded(node)); |
| 1276 } | 1273 } |
| 1277 | 1274 |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1452 __ j(NOT_EQUAL, &non_null, Assembler::kNearJump); | 1449 __ j(NOT_EQUAL, &non_null, Assembler::kNearJump); |
| 1453 __ PushObject(negate_result ? bool_true : bool_false); | 1450 __ PushObject(negate_result ? bool_true : bool_false); |
| 1454 __ jmp(&done); | 1451 __ jmp(&done); |
| 1455 __ Bind(&non_null); | 1452 __ Bind(&non_null); |
| 1456 } | 1453 } |
| 1457 | 1454 |
| 1458 GenerateInlineInstanceof(node_id, token_index, type, | 1455 GenerateInlineInstanceof(node_id, token_index, type, |
| 1459 &is_instance_of, &is_not_instance_of); | 1456 &is_instance_of, &is_not_instance_of); |
| 1460 | 1457 |
| 1461 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 1458 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
| 1462 const Immediate location = | 1459 const Immediate location = Immediate(Smi::RawValue(token_index)); |
| 1463 Immediate(reinterpret_cast<int32_t>(Smi::New(token_index))); | 1460 const Immediate node_id_as_smi = Immediate(Smi::RawValue(node_id)); |
| 1464 const Immediate node_id_as_smi = | |
| 1465 Immediate(reinterpret_cast<int32_t>(Smi::New(node_id))); | |
| 1466 __ pushl(location); // Push the source location. | 1461 __ pushl(location); // Push the source location. |
| 1467 __ pushl(node_id_as_smi); // node-id. | 1462 __ pushl(node_id_as_smi); // node-id. |
| 1468 __ pushl(EAX); // Push the instance. | 1463 __ pushl(EAX); // Push the instance. |
| 1469 __ PushObject(type); // Push the type. | 1464 __ PushObject(type); // Push the type. |
| 1470 if (!type.IsInstantiated()) { | 1465 if (!type.IsInstantiated()) { |
| 1471 GenerateInstantiatorTypeArguments(token_index); | 1466 GenerateInstantiatorTypeArguments(token_index); |
| 1472 } else { | 1467 } else { |
| 1473 __ pushl(raw_null); // Null instantiator. | 1468 __ pushl(raw_null); // Null instantiator. |
| 1474 } | 1469 } |
| 1475 GenerateCallRuntime(node_id, token_index, kInstanceofRuntimeEntry); | 1470 GenerateCallRuntime(node_id, token_index, kInstanceofRuntimeEntry); |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1817 Label done, runtime_call; | 1812 Label done, runtime_call; |
| 1818 __ cmpl(EAX, raw_null); | 1813 __ cmpl(EAX, raw_null); |
| 1819 __ j(EQUAL, &done); | 1814 __ j(EQUAL, &done); |
| 1820 | 1815 |
| 1821 // Generate throw new TypeError() if the type is malformed. | 1816 // Generate throw new TypeError() if the type is malformed. |
| 1822 if (dst_type.IsMalformed()) { | 1817 if (dst_type.IsMalformed()) { |
| 1823 const Error& error = Error::Handle(dst_type.malformed_error()); | 1818 const Error& error = Error::Handle(dst_type.malformed_error()); |
| 1824 const String& error_message = String::ZoneHandle( | 1819 const String& error_message = String::ZoneHandle( |
| 1825 String::NewSymbol(error.ToErrorCString())); | 1820 String::NewSymbol(error.ToErrorCString())); |
| 1826 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 1821 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
| 1827 const Immediate location = | 1822 __ pushl(Immediate(Smi::RawValue(token_index))); // Source location. |
| 1828 Immediate(reinterpret_cast<int32_t>(Smi::New(token_index))); | |
| 1829 __ pushl(location); // Push the source location. | |
| 1830 __ pushl(EAX); // Push the source object. | 1823 __ pushl(EAX); // Push the source object. |
| 1831 __ PushObject(dst_name); // Push the name of the destination. | 1824 __ PushObject(dst_name); // Push the name of the destination. |
| 1832 __ PushObject(error_message); | 1825 __ PushObject(error_message); |
| 1833 GenerateCallRuntime(node_id, token_index, kMalformedTypeErrorRuntimeEntry); | 1826 GenerateCallRuntime(node_id, token_index, kMalformedTypeErrorRuntimeEntry); |
| 1834 // We should never return here. | 1827 // We should never return here. |
| 1835 __ int3(); | 1828 __ int3(); |
| 1836 | 1829 |
| 1837 __ Bind(&done); // For a null object. | 1830 __ Bind(&done); // For a null object. |
| 1838 return; | 1831 return; |
| 1839 } | 1832 } |
| 1840 | 1833 |
| 1841 GenerateInlineInstanceof(node_id, token_index, dst_type, | 1834 GenerateInlineInstanceof(node_id, token_index, dst_type, |
| 1842 &done, &runtime_call); | 1835 &done, &runtime_call); |
| 1843 | 1836 |
| 1844 __ Bind(&runtime_call); | 1837 __ Bind(&runtime_call); |
| 1845 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 1838 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
| 1846 const Immediate location = | 1839 __ pushl(Immediate(Smi::RawValue(token_index))); // Source location. |
| 1847 Immediate(reinterpret_cast<int32_t>(Smi::New(token_index))); | 1840 __ pushl(Immediate(Smi::RawValue(node_id))); // node-id. |
| 1848 const Immediate node_id_as_smi = | |
| 1849 Immediate(reinterpret_cast<int32_t>(Smi::New(node_id))); | |
| 1850 __ pushl(location); // Push the source location. | |
| 1851 __ pushl(node_id_as_smi); // node-id. | |
| 1852 __ pushl(EAX); // Push the source object. | 1841 __ pushl(EAX); // Push the source object. |
| 1853 __ PushObject(dst_type); // Push the type of the destination. | 1842 __ PushObject(dst_type); // Push the type of the destination. |
| 1854 if (dst_type.IsInstantiated()) { | 1843 if (dst_type.IsInstantiated()) { |
| 1855 __ pushl(raw_null); // Null instantiator. | 1844 __ pushl(raw_null); // Null instantiator. |
| 1856 } else { | 1845 } else { |
| 1857 GenerateInstantiatorTypeArguments(token_index); | 1846 GenerateInstantiatorTypeArguments(token_index); |
| 1858 } | 1847 } |
| 1859 __ PushObject(dst_name); // Push the name of the destination. | 1848 __ PushObject(dst_name); // Push the name of the destination. |
| 1860 GenerateCallRuntime(node_id, token_index, kTypeCheckRuntimeEntry); | 1849 GenerateCallRuntime(node_id, token_index, kTypeCheckRuntimeEntry); |
| 1861 // Pop the parameters supplied to the runtime entry. The result of the | 1850 // Pop the parameters supplied to the runtime entry. The result of the |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1907 // This check should pass if the receiver's class implements the interface | 1896 // This check should pass if the receiver's class implements the interface |
| 1908 // 'bool'. Check only class 'Bool' since it is the only legal implementation | 1897 // 'bool'. Check only class 'Bool' since it is the only legal implementation |
| 1909 // of the interface 'bool'. | 1898 // of the interface 'bool'. |
| 1910 const Class& bool_class = | 1899 const Class& bool_class = |
| 1911 Class::ZoneHandle(Isolate::Current()->object_store()->bool_class()); | 1900 Class::ZoneHandle(Isolate::Current()->object_store()->bool_class()); |
| 1912 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); | 1901 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); |
| 1913 __ CompareObject(ECX, bool_class); | 1902 __ CompareObject(ECX, bool_class); |
| 1914 __ j(EQUAL, &done, Assembler::kNearJump); | 1903 __ j(EQUAL, &done, Assembler::kNearJump); |
| 1915 | 1904 |
| 1916 __ Bind(&runtime_call); | 1905 __ Bind(&runtime_call); |
| 1917 const Immediate location = | 1906 __ pushl(Immediate(Smi::RawValue(token_index))); // Source location. |
| 1918 Immediate(reinterpret_cast<int32_t>(Smi::New(token_index))); | |
| 1919 __ pushl(location); // Push the source location. | |
| 1920 __ pushl(EAX); // Push the source object. | 1907 __ pushl(EAX); // Push the source object. |
| 1921 GenerateCallRuntime(node_id, token_index, kConditionTypeErrorRuntimeEntry); | 1908 GenerateCallRuntime(node_id, token_index, kConditionTypeErrorRuntimeEntry); |
| 1922 // We should never return here. | 1909 // We should never return here. |
| 1923 __ int3(); | 1910 __ int3(); |
| 1924 | 1911 |
| 1925 __ Bind(&done); | 1912 __ Bind(&done); |
| 1926 } | 1913 } |
| 1927 | 1914 |
| 1928 | 1915 |
| 1929 void CodeGenerator::VisitComparisonNode(ComparisonNode* node) { | 1916 void CodeGenerator::VisitComparisonNode(ComparisonNode* node) { |
| (...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2543 // Instantiate non-null type arguments. | 2530 // Instantiate non-null type arguments. |
| 2544 if (node->type_arguments().IsUninstantiatedIdentity()) { | 2531 if (node->type_arguments().IsUninstantiatedIdentity()) { |
| 2545 // Check if the instantiator type argument vector is a TypeArguments of a | 2532 // Check if the instantiator type argument vector is a TypeArguments of a |
| 2546 // matching length and, if so, use it as the instantiated type_arguments. | 2533 // matching length and, if so, use it as the instantiated type_arguments. |
| 2547 // No need to check RAX for null (again), because a null instance will | 2534 // No need to check RAX for null (again), because a null instance will |
| 2548 // have the wrong class (Null instead of TypeArguments). | 2535 // have the wrong class (Null instead of TypeArguments). |
| 2549 Label type_arguments_uninstantiated; | 2536 Label type_arguments_uninstantiated; |
| 2550 __ LoadObject(ECX, Class::ZoneHandle(Object::type_arguments_class())); | 2537 __ LoadObject(ECX, Class::ZoneHandle(Object::type_arguments_class())); |
| 2551 __ cmpl(ECX, FieldAddress(EAX, Object::class_offset())); | 2538 __ cmpl(ECX, FieldAddress(EAX, Object::class_offset())); |
| 2552 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump); | 2539 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump); |
| 2553 Immediate arguments_length = Immediate(reinterpret_cast<int32_t>( | 2540 Immediate arguments_length = |
| 2554 Smi::New(node->type_arguments().Length()))); | 2541 Immediate(Smi::RawValue(node->type_arguments().Length())); |
| 2555 __ cmpl(FieldAddress(EAX, TypeArguments::length_offset()), | 2542 __ cmpl(FieldAddress(EAX, TypeArguments::length_offset()), |
| 2556 arguments_length); | 2543 arguments_length); |
| 2557 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); | 2544 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); |
| 2558 __ Bind(&type_arguments_uninstantiated); | 2545 __ Bind(&type_arguments_uninstantiated); |
| 2559 } | 2546 } |
| 2560 if (node->constructor().IsFactory()) { | 2547 if (node->constructor().IsFactory()) { |
| 2561 // A runtime call to instantiate the type arguments is required before | 2548 // A runtime call to instantiate the type arguments is required before |
| 2562 // calling the factory. | 2549 // calling the factory. |
| 2563 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 2550 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
| 2564 __ PushObject(node->type_arguments()); | 2551 __ PushObject(node->type_arguments()); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2610 } | 2597 } |
| 2611 return; | 2598 return; |
| 2612 } | 2599 } |
| 2613 | 2600 |
| 2614 const Class& cls = Class::ZoneHandle(node->constructor().owner()); | 2601 const Class& cls = Class::ZoneHandle(node->constructor().owner()); |
| 2615 const bool requires_type_arguments = cls.HasTypeArguments(); | 2602 const bool requires_type_arguments = cls.HasTypeArguments(); |
| 2616 GenerateTypeArguments(node, requires_type_arguments); | 2603 GenerateTypeArguments(node, requires_type_arguments); |
| 2617 | 2604 |
| 2618 // If cls is parameterized, the type arguments and the instantiator's | 2605 // If cls is parameterized, the type arguments and the instantiator's |
| 2619 // type arguments are on the stack. | 2606 // type arguments are on the stack. |
| 2620 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls)); | 2607 // In checked mode, if the type arguments are uninstantiated, they may need to |
| 2621 const ExternalLabel label(cls.ToCString(), stub.EntryPoint()); | 2608 // be checked against declared bounds at run time. |
| 2622 GenerateCall(node->token_index(), &label, PcDescriptors::kOther); | 2609 Error& malformed_error = Error::Handle(); |
| 2623 if (requires_type_arguments) { | 2610 if (FLAG_enable_type_checks && |
| 2611 requires_type_arguments && |
| 2612 !node->type_arguments().IsNull() && |
| 2613 !node->type_arguments().IsInstantiated() && |
| 2614 !node->type_arguments().IsWithinBoundsOf(cls, |
| 2615 node->type_arguments(), |
| 2616 &malformed_error)) { |
| 2617 // The uninstantiated type arguments cannot be verified to be within their |
| 2618 // bounds at compile time, so verify them at runtime. |
| 2619 // Although the type arguments may be uninstantiated at compile time, they |
| 2620 // may represent the identity vector and may be replaced by the instantiated |
| 2621 // type arguments of the instantiator at run time. |
| 2622 __ popl(ECX); // Pop instantiator type arguments. |
| 2623 __ popl(EAX); // Pop type arguments. |
| 2624 |
| 2625 // Push the result place holder initialized to NULL. |
| 2626 __ PushObject(Object::ZoneHandle()); |
| 2627 __ pushl(Immediate(Smi::RawValue(node->token_index()))); |
| 2628 __ PushObject(cls); |
| 2629 __ pushl(EAX); // Push type arguments. |
| 2630 __ pushl(ECX); // Push instantiator type arguments. |
| 2631 GenerateCallRuntime(node->id(), |
| 2632 node->token_index(), |
| 2633 kAllocateObjectWithBoundsCheckRuntimeEntry); |
| 2634 __ popl(ECX); // Pop instantiator type arguments. |
| 2624 __ popl(ECX); // Pop type arguments. | 2635 __ popl(ECX); // Pop type arguments. |
| 2625 __ popl(ECX); // Pop instantiator type arguments. | 2636 __ popl(ECX); // Pop class. |
| 2637 __ popl(ECX); // Pop source location. |
| 2638 __ popl(EAX); // Pop new instance. |
| 2639 } else { |
| 2640 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls)); |
| 2641 const ExternalLabel label(cls.ToCString(), stub.EntryPoint()); |
| 2642 GenerateCall(node->token_index(), &label, PcDescriptors::kOther); |
| 2643 if (requires_type_arguments) { |
| 2644 __ popl(ECX); // Pop instantiator type arguments. |
| 2645 __ popl(ECX); // Pop type arguments. |
| 2646 } |
| 2626 } | 2647 } |
| 2627 | 2648 |
| 2628 if (IsResultNeeded(node)) { | 2649 if (IsResultNeeded(node)) { |
| 2629 __ pushl(EAX); // Set up return value from allocate. | 2650 __ pushl(EAX); // Set up return value from allocate. |
| 2630 } | 2651 } |
| 2631 | 2652 |
| 2632 // First argument(this) for constructor call which follows. | 2653 // First argument(this) for constructor call which follows. |
| 2633 __ pushl(EAX); | 2654 __ pushl(EAX); |
| 2634 // Second argument is the implicit construction phase parameter. | 2655 // Second argument is the implicit construction phase parameter. |
| 2635 // Run both the constructor initializer list and the constructor body. | 2656 // Run both the constructor initializer list and the constructor body. |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2970 const Error& error = Error::Handle( | 2991 const Error& error = Error::Handle( |
| 2971 Parser::FormatError(script, token_index, "Error", format, args)); | 2992 Parser::FormatError(script, token_index, "Error", format, args)); |
| 2972 va_end(args); | 2993 va_end(args); |
| 2973 Isolate::Current()->long_jump_base()->Jump(1, error); | 2994 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2974 UNREACHABLE(); | 2995 UNREACHABLE(); |
| 2975 } | 2996 } |
| 2976 | 2997 |
| 2977 } // namespace dart | 2998 } // namespace dart |
| 2978 | 2999 |
| 2979 #endif // defined TARGET_ARCH_IA32 | 3000 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |