| 307 | } |
| 308 | |
| 309 | Expect<void> |
| 310 | Executor::checkOffsetOverflow(const Runtime::Instance::MemoryInstance &MemInst, |
| 311 | const AST::Instruction &Instr, const uint64_t Val, |
| 312 | const uint64_t Size) const noexcept { |
| 313 | // This function simply checks that the calculated offset fits in 64 bits. |
| 314 | uint64_t StartOffset; |
| 315 | #if defined(_MSC_VER) && !defined(__clang__) // MSVC |
| 316 | if (std::numeric_limits<uint64_t>::max() - Instr.getMemoryOffset() < Val) { |
| 317 | StartOffset = Instr.getMemoryOffset() + Val; |
| 318 | #else |
| 319 | if (unlikely( |
| 320 | __builtin_add_overflow(Instr.getMemoryOffset(), Val, &StartOffset))) { |
| 321 | #endif |
| 322 | spdlog::error(ErrCode::Value::MemoryOutOfBounds); |
| 323 | spdlog::error( |
| 324 | ErrInfo::InfoBoundary(StartOffset, Size, MemInst.getSize(), true)); |
| 325 | spdlog::error( |
| 326 | ErrInfo::InfoInstruction(Instr.getOpCode(), Instr.getOffset())); |
| 327 | return Unexpect(ErrCode::Value::MemoryOutOfBounds); |
| 328 | } |
| 329 | return {}; |
| 330 | } |
| 331 | |
| 332 | const AST::SubType *Executor::getDefTypeByIdx(Runtime::StackManager &StackMgr, |
| 333 | const uint32_t Idx) const { |
| 334 | const auto *ModInst = StackMgr.getModule(); |
| 335 | // When the top frame is a dummy frame, the instance cannot be found. |
| 336 | if (unlikely(ModInst == nullptr)) { |
| 337 | return nullptr; |
| 338 | } |
| 339 | return ModInst->unsafeGetType(Idx); |
| 340 | } |
| 341 | |
| 342 | const WasmEdge::AST::CompositeType & |
| 343 | Executor::getCompositeTypeByIdx(Runtime::StackManager &StackMgr, |
| 344 | const uint32_t Idx) const noexcept { |
| 345 | auto *DefType = getDefTypeByIdx(StackMgr, Idx); |
| 346 | assuming(DefType); |
| 347 | const auto &CompType = DefType->getCompositeType(); |
| 348 | assuming(!CompType.isFunc()); |
| 349 | return CompType; |
| 350 | } |
| 351 | |
| 352 | const ValType & |
| 353 | Executor::getStructStorageTypeByIdx(Runtime::StackManager &StackMgr, |
| 354 | const uint32_t Idx, |
| 355 | const uint32_t Off) const noexcept { |
| 356 | const auto &CompType = getCompositeTypeByIdx(StackMgr, Idx); |
| 357 | assuming(static_cast<uint32_t>(CompType.getFieldTypes().size()) > Off); |
| 358 | return CompType.getFieldTypes()[Off].getStorageType(); |
| 359 | } |
| 360 | |
| 361 | const ValType & |
| 362 | Executor::getArrayStorageTypeByIdx(Runtime::StackManager &StackMgr, |
| 363 | const uint32_t Idx) const noexcept { |
| 364 | const auto &CompType = getCompositeTypeByIdx(StackMgr, Idx); |
| 365 | assuming(static_cast<uint32_t>(CompType.getFieldTypes().size()) == 1); |
| 366 | return CompType.getFieldTypes()[0].getStorageType(); |
nothing calls this directly
no test coverage detected