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

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

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

Powered by Google App Engine
This is Rietveld 408576698