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/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
(...skipping 2303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2314 // Store current context. | 2314 // Store current context. |
2315 tmp_val = Bind(new LoadLocalInstr(*tmp_var)); | 2315 tmp_val = Bind(new LoadLocalInstr(*tmp_var)); |
2316 Value* context = Bind(new CurrentContextInstr()); | 2316 Value* context = Bind(new CurrentContextInstr()); |
2317 Do(new StoreInstanceFieldInstr(context_field, | 2317 Do(new StoreInstanceFieldInstr(context_field, |
2318 tmp_val, | 2318 tmp_val, |
2319 context, | 2319 context, |
2320 kEmitStoreBarrier)); | 2320 kEmitStoreBarrier)); |
2321 ReturnDefinition(ExitTempLocalScope(tmp_var)); | 2321 ReturnDefinition(ExitTempLocalScope(tmp_var)); |
2322 } | 2322 } |
2323 } else { | 2323 } else { |
2324 // TODO(regis): Merge this branch in the above one. | |
2324 ASSERT(function.IsImplicitInstanceClosureFunction()); | 2325 ASSERT(function.IsImplicitInstanceClosureFunction()); |
2325 ValueGraphVisitor for_receiver(owner()); | |
2326 node->receiver()->Visit(&for_receiver); | |
2327 Append(for_receiver); | |
2328 Value* receiver = for_receiver.value(); | |
2329 | 2326 |
2330 PushArgumentInstr* push_receiver = PushArgument(receiver); | |
2331 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2327 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
2332 new ZoneGrowableArray<PushArgumentInstr*>(2); | 2328 new ZoneGrowableArray<PushArgumentInstr*>(2); // 1? here and above too? |
2333 arguments->Add(push_receiver); | |
2334 ASSERT(function.context_scope() != ContextScope::null()); | 2329 ASSERT(function.context_scope() != ContextScope::null()); |
2335 | 2330 |
2336 // The function type of a closure may have type arguments. In that case, | 2331 // The function type of a closure may have type arguments. In that case, |
2337 // pass the type arguments of the instantiator. Otherwise, pass null object. | 2332 // pass the type arguments of the instantiator. Otherwise, pass null object. |
2338 const Class& cls = Class::Handle(function.signature_class()); | 2333 const Class& cls = Class::ZoneHandle(function.signature_class()); |
2339 ASSERT(!cls.IsNull()); | 2334 ASSERT(!cls.IsNull()); |
2340 const bool requires_type_arguments = cls.NumTypeArguments() > 0; | 2335 const bool requires_type_arguments = cls.NumTypeArguments() > 0; |
2341 Value* type_arguments = NULL; | 2336 Value* type_arguments = NULL; |
2342 if (requires_type_arguments) { | 2337 if (requires_type_arguments) { |
2343 const Class& instantiator_class = Class::Handle( | 2338 const Class& instantiator_class = Class::Handle( |
2344 owner()->parsed_function()->function().Owner()); | 2339 owner()->parsed_function()->function().Owner()); |
2345 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), | 2340 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), |
2346 instantiator_class, | 2341 instantiator_class, |
2347 NULL); | 2342 NULL); |
2348 } else { | 2343 arguments->Add(PushArgument(type_arguments)); |
2349 type_arguments = BuildNullValue(); | |
2350 } | 2344 } |
2351 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments); | 2345 AllocateObjectInstr* alloc = new AllocateObjectInstr(node->token_pos(), |
2352 arguments->Add(push_type_arguments); | 2346 cls, |
2353 ReturnDefinition( | 2347 arguments); |
2354 new CreateClosureInstr(node->function(), arguments, node->token_pos())); | 2348 alloc->set_closure_function(function); |
2349 | |
2350 // Create fake fields for function and context. Only the context field is | |
2351 // stored at the allocation to be used later when inlining a closure call. | |
2352 const Field& function_field = | |
2353 Field::ZoneHandle( | |
2354 Field::New(Symbols::ClosureFunctionField(), | |
2355 false, // !static | |
2356 false, // !final | |
2357 false, // !const | |
2358 alloc->cls(), | |
2359 0)); // No token position. | |
2360 function_field.SetOffset(Closure::function_offset()); | |
2361 const Field& context_field = | |
2362 Field::ZoneHandle(Field::New( | |
2363 Symbols::ClosureContextField(), | |
2364 false, // !static | |
2365 false, // !final | |
2366 false, // !const | |
2367 alloc->cls(), | |
2368 0)); // No token position. | |
2369 context_field.SetOffset(Closure::context_offset()); | |
2370 alloc->set_context_field(context_field); | |
2371 | |
2372 Value* closure_val = Bind(alloc); | |
2373 { LocalVariable* tmp_var = EnterTempLocalScope(closure_val); | |
2374 // Store function. | |
2375 Value* tmp_val = Bind(new LoadLocalInstr(*tmp_var)); | |
2376 Value* func_val = | |
2377 Bind(new ConstantInstr(Function::ZoneHandle(function.raw()))); | |
2378 Do(new StoreInstanceFieldInstr(function_field, | |
2379 tmp_val, | |
2380 func_val, | |
2381 kEmitStoreBarrier)); | |
2382 // Create new context containing the receiver. | |
2383 const intptr_t kNumContextVariables = 1; // The receiver. | |
2384 Value* allocated_context = | |
2385 Bind(new AllocateContextInstr(node->token_pos(), | |
2386 kNumContextVariables)); | |
2387 { LocalVariable* tmp_var = EnterTempLocalScope(allocated_context); | |
2388 ValueGraphVisitor for_receiver(owner()); | |
2389 node->receiver()->Visit(&for_receiver); | |
Florian Schneider
2014/02/24 18:50:23
Is there a dependency on the evaluation order of t
regis
2014/02/24 19:01:30
I do not think that the evaluation of the type arg
| |
2390 Append(for_receiver); | |
2391 Value* receiver = for_receiver.value(); | |
2392 Value* tmp_val = Bind(new LoadLocalInstr(*tmp_var)); | |
2393 Do(new StoreVMFieldInstr(tmp_val, | |
2394 Context::variable_offset(0), | |
2395 receiver, | |
2396 Type::ZoneHandle())); | |
2397 AddInstruction( | |
2398 new StoreContextInstr(Bind(ExitTempLocalScope(tmp_var)))); | |
Florian Schneider
2014/02/24 18:50:23
The StoreContext does not appear in the original c
regis
2014/02/24 19:01:30
No idea why I have this StoreContextInstr here.
| |
2399 } | |
2400 // Store new context. | |
2401 tmp_val = Bind(new LoadLocalInstr(*tmp_var)); | |
2402 Do(new StoreInstanceFieldInstr(context_field, | |
Florian Schneider
2014/02/24 18:50:23
Try move this store into the inner TempLocalScope:
regis
2014/02/24 19:01:30
Yes, exactly. I already renamed these as you sugge
| |
2403 tmp_val, | |
2404 allocated_context, | |
2405 kEmitStoreBarrier)); | |
2406 ReturnDefinition(ExitTempLocalScope(tmp_var)); | |
2407 } | |
2355 } | 2408 } |
2356 } | 2409 } |
2357 | 2410 |
2358 | 2411 |
2359 void EffectGraphVisitor::BuildPushArguments( | 2412 void EffectGraphVisitor::BuildPushArguments( |
2360 const ArgumentListNode& node, | 2413 const ArgumentListNode& node, |
2361 ZoneGrowableArray<PushArgumentInstr*>* values) { | 2414 ZoneGrowableArray<PushArgumentInstr*>* values) { |
2362 for (intptr_t i = 0; i < node.length(); ++i) { | 2415 for (intptr_t i = 0; i < node.length(); ++i) { |
2363 ValueGraphVisitor for_argument(owner()); | 2416 ValueGraphVisitor for_argument(owner()); |
2364 node.NodeAt(i)->Visit(&for_argument); | 2417 node.NodeAt(i)->Visit(&for_argument); |
(...skipping 1576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3941 LanguageError::kError, | 3994 LanguageError::kError, |
3942 Heap::kNew, | 3995 Heap::kNew, |
3943 "FlowGraphBuilder Bailout: %s %s", | 3996 "FlowGraphBuilder Bailout: %s %s", |
3944 String::Handle(function.name()).ToCString(), | 3997 String::Handle(function.name()).ToCString(), |
3945 reason)); | 3998 reason)); |
3946 Isolate::Current()->long_jump_base()->Jump(1, error); | 3999 Isolate::Current()->long_jump_base()->Jump(1, error); |
3947 } | 4000 } |
3948 | 4001 |
3949 | 4002 |
3950 } // namespace dart | 4003 } // namespace dart |
OLD | NEW |