Commit 3f24baf6 authored by Manos Koukoutos's avatar Manos Koukoutos Committed by V8 LUCI CQ

[wasm] Remove current global argument from consume_init_expr

We can get rid of this by deferring adding a new global to the module's
globals, and using the current size of globals to determine allowed
global indices.

Bug: v8:11895
Change-Id: Ide80eab2de4abdbab96a7298acf3665599c394ff
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2972908
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75295}
parent 6288483b
...@@ -752,7 +752,7 @@ class ModuleDecoderImpl : public Decoder { ...@@ -752,7 +752,7 @@ class ModuleDecoderImpl : public Decoder {
&table->initial_size, &table->has_maximum_size, &table->initial_size, &table->has_maximum_size,
std::numeric_limits<uint32_t>::max(), &table->maximum_size, flags); std::numeric_limits<uint32_t>::max(), &table->maximum_size, flags);
if (!table_type.is_defaultable()) { if (!table_type.is_defaultable()) {
table->initial_value = consume_init_expr(module_.get(), table_type, 0); table->initial_value = consume_init_expr(module_.get(), table_type);
} }
} }
} }
...@@ -777,14 +777,12 @@ class ModuleDecoderImpl : public Decoder { ...@@ -777,14 +777,12 @@ class ModuleDecoderImpl : public Decoder {
module_->globals.reserve(imported_globals + globals_count); module_->globals.reserve(imported_globals + globals_count);
for (uint32_t i = 0; ok() && i < globals_count; ++i) { for (uint32_t i = 0; ok() && i < globals_count; ++i) {
TRACE("DecodeGlobal[%d] module+%d\n", i, static_cast<int>(pc_ - start_)); TRACE("DecodeGlobal[%d] module+%d\n", i, static_cast<int>(pc_ - start_));
// Add an uninitialized global and pass a pointer to it. ValueType type = consume_value_type();
bool mutability = consume_mutability();
if (failed()) break;
WasmInitExpr init = consume_init_expr(module_.get(), type);
module_->globals.push_back( module_->globals.push_back(
{kWasmVoid, false, WasmInitExpr(), {0}, false, false}); {type, mutability, std::move(init), {0}, false, false});
WasmGlobal* global = &module_->globals.back();
global->type = consume_value_type();
global->mutability = consume_mutability();
global->init =
consume_init_expr(module_.get(), global->type, imported_globals + i);
} }
if (ok()) CalculateGlobalOffsets(module_.get()); if (ok()) CalculateGlobalOffsets(module_.get());
} }
...@@ -1386,7 +1384,7 @@ class ModuleDecoderImpl : public Decoder { ...@@ -1386,7 +1384,7 @@ class ModuleDecoderImpl : public Decoder {
} }
WasmInitExpr DecodeInitExprForTesting(ValueType expected) { WasmInitExpr DecodeInitExprForTesting(ValueType expected) {
return consume_init_expr(module_.get(), expected, 0); return consume_init_expr(module_.get(), expected);
} }
const std::shared_ptr<WasmModule>& shared_module() const { return module_; } const std::shared_ptr<WasmModule>& shared_module() const { return module_; }
...@@ -1689,8 +1687,7 @@ class ModuleDecoderImpl : public Decoder { ...@@ -1689,8 +1687,7 @@ class ModuleDecoderImpl : public Decoder {
return true; return true;
} }
WasmInitExpr consume_init_expr(WasmModule* module, ValueType expected, WasmInitExpr consume_init_expr(WasmModule* module, ValueType expected) {
size_t current_global_index) {
constexpr Decoder::ValidateFlag validate = Decoder::kFullValidation; constexpr Decoder::ValidateFlag validate = Decoder::kFullValidation;
WasmOpcode opcode = kExprNop; WasmOpcode opcode = kExprNop;
std::vector<WasmInitExpr> stack; std::vector<WasmInitExpr> stack;
...@@ -1701,14 +1698,8 @@ class ModuleDecoderImpl : public Decoder { ...@@ -1701,14 +1698,8 @@ class ModuleDecoderImpl : public Decoder {
case kExprGlobalGet: { case kExprGlobalGet: {
GlobalIndexImmediate<validate> imm(this, pc() + 1); GlobalIndexImmediate<validate> imm(this, pc() + 1);
len = 1 + imm.length; len = 1 + imm.length;
// We use 'capacity' over 'size' because we might be if (V8_UNLIKELY(imm.index >= module->globals.size())) {
// mid-DecodeGlobalSection(). errorf(pc() + 1, "Invalid global index: %u", imm.index);
if (V8_UNLIKELY(imm.index >= module->globals.capacity())) {
error(pc() + 1, "global index is out of bounds");
return {};
}
if (V8_UNLIKELY(imm.index >= current_global_index)) {
errorf(pc() + 1, "global #%u is not defined yet", imm.index);
return {}; return {};
} }
WasmGlobal* global = &module->globals[imm.index]; WasmGlobal* global = &module->globals[imm.index];
...@@ -2189,8 +2180,7 @@ class ModuleDecoderImpl : public Decoder { ...@@ -2189,8 +2180,7 @@ class ModuleDecoderImpl : public Decoder {
WasmInitExpr offset; WasmInitExpr offset;
if (is_active) { if (is_active) {
offset = consume_init_expr(module_.get(), kWasmI32, offset = consume_init_expr(module_.get(), kWasmI32);
module_.get()->globals.size());
// Failed to parse offset initializer, return early. // Failed to parse offset initializer, return early.
if (failed()) return {}; if (failed()) return {};
} }
...@@ -2262,12 +2252,11 @@ class ModuleDecoderImpl : public Decoder { ...@@ -2262,12 +2252,11 @@ class ModuleDecoderImpl : public Decoder {
} }
// We know now that the flag is valid. Time to read the rest. // We know now that the flag is valid. Time to read the rest.
size_t num_globals = module_->globals.size();
ValueType expected_type = module_->is_memory64 ? kWasmI64 : kWasmI32; ValueType expected_type = module_->is_memory64 ? kWasmI64 : kWasmI32;
if (flag == SegmentFlags::kActiveNoIndex) { if (flag == SegmentFlags::kActiveNoIndex) {
*is_active = true; *is_active = true;
*index = 0; *index = 0;
*offset = consume_init_expr(module_.get(), expected_type, num_globals); *offset = consume_init_expr(module_.get(), expected_type);
return; return;
} }
if (flag == SegmentFlags::kPassive) { if (flag == SegmentFlags::kPassive) {
...@@ -2277,7 +2266,7 @@ class ModuleDecoderImpl : public Decoder { ...@@ -2277,7 +2266,7 @@ class ModuleDecoderImpl : public Decoder {
if (flag == SegmentFlags::kActiveWithIndex) { if (flag == SegmentFlags::kActiveWithIndex) {
*is_active = true; *is_active = true;
*index = consume_u32v("memory index"); *index = consume_u32v("memory index");
*offset = consume_init_expr(module_.get(), expected_type, num_globals); *offset = consume_init_expr(module_.get(), expected_type);
} }
} }
......
...@@ -560,7 +560,7 @@ TEST_F(WasmModuleVerifyTest, GlobalInitializer) { ...@@ -560,7 +560,7 @@ TEST_F(WasmModuleVerifyTest, GlobalInitializer) {
WASM_GLOBAL_GET(42), kExprEnd) // init value WASM_GLOBAL_GET(42), kExprEnd) // init value
}; };
EXPECT_FAILURE_WITH_MSG(referencing_out_of_bounds_global, EXPECT_FAILURE_WITH_MSG(referencing_out_of_bounds_global,
"global index is out of bounds"); "Invalid global index: 42");
static const byte referencing_undefined_global[] = { static const byte referencing_undefined_global[] = {
SECTION(Global, ENTRY_COUNT(2), // -- SECTION(Global, ENTRY_COUNT(2), // --
...@@ -572,7 +572,7 @@ TEST_F(WasmModuleVerifyTest, GlobalInitializer) { ...@@ -572,7 +572,7 @@ TEST_F(WasmModuleVerifyTest, GlobalInitializer) {
WASM_I32V(0), kExprEnd) // init value WASM_I32V(0), kExprEnd) // init value
}; };
EXPECT_FAILURE_WITH_MSG(referencing_undefined_global, EXPECT_FAILURE_WITH_MSG(referencing_undefined_global,
"global #1 is not defined yet"); "Invalid global index: 1");
{ {
WASM_FEATURE_SCOPE(reftypes); WASM_FEATURE_SCOPE(reftypes);
...@@ -591,7 +591,7 @@ TEST_F(WasmModuleVerifyTest, GlobalInitializer) { ...@@ -591,7 +591,7 @@ TEST_F(WasmModuleVerifyTest, GlobalInitializer) {
WASM_RTT_CANON(0), kExprEnd) // init value WASM_RTT_CANON(0), kExprEnd) // init value
}; };
EXPECT_FAILURE_WITH_MSG(referencing_undefined_global_nested, EXPECT_FAILURE_WITH_MSG(referencing_undefined_global_nested,
"global #1 is not defined yet"); "Invalid global index: 1");
} }
static const byte referencing_mutable_global[] = { static const byte referencing_mutable_global[] = {
......
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