| 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 // There are only three instances that can be of Class Null: |
| 299 // Object::null(), Object::sentinel(), and Object::transition_sentinel(). |
| 300 // The inline code and run time code performing the type check will never |
| 301 // encounter the 2 sentinel values. The type check of a sentinel value |
| 302 // will always be eliminated here, because these sentinel values can only |
| 303 // be encountered as constants, never as actual value of an heap object |
| 304 // being type checked. |
| 305 ASSERT(literal_value.IsNull() || |
| 306 (literal_value.raw() == Object::sentinel()) || |
| 307 (literal_value.raw() == Object::transition_sentinel())); |
| 308 return true; |
| 309 } |
| 310 Error& malformed_error = Error::Handle(); |
| 311 if (!dst_type.IsMalformed() && |
| 312 dst_type.IsInstantiated() && |
| 313 literal_value.IsInstanceOf(dst_type, |
| 314 TypeArguments::Handle(), |
| 315 &malformed_error)) { |
| 316 return true; |
| 317 } |
| 318 } |
| 319 return false; |
| 320 } |
| 321 |
| 322 |
| 278 // <Expression> :: Assignable { expr: <Expression> | 323 // <Expression> :: Assignable { expr: <Expression> |
| 279 // type: AbstractType | 324 // type: AbstractType |
| 280 // dst_name: String } | 325 // dst_name: String } |
| 281 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { | 326 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { |
| 327 UNREACHABLE(); |
| 328 } |
| 329 |
| 330 |
| 331 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { |
| 282 ValueGraphVisitor for_value(owner(), temp_index()); | 332 ValueGraphVisitor for_value(owner(), temp_index()); |
| 283 node->expr()->Visit(&for_value); | 333 node->expr()->Visit(&for_value); |
| 284 Append(for_value); | 334 Append(for_value); |
| 285 Value* type_arguments = NULL; | 335 ReturnValue(BuildAssignableValue(node->id(), |
| 286 if (!node->type().IsInstantiated()) { | 336 node->token_index(), |
| 287 type_arguments = BuildInstantiatorTypeArguments( | 337 for_value.value(), |
| 288 node->token_index(), for_value.temp_index()); | 338 node->type(), |
| 289 } | 339 node->dst_name(), |
| 290 AssertAssignableComp* assert_assignable = | 340 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 } | 341 } |
| 300 | 342 |
| 301 | 343 |
| 302 // <Expression> :: BinaryOp { kind: Token::Kind | 344 // <Expression> :: BinaryOp { kind: Token::Kind |
| 303 // left: <Expression> | 345 // left: <Expression> |
| 304 // right: <Expression> } | 346 // right: <Expression> } |
| 305 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 347 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| 306 // Operators "&&" and "||" cannot be overloaded therefore do not call | 348 // Operators "&&" and "||" cannot be overloaded therefore do not call |
| 307 // operator. | 349 // operator. |
| 308 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 350 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 = | 508 StaticCallComp* call = |
| 467 new StaticCallComp(node->token_index(), | 509 new StaticCallComp(node->token_index(), |
| 468 owner()->try_index(), | 510 owner()->try_index(), |
| 469 interpol_func, | 511 interpol_func, |
| 470 interpol_arg->names(), | 512 interpol_arg->names(), |
| 471 values); | 513 values); |
| 472 ReturnComputation(call); | 514 ReturnComputation(call); |
| 473 } | 515 } |
| 474 | 516 |
| 475 | 517 |
| 518 void EffectGraphVisitor::BuildAssertAssignable(intptr_t node_id, |
| 519 intptr_t token_index, |
| 520 Value* value, |
| 521 const AbstractType& dst_type, |
| 522 const String& dst_name, |
| 523 intptr_t start_index) { |
| 524 // We should not call this function if the type check can be skipped. |
| 525 ASSERT(!CanSkipTypeCheck(value, dst_type)); |
| 526 |
| 527 // Build the type check computation. |
| 528 Value* instantiator_type_arguments = NULL; |
| 529 if (!dst_type.IsInstantiated()) { |
| 530 instantiator_type_arguments = |
| 531 BuildInstantiatorTypeArguments(token_index, start_index + 1); |
| 532 } |
| 533 AssertAssignableComp* assert_assignable = |
| 534 new AssertAssignableComp(node_id, |
| 535 token_index, |
| 536 owner()->try_index(), |
| 537 value, |
| 538 instantiator_type_arguments, |
| 539 dst_type, |
| 540 dst_name); |
| 541 AddInstruction(new DoInstr(assert_assignable)); |
| 542 } |
| 543 |
| 544 |
| 545 Value* EffectGraphVisitor::BuildAssignableValue(intptr_t node_id, |
| 546 intptr_t token_index, |
| 547 Value* value, |
| 548 const AbstractType& dst_type, |
| 549 const String& dst_name, |
| 550 intptr_t start_index) { |
| 551 if (CanSkipTypeCheck(value, dst_type)) { |
| 552 return value; |
| 553 } |
| 554 |
| 555 // Build the type check computation. |
| 556 Value* instantiator_type_arguments = NULL; |
| 557 if (!dst_type.IsInstantiated()) { |
| 558 instantiator_type_arguments = |
| 559 BuildInstantiatorTypeArguments(token_index, start_index + 1); |
| 560 } |
| 561 AssertAssignableComp* assert_assignable = |
| 562 new AssertAssignableComp(node_id, |
| 563 token_index, |
| 564 owner()->try_index(), |
| 565 value, |
| 566 instantiator_type_arguments, |
| 567 dst_type, |
| 568 dst_name); |
| 569 AddInstruction(new BindInstr(start_index, assert_assignable)); |
| 570 return new TempVal(start_index); |
| 571 } |
| 572 |
| 573 |
| 476 void EffectGraphVisitor::BuildInstanceOf(ComparisonNode* node) { | 574 void EffectGraphVisitor::BuildInstanceOf(ComparisonNode* node) { |
| 477 ASSERT(Token::IsInstanceofOperator(node->kind())); | 575 ASSERT(Token::IsInstanceofOperator(node->kind())); |
| 478 EffectGraphVisitor for_left_value(owner(), temp_index()); | 576 EffectGraphVisitor for_left_value(owner(), temp_index()); |
| 479 node->left()->Visit(&for_left_value); | 577 node->left()->Visit(&for_left_value); |
| 480 Append(for_left_value); | 578 Append(for_left_value); |
| 481 } | 579 } |
| 482 | 580 |
| 483 | 581 |
| 484 void ValueGraphVisitor::BuildInstanceOf(ComparisonNode* node) { | 582 void ValueGraphVisitor::BuildInstanceOf(ComparisonNode* node) { |
| 485 ASSERT(Token::IsInstanceofOperator(node->kind())); | 583 ASSERT(Token::IsInstanceofOperator(node->kind())); |
| (...skipping 1304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1790 ReturnComputation(load); | 1888 ReturnComputation(load); |
| 1791 } | 1889 } |
| 1792 | 1890 |
| 1793 | 1891 |
| 1794 // <Expression> ::= StoreLocal { local: LocalVariable | 1892 // <Expression> ::= StoreLocal { local: LocalVariable |
| 1795 // value: <Expression> } | 1893 // value: <Expression> } |
| 1796 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { | 1894 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { |
| 1797 ValueGraphVisitor for_value(owner(), temp_index()); | 1895 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1798 node->value()->Visit(&for_value); | 1896 node->value()->Visit(&for_value); |
| 1799 Append(for_value); | 1897 Append(for_value); |
| 1800 | 1898 Value* store_value = for_value.value(); |
| 1801 Value* value = for_value.value(); | |
| 1802 if (FLAG_enable_type_checks) { | 1899 if (FLAG_enable_type_checks) { |
| 1803 Value* type_arguments = NULL; | 1900 store_value = BuildAssignableValue(node->id(), |
| 1804 if (!node->local().type().IsInstantiated()) { | 1901 node->value()->token_index(), |
| 1805 type_arguments = BuildInstantiatorTypeArguments( | 1902 store_value, |
| 1806 node->token_index(), for_value.temp_index()); | 1903 node->local().type(), |
| 1807 } | 1904 node->local().name(), |
| 1808 AssertAssignableComp* assert_assignable = | 1905 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 } | 1906 } |
| 1819 | |
| 1820 StoreLocalComp* store = | 1907 StoreLocalComp* store = |
| 1821 new StoreLocalComp(node->local(), value, owner()->context_level()); | 1908 new StoreLocalComp(node->local(), store_value, owner()->context_level()); |
| 1822 ReturnComputation(store); | 1909 ReturnComputation(store); |
| 1823 } | 1910 } |
| 1824 | 1911 |
| 1825 | 1912 |
| 1826 void EffectGraphVisitor::VisitLoadInstanceFieldNode( | 1913 void EffectGraphVisitor::VisitLoadInstanceFieldNode( |
| 1827 LoadInstanceFieldNode* node) { | 1914 LoadInstanceFieldNode* node) { |
| 1828 ValueGraphVisitor for_instance(owner(), temp_index()); | 1915 ValueGraphVisitor for_instance(owner(), temp_index()); |
| 1829 node->instance()->Visit(&for_instance); | 1916 node->instance()->Visit(&for_instance); |
| 1830 Append(for_instance); | 1917 Append(for_instance); |
| 1831 LoadInstanceFieldComp* load = | 1918 LoadInstanceFieldComp* load = |
| 1832 new LoadInstanceFieldComp(node, for_instance.value()); | 1919 new LoadInstanceFieldComp(node, for_instance.value()); |
| 1833 ReturnComputation(load); | 1920 ReturnComputation(load); |
| 1834 } | 1921 } |
| 1835 | 1922 |
| 1836 | 1923 |
| 1837 void EffectGraphVisitor::VisitStoreInstanceFieldNode( | 1924 void EffectGraphVisitor::VisitStoreInstanceFieldNode( |
| 1838 StoreInstanceFieldNode* node) { | 1925 StoreInstanceFieldNode* node) { |
| 1839 ValueGraphVisitor for_instance(owner(), temp_index()); | 1926 ValueGraphVisitor for_instance(owner(), temp_index()); |
| 1840 node->instance()->Visit(&for_instance); | 1927 node->instance()->Visit(&for_instance); |
| 1841 Append(for_instance); | 1928 Append(for_instance); |
| 1842 ValueGraphVisitor for_value(owner(), for_instance.temp_index()); | 1929 ValueGraphVisitor for_value(owner(), for_instance.temp_index()); |
| 1843 node->value()->Visit(&for_value); | 1930 node->value()->Visit(&for_value); |
| 1844 Append(for_value); | 1931 Append(for_value); |
| 1845 Value* store_value = for_value.value(); | 1932 Value* store_value = for_value.value(); |
| 1846 if (FLAG_enable_type_checks) { | 1933 if (FLAG_enable_type_checks) { |
| 1847 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 1934 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
| 1848 Value* type_arguments = NULL; | 1935 const String& dst_name = String::ZoneHandle(node->field().name()); |
| 1849 if (!type.IsInstantiated()) { | 1936 store_value = BuildAssignableValue(node->id(), |
| 1850 type_arguments = BuildInstantiatorTypeArguments( | 1937 node->value()->token_index(), |
| 1851 node->token_index(), for_value.temp_index()); | 1938 store_value, |
| 1852 } | 1939 type, |
| 1853 AssertAssignableComp* assert_assignable = | 1940 dst_name, |
| 1854 new AssertAssignableComp(node->id(), | 1941 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 } | 1942 } |
| 1864 StoreInstanceFieldComp* store = | 1943 StoreInstanceFieldComp* store = |
| 1865 new StoreInstanceFieldComp(node, for_instance.value(), store_value); | 1944 new StoreInstanceFieldComp(node, for_instance.value(), store_value); |
| 1866 ReturnComputation(store); | 1945 ReturnComputation(store); |
| 1867 } | 1946 } |
| 1868 | 1947 |
| 1869 | 1948 |
| 1870 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { | 1949 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { |
| 1871 LoadStaticFieldComp* load = new LoadStaticFieldComp(node->field()); | 1950 LoadStaticFieldComp* load = new LoadStaticFieldComp(node->field()); |
| 1872 ReturnComputation(load); | 1951 ReturnComputation(load); |
| 1873 } | 1952 } |
| 1874 | 1953 |
| 1875 | 1954 |
| 1876 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { | 1955 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { |
| 1877 ValueGraphVisitor for_value(owner(), temp_index()); | 1956 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1878 node->value()->Visit(&for_value); | 1957 node->value()->Visit(&for_value); |
| 1879 Append(for_value); | 1958 Append(for_value); |
| 1880 Value* store_value = for_value.value(); | 1959 Value* store_value = for_value.value(); |
| 1881 if (FLAG_enable_type_checks) { | 1960 if (FLAG_enable_type_checks) { |
| 1882 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 1961 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
| 1883 Value* type_arguments = NULL; | 1962 const String& dst_name = String::ZoneHandle(node->field().name()); |
| 1884 if (!type.IsInstantiated()) { | 1963 store_value = BuildAssignableValue(node->id(), |
| 1885 type_arguments = BuildInstantiatorTypeArguments( | 1964 node->value()->token_index(), |
| 1886 node->token_index(), for_value.temp_index()); | 1965 store_value, |
| 1887 } | 1966 type, |
| 1888 AssertAssignableComp* assert_assignable = | 1967 dst_name, |
| 1889 new AssertAssignableComp(node->id(), | 1968 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 } | 1969 } |
| 1899 StoreStaticFieldComp* store = | 1970 StoreStaticFieldComp* store = |
| 1900 new StoreStaticFieldComp(node->field(), store_value); | 1971 new StoreStaticFieldComp(node->field(), store_value); |
| 1901 ReturnComputation(store); | 1972 ReturnComputation(store); |
| 1902 } | 1973 } |
| 1903 | 1974 |
| 1904 | 1975 |
| 1905 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { | 1976 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { |
| 1906 ArgumentGraphVisitor for_array(owner(), temp_index()); | 1977 ArgumentGraphVisitor for_array(owner(), temp_index()); |
| 1907 node->array()->Visit(&for_array); | 1978 node->array()->Visit(&for_array); |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2041 } | 2112 } |
| 2042 } | 2113 } |
| 2043 | 2114 |
| 2044 if (FLAG_enable_type_checks && | 2115 if (FLAG_enable_type_checks && |
| 2045 (node == owner()->parsed_function().node_sequence())) { | 2116 (node == owner()->parsed_function().node_sequence())) { |
| 2046 const int num_params = | 2117 const int num_params = |
| 2047 owner()->parsed_function().function().NumberOfParameters(); | 2118 owner()->parsed_function().function().NumberOfParameters(); |
| 2048 for (int pos = 0; pos < num_params; pos++) { | 2119 for (int pos = 0; pos < num_params; pos++) { |
| 2049 const LocalVariable& parameter = *scope->VariableAt(pos); | 2120 const LocalVariable& parameter = *scope->VariableAt(pos); |
| 2050 ASSERT(parameter.owner() == scope); | 2121 ASSERT(parameter.owner() == scope); |
| 2051 LoadLocalComp* load = new LoadLocalComp(parameter, | 2122 if (!CanSkipTypeCheck(NULL, parameter.type())) { |
| 2052 owner()->context_level()); | 2123 LoadLocalComp* load = new LoadLocalComp(parameter, |
| 2053 AddInstruction(new BindInstr(temp_index(), load)); | 2124 owner()->context_level()); |
| 2054 TempVal* argument_value = new TempVal(temp_index()); | 2125 AddInstruction(new BindInstr(temp_index(), load)); |
| 2055 Value* type_arguments = NULL; | 2126 TempVal* argument_value = new TempVal(temp_index()); |
| 2056 if (!parameter.type().IsInstantiated()) { | 2127 BuildAssertAssignable(node->id(), |
| 2057 type_arguments = BuildInstantiatorTypeArguments( | 2128 parameter.token_index(), |
| 2058 node->token_index(), temp_index() + 1); | 2129 argument_value, |
| 2130 parameter.type(), |
| 2131 parameter.name(), |
| 2132 temp_index()); |
| 2059 } | 2133 } |
| 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 } | 2134 } |
| 2070 } | 2135 } |
| 2071 | 2136 |
| 2072 intptr_t i = 0; | 2137 intptr_t i = 0; |
| 2073 while (is_open() && (i < node->length())) { | 2138 while (is_open() && (i < node->length())) { |
| 2074 EffectGraphVisitor for_effect(owner(), temp_index()); | 2139 EffectGraphVisitor for_effect(owner(), temp_index()); |
| 2075 node->NodeAt(i++)->Visit(&for_effect); | 2140 node->NodeAt(i++)->Visit(&for_effect); |
| 2076 Append(for_effect); | 2141 Append(for_effect); |
| 2077 if (!is_open()) { | 2142 if (!is_open()) { |
| 2078 // E.g., because of a JumpNode. | 2143 // 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()); | 2362 OS::Print("#%s", val->value().ToCString()); |
| 2298 } | 2363 } |
| 2299 | 2364 |
| 2300 | 2365 |
| 2301 void FlowGraphPrinter::VisitAssertAssignable(AssertAssignableComp* comp) { | 2366 void FlowGraphPrinter::VisitAssertAssignable(AssertAssignableComp* comp) { |
| 2302 OS::Print("AssertAssignable("); | 2367 OS::Print("AssertAssignable("); |
| 2303 comp->value()->Accept(this); | 2368 comp->value()->Accept(this); |
| 2304 OS::Print(", %s, '%s'", | 2369 OS::Print(", %s, '%s'", |
| 2305 String::Handle(comp->dst_type().Name()).ToCString(), | 2370 String::Handle(comp->dst_type().Name()).ToCString(), |
| 2306 comp->dst_name().ToCString()); | 2371 comp->dst_name().ToCString()); |
| 2307 if (comp->type_arguments() != NULL) { | 2372 if (comp->instantiator_type_arguments() != NULL) { |
| 2308 OS::Print(" (type-arg:"); | 2373 OS::Print(" (instantiator:"); |
| 2309 comp->type_arguments()->Accept(this); | 2374 comp->instantiator_type_arguments()->Accept(this); |
| 2310 } | 2375 } |
| 2311 OS::Print(")"); | 2376 OS::Print(")"); |
| 2312 } | 2377 } |
| 2313 | 2378 |
| 2314 | 2379 |
| 2315 void FlowGraphPrinter::VisitAssertBoolean(AssertBooleanComp* comp) { | 2380 void FlowGraphPrinter::VisitAssertBoolean(AssertBooleanComp* comp) { |
| 2316 OS::Print("AssertBoolean("); | 2381 OS::Print("AssertBoolean("); |
| 2317 comp->value()->Accept(this); | 2382 comp->value()->Accept(this); |
| 2318 OS::Print(")"); | 2383 OS::Print(")"); |
| 2319 } | 2384 } |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2769 char* chars = reinterpret_cast<char*>( | 2834 char* chars = reinterpret_cast<char*>( |
| 2770 Isolate::Current()->current_zone()->Allocate(len)); | 2835 Isolate::Current()->current_zone()->Allocate(len)); |
| 2771 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2836 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2772 const Error& error = Error::Handle( | 2837 const Error& error = Error::Handle( |
| 2773 LanguageError::New(String::Handle(String::New(chars)))); | 2838 LanguageError::New(String::Handle(String::New(chars)))); |
| 2774 Isolate::Current()->long_jump_base()->Jump(1, error); | 2839 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2775 } | 2840 } |
| 2776 | 2841 |
| 2777 | 2842 |
| 2778 } // namespace dart | 2843 } // namespace dart |
| OLD | NEW |