Commit 18929af9 authored by Jakob Kummerow's avatar Jakob Kummerow Committed by Commit Bot

[wasm-gc] Add preliminary opcodes

These opcodes are not officially specified yet, they are defined
in the "prototype implementation spec" at https://bit.ly/3cWcm6Q.

Drive-by: drop a unit test whose entire coverage can be provided
by a compile-time check.

Bug: v8:7748
Change-Id: Icefa6dd321802c8a01c4561178b9d21eca1fbaa3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2152841Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67208}
parent acc71c78
......@@ -200,6 +200,8 @@ constexpr ValueType kWasmI64 = ValueType(ValueType::kI64);
constexpr ValueType kWasmF32 = ValueType(ValueType::kF32);
constexpr ValueType kWasmF64 = ValueType(ValueType::kF64);
constexpr ValueType kWasmAnyRef = ValueType(ValueType::kAnyRef);
// TODO(jkummerow): introduce ValueType::kEqRef
constexpr ValueType kWasmEqRef = ValueType(ValueType::kAnyRef);
constexpr ValueType kWasmExnRef = ValueType(ValueType::kExnRef);
constexpr ValueType kWasmFuncRef = ValueType(ValueType::kFuncRef);
constexpr ValueType kWasmNullRef = ValueType(ValueType::kNullRef);
......
......@@ -29,6 +29,11 @@ enum ValueTypeCode : uint8_t {
kLocalFuncRef = 0x70,
kLocalAnyRef = 0x6f,
kLocalNullRef = 0x6e,
kLocalRef = 0x6d, // GC proposal
kLocalOptRef = 0x6c, // GC proposal
kLocalEqRef = 0x6b, // GC proposal
kLocalI31Ref = 0x6a, // GC proposal
kLocalRttRef = 0x69, // GC proposal
kLocalExnRef = 0x68,
};
// Binary encoding of other types.
......
......@@ -335,7 +335,38 @@ const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) {
CASE_UNSIGNED_ALL_OP(AtomicExchange, "atomic.xchng")
CASE_UNSIGNED_ALL_OP(AtomicCompareExchange, "atomic.cmpxchng")
default : return "unknown";
// GC operations.
CASE_OP(StructNew, "struct.new")
CASE_OP(StructNewSub, "struct.new_sub")
CASE_OP(StructNewDefault, "struct.new_default")
CASE_OP(StructGet, "struct.get")
CASE_OP(StructGetS, "struct.get_s")
CASE_OP(StructGetU, "struct.get_u")
CASE_OP(StructSet, "struct.set")
CASE_OP(ArrayNew, "array.new")
CASE_OP(ArrayNewSub, "array.new_sub")
CASE_OP(ArrayNewDefault, "array.new_default")
CASE_OP(ArrayGet, "array.get")
CASE_OP(ArrayGetS, "array.get_s")
CASE_OP(ArrayGetU, "array.get_u")
CASE_OP(ArrayLen, "array.len")
CASE_OP(ArraySet, "array.set")
CASE_OP(I31New, "i31.new")
CASE_OP(I31GetS, "i31.get_s")
CASE_OP(I31GetU, "i31.get_u")
CASE_OP(RttGet, "rtt.get")
CASE_OP(RttSub, "rtt.sub")
CASE_OP(RefTest, "ref.test")
CASE_OP(RefCast, "ref.cast")
CASE_OP(BrOnCast, "br_on_cast")
CASE_OP(RefEq, "ref.eq")
case kNumericPrefix:
case kSimdPrefix:
case kAtomicPrefix:
case kGCPrefix:
return "unknown";
// clang-format on
}
}
......
......@@ -227,9 +227,13 @@ bool IsJSCompatibleSignature(const FunctionSig* sig, const WasmFeatures&);
V(I64SExtendI16, 0xc3, l_l) \
V(I64SExtendI32, 0xc4, l_l)
#define FOREACH_SIMPLE_PROTOTYPE_OPCODE(V) V(RefIsNull, 0xd1, i_r)
#define FOREACH_SIMPLE_PROTOTYPE_OPCODE(V) \
V(RefIsNull, 0xd1, i_r) \
V(RefEq, 0xd3, i_rr) /* made-up opcode, guessing future spec (GC) */
// For compatibility with Asm.js.
// These opcodes are not spec'ed (or visible) externally; the idea is
// to use unused ranges for internal purposes.
#define FOREACH_ASMJS_COMPAT_OPCODE(V) \
V(F64Acos, 0xc5, d_d) \
V(F64Asin, 0xc6, d_d) \
......@@ -242,7 +246,7 @@ bool IsJSCompatibleSignature(const FunctionSig* sig, const WasmFeatures&);
V(F64Atan2, 0xcd, d_dd) \
V(F64Pow, 0xce, d_dd) \
V(F64Mod, 0xcf, d_dd) \
V(I32AsmjsDivS, 0xd3, i_ii) \
V(I32AsmjsDivS, 0xe7, i_ii) \
V(I32AsmjsDivU, 0xd4, i_ii) \
V(I32AsmjsRemS, 0xd5, i_ii) \
V(I32AsmjsRemU, 0xd6, i_ii) \
......@@ -574,6 +578,33 @@ bool IsJSCompatibleSignature(const FunctionSig* sig, const WasmFeatures&);
V(I64AtomicCompareExchange16U, 0xfe4d, l_ill) \
V(I64AtomicCompareExchange32U, 0xfe4e, l_ill)
// Opcode values are guesswork for now, see:
// https://docs.google.com/document/d/1DklC3qVuOdLHSXB5UXghM_syCh-4cMinQ50ICiXnK3Q/edit
#define FOREACH_GC_OPCODE(V) \
V(StructNew, 0xfb00, _) \
V(StructNewSub, 0xfb01, _) \
V(StructNewDefault, 0xfb02, _) \
V(StructGet, 0xfb03, _) \
V(StructGetS, 0xfb04, _) \
V(StructGetU, 0xfb05, _) \
V(StructSet, 0xfb06, _) \
V(ArrayNew, 0xfb10, _) \
V(ArrayNewSub, 0xfb11, _) \
V(ArrayNewDefault, 0xfb12, _) \
V(ArrayGet, 0xfb13, _) \
V(ArrayGetS, 0xfb14, _) \
V(ArrayGetU, 0xfb15, _) \
V(ArraySet, 0xfb16, _) \
V(ArrayLen, 0xfb17, _) \
V(I31New, 0xfb20, _) \
V(I31GetS, 0xfb21, _) \
V(I31GetU, 0xfb22, _) \
V(RttGet, 0xfb30, _) \
V(RttSub, 0xfb31, _) \
V(RefTest, 0xfb40, _) \
V(RefCast, 0xfb41, _) \
V(BrOnCast, 0xfb42, _)
#define FOREACH_ATOMIC_0_OPERAND_OPCODE(V) \
/* AtomicFence does not target a particular linear memory. */ \
V(AtomicFence, 0xfe03, v_v)
......@@ -594,7 +625,8 @@ bool IsJSCompatibleSignature(const FunctionSig* sig, const WasmFeatures&);
FOREACH_SIMD_MEM_OPCODE(V) \
FOREACH_ATOMIC_OPCODE(V) \
FOREACH_ATOMIC_0_OPERAND_OPCODE(V) \
FOREACH_NUMERIC_OPCODE(V)
FOREACH_NUMERIC_OPCODE(V) \
FOREACH_GC_OPCODE(V)
// All signatures.
#define FOREACH_SIGNATURE(V) \
......@@ -637,7 +669,8 @@ bool IsJSCompatibleSignature(const FunctionSig* sig, const WasmFeatures&);
V(i_iil, kWasmI32, kWasmI32, kWasmI32, kWasmI64) \
V(i_ill, kWasmI32, kWasmI32, kWasmI64, kWasmI64) \
V(i_r, kWasmI32, kWasmAnyRef) \
V(i_ai, kWasmI32, kWasmFuncRef, kWasmI32)
V(i_ai, kWasmI32, kWasmFuncRef, kWasmI32) \
V(i_rr, kWasmI32, kWasmEqRef, kWasmEqRef)
#define FOREACH_SIMD_SIGNATURE(V) \
V(s_s, kWasmS128, kWasmS128) \
......@@ -654,7 +687,8 @@ bool IsJSCompatibleSignature(const FunctionSig* sig, const WasmFeatures&);
#define FOREACH_PREFIX(V) \
V(Numeric, 0xfc) \
V(Simd, 0xfd) \
V(Atomic, 0xfe)
V(Atomic, 0xfe) \
V(GC, 0xfb)
enum WasmOpcode {
// Declare expression opcodes.
......
......@@ -302,7 +302,6 @@ v8_source_set("unittests_sources") {
"wasm/wasm-macro-gen-unittest.cc",
"wasm/wasm-module-builder-unittest.cc",
"wasm/wasm-module-sourcemap-unittest.cc",
"wasm/wasm-opcodes-unittest.cc",
"zone/zone-allocator-unittest.cc",
"zone/zone-chunk-list-unittest.cc",
"zone/zone-unittest.cc",
......
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "test/unittests/test-utils.h"
#include "src/wasm/wasm-opcodes.h"
namespace v8 {
namespace internal {
namespace wasm {
class WasmOpcodesTest : public TestWithZone {};
TEST_F(WasmOpcodesTest, EveryOpcodeHasAName) {
static const struct {
WasmOpcode opcode;
const char* debug_name;
} kValues[] = {
#define DECLARE_ELEMENT(name, opcode, sig) {kExpr##name, "kExpr" #name},
FOREACH_OPCODE(DECLARE_ELEMENT)};
#undef DECLARE_ELEMENT
for (size_t i = 0; i < arraysize(kValues); i++) {
const char* result = WasmOpcodes::OpcodeName(kValues[i].opcode);
if (strcmp("unknown", result) == 0) {
EXPECT_TRUE(false) << "WasmOpcodes::OpcodeName(" << kValues[i].debug_name
<< ") == \"unknown\";"
" plazz halp in src/wasm/wasm-opcodes.cc";
}
}
}
} // namespace wasm
} // namespace internal
} // namespace v8
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