diff --git a/src/ir/properties.h b/src/ir/properties.h index e52902597a0..4b4126d750d 100644 --- a/src/ir/properties.h +++ b/src/ir/properties.h @@ -521,8 +521,8 @@ inline MemoryOrder getMemoryOrder(Expression* curr) { } // Whether this instruction will be unwritable in the text and binary formats -// because it requires a type index immediate giving the type of a child that -// has unreachable or null type, and therefore does not have a type index. +// because it requires a type index immediate computed from an expression with +// unreachable or null type, and therefore no type index. inline bool hasUnwritableTypeImmediate(Expression* curr) { #define DELEGATE_ID curr->_id @@ -534,6 +534,24 @@ inline bool hasUnwritableTypeImmediate(Expression* curr) { } \ } +#define DELEGATE_IMMEDIATE_TYPED_RESULT(id) \ + if (curr->type == Type::unreachable) { \ + if constexpr (id::SpecificId == Expression::Id::RefCastId) { \ + auto* cast = curr->cast(); \ + if (!cast->desc) { \ + return true; \ + } \ + if (!cast->desc->type.isRef()) { \ + return true; \ + } \ + if (!cast->desc->type.getHeapType().getDescribedType()) { \ + return true; \ + } \ + return false; \ + } \ + return true; \ + } + #define DELEGATE_FIELD_CHILD(id, field) #define DELEGATE_FIELD_CHILD_VECTOR(id, field) #define DELEGATE_FIELD_INT(id, field) diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 11a73315b74..68981953211 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -320,63 +320,6 @@ struct PrintSExpression : public UnifiedExpressionVisitor { void visitTryTable(TryTable* curr); void printUnreachableReplacement(Expression* curr); - bool maybePrintUnreachableReplacement(Expression* curr, Type type); - void visitRefCast(RefCast* curr) { - if ((curr->desc && curr->desc->type != Type::unreachable) || - !maybePrintUnreachableReplacement(curr, curr->type)) { - visitExpression(curr); - } - } - void visitStructNew(StructNew* curr) { - if (!maybePrintUnreachableReplacement(curr, curr->type)) { - visitExpression(curr); - } - } - void visitArrayNew(ArrayNew* curr) { - if (!maybePrintUnreachableReplacement(curr, curr->type)) { - visitExpression(curr); - } - } - void visitArrayNewData(ArrayNewData* curr) { - if (!maybePrintUnreachableReplacement(curr, curr->type)) { - visitExpression(curr); - } - } - void visitArrayNewElem(ArrayNewElem* curr) { - if (!maybePrintUnreachableReplacement(curr, curr->type)) { - visitExpression(curr); - } - } - void visitArrayNewFixed(ArrayNewFixed* curr) { - if (!maybePrintUnreachableReplacement(curr, curr->type)) { - visitExpression(curr); - } - } - void visitContNew(ContNew* curr) { - if (!maybePrintUnreachableReplacement(curr, curr->type)) { - visitExpression(curr); - } - } - void visitContBind(ContBind* curr) { - if (!maybePrintUnreachableReplacement(curr, curr->type)) { - visitExpression(curr); - } - } - void visitResume(Resume* curr) { - if (!maybePrintUnreachableReplacement(curr, curr->type)) { - visitExpression(curr); - } - } - void visitResumeThrow(ResumeThrow* curr) { - if (!maybePrintUnreachableReplacement(curr, curr->type)) { - visitExpression(curr); - } - } - void visitStackSwitch(StackSwitch* curr) { - if (!maybePrintUnreachableReplacement(curr, curr->type)) { - visitExpression(curr); - } - } // Module-level visitors void handleSignature(Function* curr, bool printImplicitNames = false); @@ -3143,19 +3086,6 @@ void PrintSExpression::printUnreachableReplacement(Expression* curr) { decIndent(); } -bool PrintSExpression::maybePrintUnreachableReplacement(Expression* curr, - Type type) { - // When we cannot print an instruction because the child from which it's - // supposed to get a type immediate is unreachable, then we print a - // semantically-equivalent block that drops each of the children and ends in - // an unreachable. - if (type == Type::unreachable) { - printUnreachableReplacement(curr); - return true; - } - return false; -} - static bool requiresExplicitFuncType(HeapType type) { // When the `(type $f)` in a function's typeuse is omitted, the typeuse // matches or declares an MVP function type. When the intended type is not an @@ -4009,6 +3939,10 @@ std::ostream& operator<<(std::ostream& o, wasm::ModuleExpression pair) { } std::ostream& operator<<(std::ostream& o, wasm::ShallowExpression expression) { + if (Properties::hasUnwritableTypeImmediate(expression.expr)) { + o << "(; unreachable " << getExpressionName(expression.expr) << " ;)"; + return o; + } wasm::PrintSExpression printer(o); printer.setModule(expression.module); wasm::PrintExpressionContents(printer).visit(expression.expr); diff --git a/src/wasm-delegations-fields.def b/src/wasm-delegations-fields.def index 142d1e7be70..432f4d832c9 100644 --- a/src/wasm-delegations-fields.def +++ b/src/wasm-delegations-fields.def @@ -29,6 +29,10 @@ // // DELEGATE_END(id) - called at the end of a case. // +// DELEGATE_IMMEDIATE_TYPED_RESULT(id) - does not actually represent a field, +// but is called for expressions whose result types are used to compute type +// immediates. Defining this is optional. +// // DELEGATE_GET_FIELD(id, field) - called to get a field by its name. This must // know the object on which to get it, so it is just useful for the case // where you operate on a single such object, but in that case it is nice @@ -117,6 +121,10 @@ #define DELEGATE_END(id) #endif +#ifndef DELEGATE_IMMEDIATE_TYPED_RESULT +#define DELEGATE_IMMEDIATE_TYPED_RESULT(id) +#endif + #ifndef DELEGATE_FIELD_CHILD #error please define DELEGATE_FIELD_CHILD(id, field) #endif @@ -659,6 +667,7 @@ DELEGATE_FIELD_CHILD(RefTest, ref) DELEGATE_FIELD_CASE_END(RefTest) DELEGATE_FIELD_CASE_START(RefCast) +DELEGATE_IMMEDIATE_TYPED_RESULT(RefCast) DELEGATE_FIELD_OPTIONAL_IMMEDIATE_TYPED_CHILD(RefCast, desc) DELEGATE_FIELD_CHILD(RefCast, ref) DELEGATE_FIELD_CASE_END(RefCast) @@ -676,6 +685,7 @@ DELEGATE_FIELD_CHILD(BrOn, ref) DELEGATE_FIELD_CASE_END(BrOn) DELEGATE_FIELD_CASE_START(StructNew) +DELEGATE_IMMEDIATE_TYPED_RESULT(StructNew) DELEGATE_FIELD_OPTIONAL_CHILD(StructNew, desc) DELEGATE_FIELD_CHILD_VECTOR(StructNew, operands) DELEGATE_FIELD_CASE_END(StructNew) @@ -711,23 +721,27 @@ DELEGATE_FIELD_INT(StructCmpxchg, order) DELEGATE_FIELD_CASE_END(StructCmpxchg) DELEGATE_FIELD_CASE_START(ArrayNew) +DELEGATE_IMMEDIATE_TYPED_RESULT(ArrayNew) DELEGATE_FIELD_CHILD(ArrayNew, size) DELEGATE_FIELD_OPTIONAL_CHILD(ArrayNew, init) DELEGATE_FIELD_CASE_END(ArrayNew) DELEGATE_FIELD_CASE_START(ArrayNewData) +DELEGATE_IMMEDIATE_TYPED_RESULT(ArrayNewData) DELEGATE_FIELD_NAME_KIND(ArrayNewData, segment, ModuleItemKind::DataSegment) DELEGATE_FIELD_CHILD(ArrayNewData, size) DELEGATE_FIELD_CHILD(ArrayNewData, offset) DELEGATE_FIELD_CASE_END(ArrayNewData) DELEGATE_FIELD_CASE_START(ArrayNewElem) +DELEGATE_IMMEDIATE_TYPED_RESULT(ArrayNewElem) DELEGATE_FIELD_NAME_KIND(ArrayNewElem, segment, ModuleItemKind::ElementSegment) DELEGATE_FIELD_CHILD(ArrayNewElem, size) DELEGATE_FIELD_CHILD(ArrayNewElem, offset) DELEGATE_FIELD_CASE_END(ArrayNewElem) DELEGATE_FIELD_CASE_START(ArrayNewFixed) +DELEGATE_IMMEDIATE_TYPED_RESULT(ArrayNewFixed) DELEGATE_FIELD_CHILD_VECTOR(ArrayNewFixed, values) DELEGATE_FIELD_CASE_END(ArrayNewFixed) @@ -866,10 +880,12 @@ DELEGATE_FIELD_CHILD(StringSliceWTF, ref) DELEGATE_FIELD_CASE_END(StringSliceWTF) DELEGATE_FIELD_CASE_START(ContNew) +DELEGATE_IMMEDIATE_TYPED_RESULT(ContNew) DELEGATE_FIELD_CHILD(ContNew, func) DELEGATE_FIELD_CASE_END(ContNew) DELEGATE_FIELD_CASE_START(ContBind) +DELEGATE_IMMEDIATE_TYPED_RESULT(ContBind) DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD(ContBind, cont) DELEGATE_FIELD_CHILD_VECTOR(ContBind, operands) DELEGATE_FIELD_CASE_END(ContBind) @@ -921,6 +937,7 @@ DELEGATE_FIELD_MAIN_END #undef DELEGATE_ID #undef DELEGATE_START #undef DELEGATE_END +#undef DELEGATE_IMMEDIATE_TYPED_RESULT #undef DELEGATE_FIELD_CHILD #undef DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD #undef DELEGATE_FIELD_OPTIONAL_CHILD