summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-binary.cpp
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2021-03-23 14:23:43 -0700
committerGitHub <noreply@github.com>2021-03-23 14:23:43 -0700
commitf2abcbc8d1659d3e6506b1d4128646b892ebc218 (patch)
tree30bb82cc27bc26df7cb32b889176605c54b9a0b3 /src/wasm/wasm-binary.cpp
parent5ef255154172504385a8218f9712a48d98a47689 (diff)
downloadbinaryen-f2abcbc8d1659d3e6506b1d4128646b892ebc218.tar.gz
binaryen-f2abcbc8d1659d3e6506b1d4128646b892ebc218.tar.bz2
binaryen-f2abcbc8d1659d3e6506b1d4128646b892ebc218.zip
[Wasm GC] Add support for non-nullable types, all except for locals (#3710)
After this PR we still do not support non-nullable locals. But we no longer turn all types into nullable upon load. In particular, we support non-nullable types on function parameters and struct fields, etc. This should be enough to experiment with optimizations in both binaryen and in VMs regarding non- nullability (since we expect that optimizing VMs can do well inside functions anyhow; it's non-nullability across calls and from data that the VM can't be expected to think about). Let is handled as before, by lowering it into gets and sets. In addition, we turn non-nullable locals into nullable ones, and add a ref.as_non_null on all their gets (to keep the type identical there). This is used not just for loading code with a let but also is needed after inlining. Most of the code changes here are removing FIXMEs for allowing non-nullable types. But there is also code to handle the issues mentioned above. Most of the test updates are removing extra nulls that we added before when we turned all types nullable. A few tests had actual issues, though, and also some new tests are added to cover the code changes here.
Diffstat (limited to 'src/wasm/wasm-binary.cpp')
-rw-r--r--src/wasm/wasm-binary.cpp26
1 files changed, 15 insertions, 11 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 6cb837296..09d3287b0 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -19,6 +19,7 @@
#include "ir/module-utils.h"
#include "ir/table-utils.h"
+#include "ir/type-updating.h"
#include "support/bits.h"
#include "support/debug.h"
#include "wasm-binary.h"
@@ -1595,12 +1596,10 @@ bool WasmBinaryBuilder::getBasicType(int32_t code, Type& out) {
out = Type::eqref;
return true;
case BinaryConsts::EncodedType::i31ref:
- // FIXME: for now, force all inputs to be nullable
- out = Type(HeapType::i31, Nullable);
+ out = Type(HeapType::i31, NonNullable);
return true;
case BinaryConsts::EncodedType::dataref:
- // FIXME: for now, force all inputs to be nullable
- out = Type(HeapType::data, Nullable);
+ out = Type(HeapType::data, NonNullable);
return true;
default:
return false;
@@ -1647,9 +1646,9 @@ Type WasmBinaryBuilder::getType(int initial) {
case BinaryConsts::EncodedType::Empty:
return Type::none;
case BinaryConsts::EncodedType::nullable:
- case BinaryConsts::EncodedType::nonnullable:
- // FIXME: for now, force all inputs to be nullable
return Type(getHeapType(), Nullable);
+ case BinaryConsts::EncodedType::nonnullable:
+ return Type(getHeapType(), NonNullable);
case BinaryConsts::EncodedType::rtt_n: {
auto depth = getU32LEB();
auto heapType = getIndexedHeapType();
@@ -1790,16 +1789,18 @@ void WasmBinaryBuilder::readTypes() {
switch (typeCode) {
case BinaryConsts::EncodedType::nullable:
case BinaryConsts::EncodedType::nonnullable: {
- // FIXME: for now, force all inputs to be nullable
+ auto nullability = typeCode == BinaryConsts::EncodedType::nullable
+ ? Nullable
+ : NonNullable;
int64_t htCode = getS64LEB(); // TODO: Actually s33
HeapType ht;
if (getBasicHeapType(htCode, ht)) {
- return Type(ht, Nullable);
+ return Type(ht, nullability);
}
if (size_t(htCode) >= numTypes) {
throwError("invalid type index: " + std::to_string(htCode));
}
- return builder.getTempRefType(size_t(htCode), Nullable);
+ return builder.getTempRefType(size_t(htCode), nullability);
}
case BinaryConsts::EncodedType::rtt_n:
case BinaryConsts::EncodedType::rtt: {
@@ -2172,6 +2173,9 @@ void WasmBinaryBuilder::readFunctions() {
throwError("binary offset at function exit not at expected location");
}
}
+
+ TypeUpdating::handleNonNullableLocals(func, wasm);
+
std::swap(func->epilogLocation, debugLocation);
currFunction = nullptr;
debugLocation.clear();
@@ -6072,8 +6076,8 @@ void WasmBinaryBuilder::visitRefFunc(RefFunc* curr) {
functionRefs[index].push_back(curr); // we don't know function names yet
// To support typed function refs, we give the reference not just a general
// funcref, but a specific subtype with the actual signature.
- // FIXME: for now, emit a nullable type here
- curr->finalize(Type(HeapType(getSignatureByFunctionIndex(index)), Nullable));
+ curr->finalize(
+ Type(HeapType(getSignatureByFunctionIndex(index)), NonNullable));
}
void WasmBinaryBuilder::visitRefEq(RefEq* curr) {