Commit a9577d87 authored by Ng Zhi An's avatar Ng Zhi An Committed by Commit Bot

[wasm-interpreter] Fix immediate decoding for numeric instructions

They were using a fixed offset of pc+2, but since the instructions can
be multiple bytes long (leb128 encoded), it should be using *len.

Drive-by fix to add missing instructions to wasm-module-builder.js.

Bug: chromium:1185323,chromium:1185492
Change-Id: I12f396cc2969ecc284aba35b94b1bc5640f12277
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2745977
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73308}
parent ce336fdb
...@@ -3821,6 +3821,18 @@ TEST(Regression_1085507) { ...@@ -3821,6 +3821,18 @@ TEST(Regression_1085507) {
WASM_BLOCK_X(sig_v_i, kExprDrop), kExprElse, kExprEnd, WASM_I32V_1(0)); WASM_BLOCK_X(sig_v_i, kExprDrop), kExprElse, kExprEnd, WASM_I32V_1(0));
} }
TEST(Regression_1185323_1185492) {
WasmRunner<int32_t> r(TestExecutionTier::kInterpreter);
r.builder().AddIndirectFunctionTable(nullptr, 1);
BUILD(r, WASM_I32V_1(0),
// Use a long leb128 encoding of kExprTableSize instruction.
// This exercises a bug in the interpreter which tries to read the
// immediate at pc+2 (it should be pc+4).
kNumericPrefix, 0x90, 0x80, 0x00, 0x00, // table.size 0.
WASM_UNREACHABLE, kExprTableSet, 0x00); // Hits a DCHECK if reached.
r.Call();
}
#undef B1 #undef B1
#undef B2 #undef B2
#undef RET #undef RET
......
...@@ -1821,7 +1821,7 @@ class WasmInterpreterInternals { ...@@ -1821,7 +1821,7 @@ class WasmInterpreterInternals {
return true; return true;
case kExprMemoryInit: { case kExprMemoryInit: {
MemoryInitImmediate<Decoder::kNoValidation> imm(decoder, MemoryInitImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + 2)); code->at(pc + *len));
// The data segment index must be in bounds since it is required by // The data segment index must be in bounds since it is required by
// validation. // validation.
DCHECK_LT(imm.data_segment_index, module()->num_declared_data_segments); DCHECK_LT(imm.data_segment_index, module()->num_declared_data_segments);
...@@ -1846,7 +1846,7 @@ class WasmInterpreterInternals { ...@@ -1846,7 +1846,7 @@ class WasmInterpreterInternals {
} }
case kExprDataDrop: { case kExprDataDrop: {
DataDropImmediate<Decoder::kNoValidation> imm(decoder, DataDropImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + 2)); code->at(pc + *len));
// The data segment index must be in bounds since it is required by // The data segment index must be in bounds since it is required by
// validation. // validation.
DCHECK_LT(imm.index, module()->num_declared_data_segments); DCHECK_LT(imm.index, module()->num_declared_data_segments);
...@@ -1856,7 +1856,7 @@ class WasmInterpreterInternals { ...@@ -1856,7 +1856,7 @@ class WasmInterpreterInternals {
} }
case kExprMemoryCopy: { case kExprMemoryCopy: {
MemoryCopyImmediate<Decoder::kNoValidation> imm(decoder, MemoryCopyImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + 2)); code->at(pc + *len));
*len += imm.length; *len += imm.length;
uint64_t size = ToMemType(Pop()); uint64_t size = ToMemType(Pop());
uint64_t src = ToMemType(Pop()); uint64_t src = ToMemType(Pop());
...@@ -1875,7 +1875,7 @@ class WasmInterpreterInternals { ...@@ -1875,7 +1875,7 @@ class WasmInterpreterInternals {
} }
case kExprMemoryFill: { case kExprMemoryFill: {
MemoryIndexImmediate<Decoder::kNoValidation> imm(decoder, MemoryIndexImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + 2)); code->at(pc + *len));
*len += imm.length; *len += imm.length;
uint64_t size = ToMemType(Pop()); uint64_t size = ToMemType(Pop());
uint32_t value = Pop().to<uint32_t>(); uint32_t value = Pop().to<uint32_t>();
...@@ -1890,7 +1890,7 @@ class WasmInterpreterInternals { ...@@ -1890,7 +1890,7 @@ class WasmInterpreterInternals {
} }
case kExprTableInit: { case kExprTableInit: {
TableInitImmediate<Decoder::kNoValidation> imm(decoder, TableInitImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + 2)); code->at(pc + *len));
*len += imm.length; *len += imm.length;
auto size = Pop().to<uint32_t>(); auto size = Pop().to<uint32_t>();
auto src = Pop().to<uint32_t>(); auto src = Pop().to<uint32_t>();
...@@ -1904,14 +1904,14 @@ class WasmInterpreterInternals { ...@@ -1904,14 +1904,14 @@ class WasmInterpreterInternals {
} }
case kExprElemDrop: { case kExprElemDrop: {
ElemDropImmediate<Decoder::kNoValidation> imm(decoder, ElemDropImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + 2)); code->at(pc + *len));
*len += imm.length; *len += imm.length;
instance_object_->dropped_elem_segments()[imm.index] = 1; instance_object_->dropped_elem_segments()[imm.index] = 1;
return true; return true;
} }
case kExprTableCopy: { case kExprTableCopy: {
TableCopyImmediate<Decoder::kNoValidation> imm(decoder, TableCopyImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + 2)); code->at(pc + *len));
auto size = Pop().to<uint32_t>(); auto size = Pop().to<uint32_t>();
auto src = Pop().to<uint32_t>(); auto src = Pop().to<uint32_t>();
auto dst = Pop().to<uint32_t>(); auto dst = Pop().to<uint32_t>();
...@@ -1925,7 +1925,7 @@ class WasmInterpreterInternals { ...@@ -1925,7 +1925,7 @@ class WasmInterpreterInternals {
} }
case kExprTableGrow: { case kExprTableGrow: {
TableIndexImmediate<Decoder::kNoValidation> imm(decoder, TableIndexImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + 2)); code->at(pc + *len));
HandleScope handle_scope(isolate_); HandleScope handle_scope(isolate_);
auto table = handle( auto table = handle(
WasmTableObject::cast(instance_object_->tables().get(imm.index)), WasmTableObject::cast(instance_object_->tables().get(imm.index)),
...@@ -1939,7 +1939,7 @@ class WasmInterpreterInternals { ...@@ -1939,7 +1939,7 @@ class WasmInterpreterInternals {
} }
case kExprTableSize: { case kExprTableSize: {
TableIndexImmediate<Decoder::kNoValidation> imm(decoder, TableIndexImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + 2)); code->at(pc + *len));
HandleScope handle_scope(isolate_); HandleScope handle_scope(isolate_);
auto table = handle( auto table = handle(
WasmTableObject::cast(instance_object_->tables().get(imm.index)), WasmTableObject::cast(instance_object_->tables().get(imm.index)),
...@@ -1951,7 +1951,7 @@ class WasmInterpreterInternals { ...@@ -1951,7 +1951,7 @@ class WasmInterpreterInternals {
} }
case kExprTableFill: { case kExprTableFill: {
TableIndexImmediate<Decoder::kNoValidation> imm(decoder, TableIndexImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + 2)); code->at(pc + *len));
HandleScope handle_scope(isolate_); HandleScope handle_scope(isolate_);
auto count = Pop().to<uint32_t>(); auto count = Pop().to<uint32_t>();
auto value = Pop().to_ref(); auto value = Pop().to_ref();
......
...@@ -568,12 +568,17 @@ let kExprI32x4Splat = 0x11; ...@@ -568,12 +568,17 @@ let kExprI32x4Splat = 0x11;
let kExprI64x2Splat = 0x12; let kExprI64x2Splat = 0x12;
let kExprF32x4Splat = 0x13; let kExprF32x4Splat = 0x13;
let kExprF64x2Splat = 0x14; let kExprF64x2Splat = 0x14;
let kExprI8x16ExtractLaneS = 0x15;
let kExprI8x16ExtractLaneU = 0x16;
let kExprI8x16ReplaceLane = 0x17; let kExprI8x16ReplaceLane = 0x17;
let kExprI16x8ExtractLaneS = 0x18; let kExprI16x8ExtractLaneS = 0x18;
let kExprI16x8ExtractLaneU = 0x19;
let kExprI16x8ReplaceLane = 0x1a; let kExprI16x8ReplaceLane = 0x1a;
let kExprI32x4ExtractLane = 0x1b; let kExprI32x4ExtractLane = 0x1b;
let kExprI32x4ReplaceLane = 0x1c; let kExprI32x4ReplaceLane = 0x1c;
let kExprI64x2ExtractLane = 0x1d;
let kExprI64x2ReplaceLane = 0x1e; let kExprI64x2ReplaceLane = 0x1e;
let kExprF32x4ExtractLane = 0x1f;
let kExprF32x4ReplaceLane = 0x20; let kExprF32x4ReplaceLane = 0x20;
let kExprF64x2ExtractLane = 0x21; let kExprF64x2ExtractLane = 0x21;
let kExprF64x2ReplaceLane = 0x22; let kExprF64x2ReplaceLane = 0x22;
......
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