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 1984 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1995 | 1995 |
1996 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { | 1996 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { |
1997 const String& getter_name = | 1997 const String& getter_name = |
1998 String::Handle(Field::GetterName(node->field_name())); | 1998 String::Handle(Field::GetterName(node->field_name())); |
1999 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1999 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
2000 new ZoneGrowableArray<PushArgumentInstr*>(); | 2000 new ZoneGrowableArray<PushArgumentInstr*>(); |
2001 Function& getter_function = Function::ZoneHandle(); | 2001 Function& getter_function = Function::ZoneHandle(); |
2002 if (node->is_super_getter()) { | 2002 if (node->is_super_getter()) { |
2003 // Statically resolved instance getter, i.e. "super getter". | 2003 // Statically resolved instance getter, i.e. "super getter". |
2004 getter_function = | 2004 getter_function = |
2005 Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name); | 2005 Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name); |
2006 ASSERT(!getter_function.IsNull()); | 2006 ASSERT(!getter_function.IsNull()); |
2007 ASSERT(node->receiver() != NULL); | 2007 ASSERT(node->receiver() != NULL); |
2008 ValueGraphVisitor receiver_value(owner(), temp_index()); | 2008 ValueGraphVisitor receiver_value(owner(), temp_index()); |
2009 node->receiver()->Visit(&receiver_value); | 2009 node->receiver()->Visit(&receiver_value); |
2010 Append(receiver_value); | 2010 Append(receiver_value); |
2011 arguments->Add(PushArgument(receiver_value.value())); | 2011 arguments->Add(PushArgument(receiver_value.value())); |
2012 } else { | 2012 } else { |
2013 getter_function = node->cls().LookupStaticFunction(getter_name); | 2013 getter_function = node->cls().LookupStaticFunction(getter_name); |
2014 if (getter_function.IsNull()) { | 2014 if (getter_function.IsNull()) { |
2015 // When the parser encounters a reference to a static field materialized | 2015 // When the parser encounters a reference to a static field materialized |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2258 ReturnDefinition(BuildStoreStaticField(node, kResultNotNeeded)); | 2258 ReturnDefinition(BuildStoreStaticField(node, kResultNotNeeded)); |
2259 } | 2259 } |
2260 | 2260 |
2261 | 2261 |
2262 void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { | 2262 void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { |
2263 ReturnDefinition(BuildStoreStaticField(node, kResultNeeded)); | 2263 ReturnDefinition(BuildStoreStaticField(node, kResultNeeded)); |
2264 } | 2264 } |
2265 | 2265 |
2266 | 2266 |
2267 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { | 2267 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { |
| 2268 Function* super_function = NULL; |
| 2269 if (node->IsSuperLoad()) { |
| 2270 // Resolve the load indexed operator in the super class. |
| 2271 const String& index_operator_name = |
| 2272 String::ZoneHandle(Symbols::IndexToken()); |
| 2273 super_function = &Function::ZoneHandle( |
| 2274 Resolver::ResolveDynamicAnyArgs(node->super_class(), |
| 2275 index_operator_name)); |
| 2276 if (super_function->IsNull()) { |
| 2277 // Could not resolve super operator. Generate call noSuchMethod() of the |
| 2278 // super class instead. |
| 2279 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); |
| 2280 arguments->Add(node->index_expr()); |
| 2281 BuildStaticNoSuchMethodCall(node->super_class(), |
| 2282 node->array(), |
| 2283 index_operator_name, |
| 2284 arguments); |
| 2285 return; |
| 2286 } |
| 2287 } |
2268 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2288 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
2269 new ZoneGrowableArray<PushArgumentInstr*>(2); | 2289 new ZoneGrowableArray<PushArgumentInstr*>(2); |
2270 ValueGraphVisitor for_array(owner(), temp_index()); | 2290 ValueGraphVisitor for_array(owner(), temp_index()); |
2271 node->array()->Visit(&for_array); | 2291 node->array()->Visit(&for_array); |
2272 Append(for_array); | 2292 Append(for_array); |
2273 arguments->Add(PushArgument(for_array.value())); | 2293 arguments->Add(PushArgument(for_array.value())); |
2274 | 2294 |
2275 ValueGraphVisitor for_index(owner(), temp_index()); | 2295 ValueGraphVisitor for_index(owner(), temp_index()); |
2276 node->index_expr()->Visit(&for_index); | 2296 node->index_expr()->Visit(&for_index); |
2277 Append(for_index); | 2297 Append(for_index); |
2278 arguments->Add(PushArgument(for_index.value())); | 2298 arguments->Add(PushArgument(for_index.value())); |
2279 | 2299 |
2280 const intptr_t checked_argument_count = 1; | 2300 if (super_function != NULL) { |
2281 const String& name = | 2301 // Generate static call to super operator. |
2282 String::ZoneHandle(Symbols::New(Token::Str(Token::kINDEX))); | 2302 StaticCallInstr* load = new StaticCallInstr(node->token_pos(), |
2283 InstanceCallInstr* load = new InstanceCallInstr(node->token_pos(), | 2303 *super_function, |
2284 name, | 2304 Array::ZoneHandle(), |
2285 Token::kINDEX, | 2305 arguments); |
2286 arguments, | 2306 ReturnDefinition(load); |
2287 Array::ZoneHandle(), | 2307 } else { |
2288 checked_argument_count); | 2308 // Generate dynamic call to index operator. |
2289 ReturnDefinition(load); | 2309 const intptr_t checked_argument_count = 1; |
| 2310 const String& name = String::ZoneHandle(Symbols::IndexToken()); |
| 2311 InstanceCallInstr* load = new InstanceCallInstr(node->token_pos(), |
| 2312 name, |
| 2313 Token::kINDEX, |
| 2314 arguments, |
| 2315 Array::ZoneHandle(), |
| 2316 checked_argument_count); |
| 2317 ReturnDefinition(load); |
| 2318 } |
2290 } | 2319 } |
2291 | 2320 |
2292 | 2321 |
2293 Definition* EffectGraphVisitor::BuildStoreIndexedValues( | 2322 Definition* EffectGraphVisitor::BuildStoreIndexedValues( |
2294 StoreIndexedNode* node, | 2323 StoreIndexedNode* node, |
2295 bool result_is_needed) { | 2324 bool result_is_needed) { |
| 2325 Function* super_function = NULL; |
| 2326 if (node->IsSuperStore()) { |
| 2327 // Resolve the store indexed operator in the super class. |
| 2328 const String& store_index_op_name = |
| 2329 String::ZoneHandle(Symbols::AssignIndexToken()); |
| 2330 super_function = &Function::ZoneHandle( |
| 2331 Resolver::ResolveDynamicAnyArgs(node->super_class(), |
| 2332 store_index_op_name)); |
| 2333 if (super_function->IsNull()) { |
| 2334 // Could not resolve super operator. Generate call noSuchMethod() of the |
| 2335 // super class instead. |
| 2336 if (result_is_needed) { |
| 2337 // Even though noSuchMethod most likely does not return, |
| 2338 // we save the stored value if the result is needed. |
| 2339 ValueGraphVisitor for_value(owner(), temp_index()); |
| 2340 node->value()->Visit(&for_value); |
| 2341 Append(for_value); |
| 2342 Bind(BuildStoreExprTemp(for_value.value())); |
| 2343 } |
| 2344 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); |
| 2345 arguments->Add(node->index_expr()); |
| 2346 arguments->Add(node->value()); |
| 2347 StaticCallInstr* call = |
| 2348 BuildStaticNoSuchMethodCall(node->super_class(), |
| 2349 node->array(), |
| 2350 store_index_op_name, |
| 2351 arguments); |
| 2352 if (result_is_needed) { |
| 2353 Do(call); |
| 2354 return BuildLoadExprTemp(); |
| 2355 } else { |
| 2356 return call; |
| 2357 } |
| 2358 } |
| 2359 } |
| 2360 |
2296 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2361 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
2297 new ZoneGrowableArray<PushArgumentInstr*>(3); | 2362 new ZoneGrowableArray<PushArgumentInstr*>(3); |
2298 ValueGraphVisitor for_array(owner(), temp_index()); | 2363 ValueGraphVisitor for_array(owner(), temp_index()); |
2299 node->array()->Visit(&for_array); | 2364 node->array()->Visit(&for_array); |
2300 Append(for_array); | 2365 Append(for_array); |
2301 arguments->Add(PushArgument(for_array.value())); | 2366 arguments->Add(PushArgument(for_array.value())); |
2302 | 2367 |
2303 ValueGraphVisitor for_index(owner(), temp_index()); | 2368 ValueGraphVisitor for_index(owner(), temp_index()); |
2304 node->index_expr()->Visit(&for_index); | 2369 node->index_expr()->Visit(&for_index); |
2305 Append(for_index); | 2370 Append(for_index); |
2306 arguments->Add(PushArgument(for_index.value())); | 2371 arguments->Add(PushArgument(for_index.value())); |
2307 | 2372 |
2308 ValueGraphVisitor for_value(owner(), temp_index()); | 2373 ValueGraphVisitor for_value(owner(), temp_index()); |
2309 node->value()->Visit(&for_value); | 2374 node->value()->Visit(&for_value); |
2310 Append(for_value); | 2375 Append(for_value); |
2311 Value* value = NULL; | 2376 Value* value = NULL; |
2312 if (result_is_needed) { | 2377 if (result_is_needed) { |
2313 value = Bind(BuildStoreExprTemp(for_value.value())); | 2378 value = Bind(BuildStoreExprTemp(for_value.value())); |
2314 } else { | 2379 } else { |
2315 value = for_value.value(); | 2380 value = for_value.value(); |
2316 } | 2381 } |
2317 arguments->Add(PushArgument(value)); | 2382 arguments->Add(PushArgument(value)); |
2318 | 2383 |
2319 const intptr_t checked_argument_count = 3; | 2384 if (super_function != NULL) { |
2320 const String& name = | 2385 // Generate static call to super operator []=. |
2321 String::ZoneHandle(Symbols::New(Token::Str(Token::kASSIGN_INDEX))); | 2386 |
2322 InstanceCallInstr* store = new InstanceCallInstr(node->token_pos(), | 2387 StaticCallInstr* store = |
2323 name, | 2388 new StaticCallInstr(node->token_pos(), |
2324 Token::kASSIGN_INDEX, | 2389 *super_function, |
2325 arguments, | 2390 Array::ZoneHandle(), |
2326 Array::ZoneHandle(), | 2391 arguments); |
2327 checked_argument_count); | 2392 if (result_is_needed) { |
2328 if (result_is_needed) { | 2393 Do(store); |
2329 Do(store); | 2394 return BuildLoadExprTemp(); |
2330 return BuildLoadExprTemp(); | 2395 } else { |
| 2396 return store; |
| 2397 } |
2331 } else { | 2398 } else { |
2332 return store; | 2399 // Generate dynamic call to operator []=. |
| 2400 const intptr_t checked_argument_count = 3; |
| 2401 const String& name = |
| 2402 String::ZoneHandle(Symbols::New(Token::Str(Token::kASSIGN_INDEX))); |
| 2403 InstanceCallInstr* store = |
| 2404 new InstanceCallInstr(node->token_pos(), |
| 2405 name, |
| 2406 Token::kASSIGN_INDEX, |
| 2407 arguments, |
| 2408 Array::ZoneHandle(), |
| 2409 checked_argument_count); |
| 2410 if (result_is_needed) { |
| 2411 Do(store); |
| 2412 return BuildLoadExprTemp(); |
| 2413 } else { |
| 2414 return store; |
| 2415 } |
2333 } | 2416 } |
2334 } | 2417 } |
2335 | 2418 |
2336 | 2419 |
2337 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { | 2420 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { |
2338 ReturnDefinition(BuildStoreIndexedValues(node, kResultNotNeeded)); | 2421 ReturnDefinition(BuildStoreIndexedValues(node, kResultNotNeeded)); |
2339 } | 2422 } |
2340 | 2423 |
2341 | 2424 |
2342 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { | 2425 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2576 | 2659 |
2577 // Generate code for the finally block if one exists. | 2660 // Generate code for the finally block if one exists. |
2578 if ((node->finally_block() != NULL) && is_open()) { | 2661 if ((node->finally_block() != NULL) && is_open()) { |
2579 EffectGraphVisitor for_finally_block(owner(), temp_index()); | 2662 EffectGraphVisitor for_finally_block(owner(), temp_index()); |
2580 node->finally_block()->Visit(&for_finally_block); | 2663 node->finally_block()->Visit(&for_finally_block); |
2581 Append(for_finally_block); | 2664 Append(for_finally_block); |
2582 } | 2665 } |
2583 } | 2666 } |
2584 | 2667 |
2585 | 2668 |
| 2669 // Looks up dynamic method noSuchMethod in target_class |
| 2670 // (including its super class chain) and builds a static call to it. |
| 2671 StaticCallInstr* EffectGraphVisitor::BuildStaticNoSuchMethodCall( |
| 2672 const Class& target_class, |
| 2673 AstNode* receiver, |
| 2674 const String& method_name, |
| 2675 ArgumentListNode* method_arguments) { |
| 2676 const String& no_such_method_name = |
| 2677 String::ZoneHandle(Symbols::NoSuchMethod()); |
| 2678 const Function& no_such_method_func = Function::ZoneHandle( |
| 2679 Resolver::ResolveDynamicAnyArgs(target_class, no_such_method_name)); |
| 2680 // We are guaranteed to find noSuchMethod of class Object. |
| 2681 ASSERT(!no_such_method_func.IsNull()); |
| 2682 |
| 2683 const intptr_t args_pos = method_arguments->token_pos(); |
| 2684 ArgumentListNode* arguments = new ArgumentListNode(args_pos); |
| 2685 // The first argument is the receiver. |
| 2686 arguments->Add(receiver); |
| 2687 // The second argument is the original method name. |
| 2688 // TODO(regis): This will change once mirrors are supported. |
| 2689 arguments->Add(new LiteralNode(args_pos, method_name)); |
| 2690 // The third argument is an array containing the original method arguments. |
| 2691 ArrayNode* args_array = |
| 2692 new ArrayNode(args_pos, Type::ZoneHandle(Type::ListInterface())); |
| 2693 for (intptr_t i = 0; i < method_arguments->length(); i++) { |
| 2694 args_array->AddElement(method_arguments->NodeAt(i)); |
| 2695 } |
| 2696 arguments->Add(args_array); |
| 2697 |
| 2698 ZoneGrowableArray<PushArgumentInstr*>* args = |
| 2699 new ZoneGrowableArray<PushArgumentInstr*>(arguments->length()); |
| 2700 BuildPushArguments(*arguments, args); |
| 2701 return new StaticCallInstr(args_pos, |
| 2702 no_such_method_func, |
| 2703 Array::ZoneHandle(), |
| 2704 args); |
| 2705 } |
| 2706 |
| 2707 |
2586 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { | 2708 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { |
2587 // TODO(kmillikin) non-local control flow is not handled correctly | 2709 // TODO(kmillikin) non-local control flow is not handled correctly |
2588 // by the inliner. | 2710 // by the inliner. |
2589 InlineBailout("EffectGraphVisitor::BuildThrowNode (exception)"); | 2711 InlineBailout("EffectGraphVisitor::BuildThrowNode (exception)"); |
2590 ValueGraphVisitor for_exception(owner(), temp_index()); | 2712 ValueGraphVisitor for_exception(owner(), temp_index()); |
2591 node->exception()->Visit(&for_exception); | 2713 node->exception()->Visit(&for_exception); |
2592 Append(for_exception); | 2714 Append(for_exception); |
2593 PushArgument(for_exception.value()); | 2715 PushArgument(for_exception.value()); |
2594 Instruction* instr = NULL; | 2716 Instruction* instr = NULL; |
2595 if (node->stacktrace() == NULL) { | 2717 if (node->stacktrace() == NULL) { |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2694 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 2816 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
2695 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 2817 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
2696 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2818 OS::SNPrint(chars, len, kFormat, function_name, reason); |
2697 const Error& error = Error::Handle( | 2819 const Error& error = Error::Handle( |
2698 LanguageError::New(String::Handle(String::New(chars)))); | 2820 LanguageError::New(String::Handle(String::New(chars)))); |
2699 Isolate::Current()->long_jump_base()->Jump(1, error); | 2821 Isolate::Current()->long_jump_base()->Jump(1, error); |
2700 } | 2822 } |
2701 | 2823 |
2702 | 2824 |
2703 } // namespace dart | 2825 } // namespace dart |
OLD | NEW |