Commit 339c555b authored by Manos Koukoutos's avatar Manos Koukoutos Committed by Commit Bot

[wasm-gc][bug] Restructure DecodeFunction(), add early exits

This fixes a bug caused by StartFunction() being called for an invalid
module.

Bug: v8:7748
Change-Id: I47a3f3573355d87554b123dd1edc7c829bb43d0e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2423710
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70081}
parent d73a775a
...@@ -4108,7 +4108,10 @@ WasmCompilationResult ExecuteLiftoffCompilation( ...@@ -4108,7 +4108,10 @@ WasmCompilationResult ExecuteLiftoffCompilation(
decoder.Decode(); decoder.Decode();
liftoff_compile_time_scope.reset(); liftoff_compile_time_scope.reset();
LiftoffCompiler* compiler = &decoder.interface(); LiftoffCompiler* compiler = &decoder.interface();
if (decoder.failed()) compiler->OnFirstError(&decoder); if (decoder.failed()) {
compiler->OnFirstError(&decoder);
return WasmCompilationResult{};
}
if (counters) { if (counters) {
// Check that the histogram for the bailout reasons has the correct size. // Check that the histogram for the bailout reasons has the correct size.
......
...@@ -1956,34 +1956,33 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -1956,34 +1956,33 @@ class WasmFullDecoder : public WasmDecoder<validate> {
uint32_t params_count = static_cast<uint32_t>(this->num_locals()); uint32_t params_count = static_cast<uint32_t>(this->num_locals());
uint32_t locals_length; uint32_t locals_length;
this->DecodeLocals(this->pc(), &locals_length, params_count); this->DecodeLocals(this->pc(), &locals_length, params_count);
this->consume_bytes(locals_length);
for (uint32_t index = params_count; index < this->num_locals(); index++) { for (uint32_t index = params_count; index < this->num_locals(); index++) {
if (!VALIDATE(this->local_type(index).is_defaultable())) { if (!VALIDATE(this->local_type(index).is_defaultable())) {
this->errorf( this->errorf(
this->pc(), this->pc(),
"Cannot define function-level local of non-defaultable type %s", "Cannot define function-level local of non-defaultable type %s",
this->local_type(index).name().c_str()); this->local_type(index).name().c_str());
return this->TraceFailed();
} }
} }
this->consume_bytes(locals_length);
CALL_INTERFACE(StartFunction); CALL_INTERFACE(StartFunction);
DecodeFunctionBody(); DecodeFunctionBody();
if (!this->failed()) CALL_INTERFACE(FinishFunction); if (this->failed()) return TraceFailed();
// Generate a better error message whether the unterminated control
// structure is the function body block or an innner structure.
if (!VALIDATE(control_.empty())) { if (!VALIDATE(control_.empty())) {
if (control_.size() > 1) { if (control_.size() > 1) {
this->error(control_.back().pc, "unterminated control structure"); this->error(control_.back().pc, "unterminated control structure");
} else if (control_.size() == 1) { } else {
this->error("function body must end with \"end\" opcode"); this->error("function body must end with \"end\" opcode");
} }
return TraceFailed();
} }
CALL_INTERFACE(FinishFunction);
if (this->failed()) return TraceFailed();
if (!VALIDATE(this->ok())) return this->TraceFailed(); TRACE("wasm-decode ok\n\n");
TRACE("wasm-decode %s\n\n", VALIDATE(this->ok()) ? "ok" : "failed");
return true; return true;
} }
......
...@@ -941,6 +941,7 @@ class WasmGraphBuildingInterface { ...@@ -941,6 +941,7 @@ class WasmGraphBuildingInterface {
} }
TFNode* DefaultValue(ValueType type) { TFNode* DefaultValue(ValueType type) {
DCHECK(type.is_defaultable());
switch (type.kind()) { switch (type.kind()) {
case ValueType::kI8: case ValueType::kI8:
case ValueType::kI16: case ValueType::kI16:
......
...@@ -3504,7 +3504,8 @@ TEST_F(FunctionBodyDecoderTest, NonDefaultableLocal) { ...@@ -3504,7 +3504,8 @@ TEST_F(FunctionBodyDecoderTest, NonDefaultableLocal) {
WASM_FEATURE_SCOPE(typed_funcref); WASM_FEATURE_SCOPE(typed_funcref);
WASM_FEATURE_SCOPE(reftypes); WASM_FEATURE_SCOPE(reftypes);
AddLocals(ValueType::Ref(HeapType::kExtern, kNonNullable), 1); AddLocals(ValueType::Ref(HeapType::kExtern, kNonNullable), 1);
ExpectFailure(sigs.v_v(), {}); ExpectFailure(sigs.v_v(), {}, kAppendEnd,
"Cannot define function-level local of non-defaultable type");
} }
TEST_F(FunctionBodyDecoderTest, RefEq) { TEST_F(FunctionBodyDecoderTest, RefEq) {
......
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