diff options
Diffstat (limited to 'src/ir')
-rw-r--r-- | src/ir/gc-type-utils.h | 77 |
1 files changed, 16 insertions, 61 deletions
diff --git a/src/ir/gc-type-utils.h b/src/ir/gc-type-utils.h index 318b1b3a3..6dbb3157a 100644 --- a/src/ir/gc-type-utils.h +++ b/src/ir/gc-type-utils.h @@ -39,6 +39,22 @@ enum EvaluationResult { SuccessOnlyIfNonNull, }; +inline EvaluationResult flipEvaluationResult(EvaluationResult result) { + switch (result) { + case Unknown: + return Unknown; + case Success: + return Failure; + case Failure: + return Success; + case SuccessOnlyIfNull: + return SuccessOnlyIfNonNull; + case SuccessOnlyIfNonNull: + return SuccessOnlyIfNull; + } + WASM_UNREACHABLE("unexpected result"); +} + // Given the type of a reference and a type to attempt to cast it to, return // what we know about the result. inline EvaluationResult evaluateCastCheck(Type refType, Type castType) { @@ -85,67 +101,6 @@ inline EvaluationResult evaluateCastCheck(Type refType, Type castType) { return Unknown; } -// Given an instruction that checks if the child reference is of a certain kind -// (like br_on_func checks if it is a function), see if type info lets us -// determine that at compile time. -// This ignores nullability - it just checks the kind. -inline EvaluationResult evaluateKindCheck(Expression* curr) { - Kind expected; - Expression* child; - - // Some operations flip the condition. - bool flip = false; - - if (auto* br = curr->dynCast<BrOn>()) { - switch (br->op) { - // We don't check nullability here. - case BrOnNull: - case BrOnNonNull: - return Unknown; - case BrOnCastFail: - flip = true; - [[fallthrough]]; - case BrOnCast: { - auto result = - GCTypeUtils::evaluateCastCheck(br->ref->type, br->castType); - if (result == Success) { - return flip ? Failure : Success; - } else if (result == Failure) { - return flip ? Success : Failure; - } - return Unknown; - } - default: - WASM_UNREACHABLE("unhandled BrOn"); - } - child = br->ref; - } else { - WASM_UNREACHABLE("invalid input to evaluateKindCheck"); - } - - auto childType = child->type; - - Kind actual; - - if (childType == Type::unreachable) { - return Unknown; - } else if (childType.isFunction()) { - actual = Func; - } else if (childType.isData()) { - actual = Data; - } else if (childType.getHeapType() == HeapType::i31) { - actual = I31; - } else { - return Unknown; - } - - auto success = actual == expected; - if (flip) { - success = !success; - } - return success ? Success : Failure; -} - } // namespace wasm::GCTypeUtils #endif // wasm_ir_gc_type_utils_h |