diff options
author | Daniel Wirtz <dcode@dcode.io> | 2020-09-24 12:02:09 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-24 12:02:09 +0200 |
commit | e9e1b2ff00aeb05aaeb57af3811add267dc25323 (patch) | |
tree | 4e19032813858b2e650f0cda46fe9fa227aa0a7f /src/wasm/literal.cpp | |
parent | a42423fafa8cf731c69303ddc0acbe80c890e0ab (diff) | |
download | binaryen-e9e1b2ff00aeb05aaeb57af3811add267dc25323.tar.gz binaryen-e9e1b2ff00aeb05aaeb57af3811add267dc25323.tar.bz2 binaryen-e9e1b2ff00aeb05aaeb57af3811add267dc25323.zip |
GC: Add i31 instructions (#3154)
Adds the `i31.new` and `i31.get_s/u` instructions for creating and working with `i31ref` typed values. Does not include fuzzer integration just yet because the fuzzer expects that trivial values it creates are suitable in global initializers, which is not the case for trivial `i31ref` expressions.
Diffstat (limited to 'src/wasm/literal.cpp')
-rw-r--r-- | src/wasm/literal.cpp | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 4a89b5cd1..eb28268fb 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -30,11 +30,16 @@ namespace wasm { template<int N> using LaneArray = std::array<Literal, N>; Literal::Literal(Type type) : type(type) { - assert(type != Type::unreachable && (!type.isRef() || type.isNullable())); - if (type.isException()) { - new (&exn) std::unique_ptr<ExceptionPackage>(); + if (type == Type::i31ref) { + // i31ref is special in that it is non-nullable, so we construct with zero + i32 = 0; } else { - memset(&v128, 0, 16); + assert(type != Type::unreachable && (!type.isRef() || type.isNullable())); + if (type.isException()) { + new (&exn) std::unique_ptr<ExceptionPackage>(); + } else { + memset(&v128, 0, 16); + } } } @@ -57,6 +62,7 @@ Literal::Literal(const Literal& other) : type(other.type) { switch (type.getBasic()) { case Type::i32: case Type::f32: + case Type::i31ref: i32 = other.i32; break; case Type::i64: @@ -72,8 +78,6 @@ Literal::Literal(const Literal& other) : type(other.type) { case Type::anyref: case Type::eqref: break; // null - case Type::i31ref: - WASM_UNREACHABLE("TODO: i31ref"); case Type::funcref: case Type::exnref: case Type::unreachable: @@ -209,6 +213,7 @@ void Literal::getBits(uint8_t (&buf)[16]) const { switch (type.getBasic()) { case Type::i32: case Type::f32: + case Type::i31ref: memcpy(buf, &i32, sizeof(i32)); break; case Type::i64: @@ -229,8 +234,6 @@ void Literal::getBits(uint8_t (&buf)[16]) const { case Type::eqref: assert(isNull() && "unexpected non-null reference type literal"); break; - case Type::i31ref: - WASM_UNREACHABLE("TODO: i31ref"); case Type::none: case Type::unreachable: WASM_UNREACHABLE("invalid type"); @@ -403,7 +406,8 @@ std::ostream& operator<<(std::ostream& o, Literal literal) { o << "eqref(null)"; break; case Type::i31ref: - WASM_UNREACHABLE("TODO: i31ref"); + o << "i31ref(" << literal.geti31(false) << ")"; + break; case Type::unreachable: WASM_UNREACHABLE("invalid type"); } |