[wasm] Refactor the module decoder to work with section bytes
This CL refactors the module decoder so that it can process a list of section buffers instead of one module buffer. This change is needed for streaming compilation. Streaming compilation may require additional changes. This CL introduces the following interface to the module decoder: StartDecoding -- starts the decoding DecodeModuleHeader -- decodes the module header DecodeSection -- decodes the section FinishDecoding -- finishes the decoding and returns the WasmModule Aside from the different interface the biggest change to the module decoder is the introduction of a buffer_offset, which is the offset of the current section buffer of the module decoder in the module bytes. This buffer_offset is used to translate from section offsets to module offsets and back. Another nice change is that the module decoder does not have a zone anymore. Instead the zone is stored directly in the WasmModule where it belongs. Zone ownership is also more obvious now. R=mtrofin@chromium.org, clemensh@chromium.org Change-Id: I815d777ec380f4c617c39e828ea0c9746c0bae20 Reviewed-on: https://chromium-review.googlesource.com/505490 Commit-Queue: Andreas Haas <ahaas@chromium.org> Reviewed-by: Clemens Hammacher <clemensh@chromium.org> Cr-Commit-Position: refs/heads/master@{#45374}
This commit is contained in:
parent
4bbe21671b
commit
a8424d592f
@ -37,10 +37,11 @@ namespace wasm {
|
|||||||
// a buffer of bytes.
|
// a buffer of bytes.
|
||||||
class Decoder {
|
class Decoder {
|
||||||
public:
|
public:
|
||||||
Decoder(const byte* start, const byte* end)
|
Decoder(const byte* start, const byte* end, uint32_t buffer_offset = 0)
|
||||||
: start_(start), pc_(start), end_(end), error_offset_(0) {}
|
: start_(start), pc_(start), end_(end), buffer_offset_(buffer_offset) {}
|
||||||
Decoder(const byte* start, const byte* pc, const byte* end)
|
Decoder(const byte* start, const byte* pc, const byte* end,
|
||||||
: start_(start), pc_(pc), end_(end), error_offset_(0) {}
|
uint32_t buffer_offset = 0)
|
||||||
|
: start_(start), pc_(pc), end_(end), buffer_offset_(buffer_offset) {}
|
||||||
|
|
||||||
virtual ~Decoder() {}
|
virtual ~Decoder() {}
|
||||||
|
|
||||||
@ -183,7 +184,7 @@ class Decoder {
|
|||||||
va_end(arguments);
|
va_end(arguments);
|
||||||
error_msg_.assign(buffer.start(), len);
|
error_msg_.assign(buffer.start(), len);
|
||||||
DCHECK_GE(pc, start_);
|
DCHECK_GE(pc, start_);
|
||||||
error_offset_ = static_cast<uint32_t>(pc - start_);
|
error_offset_ = static_cast<uint32_t>(pc - start_) + buffer_offset_;
|
||||||
onFirstError();
|
onFirstError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,28 +215,44 @@ class Decoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Resets the boundaries of this decoder.
|
// Resets the boundaries of this decoder.
|
||||||
void Reset(const byte* start, const byte* end) {
|
void Reset(const byte* start, const byte* end, uint32_t buffer_offset = 0) {
|
||||||
start_ = start;
|
start_ = start;
|
||||||
pc_ = start;
|
pc_ = start;
|
||||||
end_ = end;
|
end_ = end;
|
||||||
|
buffer_offset_ = buffer_offset;
|
||||||
error_offset_ = 0;
|
error_offset_ = 0;
|
||||||
error_msg_.clear();
|
error_msg_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Reset(Vector<const uint8_t> bytes, uint32_t buffer_offset = 0) {
|
||||||
|
Reset(bytes.begin(), bytes.end(), buffer_offset);
|
||||||
|
}
|
||||||
|
|
||||||
bool ok() const { return error_msg_.empty(); }
|
bool ok() const { return error_msg_.empty(); }
|
||||||
bool failed() const { return !ok(); }
|
bool failed() const { return !ok(); }
|
||||||
bool more() const { return pc_ < end_; }
|
bool more() const { return pc_ < end_; }
|
||||||
|
|
||||||
const byte* start() const { return start_; }
|
const byte* start() const { return start_; }
|
||||||
const byte* pc() const { return pc_; }
|
const byte* pc() const { return pc_; }
|
||||||
uint32_t pc_offset() const { return static_cast<uint32_t>(pc_ - start_); }
|
uint32_t pc_offset() const {
|
||||||
|
return static_cast<uint32_t>(pc_ - start_) + buffer_offset_;
|
||||||
|
}
|
||||||
|
uint32_t buffer_offset() const { return buffer_offset_; }
|
||||||
|
// Takes an offset relative to the module start and returns an offset relative
|
||||||
|
// to the current buffer of the decoder.
|
||||||
|
uint32_t GetBufferRelativeOffset(uint32_t offset) const {
|
||||||
|
DCHECK_LE(buffer_offset_, offset);
|
||||||
|
return offset - buffer_offset_;
|
||||||
|
}
|
||||||
const byte* end() const { return end_; }
|
const byte* end() const { return end_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const byte* start_;
|
const byte* start_;
|
||||||
const byte* pc_;
|
const byte* pc_;
|
||||||
const byte* end_;
|
const byte* end_;
|
||||||
uint32_t error_offset_;
|
// The offset of the current buffer in the module. Needed for streaming.
|
||||||
|
uint32_t buffer_offset_;
|
||||||
|
uint32_t error_offset_ = 0;
|
||||||
std::string error_msg_;
|
std::string error_msg_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -20,7 +20,7 @@ const uint8_t kWasmFunctionTypeForm = 0x60;
|
|||||||
const uint8_t kWasmAnyFunctionTypeForm = 0x70;
|
const uint8_t kWasmAnyFunctionTypeForm = 0x70;
|
||||||
const uint8_t kResizableMaximumFlag = 1;
|
const uint8_t kResizableMaximumFlag = 1;
|
||||||
|
|
||||||
enum SectionCode {
|
enum SectionCode : int8_t {
|
||||||
kUnknownSectionCode = 0, // code for unknown sections
|
kUnknownSectionCode = 0, // code for unknown sections
|
||||||
kTypeSectionCode = 1, // Function signature declarations
|
kTypeSectionCode = 1, // Function signature declarations
|
||||||
kImportSectionCode = 2, // Import declarations
|
kImportSectionCode = 2, // Import declarations
|
||||||
@ -34,6 +34,9 @@ enum SectionCode {
|
|||||||
kCodeSectionCode = 10, // Function code
|
kCodeSectionCode = 10, // Function code
|
||||||
kDataSectionCode = 11, // Data segments
|
kDataSectionCode = 11, // Data segments
|
||||||
kNameSectionCode = 12, // Name section (encoded as a string)
|
kNameSectionCode = 12, // Name section (encoded as a string)
|
||||||
|
|
||||||
|
// Helper values
|
||||||
|
kFirstSectionInModule = kTypeSectionCode,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum NameSectionType : uint8_t { kFunction = 1, kLocal = 2 };
|
enum NameSectionType : uint8_t { kFunction = 1, kLocal = 2 };
|
||||||
|
@ -960,8 +960,8 @@ WasmInstanceObject* wasm::GetOwningWasmInstance(Code* code) {
|
|||||||
return WasmInstanceObject::cast(cell->value());
|
return WasmInstanceObject::cast(cell->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
WasmModule::WasmModule(Zone* owned)
|
WasmModule::WasmModule(std::unique_ptr<Zone> owned)
|
||||||
: owned_zone(owned), pending_tasks(new base::Semaphore(0)) {}
|
: signature_zone(std::move(owned)), pending_tasks(new base::Semaphore(0)) {}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ struct V8_EXPORT_PRIVATE WasmModule {
|
|||||||
static const uint32_t kPageSize = 0x10000; // Page size, 64kb.
|
static const uint32_t kPageSize = 0x10000; // Page size, 64kb.
|
||||||
static const uint32_t kMinMemPages = 1; // Minimum memory size = 64kb
|
static const uint32_t kMinMemPages = 1; // Minimum memory size = 64kb
|
||||||
|
|
||||||
Zone* owned_zone;
|
std::unique_ptr<Zone> signature_zone;
|
||||||
uint32_t min_mem_pages = 0; // minimum size of the memory in 64k pages
|
uint32_t min_mem_pages = 0; // minimum size of the memory in 64k pages
|
||||||
uint32_t max_mem_pages = 0; // maximum size of the memory in 64k pages
|
uint32_t max_mem_pages = 0; // maximum size of the memory in 64k pages
|
||||||
bool has_max_mem = false; // try if a maximum memory size exists
|
bool has_max_mem = false; // try if a maximum memory size exists
|
||||||
@ -185,10 +185,7 @@ struct V8_EXPORT_PRIVATE WasmModule {
|
|||||||
std::unique_ptr<base::Semaphore> pending_tasks;
|
std::unique_ptr<base::Semaphore> pending_tasks;
|
||||||
|
|
||||||
WasmModule() : WasmModule(nullptr) {}
|
WasmModule() : WasmModule(nullptr) {}
|
||||||
WasmModule(Zone* owned_zone);
|
WasmModule(std::unique_ptr<Zone> owned);
|
||||||
~WasmModule() {
|
|
||||||
if (owned_zone) delete owned_zone;
|
|
||||||
}
|
|
||||||
|
|
||||||
ModuleOrigin get_origin() const { return origin_; }
|
ModuleOrigin get_origin() const { return origin_; }
|
||||||
void set_origin(ModuleOrigin new_value) { origin_ = new_value; }
|
void set_origin(ModuleOrigin new_value) { origin_ = new_value; }
|
||||||
|
Loading…
Reference in New Issue
Block a user