a04691a8a8
This adds serialization of the new local variables, VariableStatement and VariableDeclaration. This prepares for replacing LegacyVariable with the new variables in all backends. TEST=existing Change-Id: I9bbebfbfd372042d6b7027f0fabd24c165699832 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/506240 Reviewed-by: Martin Kustermann <kustermann@google.com> Reviewed-by: Jens Johansen <jensj@google.com> Commit-Queue: Johnni Winther <johnniwinther@google.com>
610 lines
23 KiB
C++
610 lines
23 KiB
C++
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
#if !defined(DART_PRECOMPILED_RUNTIME)
|
|
|
|
#include "vm/kernel.h"
|
|
|
|
#include "vm/bit_vector.h"
|
|
#include "vm/compiler/frontend/constant_reader.h"
|
|
#include "vm/compiler/frontend/kernel_translation_helper.h"
|
|
#include "vm/compiler/jit/compiler.h"
|
|
#include "vm/longjump.h"
|
|
#include "vm/object_store.h"
|
|
#include "vm/parser.h" // For Parser::kParameter* constants.
|
|
#include "vm/stack_frame.h"
|
|
|
|
namespace dart {
|
|
namespace kernel {
|
|
|
|
class KernelTokenPositionCollector : public KernelReaderHelper {
|
|
public:
|
|
KernelTokenPositionCollector(
|
|
Zone* zone,
|
|
TranslationHelper* translation_helper,
|
|
const Script& script,
|
|
const TypedDataView& data,
|
|
intptr_t data_program_offset,
|
|
intptr_t initial_script_index,
|
|
intptr_t record_for_script_id,
|
|
GrowableArray<intptr_t>* record_token_positions_into)
|
|
: KernelReaderHelper(zone, translation_helper, data, data_program_offset),
|
|
current_script_id_(initial_script_index),
|
|
record_for_script_id_(record_for_script_id),
|
|
record_token_positions_into_(record_token_positions_into) {}
|
|
|
|
void CollectTokenPositions(intptr_t kernel_offset);
|
|
|
|
void RecordTokenPosition(TokenPosition position) override;
|
|
|
|
void set_current_script_id(intptr_t id) override { current_script_id_ = id; }
|
|
|
|
private:
|
|
intptr_t current_script_id_;
|
|
intptr_t record_for_script_id_;
|
|
GrowableArray<intptr_t>* record_token_positions_into_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(KernelTokenPositionCollector);
|
|
};
|
|
|
|
void KernelTokenPositionCollector::CollectTokenPositions(
|
|
intptr_t kernel_offset) {
|
|
SetOffset(kernel_offset);
|
|
|
|
const Tag tag = PeekTag();
|
|
if (tag == kProcedure) {
|
|
ProcedureHelper procedure_helper(this);
|
|
procedure_helper.ReadUntilExcluding(ProcedureHelper::kEnd);
|
|
} else if (tag == kConstructor) {
|
|
ConstructorHelper constructor_helper(this);
|
|
constructor_helper.ReadUntilExcluding(ConstructorHelper::kEnd);
|
|
} else if (tag == kFunctionNode) {
|
|
FunctionNodeHelper function_node_helper(this);
|
|
function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kEnd);
|
|
} else if (tag == kField) {
|
|
FieldHelper field_helper(this);
|
|
field_helper.ReadUntilExcluding(FieldHelper::kEnd);
|
|
} else if (tag == kClass) {
|
|
ClassHelper class_helper(this);
|
|
class_helper.ReadUntilExcluding(ClassHelper::kEnd);
|
|
} else {
|
|
ReportUnexpectedTag("a class or a member", tag);
|
|
UNREACHABLE();
|
|
}
|
|
}
|
|
|
|
void KernelTokenPositionCollector::RecordTokenPosition(TokenPosition position) {
|
|
if (record_for_script_id_ == current_script_id_ &&
|
|
record_token_positions_into_ != nullptr && position.IsReal()) {
|
|
record_token_positions_into_->Add(position.Serialize());
|
|
}
|
|
}
|
|
|
|
static void CollectKernelLibraryTokenPositions(
|
|
const TypedDataView& kernel_data,
|
|
const Script& script,
|
|
intptr_t kernel_offset,
|
|
intptr_t data_kernel_offset,
|
|
Zone* zone,
|
|
TranslationHelper* helper,
|
|
GrowableArray<intptr_t>* token_positions) {
|
|
if (kernel_data.IsNull()) {
|
|
return;
|
|
}
|
|
|
|
KernelTokenPositionCollector token_position_collector(
|
|
zone, helper, script, kernel_data, data_kernel_offset,
|
|
script.kernel_script_index(), script.kernel_script_index(),
|
|
token_positions);
|
|
|
|
token_position_collector.CollectTokenPositions(kernel_offset);
|
|
}
|
|
|
|
void CollectScriptTokenPositionsFromKernel(
|
|
const Script& interesting_script,
|
|
GrowableArray<intptr_t>* token_positions) {
|
|
Thread* thread = Thread::Current();
|
|
Zone* zone = thread->zone();
|
|
|
|
const auto& kernel_info =
|
|
KernelProgramInfo::Handle(zone, interesting_script.kernel_program_info());
|
|
|
|
TranslationHelper helper(thread);
|
|
helper.InitFromKernelProgramInfo(kernel_info);
|
|
|
|
auto isolate_group = thread->isolate_group();
|
|
const GrowableObjectArray& libs = GrowableObjectArray::Handle(
|
|
zone, isolate_group->object_store()->libraries());
|
|
Library& lib = Library::Handle(zone);
|
|
Object& entry = Object::Handle(zone);
|
|
Script& entry_script = Script::Handle(zone);
|
|
auto& data = TypedDataView::Handle(zone);
|
|
|
|
auto& temp_array = Array::Handle(zone);
|
|
auto& temp_field = Field::Handle(zone);
|
|
auto& temp_function = Function::Handle(zone);
|
|
for (intptr_t i = 0; i < libs.Length(); i++) {
|
|
lib ^= libs.At(i);
|
|
lib.EnsureTopLevelClassIsFinalized();
|
|
DictionaryIterator it(lib);
|
|
while (it.HasNext()) {
|
|
entry = it.GetNext();
|
|
data = TypedDataView::null();
|
|
if (entry.IsClass()) {
|
|
const Class& klass = Class::Cast(entry);
|
|
if (klass.script() == interesting_script.ptr()) {
|
|
token_positions->Add(klass.token_pos().Serialize());
|
|
token_positions->Add(klass.end_token_pos().Serialize());
|
|
}
|
|
if (klass.is_finalized()) {
|
|
temp_array = klass.fields();
|
|
for (intptr_t i = 0; i < temp_array.Length(); ++i) {
|
|
temp_field ^= temp_array.At(i);
|
|
if (temp_field.kernel_offset() <= 0) {
|
|
// Skip artificially injected fields.
|
|
continue;
|
|
}
|
|
entry_script = temp_field.Script();
|
|
if (entry_script.ptr() != interesting_script.ptr()) {
|
|
continue;
|
|
}
|
|
data = temp_field.KernelLibrary();
|
|
CollectKernelLibraryTokenPositions(data, interesting_script,
|
|
temp_field.kernel_offset(),
|
|
temp_field.KernelLibraryOffset(),
|
|
zone, &helper, token_positions);
|
|
}
|
|
temp_array = klass.current_functions();
|
|
for (intptr_t i = 0; i < temp_array.Length(); ++i) {
|
|
temp_function ^= temp_array.At(i);
|
|
entry_script = temp_function.script();
|
|
if (entry_script.ptr() != interesting_script.ptr()) {
|
|
continue;
|
|
}
|
|
data = temp_function.KernelLibrary();
|
|
CollectKernelLibraryTokenPositions(
|
|
data, interesting_script, temp_function.kernel_offset(),
|
|
temp_function.KernelLibraryOffset(), zone, &helper,
|
|
token_positions);
|
|
}
|
|
} else {
|
|
// Class isn't finalized yet: read the data attached to it.
|
|
ASSERT(klass.kernel_offset() > 0);
|
|
data = lib.KernelLibrary();
|
|
ASSERT(!data.IsNull());
|
|
const intptr_t library_kernel_offset = lib.KernelLibraryOffset();
|
|
ASSERT(library_kernel_offset > 0);
|
|
const intptr_t class_offset = klass.kernel_offset();
|
|
|
|
entry_script = klass.script();
|
|
if (entry_script.ptr() != interesting_script.ptr()) {
|
|
continue;
|
|
}
|
|
CollectKernelLibraryTokenPositions(
|
|
data, interesting_script, class_offset, library_kernel_offset,
|
|
zone, &helper, token_positions);
|
|
}
|
|
} else if (entry.IsFunction()) {
|
|
temp_function ^= entry.ptr();
|
|
entry_script = temp_function.script();
|
|
if (entry_script.ptr() != interesting_script.ptr()) {
|
|
continue;
|
|
}
|
|
data = temp_function.KernelLibrary();
|
|
CollectKernelLibraryTokenPositions(data, interesting_script,
|
|
temp_function.kernel_offset(),
|
|
temp_function.KernelLibraryOffset(),
|
|
zone, &helper, token_positions);
|
|
} else if (entry.IsField()) {
|
|
const Field& field = Field::Cast(entry);
|
|
if (field.kernel_offset() <= 0) {
|
|
// Skip artificially injected fields.
|
|
continue;
|
|
}
|
|
entry_script = field.Script();
|
|
if (entry_script.ptr() != interesting_script.ptr()) {
|
|
continue;
|
|
}
|
|
data = field.KernelLibrary();
|
|
CollectKernelLibraryTokenPositions(
|
|
data, interesting_script, field.kernel_offset(),
|
|
field.KernelLibraryOffset(), zone, &helper, token_positions);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace kernel
|
|
|
|
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
|
|
ArrayPtr Script::CollectConstConstructorCoverageFromKernel() const {
|
|
Thread* thread = Thread::Current();
|
|
Zone* zone = thread->zone();
|
|
kernel::TranslationHelper helper(thread);
|
|
|
|
const auto& interesting_script = *this;
|
|
|
|
const auto& kernel_info =
|
|
KernelProgramInfo::Handle(zone, kernel_program_info());
|
|
helper.InitFromKernelProgramInfo(kernel_info);
|
|
|
|
const auto& data = TypedDataView::Handle(
|
|
zone, interesting_script.kernel_constant_coverage());
|
|
|
|
kernel::KernelReaderHelper kernel_reader(zone, &helper, data, 0);
|
|
|
|
// Read "constant coverage constructors". Note that this also includes
|
|
// "constructors" for extensions type which is actually toplevel methods.
|
|
const intptr_t constant_coverage_constructors =
|
|
kernel_reader.ReadListLength();
|
|
const Array& constructors =
|
|
Array::Handle(Array::New(constant_coverage_constructors));
|
|
Object& member = Object::Handle(zone);
|
|
Function& target = Function::Handle(zone);
|
|
for (intptr_t i = 0; i < constant_coverage_constructors; ++i) {
|
|
kernel::NameIndex kernel_name = kernel_reader.ReadCanonicalNameReference();
|
|
member = helper.LookupMemberByMember(kernel_name);
|
|
ASSERT(member.IsFunction());
|
|
target = Function::Cast(member).ptr();
|
|
constructors.SetAt(i, target);
|
|
}
|
|
return constructors.ptr();
|
|
}
|
|
#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
|
|
|
|
namespace kernel {
|
|
|
|
ObjectPtr EvaluateStaticConstFieldInitializer(const Field& field) {
|
|
ASSERT(field.is_static() && field.is_const());
|
|
|
|
Thread* thread = Thread::Current();
|
|
LongJumpScope jump(thread);
|
|
if (DART_SETJMP(*jump.Set()) == 0) {
|
|
Zone* zone = thread->zone();
|
|
TranslationHelper helper(thread);
|
|
auto& kernel_program_info =
|
|
KernelProgramInfo::Handle(zone, field.KernelProgramInfo());
|
|
helper.InitFromKernelProgramInfo(kernel_program_info);
|
|
|
|
const Class& owner_class = Class::Handle(zone, field.Owner());
|
|
ActiveClass active_class;
|
|
ActiveClassScope active_class_scope(&active_class, &owner_class);
|
|
|
|
KernelReaderHelper kernel_reader(
|
|
zone, &helper, TypedDataView::Handle(zone, field.KernelLibrary()),
|
|
field.KernelLibraryOffset());
|
|
kernel_reader.SetOffset(field.kernel_offset());
|
|
ConstantReader constant_reader(&kernel_reader, &active_class);
|
|
|
|
FieldHelper field_helper(&kernel_reader);
|
|
field_helper.ReadUntilExcluding(FieldHelper::kInitializer);
|
|
ASSERT(field_helper.IsConst());
|
|
|
|
return constant_reader.ReadConstantInitializer();
|
|
} else {
|
|
return thread->StealStickyError();
|
|
}
|
|
}
|
|
|
|
class MetadataEvaluator : public KernelReaderHelper {
|
|
public:
|
|
MetadataEvaluator(Zone* zone,
|
|
TranslationHelper* translation_helper,
|
|
const TypedDataView& data,
|
|
intptr_t data_program_offset,
|
|
ActiveClass* active_class)
|
|
: KernelReaderHelper(zone, translation_helper, data, data_program_offset),
|
|
constant_reader_(this, active_class) {}
|
|
|
|
ObjectPtr EvaluateMetadata(intptr_t kernel_offset,
|
|
bool is_annotations_offset) {
|
|
SetOffset(kernel_offset);
|
|
|
|
// Library and LibraryDependency objects do not have a tag in kernel binary.
|
|
// Synthetic metadata fields corresponding to these objects keep kernel
|
|
// offset of annotations list instead of annotated object.
|
|
if (!is_annotations_offset) {
|
|
const Tag tag = PeekTag();
|
|
|
|
if (tag == kClass) {
|
|
ClassHelper class_helper(this);
|
|
class_helper.ReadUntilExcluding(ClassHelper::kAnnotations);
|
|
} else if (tag == kProcedure) {
|
|
ProcedureHelper procedure_helper(this);
|
|
procedure_helper.ReadUntilExcluding(ProcedureHelper::kAnnotations);
|
|
} else if (tag == kField) {
|
|
FieldHelper field_helper(this);
|
|
field_helper.ReadUntilExcluding(FieldHelper::kAnnotations);
|
|
} else if (tag == kConstructor) {
|
|
ConstructorHelper constructor_helper(this);
|
|
constructor_helper.ReadUntilExcluding(ConstructorHelper::kAnnotations);
|
|
} else if (tag == kFunctionDeclaration) {
|
|
ReadTag();
|
|
ReadPosition(); // fileOffset
|
|
VariableHelper variable_helper(this);
|
|
variable_helper.ReadUntilExcluding(VariableHelper::kAnnotations);
|
|
} else {
|
|
FATAL("No support for metadata on this type of kernel node: %" Pd32
|
|
"\n",
|
|
tag);
|
|
}
|
|
}
|
|
|
|
return constant_reader_.ReadAnnotations();
|
|
}
|
|
|
|
private:
|
|
ConstantReader constant_reader_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(MetadataEvaluator);
|
|
};
|
|
|
|
ObjectPtr EvaluateMetadata(const Library& library,
|
|
intptr_t kernel_offset,
|
|
bool is_annotations_offset) {
|
|
Thread* thread = Thread::Current();
|
|
LongJumpScope jump(thread);
|
|
if (DART_SETJMP(*jump.Set()) == 0) {
|
|
Zone* zone = thread->zone();
|
|
TranslationHelper helper(thread);
|
|
const auto& kernel_info =
|
|
KernelProgramInfo::Handle(zone, library.kernel_program_info());
|
|
helper.InitFromKernelProgramInfo(kernel_info);
|
|
|
|
const Class& owner_class = Class::Handle(zone, library.toplevel_class());
|
|
ActiveClass active_class;
|
|
ActiveClassScope active_class_scope(&active_class, &owner_class);
|
|
|
|
MetadataEvaluator metadata_evaluator(
|
|
zone, &helper, TypedDataView::Handle(zone, library.KernelLibrary()),
|
|
library.KernelLibraryOffset(), &active_class);
|
|
|
|
return metadata_evaluator.EvaluateMetadata(kernel_offset,
|
|
is_annotations_offset);
|
|
|
|
} else {
|
|
return thread->StealStickyError();
|
|
}
|
|
}
|
|
|
|
class ParameterDescriptorBuilder : public KernelReaderHelper {
|
|
public:
|
|
ParameterDescriptorBuilder(TranslationHelper* translation_helper,
|
|
Zone* zone,
|
|
const TypedDataView& data,
|
|
intptr_t data_program_offset,
|
|
ActiveClass* active_class)
|
|
: KernelReaderHelper(zone, translation_helper, data, data_program_offset),
|
|
constant_reader_(this, active_class) {}
|
|
|
|
ObjectPtr BuildParameterDescriptor(const Function& function);
|
|
|
|
private:
|
|
ConstantReader constant_reader_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(ParameterDescriptorBuilder);
|
|
};
|
|
|
|
ObjectPtr ParameterDescriptorBuilder::BuildParameterDescriptor(
|
|
const Function& function) {
|
|
SetOffset(function.kernel_offset());
|
|
ReadUntilFunctionNode();
|
|
FunctionNodeHelper function_node_helper(this);
|
|
function_node_helper.ReadUntilExcluding(
|
|
FunctionNodeHelper::kPositionalParameters);
|
|
intptr_t param_count = function_node_helper.total_parameter_count_;
|
|
intptr_t positional_count = ReadListLength(); // read list length.
|
|
intptr_t named_parameter_count = param_count - positional_count;
|
|
|
|
const Array& param_descriptor = Array::Handle(
|
|
Array::New(param_count * Parser::kParameterEntrySize, Heap::kOld));
|
|
for (intptr_t i = 0; i < param_count; ++i) {
|
|
const intptr_t entry_start = i * Parser::kParameterEntrySize;
|
|
|
|
if (i == positional_count) {
|
|
intptr_t named_parameter_count_check =
|
|
ReadListLength(); // read list length.
|
|
ASSERT(named_parameter_count_check == named_parameter_count);
|
|
}
|
|
|
|
// Read ith variable declaration.
|
|
intptr_t param_kernel_offset = reader_.offset();
|
|
VariableHelper helper(this);
|
|
helper.ReadUntilExcluding(VariableHelper::kInitializer);
|
|
param_descriptor.SetAt(entry_start + Parser::kParameterIsFinalOffset,
|
|
helper.IsFinal() ? Bool::True() : Bool::False());
|
|
|
|
Tag tag = ReadTag(); // read (first part of) initializer.
|
|
if ((tag == kSomething) && !function.is_abstract()) {
|
|
// This will read the initializer.
|
|
Instance& constant = Instance::ZoneHandle(
|
|
zone_, constant_reader_.ReadConstantExpression());
|
|
param_descriptor.SetAt(entry_start + Parser::kParameterDefaultValueOffset,
|
|
constant);
|
|
} else {
|
|
if (tag == kSomething) {
|
|
SkipExpression(); // Skip initializer.
|
|
}
|
|
param_descriptor.SetAt(entry_start + Parser::kParameterDefaultValueOffset,
|
|
Object::null_instance());
|
|
}
|
|
|
|
if (FLAG_enable_mirrors && (helper.annotation_count_ > 0)) {
|
|
AlternativeReadingScope alt(&reader_, param_kernel_offset);
|
|
VariableHelper helper(this);
|
|
helper.ReadUntilExcluding(VariableHelper::kAnnotations);
|
|
Object& metadata =
|
|
Object::ZoneHandle(zone_, constant_reader_.ReadAnnotations());
|
|
param_descriptor.SetAt(entry_start + Parser::kParameterMetadataOffset,
|
|
metadata);
|
|
} else {
|
|
param_descriptor.SetAt(entry_start + Parser::kParameterMetadataOffset,
|
|
Object::null_instance());
|
|
}
|
|
}
|
|
return param_descriptor.ptr();
|
|
}
|
|
|
|
ObjectPtr BuildParameterDescriptor(const Function& function) {
|
|
Thread* thread = Thread::Current();
|
|
LongJumpScope jump(thread);
|
|
if (DART_SETJMP(*jump.Set()) == 0) {
|
|
Zone* zone = thread->zone();
|
|
|
|
const auto& kernel_info =
|
|
KernelProgramInfo::Handle(zone, function.KernelProgramInfo());
|
|
|
|
TranslationHelper helper(thread);
|
|
helper.InitFromKernelProgramInfo(kernel_info);
|
|
|
|
const Class& owner_class = Class::Handle(zone, function.Owner());
|
|
ActiveClass active_class;
|
|
ActiveClassScope active_class_scope(&active_class, &owner_class);
|
|
|
|
ParameterDescriptorBuilder builder(
|
|
&helper, zone, TypedDataView::Handle(zone, function.KernelLibrary()),
|
|
function.KernelLibraryOffset(), &active_class);
|
|
|
|
return builder.BuildParameterDescriptor(function);
|
|
} else {
|
|
return thread->StealStickyError();
|
|
}
|
|
}
|
|
|
|
void ReadParameterCovariance(const Function& function,
|
|
BitVector* is_covariant,
|
|
BitVector* is_generic_covariant_impl) {
|
|
Thread* thread = Thread::Current();
|
|
Zone* zone = thread->zone();
|
|
|
|
const intptr_t num_params = function.NumParameters();
|
|
ASSERT(is_covariant->length() == num_params);
|
|
ASSERT(is_generic_covariant_impl->length() == num_params);
|
|
|
|
const auto& kernel_info =
|
|
KernelProgramInfo::Handle(zone, function.KernelProgramInfo());
|
|
|
|
TranslationHelper translation_helper(thread);
|
|
translation_helper.InitFromKernelProgramInfo(kernel_info);
|
|
|
|
KernelReaderHelper reader_helper(
|
|
zone, &translation_helper,
|
|
TypedDataView::Handle(zone, function.KernelLibrary()),
|
|
function.KernelLibraryOffset());
|
|
|
|
reader_helper.SetOffset(function.kernel_offset());
|
|
reader_helper.ReadUntilFunctionNode();
|
|
|
|
FunctionNodeHelper function_node_helper(&reader_helper);
|
|
function_node_helper.ReadUntilExcluding(
|
|
FunctionNodeHelper::kPositionalParameters);
|
|
|
|
// Positional.
|
|
const intptr_t num_positional_params = reader_helper.ReadListLength();
|
|
intptr_t param_index = function.NumImplicitParameters();
|
|
for (intptr_t i = 0; i < num_positional_params; ++i, ++param_index) {
|
|
VariableHelper helper(&reader_helper);
|
|
helper.ReadUntilExcluding(VariableHelper::kEnd);
|
|
|
|
if (helper.IsCovariant()) {
|
|
is_covariant->Add(param_index);
|
|
}
|
|
if (helper.IsGenericCovariantImpl()) {
|
|
is_generic_covariant_impl->Add(param_index);
|
|
}
|
|
}
|
|
|
|
// Named.
|
|
const intptr_t num_named_params = reader_helper.ReadListLength();
|
|
for (intptr_t i = 0; i < num_named_params; ++i, ++param_index) {
|
|
VariableHelper helper(&reader_helper);
|
|
helper.ReadUntilExcluding(VariableHelper::kEnd);
|
|
|
|
if (helper.IsCovariant()) {
|
|
is_covariant->Add(param_index);
|
|
}
|
|
if (helper.IsGenericCovariantImpl()) {
|
|
is_generic_covariant_impl->Add(param_index);
|
|
}
|
|
}
|
|
}
|
|
|
|
static ProcedureAttributesMetadata ProcedureAttributesOf(
|
|
Zone* zone,
|
|
const KernelProgramInfo& kernel_program_info,
|
|
const TypedDataView& kernel_data,
|
|
intptr_t kernel_data_program_offset,
|
|
intptr_t kernel_offset) {
|
|
TranslationHelper translation_helper(Thread::Current());
|
|
translation_helper.InitFromKernelProgramInfo(kernel_program_info);
|
|
KernelReaderHelper reader_helper(zone, &translation_helper, kernel_data,
|
|
kernel_data_program_offset);
|
|
ProcedureAttributesMetadataHelper procedure_attributes_metadata_helper(
|
|
&reader_helper);
|
|
ProcedureAttributesMetadata attrs =
|
|
procedure_attributes_metadata_helper.GetProcedureAttributes(
|
|
kernel_offset);
|
|
return attrs;
|
|
}
|
|
|
|
ProcedureAttributesMetadata ProcedureAttributesOf(const Function& function,
|
|
Zone* zone) {
|
|
const auto& kernel_program_info =
|
|
KernelProgramInfo::Handle(zone, function.KernelProgramInfo());
|
|
return ProcedureAttributesOf(
|
|
zone, kernel_program_info,
|
|
TypedDataView::Handle(zone, function.KernelLibrary()),
|
|
function.KernelLibraryOffset(), function.kernel_offset());
|
|
}
|
|
|
|
ProcedureAttributesMetadata ProcedureAttributesOf(const Field& field,
|
|
Zone* zone) {
|
|
const auto& kernel_program_info =
|
|
KernelProgramInfo::Handle(zone, field.KernelProgramInfo());
|
|
return ProcedureAttributesOf(
|
|
zone, kernel_program_info,
|
|
TypedDataView::Handle(zone, field.KernelLibrary()),
|
|
field.KernelLibraryOffset(), field.kernel_offset());
|
|
}
|
|
|
|
static UnboxingInfoMetadata* UnboxingInfoMetadataOf(
|
|
Zone* zone,
|
|
const KernelProgramInfo& kernel_program_info,
|
|
const TypedDataView& kernel_data,
|
|
intptr_t kernel_data_program_offset,
|
|
intptr_t kernel_offset) {
|
|
TranslationHelper translation_helper(Thread::Current());
|
|
translation_helper.InitFromKernelProgramInfo(kernel_program_info);
|
|
KernelReaderHelper reader_helper(zone, &translation_helper, kernel_data,
|
|
kernel_data_program_offset);
|
|
UnboxingInfoMetadataHelper unboxing_info_metadata_helper(&reader_helper);
|
|
return unboxing_info_metadata_helper.GetUnboxingInfoMetadata(kernel_offset);
|
|
}
|
|
|
|
UnboxingInfoMetadata* UnboxingInfoMetadataOf(const Function& function,
|
|
Zone* zone) {
|
|
const auto& kernel_program_info =
|
|
KernelProgramInfo::Handle(zone, function.KernelProgramInfo());
|
|
return UnboxingInfoMetadataOf(
|
|
zone, kernel_program_info,
|
|
TypedDataView::Handle(zone, function.KernelLibrary()),
|
|
function.KernelLibraryOffset(), function.kernel_offset());
|
|
}
|
|
|
|
TableSelectorMetadata* TableSelectorMetadataForProgram(
|
|
const KernelProgramInfo& info,
|
|
Zone* zone) {
|
|
TranslationHelper translation_helper(Thread::Current());
|
|
translation_helper.InitFromKernelProgramInfo(info);
|
|
const auto& data = TypedDataView::Handle(zone, info.metadata_payloads());
|
|
KernelReaderHelper reader_helper(zone, &translation_helper, data, 0);
|
|
TableSelectorMetadataHelper table_selector_metadata_helper(&reader_helper);
|
|
return table_selector_metadata_helper.GetTableSelectorMetadata(zone);
|
|
}
|
|
|
|
} // namespace kernel
|
|
} // namespace dart
|
|
|
|
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|