Commit cf7731e2 authored by Manos Koukoutos's avatar Manos Koukoutos Committed by Commit Bot

[wasm][refactor] Change signature of DecodeLocals.

We would like DecodeLocals to allow inserting new locals
in any position. This is useful for the upcoming 'let' instruction.

Bug: v8:7748
Change-Id: Ic7f2a7fba0f69ee76b0ace46bb0cecee9d047306
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2208859
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67936}
parent 5885c9e5
...@@ -952,24 +952,28 @@ class WasmDecoder : public Decoder { ...@@ -952,24 +952,28 @@ class WasmDecoder : public Decoder {
} }
} }
enum DecodeLocalsMode { kUpdateLocals, kNoUpdateLocals };
// Decodes local definitions in the current decoder. // Decodes local definitions in the current decoder.
// Returns true iff locals are found. // Returns true iff locals are found.
// Write the total length of decoded locals in 'total_length'. // Writes the total length of decoded locals in 'total_length'.
// If 'mode' is kPrependLocals, the 'local_types_' of this decoder // If insert_postion is present, the decoded locals will be inserted into the
// will be updated. Otherwise, this is used just to check legality and // 'local_types_' of this decoder. Otherwise, this function is used just to
// measure the size of the locals. // check validity and determine the encoding length of the locals in bytes.
// The decoder's pc is not advanced. // The decoder's pc is not advanced. If no locals are found (i.e., no
// If no locals are found (i.e., no compressed uint32 is found at pc), // compressed uint32 is found at pc), this will exit as 'false' and without an
// this will exit as 'false' and without an error. // error.
bool DecodeLocals(const byte* pc, uint32_t* total_length, bool DecodeLocals(const byte* pc, uint32_t* total_length,
DecodeLocalsMode mode) { const base::Optional<uint32_t> insert_position) {
DCHECK_NOT_NULL(local_types_); DCHECK_NOT_NULL(local_types_);
uint32_t length; uint32_t length;
*total_length = 0; *total_length = 0;
// The 'else' value is useless, we pass it for convenience.
ZoneVector<ValueType>::iterator insert_iterator =
insert_position.has_value()
? local_types_->begin() + insert_position.value()
: local_types_->begin();
// Decode local declarations, if any. // Decode local declarations, if any.
uint32_t entries = read_u32v<kValidate>(pc, &length, "local decls count"); uint32_t entries = read_u32v<kValidate>(pc, &length, "local decls count");
if (failed()) { if (failed()) {
...@@ -1005,8 +1009,9 @@ class WasmDecoder : public Decoder { ...@@ -1005,8 +1009,9 @@ class WasmDecoder : public Decoder {
return false; return false;
} }
*total_length += length; *total_length += length;
if (mode == kUpdateLocals) { if (insert_position.has_value()) {
local_types_->insert(local_types_->end(), count, type); insert_iterator =
local_types_->insert(insert_iterator, count, type) + count;
} }
} }
DCHECK(ok()); DCHECK(ok());
...@@ -1800,7 +1805,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -1800,7 +1805,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
this->InitializeLocalsFromSig(); this->InitializeLocalsFromSig();
uint32_t locals_length; uint32_t locals_length;
this->DecodeLocals(this->pc(), &locals_length, this->DecodeLocals(this->pc(), &locals_length,
WasmDecoder<validate>::kUpdateLocals); static_cast<uint32_t>(this->local_types_->size()));
this->consume_bytes(locals_length); this->consume_bytes(locals_length);
CALL_INTERFACE(StartFunction); CALL_INTERFACE(StartFunction);
......
...@@ -24,16 +24,21 @@ bool DecodeLocalDecls(const WasmFeatures& enabled, BodyLocalDecls* decls, ...@@ -24,16 +24,21 @@ bool DecodeLocalDecls(const WasmFeatures& enabled, BodyLocalDecls* decls,
WasmFeatures no_features = WasmFeatures::None(); WasmFeatures no_features = WasmFeatures::None();
WasmDecoder<Decoder::kValidate> decoder(nullptr, enabled, &no_features, WasmDecoder<Decoder::kValidate> decoder(nullptr, enabled, &no_features,
nullptr, start, end, 0); nullptr, start, end, 0);
// The decoded functions need to be inserted into &decls->type_list,
// so we pass a pointer to it to local_types_ which will be updated
// in DecodeLocals.
decoder.local_types_ = &decls->type_list; decoder.local_types_ = &decls->type_list;
uint32_t length; uint32_t length;
if (decoder.DecodeLocals(decoder.pc(), &length, if (decoder.DecodeLocals(
decoder.DecodeLocalsMode::kUpdateLocals)) { decoder.pc(), &length,
static_cast<uint32_t>(decoder.local_types_->size()))) {
DCHECK(decoder.ok()); DCHECK(decoder.ok());
decoder.consume_bytes(length); decls->encoded_size = length;
decls->encoded_size = decoder.pc_offset();
return true; return true;
} else {
decls->encoded_size = 0;
return false;
} }
return false;
} }
BytecodeIterator::BytecodeIterator(const byte* start, const byte* end, BytecodeIterator::BytecodeIterator(const byte* start, const byte* end,
......
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