Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/binaryen-c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ Literal fromBinaryenLiteral(BinaryenLiteral x) {
case HeapType::nocont:
case HeapType::noexn:
case HeapType::nowaitqueue:
assert(type.isNullable());
assert(type.isNullableRef());
return Literal::makeNull(heapType);
}
}
Expand Down Expand Up @@ -397,7 +397,7 @@ BinaryenHeapType BinaryenTypeGetHeapType(BinaryenType type) {
return Type(type).getHeapType().getID();
}
bool BinaryenTypeIsNullable(BinaryenType type) {
return Type(type).isNullable();
return Type(type).isNullableRef();
}
BinaryenType BinaryenTypeFromHeapType(BinaryenHeapType heapType,
bool nullable) {
Expand Down
4 changes: 2 additions & 2 deletions src/ir/LocalStructuralDominance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ LocalStructuralDominance::LocalStructuralDominance(Function* func,
for (auto type : var) {
// Check if we have any non-nullable vars (or tuple vars with
// non-nullable elements) at all.
if (type.isNonNullable()) {
if (type.isNonNullableRef()) {
hasNonNullableVar = true;
break;
}
Expand Down Expand Up @@ -78,7 +78,7 @@ LocalStructuralDominance::LocalStructuralDominance(Function* func,
auto localType = func->getLocalType(i);
bool interesting = false;
for (auto type : localType) {
if (type.isRef() && (mode == All || type.isNonNullable())) {
if ((mode == All && type.isRef()) || type.isNonNullableRef()) {
interesting = true;
break;
}
Expand Down
2 changes: 1 addition & 1 deletion src/ir/cost.h
Original file line number Diff line number Diff line change
Expand Up @@ -885,7 +885,7 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, CostType> {
private:
CostType nullCheckCost(Expression* ref) {
// A nullable type requires a bounds check in most VMs.
return ref->type.isNullable();
return ref->type.isNullableRef();
}
};

Expand Down
2 changes: 1 addition & 1 deletion src/ir/effects.h
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,7 @@ class EffectAnalyzer {
parent.trap = true;
return true;
}
if (type.isNullable()) {
if (type.isNullableRef()) {
parent.implicitTrap = true;
}

Expand Down
12 changes: 6 additions & 6 deletions src/ir/gc-type-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
namespace wasm::GCTypeUtils {

inline bool isUninhabitable(Type type) {
return type.isNonNullable() && type.getHeapType().isBottom();
return type.isNonNullableRef() && type.getHeapType().isBottom();
}

// Helper code to evaluate a reference at compile time and check if it is of a
Expand Down Expand Up @@ -84,7 +84,7 @@ inline EvaluationResult evaluateCastCheck(Type refType, Type castType) {

auto refHeapType = refType.getHeapType();

if (castType.isNonNullable() && refHeapType.isBottom()) {
if (castType.isNonNullableRef() && refHeapType.isBottom()) {
// Non-null references to bottom types do not exist, so there's no value
// that could make the cast succeed.
//
Expand Down Expand Up @@ -123,15 +123,15 @@ inline EvaluationResult evaluateCastCheck(Type refType, Type castType) {
if (refIsHeapSubType) {
// The heap type is a subtype. All we need is for nullability to work out as
// well, and then the cast must succeed.
if (castType.isNullable() || refType.isNonNullable()) {
if (castType.isNullableRef() || refType.isNonNullableRef()) {
return Success;
}

// If the heap type part of the cast is compatible but the cast as a whole
// is not, we must have a nullable input ref that we are casting to a
// non-nullable type.
assert(refType.isNullable());
assert(castType.isNonNullable());
assert(refType.isNullableRef());
assert(castType.isNonNullableRef());
return SuccessOnlyIfNonNull;
}

Expand All @@ -144,7 +144,7 @@ inline EvaluationResult evaluateCastCheck(Type refType, Type castType) {
// can succeed is if it allows nulls and the input is null.
//
// Note that this handles uninhabitability of the cast type.
if (refType.isNonNullable() || castType.isNonNullable()) {
if (refType.isNonNullableRef() || castType.isNonNullableRef()) {
return Failure;
}

Expand Down
8 changes: 4 additions & 4 deletions src/ir/possible-contents.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ void PossibleContents::intersect(const PossibleContents& other) {
auto newType = Type::getGreatestLowerBound(type, otherType);

auto setNoneOrNull = [&]() {
if (newType.isNullable()) {
if (newType.isNullableRef()) {
value = Literal::makeNull(heapType);
} else {
value = None();
Expand Down Expand Up @@ -278,7 +278,7 @@ bool PossibleContents::haveIntersection(const PossibleContents& a,
auto aHeapType = aType.getHeapType();
auto bHeapType = bType.getHeapType();

if (aType.isNullable() && bType.isNullable() &&
if (aType.isNullableRef() && bType.isNullableRef() &&
aHeapType.getBottom() == bHeapType.getBottom()) {
// A compatible null is possible on both sides.
return true;
Expand Down Expand Up @@ -356,7 +356,7 @@ bool PossibleContents::isSubContents(const PossibleContents& a,

if (b.isFullConeType()) {
if (a.isNull()) {
return b.getType().isNullable();
return b.getType().isNullableRef();
}
return Type::isSubType(a.getType(), b.getType());
}
Expand Down Expand Up @@ -1764,7 +1764,7 @@ void TNHOracle::scan(Function* func,
// This function is called with the reference that will be trapped on,
// if it is null.
void notePossibleTrap(Expression* expr) {
if (!expr->type.isRef() || expr->type.isNonNullable()) {
if (!expr->type.isNullableRef()) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks equivalent to !isRef || !isNullable while the original code is !isRef || isNonNullable. Is !isNullable the same as isNonNullable? I guess this is only in the case when isRef so yes?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think this should be good.

Non-refs: take the branch before and after.
nullable refs: do not take the branch before and after.
non-nullable refs: take the branch before and after.

return;
}
noteCast(expr, Type(expr->type.getHeapType(), NonNullable));
Expand Down
2 changes: 1 addition & 1 deletion src/ir/possible-contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ class PossibleContents {
if (wasm && wasm->typeNames.contains(h)) {
o << " $" << wasm->typeNames[h].name;
}
if (t.isNullable()) {
if (t.isNullableRef()) {
o << " null";
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/ir/type-updating.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ void handleNonDefaultableLocals(Function* func, Module& wasm) {
bool hasNonNullable = false;
for (auto varType : func->vars) {
for (auto type : varType) {
if (type.isNonNullable()) {
if (type.isNonNullableRef()) {
hasNonNullable = true;
break;
}
Expand All @@ -529,7 +529,7 @@ void handleNonDefaultableLocals(Function* func, Module& wasm) {
// LocalStructuralDominance should have only looked at non-nullable indexes
// since we told it to ignore nullable ones. Also, params always dominate
// and should not appear here.
assert(func->getLocalType(index).isNonNullable() ||
assert(func->getLocalType(index).isNonNullableRef() ||
func->getLocalType(index).isTuple());
assert(!func->isParam(index));
}
Expand Down Expand Up @@ -572,7 +572,7 @@ void handleNonDefaultableLocals(Function* func, Module& wasm) {
for (size_t i = 0, size = type.size(); i < size; ++i) {
elems[i] = builder.makeTupleExtract(
builder.makeLocalGet(set->index, validType), i);
if (type[i].isNonNullable()) {
if (type[i].isNonNullableRef()) {
elems[i] = builder.makeRefAs(RefAsNonNull, elems[i]);
}
}
Expand All @@ -592,7 +592,7 @@ void handleNonDefaultableLocals(Function* func, Module& wasm) {

Type getValidLocalType(Type type, FeatureSet features) {
assert(type.isConcrete());
if (type.isNonNullable()) {
if (type.isNonNullableRef()) {
return type.with(Nullable);
}
if (type.isTuple()) {
Expand All @@ -606,7 +606,7 @@ Type getValidLocalType(Type type, FeatureSet features) {
}

Expression* fixLocalGet(LocalGet* get, Module& wasm) {
if (get->type.isNonNullable()) {
if (get->type.isNonNullableRef()) {
// The get should now return a nullable value, and a ref.as_non_null
// fixes that up.
get->type = getValidLocalType(get->type, wasm.features);
Expand All @@ -621,7 +621,7 @@ Expression* fixLocalGet(LocalGet* get, Module& wasm) {
auto* elemGet =
i == 0 ? get : builder.makeLocalGet(get->index, get->type);
elems[i] = builder.makeTupleExtract(elemGet, i);
if (type[i].isNonNullable()) {
if (type[i].isNonNullableRef()) {
elems[i] = builder.makeRefAs(RefAsNonNull, elems[i]);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/passes/AbstractTypeRefining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ struct AbstractTypeRefining : public Pass {
Builder builder(*getModule());
if (curr->type.isExact() || (curr->desc && optimized->isBottom())) {
if (curr->desc) {
if (curr->desc->type.isNullable() &&
if (curr->desc->type.isNullableRef() &&
!getPassOptions().trapsNeverHappen) {
curr->desc = builder.makeRefAs(RefAsNonNull, curr->desc);
}
Expand Down Expand Up @@ -442,7 +442,7 @@ struct AbstractTypeRefining : public Pass {
bool isFail = curr->op == BrOnCastDescEqFail;
if (curr->castType.isExact() || (curr->desc && optimized->isBottom())) {
if (curr->desc) {
if (curr->desc->type.isNullable() &&
if (curr->desc->type.isNullableRef() &&
!getPassOptions().trapsNeverHappen) {
curr->desc = builder.makeRefAs(RefAsNonNull, curr->desc);
}
Expand Down
2 changes: 1 addition & 1 deletion src/passes/DeadArgumentElimination.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ struct DAE : public Pass {
// Do this for more complicated uninhabitable types such as non-nullable
// references to structs with non-nullable reference cycles.
bool wasReturnUninhabitable =
func->getResults().isNull() && func->getResults().isNonNullable();
func->getResults().isNull() && func->getResults().isNonNullableRef();
Comment on lines 553 to +554

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

There is a logical contradiction in this check. func->getResults().isNull() checks if the type is the null type (which is a nullable reference type), while func->getResults().isNonNullableRef() checks if it is non-nullable. A type cannot be both null and non-nullable, so wasReturnUninhabitable will always evaluate to false. Based on the comment, you likely want to check if the return type is a non-nullable reference.

Suggested change
bool wasReturnUninhabitable =
func->getResults().isNull() && func->getResults().isNonNullable();
func->getResults().isNull() && func->getResults().isNonNullableRef();
bool wasReturnUninhabitable =
func->getResults().isNonNullableRef();

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not correct, but also points to a good renaming we could do. I'll also rename "isNull" to "isBottomRef".

func->setResults(Type::none);
// Remove the drops on the calls. Note that we must do this before updating
// returns in ReturnUpdater, as there may be recursive calls of this
Expand Down
2 changes: 1 addition & 1 deletion src/passes/DeadArgumentElimination2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1097,7 +1097,7 @@ struct Optimizer
// Add new vars to replace the removed params.
for (Index i = removedParams.size(); i > 0; --i) {
auto& [type, name] = removedParams[i - 1];
if (type.isNonNullable()) {
if (type.isNonNullableRef()) {
hasNewNonNullableLocal = true;
}
Builder::addVar(func, name, type);
Expand Down
2 changes: 1 addition & 1 deletion src/passes/GlobalStructInference.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,7 @@ struct GlobalStructInference : public Pass {
// We must add a cast to non-null in some cases: A read of a null
// descriptor returns a non-null value, so if there was a null in the
// global, that would not validate by itself.
if (ret->type.isNullable() && curr->type.isNonNullable()) {
if (ret->type.isNullableRef() && curr->type.isNonNullableRef()) {
ret = builder.makeRefAs(RefAsNonNull, ret);
}

Expand Down
5 changes: 3 additions & 2 deletions src/passes/Heap2Local.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -769,7 +769,7 @@ struct Struct2Local : PostWalker<Struct2Local> {
// Preserve the trapping on null descriptors by inserting a
// ref.as_non_null.
Expression* desc = curr->desc;
if (curr->desc->type.isNullable()) {
if (curr->desc->type.isNullableRef()) {
desc = builder.makeRefAs(RefAsNonNull, desc);
}
contents.push_back(builder.makeLocalSet(tempIndexes[numTemps - 1], desc));
Expand Down Expand Up @@ -898,7 +898,8 @@ struct Struct2Local : PostWalker<Struct2Local> {
// side effects, but that local.set would not be reflected in the parent
// map, so it would not be updated if the allocation flowing through
// that desc operand were later optimized.
if (allocIsCastDescEq && !allocIsCastRef && curr->type.isNullable()) {
if (allocIsCastDescEq && !allocIsCastRef &&
curr->type.isNullableRef()) {
// There might be a null value to let through. Reuse curr as a cast to
// null. Use a scratch local to move the reference value past the desc
// value.
Expand Down
8 changes: 4 additions & 4 deletions src/passes/InstrumentLocals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> {
Name import;
if (curr->type.isRef()) {
auto heapType = curr->type.getHeapType();
if (heapType == HeapType::func && curr->type.isNullable()) {
if (heapType == HeapType::func && curr->type.isNullableRef()) {
import = get_funcref;
} else if (heapType == HeapType::ext && curr->type.isNullable()) {
} else if (heapType == HeapType::ext && curr->type.isNullableRef()) {
import = get_externref;
} else {
WASM_UNREACHABLE("TODO: general reference types");
Expand Down Expand Up @@ -129,9 +129,9 @@ struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> {
}
if (type.isRef()) {
auto heapType = type.getHeapType();
if (heapType == HeapType::func && type.isNullable()) {
if (heapType == HeapType::func && type.isNullableRef()) {
import = set_funcref;
} else if (heapType == HeapType::ext && type.isNullable()) {
} else if (heapType == HeapType::ext && type.isNullableRef()) {
import = set_externref;
} else {
WASM_UNREACHABLE("TODO: general reference types");
Expand Down
2 changes: 1 addition & 1 deletion src/passes/LocalSubtyping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ struct LocalSubtyping : public WalkerPass<PostWalker<LocalSubtyping>> {
assert(newType != Type::none); // in valid wasm there must be a LUB

// Remove non-nullability if we disallow that in locals.
if (newType.isNonNullable()) {
if (newType.isNonNullableRef()) {
if (cannotBeNonNullable.contains(i)) {
newType = newType.with(Nullable);
}
Expand Down
12 changes: 6 additions & 6 deletions src/passes/MakeSharedObjects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ struct LazyTable {
Type sharedI31Nullable = Type(HeapTypes::i31.getBasic(Shared), Nullable);
Expression* res =
builder.makeCall(getRefToIndexName(), {arg}, sharedI31Nullable);
if (targetType.isNonNullable()) {
if (targetType.isNonNullableRef()) {
res = builder.makeRefAs(RefAsNonNull, res);
}
return res;
Expand Down Expand Up @@ -564,7 +564,7 @@ struct MakeSharedObjects
return;
}
Builder builder(*getModule());
if (curr->ref->type.isNonNullable()) {
if (curr->ref->type.isNonNullableRef()) {
// (ref.test castType (table.get $t (i31.get_u ref)))
curr->ref = builder.makeTableGet(
funcTable.getName(), builder.makeI31Get(curr->ref, false), funcref);
Expand All @@ -582,7 +582,7 @@ struct MakeSharedObjects
auto* cond = builder.makeRefIsNull(
builder.makeLocalTee(scratch, curr->ref, scratchType));
auto* ifNull =
builder.makeConst(Literal(int32_t(curr->castType.isNullable())));
builder.makeConst(Literal(int32_t(curr->castType.isNullableRef())));
curr->ref = builder.makeTableGet(
funcTable.getName(),
builder.makeI31Get(builder.makeLocalGet(scratch, scratchType), false),
Expand Down Expand Up @@ -630,7 +630,7 @@ struct MakeSharedObjects
auto* tee = builder.makeLocalTee(scratch, curr->ref, scratchType);
auto* isNull = builder.makeRefIsNull(tee);
Expression* ifNull = nullptr;
if (curr->type.isNullable()) {
if (curr->type.isNullableRef()) {
ifNull = builder.makeLocalGet(scratch, scratchType);
} else {
ifNull = builder.makeUnreachable();
Expand All @@ -640,7 +640,7 @@ struct MakeSharedObjects
auto* tableGet = builder.makeTableGet(funcTable.getName(), i31get, funcref);
auto* refTest = builder.makeRefTest(tableGet, curr->type);
Expression* ifPass = builder.makeLocalGet(scratch, scratchType);
if (curr->type.isNonNullable()) {
if (curr->type.isNonNullableRef()) {
ifPass = builder.makeRefAs(RefAsNonNull, ifPass);
}
auto* ifFail = builder.makeUnreachable();
Expand Down Expand Up @@ -676,7 +676,7 @@ struct MakeSharedObjects
Type sharedAnyNullable = Type(HeapTypes::any.getBasic(Shared), Nullable);
Expression* call =
builder.makeCall(getExternToAnyName(), {ext}, sharedAnyNullable);
if (curr->type.isNonNullable()) {
if (curr->type.isNonNullableRef()) {
call = builder.makeRefAs(RefAsNonNull, call);
}
replaceCurrent(call);
Expand Down
2 changes: 1 addition & 1 deletion src/passes/OptimizeCasts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ struct EarlyCastFinder
// As we only move RefAsNonNull RefAs casts right now, we should
// ignore a LocalGet if the type is already non-nullable, as
// adding an extra ref.as_non_null has no effect.
if (!currRefAsMove[curr->index].target && curr->type.isNullable()) {
if (!currRefAsMove[curr->index].target && curr->type.isNullableRef()) {
currRefAsMove[curr->index].target = curr;
}
}
Expand Down
Loading
Loading