Allow the VM to read Kernel files with external libraries

The meaning of a Kernel file with an external library is that the
library is one that is already known to be loaded in the VM.

Fixes issue #30111.

BUG=https://github.com/dart-lang/sdk/issues/30111
R=jensj@google.com

Review-Url: https://codereview.chromium.org/2995423002 .
This commit is contained in:
Kevin Millikin 2017-08-22 16:05:16 +02:00
parent d1385f099f
commit 2f49198520
6 changed files with 27 additions and 29 deletions

View file

@ -206,7 +206,7 @@ class Reader {
bool ReadBool() { return (ReadByte() & 1) == 1; }
word ReadFlags() { return ReadByte(); }
uint8_t ReadFlags() { return ReadByte(); }
Tag ReadTag(uint8_t* payload = NULL) {
uint8_t byte = ReadByte();

View file

@ -87,7 +87,7 @@ void VariableDeclarationHelper::ReadUntilExcluding(Field field) {
equals_position_ = builder_->ReadPosition(); // read equals position.
if (++next_read_ == field) return;
case kFlags:
flags_ = builder_->ReadFlags(); // read flags.
flags_ = builder_->ReadFlags();
if (++next_read_ == field) return;
case kNameIndex:
name_index_ = builder_->ReadStringReference(); // read name index.
@ -133,7 +133,7 @@ void FieldHelper::ReadUntilExcluding(Field field,
end_position_ = builder_->ReadPosition(false); // read end position.
if (++next_read_ == field) return;
case kFlags:
flags_ = builder_->ReadFlags(); // read flags.
flags_ = builder_->ReadFlags();
if (++next_read_ == field) return;
case kName:
builder_->SkipName(); // read name.
@ -205,7 +205,7 @@ void ProcedureHelper::ReadUntilExcluding(Field field) {
kind_ = static_cast<Kind>(builder_->ReadByte());
if (++next_read_ == field) return;
case kFlags:
flags_ = builder_->ReadFlags(); // read flags.
flags_ = builder_->ReadFlags();
if (++next_read_ == field) return;
case kName:
builder_->SkipName(); // read name.
@ -256,7 +256,7 @@ void ConstructorHelper::ReadUntilExcluding(Field field) {
end_position_ = builder_->ReadPosition(); // read end position.
if (++next_read_ == field) return;
case kFlags:
flags_ = builder_->ReadFlags(); // read flags.
flags_ = builder_->ReadFlags();
if (++next_read_ == field) return;
case kName:
builder_->SkipName(); // read name.
@ -410,8 +410,7 @@ void LibraryHelper::ReadUntilExcluding(Field field) {
// Ordered with fall-through.
switch (next_read_) {
case kFlags: {
word flags = builder_->ReadFlags(); // read flags.
ASSERT(flags == 0); // external libraries not supported
flags_ = builder_->ReadFlags();
if (++next_read_ == field) return;
}
case kCanonicalName:
@ -4660,11 +4659,11 @@ void StreamingFlowGraphBuilder::SkipLibraryCombinator() {
}
void StreamingFlowGraphBuilder::SkipLibraryDependency() {
ReadFlags(); // read flags.
SkipListOfExpressions(); // Read annotations.
ReadCanonicalNameReference(); // read target_reference.
ReadStringReference(); // read name_index.
intptr_t combinator_count = ReadListLength(); // read list length.
ReadFlags();
SkipListOfExpressions(); // Annotations.
ReadCanonicalNameReference();
ReadStringReference(); // Name.
intptr_t combinator_count = ReadListLength();
for (intptr_t i = 0; i < combinator_count; ++i) {
SkipLibraryCombinator();
}
@ -4714,10 +4713,6 @@ Tag StreamingFlowGraphBuilder::PeekTag(uint8_t* payload) {
return reader_->PeekTag(payload);
}
word StreamingFlowGraphBuilder::ReadFlags() {
return reader_->ReadFlags();
}
void StreamingFlowGraphBuilder::loop_depth_inc() {
++flow_graph_builder_->loop_depth_;
}

View file

@ -119,7 +119,7 @@ class VariableDeclarationHelper {
TokenPosition position_;
TokenPosition equals_position_;
word flags_;
uint8_t flags_;
StringIndex name_index_;
private:
@ -190,7 +190,7 @@ class FieldHelper {
NameIndex canonical_name_;
TokenPosition position_;
TokenPosition end_position_;
word flags_;
uint8_t flags_;
intptr_t source_uri_index_;
intptr_t annotation_count_;
@ -265,7 +265,7 @@ class ProcedureHelper {
TokenPosition position_;
TokenPosition end_position_;
Kind kind_;
word flags_;
uint8_t flags_;
intptr_t source_uri_index_;
intptr_t annotation_count_;
@ -322,7 +322,7 @@ class ConstructorHelper {
NameIndex canonical_name_;
TokenPosition position_;
TokenPosition end_position_;
word flags_;
uint8_t flags_;
intptr_t annotation_count_;
private:
@ -410,6 +410,10 @@ class LibraryHelper {
kEnd,
};
enum Flag {
kExternal = 1,
};
explicit LibraryHelper(StreamingFlowGraphBuilder* builder) {
builder_ = builder;
next_read_ = kFlags;
@ -424,6 +428,9 @@ class LibraryHelper {
void SetNext(Field field) { next_read_ = field; }
void SetJustRead(Field field) { next_read_ = field + 1; }
bool IsExternal() const { return (flags_ & kExternal) != 0; }
uint8_t flags_;
NameIndex canonical_name_;
StringIndex name_index_;
intptr_t source_uri_index_;
@ -837,7 +844,7 @@ class StreamingFlowGraphBuilder {
void record_yield_position(TokenPosition position);
Tag ReadTag(uint8_t* payload = NULL);
Tag PeekTag(uint8_t* payload = NULL);
word ReadFlags();
uint8_t ReadFlags() { return reader_->ReadFlags(); }
void loop_depth_inc();
void loop_depth_dec();

View file

@ -253,6 +253,8 @@ void KernelReader::ReadLibrary(intptr_t kernel_offset) {
LibraryHelper library_helper(&builder_);
library_helper.ReadUntilIncluding(LibraryHelper::kCanonicalName);
Library& library = LookupLibrary(library_helper.canonical_name_);
// The Kernel library is external implies that it is already loaded.
ASSERT(!library_helper.IsExternal() || library.Loaded());
if (library.Loaded()) return;
library_helper.ReadUntilIncluding(LibraryHelper::kName);

View file

@ -94,7 +94,7 @@ class KernelReader {
reader.set_offset(reader.ReadUInt32());
// Start reading library.
reader.ReadFlags(); // read flags.
reader.ReadFlags();
return reader.ReadCanonicalNameReference();
}

View file

@ -164,16 +164,10 @@ Future _main(List<String> argv) async {
Uri.parse('dart:$vmserviceName'),
new CompilerOptions()
..setExitCodeOnProblem = true
// TODO(sigmund): investigate. This should be outline, but it breaks
// vm-debug tests. Issue #30111
..sdkSummary = platform
..sdkSummary = outline
..librariesSpecificationUri = vmserviceJsonUri
..packagesFileUri = packages);
Uri vmserviceUri = outDirUri.resolve('$vmserviceName.dill');
// TODO(sigmund): remove. This is a workaround because in the VM
// doesn't support loading vmservice if it contains external libraries
// (there is an assertion that only fails in debug builds). Issue #30111
program.libraries.forEach((l) => l.isExternal = false);
await writeProgramToFile(program, vmserviceUri);
}