| 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 "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
| 9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
| 10 #include "vm/code_descriptors.h" | 10 #include "vm/code_descriptors.h" |
| (...skipping 1822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1833 | 1833 |
| 1834 LocalVariable* EffectGraphVisitor::EnterTempLocalScope(Value* value) { | 1834 LocalVariable* EffectGraphVisitor::EnterTempLocalScope(Value* value) { |
| 1835 Do(new PushTempInstr(value)); | 1835 Do(new PushTempInstr(value)); |
| 1836 AllocateTempIndex(); | 1836 AllocateTempIndex(); |
| 1837 | 1837 |
| 1838 ASSERT(value->definition()->temp_index() == temp_index() - 1); | 1838 ASSERT(value->definition()->temp_index() == temp_index() - 1); |
| 1839 intptr_t index = GetCurrentTempLocalIndex(); | 1839 intptr_t index = GetCurrentTempLocalIndex(); |
| 1840 char name[64]; | 1840 char name[64]; |
| 1841 OS::SNPrint(name, 64, ":tmp_local%"Pd, index); | 1841 OS::SNPrint(name, 64, ":tmp_local%"Pd, index); |
| 1842 LocalVariable* var = | 1842 LocalVariable* var = |
| 1843 new LocalVariable(0, String::ZoneHandle(Symbols::New(name)), | 1843 new LocalVariable(0, |
| 1844 Type::ZoneHandle(Type::DynamicType())); | 1844 String::ZoneHandle(Symbols::New(name)), |
| 1845 *value->Type()->ToAbstractType()); |
| 1845 var->set_index(index); | 1846 var->set_index(index); |
| 1846 return var; | 1847 return var; |
| 1847 } | 1848 } |
| 1848 | 1849 |
| 1849 | 1850 |
| 1850 Definition* EffectGraphVisitor::ExitTempLocalScope(LocalVariable* var) { | 1851 Definition* EffectGraphVisitor::ExitTempLocalScope(LocalVariable* var) { |
| 1851 Value* tmp = Bind(new LoadLocalInstr(*var)); | 1852 Value* tmp = Bind(new LoadLocalInstr(*var)); |
| 1852 DeallocateTempIndex(1); | 1853 DeallocateTempIndex(1); |
| 1853 ASSERT(GetCurrentTempLocalIndex() == var->index()); | 1854 ASSERT(GetCurrentTempLocalIndex() == var->index()); |
| 1854 return new DropTempsInstr(1, tmp); | 1855 return new DropTempsInstr(1, tmp); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1971 closure ^= function.implicit_static_closure(); | 1972 closure ^= function.implicit_static_closure(); |
| 1972 if (closure.IsNull()) { | 1973 if (closure.IsNull()) { |
| 1973 ObjectStore* object_store = Isolate::Current()->object_store(); | 1974 ObjectStore* object_store = Isolate::Current()->object_store(); |
| 1974 const Context& context = Context::Handle(object_store->empty_context()); | 1975 const Context& context = Context::Handle(object_store->empty_context()); |
| 1975 closure ^= Closure::New(function, context, Heap::kOld); | 1976 closure ^= Closure::New(function, context, Heap::kOld); |
| 1976 function.set_implicit_static_closure(closure); | 1977 function.set_implicit_static_closure(closure); |
| 1977 } | 1978 } |
| 1978 ReturnDefinition(new ConstantInstr(closure)); | 1979 ReturnDefinition(new ConstantInstr(closure)); |
| 1979 return; | 1980 return; |
| 1980 } | 1981 } |
| 1981 Value* receiver = NULL; | |
| 1982 if (function.IsNonImplicitClosureFunction()) { | 1982 if (function.IsNonImplicitClosureFunction()) { |
| 1983 // The context scope may have already been set by the non-optimizing | 1983 // The context scope may have already been set by the non-optimizing |
| 1984 // compiler. If it was not, set it here. | 1984 // compiler. If it was not, set it here. |
| 1985 if (function.context_scope() == ContextScope::null()) { | 1985 if (function.context_scope() == ContextScope::null()) { |
| 1986 // TODO(regis): Why are we not doing this in the parser? | 1986 // TODO(regis): Why are we not doing this in the parser? |
| 1987 const ContextScope& context_scope = ContextScope::ZoneHandle( | 1987 const ContextScope& context_scope = ContextScope::ZoneHandle( |
| 1988 node->scope()->PreserveOuterScope(owner()->context_level())); | 1988 node->scope()->PreserveOuterScope(owner()->context_level())); |
| 1989 ASSERT(!function.HasCode()); | 1989 ASSERT(!function.HasCode()); |
| 1990 ASSERT(function.context_scope() == ContextScope::null()); | 1990 ASSERT(function.context_scope() == ContextScope::null()); |
| 1991 function.set_context_scope(context_scope); | 1991 function.set_context_scope(context_scope); |
| 1992 } | 1992 } |
| 1993 receiver = BuildNullValue(); | 1993 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1994 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1995 ASSERT(function.context_scope() != ContextScope::null()); |
| 1996 |
| 1997 // The function type of a closure may have type arguments. In that case, |
| 1998 // pass the type arguments of the instantiator. |
| 1999 const Class& cls = Class::ZoneHandle(function.signature_class()); |
| 2000 ASSERT(!cls.IsNull()); |
| 2001 const bool requires_type_arguments = cls.HasTypeArguments(); |
| 2002 Value* type_arguments = NULL; |
| 2003 if (requires_type_arguments) { |
| 2004 ASSERT(cls.type_arguments_field_offset() == |
| 2005 Closure::type_arguments_offset()); |
| 2006 const Class& instantiator_class = Class::Handle( |
| 2007 owner()->parsed_function()->function().Owner()); |
| 2008 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), |
| 2009 instantiator_class, |
| 2010 NULL); |
| 2011 arguments->Add(PushArgument(type_arguments)); |
| 2012 |
| 2013 Value* instantiator_val = Bind(new ConstantInstr( |
| 2014 Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator)))); |
| 2015 arguments->Add(PushArgument(instantiator_val)); |
| 2016 } |
| 2017 AllocateObjectInstr* alloc = new AllocateObjectInstr(node->token_pos(), |
| 2018 cls, |
| 2019 arguments); |
| 2020 alloc->set_closure_function(function); |
| 2021 |
| 2022 // Create fake fields for function and context. Only the context field is |
| 2023 // stored at the allocation to be used later when inlining a closure call. |
| 2024 const Field& function_field = |
| 2025 Field::ZoneHandle( |
| 2026 Field::New(Symbols::ClosureFunctionField(), |
| 2027 false, // !static |
| 2028 false, // !final |
| 2029 false, // !const |
| 2030 alloc->cls(), |
| 2031 0)); // No token position. |
| 2032 function_field.SetOffset(Closure::function_offset()); |
| 2033 const Field& context_field = |
| 2034 Field::ZoneHandle(Field::New( |
| 2035 Symbols::ClosureContextField(), |
| 2036 false, // !static |
| 2037 false, // !final |
| 2038 false, // !const |
| 2039 alloc->cls(), |
| 2040 0)); // No token position. |
| 2041 context_field.SetOffset(Closure::context_offset()); |
| 2042 alloc->set_context_field(context_field); |
| 2043 |
| 2044 Value* closure_val = Bind(alloc); |
| 2045 { LocalVariable* tmp_var = EnterTempLocalScope(closure_val); |
| 2046 // Store function. |
| 2047 Value* tmp_val = Bind(new LoadLocalInstr(*tmp_var)); |
| 2048 Value* func_val = |
| 2049 Bind(new ConstantInstr(Function::ZoneHandle(function.raw()))); |
| 2050 Do(new StoreInstanceFieldInstr(function_field, |
| 2051 tmp_val, |
| 2052 func_val, |
| 2053 kEmitStoreBarrier)); |
| 2054 // Store current context. |
| 2055 tmp_val = Bind(new LoadLocalInstr(*tmp_var)); |
| 2056 Value* context = Bind(new CurrentContextInstr()); |
| 2057 Do(new StoreInstanceFieldInstr(context_field, |
| 2058 tmp_val, |
| 2059 context, |
| 2060 kEmitStoreBarrier)); |
| 2061 ReturnDefinition(ExitTempLocalScope(tmp_var)); |
| 2062 } |
| 1994 } else { | 2063 } else { |
| 1995 ASSERT(function.IsImplicitInstanceClosureFunction()); | 2064 ASSERT(function.IsImplicitInstanceClosureFunction()); |
| 1996 ValueGraphVisitor for_receiver(owner(), temp_index()); | 2065 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 1997 node->receiver()->Visit(&for_receiver); | 2066 node->receiver()->Visit(&for_receiver); |
| 1998 Append(for_receiver); | 2067 Append(for_receiver); |
| 1999 receiver = for_receiver.value(); | 2068 Value* receiver = for_receiver.value(); |
| 2069 |
| 2070 PushArgumentInstr* push_receiver = PushArgument(receiver); |
| 2071 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2072 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 2073 arguments->Add(push_receiver); |
| 2074 ASSERT(function.context_scope() != ContextScope::null()); |
| 2075 |
| 2076 // The function type of a closure may have type arguments. In that case, |
| 2077 // pass the type arguments of the instantiator. Otherwise, pass null object. |
| 2078 const Class& cls = Class::Handle(function.signature_class()); |
| 2079 ASSERT(!cls.IsNull()); |
| 2080 const bool requires_type_arguments = cls.HasTypeArguments(); |
| 2081 Value* type_arguments = NULL; |
| 2082 if (requires_type_arguments) { |
| 2083 const Class& instantiator_class = Class::Handle( |
| 2084 owner()->parsed_function()->function().Owner()); |
| 2085 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), |
| 2086 instantiator_class, |
| 2087 NULL); |
| 2088 } else { |
| 2089 type_arguments = BuildNullValue(); |
| 2090 } |
| 2091 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments); |
| 2092 arguments->Add(push_type_arguments); |
| 2093 ReturnDefinition( |
| 2094 new CreateClosureInstr(node->function(), arguments, node->token_pos())); |
| 2000 } | 2095 } |
| 2001 PushArgumentInstr* push_receiver = PushArgument(receiver); | |
| 2002 ZoneGrowableArray<PushArgumentInstr*>* arguments = | |
| 2003 new ZoneGrowableArray<PushArgumentInstr*>(2); | |
| 2004 arguments->Add(push_receiver); | |
| 2005 ASSERT(function.context_scope() != ContextScope::null()); | |
| 2006 | |
| 2007 // The function type of a closure may have type arguments. In that case, pass | |
| 2008 // the type arguments of the instantiator. Otherwise, pass null object. | |
| 2009 const Class& cls = Class::Handle(function.signature_class()); | |
| 2010 ASSERT(!cls.IsNull()); | |
| 2011 const bool requires_type_arguments = cls.HasTypeArguments(); | |
| 2012 Value* type_arguments = NULL; | |
| 2013 if (requires_type_arguments) { | |
| 2014 ASSERT(!function.IsImplicitStaticClosureFunction()); | |
| 2015 const Class& instantiator_class = Class::Handle( | |
| 2016 owner()->parsed_function()->function().Owner()); | |
| 2017 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), | |
| 2018 instantiator_class, | |
| 2019 NULL); | |
| 2020 } else { | |
| 2021 type_arguments = BuildNullValue(); | |
| 2022 } | |
| 2023 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments); | |
| 2024 arguments->Add(push_type_arguments); | |
| 2025 ReturnDefinition( | |
| 2026 new CreateClosureInstr(node->function(), arguments, node->token_pos())); | |
| 2027 } | 2096 } |
| 2028 | 2097 |
| 2029 | 2098 |
| 2030 void EffectGraphVisitor::TranslateArgumentList( | 2099 void EffectGraphVisitor::TranslateArgumentList( |
| 2031 const ArgumentListNode& node, | 2100 const ArgumentListNode& node, |
| 2032 ZoneGrowableArray<Value*>* values) { | 2101 ZoneGrowableArray<Value*>* values) { |
| 2033 for (intptr_t i = 0; i < node.length(); ++i) { | 2102 for (intptr_t i = 0; i < node.length(); ++i) { |
| 2034 ValueGraphVisitor for_argument(owner(), temp_index()); | 2103 ValueGraphVisitor for_argument(owner(), temp_index()); |
| 2035 node.NodeAt(i)->Visit(&for_argument); | 2104 node.NodeAt(i)->Visit(&for_argument); |
| 2036 Append(for_argument); | 2105 Append(for_argument); |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2193 // The uninstantiated type arguments cannot be verified to be within their | 2262 // The uninstantiated type arguments cannot be verified to be within their |
| 2194 // bounds at compile time, so verify them at runtime. | 2263 // bounds at compile time, so verify them at runtime. |
| 2195 allocation = new AllocateObjectWithBoundsCheckInstr(node); | 2264 allocation = new AllocateObjectWithBoundsCheckInstr(node); |
| 2196 } else { | 2265 } else { |
| 2197 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = | 2266 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = |
| 2198 new ZoneGrowableArray<PushArgumentInstr*>(); | 2267 new ZoneGrowableArray<PushArgumentInstr*>(); |
| 2199 if (requires_type_arguments) { | 2268 if (requires_type_arguments) { |
| 2200 BuildConstructorTypeArguments(node, allocate_arguments); | 2269 BuildConstructorTypeArguments(node, allocate_arguments); |
| 2201 } | 2270 } |
| 2202 | 2271 |
| 2203 allocation = new AllocateObjectInstr(node, allocate_arguments); | 2272 allocation = new AllocateObjectInstr( |
| 2273 node->token_pos(), |
| 2274 Class::ZoneHandle(node->constructor().Owner()), |
| 2275 allocate_arguments); |
| 2204 } | 2276 } |
| 2205 return Bind(allocation); | 2277 return Bind(allocation); |
| 2206 } | 2278 } |
| 2207 | 2279 |
| 2208 | 2280 |
| 2209 void EffectGraphVisitor::BuildConstructorCall( | 2281 void EffectGraphVisitor::BuildConstructorCall( |
| 2210 ConstructorCallNode* node, | 2282 ConstructorCallNode* node, |
| 2211 PushArgumentInstr* push_alloc_value) { | 2283 PushArgumentInstr* push_alloc_value) { |
| 2212 Value* ctor_arg = Bind( | 2284 Value* ctor_arg = Bind( |
| 2213 new ConstantInstr(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); | 2285 new ConstantInstr(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); |
| (...skipping 1336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3550 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 3622 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 3551 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 3623 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 3552 OS::SNPrint(chars, len, kFormat, function_name, reason); | 3624 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 3553 const Error& error = Error::Handle( | 3625 const Error& error = Error::Handle( |
| 3554 LanguageError::New(String::Handle(String::New(chars)))); | 3626 LanguageError::New(String::Handle(String::New(chars)))); |
| 3555 Isolate::Current()->long_jump_base()->Jump(1, error); | 3627 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 3556 } | 3628 } |
| 3557 | 3629 |
| 3558 | 3630 |
| 3559 } // namespace dart | 3631 } // namespace dart |
| OLD | NEW |