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/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "vm/ast_printer.h" | 7 #include "vm/ast_printer.h" |
| 8 #include "vm/code_descriptors.h" | 8 #include "vm/code_descriptors.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/flags.h" | 10 #include "vm/flags.h" |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 213 (kind == RawFunction::kConstImplicitGetter); | 213 (kind == RawFunction::kConstImplicitGetter); |
| 214 const bool is_static = owner()->parsed_function().function().is_static(); | 214 const bool is_static = owner()->parsed_function().function().is_static(); |
| 215 // Implicit getters do not need a type check at return, unless they compute | 215 // Implicit getters do not need a type check at return, unless they compute |
| 216 // the initial value of a static field. | 216 // the initial value of a static field. |
| 217 if (is_static || !is_implicit_getter) { | 217 if (is_static || !is_implicit_getter) { |
| 218 const AbstractType& dst_type = | 218 const AbstractType& dst_type = |
| 219 AbstractType::ZoneHandle( | 219 AbstractType::ZoneHandle( |
| 220 owner()->parsed_function().function().result_type()); | 220 owner()->parsed_function().function().result_type()); |
| 221 const String& dst_name = | 221 const String& dst_name = |
| 222 String::ZoneHandle(String::NewSymbol("function result")); | 222 String::ZoneHandle(String::NewSymbol("function result")); |
| 223 Value* type_arguments = NULL; | 223 return_value = BuildAssignableValue(node->id(), |
| 224 if (!dst_type.IsInstantiated()) { | 224 node->value()->token_index(), |
| 225 type_arguments = BuildInstantiatorTypeArguments( | 225 return_value, |
| 226 node->token_index(), for_value.temp_index()); | 226 dst_type, |
| 227 } | 227 dst_name, |
| 228 AssertAssignableComp* assert = | 228 temp_index()); |
| 229 new AssertAssignableComp(node->id(), | |
| 230 node->value()->token_index(), | |
| 231 owner()->try_index(), | |
| 232 return_value, | |
| 233 type_arguments, | |
| 234 dst_type, | |
| 235 dst_name); | |
| 236 AddInstruction(new BindInstr(temp_index(), assert)); | |
| 237 return_value = new TempVal(temp_index()); | |
| 238 } | 229 } |
| 239 } | 230 } |
| 240 | 231 |
| 241 intptr_t current_context_level = owner()->context_level(); | 232 intptr_t current_context_level = owner()->context_level(); |
| 242 ASSERT(current_context_level >= 0); | 233 ASSERT(current_context_level >= 0); |
| 243 if (owner()->parsed_function().saved_context_var() != NULL) { | 234 if (owner()->parsed_function().saved_context_var() != NULL) { |
| 244 // CTX on entry was saved, but not linked as context parent. | 235 // CTX on entry was saved, but not linked as context parent. |
| 245 BuildLoadContext(*owner()->parsed_function().saved_context_var(), 0); | 236 BuildLoadContext(*owner()->parsed_function().saved_context_var(), 0); |
| 246 } else { | 237 } else { |
| 247 while (current_context_level-- > 0) { | 238 while (current_context_level-- > 0) { |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 268 void TestGraphVisitor::VisitLiteralNode(LiteralNode* node) { | 259 void TestGraphVisitor::VisitLiteralNode(LiteralNode* node) { |
| 269 ReturnValue(new ConstantVal(node->literal())); | 260 ReturnValue(new ConstantVal(node->literal())); |
| 270 } | 261 } |
| 271 | 262 |
| 272 | 263 |
| 273 // Type nodes only occur as the right-hand side of instanceof comparisons, | 264 // Type nodes only occur as the right-hand side of instanceof comparisons, |
| 274 // and they are handled specially in that context. | 265 // and they are handled specially in that context. |
| 275 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); } | 266 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); } |
| 276 | 267 |
| 277 | 268 |
| 269 // Returns true if the type check can be skipped, for example, if the type is | |
| 270 // Dynamic or if the value is a compile time constant and an instance of type. | |
| 271 static bool CanSkipTypeCheck(Value* value, const AbstractType& dst_type) { | |
| 272 ASSERT(FLAG_enable_type_checks); | |
| 273 ASSERT(!dst_type.IsNull()); | |
| 274 ASSERT(dst_type.IsFinalized()); | |
| 275 | |
| 276 // Any expression is assignable to the Dynamic type and to the Object type. | |
| 277 // Skip the test. | |
| 278 if (!dst_type.IsMalformed() && | |
| 279 (dst_type.IsDynamicType() || dst_type.IsObjectType())) { | |
| 280 return true; | |
| 281 } | |
| 282 | |
| 283 // It is a compile-time error to explicitly return a value (including null) | |
| 284 // from a void function. However, functions that do not explicitly return a | |
| 285 // value, implicitly return null. This includes void functions. Therefore, we | |
| 286 // skip the type test here and trust the parser to only return null in void | |
| 287 // function. | |
| 288 if (dst_type.IsVoidType()) { | |
| 289 return true; | |
| 290 } | |
| 291 | |
| 292 // Eliminate the test if it can be performed successfully at compile time. | |
| 293 if ((value != NULL) && value->IsConstant()) { | |
| 294 Instance& literal_value = Instance::Handle(); | |
| 295 literal_value ^= value->AsConstant()->value().raw(); | |
| 296 const Class& cls = Class::Handle(literal_value.clazz()); | |
| 297 if (cls.IsNullClass()) { | |
| 298 ASSERT(literal_value.IsNull() || | |
| 299 (literal_value.raw() == Object::sentinel()) || | |
| 300 (literal_value.raw() == Object::transition_sentinel())); | |
|
srdjan
2012/04/18 21:33:16
Why is this assert needed?
regis
2012/04/18 21:58:31
The assert is only to document the fact that we el
| |
| 301 return true; | |
| 302 } | |
| 303 Error& malformed_error = Error::Handle(); | |
| 304 if (!dst_type.IsMalformed() && | |
| 305 dst_type.IsInstantiated() && | |
| 306 literal_value.IsInstanceOf(dst_type, | |
| 307 TypeArguments::Handle(), | |
| 308 &malformed_error)) { | |
| 309 return true; | |
| 310 } | |
| 311 } | |
| 312 return false; | |
| 313 } | |
| 314 | |
| 315 | |
| 278 // <Expression> :: Assignable { expr: <Expression> | 316 // <Expression> :: Assignable { expr: <Expression> |
| 279 // type: AbstractType | 317 // type: AbstractType |
| 280 // dst_name: String } | 318 // dst_name: String } |
| 281 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { | 319 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { |
| 320 UNREACHABLE(); | |
| 321 } | |
| 322 | |
| 323 | |
| 324 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { | |
| 282 ValueGraphVisitor for_value(owner(), temp_index()); | 325 ValueGraphVisitor for_value(owner(), temp_index()); |
| 283 node->expr()->Visit(&for_value); | 326 node->expr()->Visit(&for_value); |
| 284 Append(for_value); | 327 Append(for_value); |
| 285 Value* type_arguments = NULL; | 328 ReturnValue(BuildAssignableValue(node->id(), |
| 286 if (!node->type().IsInstantiated()) { | 329 node->token_index(), |
| 287 type_arguments = BuildInstantiatorTypeArguments( | 330 for_value.value(), |
| 288 node->token_index(), for_value.temp_index()); | 331 node->type(), |
| 289 } | 332 node->dst_name(), |
| 290 AssertAssignableComp* assert_assignable = | 333 temp_index())); |
| 291 new AssertAssignableComp(node->id(), | |
| 292 node->token_index(), | |
| 293 owner()->try_index(), | |
| 294 for_value.value(), | |
| 295 type_arguments, | |
| 296 node->type(), | |
| 297 node->dst_name()); | |
| 298 ReturnComputation(assert_assignable); | |
| 299 } | 334 } |
| 300 | 335 |
| 301 | 336 |
| 302 // <Expression> :: BinaryOp { kind: Token::Kind | 337 // <Expression> :: BinaryOp { kind: Token::Kind |
| 303 // left: <Expression> | 338 // left: <Expression> |
| 304 // right: <Expression> } | 339 // right: <Expression> } |
| 305 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 340 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| 306 // Operators "&&" and "||" cannot be overloaded therefore do not call | 341 // Operators "&&" and "||" cannot be overloaded therefore do not call |
| 307 // operator. | 342 // operator. |
| 308 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 343 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 466 StaticCallComp* call = | 501 StaticCallComp* call = |
| 467 new StaticCallComp(node->token_index(), | 502 new StaticCallComp(node->token_index(), |
| 468 owner()->try_index(), | 503 owner()->try_index(), |
| 469 interpol_func, | 504 interpol_func, |
| 470 interpol_arg->names(), | 505 interpol_arg->names(), |
| 471 values); | 506 values); |
| 472 ReturnComputation(call); | 507 ReturnComputation(call); |
| 473 } | 508 } |
| 474 | 509 |
| 475 | 510 |
| 511 void EffectGraphVisitor::BuildAssertAssignable(intptr_t node_id, | |
| 512 intptr_t token_index, | |
| 513 Value* value, | |
| 514 const AbstractType& dst_type, | |
| 515 const String& dst_name, | |
| 516 intptr_t start_index) { | |
| 517 // We should not call this function if the type check can be skipped. | |
| 518 ASSERT(!CanSkipTypeCheck(value, dst_type)); | |
| 519 | |
| 520 // Build the type check computation. | |
| 521 Value* instantiator_type_arguments = NULL; | |
| 522 if (!dst_type.IsInstantiated()) { | |
| 523 instantiator_type_arguments = | |
| 524 BuildInstantiatorTypeArguments(token_index, start_index + 1); | |
| 525 } | |
| 526 AssertAssignableComp* assert_assignable = | |
| 527 new AssertAssignableComp(node_id, | |
| 528 token_index, | |
| 529 owner()->try_index(), | |
| 530 value, | |
| 531 instantiator_type_arguments, | |
| 532 dst_type, | |
| 533 dst_name); | |
| 534 AddInstruction(new DoInstr(assert_assignable)); | |
| 535 } | |
| 536 | |
| 537 | |
| 538 Value* EffectGraphVisitor::BuildAssignableValue(intptr_t node_id, | |
| 539 intptr_t token_index, | |
| 540 Value* value, | |
| 541 const AbstractType& dst_type, | |
| 542 const String& dst_name, | |
| 543 intptr_t start_index) { | |
| 544 if (CanSkipTypeCheck(value, dst_type)) { | |
| 545 return value; | |
| 546 } | |
| 547 | |
| 548 // Build the type check computation. | |
| 549 Value* instantiator_type_arguments = NULL; | |
| 550 if (!dst_type.IsInstantiated()) { | |
| 551 instantiator_type_arguments = | |
| 552 BuildInstantiatorTypeArguments(token_index, start_index + 1); | |
| 553 } | |
| 554 AssertAssignableComp* assert_assignable = | |
| 555 new AssertAssignableComp(node_id, | |
| 556 token_index, | |
| 557 owner()->try_index(), | |
| 558 value, | |
| 559 instantiator_type_arguments, | |
| 560 dst_type, | |
| 561 dst_name); | |
| 562 AddInstruction(new BindInstr(start_index, assert_assignable)); | |
| 563 return new TempVal(start_index); | |
| 564 } | |
| 565 | |
| 566 | |
| 476 void EffectGraphVisitor::BuildInstanceOf(ComparisonNode* node) { | 567 void EffectGraphVisitor::BuildInstanceOf(ComparisonNode* node) { |
| 477 ASSERT(Token::IsInstanceofOperator(node->kind())); | 568 ASSERT(Token::IsInstanceofOperator(node->kind())); |
| 478 EffectGraphVisitor for_left_value(owner(), temp_index()); | 569 EffectGraphVisitor for_left_value(owner(), temp_index()); |
| 479 node->left()->Visit(&for_left_value); | 570 node->left()->Visit(&for_left_value); |
| 480 Append(for_left_value); | 571 Append(for_left_value); |
| 481 } | 572 } |
| 482 | 573 |
| 483 | 574 |
| 484 void ValueGraphVisitor::BuildInstanceOf(ComparisonNode* node) { | 575 void ValueGraphVisitor::BuildInstanceOf(ComparisonNode* node) { |
| 485 ASSERT(Token::IsInstanceofOperator(node->kind())); | 576 ASSERT(Token::IsInstanceofOperator(node->kind())); |
| (...skipping 1304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1790 ReturnComputation(load); | 1881 ReturnComputation(load); |
| 1791 } | 1882 } |
| 1792 | 1883 |
| 1793 | 1884 |
| 1794 // <Expression> ::= StoreLocal { local: LocalVariable | 1885 // <Expression> ::= StoreLocal { local: LocalVariable |
| 1795 // value: <Expression> } | 1886 // value: <Expression> } |
| 1796 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { | 1887 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { |
| 1797 ValueGraphVisitor for_value(owner(), temp_index()); | 1888 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1798 node->value()->Visit(&for_value); | 1889 node->value()->Visit(&for_value); |
| 1799 Append(for_value); | 1890 Append(for_value); |
| 1800 | 1891 Value* store_value = for_value.value(); |
| 1801 Value* value = for_value.value(); | |
| 1802 if (FLAG_enable_type_checks) { | 1892 if (FLAG_enable_type_checks) { |
| 1803 Value* type_arguments = NULL; | 1893 store_value = BuildAssignableValue(node->id(), |
| 1804 if (!node->local().type().IsInstantiated()) { | 1894 node->value()->token_index(), |
| 1805 type_arguments = BuildInstantiatorTypeArguments( | 1895 store_value, |
| 1806 node->token_index(), for_value.temp_index()); | 1896 node->local().type(), |
| 1807 } | 1897 node->local().name(), |
| 1808 AssertAssignableComp* assert_assignable = | 1898 temp_index()); |
| 1809 new AssertAssignableComp(node->id(), | |
| 1810 node->value()->token_index(), | |
| 1811 owner()->try_index(), | |
| 1812 value, | |
| 1813 type_arguments, | |
| 1814 node->local().type(), | |
| 1815 node->local().name()); | |
| 1816 AddInstruction(new BindInstr(temp_index(), assert_assignable)); | |
| 1817 value = new TempVal(temp_index()); | |
| 1818 } | 1899 } |
| 1819 | |
| 1820 StoreLocalComp* store = | 1900 StoreLocalComp* store = |
| 1821 new StoreLocalComp(node->local(), value, owner()->context_level()); | 1901 new StoreLocalComp(node->local(), store_value, owner()->context_level()); |
| 1822 ReturnComputation(store); | 1902 ReturnComputation(store); |
| 1823 } | 1903 } |
| 1824 | 1904 |
| 1825 | 1905 |
| 1826 void EffectGraphVisitor::VisitLoadInstanceFieldNode( | 1906 void EffectGraphVisitor::VisitLoadInstanceFieldNode( |
| 1827 LoadInstanceFieldNode* node) { | 1907 LoadInstanceFieldNode* node) { |
| 1828 ValueGraphVisitor for_instance(owner(), temp_index()); | 1908 ValueGraphVisitor for_instance(owner(), temp_index()); |
| 1829 node->instance()->Visit(&for_instance); | 1909 node->instance()->Visit(&for_instance); |
| 1830 Append(for_instance); | 1910 Append(for_instance); |
| 1831 LoadInstanceFieldComp* load = | 1911 LoadInstanceFieldComp* load = |
| 1832 new LoadInstanceFieldComp(node, for_instance.value()); | 1912 new LoadInstanceFieldComp(node, for_instance.value()); |
| 1833 ReturnComputation(load); | 1913 ReturnComputation(load); |
| 1834 } | 1914 } |
| 1835 | 1915 |
| 1836 | 1916 |
| 1837 void EffectGraphVisitor::VisitStoreInstanceFieldNode( | 1917 void EffectGraphVisitor::VisitStoreInstanceFieldNode( |
| 1838 StoreInstanceFieldNode* node) { | 1918 StoreInstanceFieldNode* node) { |
| 1839 ValueGraphVisitor for_instance(owner(), temp_index()); | 1919 ValueGraphVisitor for_instance(owner(), temp_index()); |
| 1840 node->instance()->Visit(&for_instance); | 1920 node->instance()->Visit(&for_instance); |
| 1841 Append(for_instance); | 1921 Append(for_instance); |
| 1842 ValueGraphVisitor for_value(owner(), for_instance.temp_index()); | 1922 ValueGraphVisitor for_value(owner(), for_instance.temp_index()); |
| 1843 node->value()->Visit(&for_value); | 1923 node->value()->Visit(&for_value); |
| 1844 Append(for_value); | 1924 Append(for_value); |
| 1845 Value* store_value = for_value.value(); | 1925 Value* store_value = for_value.value(); |
| 1846 if (FLAG_enable_type_checks) { | 1926 if (FLAG_enable_type_checks) { |
| 1847 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 1927 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
| 1848 Value* type_arguments = NULL; | 1928 const String& dst_name = String::ZoneHandle(node->field().name()); |
| 1849 if (!type.IsInstantiated()) { | 1929 store_value = BuildAssignableValue(node->id(), |
| 1850 type_arguments = BuildInstantiatorTypeArguments( | 1930 node->value()->token_index(), |
| 1851 node->token_index(), for_value.temp_index()); | 1931 store_value, |
| 1852 } | 1932 type, |
| 1853 AssertAssignableComp* assert_assignable = | 1933 dst_name, |
| 1854 new AssertAssignableComp(node->id(), | 1934 for_instance.temp_index()); |
| 1855 node->value()->token_index(), | |
| 1856 owner()->try_index(), | |
| 1857 store_value, | |
| 1858 type_arguments, | |
| 1859 type, | |
| 1860 String::ZoneHandle(node->field().name())); | |
| 1861 AddInstruction(new BindInstr(temp_index() + 1, assert_assignable)); | |
| 1862 store_value = new TempVal(temp_index() + 1); | |
| 1863 } | 1935 } |
| 1864 StoreInstanceFieldComp* store = | 1936 StoreInstanceFieldComp* store = |
| 1865 new StoreInstanceFieldComp(node, for_instance.value(), store_value); | 1937 new StoreInstanceFieldComp(node, for_instance.value(), store_value); |
| 1866 ReturnComputation(store); | 1938 ReturnComputation(store); |
| 1867 } | 1939 } |
| 1868 | 1940 |
| 1869 | 1941 |
| 1870 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { | 1942 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { |
| 1871 LoadStaticFieldComp* load = new LoadStaticFieldComp(node->field()); | 1943 LoadStaticFieldComp* load = new LoadStaticFieldComp(node->field()); |
| 1872 ReturnComputation(load); | 1944 ReturnComputation(load); |
| 1873 } | 1945 } |
| 1874 | 1946 |
| 1875 | 1947 |
| 1876 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { | 1948 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { |
| 1877 ValueGraphVisitor for_value(owner(), temp_index()); | 1949 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1878 node->value()->Visit(&for_value); | 1950 node->value()->Visit(&for_value); |
| 1879 Append(for_value); | 1951 Append(for_value); |
| 1880 Value* store_value = for_value.value(); | 1952 Value* store_value = for_value.value(); |
| 1881 if (FLAG_enable_type_checks) { | 1953 if (FLAG_enable_type_checks) { |
| 1882 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 1954 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
| 1883 Value* type_arguments = NULL; | 1955 const String& dst_name = String::ZoneHandle(node->field().name()); |
| 1884 if (!type.IsInstantiated()) { | 1956 store_value = BuildAssignableValue(node->id(), |
| 1885 type_arguments = BuildInstantiatorTypeArguments( | 1957 node->value()->token_index(), |
| 1886 node->token_index(), for_value.temp_index()); | 1958 store_value, |
| 1887 } | 1959 type, |
| 1888 AssertAssignableComp* assert_assignable = | 1960 dst_name, |
| 1889 new AssertAssignableComp(node->id(), | 1961 temp_index()); |
| 1890 node->value()->token_index(), | |
| 1891 owner()->try_index(), | |
| 1892 store_value, | |
| 1893 type_arguments, | |
| 1894 type, | |
| 1895 String::ZoneHandle(node->field().name())); | |
| 1896 AddInstruction(new BindInstr(temp_index(), assert_assignable)); | |
| 1897 store_value = new TempVal(temp_index()); | |
| 1898 } | 1962 } |
| 1899 StoreStaticFieldComp* store = | 1963 StoreStaticFieldComp* store = |
| 1900 new StoreStaticFieldComp(node->field(), store_value); | 1964 new StoreStaticFieldComp(node->field(), store_value); |
| 1901 ReturnComputation(store); | 1965 ReturnComputation(store); |
| 1902 } | 1966 } |
| 1903 | 1967 |
| 1904 | 1968 |
| 1905 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { | 1969 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { |
| 1906 ArgumentGraphVisitor for_array(owner(), temp_index()); | 1970 ArgumentGraphVisitor for_array(owner(), temp_index()); |
| 1907 node->array()->Visit(&for_array); | 1971 node->array()->Visit(&for_array); |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2041 } | 2105 } |
| 2042 } | 2106 } |
| 2043 | 2107 |
| 2044 if (FLAG_enable_type_checks && | 2108 if (FLAG_enable_type_checks && |
| 2045 (node == owner()->parsed_function().node_sequence())) { | 2109 (node == owner()->parsed_function().node_sequence())) { |
| 2046 const int num_params = | 2110 const int num_params = |
| 2047 owner()->parsed_function().function().NumberOfParameters(); | 2111 owner()->parsed_function().function().NumberOfParameters(); |
| 2048 for (int pos = 0; pos < num_params; pos++) { | 2112 for (int pos = 0; pos < num_params; pos++) { |
| 2049 const LocalVariable& parameter = *scope->VariableAt(pos); | 2113 const LocalVariable& parameter = *scope->VariableAt(pos); |
| 2050 ASSERT(parameter.owner() == scope); | 2114 ASSERT(parameter.owner() == scope); |
| 2051 LoadLocalComp* load = new LoadLocalComp(parameter, | 2115 if (!CanSkipTypeCheck(NULL, parameter.type())) { |
| 2052 owner()->context_level()); | 2116 LoadLocalComp* load = new LoadLocalComp(parameter, |
| 2053 AddInstruction(new BindInstr(temp_index(), load)); | 2117 owner()->context_level()); |
| 2054 TempVal* argument_value = new TempVal(temp_index()); | 2118 AddInstruction(new BindInstr(temp_index(), load)); |
| 2055 Value* type_arguments = NULL; | 2119 TempVal* argument_value = new TempVal(temp_index()); |
| 2056 if (!parameter.type().IsInstantiated()) { | 2120 BuildAssertAssignable(node->id(), |
| 2057 type_arguments = BuildInstantiatorTypeArguments( | 2121 parameter.token_index(), |
| 2058 node->token_index(), temp_index() + 1); | 2122 argument_value, |
| 2123 parameter.type(), | |
| 2124 parameter.name(), | |
| 2125 temp_index()); | |
| 2059 } | 2126 } |
| 2060 AssertAssignableComp* assert_assignable = | |
| 2061 new AssertAssignableComp(node->id(), | |
| 2062 parameter.token_index(), | |
| 2063 owner()->try_index(), | |
| 2064 argument_value, | |
| 2065 type_arguments, | |
| 2066 parameter.type(), | |
| 2067 parameter.name()); | |
| 2068 AddInstruction(new DoInstr(assert_assignable)); | |
| 2069 } | 2127 } |
| 2070 } | 2128 } |
| 2071 | 2129 |
| 2072 intptr_t i = 0; | 2130 intptr_t i = 0; |
| 2073 while (is_open() && (i < node->length())) { | 2131 while (is_open() && (i < node->length())) { |
| 2074 EffectGraphVisitor for_effect(owner(), temp_index()); | 2132 EffectGraphVisitor for_effect(owner(), temp_index()); |
| 2075 node->NodeAt(i++)->Visit(&for_effect); | 2133 node->NodeAt(i++)->Visit(&for_effect); |
| 2076 Append(for_effect); | 2134 Append(for_effect); |
| 2077 if (!is_open()) { | 2135 if (!is_open()) { |
| 2078 // E.g., because of a JumpNode. | 2136 // E.g., because of a JumpNode. |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2297 OS::Print("#%s", val->value().ToCString()); | 2355 OS::Print("#%s", val->value().ToCString()); |
| 2298 } | 2356 } |
| 2299 | 2357 |
| 2300 | 2358 |
| 2301 void FlowGraphPrinter::VisitAssertAssignable(AssertAssignableComp* comp) { | 2359 void FlowGraphPrinter::VisitAssertAssignable(AssertAssignableComp* comp) { |
| 2302 OS::Print("AssertAssignable("); | 2360 OS::Print("AssertAssignable("); |
| 2303 comp->value()->Accept(this); | 2361 comp->value()->Accept(this); |
| 2304 OS::Print(", %s, '%s'", | 2362 OS::Print(", %s, '%s'", |
| 2305 String::Handle(comp->dst_type().Name()).ToCString(), | 2363 String::Handle(comp->dst_type().Name()).ToCString(), |
| 2306 comp->dst_name().ToCString()); | 2364 comp->dst_name().ToCString()); |
| 2307 if (comp->type_arguments() != NULL) { | 2365 if (comp->instantiator_type_arguments() != NULL) { |
| 2308 OS::Print(" (type-arg:"); | 2366 OS::Print(" (instantiator:"); |
| 2309 comp->type_arguments()->Accept(this); | 2367 comp->instantiator_type_arguments()->Accept(this); |
| 2310 } | 2368 } |
| 2311 OS::Print(")"); | 2369 OS::Print(")"); |
| 2312 } | 2370 } |
| 2313 | 2371 |
| 2314 | 2372 |
| 2315 void FlowGraphPrinter::VisitAssertBoolean(AssertBooleanComp* comp) { | 2373 void FlowGraphPrinter::VisitAssertBoolean(AssertBooleanComp* comp) { |
| 2316 OS::Print("AssertBoolean("); | 2374 OS::Print("AssertBoolean("); |
| 2317 comp->value()->Accept(this); | 2375 comp->value()->Accept(this); |
| 2318 OS::Print(")"); | 2376 OS::Print(")"); |
| 2319 } | 2377 } |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2769 char* chars = reinterpret_cast<char*>( | 2827 char* chars = reinterpret_cast<char*>( |
| 2770 Isolate::Current()->current_zone()->Allocate(len)); | 2828 Isolate::Current()->current_zone()->Allocate(len)); |
| 2771 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2829 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2772 const Error& error = Error::Handle( | 2830 const Error& error = Error::Handle( |
| 2773 LanguageError::New(String::Handle(String::New(chars)))); | 2831 LanguageError::New(String::Handle(String::New(chars)))); |
| 2774 Isolate::Current()->long_jump_base()->Jump(1, error); | 2832 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2775 } | 2833 } |
| 2776 | 2834 |
| 2777 | 2835 |
| 2778 } // namespace dart | 2836 } // namespace dart |
| OLD | NEW |