Commit d9b42b7b authored by Andreas Haas's avatar Andreas Haas Committed by Commit Bot

[wasm] Handle modules without code in streaming compilation

Streaming compilation started the compilation of a module at the
beginning of the code section. However, there exist valid modules which
do not contain a code section. In this CL we check for the existence of
a code section when we finish the stream. We do this by checking if the
module compiler in the AsyncCompileJob exists, because the module
compiler gets initialized at the beginning of the code section.

If we detect that compilation has not been started because there was no
code section, then we start compilation when the stream finishes.

R=clemensh@chromium.org

Bug: chromium:771973
Change-Id: I7c95a7a791d02254f086961e7cd81885eec27382
Reviewed-on: https://chromium-review.googlesource.com/778541
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49494}
parent 209d3790
......@@ -3489,8 +3489,18 @@ void AsyncStreamingProcessor::OnFinishedStream(std::unique_ptr<uint8_t[]> bytes,
ModuleResult result = decoder_.FinishDecoding(false);
DCHECK(result.ok());
job_->module_ = std::move(result.val);
if (job_->DecrementAndCheckFinisherCount())
job_->DoSync<AsyncCompileJob::FinishCompile>();
if (job_->DecrementAndCheckFinisherCount()) {
if (!job_->compiler_) {
// We are processing a WebAssembly module without code section. We need to
// prepare compilation first before we can finish it.
// {PrepareAndStartCompile} will call {FinishCompile} by itself if there
// is no code section.
job_->DoSync<AsyncCompileJob::PrepareAndStartCompile>(job_->module_.get(),
true);
} else {
job_->DoSync<AsyncCompileJob::FinishCompile>();
}
}
}
// Report an error detected in the StreamingDecoder.
......
......@@ -385,8 +385,7 @@ StreamingDecoder::DecodeNumberOfFunctions::NextWithValue(
section_buffer(), section_buffer()->payload_offset() + bytes_needed(),
value());
} else {
if (section_buffer()->payload_offset() + size() !=
section_buffer()->length()) {
if (section_buffer()->payload_length() != bytes_needed()) {
return streaming->Error("not all code section bytes were used");
}
return base::make_unique<DecodeSectionID>(streaming->module_offset());
......
......@@ -835,6 +835,42 @@ STREAM_TEST(TestAbortAfterCompilationError2) {
tester.RunCompilerTasks();
}
STREAM_TEST(TestOnlyModuleHeader) {
StreamTester tester;
const uint8_t bytes[] = {
WASM_MODULE_HEADER, // module header
};
tester.OnBytesReceived(bytes, arraysize(bytes));
tester.FinishStream();
tester.RunCompilerTasks();
CHECK(tester.IsPromiseFulfilled());
}
STREAM_TEST(TestModuleWithZeroFunctions) {
StreamTester tester;
const uint8_t bytes[] = {
WASM_MODULE_HEADER, // module header
kTypeSectionCode, // section code
U32V_1(1), // section size
U32V_1(0), // type count
kFunctionSectionCode, // section code
U32V_1(1), // section size
U32V_1(0), // functions count
kCodeSectionCode, // section code
U32V_1(1), // section size
U32V_1(0), // functions count
};
tester.OnBytesReceived(bytes, arraysize(bytes));
tester.FinishStream();
tester.RunCompilerTasks();
CHECK(tester.IsPromiseFulfilled());
}
#undef STREAM_TEST
} // namespace wasm
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment