| 321 | } |
| 322 | |
| 323 | Expect<void> |
| 324 | Executor::runRefTestOp(const Runtime::Instance::ModuleInstance *ModInst, |
| 325 | ValVariant &Val, const AST::Instruction &Instr, |
| 326 | const bool IsCast) const noexcept { |
| 327 | // Copy the value type here due to handling the externalized case. |
| 328 | auto VT = Val.get<RefVariant>().getType(); |
| 329 | if (VT.isExternalized()) { |
| 330 | VT = ValType(VT.isNullableRefType() ? TypeCode::RefNull : TypeCode::Ref, |
| 331 | TypeCode::ExternRef); |
| 332 | } |
| 333 | Span<const AST::SubType *const> GotTypeList = ModInst->getTypeList(); |
| 334 | if (!VT.isAbsHeapType()) { |
| 335 | auto *Inst = |
| 336 | Val.get<RefVariant>().getPtr<Runtime::Instance::CompositeBase>(); |
| 337 | // Reference must not be nullptr here because the null references are typed |
| 338 | // with the least abstract heap type. |
| 339 | assuming(Inst); |
| 340 | if (Inst->getModule()) { |
| 341 | GotTypeList = Inst->getModule()->getTypeList(); |
| 342 | } |
| 343 | } |
| 344 | |
| 345 | if (AST::TypeMatcher::matchType(ModInst->getTypeList(), Instr.getValType(), |
| 346 | GotTypeList, VT)) { |
| 347 | if (!IsCast) { |
| 348 | Val.emplace<uint32_t>(1U); |
| 349 | } |
| 350 | } else { |
| 351 | if (IsCast) { |
| 352 | spdlog::error(ErrCode::Value::CastFailed); |
| 353 | spdlog::error(ErrInfo::InfoMismatch(Instr.getValType(), VT)); |
| 354 | spdlog::error( |
| 355 | ErrInfo::InfoInstruction(Instr.getOpCode(), Instr.getOffset())); |
| 356 | return Unexpect(ErrCode::Value::CastFailed); |
| 357 | } else { |
| 358 | Val.emplace<uint32_t>(0U); |
| 359 | } |
| 360 | } |
| 361 | return {}; |
| 362 | } |
| 363 | |
| 364 | Expect<void> Executor::runRefConvOp(RefVariant &Ref, |
| 365 | TypeCode TCode) const noexcept { |
nothing calls this directly
no test coverage detected