Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(673)

Side by Side Diff: runtime/vm/flow_graph_builder.cc

Issue 11267027: More fixes for super[] (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698