Commit 63c95e61 authored by Clemens Backes's avatar Clemens Backes Committed by V8 LUCI CQ

[wasm] Remove wrong signature definitions for numerics

Some of the numeric opcodes have a variadic signature, e.g. table.grow
or table.fill, and soon also the bulk memory opcodes because their
consumed types depend on the memory type.

For those opcodes, remove the signature definition from the opcode macro
lists, because using it might result in bugs.

R=thibaudm@chromium.org

Bug: v8:10949, chromium:1281995
Change-Id: I350e75db7197d97a561f8219cedba5fe85b5c9c9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3424494Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78903}
parent 418aa66f
......@@ -1687,7 +1687,7 @@ class WasmDecoder : public Decoder {
case kExprRefAsNonNull:
return 1;
#define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name:
#define DECLARE_OPCODE_CASE(name, ...) case kExpr##name:
// clang-format off
/********** Simple and memory opcodes **********/
FOREACH_SIMPLE_OPCODE(DECLARE_OPCODE_CASE)
......@@ -1914,7 +1914,7 @@ class WasmDecoder : public Decoder {
// Prefixed opcodes (already handled, included here for completeness of
// switch)
FOREACH_SIMD_OPCODE(DECLARE_OPCODE_CASE)
FOREACH_NUMERIC_OPCODE(DECLARE_OPCODE_CASE)
FOREACH_NUMERIC_OPCODE(DECLARE_OPCODE_CASE, DECLARE_OPCODE_CASE)
FOREACH_ATOMIC_OPCODE(DECLARE_OPCODE_CASE)
FOREACH_ATOMIC_0_OPERAND_OPCODE(DECLARE_OPCODE_CASE)
FOREACH_GC_OPCODE(DECLARE_OPCODE_CASE)
......@@ -2022,13 +2022,19 @@ class WasmDecoder : public Decoder {
return {2, 1};
FOREACH_SIMD_CONST_OPCODE(DECLARE_OPCODE_CASE)
return {0, 1};
// Special case numeric opcodes without fixed signature.
case kExprMemoryInit:
case kExprMemoryCopy:
case kExprMemoryFill:
return {3, 0};
case kExprTableGrow:
return {2, 1};
case kExprTableFill:
return {3, 0};
default: {
sig = WasmOpcodes::Signature(opcode);
if (sig) {
return {sig->parameter_count(), sig->return_count()};
} else {
UNREACHABLE();
}
DCHECK_NOT_NULL(sig);
return {sig->parameter_count(), sig->return_count()};
}
}
}
......@@ -4924,10 +4930,6 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
unsigned DecodeNumericOpcode(WasmOpcode opcode, uint32_t opcode_length) {
const FunctionSig* sig = WasmOpcodes::Signature(opcode);
if (!VALIDATE(sig != nullptr)) {
this->DecodeError("invalid numeric opcode");
return 0;
}
switch (opcode) {
case kExprI32SConvertSatF32:
case kExprI32UConvertSatF32:
......@@ -4943,10 +4945,11 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
case kExprMemoryInit: {
MemoryInitImmediate<validate> imm(this, this->pc_ + opcode_length);
if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
Value size = Peek(0, 2, sig->GetParam(2));
Value src = Peek(1, 1, sig->GetParam(1));
Value dst = Peek(2, 0, sig->GetParam(0));
CALL_INTERFACE_IF_OK_AND_REACHABLE(MemoryInit, imm, dst, src, size);
// TODO(clemensb): Add memory64 support.
Value size = Peek(0, 2, kWasmI32);
Value offset = Peek(1, 1, kWasmI32);
Value dst = Peek(2, 0, kWasmI32);
CALL_INTERFACE_IF_OK_AND_REACHABLE(MemoryInit, imm, dst, offset, size);
Drop(3);
return opcode_length + imm.length;
}
......@@ -4962,9 +4965,10 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
case kExprMemoryCopy: {
MemoryCopyImmediate<validate> imm(this, this->pc_ + opcode_length);
if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
Value size = Peek(0, 2, sig->GetParam(2));
Value src = Peek(1, 1, sig->GetParam(1));
Value dst = Peek(2, 0, sig->GetParam(0));
// TODO(clemensb): Add memory64 support.
Value size = Peek(0, 2, kWasmI32);
Value src = Peek(1, 1, kWasmI32);
Value dst = Peek(2, 0, kWasmI32);
CALL_INTERFACE_IF_OK_AND_REACHABLE(MemoryCopy, imm, dst, src, size);
Drop(3);
return opcode_length + imm.length;
......@@ -4972,9 +4976,10 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
case kExprMemoryFill: {
MemoryIndexImmediate<validate> imm(this, this->pc_ + opcode_length);
if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
Value size = Peek(0, 2, sig->GetParam(2));
Value value = Peek(1, 1, sig->GetParam(1));
Value dst = Peek(2, 0, sig->GetParam(0));
// TODO(clemensb): Add memory64 support.
Value size = Peek(0, 2, kWasmI32);
Value value = Peek(1, 1, kWasmI32);
Value dst = Peek(2, 0, kWasmI32);
CALL_INTERFACE_IF_OK_AND_REACHABLE(MemoryFill, imm, dst, value, size);
Drop(3);
return opcode_length + imm.length;
......@@ -5010,7 +5015,7 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
IndexImmediate<validate> imm(this, this->pc_ + opcode_length,
"table index");
if (!this->ValidateTable(this->pc_ + opcode_length, imm)) return 0;
Value delta = Peek(0, 1, sig->GetParam(1));
Value delta = Peek(0, 1, kWasmI32);
Value value = Peek(1, 0, this->module_->tables[imm.index].type);
Value result = CreateValue(kWasmI32);
CALL_INTERFACE_IF_OK_AND_REACHABLE(TableGrow, imm, value, delta,
......@@ -5032,9 +5037,9 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
IndexImmediate<validate> imm(this, this->pc_ + opcode_length,
"table index");
if (!this->ValidateTable(this->pc_ + opcode_length, imm)) return 0;
Value count = Peek(0, 2, sig->GetParam(2));
Value count = Peek(0, 2, kWasmI32);
Value value = Peek(1, 1, this->module_->tables[imm.index].type);
Value start = Peek(2, 0, sig->GetParam(0));
Value start = Peek(2, 0, kWasmI32);
CALL_INTERFACE_IF_OK_AND_REACHABLE(TableFill, imm, start, value, count);
Drop(3);
return opcode_length + imm.length;
......
......@@ -106,8 +106,8 @@ void PrintRawWasmCode(const byte* start, const byte* end) {
namespace {
const char* RawOpcodeName(WasmOpcode opcode) {
switch (opcode) {
#define DECLARE_NAME_CASE(name, opcode, sig) \
case kExpr##name: \
#define DECLARE_NAME_CASE(name, ...) \
case kExpr##name: \
return "kExpr" #name;
FOREACH_OPCODE(DECLARE_NAME_CASE)
#undef DECLARE_NAME_CASE
......
......@@ -633,9 +633,11 @@ constexpr WasmOpcodeSig GetAtomicOpcodeSigIndex(byte opcode) {
}
constexpr WasmOpcodeSig GetNumericOpcodeSigIndex(byte opcode) {
#define CASE(name, opc, sig) opcode == (opc & 0xFF) ? kSigEnum_##sig:
return FOREACH_NUMERIC_OPCODE(CASE) kSigEnum_None;
#undef CASE
#define CASE_SIG(name, opc, sig) opcode == (opc & 0xFF) ? kSigEnum_##sig:
#define CASE_VARIADIC(name, opc)
return FOREACH_NUMERIC_OPCODE(CASE_SIG, CASE_VARIADIC) kSigEnum_None;
#undef CASE_SIG
#undef CASE_VARIADIC
}
constexpr std::array<WasmOpcodeSig, 256> kShortSigTable =
......
......@@ -569,29 +569,29 @@ bool V8_EXPORT_PRIVATE IsJSCompatibleSignature(const FunctionSig* sig,
FOREACH_SIMD_MEM_1_OPERAND_OPCODE(V) \
FOREACH_SIMD_CONST_OPCODE(V)
#define FOREACH_NUMERIC_OPCODE(V) \
V(I32SConvertSatF32, 0xfc00, i_f) \
V(I32UConvertSatF32, 0xfc01, i_f) \
V(I32SConvertSatF64, 0xfc02, i_d) \
V(I32UConvertSatF64, 0xfc03, i_d) \
V(I64SConvertSatF32, 0xfc04, l_f) \
V(I64UConvertSatF32, 0xfc05, l_f) \
V(I64SConvertSatF64, 0xfc06, l_d) \
V(I64UConvertSatF64, 0xfc07, l_d) \
V(MemoryInit, 0xfc08, v_iii) \
V(DataDrop, 0xfc09, v_v) \
V(MemoryCopy, 0xfc0a, v_iii) \
V(MemoryFill, 0xfc0b, v_iii) \
V(TableInit, 0xfc0c, v_iii) \
V(ElemDrop, 0xfc0d, v_v) \
V(TableCopy, 0xfc0e, v_iii) \
#define FOREACH_NUMERIC_OPCODE(V_SIG, V_VARIADIC) \
V_SIG(I32SConvertSatF32, 0xfc00, i_f) \
V_SIG(I32UConvertSatF32, 0xfc01, i_f) \
V_SIG(I32SConvertSatF64, 0xfc02, i_d) \
V_SIG(I32UConvertSatF64, 0xfc03, i_d) \
V_SIG(I64SConvertSatF32, 0xfc04, l_f) \
V_SIG(I64UConvertSatF32, 0xfc05, l_f) \
V_SIG(I64SConvertSatF64, 0xfc06, l_d) \
V_SIG(I64UConvertSatF64, 0xfc07, l_d) \
V_VARIADIC(MemoryInit, 0xfc08) \
V_SIG(DataDrop, 0xfc09, v_v) \
V_VARIADIC(MemoryCopy, 0xfc0a) \
V_VARIADIC(MemoryFill, 0xfc0b) \
V_SIG(TableInit, 0xfc0c, v_iii) \
V_SIG(ElemDrop, 0xfc0d, v_v) \
V_SIG(TableCopy, 0xfc0e, v_iii) \
/* TableGrow is polymorphic in the first parameter. */ \
/* It's whatever the table type is. */ \
V(TableGrow, 0xfc0f, i_ci) \
V(TableSize, 0xfc10, i_v) \
V_VARIADIC(TableGrow, 0xfc0f) \
V_SIG(TableSize, 0xfc10, i_v) \
/* TableFill is polymorphic in the second parameter. */ \
/* It's whatever the table type is. */ \
V(TableFill, 0xfc11, v_iii)
V_VARIADIC(TableFill, 0xfc11)
#define FOREACH_ATOMIC_OPCODE(V) \
V(AtomicNotify, 0xfe00, i_ii) \
......@@ -730,7 +730,7 @@ bool V8_EXPORT_PRIVATE IsJSCompatibleSignature(const FunctionSig* sig,
FOREACH_SIMD_OPCODE(V) \
FOREACH_ATOMIC_OPCODE(V) \
FOREACH_ATOMIC_0_OPERAND_OPCODE(V) \
FOREACH_NUMERIC_OPCODE(V) \
FOREACH_NUMERIC_OPCODE(V, V) \
FOREACH_GC_OPCODE(V)
// All signatures.
......@@ -799,7 +799,7 @@ bool V8_EXPORT_PRIVATE IsJSCompatibleSignature(const FunctionSig* sig,
enum WasmOpcode {
// Declare expression opcodes.
#define DECLARE_NAMED_ENUM(name, opcode, sig) kExpr##name = opcode,
#define DECLARE_NAMED_ENUM(name, opcode, ...) kExpr##name = opcode,
FOREACH_OPCODE(DECLARE_NAMED_ENUM)
#undef DECLARE_NAMED_ENUM
#define DECLARE_PREFIX(name, opcode) k##name##Prefix = opcode,
......
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