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

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

Issue 2411823003: VM support for running Kernel binaries. (Closed)
Patch Set: Address initial review comments Created 4 years, 2 months 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
OLDNEW
(Empty)
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
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.
4
5 #include "vm/dil_reader.h"
6
7 #include <string.h>
8
9 #include "vm/dart_api_impl.h"
10 #include "vm/longjump.h"
11 #include "vm/object_store.h"
12 #include "vm/parser.h"
13 #include "vm/symbols.h"
14
15 namespace dart {
16 namespace dil {
17
18 #define Z (zone_)
19 #define I (isolate_)
20 #define T (type_translator_)
21 #define H (translation_helper_)
22
23 // FIXME(kustermann): We should add support for type conversion to annotate
24 // fields/parameters/variables with proper types.
25
26
27 class SimpleExpressionConverter : public ExpressionVisitor {
28 public:
29 SimpleExpressionConverter(Thread* thread, Zone* zone)
30 : translation_helper_(thread, zone, NULL),
31 zone_(zone),
32 is_simple_(false),
33 simple_value_(NULL) {}
34
35 virtual void VisitDefaultExpression(Expression* node) { is_simple_ = false; }
36
37 virtual void VisitIntLiteral(IntLiteral* node) {
38 is_simple_ = true;
39 simple_value_ =
40 &Integer::ZoneHandle(Z, Integer::New(node->value(), Heap::kOld));
41 *simple_value_ = H.Canonicalize(*simple_value_);
42 }
43
44 virtual void VisitBigintLiteral(BigintLiteral* node) {
45 is_simple_ = true;
46 simple_value_ = &Integer::ZoneHandle(
47 Z, Integer::New(H.DartString(node->value(), Heap::kOld)));
48 *simple_value_ = H.Canonicalize(*simple_value_);
49 }
50
51 virtual void VisitDoubleLiteral(DoubleLiteral* node) {
52 is_simple_ = true;
53 simple_value_ = &Double::ZoneHandle(
54 Z, Double::New(H.DartString(node->value()), Heap::kOld));
55 *simple_value_ = H.Canonicalize(*simple_value_);
56 }
57
58 virtual void VisitBoolLiteral(BoolLiteral* node) {
59 is_simple_ = true;
60 simple_value_ = &Bool::Handle(Z, Bool::Get(node->value()).raw());
61 }
62
63 virtual void VisitNullLiteral(NullLiteral* node) {
64 is_simple_ = true;
65 simple_value_ = &dart::Instance::ZoneHandle(Z, dart::Instance::null());
66 }
67
68 virtual void VisitStringLiteral(StringLiteral* node) {
69 is_simple_ = true;
70 simple_value_ = &H.DartSymbol(node->value());
71 }
72
73 bool IsSimple(Expression* expression) {
74 expression->AcceptExpressionVisitor(this);
75 return is_simple_;
76 }
77
78 const dart::Instance& SimpleValue() { return *simple_value_; }
79
80 private:
81 TranslationHelper translation_helper_;
82 dart::Zone* zone_;
83 bool is_simple_;
84 dart::Instance* simple_value_;
85 };
86
87 void BuildingTranslationHelper::SetFinalize(bool finalize) {
88 reader_->finalize_ = finalize;
89 }
90
91 RawLibrary* BuildingTranslationHelper::LookupLibraryByDilLibrary(
92 Library* library) {
93 return reader_->LookupLibrary(library).raw();
94 }
95
96 RawClass* BuildingTranslationHelper::LookupClassByDilClass(Class* klass) {
97 return reader_->LookupClass(klass).raw();
98 }
99
100 Object& DilReader::ReadProgram() {
101 ASSERT(!bootstrapping_);
102 Program* program = ReadPrecompiledDilFromBuffer(buffer_, buffer_length_);
103 if (program == NULL) {
104 const dart::String& error = H.DartString("Failed to read .dill file");
105 return Object::Handle(Z, ApiError::New(error));
106 }
107
108 LongJumpScope jump;
109 if (setjmp(*jump.Set()) == 0) {
110 Procedure* main = program->main_method();
111 Library* dil_main_library = Library::Cast(main->parent());
112
113 intptr_t length = program->libraries().length();
114 for (intptr_t i = 0; i < length; i++) {
115 Library* dil_library = program->libraries()[i];
116 ReadLibrary(dil_library);
117 }
118
119 // We finalize classes after we've constructed all classes since we
120 // currently don't construct them in pre-order of the class hierarchy (and
121 // finalization of a class needs all of its superclasses to be finalized).
122 dart::String& name = dart::String::Handle();
123 for (intptr_t i = 0; i < length; i++) {
124 Library* dil_library = program->libraries()[i];
125 dart::Library& library = LookupLibrary(dil_library);
126 name = library.url();
127
128 // TODO(vegorov) unskip this library when we fix underlying issue.
129 if (name.Equals("dart:vmservice_io")) {
130 continue;
131 }
132
133 if (!library.Loaded()) {
134 dart::Class& klass = dart::Class::Handle(Z);
135 for (intptr_t i = 0; i < dil_library->classes().length(); i++) {
136 klass = LookupClass(dil_library->classes()[i]).raw();
137 ClassFinalizer::FinalizeTypesInClass(klass);
138 ClassFinalizer::FinalizeClass(klass);
139 }
140 library.SetLoaded();
141 }
142 }
143
144 dart::Library& library = LookupLibrary(dil_main_library);
145
146 // Sanity check that we can find the main entrypoint.
147 Object& main_obj = Object::Handle(
148 Z, library.LookupObjectAllowPrivate(H.DartSymbol("main")));
149 ASSERT(!main_obj.IsNull());
150 return library;
151 } else {
152 // Everything else is a compile-time error. We don't use the [error] since
153 // it sometimes causes the higher-level error handling to try to read the
154 // script and token position (which we don't have) to produce a nice error
155 // message.
156 Error& error = Error::Handle(Z);
157 error = thread_->sticky_error();
158 thread_->clear_sticky_error();
159
160 // Instead we simply make a non-informative error message.
161 const dart::String& error_message =
162 H.DartString("Failed to read .dill file => CompileTimeError.");
163 return Object::Handle(Z, LanguageError::New(error_message));
164 }
165 }
166
167 void DilReader::ReadLibrary(Library* dil_library) {
168 dart::Library& library = LookupLibrary(dil_library);
169 if (library.Loaded()) return;
170
171 // The bootstrapper will take care of creating the native wrapper classes, but
172 // we will add the synthetic constructors to them here.
173 if (library.name() ==
174 Symbols::Symbol(Symbols::kDartNativeWrappersLibNameId).raw()) {
175 ASSERT(library.LoadInProgress());
176 } else {
177 library.SetLoadInProgress();
178 }
179 // Setup toplevel class (which contains library fields/procedures).
180
181 // FIXME(kustermann): Figure out why we need this script stuff here.
182 Script& script = Script::Handle(
183 Z,
184 Script::New(H.DartString(""), H.DartString(""), RawScript::kScriptTag));
185 script.SetLocationOffset(0, 0);
186 script.Tokenize(H.DartString("nop() {}"));
187 dart::Class& toplevel_class = dart::Class::Handle(dart::Class::New(
188 library, Symbols::TopLevel(), script, TokenPosition::kNoSource));
189 toplevel_class.set_is_cycle_free();
190 library.set_toplevel_class(toplevel_class);
191 if (bootstrapping_) {
192 GrowableObjectArray::Handle(I->object_store()->pending_classes())
193 .Add(toplevel_class, Heap::kOld);
194 }
195
196 ActiveClassScope active_class_scope(&active_class_, NULL, &toplevel_class);
197 // Load toplevel fields.
198 for (intptr_t i = 0; i < dil_library->fields().length(); i++) {
199 Field* dil_field = dil_library->fields()[i];
200
201 ActiveMemberScope active_member_scope(&active_class_, dil_field);
202 const dart::String& name = H.DartFieldName(dil_field->name());
203 dart::Field& field = dart::Field::Handle(
204 Z, dart::Field::NewTopLevel(name, dil_field->IsFinal(),
205 dil_field->IsConst(), toplevel_class,
206 TokenPosition::kNoSource));
207 field.set_dil_field(reinterpret_cast<intptr_t>(dil_field));
208 const AbstractType& type = T.TranslateType(dil_field->type());
209 field.SetFieldType(type);
210 field.set_has_initializer(dil_field->initializer() != NULL);
211 GenerateFieldAccessors(toplevel_class, field, dil_field);
212 toplevel_class.AddField(field);
213 library.AddObject(field, name);
214 }
215
216 // Load toplevel procedures.
217 for (intptr_t i = 0; i < dil_library->procedures().length(); i++) {
218 Procedure* dil_procedure = dil_library->procedures()[i];
219 ReadProcedure(library, toplevel_class, dil_procedure);
220 }
221
222 // Load all classes.
223 for (intptr_t i = 0; i < dil_library->classes().length(); i++) {
224 Class* dil_klass = dil_library->classes()[i];
225 ReadClass(library, dil_klass);
226 }
227 }
228
229 void DilReader::ReadPreliminaryClass(dart::Class* klass, Class* dil_klass) {
230 ActiveClassScope active_class_scope(&active_class_, dil_klass, klass);
231
232 // First setup the type parameters, so if any of the following code uses it
233 // (in a recursive way) we're fine.
234 TypeArguments& type_parameters =
235 TypeArguments::Handle(Z, TypeArguments::null());
236 intptr_t num_type_parameters = dil_klass->type_parameters().length();
237 if (num_type_parameters > 0) {
238 dart::TypeParameter& parameter = dart::TypeParameter::Handle(Z);
239 Type& null_bound = Type::Handle(Z, Type::null());
240
241 // Step a) Create array of [TypeParameter] objects (without bound).
242 type_parameters = TypeArguments::New(num_type_parameters);
243 for (intptr_t i = 0; i < num_type_parameters; i++) {
244 parameter = dart::TypeParameter::New(
245 *klass, Function::Handle(Z), i,
246 H.DartSymbol(dil_klass->type_parameters()[i]->name()), null_bound,
247 TokenPosition::kNoSource);
248 type_parameters.SetTypeAt(i, parameter);
249 }
250 klass->set_type_parameters(type_parameters);
251
252 // Step b) Fill in the bounds of all [TypeParameter]s.
253 for (intptr_t i = 0; i < num_type_parameters; i++) {
254 TypeParameter* dil_parameter = dil_klass->type_parameters()[i];
255 // There is no dynamic bound, only Object.
256 // TODO(kustermann): Should we fix this in the kernel IR generator?
257 if (dil_parameter->bound()->IsDynamicType()) {
258 parameter ^= type_parameters.TypeAt(i);
259 parameter.set_bound(Type::Handle(Z, I->object_store()->object_type()));
260 } else {
261 AbstractType& bound =
262 T.TranslateTypeWithoutFinalization(dil_parameter->bound());
263 if (bound.IsMalformedOrMalbounded()) {
264 bound = I->object_store()->object_type();
265 }
266
267 parameter ^= type_parameters.TypeAt(i);
268 parameter.set_bound(bound);
269 }
270 }
271 }
272
273 if (dil_klass->IsNormalClass()) {
274 NormalClass* dil_normal_class = NormalClass::Cast(dil_klass);
275
276 // Set super type. Some classes (e.g., Object) do not have one.
277 if (dil_normal_class->super_class() != NULL) {
278 AbstractType& super_type =
279 T.TranslateTypeWithoutFinalization(dil_normal_class->super_class());
280 if (super_type.IsMalformed()) H.ReportError("Malformed super type");
281 klass->set_super_type(super_type);
282 }
283 } else {
284 MixinClass* dil_mixin = MixinClass::Cast(dil_klass);
285
286 // Set super type.
287 AbstractType& super_type =
288 T.TranslateTypeWithoutFinalization(dil_mixin->first());
289 if (super_type.IsMalformed()) H.ReportError("Malformed super type.");
290 klass->set_super_type(super_type);
291
292 // Tell the rest of the system there is nothing to resolve.
293 super_type.SetIsResolved();
294
295 // Set mixin type.
296 AbstractType& mixin_type =
297 T.TranslateTypeWithoutFinalization(dil_mixin->second());
298 if (mixin_type.IsMalformed()) H.ReportError("Malformed mixin type.");
299 klass->set_mixin(Type::Cast(mixin_type));
300 }
301
302 // Build implemented interface types
303 intptr_t interface_count = dil_klass->implemented_classes().length();
304 const dart::Array& interfaces =
305 dart::Array::Handle(Z, dart::Array::New(interface_count));
306 dart::Class& interface_class = dart::Class::Handle(Z);
307 for (intptr_t i = 0; i < interface_count; i++) {
308 InterfaceType* dil_interface_type = dil_klass->implemented_classes()[i];
309 const AbstractType& type =
310 T.TranslateTypeWithoutFinalization(dil_interface_type);
311 if (type.IsMalformed()) H.ReportError("Malformed interface type.");
312 interfaces.SetAt(i, type);
313
314 // NOTE: Normally the DartVM keeps a list of pending classes and iterates
315 // through them later on using `ClassFinalizer::ProcessPendingClasses()`.
316 // This involes calling `ClassFinalizer::ResolveSuperTypeAndInterfaces()`
317 // which does a lot of error validation (e.g. cycle checks) which we don't
318 // need here. But we do need to do one thing which this resolving phase
319 // normally does for us: set the `is_implemented` boolean.
320
321 // TODO(kustermann): Maybe we can do this differently once we have
322 // "bootstrapping from dill"-support.
323 interface_class = type.type_class();
324 interface_class.set_is_implemented();
325 }
326 klass->set_interfaces(interfaces);
327 if (dil_klass->is_abstract()) klass->set_is_abstract();
328 klass->set_is_cycle_free();
329
330 // When bootstrapping we should not finalize types yet because they will be
331 // finalized when the object store's pending_classes list is drained by
332 // ClassFinalizer::ProcessPendingClasses. Even when not bootstrapping we are
333 // careful not to eagerly finalize types that may introduce a circularity
334 // (such as type arguments, interface types, field types, etc.).
335 if (finalize_) ClassFinalizer::FinalizeTypesInClass(*klass);
336 }
337
338 void DilReader::ReadClass(const dart::Library& library, Class* dil_klass) {
339 // This will trigger a call to [ReadPreliminaryClass] if not already done.
340 dart::Class& klass = LookupClass(dil_klass);
341
342 ActiveClassScope active_class_scope(&active_class_, dil_klass, &klass);
343
344 TokenPosition pos(0);
345
346 for (intptr_t i = 0; i < dil_klass->fields().length(); i++) {
347 Field* dil_field = dil_klass->fields()[i];
348 ActiveMemberScope active_member_scope(&active_class_, dil_field);
349
350 const dart::String& name = H.DartFieldName(dil_field->name());
351 // TODO(vegorov) check if this might have some ordering issues
352 // e.g. addressing types that are not loaded yet.
353 const AbstractType& type =
354 T.TranslateTypeWithoutFinalization(dil_field->type());
355 dart::Field& field = dart::Field::Handle(
356 Z, dart::Field::New(name, dil_field->IsStatic(),
357 // In the VM all const fields are implicitly final
358 // whereas in Kernel they are not final because they
359 // are not explicitly declared that way.
360 dil_field->IsFinal() || dil_field->IsConst(),
361 dil_field->IsConst(),
362 false, // is_reflectable
363 klass, type, pos));
364 field.set_dil_field(reinterpret_cast<intptr_t>(dil_field));
365 field.set_has_initializer(dil_field->initializer() != NULL);
366 GenerateFieldAccessors(klass, field, dil_field);
367 klass.AddField(field);
368 }
369
370 for (intptr_t i = 0; i < dil_klass->constructors().length(); i++) {
371 Constructor* dil_constructor = dil_klass->constructors()[i];
372 ActiveMemberScope active_member_scope(&active_class_, dil_constructor);
373 ActiveFunctionScope active_function_scope(&active_class_,
374 dil_constructor->function());
375
376 const dart::String& name = H.DartConstructorName(dil_constructor);
377 Function& function = dart::Function::ZoneHandle(
378 Z, dart::Function::New(name, RawFunction::kConstructor,
379 false, // is_static
380 dil_constructor->IsConst(),
381 false, // is_abstract
382 dil_constructor->IsExternal(),
383 false, // is_native
384 klass, pos));
385 klass.AddFunction(function);
386 function.set_dil_function(reinterpret_cast<intptr_t>(dil_constructor));
387 function.set_result_type(T.ReceiverType(klass));
388 SetupFunctionParameters(H, T, klass, function, dil_constructor->function(),
389 true, // is_method
390 false); // is_closure
391 }
392
393 for (intptr_t i = 0; i < dil_klass->procedures().length(); i++) {
394 Procedure* dil_procedure = dil_klass->procedures()[i];
395 ActiveMemberScope active_member_scope(&active_class_, dil_procedure);
396 ReadProcedure(library, klass, dil_procedure, dil_klass);
397 }
398
399 if (bootstrapping_ && !klass.is_marked_for_parsing()) {
400 klass.set_is_marked_for_parsing();
401 GrowableObjectArray::Handle(Z, I->object_store()->pending_classes())
402 .Add(klass, Heap::kOld);
403 }
404 }
405
406 void DilReader::ReadProcedure(const dart::Library& library,
407 const dart::Class& owner,
408 Procedure* dil_procedure, Class* dil_klass) {
409 ActiveClassScope active_class_scope(&active_class_, dil_klass, &owner);
410 ActiveMemberScope active_member_scope(&active_class_, dil_procedure);
411 ActiveFunctionScope active_function_scope(&active_class_,
412 dil_procedure->function());
413
414 const dart::String& name = H.DartProcedureName(dil_procedure);
415 TokenPosition pos(0);
416 bool is_method = dil_klass != NULL && !dil_procedure->IsStatic();
417 bool is_abstract = dil_procedure->IsAbstract();
418 bool is_external = dil_procedure->IsExternal();
419 dart::String* native_name = NULL;
420 if (is_external) {
421 // Maybe it has a native implementation, which is not external as far as
422 // the VM is concerned because it does have an implementation. Check for
423 // an ExternalName annotation and extract the string from it.
424 for (int i = 0; i < dil_procedure->annotations().length(); ++i) {
425 Expression* annotation = dil_procedure->annotations()[i];
426 if (!annotation->IsConstructorInvocation()) continue;
427 ConstructorInvocation* invocation =
428 ConstructorInvocation::Cast(annotation);
429 Class* annotation_class = Class::Cast(invocation->target()->parent());
430 String* class_name = annotation_class->name();
431 // Just compare by name, do not generate the annotation class.
432 int length = sizeof("ExternalName") - 1;
433 if (class_name->size() != length) continue;
434 if (memcmp(class_name->buffer(), "ExternalName", length) != 0) continue;
435 String* library_name = annotation_class->parent()->name();
436 length = sizeof("dart._internal") - 1;
437 if (library_name->size() != length) continue;
438 if (memcmp(library_name->buffer(), "dart._internal", length) != 0) {
439 continue;
440 }
441
442 is_external = false;
443 ASSERT(invocation->arguments()->positional().length() == 1 &&
444 invocation->arguments()->named().length() == 0);
445 StringLiteral* literal =
446 StringLiteral::Cast(invocation->arguments()->positional()[0]);
447 native_name = &H.DartSymbol(literal->value());
448 break;
449 }
450 }
451 dart::Function& function = dart::Function::ZoneHandle(
452 Z, Function::New(name, GetFunctionType(dil_procedure),
453 !is_method, // is_static
454 false, // is_const
455 is_abstract, is_external,
456 native_name != NULL, // is_native
457 owner, pos));
458 owner.AddFunction(function);
459 function.set_dil_function(reinterpret_cast<intptr_t>(dil_procedure));
460 function.set_is_debuggable(false);
461 if (native_name != NULL) {
462 function.set_native_name(*native_name);
463 }
464
465 SetupFunctionParameters(H, T, owner, function, dil_procedure->function(),
466 is_method,
467 false); // is_closure
468
469 if (dil_klass == NULL) {
470 library.AddObject(function, name);
471 ASSERT(!Object::Handle(library.LookupObjectAllowPrivate(
472 H.DartProcedureName(dil_procedure)))
473 .IsNull());
474 }
475 }
476
477 void DilReader::GenerateFieldAccessors(const dart::Class& klass,
478 const dart::Field& field,
479 Field* dil_field) {
480 TokenPosition pos(0);
481
482 if (dil_field->IsStatic() && dil_field->initializer() != NULL) {
483 // Static fields with initializers either have the static value set to the
484 // initializer value if it is simple enough or else set to an uninitialized
485 // sentinel.
486 SimpleExpressionConverter converter(H.thread(), Z);
487 if (converter.IsSimple(dil_field->initializer())) {
488 // We do not need a getter.
489 field.SetStaticValue(converter.SimpleValue(), true);
490 return;
491 }
492 // We do need a getter that evaluates the initializer if necessary.
493 field.SetStaticValue(Object::sentinel(), true);
494 }
495
496 const dart::String& getter_name = H.DartGetterName(dil_field->name());
497 Function& getter = Function::ZoneHandle(
498 Z,
499 Function::New(
500 getter_name,
501 dil_field->IsStatic() ? RawFunction::kImplicitStaticFinalGetter
502 : RawFunction::kImplicitGetter,
503 dil_field->IsStatic(),
504 // The functions created by the parser have is_const for static fields
505 // that are const (not just final) and they have is_const for
506 // non-static
507 // fields that are final.
508 dil_field->IsStatic() ? dil_field->IsConst() : dil_field->IsFinal(),
509 false, // is_abstract
510 false, // is_external
511 false, // is_native
512 klass, pos));
513 klass.AddFunction(getter);
514 if (klass.IsTopLevel()) {
515 dart::Library& library = dart::Library::Handle(Z, klass.library());
516 library.AddObject(getter, getter_name);
517 }
518 getter.set_dil_function(reinterpret_cast<intptr_t>(dil_field));
519 getter.set_result_type(AbstractType::Handle(Z, field.type()));
520 getter.set_is_debuggable(false);
521 SetupFieldAccessorFunction(klass, getter);
522
523 if (!dil_field->IsStatic() && !dil_field->IsFinal()) {
524 // Only static fields can be const.
525 ASSERT(!dil_field->IsConst());
526 const dart::String& setter_name = H.DartSetterName(dil_field->name());
527 Function& setter = Function::ZoneHandle(
528 Z, Function::New(setter_name, RawFunction::kImplicitSetter,
529 false, // is_static
530 false, // is_const
531 false, // is_abstract
532 false, // is_external
533 false, // is_native
534 klass, pos));
535 klass.AddFunction(setter);
536 setter.set_dil_function(reinterpret_cast<intptr_t>(dil_field));
537 setter.set_result_type(Object::void_type());
538 setter.set_is_debuggable(false);
539 SetupFieldAccessorFunction(klass, setter);
540 }
541 }
542
543 void DilReader::SetupFunctionParameters(TranslationHelper translation_helper_,
544 DartTypeTranslator type_translator_,
545 const dart::Class& klass,
546 const dart::Function& function,
547 FunctionNode* node, bool is_method,
548 bool is_closure) {
549 ASSERT(!(is_method && is_closure));
550 bool is_factory = function.IsFactory();
551 intptr_t extra_parameters = (is_method || is_closure || is_factory) ? 1 : 0;
552
553 function.set_num_fixed_parameters(extra_parameters +
554 node->required_parameter_count());
555 if (node->named_parameters().length() > 0) {
556 function.SetNumOptionalParameters(node->named_parameters().length(), false);
557 } else {
558 function.SetNumOptionalParameters(node->positional_parameters().length() -
559 node->required_parameter_count(),
560 true);
561 }
562 intptr_t num_parameters = extra_parameters +
563 node->positional_parameters().length() +
564 node->named_parameters().length();
565 function.set_parameter_types(
566 Array::Handle(Array::New(num_parameters, Heap::kOld)));
567 function.set_parameter_names(
568 Array::Handle(Array::New(num_parameters, Heap::kOld)));
569 intptr_t pos = 0;
570 if (is_method) {
571 ASSERT(!klass.IsNull());
572 function.SetParameterTypeAt(pos, H.GetCanonicalType(klass));
573 function.SetParameterNameAt(pos, Symbols::This());
574 pos++;
575 } else if (is_closure) {
576 function.SetParameterTypeAt(pos, AbstractType::dynamic_type());
577 function.SetParameterNameAt(pos, Symbols::ClosureParameter());
578 pos++;
579 } else if (is_factory) {
580 function.SetParameterTypeAt(pos, AbstractType::dynamic_type());
581 function.SetParameterNameAt(pos, Symbols::TypeArgumentsParameter());
582 pos++;
583 }
584 for (intptr_t i = 0; i < node->positional_parameters().length(); i++, pos++) {
585 VariableDeclaration* dil_variable = node->positional_parameters()[i];
586 const AbstractType& type = T.TranslateType(dil_variable->type());
587 function.SetParameterTypeAt(
588 pos, type.IsMalformed() ? Type::dynamic_type() : type);
589 function.SetParameterNameAt(pos, H.DartSymbol(dil_variable->name()));
590 }
591 for (intptr_t i = 0; i < node->named_parameters().length(); i++, pos++) {
592 VariableDeclaration* named_expression = node->named_parameters()[i];
593 const AbstractType& type = T.TranslateType(named_expression->type());
594 function.SetParameterTypeAt(
595 pos, type.IsMalformed() ? Type::dynamic_type() : type);
596 function.SetParameterNameAt(pos, H.DartSymbol(named_expression->name()));
597 }
598
599 const AbstractType& return_type = T.TranslateType(node->return_type());
600 function.set_result_type(return_type.IsMalformed() ? Type::dynamic_type()
601 : return_type);
602 }
603
604 void DilReader::SetupFieldAccessorFunction(const dart::Class& klass,
605 const dart::Function& function) {
606 bool is_setter = function.IsImplicitSetterFunction();
607 bool is_method = !function.IsStaticFunction();
608 intptr_t num_parameters = (is_method ? 1 : 0) + (is_setter ? 1 : 0);
609
610 function.SetNumOptionalParameters(0, false);
611 function.set_num_fixed_parameters(num_parameters);
612 function.set_parameter_types(
613 Array::Handle(Array::New(num_parameters, Heap::kOld)));
614 function.set_parameter_names(
615 Array::Handle(Array::New(num_parameters, Heap::kOld)));
616
617 intptr_t pos = 0;
618 if (is_method) {
619 function.SetParameterTypeAt(pos, T.ReceiverType(klass));
620 function.SetParameterNameAt(pos, Symbols::This());
621 pos++;
622 }
623 if (is_setter) {
624 function.SetParameterTypeAt(pos, AbstractType::dynamic_type());
625 function.SetParameterNameAt(pos, Symbols::Value());
626 pos++;
627 }
628 }
629
630 dart::Library& DilReader::LookupLibrary(Library* library) {
631 dart::Library* handle = NULL;
632 if (!libraries_.Lookup(library, &handle)) {
633 const dart::String& url = H.DartSymbol(library->import_uri());
634 handle =
635 &dart::Library::Handle(Z, dart::Library::LookupLibrary(thread_, url));
636 if (handle->IsNull()) {
637 *handle = dart::Library::New(url);
638 handle->Register(thread_);
639 }
640 ASSERT(!handle->IsNull());
641 libraries_.Insert(library, handle);
642 }
643 return *handle;
644 }
645
646 dart::Class& DilReader::LookupClass(Class* klass) {
647 dart::Class* handle = NULL;
648 if (!classes_.Lookup(klass, &handle)) {
649 dart::Library& library = LookupLibrary(klass->parent());
650 const dart::String& name = H.DartClassName(klass);
651 handle = &dart::Class::Handle(Z, library.LookupClass(name));
652 if (handle->IsNull()) {
653 // The class needs to have a script because all the functions in the class
654 // will inherit it. The predicate Function::IsOptimizable uses the
655 // absence of a script to detect test functions that should not be
656 // optimized. Use a dummy script.
657 //
658 // TODO(kmillikin): We shouldn't need a dummy script per class. At the
659 // least we could have a singleton. At best, we'd change IsOptimizable to
660 // detect test functions some other way (like simply not setting the
661 // optimizable bit on those functions in the first place).
662 TokenPosition pos(0);
663 Script& script =
664 Script::Handle(Z, Script::New(H.DartString(""), H.DartString(""),
665 RawScript::kScriptTag));
666 handle =
667 &dart::Class::Handle(Z, dart::Class::New(library, name, script, pos));
668 library.AddClass(*handle);
669 } else if (handle->script() == Script::null()) {
670 // When bootstrapping we can encounter classes that do not yet have a
671 // dummy script.
672 TokenPosition pos(0);
673 Script& script =
674 Script::Handle(Z, Script::New(H.DartString(""), H.DartString(""),
675 RawScript::kScriptTag));
676 handle->set_script(script);
677 }
678 // Insert the class in the cache before calling ReadPreliminaryClass so
679 // we do not risk allocating the class again by calling LookupClass
680 // recursively from ReadPreliminaryClass for the same class.
681 classes_.Insert(klass, handle);
682 if (!handle->is_type_finalized()) {
683 ReadPreliminaryClass(handle, klass);
684 }
685 }
686 return *handle;
687 }
688
689 RawFunction::Kind DilReader::GetFunctionType(Procedure* dil_procedure) {
690 // TODO(kustermann): Are these correct?
691 intptr_t lookuptable[] = {
692 RawFunction::kRegularFunction, // Procedure::kMethod
693 RawFunction::kGetterFunction, // Procedure::kGetter
694 RawFunction::kSetterFunction, // Procedure::kSetter
695 RawFunction::kRegularFunction, // Procedure::kOperator
696 RawFunction::kConstructor, // Procedure::kFactory
697 };
698 intptr_t kind = static_cast<int>(dil_procedure->kind());
699 if (kind == Procedure::kIncompleteProcedure) {
700 // TODO(kustermann): Is this correct?
701 return RawFunction::kSignatureFunction;
702 } else {
703 ASSERT(0 <= kind && kind <= Procedure::kFactory);
704 return static_cast<RawFunction::Kind>(lookuptable[kind]);
705 }
706 }
707
708 } // namespace dil
709 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698