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