1// Copyright (c) 2018, 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/compiler/frontend/bytecode_reader.h"
6
7#include "vm/bit_vector.h"
8#include "vm/bootstrap.h"
9#include "vm/class_finalizer.h"
10#include "vm/code_descriptors.h"
11#include "vm/compiler/aot/precompiler.h" // For Obfuscator
12#include "vm/compiler/assembler/disassembler_kbc.h"
13#include "vm/compiler/frontend/bytecode_scope_builder.h"
14#include "vm/constants_kbc.h"
15#include "vm/dart_api_impl.h" // For Api::IsFfiEnabled().
16#include "vm/dart_entry.h"
17#include "vm/debugger.h"
18#include "vm/flags.h"
19#include "vm/hash.h"
20#include "vm/longjump.h"
21#include "vm/object_store.h"
22#include "vm/reusable_handles.h"
23#include "vm/scopes.h"
24#include "vm/stack_frame_kbc.h"
25#include "vm/timeline.h"
26
27#define Z (zone_)
28#define H (translation_helper_)
29#define I (translation_helper_.isolate())
30
31namespace dart {
32
33DEFINE_FLAG(bool, dump_kernel_bytecode, false, "Dump kernel bytecode");
34
35namespace kernel {
36
37BytecodeMetadataHelper::BytecodeMetadataHelper(KernelReaderHelper* helper,
38 ActiveClass* active_class)
39 : MetadataHelper(helper, tag(), /* precompiler_only = */ false),
40 active_class_(active_class) {}
41
42void BytecodeMetadataHelper::ParseBytecodeFunction(
43 ParsedFunction* parsed_function) {
44 TIMELINE_DURATION(Thread::Current(), CompilerVerbose,
45 "BytecodeMetadataHelper::ParseBytecodeFunction");
46
47 const Function& function = parsed_function->function();
48 ASSERT(function.is_declared_in_bytecode());
49
50 BytecodeComponentData bytecode_component(
51 &Array::Handle(helper_->zone_, GetBytecodeComponent()));
52 BytecodeReaderHelper bytecode_reader(&H, active_class_, &bytecode_component);
53
54 bytecode_reader.ParseBytecodeFunction(parsed_function, function);
55}
56
57bool BytecodeMetadataHelper::ReadLibraries() {
58 TIMELINE_DURATION(Thread::Current(), Compiler,
59 "BytecodeMetadataHelper::ReadLibraries");
60 ASSERT(Thread::Current()->IsMutatorThread());
61
62 if (translation_helper_.GetBytecodeComponent() == Array::null()) {
63 return false;
64 }
65
66 BytecodeComponentData bytecode_component(
67 &Array::Handle(helper_->zone_, GetBytecodeComponent()));
68
69 BytecodeReaderHelper bytecode_reader(&H, active_class_, &bytecode_component);
70 AlternativeReadingScope alt(&bytecode_reader.reader(),
71 bytecode_component.GetLibraryIndexOffset());
72 bytecode_reader.ReadLibraryDeclarations(bytecode_component.GetNumLibraries());
73 return true;
74}
75
76void BytecodeMetadataHelper::ReadLibrary(const Library& library) {
77 TIMELINE_DURATION(Thread::Current(), Compiler,
78 "BytecodeMetadataHelper::ReadLibrary");
79 ASSERT(Thread::Current()->IsMutatorThread());
80 ASSERT(!library.Loaded());
81
82 if (translation_helper_.GetBytecodeComponent() == Array::null()) {
83 return;
84 }
85
86 BytecodeComponentData bytecode_component(
87 &Array::Handle(helper_->zone_, GetBytecodeComponent()));
88 BytecodeReaderHelper bytecode_reader(&H, active_class_, &bytecode_component);
89 AlternativeReadingScope alt(&bytecode_reader.reader(),
90 bytecode_component.GetLibraryIndexOffset());
91 bytecode_reader.FindAndReadSpecificLibrary(
92 library, bytecode_component.GetNumLibraries());
93}
94
95bool BytecodeMetadataHelper::FindModifiedLibrariesForHotReload(
96 BitVector* modified_libs,
97 bool* is_empty_program,
98 intptr_t* p_num_classes,
99 intptr_t* p_num_procedures) {
100 ASSERT(Thread::Current()->IsMutatorThread());
101
102 if (translation_helper_.GetBytecodeComponent() == Array::null()) {
103 return false;
104 }
105
106 BytecodeComponentData bytecode_component(
107 &Array::Handle(helper_->zone_, GetBytecodeComponent()));
108 BytecodeReaderHelper bytecode_reader(&H, active_class_, &bytecode_component);
109 AlternativeReadingScope alt(&bytecode_reader.reader(),
110 bytecode_component.GetLibraryIndexOffset());
111 bytecode_reader.FindModifiedLibrariesForHotReload(
112 modified_libs, bytecode_component.GetNumLibraries());
113
114 if (is_empty_program != nullptr) {
115 *is_empty_program = (bytecode_component.GetNumLibraries() == 0);
116 }
117 if (p_num_classes != nullptr) {
118 *p_num_classes = bytecode_component.GetNumClasses();
119 }
120 if (p_num_procedures != nullptr) {
121 *p_num_procedures = bytecode_component.GetNumCodes();
122 }
123 return true;
124}
125
126LibraryPtr BytecodeMetadataHelper::GetMainLibrary() {
127 const intptr_t md_offset = GetComponentMetadataPayloadOffset();
128 if (md_offset < 0) {
129 return Library::null();
130 }
131
132 BytecodeComponentData bytecode_component(
133 &Array::Handle(helper_->zone_, GetBytecodeComponent()));
134 const intptr_t main_offset = bytecode_component.GetMainOffset();
135 if (main_offset == 0) {
136 return Library::null();
137 }
138
139 BytecodeReaderHelper bytecode_reader(&H, active_class_, &bytecode_component);
140 AlternativeReadingScope alt(&bytecode_reader.reader(), main_offset);
141 return bytecode_reader.ReadMain();
142}
143
144ArrayPtr BytecodeMetadataHelper::GetBytecodeComponent() {
145 ArrayPtr array = translation_helper_.GetBytecodeComponent();
146 if (array == Array::null()) {
147 array = ReadBytecodeComponent();
148 ASSERT(array != Array::null());
149 }
150 return array;
151}
152
153ArrayPtr BytecodeMetadataHelper::ReadBytecodeComponent() {
154 const intptr_t md_offset = GetComponentMetadataPayloadOffset();
155 if (md_offset < 0) {
156 return Array::null();
157 }
158
159 BytecodeReaderHelper component_reader(&H, nullptr, nullptr);
160 return component_reader.ReadBytecodeComponent(md_offset);
161}
162
163BytecodeReaderHelper::BytecodeReaderHelper(
164 TranslationHelper* translation_helper,
165 ActiveClass* active_class,
166 BytecodeComponentData* bytecode_component)
167 : reader_(translation_helper->metadata_payloads()),
168 translation_helper_(*translation_helper),
169 active_class_(active_class),
170 thread_(translation_helper->thread()),
171 zone_(translation_helper->zone()),
172 bytecode_component_(bytecode_component),
173 scoped_function_(Function::Handle(translation_helper->zone())),
174 scoped_function_name_(String::Handle(translation_helper->zone())),
175 scoped_function_class_(Class::Handle(translation_helper->zone())) {}
176
177void BytecodeReaderHelper::ReadCode(const Function& function,
178 intptr_t code_offset) {
179 ASSERT(Thread::Current()->IsMutatorThread());
180 ASSERT(!function.IsImplicitGetterFunction() &&
181 !function.IsImplicitSetterFunction());
182 if (code_offset == 0) {
183 FATAL2("Function %s (kind %s) doesn't have bytecode",
184 function.ToFullyQualifiedCString(),
185 Function::KindToCString(function.kind()));
186 }
187
188 AlternativeReadingScope alt(&reader_, code_offset);
189 // This scope is needed to set active_class_->enclosing_ which is used to
190 // assign parent function for function types.
191 ActiveEnclosingFunctionScope active_enclosing_function(active_class_,
192 &function);
193
194 const intptr_t flags = reader_.ReadUInt();
195 const bool has_exceptions_table =
196 (flags & Code::kHasExceptionsTableFlag) != 0;
197 const bool has_source_positions =
198 (flags & Code::kHasSourcePositionsFlag) != 0;
199 const bool has_local_variables = (flags & Code::kHasLocalVariablesFlag) != 0;
200 const bool has_nullable_fields = (flags & Code::kHasNullableFieldsFlag) != 0;
201 const bool has_closures = (flags & Code::kHasClosuresFlag) != 0;
202 const bool has_parameters_flags = (flags & Code::kHasParameterFlagsFlag) != 0;
203 const bool has_forwarding_stub_target =
204 (flags & Code::kHasForwardingStubTargetFlag) != 0;
205 const bool has_default_function_type_args =
206 (flags & Code::kHasDefaultFunctionTypeArgsFlag) != 0;
207
208 if (has_parameters_flags) {
209 intptr_t num_params = reader_.ReadUInt();
210 ASSERT(num_params ==
211 function.NumParameters() - function.NumImplicitParameters());
212 for (intptr_t i = function.NumImplicitParameters();
213 i < function.NumParameters(); ++i) {
214 const intptr_t flags = reader_.ReadUInt();
215 if ((flags & Parameter::kIsRequiredFlag) != 0) {
216 RELEASE_ASSERT(i >= function.num_fixed_parameters());
217 function.SetIsRequiredAt(i);
218 }
219 }
220 }
221 function.TruncateUnusedParameterFlags();
222 if (has_forwarding_stub_target) {
223 reader_.ReadUInt();
224 }
225 if (has_default_function_type_args) {
226 reader_.ReadUInt();
227 }
228
229 intptr_t num_closures = 0;
230 if (has_closures) {
231 num_closures = reader_.ReadListLength();
232 closures_ = &Array::Handle(Z, Array::New(num_closures));
233 for (intptr_t i = 0; i < num_closures; i++) {
234 ReadClosureDeclaration(function, i);
235 }
236 }
237
238 // Create object pool and read pool entries.
239 const intptr_t obj_count = reader_.ReadListLength();
240 const ObjectPool& pool = ObjectPool::Handle(Z, ObjectPool::New(obj_count));
241 ReadConstantPool(function, pool, 0);
242
243 // Read bytecode and attach to function.
244 const Bytecode& bytecode = Bytecode::Handle(Z, ReadBytecode(pool));
245 function.AttachBytecode(bytecode);
246 ASSERT(bytecode.GetBinary(Z) == reader_.typed_data()->raw());
247
248 ReadExceptionsTable(bytecode, has_exceptions_table);
249
250 ReadSourcePositions(bytecode, has_source_positions);
251
252 ReadLocalVariables(bytecode, has_local_variables);
253
254 if (FLAG_dump_kernel_bytecode) {
255 KernelBytecodeDisassembler::Disassemble(function);
256 }
257
258 // Initialization of fields with null literal is elided from bytecode.
259 // Record the corresponding stores if field guards are enabled.
260 if (has_nullable_fields) {
261 ASSERT(function.IsGenerativeConstructor());
262 const intptr_t num_fields = reader_.ReadListLength();
263 if (I->use_field_guards()) {
264 Field& field = Field::Handle(Z);
265 for (intptr_t i = 0; i < num_fields; i++) {
266 field ^= ReadObject();
267 field.RecordStore(Object::null_object());
268 }
269 } else {
270 for (intptr_t i = 0; i < num_fields; i++) {
271 ReadObject();
272 }
273 }
274 }
275
276 // Read closures.
277 if (has_closures) {
278 Function& closure = Function::Handle(Z);
279 Bytecode& closure_bytecode = Bytecode::Handle(Z);
280 for (intptr_t i = 0; i < num_closures; i++) {
281 closure ^= closures_->At(i);
282
283 const intptr_t flags = reader_.ReadUInt();
284 const bool has_exceptions_table =
285 (flags & ClosureCode::kHasExceptionsTableFlag) != 0;
286 const bool has_source_positions =
287 (flags & ClosureCode::kHasSourcePositionsFlag) != 0;
288 const bool has_local_variables =
289 (flags & ClosureCode::kHasLocalVariablesFlag) != 0;
290
291 // Read closure bytecode and attach to closure function.
292 closure_bytecode = ReadBytecode(pool);
293 closure.AttachBytecode(closure_bytecode);
294 ASSERT(bytecode.GetBinary(Z) == reader_.typed_data()->raw());
295
296 ReadExceptionsTable(closure_bytecode, has_exceptions_table);
297
298 ReadSourcePositions(closure_bytecode, has_source_positions);
299
300 ReadLocalVariables(closure_bytecode, has_local_variables);
301
302 if (FLAG_dump_kernel_bytecode) {
303 KernelBytecodeDisassembler::Disassemble(closure);
304 }
305
306#if !defined(PRODUCT)
307 thread_->isolate()->debugger()->NotifyBytecodeLoaded(closure);
308#endif
309 }
310 }
311
312#if !defined(PRODUCT)
313 thread_->isolate()->debugger()->NotifyBytecodeLoaded(function);
314#endif
315}
316
317static intptr_t IndexFor(Zone* zone,
318 const Function& function,
319 const String& name) {
320 const Bytecode& bc = Bytecode::Handle(zone, function.bytecode());
321 const ObjectPool& pool = ObjectPool::Handle(zone, bc.object_pool());
322 const KBCInstr* pc = reinterpret_cast<const KBCInstr*>(bc.PayloadStart());
323
324 ASSERT(KernelBytecode::IsEntryOptionalOpcode(pc));
325 ASSERT(KernelBytecode::DecodeB(pc) ==
326 function.NumOptionalPositionalParameters());
327 ASSERT(KernelBytecode::DecodeC(pc) == function.NumOptionalNamedParameters());
328 pc = KernelBytecode::Next(pc);
329
330 const intptr_t num_opt_params = function.NumOptionalParameters();
331 const intptr_t num_fixed_params = function.num_fixed_parameters();
332 for (intptr_t i = 0; i < num_opt_params; i++) {
333 const KBCInstr* load_name = pc;
334 const KBCInstr* load_value = KernelBytecode::Next(load_name);
335 pc = KernelBytecode::Next(load_value);
336 ASSERT(KernelBytecode::IsLoadConstantOpcode(load_name));
337 ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value));
338 if (pool.ObjectAt(KernelBytecode::DecodeE(load_name)) == name.raw()) {
339 return num_fixed_params + i;
340 }
341 }
342
343 UNREACHABLE();
344 return -1;
345}
346
347ArrayPtr BytecodeReaderHelper::CreateForwarderChecks(const Function& function) {
348 ASSERT(function.kind() != FunctionLayout::kDynamicInvocationForwarder);
349 ASSERT(function.is_declared_in_bytecode());
350
351 TypeArguments& default_args = TypeArguments::Handle(Z);
352 if (function.bytecode_offset() != 0) {
353 AlternativeReadingScope alt(&reader_, function.bytecode_offset());
354
355 const intptr_t flags = reader_.ReadUInt();
356 const bool has_parameters_flags =
357 (flags & Code::kHasParameterFlagsFlag) != 0;
358 const bool has_forwarding_stub_target =
359 (flags & Code::kHasForwardingStubTargetFlag) != 0;
360 const bool has_default_function_type_args =
361 (flags & Code::kHasDefaultFunctionTypeArgsFlag) != 0;
362
363 if (has_parameters_flags) {
364 intptr_t num_params = reader_.ReadUInt();
365 ASSERT(num_params ==
366 function.NumParameters() - function.NumImplicitParameters());
367 for (intptr_t i = 0; i < num_params; ++i) {
368 reader_.ReadUInt();
369 }
370 }
371
372 if (has_forwarding_stub_target) {
373 reader_.ReadUInt();
374 }
375
376 if (has_default_function_type_args) {
377 const intptr_t index = reader_.ReadUInt();
378 const Bytecode& code = Bytecode::Handle(Z, function.bytecode());
379 const ObjectPool& pool = ObjectPool::Handle(Z, code.object_pool());
380 default_args ^= pool.ObjectAt(index);
381 }
382 }
383
384 auto& name = String::Handle(Z);
385 auto& check = ParameterTypeCheck::Handle(Z);
386 auto& checks = GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
387
388 checks.Add(function);
389 checks.Add(default_args);
390
391 const auto& type_params =
392 TypeArguments::Handle(Z, function.type_parameters());
393 if (!type_params.IsNull()) {
394 auto& type_param = TypeParameter::Handle(Z);
395 auto& bound = AbstractType::Handle(Z);
396 for (intptr_t i = 0, n = type_params.Length(); i < n; ++i) {
397 type_param ^= type_params.TypeAt(i);
398 bound = type_param.bound();
399 if (!bound.IsTopTypeForSubtyping() &&
400 !type_param.IsGenericCovariantImpl()) {
401 name = type_param.name();
402 ASSERT(type_param.IsFinalized());
403 check = ParameterTypeCheck::New();
404 check.set_param(type_param);
405 check.set_type_or_bound(bound);
406 check.set_name(name);
407 checks.Add(check);
408 }
409 }
410 }
411
412 const intptr_t num_params = function.NumParameters();
413 const intptr_t num_pos_params = function.HasOptionalNamedParameters()
414 ? function.num_fixed_parameters()
415 : num_params;
416
417 BitVector is_covariant(Z, num_params);
418 BitVector is_generic_covariant_impl(Z, num_params);
419 ReadParameterCovariance(function, &is_covariant, &is_generic_covariant_impl);
420
421 auto& type = AbstractType::Handle(Z);
422 auto& cache = SubtypeTestCache::Handle(Z);
423 const bool has_optional_parameters = function.HasOptionalParameters();
424 for (intptr_t i = function.NumImplicitParameters(); i < num_params; ++i) {
425 type = function.ParameterTypeAt(i);
426 if (!type.IsTopTypeForSubtyping() &&
427 !is_generic_covariant_impl.Contains(i) && !is_covariant.Contains(i)) {
428 name = function.ParameterNameAt(i);
429 intptr_t index;
430 if (i >= num_pos_params) {
431 // Named parameter.
432 index = IndexFor(Z, function, name);
433 } else if (has_optional_parameters) {
434 // Fixed or optional parameter.
435 index = i;
436 } else {
437 // Fixed parameter.
438 index = -kKBCParamEndSlotFromFp - num_params + i;
439 }
440 check = ParameterTypeCheck::New();
441 check.set_index(index);
442 check.set_type_or_bound(type);
443 check.set_name(name);
444 cache = SubtypeTestCache::New();
445 check.set_cache(cache);
446 checks.Add(check);
447 }
448 }
449
450 return Array::MakeFixedLength(checks);
451}
452
453void BytecodeReaderHelper::ReadClosureDeclaration(const Function& function,
454 intptr_t closureIndex) {
455 // Closure flags, must be in sync with ClosureDeclaration constants in
456 // pkg/vm/lib/bytecode/declarations.dart.
457 const int kHasOptionalPositionalParamsFlag = 1 << 0;
458 const int kHasOptionalNamedParamsFlag = 1 << 1;
459 const int kHasTypeParamsFlag = 1 << 2;
460 const int kHasSourcePositionsFlag = 1 << 3;
461 const int kIsAsyncFlag = 1 << 4;
462 const int kIsAsyncStarFlag = 1 << 5;
463 const int kIsSyncStarFlag = 1 << 6;
464 const int kIsDebuggableFlag = 1 << 7;
465 const int kHasAttributesFlag = 1 << 8;
466 const int kHasParameterFlagsFlag = 1 << 9;
467
468 const intptr_t flags = reader_.ReadUInt();
469
470 Object& parent = Object::Handle(Z, ReadObject());
471 if (!parent.IsFunction()) {
472 ASSERT(parent.IsField());
473 ASSERT(function.kind() == FunctionLayout::kFieldInitializer);
474 // Closure in a static field initializer, so use current function as parent.
475 parent = function.raw();
476 }
477
478 String& name = String::CheckedHandle(Z, ReadObject());
479 ASSERT(name.IsSymbol());
480
481 TokenPosition position = TokenPosition::kNoSource;
482 TokenPosition end_position = TokenPosition::kNoSource;
483 if ((flags & kHasSourcePositionsFlag) != 0) {
484 position = reader_.ReadPosition();
485 end_position = reader_.ReadPosition();
486 }
487
488 const Function& closure = Function::Handle(
489 Z, Function::NewClosureFunction(name, Function::Cast(parent), position));
490
491 closure.set_is_declared_in_bytecode(true);
492 closure.set_end_token_pos(end_position);
493
494 if ((flags & kIsSyncStarFlag) != 0) {
495 closure.set_modifier(FunctionLayout::kSyncGen);
496 } else if ((flags & kIsAsyncFlag) != 0) {
497 closure.set_modifier(FunctionLayout::kAsync);
498 closure.set_is_inlinable(!FLAG_causal_async_stacks &&
499 !FLAG_lazy_async_stacks);
500 } else if ((flags & kIsAsyncStarFlag) != 0) {
501 closure.set_modifier(FunctionLayout::kAsyncGen);
502 closure.set_is_inlinable(!FLAG_causal_async_stacks &&
503 !FLAG_lazy_async_stacks);
504 }
505 if (Function::Cast(parent).IsAsyncOrGenerator()) {
506 closure.set_is_generated_body(true);
507 }
508 closure.set_is_debuggable((flags & kIsDebuggableFlag) != 0);
509
510 closures_->SetAt(closureIndex, closure);
511
512 Type& signature_type = Type::Handle(
513 Z, ReadFunctionSignature(
514 closure, (flags & kHasOptionalPositionalParamsFlag) != 0,
515 (flags & kHasOptionalNamedParamsFlag) != 0,
516 (flags & kHasTypeParamsFlag) != 0,
517 /* has_positional_param_names = */ true,
518 (flags & kHasParameterFlagsFlag) != 0, Nullability::kNonNullable));
519
520 closure.SetSignatureType(signature_type);
521
522 if ((flags & kHasAttributesFlag) != 0) {
523 ReadAttributes(closure);
524 }
525
526 I->AddClosureFunction(closure);
527}
528
529static bool IsNonCanonical(const AbstractType& type) {
530 return type.IsTypeRef() || (type.IsType() && !type.IsCanonical());
531}
532
533static bool HasNonCanonicalTypes(Zone* zone, const Function& func) {
534 auto& type = AbstractType::Handle(zone);
535 for (intptr_t i = 0; i < func.NumParameters(); ++i) {
536 type = func.ParameterTypeAt(i);
537 if (IsNonCanonical(type)) {
538 return true;
539 }
540 }
541 type = func.result_type();
542 if (IsNonCanonical(type)) {
543 return true;
544 }
545 const auto& type_params = TypeArguments::Handle(zone, func.type_parameters());
546 if (!type_params.IsNull()) {
547 for (intptr_t i = 0; i < type_params.Length(); ++i) {
548 type = type_params.TypeAt(i);
549 type = TypeParameter::Cast(type).bound();
550 if (IsNonCanonical(type)) {
551 return true;
552 }
553 }
554 }
555 return false;
556}
557
558TypePtr BytecodeReaderHelper::ReadFunctionSignature(
559 const Function& func,
560 bool has_optional_positional_params,
561 bool has_optional_named_params,
562 bool has_type_params,
563 bool has_positional_param_names,
564 bool has_parameter_flags,
565 Nullability nullability) {
566 FunctionTypeScope function_type_scope(this);
567
568 if (has_type_params) {
569 ReadTypeParametersDeclaration(Class::Handle(Z), func);
570 }
571
572 const intptr_t kImplicitClosureParam = 1;
573 const intptr_t num_params = kImplicitClosureParam + reader_.ReadUInt();
574
575 intptr_t num_required_params = num_params;
576 if (has_optional_positional_params || has_optional_named_params) {
577 num_required_params = kImplicitClosureParam + reader_.ReadUInt();
578 }
579
580 func.set_num_fixed_parameters(num_required_params);
581 func.SetNumOptionalParameters(num_params - num_required_params,
582 !has_optional_named_params);
583 const Array& parameter_types =
584 Array::Handle(Z, Array::New(num_params, Heap::kOld));
585 func.set_parameter_types(parameter_types);
586 const Array& parameter_names = Array::Handle(
587 Z, Array::New(Function::NameArrayLengthIncludingFlags(num_params),
588 Heap::kOld));
589 func.set_parameter_names(parameter_names);
590
591 intptr_t i = 0;
592 parameter_types.SetAt(i, AbstractType::dynamic_type());
593 parameter_names.SetAt(i, Symbols::ClosureParameter());
594 ++i;
595
596 AbstractType& type = AbstractType::Handle(Z);
597 String& name = String::Handle(Z);
598 for (; i < num_params; ++i) {
599 if (has_positional_param_names ||
600 (has_optional_named_params && (i >= num_required_params))) {
601 name ^= ReadObject();
602 } else {
603 name = Symbols::NotNamed().raw();
604 }
605 parameter_names.SetAt(i, name);
606 type ^= ReadObject();
607 parameter_types.SetAt(i, type);
608 }
609 if (has_parameter_flags) {
610 intptr_t num_flags = reader_.ReadUInt();
611 for (intptr_t i = 0; i < num_flags; ++i) {
612 intptr_t flag = reader_.ReadUInt();
613 if ((flag & Parameter::kIsRequiredFlag) != 0) {
614 RELEASE_ASSERT(kImplicitClosureParam + i >= num_required_params);
615 func.SetIsRequiredAt(kImplicitClosureParam + i);
616 }
617 }
618 }
619 func.TruncateUnusedParameterFlags();
620
621 type ^= ReadObject();
622 func.set_result_type(type);
623
624 // Finalize function type.
625 type = func.SignatureType(nullability);
626 ClassFinalizer::FinalizationKind finalization = ClassFinalizer::kCanonicalize;
627 if (pending_recursive_types_ != nullptr && HasNonCanonicalTypes(Z, func)) {
628 // This function type is a part of recursive type. Avoid canonicalization
629 // as not all TypeRef objects are filled up at this point.
630 finalization = ClassFinalizer::kFinalize;
631 }
632 type =
633 ClassFinalizer::FinalizeType(*(active_class_->klass), type, finalization);
634 return Type::Cast(type).raw();
635}
636
637void BytecodeReaderHelper::ReadTypeParametersDeclaration(
638 const Class& parameterized_class,
639 const Function& parameterized_function) {
640 ASSERT(parameterized_class.IsNull() != parameterized_function.IsNull());
641
642 const intptr_t num_type_params = reader_.ReadUInt();
643 ASSERT(num_type_params > 0);
644
645 intptr_t offset;
646 NNBDMode nnbd_mode;
647 if (!parameterized_class.IsNull()) {
648 offset = parameterized_class.NumTypeArguments() - num_type_params;
649 nnbd_mode = parameterized_class.nnbd_mode();
650 } else {
651 offset = parameterized_function.NumParentTypeParameters();
652 nnbd_mode = parameterized_function.nnbd_mode();
653 }
654 const Nullability nullability = (nnbd_mode == NNBDMode::kOptedInLib)
655 ? Nullability::kNonNullable
656 : Nullability::kLegacy;
657
658 // First setup the type parameters, so if any of the following code uses it
659 // (in a recursive way) we're fine.
660 //
661 // Step a) Create array of [TypeParameter] objects (without bound).
662 const TypeArguments& type_parameters =
663 TypeArguments::Handle(Z, TypeArguments::New(num_type_params));
664 String& name = String::Handle(Z);
665 TypeParameter& parameter = TypeParameter::Handle(Z);
666 AbstractType& bound = AbstractType::Handle(Z);
667 for (intptr_t i = 0; i < num_type_params; ++i) {
668 name ^= ReadObject();
669 ASSERT(name.IsSymbol());
670 parameter = TypeParameter::New(parameterized_class, parameterized_function,
671 i, name, bound,
672 /* is_generic_covariant_impl = */ false,
673 nullability, TokenPosition::kNoSource);
674 parameter.set_index(offset + i);
675 parameter.SetIsFinalized();
676 parameter.SetCanonical();
677 parameter.SetDeclaration(true);
678 type_parameters.SetTypeAt(i, parameter);
679 }
680
681 if (!parameterized_class.IsNull()) {
682 parameterized_class.set_type_parameters(type_parameters);
683 } else if (!parameterized_function.IsFactory()) {
684 // Do not set type parameters for factories, as VM uses class type
685 // parameters instead.
686 parameterized_function.set_type_parameters(type_parameters);
687 if (parameterized_function.IsSignatureFunction()) {
688 if (function_type_type_parameters_ == nullptr) {
689 function_type_type_parameters_ = &type_parameters;
690 } else {
691 function_type_type_parameters_ = &TypeArguments::Handle(
692 Z, function_type_type_parameters_->ConcatenateTypeParameters(
693 Z, type_parameters));
694 }
695 } else {
696 ASSERT(function_type_type_parameters_ == nullptr);
697 }
698 }
699
700 // Step b) Fill in the bounds of all [TypeParameter]s.
701 for (intptr_t i = 0; i < num_type_params; ++i) {
702 parameter ^= type_parameters.TypeAt(i);
703 bound ^= ReadObject();
704 // Convert dynamic to Object? or Object* in bounds of type parameters so
705 // they are equivalent when doing subtype checks for function types.
706 // TODO(https://github.com/dart-lang/language/issues/495): revise this
707 // when function subtyping is fixed.
708 if (bound.IsDynamicType()) {
709 bound = nnbd_mode == NNBDMode::kOptedInLib
710 ? I->object_store()->nullable_object_type()
711 : I->object_store()->legacy_object_type();
712 }
713 parameter.set_bound(bound);
714 }
715
716 // Fix bounds in all derived type parameters (with different nullabilities).
717 if (active_class_->derived_type_parameters != nullptr) {
718 auto& derived = TypeParameter::Handle(Z);
719 auto& bound = AbstractType::Handle(Z);
720 for (intptr_t i = 0, n = active_class_->derived_type_parameters->Length();
721 i < n; ++i) {
722 derived ^= active_class_->derived_type_parameters->At(i);
723 if (derived.bound() == AbstractType::null() &&
724 ((!parameterized_class.IsNull() &&
725 derived.parameterized_class() == parameterized_class.raw()) ||
726 (!parameterized_function.IsNull() &&
727 derived.parameterized_function() ==
728 parameterized_function.raw()))) {
729 ASSERT(derived.IsFinalized());
730 parameter ^= type_parameters.TypeAt(derived.index() - offset);
731 bound = parameter.bound();
732 derived.set_bound(bound);
733 }
734 }
735 }
736}
737
738intptr_t BytecodeReaderHelper::ReadConstantPool(const Function& function,
739 const ObjectPool& pool,
740 intptr_t start_index) {
741 TIMELINE_DURATION(Thread::Current(), CompilerVerbose,
742 "BytecodeReaderHelper::ReadConstantPool");
743
744 // These enums and the code below reading the constant pool from kernel must
745 // be kept in sync with pkg/vm/lib/bytecode/constant_pool.dart.
746 enum ConstantPoolTag {
747 kInvalid,
748 kUnused1,
749 kUnused2,
750 kUnused3,
751 kUnused4,
752 kUnused5,
753 kUnused6,
754 kUnused6a,
755 kUnused7,
756 kStaticField,
757 kInstanceField,
758 kClass,
759 kTypeArgumentsField,
760 kUnused8,
761 kType,
762 kUnused9,
763 kUnused10,
764 kUnused11,
765 kUnused12,
766 kClosureFunction,
767 kEndClosureFunctionScope,
768 kNativeEntry,
769 kSubtypeTestCache,
770 kUnused13,
771 kEmptyTypeArguments,
772 kUnused14,
773 kUnused15,
774 kObjectRef,
775 kDirectCall,
776 kInterfaceCall,
777 kInstantiatedInterfaceCall,
778 kDynamicCall,
779 kDirectCallViaDynamicForwarder,
780 };
781
782 Object& obj = Object::Handle(Z);
783 Object& elem = Object::Handle(Z);
784 Field& field = Field::Handle(Z);
785 Class& cls = Class::Handle(Z);
786 String& name = String::Handle(Z);
787 const intptr_t obj_count = pool.Length();
788 for (intptr_t i = start_index; i < obj_count; ++i) {
789 const intptr_t tag = reader_.ReadTag();
790 switch (tag) {
791 case ConstantPoolTag::kInvalid:
792 UNREACHABLE();
793 case ConstantPoolTag::kStaticField:
794 obj = ReadObject();
795 ASSERT(obj.IsField());
796 break;
797 case ConstantPoolTag::kInstanceField:
798 field ^= ReadObject();
799 // InstanceField constant occupies 2 entries.
800 // The first entry is used for field offset.
801 obj = Smi::New(field.HostOffset() / kWordSize);
802 pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject,
803 ObjectPool::Patchability::kNotPatchable);
804 pool.SetObjectAt(i, obj);
805 ++i;
806 ASSERT(i < obj_count);
807 // The second entry is used for field object.
808 obj = field.raw();
809 break;
810 case ConstantPoolTag::kClass:
811 obj = ReadObject();
812 ASSERT(obj.IsClass());
813 break;
814 case ConstantPoolTag::kTypeArgumentsField:
815 cls ^= ReadObject();
816 obj = Smi::New(cls.host_type_arguments_field_offset() / kWordSize);
817 break;
818 case ConstantPoolTag::kType:
819 obj = ReadObject();
820 ASSERT(obj.IsAbstractType());
821 break;
822 case ConstantPoolTag::kClosureFunction: {
823 intptr_t closure_index = reader_.ReadUInt();
824 obj = closures_->At(closure_index);
825 ASSERT(obj.IsFunction());
826 // Set current entry.
827 pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject,
828 ObjectPool::Patchability::kNotPatchable);
829 pool.SetObjectAt(i, obj);
830
831 // This scope is needed to set active_class_->enclosing_ which is used
832 // to assign parent function for function types.
833 ActiveEnclosingFunctionScope active_enclosing_function(
834 active_class_, &Function::Cast(obj));
835
836 // Read constant pool until corresponding EndClosureFunctionScope.
837 i = ReadConstantPool(function, pool, i + 1);
838
839 // Proceed with the rest of entries.
840 continue;
841 }
842 case ConstantPoolTag::kEndClosureFunctionScope: {
843 // EndClosureFunctionScope entry is not used and set to null.
844 obj = Object::null();
845 pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject,
846 ObjectPool::Patchability::kNotPatchable);
847 pool.SetObjectAt(i, obj);
848 return i;
849 }
850 case ConstantPoolTag::kNativeEntry: {
851 name = ReadString();
852 obj = NativeEntry(function, name);
853 pool.SetTypeAt(i, ObjectPool::EntryType::kNativeEntryData,
854 ObjectPool::Patchability::kNotPatchable);
855 pool.SetObjectAt(i, obj);
856 continue;
857 }
858 case ConstantPoolTag::kSubtypeTestCache: {
859 obj = SubtypeTestCache::New();
860 } break;
861 case ConstantPoolTag::kEmptyTypeArguments:
862 obj = Object::empty_type_arguments().raw();
863 break;
864 case ConstantPoolTag::kObjectRef:
865 obj = ReadObject();
866 break;
867 case ConstantPoolTag::kDirectCall: {
868 // DirectCall constant occupies 2 entries.
869 // The first entry is used for target function.
870 obj = ReadObject();
871 ASSERT(obj.IsFunction());
872 pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject,
873 ObjectPool::Patchability::kNotPatchable);
874 pool.SetObjectAt(i, obj);
875 ++i;
876 ASSERT(i < obj_count);
877 // The second entry is used for arguments descriptor.
878 obj = ReadObject();
879 } break;
880 case ConstantPoolTag::kInterfaceCall: {
881 elem = ReadObject();
882 ASSERT(elem.IsFunction());
883 // InterfaceCall constant occupies 2 entries.
884 // The first entry is used for interface target.
885 pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject,
886 ObjectPool::Patchability::kNotPatchable);
887 pool.SetObjectAt(i, elem);
888 ++i;
889 ASSERT(i < obj_count);
890 // The second entry is used for arguments descriptor.
891 obj = ReadObject();
892 } break;
893 case ConstantPoolTag::kInstantiatedInterfaceCall: {
894 elem = ReadObject();
895 ASSERT(elem.IsFunction());
896 // InstantiatedInterfaceCall constant occupies 3 entries:
897 // 1) Interface target.
898 pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject,
899 ObjectPool::Patchability::kNotPatchable);
900 pool.SetObjectAt(i, elem);
901 ++i;
902 ASSERT(i < obj_count);
903 // 2) Arguments descriptor.
904 obj = ReadObject();
905 pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject,
906 ObjectPool::Patchability::kNotPatchable);
907 pool.SetObjectAt(i, obj);
908 ++i;
909 ASSERT(i < obj_count);
910 // 3) Static receiver type.
911 obj = ReadObject();
912 } break;
913 case ConstantPoolTag::kDynamicCall: {
914 name ^= ReadObject();
915 ASSERT(name.IsSymbol());
916 // Do not mangle ==:
917 // * operator == takes an Object so it is either not checked or
918 // checked at the entry because the parameter is marked covariant,
919 // neither of those cases require a dynamic invocation forwarder
920 if (!Field::IsGetterName(name) &&
921 (name.raw() != Symbols::EqualOperator().raw())) {
922 name = Function::CreateDynamicInvocationForwarderName(name);
923 }
924 // DynamicCall constant occupies 2 entries: selector and arguments
925 // descriptor.
926 pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject,
927 ObjectPool::Patchability::kNotPatchable);
928 pool.SetObjectAt(i, name);
929 ++i;
930 ASSERT(i < obj_count);
931 // The second entry is used for arguments descriptor.
932 obj = ReadObject();
933 } break;
934 case ConstantPoolTag::kDirectCallViaDynamicForwarder: {
935 // DirectCallViaDynamicForwarder constant occupies 2 entries.
936 // The first entry is used for target function.
937 obj = ReadObject();
938 ASSERT(obj.IsFunction());
939 name = Function::Cast(obj).name();
940 name = Function::CreateDynamicInvocationForwarderName(name);
941 obj = Function::Cast(obj).GetDynamicInvocationForwarder(name);
942
943 pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject,
944 ObjectPool::Patchability::kNotPatchable);
945 pool.SetObjectAt(i, obj);
946 ++i;
947 ASSERT(i < obj_count);
948 // The second entry is used for arguments descriptor.
949 obj = ReadObject();
950 } break;
951 default:
952 UNREACHABLE();
953 }
954 pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject,
955 ObjectPool::Patchability::kNotPatchable);
956 pool.SetObjectAt(i, obj);
957 }
958
959 return obj_count - 1;
960}
961
962BytecodePtr BytecodeReaderHelper::ReadBytecode(const ObjectPool& pool) {
963#if defined(SUPPORT_TIMELINE)
964 TIMELINE_DURATION(Thread::Current(), CompilerVerbose,
965 "BytecodeReaderHelper::ReadBytecode");
966#endif // defined(SUPPORT_TIMELINE)
967 const intptr_t size = reader_.ReadUInt();
968 const intptr_t offset = reader_.offset();
969
970 const uint8_t* data = reader_.BufferAt(offset);
971 reader_.set_offset(offset + size);
972
973 // Create and return bytecode object.
974 return Bytecode::New(reinterpret_cast<uword>(data), size, offset, pool);
975}
976
977void BytecodeReaderHelper::ReadExceptionsTable(const Bytecode& bytecode,
978 bool has_exceptions_table) {
979#if defined(SUPPORT_TIMELINE)
980 TIMELINE_DURATION(Thread::Current(), CompilerVerbose,
981 "BytecodeReaderHelper::ReadExceptionsTable");
982#endif
983
984 const intptr_t try_block_count =
985 has_exceptions_table ? reader_.ReadListLength() : 0;
986 if (try_block_count > 0) {
987 const ObjectPool& pool = ObjectPool::Handle(Z, bytecode.object_pool());
988 AbstractType& handler_type = AbstractType::Handle(Z);
989 Array& handler_types = Array::Handle(Z);
990 DescriptorList* pc_descriptors_list = new (Z) DescriptorList(64);
991 ExceptionHandlerList* exception_handlers_list =
992 new (Z) ExceptionHandlerList();
993
994 // Encoding of ExceptionsTable is described in
995 // pkg/vm/lib/bytecode/exceptions.dart.
996 for (intptr_t try_index = 0; try_index < try_block_count; try_index++) {
997 intptr_t outer_try_index_plus1 = reader_.ReadUInt();
998 intptr_t outer_try_index = outer_try_index_plus1 - 1;
999 // PcDescriptors are expressed in terms of return addresses.
1000 intptr_t start_pc =
1001 KernelBytecode::BytecodePcToOffset(reader_.ReadUInt(),
1002 /* is_return_address = */ true);
1003 intptr_t end_pc =
1004 KernelBytecode::BytecodePcToOffset(reader_.ReadUInt(),
1005 /* is_return_address = */ true);
1006 intptr_t handler_pc =
1007 KernelBytecode::BytecodePcToOffset(reader_.ReadUInt(),
1008 /* is_return_address = */ false);
1009 uint8_t flags = reader_.ReadByte();
1010 const uint8_t kFlagNeedsStackTrace = 1 << 0;
1011 const uint8_t kFlagIsSynthetic = 1 << 1;
1012 const bool needs_stacktrace = (flags & kFlagNeedsStackTrace) != 0;
1013 const bool is_generated = (flags & kFlagIsSynthetic) != 0;
1014 intptr_t type_count = reader_.ReadListLength();
1015 ASSERT(type_count > 0);
1016 handler_types = Array::New(type_count, Heap::kOld);
1017 for (intptr_t i = 0; i < type_count; i++) {
1018 intptr_t type_index = reader_.ReadUInt();
1019 ASSERT(type_index < pool.Length());
1020 handler_type ^= pool.ObjectAt(type_index);
1021 handler_types.SetAt(i, handler_type);
1022 }
1023 pc_descriptors_list->AddDescriptor(
1024 PcDescriptorsLayout::kOther, start_pc, DeoptId::kNone,
1025 TokenPosition::kNoSource, try_index,
1026 PcDescriptorsLayout::kInvalidYieldIndex);
1027 pc_descriptors_list->AddDescriptor(
1028 PcDescriptorsLayout::kOther, end_pc, DeoptId::kNone,
1029 TokenPosition::kNoSource, try_index,
1030 PcDescriptorsLayout::kInvalidYieldIndex);
1031
1032 // The exception handler keeps a zone handle of the types array, rather
1033 // than a raw pointer. Do not share the handle across iterations to avoid
1034 // clobbering the array.
1035 exception_handlers_list->AddHandler(
1036 try_index, outer_try_index, handler_pc, is_generated,
1037 Array::ZoneHandle(Z, handler_types.raw()), needs_stacktrace);
1038 }
1039 const PcDescriptors& descriptors = PcDescriptors::Handle(
1040 Z, pc_descriptors_list->FinalizePcDescriptors(bytecode.PayloadStart()));
1041 bytecode.set_pc_descriptors(descriptors);
1042 const ExceptionHandlers& handlers = ExceptionHandlers::Handle(
1043 Z, exception_handlers_list->FinalizeExceptionHandlers(
1044 bytecode.PayloadStart()));
1045 bytecode.set_exception_handlers(handlers);
1046 } else {
1047 bytecode.set_pc_descriptors(Object::empty_descriptors());
1048 bytecode.set_exception_handlers(Object::empty_exception_handlers());
1049 }
1050}
1051
1052void BytecodeReaderHelper::ReadSourcePositions(const Bytecode& bytecode,
1053 bool has_source_positions) {
1054 if (!has_source_positions) {
1055 return;
1056 }
1057
1058 intptr_t offset = reader_.ReadUInt();
1059 bytecode.set_source_positions_binary_offset(
1060 bytecode_component_->GetSourcePositionsOffset() + offset);
1061}
1062
1063void BytecodeReaderHelper::ReadLocalVariables(const Bytecode& bytecode,
1064 bool has_local_variables) {
1065 if (!has_local_variables) {
1066 return;
1067 }
1068
1069 const intptr_t offset = reader_.ReadUInt();
1070 bytecode.set_local_variables_binary_offset(
1071 bytecode_component_->GetLocalVariablesOffset() + offset);
1072}
1073
1074TypedDataPtr BytecodeReaderHelper::NativeEntry(const Function& function,
1075 const String& external_name) {
1076 MethodRecognizer::Kind kind = function.recognized_kind();
1077 // This list of recognized methods must be kept in sync with the list of
1078 // methods handled specially by the NativeCall bytecode in the interpreter.
1079 switch (kind) {
1080 case MethodRecognizer::kObjectEquals:
1081 case MethodRecognizer::kStringBaseLength:
1082 case MethodRecognizer::kStringBaseIsEmpty:
1083 case MethodRecognizer::kGrowableArrayLength:
1084 case MethodRecognizer::kObjectArrayLength:
1085 case MethodRecognizer::kImmutableArrayLength:
1086 case MethodRecognizer::kTypedListLength:
1087 case MethodRecognizer::kTypedListViewLength:
1088 case MethodRecognizer::kByteDataViewLength:
1089 case MethodRecognizer::kByteDataViewOffsetInBytes:
1090 case MethodRecognizer::kTypedDataViewOffsetInBytes:
1091 case MethodRecognizer::kByteDataViewTypedData:
1092 case MethodRecognizer::kTypedDataViewTypedData:
1093 case MethodRecognizer::kClassIDgetID:
1094 case MethodRecognizer::kGrowableArrayCapacity:
1095 case MethodRecognizer::kListFactory:
1096 case MethodRecognizer::kObjectArrayAllocate:
1097 case MethodRecognizer::kLinkedHashMap_getIndex:
1098 case MethodRecognizer::kLinkedHashMap_setIndex:
1099 case MethodRecognizer::kLinkedHashMap_getData:
1100 case MethodRecognizer::kLinkedHashMap_setData:
1101 case MethodRecognizer::kLinkedHashMap_getHashMask:
1102 case MethodRecognizer::kLinkedHashMap_setHashMask:
1103 case MethodRecognizer::kLinkedHashMap_getUsedData:
1104 case MethodRecognizer::kLinkedHashMap_setUsedData:
1105 case MethodRecognizer::kLinkedHashMap_getDeletedKeys:
1106 case MethodRecognizer::kLinkedHashMap_setDeletedKeys:
1107 case MethodRecognizer::kFfiAbi:
1108 break;
1109 case MethodRecognizer::kAsyncStackTraceHelper:
1110 // If causal async stacks are disabled the interpreter.cc will handle this
1111 // native call specially.
1112 if (!FLAG_causal_async_stacks) {
1113 break;
1114 }
1115 FALL_THROUGH;
1116 default:
1117 kind = MethodRecognizer::kUnknown;
1118 }
1119 NativeFunctionWrapper trampoline = NULL;
1120 NativeFunction native_function = NULL;
1121 intptr_t argc_tag = 0;
1122 if (kind == MethodRecognizer::kUnknown) {
1123 if (!FLAG_link_natives_lazily) {
1124 const Class& cls = Class::Handle(Z, function.Owner());
1125 const Library& library = Library::Handle(Z, cls.library());
1126 Dart_NativeEntryResolver resolver = library.native_entry_resolver();
1127 const bool is_bootstrap_native = Bootstrap::IsBootstrapResolver(resolver);
1128 const int num_params =
1129 NativeArguments::ParameterCountForResolution(function);
1130 bool is_auto_scope = true;
1131 native_function = NativeEntry::ResolveNative(library, external_name,
1132 num_params, &is_auto_scope);
1133 if (native_function == nullptr) {
1134 Report::MessageF(Report::kError, Script::Handle(function.script()),
1135 function.token_pos(), Report::AtLocation,
1136 "native function '%s' (%" Pd
1137 " arguments) cannot be found",
1138 external_name.ToCString(), function.NumParameters());
1139 }
1140 if (is_bootstrap_native) {
1141 trampoline = &NativeEntry::BootstrapNativeCallWrapper;
1142 } else if (is_auto_scope) {
1143 trampoline = &NativeEntry::AutoScopeNativeCallWrapper;
1144 } else {
1145 trampoline = &NativeEntry::NoScopeNativeCallWrapper;
1146 }
1147 }
1148 argc_tag = NativeArguments::ComputeArgcTag(function);
1149 }
1150 return NativeEntryData::New(kind, trampoline, native_function, argc_tag);
1151}
1152
1153ArrayPtr BytecodeReaderHelper::ReadBytecodeComponent(intptr_t md_offset) {
1154 ASSERT(Thread::Current()->IsMutatorThread());
1155
1156 AlternativeReadingScope alt(&reader_, md_offset);
1157
1158 const intptr_t start_offset = reader_.offset();
1159
1160 intptr_t magic = reader_.ReadUInt32();
1161 if (magic != KernelBytecode::kMagicValue) {
1162 FATAL1("Unexpected Dart bytecode magic %" Px, magic);
1163 }
1164
1165 const intptr_t version = reader_.ReadUInt32();
1166 if ((version < KernelBytecode::kMinSupportedBytecodeFormatVersion) ||
1167 (version > KernelBytecode::kMaxSupportedBytecodeFormatVersion)) {
1168 FATAL3("Unsupported Dart bytecode format version %" Pd
1169 ". "
1170 "This version of Dart VM supports bytecode format versions from %" Pd
1171 " to %" Pd ".",
1172 version, KernelBytecode::kMinSupportedBytecodeFormatVersion,
1173 KernelBytecode::kMaxSupportedBytecodeFormatVersion);
1174 }
1175
1176 reader_.ReadUInt32(); // Skip stringTable.numItems
1177 const intptr_t string_table_offset = start_offset + reader_.ReadUInt32();
1178
1179 reader_.ReadUInt32(); // Skip objectTable.numItems
1180 const intptr_t object_table_offset = start_offset + reader_.ReadUInt32();
1181
1182 reader_.ReadUInt32(); // Skip main.numItems
1183 const intptr_t main_offset = start_offset + reader_.ReadUInt32();
1184
1185 const intptr_t num_libraries = reader_.ReadUInt32();
1186 const intptr_t library_index_offset = start_offset + reader_.ReadUInt32();
1187
1188 reader_.ReadUInt32(); // Skip libraries.numItems
1189 const intptr_t libraries_offset = start_offset + reader_.ReadUInt32();
1190
1191 const intptr_t num_classes = reader_.ReadUInt32();
1192 const intptr_t classes_offset = start_offset + reader_.ReadUInt32();
1193
1194 reader_.ReadUInt32(); // Skip members.numItems
1195 const intptr_t members_offset = start_offset + reader_.ReadUInt32();
1196
1197 const intptr_t num_codes = reader_.ReadUInt32();
1198 const intptr_t codes_offset = start_offset + reader_.ReadUInt32();
1199
1200 reader_.ReadUInt32(); // Skip sourcePositions.numItems
1201 const intptr_t source_positions_offset = start_offset + reader_.ReadUInt32();
1202
1203 reader_.ReadUInt32(); // Skip sourceFiles.numItems
1204 const intptr_t source_files_offset = start_offset + reader_.ReadUInt32();
1205
1206 reader_.ReadUInt32(); // Skip lineStarts.numItems
1207 const intptr_t line_starts_offset = start_offset + reader_.ReadUInt32();
1208
1209 reader_.ReadUInt32(); // Skip localVariables.numItems
1210 const intptr_t local_variables_offset = start_offset + reader_.ReadUInt32();
1211
1212 reader_.ReadUInt32(); // Skip annotations.numItems
1213 const intptr_t annotations_offset = start_offset + reader_.ReadUInt32();
1214
1215 const intptr_t num_protected_names = reader_.ReadUInt32();
1216 const intptr_t protected_names_offset = start_offset + reader_.ReadUInt32();
1217
1218 // Read header of string table.
1219 reader_.set_offset(string_table_offset);
1220 const intptr_t num_one_byte_strings = reader_.ReadUInt32();
1221 const intptr_t num_two_byte_strings = reader_.ReadUInt32();
1222 const intptr_t strings_contents_offset =
1223 reader_.offset() + (num_one_byte_strings + num_two_byte_strings) * 4;
1224
1225 // Read header of object table.
1226 reader_.set_offset(object_table_offset);
1227 const intptr_t num_objects = reader_.ReadUInt();
1228 const intptr_t objects_size = reader_.ReadUInt();
1229
1230 // Skip over contents of objects.
1231 const intptr_t objects_contents_offset = reader_.offset();
1232 const intptr_t object_offsets_offset = objects_contents_offset + objects_size;
1233 reader_.set_offset(object_offsets_offset);
1234
1235 auto& bytecode_component_array = Array::Handle(
1236 Z,
1237 BytecodeComponentData::New(
1238 Z, version, num_objects, string_table_offset, strings_contents_offset,
1239 object_offsets_offset, objects_contents_offset, main_offset,
1240 num_libraries, library_index_offset, libraries_offset, num_classes,
1241 classes_offset, members_offset, num_codes, codes_offset,
1242 source_positions_offset, source_files_offset, line_starts_offset,
1243 local_variables_offset, annotations_offset, Heap::kOld));
1244
1245 BytecodeComponentData bytecode_component(&bytecode_component_array);
1246
1247 // Read object offsets.
1248 Smi& offs = Smi::Handle(Z);
1249 for (intptr_t i = 0; i < num_objects; ++i) {
1250 offs = Smi::New(reader_.ReadUInt());
1251 bytecode_component.SetObject(i, offs);
1252 }
1253
1254 // Read protected names.
1255 if (I->obfuscate() && (num_protected_names > 0)) {
1256 bytecode_component_ = &bytecode_component;
1257
1258 reader_.set_offset(protected_names_offset);
1259 Obfuscator obfuscator(thread_, Object::null_string());
1260 auto& name = String::Handle(Z);
1261 for (intptr_t i = 0; i < num_protected_names; ++i) {
1262 name = ReadString();
1263 obfuscator.PreventRenaming(name);
1264 }
1265
1266 bytecode_component_ = nullptr;
1267 }
1268
1269 H.SetBytecodeComponent(bytecode_component_array);
1270
1271 return bytecode_component_array.raw();
1272}
1273
1274void BytecodeReaderHelper::ResetObjects() {
1275 reader_.set_offset(bytecode_component_->GetObjectOffsetsOffset());
1276 const intptr_t num_objects = bytecode_component_->GetNumObjects();
1277
1278 // Read object offsets.
1279 Smi& offs = Smi::Handle(Z);
1280 for (intptr_t i = 0; i < num_objects; ++i) {
1281 offs = Smi::New(reader_.ReadUInt());
1282 bytecode_component_->SetObject(i, offs);
1283 }
1284}
1285
1286ObjectPtr BytecodeReaderHelper::ReadObject() {
1287 uint32_t header = reader_.ReadUInt();
1288 if ((header & kReferenceBit) != 0) {
1289 intptr_t index = header >> kIndexShift;
1290 if (index == 0) {
1291 return Object::null();
1292 }
1293 ObjectPtr obj = bytecode_component_->GetObject(index);
1294 if (obj->IsHeapObject()) {
1295 return obj;
1296 }
1297 // Object is not loaded yet.
1298 intptr_t offset = bytecode_component_->GetObjectsContentsOffset() +
1299 Smi::Value(Smi::RawCast(obj));
1300 AlternativeReadingScope alt(&reader_, offset);
1301 header = reader_.ReadUInt();
1302
1303 obj = ReadObjectContents(header);
1304 ASSERT(obj->IsHeapObject());
1305 {
1306 REUSABLE_OBJECT_HANDLESCOPE(thread_);
1307 Object& obj_handle = thread_->ObjectHandle();
1308 obj_handle = obj;
1309 bytecode_component_->SetObject(index, obj_handle);
1310 }
1311 return obj;
1312 }
1313
1314 return ReadObjectContents(header);
1315}
1316
1317StringPtr BytecodeReaderHelper::ConstructorName(const Class& cls,
1318 const String& name) {
1319 GrowableHandlePtrArray<const String> pieces(Z, 3);
1320 pieces.Add(String::Handle(Z, cls.Name()));
1321 pieces.Add(Symbols::Dot());
1322 pieces.Add(name);
1323 return Symbols::FromConcatAll(thread_, pieces);
1324}
1325
1326ObjectPtr BytecodeReaderHelper::ReadObjectContents(uint32_t header) {
1327 ASSERT(((header & kReferenceBit) == 0));
1328
1329 // Must be in sync with enum ObjectKind in
1330 // pkg/vm/lib/bytecode/object_table.dart.
1331 enum ObjectKind {
1332 kInvalid,
1333 kLibrary,
1334 kClass,
1335 kMember,
1336 kClosure,
1337 kUnused1,
1338 kUnused2,
1339 kUnused3,
1340 kUnused4,
1341 kName,
1342 kTypeArguments,
1343 kUnused5,
1344 kConstObject,
1345 kArgDesc,
1346 kScript,
1347 kType,
1348 };
1349
1350 // Member flags, must be in sync with _MemberHandle constants in
1351 // pkg/vm/lib/bytecode/object_table.dart.
1352 const intptr_t kFlagIsField = kFlagBit0;
1353 const intptr_t kFlagIsConstructor = kFlagBit1;
1354
1355 // ArgDesc flags, must be in sync with _ArgDescHandle constants in
1356 // pkg/vm/lib/bytecode/object_table.dart.
1357 const int kFlagHasNamedArgs = kFlagBit0;
1358 const int kFlagHasTypeArgs = kFlagBit1;
1359
1360 // Script flags, must be in sync with _ScriptHandle constants in
1361 // pkg/vm/lib/bytecode/object_table.dart.
1362 const int kFlagHasSourceFile = kFlagBit0;
1363
1364 // Name flags, must be in sync with _NameHandle constants in
1365 // pkg/vm/lib/bytecode/object_table.dart.
1366 const intptr_t kFlagIsPublic = kFlagBit0;
1367
1368 const intptr_t kind = (header >> kKindShift) & kKindMask;
1369 const intptr_t flags = header & kFlagsMask;
1370
1371 switch (kind) {
1372 case kInvalid:
1373 UNREACHABLE();
1374 break;
1375 case kLibrary: {
1376 String& uri = String::CheckedHandle(Z, ReadObject());
1377 LibraryPtr library = Library::LookupLibrary(thread_, uri);
1378 if (library == Library::null()) {
1379 // We do not register expression evaluation libraries with the VM:
1380 // The expression evaluation functions should be GC-able as soon as
1381 // they are not reachable anymore and we never look them up by name.
1382 if (uri.raw() == Symbols::EvalSourceUri().raw()) {
1383 ASSERT(expression_evaluation_library_ != nullptr);
1384 return expression_evaluation_library_->raw();
1385 }
1386#if !defined(PRODUCT)
1387 ASSERT(Isolate::Current()->HasAttemptedReload());
1388 const String& msg = String::Handle(
1389 Z,
1390 String::NewFormatted("Unable to find library %s", uri.ToCString()));
1391 Report::LongJump(LanguageError::Handle(Z, LanguageError::New(msg)));
1392#else
1393 FATAL1("Unable to find library %s", uri.ToCString());
1394#endif
1395 }
1396 return library;
1397 }
1398 case kClass: {
1399 const Library& library = Library::CheckedHandle(Z, ReadObject());
1400 const String& class_name = String::CheckedHandle(Z, ReadObject());
1401 if (class_name.raw() == Symbols::Empty().raw()) {
1402 NoSafepointScope no_safepoint_scope(thread_);
1403 ClassPtr cls = library.toplevel_class();
1404 if (cls == Class::null()) {
1405 FATAL1("Unable to find toplevel class %s", library.ToCString());
1406 }
1407 return cls;
1408 }
1409 ClassPtr cls = library.LookupLocalClass(class_name);
1410 if (cls == Class::null()) {
1411 if (IsExpressionEvaluationLibrary(library)) {
1412 return H.GetExpressionEvaluationRealClass();
1413 }
1414#if !defined(PRODUCT)
1415 ASSERT(Isolate::Current()->HasAttemptedReload());
1416 const String& msg = String::Handle(
1417 Z,
1418 String::NewFormatted("Unable to find class %s in %s",
1419 class_name.ToCString(), library.ToCString()));
1420 Report::LongJump(LanguageError::Handle(Z, LanguageError::New(msg)));
1421#else
1422 FATAL2("Unable to find class %s in %s", class_name.ToCString(),
1423 library.ToCString());
1424#endif
1425 }
1426 return cls;
1427 }
1428 case kMember: {
1429 const Class& cls = Class::CheckedHandle(Z, ReadObject());
1430 String& name = String::CheckedHandle(Z, ReadObject());
1431 if ((flags & kFlagIsField) != 0) {
1432 FieldPtr field = cls.LookupField(name);
1433 if (field == Field::null()) {
1434#if !defined(PRODUCT)
1435 ASSERT(Isolate::Current()->HasAttemptedReload());
1436 const String& msg = String::Handle(
1437 Z, String::NewFormatted("Unable to find field %s in %s",
1438 name.ToCString(), cls.ToCString()));
1439 Report::LongJump(LanguageError::Handle(Z, LanguageError::New(msg)));
1440#else
1441 FATAL2("Unable to find field %s in %s", name.ToCString(),
1442 cls.ToCString());
1443#endif
1444 }
1445 return field;
1446 } else {
1447 if ((flags & kFlagIsConstructor) != 0) {
1448 name = ConstructorName(cls, name);
1449 }
1450 ASSERT(!name.IsNull() && name.IsSymbol());
1451 if (name.raw() == scoped_function_name_.raw() &&
1452 cls.raw() == scoped_function_class_.raw()) {
1453 return scoped_function_.raw();
1454 }
1455 FunctionPtr function = cls.LookupFunction(name);
1456 if (function == Function::null()) {
1457 // When requesting a getter, also return method extractors.
1458 if (Field::IsGetterName(name)) {
1459 String& method_name =
1460 String::Handle(Z, Field::NameFromGetter(name));
1461 function = cls.LookupFunction(method_name);
1462 if (function != Function::null()) {
1463 function =
1464 Function::Handle(Z, function).CreateMethodExtractor(name);
1465 if (function != Function::null()) {
1466 return function;
1467 }
1468 }
1469 }
1470#if !defined(PRODUCT)
1471 ASSERT(Isolate::Current()->HasAttemptedReload());
1472 const String& msg = String::Handle(
1473 Z, String::NewFormatted("Unable to find function %s in %s",
1474 name.ToCString(), cls.ToCString()));
1475 Report::LongJump(LanguageError::Handle(Z, LanguageError::New(msg)));
1476#else
1477 FATAL2("Unable to find function %s in %s", name.ToCString(),
1478 cls.ToCString());
1479#endif
1480 }
1481 return function;
1482 }
1483 }
1484 case kClosure: {
1485 ReadObject(); // Skip enclosing member.
1486 const intptr_t closure_index = reader_.ReadUInt();
1487 return closures_->At(closure_index);
1488 }
1489 case kName: {
1490 if ((flags & kFlagIsPublic) == 0) {
1491 const Library& library = Library::CheckedHandle(Z, ReadObject());
1492 ASSERT(!library.IsNull());
1493 auto& name = String::Handle(Z, ReadString(/* is_canonical = */ false));
1494 name = library.PrivateName(name);
1495 if (I->obfuscate()) {
1496 const auto& library_key = String::Handle(Z, library.private_key());
1497 Obfuscator obfuscator(thread_, library_key);
1498 return obfuscator.Rename(name);
1499 }
1500 return name.raw();
1501 }
1502 if (I->obfuscate()) {
1503 Obfuscator obfuscator(thread_, Object::null_string());
1504 const auto& name = String::Handle(Z, ReadString());
1505 return obfuscator.Rename(name);
1506 } else {
1507 return ReadString();
1508 }
1509 }
1510 case kTypeArguments: {
1511 return ReadTypeArguments();
1512 }
1513 case kConstObject: {
1514 const intptr_t tag = flags / kFlagBit0;
1515 return ReadConstObject(tag);
1516 }
1517 case kArgDesc: {
1518 const intptr_t num_arguments = reader_.ReadUInt();
1519 const intptr_t num_type_args =
1520 ((flags & kFlagHasTypeArgs) != 0) ? reader_.ReadUInt() : 0;
1521 if ((flags & kFlagHasNamedArgs) == 0) {
1522 return ArgumentsDescriptor::NewBoxed(num_type_args, num_arguments);
1523 } else {
1524 const intptr_t num_arg_names = reader_.ReadListLength();
1525 const Array& array = Array::Handle(Z, Array::New(num_arg_names));
1526 String& name = String::Handle(Z);
1527 for (intptr_t i = 0; i < num_arg_names; ++i) {
1528 name ^= ReadObject();
1529 array.SetAt(i, name);
1530 }
1531 return ArgumentsDescriptor::NewBoxed(num_type_args, num_arguments,
1532 array);
1533 }
1534 }
1535 case kScript: {
1536 const String& uri = String::CheckedHandle(Z, ReadObject());
1537 Script& script = Script::Handle(Z);
1538 if ((flags & kFlagHasSourceFile) != 0) {
1539 // TODO(alexmarkov): read source and line starts only when needed.
1540 script =
1541 ReadSourceFile(uri, bytecode_component_->GetSourceFilesOffset() +
1542 reader_.ReadUInt());
1543 } else {
1544 script = Script::New(uri, Object::null_string());
1545 }
1546 script.set_kernel_program_info(H.GetKernelProgramInfo());
1547 return script.raw();
1548 }
1549 case kType: {
1550 const intptr_t tag = (flags & kTagMask) / kFlagBit0;
1551 const Nullability nullability =
1552 Reader::ConvertNullability(static_cast<KernelNullability>(
1553 (flags & kNullabilityMask) / kFlagBit4));
1554 return ReadType(tag, nullability);
1555 }
1556 default:
1557 UNREACHABLE();
1558 }
1559
1560 return Object::null();
1561}
1562
1563ObjectPtr BytecodeReaderHelper::ReadConstObject(intptr_t tag) {
1564 // Must be in sync with enum ConstTag in
1565 // pkg/vm/lib/bytecode/object_table.dart.
1566 enum ConstTag {
1567 kInvalid,
1568 kInstance,
1569 kInt,
1570 kDouble,
1571 kList,
1572 kTearOff,
1573 kBool,
1574 kSymbol,
1575 kTearOffInstantiation,
1576 kString,
1577 };
1578
1579 switch (tag) {
1580 case kInvalid:
1581 UNREACHABLE();
1582 break;
1583 case kInstance: {
1584 const Type& type = Type::CheckedHandle(Z, ReadObject());
1585 const Class& cls = Class::Handle(Z, type.type_class());
1586 const Instance& obj = Instance::Handle(Z, Instance::New(cls, Heap::kOld));
1587 if (type.arguments() != TypeArguments::null()) {
1588 const TypeArguments& type_args =
1589 TypeArguments::Handle(Z, type.arguments());
1590 obj.SetTypeArguments(type_args);
1591 }
1592 const intptr_t num_fields = reader_.ReadUInt();
1593 Field& field = Field::Handle(Z);
1594 Object& value = Object::Handle(Z);
1595 for (intptr_t i = 0; i < num_fields; ++i) {
1596 field ^= ReadObject();
1597 value = ReadObject();
1598 obj.SetField(field, value);
1599 }
1600 return H.Canonicalize(obj);
1601 }
1602 case kInt: {
1603 const int64_t value = reader_.ReadSLEB128AsInt64();
1604 if (Smi::IsValid(value)) {
1605 return Smi::New(static_cast<intptr_t>(value));
1606 }
1607 const Integer& obj = Integer::Handle(Z, Integer::New(value, Heap::kOld));
1608 return H.Canonicalize(obj);
1609 }
1610 case kDouble: {
1611 const int64_t bits = reader_.ReadSLEB128AsInt64();
1612 double value = bit_cast<double, int64_t>(bits);
1613 const Double& obj = Double::Handle(Z, Double::New(value, Heap::kOld));
1614 return H.Canonicalize(obj);
1615 }
1616 case kList: {
1617 const AbstractType& elem_type =
1618 AbstractType::CheckedHandle(Z, ReadObject());
1619 const intptr_t length = reader_.ReadUInt();
1620 const Array& array = Array::Handle(Z, Array::New(length, elem_type));
1621 Object& value = Object::Handle(Z);
1622 for (intptr_t i = 0; i < length; ++i) {
1623 value = ReadObject();
1624 array.SetAt(i, value);
1625 }
1626 array.MakeImmutable();
1627 return H.Canonicalize(array);
1628 }
1629 case kTearOff: {
1630 Object& obj = Object::Handle(Z, ReadObject());
1631 ASSERT(obj.IsFunction());
1632 obj = Function::Cast(obj).ImplicitClosureFunction();
1633 ASSERT(obj.IsFunction());
1634 obj = Function::Cast(obj).ImplicitStaticClosure();
1635 ASSERT(obj.IsInstance());
1636 return H.Canonicalize(Instance::Cast(obj));
1637 }
1638 case kBool: {
1639 bool is_true = reader_.ReadByte() != 0;
1640 return is_true ? Bool::True().raw() : Bool::False().raw();
1641 }
1642 case kSymbol: {
1643 const String& name = String::CheckedHandle(Z, ReadObject());
1644 ASSERT(name.IsSymbol());
1645 const Library& library = Library::Handle(Z, Library::InternalLibrary());
1646 ASSERT(!library.IsNull());
1647 const Class& cls =
1648 Class::Handle(Z, library.LookupClass(Symbols::Symbol()));
1649 ASSERT(!cls.IsNull());
1650 const Field& field = Field::Handle(
1651 Z, cls.LookupInstanceFieldAllowPrivate(Symbols::_name()));
1652 ASSERT(!field.IsNull());
1653 const Instance& obj = Instance::Handle(Z, Instance::New(cls, Heap::kOld));
1654 obj.SetField(field, name);
1655 return H.Canonicalize(obj);
1656 }
1657 case kTearOffInstantiation: {
1658 Closure& closure = Closure::CheckedHandle(Z, ReadObject());
1659 const TypeArguments& type_args =
1660 TypeArguments::CheckedHandle(Z, ReadObject());
1661 closure = Closure::New(
1662 TypeArguments::Handle(Z, closure.instantiator_type_arguments()),
1663 TypeArguments::Handle(Z, closure.function_type_arguments()),
1664 type_args, Function::Handle(Z, closure.function()),
1665 Context::Handle(Z, closure.context()), Heap::kOld);
1666 return H.Canonicalize(closure);
1667 }
1668 case kString:
1669 return ReadString();
1670 default:
1671 UNREACHABLE();
1672 }
1673 return Object::null();
1674}
1675
1676ObjectPtr BytecodeReaderHelper::ReadType(intptr_t tag,
1677 Nullability nullability) {
1678 // Must be in sync with enum TypeTag in
1679 // pkg/vm/lib/bytecode/object_table.dart.
1680 enum TypeTag {
1681 kInvalid,
1682 kDynamic,
1683 kVoid,
1684 kSimpleType,
1685 kTypeParameter,
1686 kGenericType,
1687 kRecursiveGenericType,
1688 kRecursiveTypeRef,
1689 kFunctionType,
1690 kNever,
1691 };
1692
1693 // FunctionType flags, must be in sync with _FunctionTypeHandle constants in
1694 // pkg/vm/lib/bytecode/object_table.dart.
1695 const int kFlagHasOptionalPositionalParams = 1 << 0;
1696 const int kFlagHasOptionalNamedParams = 1 << 1;
1697 const int kFlagHasTypeParams = 1 << 2;
1698
1699 switch (tag) {
1700 case kInvalid:
1701 UNREACHABLE();
1702 break;
1703 case kDynamic:
1704 return AbstractType::dynamic_type().raw();
1705 case kVoid:
1706 return AbstractType::void_type().raw();
1707 case kNever:
1708 return Type::Handle(Z, Type::NeverType())
1709 .ToNullability(nullability, Heap::kOld);
1710 case kSimpleType: {
1711 const Class& cls = Class::CheckedHandle(Z, ReadObject());
1712 if (!cls.is_declaration_loaded()) {
1713 LoadReferencedClass(cls);
1714 }
1715 const Type& type = Type::Handle(Z, cls.DeclarationType());
1716 return type.ToNullability(nullability, Heap::kOld);
1717 }
1718 case kTypeParameter: {
1719 Object& parent = Object::Handle(Z, ReadObject());
1720 const intptr_t index_in_parent = reader_.ReadUInt();
1721 TypeArguments& type_parameters = TypeArguments::Handle(Z);
1722 if (parent.IsClass()) {
1723 type_parameters = Class::Cast(parent).type_parameters();
1724 } else if (parent.IsFunction()) {
1725 if (Function::Cast(parent).IsFactory()) {
1726 // For factory constructors VM uses type parameters of a class
1727 // instead of constructor's type parameters.
1728 parent = Function::Cast(parent).Owner();
1729 type_parameters = Class::Cast(parent).type_parameters();
1730 } else {
1731 type_parameters = Function::Cast(parent).type_parameters();
1732 }
1733 } else if (parent.IsNull()) {
1734 ASSERT(function_type_type_parameters_ != nullptr);
1735 type_parameters = function_type_type_parameters_->raw();
1736 } else {
1737 UNREACHABLE();
1738 }
1739 TypeParameter& type_parameter = TypeParameter::Handle(Z);
1740 type_parameter ^= type_parameters.TypeAt(index_in_parent);
1741 if (type_parameter.bound() == AbstractType::null()) {
1742 AbstractType& derived = AbstractType::Handle(
1743 Z, type_parameter.ToNullability(nullability, Heap::kOld));
1744 active_class_->RecordDerivedTypeParameter(Z, type_parameter,
1745 TypeParameter::Cast(derived));
1746 return derived.raw();
1747 }
1748 return type_parameter.ToNullability(nullability, Heap::kOld);
1749 }
1750 case kGenericType: {
1751 const Class& cls = Class::CheckedHandle(Z, ReadObject());
1752 if (!cls.is_declaration_loaded()) {
1753 LoadReferencedClass(cls);
1754 }
1755 const TypeArguments& type_arguments =
1756 TypeArguments::CheckedHandle(Z, ReadObject());
1757 const Type& type =
1758 Type::Handle(Z, Type::New(cls, type_arguments,
1759 TokenPosition::kNoSource, nullability));
1760 type.SetIsFinalized();
1761 return type.Canonicalize();
1762 }
1763 case kRecursiveGenericType: {
1764 const intptr_t id = reader_.ReadUInt();
1765 const Class& cls = Class::CheckedHandle(Z, ReadObject());
1766 if (!cls.is_declaration_loaded()) {
1767 LoadReferencedClass(cls);
1768 }
1769 const auto saved_pending_recursive_types = pending_recursive_types_;
1770 if (id == 0) {
1771 pending_recursive_types_ = &GrowableObjectArray::Handle(
1772 Z, GrowableObjectArray::New(Heap::kOld));
1773 }
1774 ASSERT(id == pending_recursive_types_->Length());
1775 const auto& type_ref =
1776 TypeRef::Handle(Z, TypeRef::New(AbstractType::null_abstract_type()));
1777 pending_recursive_types_->Add(type_ref);
1778
1779 reading_type_arguments_of_recursive_type_ = true;
1780 const TypeArguments& type_arguments =
1781 TypeArguments::CheckedHandle(Z, ReadObject());
1782 reading_type_arguments_of_recursive_type_ = false;
1783
1784 ASSERT(id == pending_recursive_types_->Length() - 1);
1785 ASSERT(pending_recursive_types_->At(id) == type_ref.raw());
1786 pending_recursive_types_->SetLength(id);
1787 pending_recursive_types_ = saved_pending_recursive_types;
1788
1789 Type& type =
1790 Type::Handle(Z, Type::New(cls, type_arguments,
1791 TokenPosition::kNoSource, nullability));
1792 type_ref.set_type(type);
1793 type.SetIsFinalized();
1794 if (id != 0) {
1795 // Do not canonicalize non-root recursive types
1796 // as not all TypeRef objects are filled up at this point.
1797 return type.raw();
1798 }
1799 return type.Canonicalize();
1800 }
1801 case kRecursiveTypeRef: {
1802 const intptr_t id = reader_.ReadUInt();
1803 ASSERT(pending_recursive_types_ != nullptr);
1804 ASSERT(pending_recursive_types_->Length() >= id);
1805 return pending_recursive_types_->At(id);
1806 }
1807 case kFunctionType: {
1808 const intptr_t flags = reader_.ReadUInt();
1809 Function& signature_function = Function::ZoneHandle(
1810 Z, Function::NewSignatureFunction(*active_class_->klass,
1811 active_class_->enclosing != NULL
1812 ? *active_class_->enclosing
1813 : Function::null_function(),
1814 TokenPosition::kNoSource));
1815
1816 // This scope is needed to set active_class_->enclosing_ which is used to
1817 // assign parent function for function types.
1818 ActiveEnclosingFunctionScope active_enclosing_function(
1819 active_class_, &signature_function);
1820
1821 // TODO(alexmarkov): skip type finalization
1822 return ReadFunctionSignature(
1823 signature_function, (flags & kFlagHasOptionalPositionalParams) != 0,
1824 (flags & kFlagHasOptionalNamedParams) != 0,
1825 (flags & kFlagHasTypeParams) != 0,
1826 /* has_positional_param_names = */ false,
1827 /* has_parameter_flags */ false, nullability);
1828 }
1829 default:
1830 UNREACHABLE();
1831 }
1832 return Object::null();
1833}
1834
1835StringPtr BytecodeReaderHelper::ReadString(bool is_canonical) {
1836 const int kFlagTwoByteString = 1;
1837 const int kHeaderFields = 2;
1838 const int kUInt32Size = 4;
1839
1840 uint32_t ref = reader_.ReadUInt();
1841 const bool isOneByteString = (ref & kFlagTwoByteString) == 0;
1842 intptr_t index = ref >> 1;
1843
1844 if (!isOneByteString) {
1845 const uint32_t num_one_byte_strings =
1846 reader_.ReadUInt32At(bytecode_component_->GetStringsHeaderOffset());
1847 index += num_one_byte_strings;
1848 }
1849
1850 AlternativeReadingScope alt(&reader_,
1851 bytecode_component_->GetStringsHeaderOffset() +
1852 (kHeaderFields + index - 1) * kUInt32Size);
1853 intptr_t start_offs = reader_.ReadUInt32();
1854 intptr_t end_offs = reader_.ReadUInt32();
1855 if (index == 0) {
1856 // For the 0-th string we read a header field instead of end offset of
1857 // the previous string.
1858 start_offs = 0;
1859 }
1860
1861 // Bytecode strings reside in ExternalTypedData which is not movable by GC,
1862 // so it is OK to take a direct pointer to string characters even if
1863 // symbol allocation triggers GC.
1864 const uint8_t* data = reader_.BufferAt(
1865 bytecode_component_->GetStringsContentsOffset() + start_offs);
1866
1867 if (is_canonical) {
1868 if (isOneByteString) {
1869 return Symbols::FromLatin1(thread_, data, end_offs - start_offs);
1870 } else {
1871 return Symbols::FromUTF16(thread_,
1872 reinterpret_cast<const uint16_t*>(data),
1873 (end_offs - start_offs) >> 1);
1874 }
1875 } else {
1876 if (isOneByteString) {
1877 return String::FromLatin1(data, end_offs - start_offs, Heap::kOld);
1878 } else {
1879 return String::FromUTF16(reinterpret_cast<const uint16_t*>(data),
1880 (end_offs - start_offs) >> 1, Heap::kOld);
1881 }
1882 }
1883}
1884
1885ScriptPtr BytecodeReaderHelper::ReadSourceFile(const String& uri,
1886 intptr_t offset) {
1887 // SourceFile flags, must be in sync with SourceFile constants in
1888 // pkg/vm/lib/bytecode/declarations.dart.
1889 const int kHasLineStartsFlag = 1 << 0;
1890 const int kHasSourceFlag = 1 << 1;
1891
1892 AlternativeReadingScope alt(&reader_, offset);
1893
1894 const intptr_t flags = reader_.ReadUInt();
1895 const String& import_uri = String::CheckedHandle(Z, ReadObject());
1896
1897 TypedData& line_starts = TypedData::Handle(Z);
1898 if ((flags & kHasLineStartsFlag) != 0) {
1899 // TODO(alexmarkov): read line starts only when needed.
1900 const intptr_t line_starts_offset =
1901 bytecode_component_->GetLineStartsOffset() + reader_.ReadUInt();
1902
1903 AlternativeReadingScope alt(&reader_, line_starts_offset);
1904
1905 const intptr_t num_line_starts = reader_.ReadUInt();
1906 line_starts = reader_.ReadLineStartsData(num_line_starts);
1907 }
1908
1909 String& source = String::Handle(Z);
1910 if ((flags & kHasSourceFlag) != 0) {
1911 source = ReadString(/* is_canonical = */ false);
1912 }
1913
1914 const Script& script =
1915 Script::Handle(Z, Script::New(import_uri, uri, source));
1916 script.set_line_starts(line_starts);
1917
1918 if (source.IsNull() && line_starts.IsNull()) {
1919 // This script provides a uri only, but no source or line_starts array.
1920 // This could be a reference to a Script in another kernel binary.
1921 // Make an attempt to find source and line starts when needed.
1922 script.SetLazyLookupSourceAndLineStarts(true);
1923 }
1924
1925 return script.raw();
1926}
1927
1928TypeArgumentsPtr BytecodeReaderHelper::ReadTypeArguments() {
1929 const bool is_recursive = reading_type_arguments_of_recursive_type_;
1930 reading_type_arguments_of_recursive_type_ = false;
1931 const intptr_t length = reader_.ReadUInt();
1932 TypeArguments& type_arguments =
1933 TypeArguments::ZoneHandle(Z, TypeArguments::New(length));
1934 AbstractType& type = AbstractType::Handle(Z);
1935 for (intptr_t i = 0; i < length; ++i) {
1936 type ^= ReadObject();
1937 type_arguments.SetTypeAt(i, type);
1938 }
1939 if (is_recursive) {
1940 // Avoid canonicalization of type arguments of recursive type
1941 // as not all TypeRef objects are filled up at this point.
1942 // Type arguments will be canoncialized when the root recursive
1943 // type is canonicalized.
1944 ASSERT(pending_recursive_types_ != nullptr);
1945 return type_arguments.raw();
1946 }
1947 return type_arguments.Canonicalize();
1948}
1949
1950void BytecodeReaderHelper::ReadAttributes(const Object& key) {
1951 ASSERT(key.IsFunction() || key.IsField());
1952 const auto& value = Object::Handle(Z, ReadObject());
1953
1954 Array& attributes =
1955 Array::Handle(Z, I->object_store()->bytecode_attributes());
1956 if (attributes.IsNull()) {
1957 attributes = HashTables::New<BytecodeAttributesMap>(16, Heap::kOld);
1958 }
1959 BytecodeAttributesMap map(attributes.raw());
1960 bool present = map.UpdateOrInsert(key, value);
1961 ASSERT(!present);
1962 I->object_store()->set_bytecode_attributes(map.Release());
1963
1964 if (key.IsField()) {
1965 const Field& field = Field::Cast(key);
1966 const auto& inferred_type_attr =
1967 Array::CheckedHandle(Z, BytecodeReader::GetBytecodeAttribute(
1968 key, Symbols::vm_inferred_type_metadata()));
1969
1970 if (!inferred_type_attr.IsNull() &&
1971 (InferredTypeBytecodeAttribute::GetPCAt(inferred_type_attr, 0) ==
1972 InferredTypeBytecodeAttribute::kFieldTypePC)) {
1973 const InferredTypeMetadata type =
1974 InferredTypeBytecodeAttribute::GetInferredTypeAt(
1975 Z, inferred_type_attr, 0);
1976 if (!type.IsTrivial()) {
1977 field.set_guarded_cid(type.cid);
1978 field.set_is_nullable(type.IsNullable());
1979 field.set_guarded_list_length(Field::kNoFixedLength);
1980 }
1981 }
1982 }
1983}
1984
1985void BytecodeReaderHelper::ReadMembers(const Class& cls, bool discard_fields) {
1986 ASSERT(Thread::Current()->IsMutatorThread());
1987 ASSERT(cls.is_type_finalized());
1988 ASSERT(!cls.is_loaded());
1989
1990 const intptr_t num_functions = reader_.ReadUInt();
1991 functions_ = &Array::Handle(Z, Array::New(num_functions, Heap::kOld));
1992 function_index_ = 0;
1993
1994 ReadFieldDeclarations(cls, discard_fields);
1995 ReadFunctionDeclarations(cls);
1996
1997 cls.set_is_loaded(true);
1998}
1999
2000void BytecodeReaderHelper::ReadFieldDeclarations(const Class& cls,
2001 bool discard_fields) {
2002 // Field flags, must be in sync with FieldDeclaration constants in
2003 // pkg/vm/lib/bytecode/declarations.dart.
2004 const int kHasNontrivialInitializerFlag = 1 << 0;
2005 const int kHasGetterFlag = 1 << 1;
2006 const int kHasSetterFlag = 1 << 2;
2007 const int kIsReflectableFlag = 1 << 3;
2008 const int kIsStaticFlag = 1 << 4;
2009 const int kIsConstFlag = 1 << 5;
2010 const int kIsFinalFlag = 1 << 6;
2011 const int kIsCovariantFlag = 1 << 7;
2012 const int kIsGenericCovariantImplFlag = 1 << 8;
2013 const int kHasSourcePositionsFlag = 1 << 9;
2014 const int kHasAnnotationsFlag = 1 << 10;
2015 const int kHasPragmaFlag = 1 << 11;
2016 const int kHasCustomScriptFlag = 1 << 12;
2017 const int kHasInitializerCodeFlag = 1 << 13;
2018 const int kHasAttributesFlag = 1 << 14;
2019 const int kIsLateFlag = 1 << 15;
2020 const int kIsExtensionMemberFlag = 1 << 16;
2021 const int kHasInitializerFlag = 1 << 17;
2022
2023 const int num_fields = reader_.ReadListLength();
2024 if ((num_fields == 0) && !cls.is_enum_class()) {
2025 return;
2026 }
2027 const Array& fields = Array::Handle(
2028 Z, Array::New(num_fields + (cls.is_enum_class() ? 1 : 0), Heap::kOld));
2029 String& name = String::Handle(Z);
2030 Object& script_class = Object::Handle(Z);
2031 AbstractType& type = AbstractType::Handle(Z);
2032 Field& field = Field::Handle(Z);
2033 Instance& value = Instance::Handle(Z);
2034 Function& function = Function::Handle(Z);
2035
2036 for (intptr_t i = 0; i < num_fields; ++i) {
2037 intptr_t flags = reader_.ReadUInt();
2038
2039 const bool is_static = (flags & kIsStaticFlag) != 0;
2040 const bool is_final = (flags & kIsFinalFlag) != 0;
2041 const bool is_const = (flags & kIsConstFlag) != 0;
2042 const bool is_late = (flags & kIsLateFlag) != 0;
2043 const bool has_nontrivial_initializer =
2044 (flags & kHasNontrivialInitializerFlag) != 0;
2045 const bool has_pragma = (flags & kHasPragmaFlag) != 0;
2046 const bool is_extension_member = (flags & kIsExtensionMemberFlag) != 0;
2047 const bool has_initializer = (flags & kHasInitializerFlag) != 0;
2048
2049 name ^= ReadObject();
2050 type ^= ReadObject();
2051
2052 if ((flags & kHasCustomScriptFlag) != 0) {
2053 Script& script = Script::CheckedHandle(Z, ReadObject());
2054 script_class = GetPatchClass(cls, script);
2055 } else {
2056 script_class = cls.raw();
2057 }
2058
2059 TokenPosition position = TokenPosition::kNoSource;
2060 TokenPosition end_position = TokenPosition::kNoSource;
2061 if ((flags & kHasSourcePositionsFlag) != 0) {
2062 position = reader_.ReadPosition();
2063 end_position = reader_.ReadPosition();
2064 }
2065
2066 field = Field::New(name, is_static, is_final, is_const,
2067 (flags & kIsReflectableFlag) != 0, is_late, script_class,
2068 type, position, end_position);
2069
2070 field.set_is_declared_in_bytecode(true);
2071 field.set_has_pragma(has_pragma);
2072 field.set_is_covariant((flags & kIsCovariantFlag) != 0);
2073 field.set_is_generic_covariant_impl((flags & kIsGenericCovariantImplFlag) !=
2074 0);
2075 field.set_has_nontrivial_initializer(has_nontrivial_initializer);
2076 field.set_is_extension_member(is_extension_member);
2077 field.set_has_initializer(has_initializer);
2078
2079 if (!has_nontrivial_initializer) {
2080 value ^= ReadObject();
2081 if (is_static) {
2082 if (field.is_late() && !has_initializer) {
2083 field.SetStaticValue(Object::sentinel(), true);
2084 } else {
2085 field.SetStaticValue(value, true);
2086 }
2087 } else {
2088 field.set_saved_initial_value(value);
2089 // Null-initialized instance fields are tracked separately for each
2090 // constructor (see handling of kHasNullableFieldsFlag).
2091 if (!value.IsNull()) {
2092 // Note: optimizer relies on DoubleInitialized bit in its
2093 // field-unboxing heuristics.
2094 // See JitCallSpecializer::VisitStoreInstanceField for more details.
2095 field.RecordStore(value);
2096 if (value.IsDouble()) {
2097 field.set_is_double_initialized(true);
2098 }
2099 }
2100 }
2101 }
2102
2103 if ((flags & kHasInitializerCodeFlag) != 0) {
2104 const intptr_t code_offset = reader_.ReadUInt();
2105 field.set_bytecode_offset(code_offset +
2106 bytecode_component_->GetCodesOffset());
2107 if (is_static) {
2108 field.SetStaticValue(Object::sentinel(), true);
2109 }
2110 }
2111
2112 if ((flags & kHasGetterFlag) != 0) {
2113 name ^= ReadObject();
2114 function = Function::New(name,
2115 is_static ? FunctionLayout::kImplicitStaticGetter
2116 : FunctionLayout::kImplicitGetter,
2117 is_static, is_const,
2118 false, // is_abstract
2119 false, // is_external
2120 false, // is_native
2121 script_class, position);
2122 function.set_end_token_pos(end_position);
2123 function.set_result_type(type);
2124 function.set_is_debuggable(false);
2125 function.set_accessor_field(field);
2126 function.set_is_declared_in_bytecode(true);
2127 function.set_is_extension_member(is_extension_member);
2128 if (is_const && has_nontrivial_initializer) {
2129 function.set_bytecode_offset(field.bytecode_offset());
2130 }
2131 H.SetupFieldAccessorFunction(cls, function, type);
2132 functions_->SetAt(function_index_++, function);
2133 }
2134
2135 if ((flags & kHasSetterFlag) != 0) {
2136 ASSERT(is_late || ((!is_static) && (!is_final)));
2137 ASSERT(!is_const);
2138 name ^= ReadObject();
2139 function = Function::New(name, FunctionLayout::kImplicitSetter, is_static,
2140 false, // is_const
2141 false, // is_abstract
2142 false, // is_external
2143 false, // is_native
2144 script_class, position);
2145 function.set_end_token_pos(end_position);
2146 function.set_result_type(Object::void_type());
2147 function.set_is_debuggable(false);
2148 function.set_accessor_field(field);
2149 function.set_is_declared_in_bytecode(true);
2150 function.set_is_extension_member(is_extension_member);
2151 H.SetupFieldAccessorFunction(cls, function, type);
2152 functions_->SetAt(function_index_++, function);
2153 }
2154
2155 if ((flags & kHasAnnotationsFlag) != 0) {
2156 intptr_t annotations_offset =
2157 reader_.ReadUInt() + bytecode_component_->GetAnnotationsOffset();
2158 ASSERT(annotations_offset > 0);
2159
2160 if (FLAG_enable_mirrors || has_pragma) {
2161 Library& library = Library::Handle(Z, cls.library());
2162 library.AddFieldMetadata(field, TokenPosition::kNoSource, 0,
2163 annotations_offset);
2164 if (has_pragma) {
2165 // TODO(alexmarkov): read annotations right away using
2166 // annotations_offset.
2167 NoOOBMessageScope no_msg_scope(thread_);
2168 NoReloadScope no_reload_scope(thread_->isolate(), thread_);
2169 library.GetMetadata(field);
2170 }
2171 }
2172 }
2173
2174 if ((flags & kHasAttributesFlag) != 0) {
2175 ReadAttributes(field);
2176 }
2177
2178 fields.SetAt(i, field);
2179 }
2180
2181 if (cls.is_enum_class()) {
2182 // Add static field 'const _deleted_enum_sentinel'.
2183 field = Field::New(Symbols::_DeletedEnumSentinel(),
2184 /* is_static = */ true,
2185 /* is_final = */ true,
2186 /* is_const = */ true,
2187 /* is_reflectable = */ false,
2188 /* is_late = */ false, cls, Object::dynamic_type(),
2189 TokenPosition::kNoSource, TokenPosition::kNoSource);
2190
2191 fields.SetAt(num_fields, field);
2192 }
2193
2194 if (!discard_fields) {
2195 cls.SetFields(fields);
2196 }
2197
2198 if (cls.IsTopLevel()) {
2199 const Library& library = Library::Handle(Z, cls.library());
2200 for (intptr_t i = 0, n = fields.Length(); i < n; ++i) {
2201 field ^= fields.At(i);
2202 name = field.name();
2203 library.AddObject(field, name);
2204 }
2205 }
2206}
2207
2208PatchClassPtr BytecodeReaderHelper::GetPatchClass(const Class& cls,
2209 const Script& script) {
2210 if (patch_class_ != nullptr && patch_class_->patched_class() == cls.raw() &&
2211 patch_class_->script() == script.raw()) {
2212 return patch_class_->raw();
2213 }
2214 if (patch_class_ == nullptr) {
2215 patch_class_ = &PatchClass::Handle(Z);
2216 }
2217 *patch_class_ = PatchClass::New(cls, script);
2218 return patch_class_->raw();
2219}
2220
2221void BytecodeReaderHelper::ReadFunctionDeclarations(const Class& cls) {
2222 // Function flags, must be in sync with FunctionDeclaration constants in
2223 // pkg/vm/lib/bytecode/declarations.dart.
2224 const int kIsConstructorFlag = 1 << 0;
2225 const int kIsGetterFlag = 1 << 1;
2226 const int kIsSetterFlag = 1 << 2;
2227 const int kIsFactoryFlag = 1 << 3;
2228 const int kIsStaticFlag = 1 << 4;
2229 const int kIsAbstractFlag = 1 << 5;
2230 const int kIsConstFlag = 1 << 6;
2231 const int kHasOptionalPositionalParamsFlag = 1 << 7;
2232 const int kHasOptionalNamedParamsFlag = 1 << 8;
2233 const int kHasTypeParamsFlag = 1 << 9;
2234 const int kIsReflectableFlag = 1 << 10;
2235 const int kIsDebuggableFlag = 1 << 11;
2236 const int kIsAsyncFlag = 1 << 12;
2237 const int kIsAsyncStarFlag = 1 << 13;
2238 const int kIsSyncStarFlag = 1 << 14;
2239 // const int kIsForwardingStubFlag = 1 << 15;
2240 const int kIsNoSuchMethodForwarderFlag = 1 << 16;
2241 const int kIsNativeFlag = 1 << 17;
2242 const int kIsExternalFlag = 1 << 18;
2243 const int kHasSourcePositionsFlag = 1 << 19;
2244 const int kHasAnnotationsFlag = 1 << 20;
2245 const int kHasPragmaFlag = 1 << 21;
2246 const int kHasCustomScriptFlag = 1 << 22;
2247 const int kHasAttributesFlag = 1 << 23;
2248 const int kIsExtensionMemberFlag = 1 << 24;
2249
2250 const intptr_t num_functions = reader_.ReadListLength();
2251 ASSERT(function_index_ + num_functions == functions_->Length());
2252
2253 if (function_index_ + num_functions == 0) {
2254 return;
2255 }
2256
2257 String& name = String::Handle(Z);
2258 Object& script_class = Object::Handle(Z);
2259 Function& function = Function::Handle(Z);
2260 Array& parameter_types = Array::Handle(Z);
2261 Array& parameter_names = Array::Handle(Z);
2262 AbstractType& type = AbstractType::Handle(Z);
2263
2264 name = cls.ScrubbedName();
2265 const bool is_async_await_completer_owner =
2266 Symbols::_AsyncAwaitCompleter().Equals(name);
2267
2268 for (intptr_t i = 0; i < num_functions; ++i) {
2269 intptr_t flags = reader_.ReadUInt();
2270
2271 const bool is_static = (flags & kIsStaticFlag) != 0;
2272 const bool is_factory = (flags & kIsFactoryFlag) != 0;
2273 const bool is_native = (flags & kIsNativeFlag) != 0;
2274 const bool has_pragma = (flags & kHasPragmaFlag) != 0;
2275 const bool is_extension_member = (flags & kIsExtensionMemberFlag) != 0;
2276
2277 name ^= ReadObject();
2278
2279 if ((flags & kHasCustomScriptFlag) != 0) {
2280 Script& script = Script::CheckedHandle(Z, ReadObject());
2281 script_class = GetPatchClass(cls, script);
2282 } else {
2283 script_class = cls.raw();
2284 }
2285
2286 TokenPosition position = TokenPosition::kNoSource;
2287 TokenPosition end_position = TokenPosition::kNoSource;
2288 if ((flags & kHasSourcePositionsFlag) != 0) {
2289 position = reader_.ReadPosition();
2290 end_position = reader_.ReadPosition();
2291 }
2292
2293 FunctionLayout::Kind kind = FunctionLayout::kRegularFunction;
2294 if ((flags & kIsGetterFlag) != 0) {
2295 kind = FunctionLayout::kGetterFunction;
2296 } else if ((flags & kIsSetterFlag) != 0) {
2297 kind = FunctionLayout::kSetterFunction;
2298 } else if ((flags & (kIsConstructorFlag | kIsFactoryFlag)) != 0) {
2299 kind = FunctionLayout::kConstructor;
2300 name = ConstructorName(cls, name);
2301 }
2302
2303 function = Function::New(name, kind, is_static, (flags & kIsConstFlag) != 0,
2304 (flags & kIsAbstractFlag) != 0,
2305 (flags & kIsExternalFlag) != 0, is_native,
2306 script_class, position);
2307
2308 const bool is_expression_evaluation =
2309 (name.raw() == Symbols::DebugProcedureName().raw());
2310
2311 // Declare function scope as types (type parameters) in function
2312 // signature may back-reference to the function being declared.
2313 // At this moment, owner class is not fully loaded yet and it won't be
2314 // able to serve function lookup requests.
2315 FunctionScope function_scope(this, function, name, cls);
2316
2317 function.set_is_declared_in_bytecode(true);
2318 function.set_has_pragma(has_pragma);
2319 function.set_end_token_pos(end_position);
2320 function.set_is_synthetic((flags & kIsNoSuchMethodForwarderFlag) != 0);
2321 function.set_is_reflectable((flags & kIsReflectableFlag) != 0);
2322 function.set_is_debuggable((flags & kIsDebuggableFlag) != 0);
2323 function.set_is_extension_member(is_extension_member);
2324
2325 // _AsyncAwaitCompleter.start should be made non-visible in stack traces,
2326 // since it is an implementation detail of our await/async desugaring.
2327 if (is_async_await_completer_owner &&
2328 Symbols::_AsyncAwaitStart().Equals(name)) {
2329 function.set_is_visible(!FLAG_causal_async_stacks &&
2330 !FLAG_lazy_async_stacks);
2331 }
2332
2333 if ((flags & kIsSyncStarFlag) != 0) {
2334 function.set_modifier(FunctionLayout::kSyncGen);
2335 function.set_is_visible(!FLAG_causal_async_stacks &&
2336 !FLAG_lazy_async_stacks);
2337 } else if ((flags & kIsAsyncFlag) != 0) {
2338 function.set_modifier(FunctionLayout::kAsync);
2339 function.set_is_inlinable(!FLAG_causal_async_stacks &&
2340 !FLAG_lazy_async_stacks);
2341 function.set_is_visible(!FLAG_causal_async_stacks &&
2342 !FLAG_lazy_async_stacks);
2343 } else if ((flags & kIsAsyncStarFlag) != 0) {
2344 function.set_modifier(FunctionLayout::kAsyncGen);
2345 function.set_is_inlinable(!FLAG_causal_async_stacks &&
2346 !FLAG_lazy_async_stacks);
2347 function.set_is_visible(!FLAG_causal_async_stacks &&
2348 !FLAG_lazy_async_stacks);
2349 }
2350
2351 if ((flags & kHasTypeParamsFlag) != 0) {
2352 ReadTypeParametersDeclaration(Class::Handle(Z), function);
2353 }
2354
2355 const intptr_t num_implicit_params = (!is_static || is_factory) ? 1 : 0;
2356 const intptr_t num_params = num_implicit_params + reader_.ReadUInt();
2357
2358 intptr_t num_required_params = num_params;
2359 if ((flags & (kHasOptionalPositionalParamsFlag |
2360 kHasOptionalNamedParamsFlag)) != 0) {
2361 num_required_params = num_implicit_params + reader_.ReadUInt();
2362 }
2363
2364 function.set_num_fixed_parameters(num_required_params);
2365 function.SetNumOptionalParameters(
2366 num_params - num_required_params,
2367 (flags & kHasOptionalNamedParamsFlag) == 0);
2368
2369 parameter_types = Array::New(num_params, Heap::kOld);
2370 function.set_parameter_types(parameter_types);
2371
2372 parameter_names = Array::New(
2373 Function::NameArrayLengthIncludingFlags(num_params), Heap::kOld);
2374 function.set_parameter_names(parameter_names);
2375
2376 intptr_t param_index = 0;
2377 if (!is_static) {
2378 if (is_expression_evaluation) {
2379 // Do not reference enclosing class as expression evaluation
2380 // method logically belongs to another (real) class.
2381 // Enclosing class is not registered and doesn't have
2382 // a valid cid, so it can't be used in a type.
2383 function.SetParameterTypeAt(param_index, AbstractType::dynamic_type());
2384 } else {
2385 function.SetParameterTypeAt(param_index, H.GetDeclarationType(cls));
2386 }
2387 function.SetParameterNameAt(param_index, Symbols::This());
2388 ++param_index;
2389 } else if (is_factory) {
2390 function.SetParameterTypeAt(param_index, AbstractType::dynamic_type());
2391 function.SetParameterNameAt(param_index,
2392 Symbols::TypeArgumentsParameter());
2393 ++param_index;
2394 }
2395
2396 for (; param_index < num_params; ++param_index) {
2397 name ^= ReadObject();
2398 parameter_names.SetAt(param_index, name);
2399 type ^= ReadObject();
2400 parameter_types.SetAt(param_index, type);
2401 }
2402
2403 type ^= ReadObject();
2404 function.set_result_type(type);
2405
2406 if (is_native) {
2407 name ^= ReadObject();
2408 function.set_native_name(name);
2409 }
2410
2411 if ((flags & kIsAbstractFlag) == 0) {
2412 const intptr_t code_offset = reader_.ReadUInt();
2413 function.set_bytecode_offset(code_offset +
2414 bytecode_component_->GetCodesOffset());
2415 }
2416
2417 if ((flags & kHasAnnotationsFlag) != 0) {
2418 const intptr_t annotations_offset =
2419 reader_.ReadUInt() + bytecode_component_->GetAnnotationsOffset();
2420 ASSERT(annotations_offset > 0);
2421
2422 if (FLAG_enable_mirrors || has_pragma) {
2423 Library& library = Library::Handle(Z, cls.library());
2424 library.AddFunctionMetadata(function, TokenPosition::kNoSource, 0,
2425 annotations_offset);
2426
2427 if (has_pragma) {
2428 if (H.constants().IsNull() &&
2429 library.raw() == Library::CoreLibrary()) {
2430 // Bootstrapping, need to postpone evaluation of pragma annotations
2431 // as classes are not fully loaded/finalized yet.
2432 const auto& pragma_funcs = GrowableObjectArray::Handle(
2433 Z, H.EnsurePotentialPragmaFunctions());
2434 pragma_funcs.Add(function);
2435 } else {
2436 // TODO(alexmarkov): read annotations right away using
2437 // annotations_offset.
2438 Thread* thread = H.thread();
2439 NoOOBMessageScope no_msg_scope(thread);
2440 NoReloadScope no_reload_scope(thread->isolate(), thread);
2441 library.GetMetadata(function);
2442 }
2443 }
2444 }
2445 }
2446
2447 if ((flags & kHasAttributesFlag) != 0) {
2448 ASSERT(!is_expression_evaluation);
2449 ReadAttributes(function);
2450 }
2451
2452 if (is_expression_evaluation) {
2453 H.SetExpressionEvaluationFunction(function);
2454 // Read bytecode of expression evaluation function eagerly,
2455 // while expression_evaluation_library_ and FunctionScope
2456 // are still set, as its constant pool may reference back to a library
2457 // or a function which are not registered and cannot be looked up.
2458 ASSERT(!function.is_abstract());
2459 ASSERT(function.bytecode_offset() != 0);
2460 // Replace class of the function in scope as we're going to look for
2461 // expression evaluation function in a real class.
2462 if (!cls.IsTopLevel()) {
2463 scoped_function_class_ = H.GetExpressionEvaluationRealClass();
2464 }
2465 CompilerState compiler_state(thread_, FLAG_precompiled_mode);
2466 ReadCode(function, function.bytecode_offset());
2467 }
2468
2469 functions_->SetAt(function_index_++, function);
2470 }
2471
2472 cls.SetFunctions(*functions_);
2473
2474 if (cls.IsTopLevel()) {
2475 const Library& library = Library::Handle(Z, cls.library());
2476 for (intptr_t i = 0, n = functions_->Length(); i < n; ++i) {
2477 function ^= functions_->At(i);
2478 name = function.name();
2479 library.AddObject(function, name);
2480 }
2481 }
2482
2483 functions_ = nullptr;
2484}
2485
2486void BytecodeReaderHelper::LoadReferencedClass(const Class& cls) {
2487 ASSERT(!cls.is_declaration_loaded());
2488
2489 if (!cls.is_declared_in_bytecode()) {
2490 cls.EnsureDeclarationLoaded();
2491 return;
2492 }
2493
2494 const auto& script = Script::Handle(Z, cls.script());
2495 if (H.GetKernelProgramInfo().raw() != script.kernel_program_info()) {
2496 // Class comes from a different binary.
2497 cls.EnsureDeclarationLoaded();
2498 return;
2499 }
2500
2501 // We can reuse current BytecodeReaderHelper.
2502 ActiveClassScope active_class_scope(active_class_, &cls);
2503 AlternativeReadingScope alt(&reader_, cls.bytecode_offset());
2504 ReadClassDeclaration(cls);
2505}
2506
2507void BytecodeReaderHelper::ReadClassDeclaration(const Class& cls) {
2508 // Class flags, must be in sync with ClassDeclaration constants in
2509 // pkg/vm/lib/bytecode/declarations.dart.
2510 const int kIsAbstractFlag = 1 << 0;
2511 const int kIsEnumFlag = 1 << 1;
2512 const int kHasTypeParamsFlag = 1 << 2;
2513 const int kHasTypeArgumentsFlag = 1 << 3;
2514 const int kIsTransformedMixinApplicationFlag = 1 << 4;
2515 const int kHasSourcePositionsFlag = 1 << 5;
2516 const int kHasAnnotationsFlag = 1 << 6;
2517 const int kHasPragmaFlag = 1 << 7;
2518
2519 // Class is allocated when reading library declaration in
2520 // BytecodeReaderHelper::ReadLibraryDeclaration.
2521 // Its cid is set in Class::New / Isolate::RegisterClass /
2522 // ClassTable::Register, unless it was loaded for expression evaluation.
2523 ASSERT(cls.is_declared_in_bytecode());
2524 ASSERT(!cls.is_declaration_loaded() || loading_native_wrappers_library_);
2525
2526 const intptr_t flags = reader_.ReadUInt();
2527 const bool has_pragma = (flags & kHasPragmaFlag) != 0;
2528
2529 // Set early to enable access to type_parameters().
2530 // TODO(alexmarkov): revise early stamping of native wrapper classes
2531 // as loaded.
2532 if (!cls.is_declaration_loaded()) {
2533 cls.set_is_declaration_loaded();
2534 }
2535
2536 const auto& script = Script::CheckedHandle(Z, ReadObject());
2537 cls.set_script(script);
2538
2539 TokenPosition position = TokenPosition::kNoSource;
2540 TokenPosition end_position = TokenPosition::kNoSource;
2541 if ((flags & kHasSourcePositionsFlag) != 0) {
2542 position = reader_.ReadPosition();
2543 end_position = reader_.ReadPosition();
2544 cls.set_token_pos(position);
2545 cls.set_end_token_pos(end_position);
2546 }
2547
2548 cls.set_has_pragma(has_pragma);
2549
2550 if ((flags & kIsAbstractFlag) != 0) {
2551 cls.set_is_abstract();
2552 }
2553 if ((flags & kIsEnumFlag) != 0) {
2554 cls.set_is_enum_class();
2555 }
2556 if ((flags & kIsTransformedMixinApplicationFlag) != 0) {
2557 cls.set_is_transformed_mixin_application();
2558 }
2559
2560 intptr_t num_type_arguments = 0;
2561 if ((flags & kHasTypeArgumentsFlag) != 0) {
2562 num_type_arguments = reader_.ReadUInt();
2563 }
2564 cls.set_num_type_arguments(num_type_arguments);
2565
2566 if ((flags & kHasTypeParamsFlag) != 0) {
2567 ReadTypeParametersDeclaration(cls, Function::null_function());
2568 }
2569
2570 auto& type = AbstractType::CheckedHandle(Z, ReadObject());
2571 cls.set_super_type(type);
2572
2573 const intptr_t num_interfaces = reader_.ReadUInt();
2574 if (num_interfaces > 0) {
2575 const auto& interfaces =
2576 Array::Handle(Z, Array::New(num_interfaces, Heap::kOld));
2577 for (intptr_t i = 0; i < num_interfaces; ++i) {
2578 type ^= ReadObject();
2579 interfaces.SetAt(i, type);
2580 }
2581 cls.set_interfaces(interfaces);
2582 }
2583
2584 if ((flags & kHasAnnotationsFlag) != 0) {
2585 intptr_t annotations_offset =
2586 reader_.ReadUInt() + bytecode_component_->GetAnnotationsOffset();
2587 ASSERT(annotations_offset > 0);
2588
2589 if (FLAG_enable_mirrors || has_pragma) {
2590 const auto& library = Library::Handle(Z, cls.library());
2591 if (cls.IsTopLevel()) {
2592 ASSERT(!has_pragma);
2593 library.AddLibraryMetadata(cls, TokenPosition::kNoSource, 0,
2594 annotations_offset);
2595 } else {
2596 const auto& top_level_class =
2597 Class::Handle(Z, library.toplevel_class());
2598
2599 library.AddClassMetadata(cls, top_level_class, TokenPosition::kNoSource,
2600 0, annotations_offset);
2601 }
2602 }
2603 }
2604
2605 const intptr_t members_offset = reader_.ReadUInt();
2606 cls.set_bytecode_offset(members_offset +
2607 bytecode_component_->GetMembersOffset());
2608
2609 // All types are finalized if loading from bytecode.
2610 // TODO(alexmarkov): revise early stamping of native wrapper classes
2611 // as type-finalized.
2612 if (!cls.is_type_finalized()) {
2613 cls.set_is_type_finalized();
2614 }
2615
2616 // Avoid registering expression evaluation class in a hierarchy, as
2617 // it doesn't have cid and shouldn't be found when enumerating subclasses.
2618 if (expression_evaluation_library_ == nullptr) {
2619 // TODO(alexmarkov): move this to class finalization.
2620 ClassFinalizer::RegisterClassInHierarchy(Z, cls);
2621 }
2622}
2623
2624void BytecodeReaderHelper::ReadLibraryDeclaration(const Library& library,
2625 bool lookup_classes) {
2626 // Library flags, must be in sync with LibraryDeclaration constants in
2627 // pkg/vm/lib/bytecode/declarations.dart.
2628 const int kUsesDartMirrorsFlag = 1 << 0;
2629 const int kUsesDartFfiFlag = 1 << 1;
2630 const int kHasExtensionsFlag = 1 << 2;
2631 const int kIsNonNullableByDefaultFlag = 1 << 3;
2632
2633 ASSERT(library.is_declared_in_bytecode());
2634 ASSERT(!library.Loaded());
2635 ASSERT(library.toplevel_class() == Object::null());
2636
2637 // TODO(alexmarkov): fill in library.used_scripts.
2638
2639 const intptr_t flags = reader_.ReadUInt();
2640 if (((flags & kUsesDartMirrorsFlag) != 0) && !FLAG_enable_mirrors) {
2641 H.ReportError(
2642 "import of dart:mirrors is not supported in the current Dart runtime");
2643 }
2644 if (((flags & kUsesDartFfiFlag) != 0) && !Api::IsFfiEnabled()) {
2645 H.ReportError(
2646 "import of dart:ffi is not supported in the current Dart runtime");
2647 }
2648
2649 auto& name = String::CheckedHandle(Z, ReadObject());
2650 library.SetName(name);
2651
2652 const auto& script = Script::CheckedHandle(Z, ReadObject());
2653
2654 if ((flags & kHasExtensionsFlag) != 0) {
2655 const intptr_t num_extensions = reader_.ReadUInt();
2656 auto& import_namespace = Namespace::Handle(Z);
2657 auto& native_library = Library::Handle(Z);
2658 for (intptr_t i = 0; i < num_extensions; ++i) {
2659 name ^= ReadObject();
2660 ASSERT(name.StartsWith(Symbols::DartExtensionScheme()));
2661
2662 // Create a dummy library and add it as an import to the current library.
2663 // Actual loading occurs in KernelLoader::LoadNativeExtensionLibraries().
2664 // This also allows later to discover and reload this native extension,
2665 // e.g. when running from an app-jit snapshot.
2666 // See Loader::ReloadNativeExtensions(...) which relies on
2667 // Dart_GetImportsOfScheme('dart-ext').
2668 native_library = Library::New(name);
2669 import_namespace = Namespace::New(native_library, Array::null_array(),
2670 Array::null_array());
2671 library.AddImport(import_namespace);
2672 }
2673 H.AddPotentialExtensionLibrary(library);
2674 }
2675
2676 if ((flags & kIsNonNullableByDefaultFlag) != 0) {
2677 library.set_is_nnbd(true);
2678 }
2679
2680 // The bootstrapper will take care of creating the native wrapper classes,
2681 // but we will add the synthetic constructors to them here.
2682 if (name.raw() ==
2683 Symbols::Symbol(Symbols::kDartNativeWrappersLibNameId).raw()) {
2684 ASSERT(library.LoadInProgress());
2685 loading_native_wrappers_library_ = true;
2686 } else {
2687 loading_native_wrappers_library_ = false;
2688 library.SetLoadInProgress();
2689 }
2690
2691 const bool register_class = !IsExpressionEvaluationLibrary(library);
2692
2693 const intptr_t num_classes = reader_.ReadUInt();
2694 ASSERT(num_classes > 0);
2695 auto& cls = Class::Handle(Z);
2696
2697 for (intptr_t i = 0; i < num_classes; ++i) {
2698 name ^= ReadObject();
2699 const intptr_t class_offset =
2700 bytecode_component_->GetClassesOffset() + reader_.ReadUInt();
2701
2702 if (i == 0) {
2703 ASSERT(name.raw() == Symbols::Empty().raw());
2704 cls = Class::New(library, Symbols::TopLevel(), script,
2705 TokenPosition::kNoSource, register_class);
2706 library.set_toplevel_class(cls);
2707 } else {
2708 if (lookup_classes) {
2709 cls = library.LookupLocalClass(name);
2710 }
2711 if (lookup_classes && !cls.IsNull()) {
2712 ASSERT(!cls.is_declaration_loaded() ||
2713 loading_native_wrappers_library_);
2714 cls.set_script(script);
2715 } else {
2716 cls = Class::New(library, name, script, TokenPosition::kNoSource,
2717 register_class);
2718 if (register_class) {
2719 library.AddClass(cls);
2720 }
2721 }
2722 }
2723
2724 cls.set_is_declared_in_bytecode(true);
2725 cls.set_bytecode_offset(class_offset);
2726
2727 if (loading_native_wrappers_library_ || !register_class) {
2728 AlternativeReadingScope alt(&reader_, class_offset);
2729 ReadClassDeclaration(cls);
2730 ActiveClassScope active_class_scope(active_class_, &cls);
2731 AlternativeReadingScope alt2(&reader_, cls.bytecode_offset());
2732 ReadMembers(cls, /* discard_fields = */ false);
2733 }
2734 }
2735
2736 ASSERT(!library.Loaded());
2737 library.SetLoaded();
2738
2739 loading_native_wrappers_library_ = false;
2740}
2741
2742void BytecodeReaderHelper::ReadLibraryDeclarations(intptr_t num_libraries) {
2743 auto& library = Library::Handle(Z);
2744 auto& uri = String::Handle(Z);
2745
2746 for (intptr_t i = 0; i < num_libraries; ++i) {
2747 uri ^= ReadObject();
2748 const intptr_t library_offset =
2749 bytecode_component_->GetLibrariesOffset() + reader_.ReadUInt();
2750
2751 if (!FLAG_precompiled_mode && !I->should_load_vmservice()) {
2752 if (uri.raw() == Symbols::DartVMServiceIO().raw()) {
2753 continue;
2754 }
2755 }
2756
2757 bool lookup_classes = true;
2758 library = Library::LookupLibrary(thread_, uri);
2759 if (library.IsNull()) {
2760 lookup_classes = false;
2761 library = Library::New(uri);
2762
2763 if (uri.raw() == Symbols::EvalSourceUri().raw()) {
2764 ASSERT(expression_evaluation_library_ == nullptr);
2765 expression_evaluation_library_ = &Library::Handle(Z, library.raw());
2766 } else {
2767 library.Register(thread_);
2768 }
2769 }
2770
2771 if (library.Loaded()) {
2772 continue;
2773 }
2774
2775 library.set_is_declared_in_bytecode(true);
2776 library.set_bytecode_offset(library_offset);
2777
2778 AlternativeReadingScope alt(&reader_, library_offset);
2779 ReadLibraryDeclaration(library, lookup_classes);
2780 }
2781}
2782
2783void BytecodeReaderHelper::FindAndReadSpecificLibrary(const Library& library,
2784 intptr_t num_libraries) {
2785 auto& uri = String::Handle(Z);
2786 for (intptr_t i = 0; i < num_libraries; ++i) {
2787 uri ^= ReadObject();
2788 const intptr_t library_offset =
2789 bytecode_component_->GetLibrariesOffset() + reader_.ReadUInt();
2790
2791 if (uri.raw() == library.url()) {
2792 library.set_is_declared_in_bytecode(true);
2793 library.set_bytecode_offset(library_offset);
2794
2795 AlternativeReadingScope alt(&reader_, library_offset);
2796 ReadLibraryDeclaration(library, /* lookup_classes = */ true);
2797 return;
2798 }
2799 }
2800}
2801
2802void BytecodeReaderHelper::FindModifiedLibrariesForHotReload(
2803 BitVector* modified_libs,
2804 intptr_t num_libraries) {
2805 auto& uri = String::Handle(Z);
2806 auto& lib = Library::Handle(Z);
2807 for (intptr_t i = 0; i < num_libraries; ++i) {
2808 uri ^= ReadObject();
2809 reader_.ReadUInt(); // Skip offset.
2810
2811 lib = Library::LookupLibrary(thread_, uri);
2812 if (!lib.IsNull() && !lib.is_dart_scheme()) {
2813 // This is a library that already exists so mark it as being modified.
2814 modified_libs->Add(lib.index());
2815 }
2816 }
2817}
2818
2819void BytecodeReaderHelper::ReadParameterCovariance(
2820 const Function& function,
2821 BitVector* is_covariant,
2822 BitVector* is_generic_covariant_impl) {
2823 ASSERT(function.is_declared_in_bytecode());
2824
2825 const intptr_t num_params = function.NumParameters();
2826 ASSERT(is_covariant->length() == num_params);
2827 ASSERT(is_generic_covariant_impl->length() == num_params);
2828
2829 AlternativeReadingScope alt(&reader_, function.bytecode_offset());
2830
2831 const intptr_t code_flags = reader_.ReadUInt();
2832 if ((code_flags & Code::kHasParameterFlagsFlag) != 0) {
2833 const intptr_t num_explicit_params = reader_.ReadUInt();
2834 ASSERT(num_params ==
2835 function.NumImplicitParameters() + num_explicit_params);
2836
2837 for (intptr_t i = function.NumImplicitParameters(); i < num_params; ++i) {
2838 const intptr_t flags = reader_.ReadUInt();
2839
2840 if ((flags & Parameter::kIsCovariantFlag) != 0) {
2841 is_covariant->Add(i);
2842 }
2843 if ((flags & Parameter::kIsGenericCovariantImplFlag) != 0) {
2844 is_generic_covariant_impl->Add(i);
2845 }
2846 }
2847 }
2848}
2849
2850ObjectPtr BytecodeReaderHelper::BuildParameterDescriptor(
2851 const Function& function) {
2852 ASSERT(function.is_declared_in_bytecode());
2853
2854 Object& result = Object::Handle(Z);
2855 if (!function.HasBytecode()) {
2856 result = BytecodeReader::ReadFunctionBytecode(Thread::Current(), function);
2857 if (result.IsError()) {
2858 return result.raw();
2859 }
2860 }
2861
2862 const intptr_t num_params = function.NumParameters();
2863 const intptr_t num_implicit_params = function.NumImplicitParameters();
2864 const intptr_t num_explicit_params = num_params - num_implicit_params;
2865 const Array& descriptor = Array::Handle(
2866 Z, Array::New(num_explicit_params * Parser::kParameterEntrySize));
2867
2868 // 1. Find isFinal in the Code declaration.
2869 bool found_final = false;
2870 if (!function.is_abstract()) {
2871 AlternativeReadingScope alt(&reader_, function.bytecode_offset());
2872 const intptr_t code_flags = reader_.ReadUInt();
2873
2874 if ((code_flags & Code::kHasParameterFlagsFlag) != 0) {
2875 const intptr_t num_explicit_params_written = reader_.ReadUInt();
2876 ASSERT(num_explicit_params == num_explicit_params_written);
2877 for (intptr_t i = 0; i < num_explicit_params; ++i) {
2878 const intptr_t flags = reader_.ReadUInt();
2879 descriptor.SetAt(
2880 i * Parser::kParameterEntrySize + Parser::kParameterIsFinalOffset,
2881 Bool::Get((flags & Parameter::kIsFinalFlag) != 0));
2882 }
2883 found_final = true;
2884 }
2885 }
2886 if (!found_final) {
2887 for (intptr_t i = 0; i < num_explicit_params; ++i) {
2888 descriptor.SetAt(
2889 i * Parser::kParameterEntrySize + Parser::kParameterIsFinalOffset,
2890 Bool::Get(false));
2891 }
2892 }
2893
2894 // 2. Find metadata implicitly after the function declaration's metadata.
2895 const Class& klass = Class::Handle(Z, function.Owner());
2896 const Library& library = Library::Handle(Z, klass.library());
2897 const Object& metadata = Object::Handle(
2898 Z, library.GetExtendedMetadata(function, num_explicit_params));
2899 if (metadata.IsError()) {
2900 return metadata.raw();
2901 }
2902 if (Array::Cast(metadata).Length() != 0) {
2903 for (intptr_t i = 0; i < num_explicit_params; i++) {
2904 result = Array::Cast(metadata).At(i);
2905 descriptor.SetAt(
2906 i * Parser::kParameterEntrySize + Parser::kParameterMetadataOffset,
2907 result);
2908 }
2909 }
2910
2911 // 3. Find the defaultValues in the EntryOptional sequence.
2912 if (!function.is_abstract()) {
2913 const Bytecode& bytecode = Bytecode::Handle(Z, function.bytecode());
2914 ASSERT(!bytecode.IsNull());
2915 const ObjectPool& constants = ObjectPool::Handle(Z, bytecode.object_pool());
2916 ASSERT(!constants.IsNull());
2917 const KBCInstr* instr =
2918 reinterpret_cast<const KBCInstr*>(bytecode.PayloadStart());
2919 if (KernelBytecode::IsEntryOptionalOpcode(instr)) {
2920 // Note that number of fixed parameters may not match 'A' operand of
2921 // EntryOptional bytecode as [function] could be an implicit closure
2922 // function with an extra implicit argument, while bytecode corresponds
2923 // to a static function without any implicit arguments.
2924 const intptr_t num_fixed_params = function.num_fixed_parameters();
2925 const intptr_t num_opt_pos_params = KernelBytecode::DecodeB(instr);
2926 const intptr_t num_opt_named_params = KernelBytecode::DecodeC(instr);
2927 instr = KernelBytecode::Next(instr);
2928 ASSERT(num_opt_pos_params == function.NumOptionalPositionalParameters());
2929 ASSERT(num_opt_named_params == function.NumOptionalNamedParameters());
2930 ASSERT((num_opt_pos_params == 0) || (num_opt_named_params == 0));
2931
2932 for (intptr_t i = 0; i < num_opt_pos_params; i++) {
2933 const KBCInstr* load_value_instr = instr;
2934 instr = KernelBytecode::Next(instr);
2935 ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value_instr));
2936 result = constants.ObjectAt(KernelBytecode::DecodeE(load_value_instr));
2937 descriptor.SetAt((num_fixed_params - num_implicit_params + i) *
2938 Parser::kParameterEntrySize +
2939 Parser::kParameterDefaultValueOffset,
2940 result);
2941 }
2942 for (intptr_t i = 0; i < num_opt_named_params; i++) {
2943 const KBCInstr* load_name_instr = instr;
2944 const KBCInstr* load_value_instr =
2945 KernelBytecode::Next(load_name_instr);
2946 instr = KernelBytecode::Next(load_value_instr);
2947 ASSERT(KernelBytecode::IsLoadConstantOpcode(load_name_instr));
2948 result = constants.ObjectAt(KernelBytecode::DecodeE(load_name_instr));
2949 intptr_t param_index;
2950 for (param_index = num_fixed_params; param_index < num_params;
2951 param_index++) {
2952 if (function.ParameterNameAt(param_index) == result.raw()) {
2953 break;
2954 }
2955 }
2956 ASSERT(param_index < num_params);
2957 ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value_instr));
2958 result = constants.ObjectAt(KernelBytecode::DecodeE(load_value_instr));
2959 descriptor.SetAt(
2960 (param_index - num_implicit_params) * Parser::kParameterEntrySize +
2961 Parser::kParameterDefaultValueOffset,
2962 result);
2963 }
2964 }
2965 }
2966
2967 return descriptor.raw();
2968}
2969
2970void BytecodeReaderHelper::ParseBytecodeFunction(
2971 ParsedFunction* parsed_function,
2972 const Function& function) {
2973 // Handle function kinds which don't have a user-defined body first.
2974 switch (function.kind()) {
2975 case FunctionLayout::kImplicitClosureFunction:
2976 ParseForwarderFunction(parsed_function, function,
2977 Function::Handle(Z, function.parent_function()));
2978 return;
2979 case FunctionLayout::kDynamicInvocationForwarder:
2980 ParseForwarderFunction(parsed_function, function,
2981 Function::Handle(Z, function.ForwardingTarget()));
2982 return;
2983 case FunctionLayout::kImplicitGetter:
2984 case FunctionLayout::kImplicitSetter:
2985 case FunctionLayout::kMethodExtractor:
2986 BytecodeScopeBuilder(parsed_function).BuildScopes();
2987 return;
2988 case FunctionLayout::kImplicitStaticGetter: {
2989 if (IsStaticFieldGetterGeneratedAsInitializer(function, Z)) {
2990 break;
2991 } else {
2992 BytecodeScopeBuilder(parsed_function).BuildScopes();
2993 return;
2994 }
2995 }
2996 case FunctionLayout::kRegularFunction:
2997 case FunctionLayout::kGetterFunction:
2998 case FunctionLayout::kSetterFunction:
2999 case FunctionLayout::kClosureFunction:
3000 case FunctionLayout::kConstructor:
3001 case FunctionLayout::kFieldInitializer:
3002 break;
3003 case FunctionLayout::kNoSuchMethodDispatcher:
3004 case FunctionLayout::kInvokeFieldDispatcher:
3005 case FunctionLayout::kSignatureFunction:
3006 case FunctionLayout::kIrregexpFunction:
3007 case FunctionLayout::kFfiTrampoline:
3008 UNREACHABLE();
3009 break;
3010 }
3011
3012 // We only reach here if function has a bytecode body. Make sure it is
3013 // loaded and collect information about covariant parameters.
3014
3015 if (!function.HasBytecode()) {
3016 ReadCode(function, function.bytecode_offset());
3017 ASSERT(function.HasBytecode());
3018 }
3019
3020 // TODO(alexmarkov): simplify access to covariant / generic_covariant_impl
3021 // flags of parameters so we won't need to read them separately.
3022 if (!parsed_function->HasCovariantParametersInfo()) {
3023 const intptr_t num_params = function.NumParameters();
3024 BitVector* covariant_parameters = new (Z) BitVector(Z, num_params);
3025 BitVector* generic_covariant_impl_parameters =
3026 new (Z) BitVector(Z, num_params);
3027 ReadParameterCovariance(function, covariant_parameters,
3028 generic_covariant_impl_parameters);
3029 parsed_function->SetCovariantParameters(covariant_parameters);
3030 parsed_function->SetGenericCovariantImplParameters(
3031 generic_covariant_impl_parameters);
3032 }
3033}
3034
3035void BytecodeReaderHelper::ParseForwarderFunction(
3036 ParsedFunction* parsed_function,
3037 const Function& function,
3038 const Function& target) {
3039 ASSERT(function.IsImplicitClosureFunction() ||
3040 function.IsDynamicInvocationForwarder());
3041
3042 ASSERT(target.is_declared_in_bytecode());
3043
3044 if (function.IsDynamicInvocationForwarder() &&
3045 target.IsImplicitSetterFunction()) {
3046 BytecodeScopeBuilder(parsed_function).BuildScopes();
3047 return;
3048 }
3049
3050 if (!target.HasBytecode()) {
3051 ReadCode(target, target.bytecode_offset());
3052 }
3053
3054 BytecodeScopeBuilder(parsed_function).BuildScopes();
3055
3056 const auto& target_bytecode = Bytecode::Handle(Z, target.bytecode());
3057 const auto& obj_pool = ObjectPool::Handle(Z, target_bytecode.object_pool());
3058
3059 AlternativeReadingScope alt(&reader_, target.bytecode_offset());
3060
3061 const intptr_t flags = reader_.ReadUInt();
3062 const bool has_parameters_flags = (flags & Code::kHasParameterFlagsFlag) != 0;
3063 const bool has_forwarding_stub_target =
3064 (flags & Code::kHasForwardingStubTargetFlag) != 0;
3065 const bool has_default_function_type_args =
3066 (flags & Code::kHasDefaultFunctionTypeArgsFlag) != 0;
3067 const auto proc_attrs = kernel::ProcedureAttributesOf(target, Z);
3068 // TODO(alexmarkov): fix building of flow graph for implicit closures so
3069 // it would include missing checks and remove 'proc_attrs.has_tearoff_uses'
3070 // from this condition.
3071 const bool body_has_generic_covariant_impl_type_checks =
3072 proc_attrs.has_non_this_uses || proc_attrs.has_tearoff_uses;
3073
3074 if (has_parameters_flags) {
3075 const intptr_t num_params = reader_.ReadUInt();
3076 const intptr_t num_implicit_params = function.NumImplicitParameters();
3077 const intptr_t num_fixed_params = function.num_fixed_parameters();
3078 for (intptr_t i = 0; i < num_params; ++i) {
3079 const intptr_t flags = reader_.ReadUInt();
3080
3081 bool is_covariant = (flags & Parameter::kIsCovariantFlag) != 0;
3082 bool is_generic_covariant_impl =
3083 (flags & Parameter::kIsGenericCovariantImplFlag) != 0;
3084 bool is_required = (flags & Parameter::kIsRequiredFlag) != 0;
3085
3086 if (is_required) {
3087 RELEASE_ASSERT(num_implicit_params + i >= num_fixed_params);
3088 function.SetIsRequiredAt(num_implicit_params + i);
3089 }
3090
3091 LocalVariable* variable =
3092 parsed_function->ParameterVariable(num_implicit_params + i);
3093
3094 if (is_covariant) {
3095 variable->set_is_explicit_covariant_parameter();
3096 }
3097
3098 const bool checked_in_method_body =
3099 is_covariant || (is_generic_covariant_impl &&
3100 body_has_generic_covariant_impl_type_checks);
3101
3102 if (checked_in_method_body) {
3103 variable->set_type_check_mode(LocalVariable::kSkipTypeCheck);
3104 } else {
3105 ASSERT(variable->type_check_mode() == LocalVariable::kDoTypeCheck);
3106 }
3107 }
3108 }
3109
3110 if (has_forwarding_stub_target) {
3111 const intptr_t cp_index = reader_.ReadUInt();
3112 const auto& forwarding_stub_target =
3113 Function::CheckedZoneHandle(Z, obj_pool.ObjectAt(cp_index));
3114 parsed_function->MarkForwardingStub(&forwarding_stub_target);
3115 }
3116
3117 if (has_default_function_type_args) {
3118 ASSERT(function.IsGeneric());
3119 const intptr_t cp_index = reader_.ReadUInt();
3120 const auto& type_args =
3121 TypeArguments::CheckedHandle(Z, obj_pool.ObjectAt(cp_index));
3122 parsed_function->SetDefaultFunctionTypeArguments(type_args);
3123 }
3124
3125 if (function.HasOptionalParameters()) {
3126 const KBCInstr* raw_bytecode =
3127 reinterpret_cast<const KBCInstr*>(target_bytecode.PayloadStart());
3128 const KBCInstr* entry = raw_bytecode;
3129 raw_bytecode = KernelBytecode::Next(raw_bytecode);
3130 ASSERT(KernelBytecode::IsEntryOptionalOpcode(entry));
3131 ASSERT(KernelBytecode::DecodeB(entry) ==
3132 function.NumOptionalPositionalParameters());
3133 ASSERT(KernelBytecode::DecodeC(entry) ==
3134 function.NumOptionalNamedParameters());
3135
3136 const intptr_t num_opt_params = function.NumOptionalParameters();
3137 ZoneGrowableArray<const Instance*>* default_values =
3138 new (Z) ZoneGrowableArray<const Instance*>(Z, num_opt_params);
3139
3140 if (function.HasOptionalPositionalParameters()) {
3141 for (intptr_t i = 0, n = function.NumOptionalPositionalParameters();
3142 i < n; ++i) {
3143 const KBCInstr* load = raw_bytecode;
3144 raw_bytecode = KernelBytecode::Next(raw_bytecode);
3145 ASSERT(KernelBytecode::IsLoadConstantOpcode(load));
3146 const auto& value = Instance::CheckedZoneHandle(
3147 Z, obj_pool.ObjectAt(KernelBytecode::DecodeE(load)));
3148 default_values->Add(&value);
3149 }
3150 } else {
3151 const intptr_t num_fixed_params = function.num_fixed_parameters();
3152 auto& param_name = String::Handle(Z);
3153 default_values->EnsureLength(num_opt_params, nullptr);
3154 for (intptr_t i = 0; i < num_opt_params; ++i) {
3155 const KBCInstr* load_name = raw_bytecode;
3156 const KBCInstr* load_value = KernelBytecode::Next(load_name);
3157 raw_bytecode = KernelBytecode::Next(load_value);
3158 ASSERT(KernelBytecode::IsLoadConstantOpcode(load_name));
3159 ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value));
3160 param_name ^= obj_pool.ObjectAt(KernelBytecode::DecodeE(load_name));
3161 const auto& value = Instance::CheckedZoneHandle(
3162 Z, obj_pool.ObjectAt(KernelBytecode::DecodeE(load_value)));
3163
3164 const intptr_t num_params = function.NumParameters();
3165 intptr_t param_index = num_fixed_params;
3166 for (; param_index < num_params; ++param_index) {
3167 if (function.ParameterNameAt(param_index) == param_name.raw()) {
3168 break;
3169 }
3170 }
3171 ASSERT(param_index < num_params);
3172 ASSERT(default_values->At(param_index - num_fixed_params) == nullptr);
3173 (*default_values)[param_index - num_fixed_params] = &value;
3174 }
3175 }
3176
3177 parsed_function->set_default_parameter_values(default_values);
3178 }
3179}
3180
3181LibraryPtr BytecodeReaderHelper::ReadMain() {
3182 return Library::RawCast(ReadObject());
3183}
3184
3185intptr_t BytecodeComponentData::GetVersion() const {
3186 return Smi::Value(Smi::RawCast(data_.At(kVersion)));
3187}
3188
3189intptr_t BytecodeComponentData::GetStringsHeaderOffset() const {
3190 return Smi::Value(Smi::RawCast(data_.At(kStringsHeaderOffset)));
3191}
3192
3193intptr_t BytecodeComponentData::GetStringsContentsOffset() const {
3194 return Smi::Value(Smi::RawCast(data_.At(kStringsContentsOffset)));
3195}
3196
3197intptr_t BytecodeComponentData::GetObjectOffsetsOffset() const {
3198 return Smi::Value(Smi::RawCast(data_.At(kObjectOffsetsOffset)));
3199}
3200
3201intptr_t BytecodeComponentData::GetNumObjects() const {
3202 return Smi::Value(Smi::RawCast(data_.At(kNumObjects)));
3203}
3204
3205intptr_t BytecodeComponentData::GetObjectsContentsOffset() const {
3206 return Smi::Value(Smi::RawCast(data_.At(kObjectsContentsOffset)));
3207}
3208
3209intptr_t BytecodeComponentData::GetMainOffset() const {
3210 return Smi::Value(Smi::RawCast(data_.At(kMainOffset)));
3211}
3212
3213intptr_t BytecodeComponentData::GetNumLibraries() const {
3214 return Smi::Value(Smi::RawCast(data_.At(kNumLibraries)));
3215}
3216
3217intptr_t BytecodeComponentData::GetLibraryIndexOffset() const {
3218 return Smi::Value(Smi::RawCast(data_.At(kLibraryIndexOffset)));
3219}
3220
3221intptr_t BytecodeComponentData::GetLibrariesOffset() const {
3222 return Smi::Value(Smi::RawCast(data_.At(kLibrariesOffset)));
3223}
3224
3225intptr_t BytecodeComponentData::GetNumClasses() const {
3226 return Smi::Value(Smi::RawCast(data_.At(kNumClasses)));
3227}
3228
3229intptr_t BytecodeComponentData::GetClassesOffset() const {
3230 return Smi::Value(Smi::RawCast(data_.At(kClassesOffset)));
3231}
3232
3233intptr_t BytecodeComponentData::GetMembersOffset() const {
3234 return Smi::Value(Smi::RawCast(data_.At(kMembersOffset)));
3235}
3236
3237intptr_t BytecodeComponentData::GetNumCodes() const {
3238 return Smi::Value(Smi::RawCast(data_.At(kNumCodes)));
3239}
3240
3241intptr_t BytecodeComponentData::GetCodesOffset() const {
3242 return Smi::Value(Smi::RawCast(data_.At(kCodesOffset)));
3243}
3244
3245intptr_t BytecodeComponentData::GetSourcePositionsOffset() const {
3246 return Smi::Value(Smi::RawCast(data_.At(kSourcePositionsOffset)));
3247}
3248
3249intptr_t BytecodeComponentData::GetSourceFilesOffset() const {
3250 return Smi::Value(Smi::RawCast(data_.At(kSourceFilesOffset)));
3251}
3252
3253intptr_t BytecodeComponentData::GetLineStartsOffset() const {
3254 return Smi::Value(Smi::RawCast(data_.At(kLineStartsOffset)));
3255}
3256
3257intptr_t BytecodeComponentData::GetLocalVariablesOffset() const {
3258 return Smi::Value(Smi::RawCast(data_.At(kLocalVariablesOffset)));
3259}
3260
3261intptr_t BytecodeComponentData::GetAnnotationsOffset() const {
3262 return Smi::Value(Smi::RawCast(data_.At(kAnnotationsOffset)));
3263}
3264
3265void BytecodeComponentData::SetObject(intptr_t index, const Object& obj) const {
3266 data_.SetAt(kNumFields + index, obj);
3267}
3268
3269ObjectPtr BytecodeComponentData::GetObject(intptr_t index) const {
3270 return data_.At(kNumFields + index);
3271}
3272
3273ArrayPtr BytecodeComponentData::New(Zone* zone,
3274 intptr_t version,
3275 intptr_t num_objects,
3276 intptr_t strings_header_offset,
3277 intptr_t strings_contents_offset,
3278 intptr_t object_offsets_offset,
3279 intptr_t objects_contents_offset,
3280 intptr_t main_offset,
3281 intptr_t num_libraries,
3282 intptr_t library_index_offset,
3283 intptr_t libraries_offset,
3284 intptr_t num_classes,
3285 intptr_t classes_offset,
3286 intptr_t members_offset,
3287 intptr_t num_codes,
3288 intptr_t codes_offset,
3289 intptr_t source_positions_offset,
3290 intptr_t source_files_offset,
3291 intptr_t line_starts_offset,
3292 intptr_t local_variables_offset,
3293 intptr_t annotations_offset,
3294 Heap::Space space) {
3295 const Array& data =
3296 Array::Handle(zone, Array::New(kNumFields + num_objects, space));
3297 Smi& smi_handle = Smi::Handle(zone);
3298
3299 smi_handle = Smi::New(version);
3300 data.SetAt(kVersion, smi_handle);
3301
3302 smi_handle = Smi::New(strings_header_offset);
3303 data.SetAt(kStringsHeaderOffset, smi_handle);
3304
3305 smi_handle = Smi::New(strings_contents_offset);
3306 data.SetAt(kStringsContentsOffset, smi_handle);
3307
3308 smi_handle = Smi::New(object_offsets_offset);
3309 data.SetAt(kObjectOffsetsOffset, smi_handle);
3310
3311 smi_handle = Smi::New(num_objects);
3312 data.SetAt(kNumObjects, smi_handle);
3313
3314 smi_handle = Smi::New(objects_contents_offset);
3315 data.SetAt(kObjectsContentsOffset, smi_handle);
3316
3317 smi_handle = Smi::New(main_offset);
3318 data.SetAt(kMainOffset, smi_handle);
3319
3320 smi_handle = Smi::New(num_libraries);
3321 data.SetAt(kNumLibraries, smi_handle);
3322
3323 smi_handle = Smi::New(library_index_offset);
3324 data.SetAt(kLibraryIndexOffset, smi_handle);
3325
3326 smi_handle = Smi::New(libraries_offset);
3327 data.SetAt(kLibrariesOffset, smi_handle);
3328
3329 smi_handle = Smi::New(num_classes);
3330 data.SetAt(kNumClasses, smi_handle);
3331
3332 smi_handle = Smi::New(classes_offset);
3333 data.SetAt(kClassesOffset, smi_handle);
3334
3335 smi_handle = Smi::New(members_offset);
3336 data.SetAt(kMembersOffset, smi_handle);
3337
3338 smi_handle = Smi::New(num_codes);
3339 data.SetAt(kNumCodes, smi_handle);
3340
3341 smi_handle = Smi::New(codes_offset);
3342 data.SetAt(kCodesOffset, smi_handle);
3343
3344 smi_handle = Smi::New(source_positions_offset);
3345 data.SetAt(kSourcePositionsOffset, smi_handle);
3346
3347 smi_handle = Smi::New(source_files_offset);
3348 data.SetAt(kSourceFilesOffset, smi_handle);
3349
3350 smi_handle = Smi::New(line_starts_offset);
3351 data.SetAt(kLineStartsOffset, smi_handle);
3352
3353 smi_handle = Smi::New(local_variables_offset);
3354 data.SetAt(kLocalVariablesOffset, smi_handle);
3355
3356 smi_handle = Smi::New(annotations_offset);
3357 data.SetAt(kAnnotationsOffset, smi_handle);
3358
3359 return data.raw();
3360}
3361
3362ErrorPtr BytecodeReader::ReadFunctionBytecode(Thread* thread,
3363 const Function& function) {
3364 ASSERT(!FLAG_precompiled_mode);
3365 ASSERT(!function.HasBytecode());
3366 ASSERT(thread->sticky_error() == Error::null());
3367 ASSERT(Thread::Current()->IsMutatorThread());
3368
3369 VMTagScope tagScope(thread, VMTag::kLoadBytecodeTagId);
3370
3371#if defined(SUPPORT_TIMELINE)
3372 TimelineBeginEndScope tbes(thread, Timeline::GetCompilerStream(),
3373 "BytecodeReader::ReadFunctionBytecode");
3374 // This increases bytecode reading time by ~7%, so only keep it around for
3375 // debugging.
3376#if defined(DEBUG)
3377 tbes.SetNumArguments(1);
3378 tbes.CopyArgument(0, "Function", function.ToQualifiedCString());
3379#endif // defined(DEBUG)
3380#endif // !defined(SUPPORT_TIMELINE)
3381
3382 LongJumpScope jump;
3383 if (setjmp(*jump.Set()) == 0) {
3384 StackZone stack_zone(thread);
3385 Zone* const zone = stack_zone.GetZone();
3386 HANDLESCOPE(thread);
3387
3388 auto& bytecode = Bytecode::Handle(zone);
3389
3390 switch (function.kind()) {
3391 case FunctionLayout::kImplicitGetter:
3392 bytecode = Object::implicit_getter_bytecode().raw();
3393 break;
3394 case FunctionLayout::kImplicitSetter:
3395 bytecode = Object::implicit_setter_bytecode().raw();
3396 break;
3397 case FunctionLayout::kImplicitStaticGetter:
3398 if (!IsStaticFieldGetterGeneratedAsInitializer(function, zone)) {
3399 bytecode = Object::implicit_static_getter_bytecode().raw();
3400 }
3401 break;
3402 case FunctionLayout::kMethodExtractor:
3403 bytecode = Object::method_extractor_bytecode().raw();
3404 break;
3405 case FunctionLayout::kInvokeFieldDispatcher:
3406 if (Class::Handle(zone, function.Owner()).id() == kClosureCid) {
3407 bytecode = Object::invoke_closure_bytecode().raw();
3408 } else {
3409 bytecode = Object::invoke_field_bytecode().raw();
3410 }
3411 break;
3412 case FunctionLayout::kNoSuchMethodDispatcher:
3413 bytecode = Object::nsm_dispatcher_bytecode().raw();
3414 break;
3415 case FunctionLayout::kDynamicInvocationForwarder: {
3416 const Function& target =
3417 Function::Handle(zone, function.ForwardingTarget());
3418 if (!target.HasBytecode()) {
3419 // The forwarder will use the target's bytecode to handle optional
3420 // parameters.
3421 const Error& error =
3422 Error::Handle(zone, ReadFunctionBytecode(thread, target));
3423 if (!error.IsNull()) {
3424 return error.raw();
3425 }
3426 }
3427 {
3428 const Script& script = Script::Handle(zone, target.script());
3429 TranslationHelper translation_helper(thread);
3430 translation_helper.InitFromScript(script);
3431
3432 ActiveClass active_class;
3433 BytecodeComponentData bytecode_component(
3434 &Array::Handle(zone, translation_helper.GetBytecodeComponent()));
3435 ASSERT(!bytecode_component.IsNull());
3436 BytecodeReaderHelper bytecode_reader(
3437 &translation_helper, &active_class, &bytecode_component);
3438
3439 const Array& checks = Array::Handle(
3440 zone, bytecode_reader.CreateForwarderChecks(target));
3441 function.SetForwardingChecks(checks);
3442 }
3443 bytecode = Object::dynamic_invocation_forwarder_bytecode().raw();
3444 } break;
3445 default:
3446 break;
3447 }
3448
3449 if (!bytecode.IsNull()) {
3450 function.AttachBytecode(bytecode);
3451 } else if (function.is_declared_in_bytecode()) {
3452 const intptr_t code_offset = function.bytecode_offset();
3453 if (code_offset != 0) {
3454 CompilerState compiler_state(thread, FLAG_precompiled_mode);
3455
3456 const Script& script = Script::Handle(zone, function.script());
3457 TranslationHelper translation_helper(thread);
3458 translation_helper.InitFromScript(script);
3459
3460 ActiveClass active_class;
3461
3462 // Setup a [ActiveClassScope] and a [ActiveMemberScope] which will be
3463 // used e.g. for type translation.
3464 const Class& klass = Class::Handle(zone, function.Owner());
3465 Function& outermost_function =
3466 Function::Handle(zone, function.GetOutermostFunction());
3467
3468 ActiveClassScope active_class_scope(&active_class, &klass);
3469 ActiveMemberScope active_member(&active_class, &outermost_function);
3470
3471 BytecodeComponentData bytecode_component(
3472 &Array::Handle(zone, translation_helper.GetBytecodeComponent()));
3473 ASSERT(!bytecode_component.IsNull());
3474 BytecodeReaderHelper bytecode_reader(&translation_helper, &active_class,
3475 &bytecode_component);
3476
3477 bytecode_reader.ReadCode(function, code_offset);
3478 }
3479 }
3480 return Error::null();
3481 } else {
3482 return thread->StealStickyError();
3483 }
3484}
3485
3486ObjectPtr BytecodeReader::ReadAnnotation(const Field& annotation_field) {
3487 ASSERT(annotation_field.is_declared_in_bytecode());
3488
3489 Thread* thread = Thread::Current();
3490 Zone* zone = thread->zone();
3491 ASSERT(thread->IsMutatorThread());
3492
3493 const Script& script = Script::Handle(zone, annotation_field.Script());
3494 TranslationHelper translation_helper(thread);
3495 translation_helper.InitFromScript(script);
3496
3497 ActiveClass active_class;
3498
3499 BytecodeComponentData bytecode_component(
3500 &Array::Handle(zone, translation_helper.GetBytecodeComponent()));
3501 ASSERT(!bytecode_component.IsNull());
3502 BytecodeReaderHelper bytecode_reader(&translation_helper, &active_class,
3503 &bytecode_component);
3504
3505 AlternativeReadingScope alt(&bytecode_reader.reader(),
3506 annotation_field.bytecode_offset());
3507
3508 return bytecode_reader.ReadObject();
3509}
3510
3511ArrayPtr BytecodeReader::ReadExtendedAnnotations(const Field& annotation_field,
3512 intptr_t count) {
3513 ASSERT(annotation_field.is_declared_in_bytecode());
3514
3515 Thread* thread = Thread::Current();
3516 Zone* zone = thread->zone();
3517 ASSERT(thread->IsMutatorThread());
3518
3519 const Script& script = Script::Handle(zone, annotation_field.Script());
3520 TranslationHelper translation_helper(thread);
3521 translation_helper.InitFromScript(script);
3522
3523 ActiveClass active_class;
3524
3525 BytecodeComponentData bytecode_component(
3526 &Array::Handle(zone, translation_helper.GetBytecodeComponent()));
3527 ASSERT(!bytecode_component.IsNull());
3528 BytecodeReaderHelper bytecode_reader(&translation_helper, &active_class,
3529 &bytecode_component);
3530
3531 AlternativeReadingScope alt(&bytecode_reader.reader(),
3532 annotation_field.bytecode_offset());
3533
3534 bytecode_reader.ReadObject(); // Discard main annotation.
3535
3536 Array& result = Array::Handle(zone, Array::New(count));
3537 Object& element = Object::Handle(zone);
3538 for (intptr_t i = 0; i < count; i++) {
3539 element = bytecode_reader.ReadObject();
3540 result.SetAt(i, element);
3541 }
3542 return result.raw();
3543}
3544
3545void BytecodeReader::ResetObjectTable(const KernelProgramInfo& info) {
3546 Thread* thread = Thread::Current();
3547 TranslationHelper translation_helper(thread);
3548 translation_helper.InitFromKernelProgramInfo(info);
3549 ActiveClass active_class;
3550 BytecodeComponentData bytecode_component(&Array::Handle(
3551 thread->zone(), translation_helper.GetBytecodeComponent()));
3552 ASSERT(!bytecode_component.IsNull());
3553 BytecodeReaderHelper bytecode_reader(&translation_helper, &active_class,
3554 &bytecode_component);
3555 bytecode_reader.ResetObjects();
3556}
3557
3558void BytecodeReader::LoadClassDeclaration(const Class& cls) {
3559 TIMELINE_DURATION(Thread::Current(), Compiler,
3560 "BytecodeReader::LoadClassDeclaration");
3561
3562 ASSERT(cls.is_declared_in_bytecode());
3563 ASSERT(!cls.is_declaration_loaded());
3564
3565 Thread* thread = Thread::Current();
3566 Zone* zone = thread->zone();
3567 ASSERT(thread->IsMutatorThread());
3568
3569 const Script& script = Script::Handle(zone, cls.script());
3570 TranslationHelper translation_helper(thread);
3571 translation_helper.InitFromScript(script);
3572
3573 ActiveClass active_class;
3574 ActiveClassScope active_class_scope(&active_class, &cls);
3575
3576 BytecodeComponentData bytecode_component(
3577 &Array::Handle(zone, translation_helper.GetBytecodeComponent()));
3578 ASSERT(!bytecode_component.IsNull());
3579 BytecodeReaderHelper bytecode_reader(&translation_helper, &active_class,
3580 &bytecode_component);
3581
3582 AlternativeReadingScope alt(&bytecode_reader.reader(), cls.bytecode_offset());
3583
3584 bytecode_reader.ReadClassDeclaration(cls);
3585}
3586
3587void BytecodeReader::FinishClassLoading(const Class& cls) {
3588 ASSERT(cls.is_declared_in_bytecode());
3589
3590 Thread* thread = Thread::Current();
3591 Zone* zone = thread->zone();
3592 ASSERT(thread->IsMutatorThread());
3593
3594 const Script& script = Script::Handle(zone, cls.script());
3595 TranslationHelper translation_helper(thread);
3596 translation_helper.InitFromScript(script);
3597
3598 ActiveClass active_class;
3599 ActiveClassScope active_class_scope(&active_class, &cls);
3600
3601 BytecodeComponentData bytecode_component(
3602 &Array::Handle(zone, translation_helper.GetBytecodeComponent()));
3603 ASSERT(!bytecode_component.IsNull());
3604 BytecodeReaderHelper bytecode_reader(&translation_helper, &active_class,
3605 &bytecode_component);
3606
3607 AlternativeReadingScope alt(&bytecode_reader.reader(), cls.bytecode_offset());
3608
3609 // If this is a dart:internal.ClassID class ignore field declarations
3610 // contained in the Kernel file and instead inject our own const
3611 // fields.
3612 const bool discard_fields = cls.InjectCIDFields();
3613
3614 bytecode_reader.ReadMembers(cls, discard_fields);
3615}
3616
3617ObjectPtr BytecodeReader::GetBytecodeAttribute(const Object& key,
3618 const String& name) {
3619 Thread* thread = Thread::Current();
3620 Zone* zone = thread->zone();
3621 const auto* object_store = thread->isolate()->object_store();
3622 if (object_store->bytecode_attributes() == Object::null()) {
3623 return Object::null();
3624 }
3625 BytecodeAttributesMap map(object_store->bytecode_attributes());
3626 const auto& attrs = Array::CheckedHandle(zone, map.GetOrNull(key));
3627 ASSERT(map.Release().raw() == object_store->bytecode_attributes());
3628 if (attrs.IsNull()) {
3629 return Object::null();
3630 }
3631 auto& obj = Object::Handle(zone);
3632 for (intptr_t i = 0, n = attrs.Length(); i + 1 < n; i += 2) {
3633 obj = attrs.At(i);
3634 if (obj.raw() == name.raw()) {
3635 return attrs.At(i + 1);
3636 }
3637 }
3638 return Object::null();
3639}
3640
3641InferredTypeMetadata InferredTypeBytecodeAttribute::GetInferredTypeAt(
3642 Zone* zone,
3643 const Array& attr,
3644 intptr_t index) {
3645 ASSERT(index + kNumElements <= attr.Length());
3646 const auto& type = AbstractType::CheckedHandle(zone, attr.At(index + 1));
3647 const intptr_t flags = Smi::Value(Smi::RawCast(attr.At(index + 2)));
3648 if (!type.IsNull()) {
3649 intptr_t cid = Type::Cast(type).type_class_id();
3650 return InferredTypeMetadata(cid, flags);
3651 } else {
3652 return InferredTypeMetadata(kDynamicCid, flags);
3653 }
3654}
3655
3656#if !defined(PRODUCT)
3657LocalVarDescriptorsPtr BytecodeReader::ComputeLocalVarDescriptors(
3658 Zone* zone,
3659 const Function& function,
3660 const Bytecode& bytecode) {
3661 ASSERT(function.is_declared_in_bytecode());
3662 ASSERT(function.HasBytecode());
3663 ASSERT(!bytecode.IsNull());
3664 ASSERT(function.bytecode() == bytecode.raw());
3665
3666 LocalVarDescriptorsBuilder vars;
3667
3668 if (function.IsLocalFunction()) {
3669 const auto& parent = Function::Handle(zone, function.parent_function());
3670 ASSERT(parent.is_declared_in_bytecode() && parent.HasBytecode());
3671 const auto& parent_bytecode = Bytecode::Handle(zone, parent.bytecode());
3672 const auto& parent_vars = LocalVarDescriptors::Handle(
3673 zone, parent_bytecode.GetLocalVarDescriptors());
3674 for (intptr_t i = 0; i < parent_vars.Length(); ++i) {
3675 LocalVarDescriptorsLayout::VarInfo var_info;
3676 parent_vars.GetInfo(i, &var_info);
3677 // Include parent's context variable if variable's scope
3678 // intersects with the local function range.
3679 // It is not enough to check if local function is declared within the
3680 // scope of variable, because in case of async functions closure has
3681 // the same range as original function.
3682 if (var_info.kind() == LocalVarDescriptorsLayout::kContextVar &&
3683 ((var_info.begin_pos <= function.token_pos() &&
3684 function.token_pos() <= var_info.end_pos) ||
3685 (function.token_pos() <= var_info.begin_pos &&
3686 var_info.begin_pos <= function.end_token_pos()))) {
3687 vars.Add(LocalVarDescriptorsBuilder::VarDesc{
3688 &String::Handle(zone, parent_vars.GetName(i)), var_info});
3689 }
3690 }
3691 }
3692
3693 if (bytecode.HasLocalVariablesInfo()) {
3694 intptr_t scope_id = 0;
3695 intptr_t context_level = -1;
3696 BytecodeLocalVariablesIterator local_vars(zone, bytecode);
3697 while (local_vars.MoveNext()) {
3698 switch (local_vars.Kind()) {
3699 case BytecodeLocalVariablesIterator::kScope: {
3700 ++scope_id;
3701 context_level = local_vars.ContextLevel();
3702 } break;
3703 case BytecodeLocalVariablesIterator::kVariableDeclaration: {
3704 LocalVarDescriptorsBuilder::VarDesc desc;
3705 desc.name = &String::Handle(zone, local_vars.Name());
3706 if (local_vars.IsCaptured()) {
3707 desc.info.set_kind(LocalVarDescriptorsLayout::kContextVar);
3708 desc.info.scope_id = context_level;
3709 desc.info.set_index(local_vars.Index());
3710 } else {
3711 desc.info.set_kind(LocalVarDescriptorsLayout::kStackVar);
3712 desc.info.scope_id = scope_id;
3713 if (local_vars.Index() < 0) {
3714 // Parameter
3715 ASSERT(local_vars.Index() < -kKBCParamEndSlotFromFp);
3716 desc.info.set_index(-local_vars.Index() - kKBCParamEndSlotFromFp);
3717 } else {
3718 desc.info.set_index(-local_vars.Index());
3719 }
3720 }
3721 desc.info.declaration_pos = local_vars.DeclarationTokenPos();
3722 desc.info.begin_pos = local_vars.StartTokenPos();
3723 desc.info.end_pos = local_vars.EndTokenPos();
3724 vars.Add(desc);
3725 } break;
3726 case BytecodeLocalVariablesIterator::kContextVariable: {
3727 ASSERT(local_vars.Index() >= 0);
3728 const intptr_t context_variable_index = -local_vars.Index();
3729 LocalVarDescriptorsBuilder::VarDesc desc;
3730 desc.name = &Symbols::CurrentContextVar();
3731 desc.info.set_kind(LocalVarDescriptorsLayout::kSavedCurrentContext);
3732 desc.info.scope_id = 0;
3733 desc.info.declaration_pos = TokenPosition::kMinSource;
3734 desc.info.begin_pos = TokenPosition::kMinSource;
3735 desc.info.end_pos = TokenPosition::kMinSource;
3736 desc.info.set_index(context_variable_index);
3737 vars.Add(desc);
3738 } break;
3739 }
3740 }
3741 }
3742
3743 return vars.Done();
3744}
3745#endif // !defined(PRODUCT)
3746
3747bool IsStaticFieldGetterGeneratedAsInitializer(const Function& function,
3748 Zone* zone) {
3749 ASSERT(function.kind() == FunctionLayout::kImplicitStaticGetter);
3750
3751 const auto& field = Field::Handle(zone, function.accessor_field());
3752 return field.is_declared_in_bytecode() && field.is_const() &&
3753 field.has_nontrivial_initializer();
3754}
3755
3756} // namespace kernel
3757} // namespace dart
3758