summaryrefslogtreecommitdiff
path: root/src/wasm/literal.cpp
diff options
context:
space:
mode:
authorDaniel Wirtz <dcode@dcode.io>2020-09-24 12:02:09 +0200
committerGitHub <noreply@github.com>2020-09-24 12:02:09 +0200
commite9e1b2ff00aeb05aaeb57af3811add267dc25323 (patch)
tree4e19032813858b2e650f0cda46fe9fa227aa0a7f /src/wasm/literal.cpp
parenta42423fafa8cf731c69303ddc0acbe80c890e0ab (diff)
downloadbinaryen-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.cpp22
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");
}