| 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 2096 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2107 // <Expression> ::= StaticCall { function: Function | 2107 // <Expression> ::= StaticCall { function: Function |
| 2108 // arguments: <ArgumentList> } | 2108 // arguments: <ArgumentList> } |
| 2109 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { | 2109 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { |
| 2110 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2110 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2111 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); | 2111 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
| 2112 BuildPushArguments(*node->arguments(), arguments); | 2112 BuildPushArguments(*node->arguments(), arguments); |
| 2113 StaticCallInstr* call = | 2113 StaticCallInstr* call = |
| 2114 new StaticCallInstr(node->token_pos(), | 2114 new StaticCallInstr(node->token_pos(), |
| 2115 node->function(), | 2115 node->function(), |
| 2116 node->arguments()->names(), | 2116 node->arguments()->names(), |
| 2117 arguments); | 2117 arguments, |
| 2118 owner()->ic_data_array()); |
| 2118 if (node->function().is_native()) { | 2119 if (node->function().is_native()) { |
| 2119 const intptr_t result_cid = GetResultCidOfNative(node->function()); | 2120 const intptr_t result_cid = GetResultCidOfNative(node->function()); |
| 2120 call->set_result_cid(result_cid); | 2121 call->set_result_cid(result_cid); |
| 2121 } | 2122 } |
| 2122 ReturnDefinition(call); | 2123 ReturnDefinition(call); |
| 2123 } | 2124 } |
| 2124 | 2125 |
| 2125 | 2126 |
| 2126 ClosureCallInstr* EffectGraphVisitor::BuildClosureCall( | 2127 ClosureCallInstr* EffectGraphVisitor::BuildClosureCall( |
| 2127 ClosureCallNode* node) { | 2128 ClosureCallNode* node) { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2217 | 2218 |
| 2218 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2219 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2219 new ZoneGrowableArray<PushArgumentInstr*>(2); | 2220 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 2220 arguments->Add(push_alloc_value); | 2221 arguments->Add(push_alloc_value); |
| 2221 arguments->Add(push_ctor_arg); | 2222 arguments->Add(push_ctor_arg); |
| 2222 | 2223 |
| 2223 BuildPushArguments(*node->arguments(), arguments); | 2224 BuildPushArguments(*node->arguments(), arguments); |
| 2224 Do(new StaticCallInstr(node->token_pos(), | 2225 Do(new StaticCallInstr(node->token_pos(), |
| 2225 node->constructor(), | 2226 node->constructor(), |
| 2226 node->arguments()->names(), | 2227 node->arguments()->names(), |
| 2227 arguments)); | 2228 arguments, |
| 2229 owner()->ic_data_array())); |
| 2228 } | 2230 } |
| 2229 | 2231 |
| 2230 | 2232 |
| 2231 // Class that recognizes factories and returns corresponding result cid. | 2233 // Class that recognizes factories and returns corresponding result cid. |
| 2232 class FactoryRecognizer : public AllStatic { | 2234 class FactoryRecognizer : public AllStatic { |
| 2233 public: | 2235 public: |
| 2234 // Return kDynamicCid if factory is not recognized. | 2236 // Return kDynamicCid if factory is not recognized. |
| 2235 static intptr_t ResultCid(const Function& factory) { | 2237 static intptr_t ResultCid(const Function& factory) { |
| 2236 ASSERT(factory.IsFactory()); | 2238 ASSERT(factory.IsFactory()); |
| 2237 const Class& function_class = Class::Handle(factory.Owner()); | 2239 const Class& function_class = Class::Handle(factory.Owner()); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2285 PushArgumentInstr* push_type_arguments = PushArgument( | 2287 PushArgumentInstr* push_type_arguments = PushArgument( |
| 2286 BuildInstantiatedTypeArguments(node->token_pos(), | 2288 BuildInstantiatedTypeArguments(node->token_pos(), |
| 2287 node->type_arguments())); | 2289 node->type_arguments())); |
| 2288 arguments->Add(push_type_arguments); | 2290 arguments->Add(push_type_arguments); |
| 2289 ASSERT(arguments->length() == 1); | 2291 ASSERT(arguments->length() == 1); |
| 2290 BuildPushArguments(*node->arguments(), arguments); | 2292 BuildPushArguments(*node->arguments(), arguments); |
| 2291 StaticCallInstr* call = | 2293 StaticCallInstr* call = |
| 2292 new StaticCallInstr(node->token_pos(), | 2294 new StaticCallInstr(node->token_pos(), |
| 2293 node->constructor(), | 2295 node->constructor(), |
| 2294 node->arguments()->names(), | 2296 node->arguments()->names(), |
| 2295 arguments); | 2297 arguments, |
| 2298 owner()->ic_data_array()); |
| 2296 const intptr_t result_cid = GetResultCidOfListFactory(node); | 2299 const intptr_t result_cid = GetResultCidOfListFactory(node); |
| 2297 if (result_cid != kDynamicCid) { | 2300 if (result_cid != kDynamicCid) { |
| 2298 call->set_result_cid(result_cid); | 2301 call->set_result_cid(result_cid); |
| 2299 call->set_is_known_list_constructor(true); | 2302 call->set_is_known_list_constructor(true); |
| 2300 // Recognized fixed length array factory must have two arguments: | 2303 // Recognized fixed length array factory must have two arguments: |
| 2301 // (0) type-arguments, (1) length. | 2304 // (0) type-arguments, (1) length. |
| 2302 ASSERT(!LoadFieldInstr::IsFixedLengthArrayCid(result_cid) || | 2305 ASSERT(!LoadFieldInstr::IsFixedLengthArrayCid(result_cid) || |
| 2303 arguments->length() == 2); | 2306 arguments->length() == 2); |
| 2304 } | 2307 } |
| 2305 ReturnDefinition(call); | 2308 ReturnDefinition(call); |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2640 InvocationMirror::kStatic, | 2643 InvocationMirror::kStatic, |
| 2641 InvocationMirror::kGetter)); | 2644 InvocationMirror::kGetter)); |
| 2642 ReturnDefinition(call); | 2645 ReturnDefinition(call); |
| 2643 return; | 2646 return; |
| 2644 } | 2647 } |
| 2645 } | 2648 } |
| 2646 ASSERT(!getter_function.IsNull()); | 2649 ASSERT(!getter_function.IsNull()); |
| 2647 StaticCallInstr* call = new StaticCallInstr(node->token_pos(), | 2650 StaticCallInstr* call = new StaticCallInstr(node->token_pos(), |
| 2648 getter_function, | 2651 getter_function, |
| 2649 Object::null_array(), // No names | 2652 Object::null_array(), // No names |
| 2650 arguments); | 2653 arguments, |
| 2654 owner()->ic_data_array()); |
| 2651 ReturnDefinition(call); | 2655 ReturnDefinition(call); |
| 2652 } | 2656 } |
| 2653 | 2657 |
| 2654 | 2658 |
| 2655 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, | 2659 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, |
| 2656 bool result_is_needed) { | 2660 bool result_is_needed) { |
| 2657 const String& setter_name = | 2661 const String& setter_name = |
| 2658 String::ZoneHandle(Field::SetterSymbol(node->field_name())); | 2662 String::ZoneHandle(Field::SetterSymbol(node->field_name())); |
| 2659 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2663 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2660 new ZoneGrowableArray<PushArgumentInstr*>(1); | 2664 new ZoneGrowableArray<PushArgumentInstr*>(1); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2707 if (result_is_needed) { | 2711 if (result_is_needed) { |
| 2708 value = Bind(BuildStoreExprTemp(for_value.value())); | 2712 value = Bind(BuildStoreExprTemp(for_value.value())); |
| 2709 } else { | 2713 } else { |
| 2710 value = for_value.value(); | 2714 value = for_value.value(); |
| 2711 } | 2715 } |
| 2712 arguments->Add(PushArgument(value)); | 2716 arguments->Add(PushArgument(value)); |
| 2713 | 2717 |
| 2714 call = new StaticCallInstr(node->token_pos(), | 2718 call = new StaticCallInstr(node->token_pos(), |
| 2715 setter_function, | 2719 setter_function, |
| 2716 Object::null_array(), // No names. | 2720 Object::null_array(), // No names. |
| 2717 arguments); | 2721 arguments, |
| 2722 owner()->ic_data_array()); |
| 2718 } | 2723 } |
| 2719 if (result_is_needed) { | 2724 if (result_is_needed) { |
| 2720 Do(call); | 2725 Do(call); |
| 2721 ReturnDefinition(BuildLoadExprTemp()); | 2726 ReturnDefinition(BuildLoadExprTemp()); |
| 2722 } else { | 2727 } else { |
| 2723 ReturnDefinition(call); | 2728 ReturnDefinition(call); |
| 2724 } | 2729 } |
| 2725 } | 2730 } |
| 2726 | 2731 |
| 2727 | 2732 |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2928 ValueGraphVisitor for_index(owner(), temp_index()); | 2933 ValueGraphVisitor for_index(owner(), temp_index()); |
| 2929 node->index_expr()->Visit(&for_index); | 2934 node->index_expr()->Visit(&for_index); |
| 2930 Append(for_index); | 2935 Append(for_index); |
| 2931 arguments->Add(PushArgument(for_index.value())); | 2936 arguments->Add(PushArgument(for_index.value())); |
| 2932 | 2937 |
| 2933 if (super_function != NULL) { | 2938 if (super_function != NULL) { |
| 2934 // Generate static call to super operator. | 2939 // Generate static call to super operator. |
| 2935 StaticCallInstr* load = new StaticCallInstr(node->token_pos(), | 2940 StaticCallInstr* load = new StaticCallInstr(node->token_pos(), |
| 2936 *super_function, | 2941 *super_function, |
| 2937 Object::null_array(), | 2942 Object::null_array(), |
| 2938 arguments); | 2943 arguments, |
| 2944 owner()->ic_data_array()); |
| 2939 ReturnDefinition(load); | 2945 ReturnDefinition(load); |
| 2940 } else { | 2946 } else { |
| 2941 // Generate dynamic call to index operator. | 2947 // Generate dynamic call to index operator. |
| 2942 const intptr_t checked_argument_count = 1; | 2948 const intptr_t checked_argument_count = 1; |
| 2943 InstanceCallInstr* load = new InstanceCallInstr(node->token_pos(), | 2949 InstanceCallInstr* load = new InstanceCallInstr(node->token_pos(), |
| 2944 Symbols::IndexToken(), | 2950 Symbols::IndexToken(), |
| 2945 Token::kINDEX, | 2951 Token::kINDEX, |
| 2946 arguments, | 2952 arguments, |
| 2947 Object::null_array(), | 2953 Object::null_array(), |
| 2948 checked_argument_count, | 2954 checked_argument_count, |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3007 } | 3013 } |
| 3008 arguments->Add(PushArgument(value)); | 3014 arguments->Add(PushArgument(value)); |
| 3009 | 3015 |
| 3010 if (super_function != NULL) { | 3016 if (super_function != NULL) { |
| 3011 // Generate static call to super operator []=. | 3017 // Generate static call to super operator []=. |
| 3012 | 3018 |
| 3013 StaticCallInstr* store = | 3019 StaticCallInstr* store = |
| 3014 new StaticCallInstr(node->token_pos(), | 3020 new StaticCallInstr(node->token_pos(), |
| 3015 *super_function, | 3021 *super_function, |
| 3016 Object::null_array(), | 3022 Object::null_array(), |
| 3017 arguments); | 3023 arguments, |
| 3024 owner()->ic_data_array()); |
| 3018 if (result_is_needed) { | 3025 if (result_is_needed) { |
| 3019 Do(store); | 3026 Do(store); |
| 3020 return BuildLoadExprTemp(); | 3027 return BuildLoadExprTemp(); |
| 3021 } else { | 3028 } else { |
| 3022 return store; | 3029 return store; |
| 3023 } | 3030 } |
| 3024 } else { | 3031 } else { |
| 3025 // Generate dynamic call to operator []=. | 3032 // Generate dynamic call to operator []=. |
| 3026 const intptr_t checked_argument_count = 3; | 3033 const intptr_t checked_argument_count = 3; |
| 3027 const String& name = | 3034 const String& name = |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3319 const Function& no_such_method_func = Function::ZoneHandle( | 3326 const Function& no_such_method_func = Function::ZoneHandle( |
| 3320 Resolver::ResolveDynamicAnyArgs(target_class, Symbols::NoSuchMethod())); | 3327 Resolver::ResolveDynamicAnyArgs(target_class, Symbols::NoSuchMethod())); |
| 3321 // We are guaranteed to find noSuchMethod of class Object. | 3328 // We are guaranteed to find noSuchMethod of class Object. |
| 3322 ASSERT(!no_such_method_func.IsNull()); | 3329 ASSERT(!no_such_method_func.IsNull()); |
| 3323 ZoneGrowableArray<PushArgumentInstr*>* push_arguments = | 3330 ZoneGrowableArray<PushArgumentInstr*>* push_arguments = |
| 3324 new ZoneGrowableArray<PushArgumentInstr*>(2); | 3331 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 3325 BuildPushArguments(*args, push_arguments); | 3332 BuildPushArguments(*args, push_arguments); |
| 3326 return new StaticCallInstr(args_pos, | 3333 return new StaticCallInstr(args_pos, |
| 3327 no_such_method_func, | 3334 no_such_method_func, |
| 3328 Object::null_array(), | 3335 Object::null_array(), |
| 3329 push_arguments); | 3336 push_arguments, |
| 3337 owner()->ic_data_array()); |
| 3330 } | 3338 } |
| 3331 StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError( | 3339 StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError( |
| 3332 intptr_t token_pos, | 3340 intptr_t token_pos, |
| 3333 const Class& function_class, | 3341 const Class& function_class, |
| 3334 const String& function_name, | 3342 const String& function_name, |
| 3335 int invocation_type) { | 3343 int invocation_type) { |
| 3336 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 3344 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 3337 new ZoneGrowableArray<PushArgumentInstr*>(); | 3345 new ZoneGrowableArray<PushArgumentInstr*>(); |
| 3338 // Object receiver. | 3346 // Object receiver. |
| 3339 // TODO(regis): For now, we pass a class literal of the unresolved | 3347 // TODO(regis): For now, we pass a class literal of the unresolved |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3375 const Function& func = Function::ZoneHandle( | 3383 const Function& func = Function::ZoneHandle( |
| 3376 Resolver::ResolveStatic(cls, | 3384 Resolver::ResolveStatic(cls, |
| 3377 PrivateCoreLibName(Symbols::ThrowNew()), | 3385 PrivateCoreLibName(Symbols::ThrowNew()), |
| 3378 arguments->length(), | 3386 arguments->length(), |
| 3379 Object::null_array(), | 3387 Object::null_array(), |
| 3380 Resolver::kIsQualified)); | 3388 Resolver::kIsQualified)); |
| 3381 ASSERT(!func.IsNull()); | 3389 ASSERT(!func.IsNull()); |
| 3382 return new StaticCallInstr(token_pos, | 3390 return new StaticCallInstr(token_pos, |
| 3383 func, | 3391 func, |
| 3384 Object::null_array(), // No names. | 3392 Object::null_array(), // No names. |
| 3385 arguments); | 3393 arguments, |
| 3394 owner()->ic_data_array()); |
| 3386 } | 3395 } |
| 3387 | 3396 |
| 3388 | 3397 |
| 3389 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { | 3398 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { |
| 3390 ValueGraphVisitor for_exception(owner(), temp_index()); | 3399 ValueGraphVisitor for_exception(owner(), temp_index()); |
| 3391 node->exception()->Visit(&for_exception); | 3400 node->exception()->Visit(&for_exception); |
| 3392 Append(for_exception); | 3401 Append(for_exception); |
| 3393 PushArgument(for_exception.value()); | 3402 PushArgument(for_exception.value()); |
| 3394 Instruction* instr = NULL; | 3403 Instruction* instr = NULL; |
| 3395 if (node->stacktrace() == NULL) { | 3404 if (node->stacktrace() == NULL) { |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3505 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 3514 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 3506 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 3515 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 3507 OS::SNPrint(chars, len, kFormat, function_name, reason); | 3516 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 3508 const Error& error = Error::Handle( | 3517 const Error& error = Error::Handle( |
| 3509 LanguageError::New(String::Handle(String::New(chars)))); | 3518 LanguageError::New(String::Handle(String::New(chars)))); |
| 3510 Isolate::Current()->long_jump_base()->Jump(1, error); | 3519 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 3511 } | 3520 } |
| 3512 | 3521 |
| 3513 | 3522 |
| 3514 } // namespace dart | 3523 } // namespace dart |
| OLD | NEW |