Load binary to construct Limit node. See "include/loader/loader.h".
| 222 | |
| 223 | // Load binary to construct Limit node. See "include/loader/loader.h". |
| 224 | Expect<void> Loader::loadLimit(AST::Limit &Lim) { |
| 225 | // Read the limit type flag. |
| 226 | EXPECTED_TRY(uint8_t B, FMgr.readByte().map_error([this](auto E) { |
| 227 | return logLoadError(E, FMgr.getLastOffset(), ASTNodeAttr::Type_Limit); |
| 228 | })); |
| 229 | |
| 230 | // Check the type flag with proposals. |
| 231 | auto LimitType = static_cast<AST::Limit::LimitType>(B); |
| 232 | switch (LimitType) { |
| 233 | case AST::Limit::LimitType::HasMin: |
| 234 | case AST::Limit::LimitType::HasMinMax: |
| 235 | case AST::Limit::LimitType::SharedNoMax: |
| 236 | case AST::Limit::LimitType::Shared: |
| 237 | case AST::Limit::LimitType::I64HasMin: |
| 238 | case AST::Limit::LimitType::I64HasMinMax: |
| 239 | case AST::Limit::LimitType::I64SharedNoMax: |
| 240 | case AST::Limit::LimitType::I64Shared: |
| 241 | Lim.setType(static_cast<AST::Limit::LimitType>(B)); |
| 242 | break; |
| 243 | default: |
| 244 | if (Conf.hasProposal(Proposal::Memory64)) { |
| 245 | // With the Memory64 proposal enabled, the error code is different. |
| 246 | return logLoadError(ErrCode::Value::MalformedLimitFlags, |
| 247 | FMgr.getLastOffset(), ASTNodeAttr::Type_Limit); |
| 248 | } else { |
| 249 | if (B == 0x80 || B == 0x81) { |
| 250 | // LEB128 cases will fail. |
| 251 | return logLoadError(ErrCode::Value::IntegerTooLong, |
| 252 | FMgr.getLastOffset(), ASTNodeAttr::Type_Limit); |
| 253 | } else { |
| 254 | return logLoadError(ErrCode::Value::IntegerTooLarge, |
| 255 | FMgr.getLastOffset(), ASTNodeAttr::Type_Limit); |
| 256 | } |
| 257 | } |
| 258 | } |
| 259 | if (Lim.isShared() && !Conf.hasProposal(Proposal::Threads)) { |
| 260 | if (Conf.hasProposal(Proposal::Memory64)) { |
| 261 | return logLoadError(ErrCode::Value::MalformedLimitFlags, |
| 262 | FMgr.getLastOffset(), ASTNodeAttr::Type_Limit); |
| 263 | } else { |
| 264 | return logLoadError(ErrCode::Value::IntegerTooLarge, FMgr.getLastOffset(), |
| 265 | ASTNodeAttr::Type_Limit); |
| 266 | } |
| 267 | } |
| 268 | if (Lim.is64() && !Conf.hasProposal(Proposal::Memory64)) { |
| 269 | return logLoadError(ErrCode::Value::IntegerTooLarge, FMgr.getLastOffset(), |
| 270 | ASTNodeAttr::Type_Limit); |
| 271 | } |
| 272 | |
| 273 | // Read the min and max numbers. |
| 274 | // S64 is accepted when the Memory64 proposal is enabled. Therefore, we should |
| 275 | // check the S32 representation length when the Memory64 proposal is disabled. |
| 276 | uint64_t MinVal = 0, MaxVal = 0; |
| 277 | if (Conf.hasProposal(Proposal::Memory64)) { |
| 278 | EXPECTED_TRY(MinVal, FMgr.readU64().map_error([this](auto E) { |
| 279 | return logLoadError(E, FMgr.getLastOffset(), ASTNodeAttr::Type_Limit); |
| 280 | })); |
| 281 | if (Lim.hasMax()) { |
nothing calls this directly
no test coverage detected