| 188 | } |
| 189 | |
| 190 | Expect<void> Executor::runCallIndirectOp(Runtime::StackManager &StackMgr, |
| 191 | const AST::Instruction &Instr, |
| 192 | AST::InstrView::iterator &PC, |
| 193 | bool IsTailCall) noexcept { |
| 194 | // Get Table Instance. |
| 195 | const auto *TabInst = getTabInstByIdx(StackMgr, Instr.getSourceIndex()); |
| 196 | |
| 197 | // Get function type at index x. |
| 198 | const auto *ModInst = StackMgr.getModule(); |
| 199 | const auto &ExpDefType = **ModInst->getType(Instr.getTargetIndex()); |
| 200 | |
| 201 | // Pop the value of index from the Stack. |
| 202 | const auto AddrType = TabInst->getTableType().getLimit().getAddrType(); |
| 203 | uint64_t Idx = extractAddr(StackMgr.pop(), AddrType); |
| 204 | |
| 205 | // If idx not small than tab.elem, trap. |
| 206 | if (Idx >= TabInst->getSize()) { |
| 207 | spdlog::error(ErrCode::Value::UndefinedElement); |
| 208 | spdlog::error(ErrInfo::InfoInstruction(Instr.getOpCode(), Instr.getOffset(), |
| 209 | {Idx}, |
| 210 | {ValTypeFromType<uint32_t>()})); |
| 211 | return Unexpect(ErrCode::Value::UndefinedElement); |
| 212 | } |
| 213 | |
| 214 | // Get function address. The bound is guaranteed. |
| 215 | RefVariant Ref = *TabInst->getRefAddr(Idx); |
| 216 | const auto *FuncInst = retrieveFuncRef(Ref); |
| 217 | if (FuncInst == nullptr) { |
| 218 | spdlog::error(ErrCode::Value::UninitializedElement); |
| 219 | spdlog::error(ErrInfo::InfoInstruction(Instr.getOpCode(), Instr.getOffset(), |
| 220 | {Idx}, |
| 221 | {ValTypeFromType<uint32_t>()})); |
| 222 | return Unexpect(ErrCode::Value::UninitializedElement); |
| 223 | } |
| 224 | |
| 225 | // Check function type. |
| 226 | bool IsMatch = false; |
| 227 | if (FuncInst->getModule()) { |
| 228 | IsMatch = AST::TypeMatcher::matchType( |
| 229 | ModInst->getTypeList(), *ExpDefType.getTypeIndex(), |
| 230 | FuncInst->getModule()->getTypeList(), FuncInst->getTypeIndex()); |
| 231 | } else { |
| 232 | // Independent host module instance case. Matching the composite type |
| 233 | // directly. |
| 234 | IsMatch = AST::TypeMatcher::matchType( |
| 235 | ModInst->getTypeList(), ExpDefType.getCompositeType(), |
| 236 | FuncInst->getHostFunc().getDefinedType().getCompositeType()); |
| 237 | } |
| 238 | if (!IsMatch) { |
| 239 | auto &ExpFuncType = ExpDefType.getCompositeType().getFuncType(); |
| 240 | auto &GotFuncType = FuncInst->getFuncType(); |
| 241 | spdlog::error(ErrCode::Value::IndirectCallTypeMismatch); |
| 242 | spdlog::error(ErrInfo::InfoInstruction(Instr.getOpCode(), Instr.getOffset(), |
| 243 | {Idx}, |
| 244 | {ValTypeFromType<uint32_t>()})); |
| 245 | spdlog::error(ErrInfo::InfoMismatch( |
| 246 | ExpFuncType.getParamTypes(), ExpFuncType.getReturnTypes(), |
| 247 | GotFuncType.getParamTypes(), GotFuncType.getReturnTypes())); |
nothing calls this directly
no test coverage detected