Serenity Operating System
at master 1427 lines 55 kB view raw
1/* 2 * Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/Debug.h> 8#include <AK/Endian.h> 9#include <AK/LEB128.h> 10#include <AK/MemoryStream.h> 11#include <AK/ScopeGuard.h> 12#include <AK/ScopeLogger.h> 13#include <LibWasm/Types.h> 14 15namespace Wasm { 16 17ParseError with_eof_check(Stream const& stream, ParseError error_if_not_eof) 18{ 19 if (stream.is_eof()) 20 return ParseError::UnexpectedEof; 21 return error_if_not_eof; 22} 23 24template<typename T> 25static auto parse_vector(Stream& stream) 26{ 27 ScopeLogger<WASM_BINPARSER_DEBUG> logger; 28 if constexpr (requires { T::parse(stream); }) { 29 using ResultT = typename decltype(T::parse(stream))::ValueType; 30 auto count_or_error = stream.read_value<LEB128<size_t>>(); 31 if (count_or_error.is_error()) 32 return ParseResult<Vector<ResultT>> { with_eof_check(stream, ParseError::ExpectedSize) }; 33 size_t count = count_or_error.release_value(); 34 35 Vector<ResultT> entries; 36 for (size_t i = 0; i < count; ++i) { 37 auto result = T::parse(stream); 38 if (result.is_error()) 39 return ParseResult<Vector<ResultT>> { result.error() }; 40 entries.append(result.release_value()); 41 } 42 return ParseResult<Vector<ResultT>> { move(entries) }; 43 } else { 44 auto count_or_error = stream.read_value<LEB128<size_t>>(); 45 if (count_or_error.is_error()) 46 return ParseResult<Vector<T>> { with_eof_check(stream, ParseError::ExpectedSize) }; 47 size_t count = count_or_error.release_value(); 48 49 Vector<T> entries; 50 for (size_t i = 0; i < count; ++i) { 51 if constexpr (IsSame<T, size_t>) { 52 auto value_or_error = stream.read_value<LEB128<size_t>>(); 53 if (value_or_error.is_error()) 54 return ParseResult<Vector<T>> { with_eof_check(stream, ParseError::ExpectedSize) }; 55 size_t value = value_or_error.release_value(); 56 entries.append(value); 57 } else if constexpr (IsSame<T, ssize_t>) { 58 auto value_or_error = stream.read_value<LEB128<ssize_t>>(); 59 if (value_or_error.is_error()) 60 return ParseResult<Vector<T>> { with_eof_check(stream, ParseError::ExpectedSize) }; 61 ssize_t value = value_or_error.release_value(); 62 entries.append(value); 63 } else if constexpr (IsSame<T, u8>) { 64 if (count > Constants::max_allowed_vector_size) 65 return ParseResult<Vector<T>> { ParseError::HugeAllocationRequested }; 66 entries.resize(count); 67 if (stream.read_until_filled({ entries.data(), entries.size() }).is_error()) 68 return ParseResult<Vector<T>> { with_eof_check(stream, ParseError::InvalidInput) }; 69 break; // Note: We read this all in one go! 70 } 71 } 72 return ParseResult<Vector<T>> { move(entries) }; 73 } 74} 75 76static ParseResult<DeprecatedString> parse_name(Stream& stream) 77{ 78 ScopeLogger<WASM_BINPARSER_DEBUG> logger; 79 auto data = parse_vector<u8>(stream); 80 if (data.is_error()) 81 return data.error(); 82 83 return DeprecatedString::copy(data.value()); 84} 85 86template<typename T> 87struct ParseUntilAnyOfResult { 88 u8 terminator { 0 }; 89 Vector<T> values; 90}; 91template<typename T, u8... terminators, typename... Args> 92static ParseResult<ParseUntilAnyOfResult<T>> parse_until_any_of(Stream& stream, Args&... args) 93requires(requires(Stream& stream, Args... args) { T::parse(stream, args...); }) 94{ 95 ScopeLogger<WASM_BINPARSER_DEBUG> logger; 96 ReconsumableStream new_stream { stream }; 97 98 ParseUntilAnyOfResult<T> result; 99 for (;;) { 100 auto byte_or_error = new_stream.read_value<u8>(); 101 if (byte_or_error.is_error()) 102 return with_eof_check(stream, ParseError::ExpectedValueOrTerminator); 103 104 auto byte = byte_or_error.release_value(); 105 106 constexpr auto equals = [](auto&& a, auto&& b) { return a == b; }; 107 108 if ((... || equals(byte, terminators))) { 109 result.terminator = byte; 110 return result; 111 } 112 113 new_stream.unread({ &byte, 1 }); 114 auto parse_result = T::parse(new_stream, args...); 115 if (parse_result.is_error()) 116 return parse_result.error(); 117 118 result.values.extend(parse_result.release_value()); 119 } 120} 121 122ParseResult<ValueType> ValueType::parse(Stream& stream) 123{ 124 ScopeLogger<WASM_BINPARSER_DEBUG> logger("ValueType"sv); 125 auto tag_or_error = stream.read_value<u8>(); 126 if (tag_or_error.is_error()) 127 return with_eof_check(stream, ParseError::ExpectedKindTag); 128 129 auto tag = tag_or_error.release_value(); 130 131 switch (tag) { 132 case Constants::i32_tag: 133 return ValueType(I32); 134 case Constants::i64_tag: 135 return ValueType(I64); 136 case Constants::f32_tag: 137 return ValueType(F32); 138 case Constants::f64_tag: 139 return ValueType(F64); 140 case Constants::function_reference_tag: 141 return ValueType(FunctionReference); 142 case Constants::extern_reference_tag: 143 return ValueType(ExternReference); 144 default: 145 return with_eof_check(stream, ParseError::InvalidTag); 146 } 147} 148 149ParseResult<ResultType> ResultType::parse(Stream& stream) 150{ 151 ScopeLogger<WASM_BINPARSER_DEBUG> logger("ResultType"sv); 152 auto types = parse_vector<ValueType>(stream); 153 if (types.is_error()) 154 return types.error(); 155 return ResultType { types.release_value() }; 156} 157 158ParseResult<FunctionType> FunctionType::parse(Stream& stream) 159{ 160 ScopeLogger<WASM_BINPARSER_DEBUG> logger("FunctionType"sv); 161 auto tag_or_error = stream.read_value<u8>(); 162 if (tag_or_error.is_error()) 163 return with_eof_check(stream, ParseError::ExpectedKindTag); 164 165 auto tag = tag_or_error.release_value(); 166 167 if (tag != Constants::function_signature_tag) { 168 dbgln("Expected 0x60, but found {:#x}", tag); 169 return with_eof_check(stream, ParseError::InvalidTag); 170 } 171 172 auto parameters_result = parse_vector<ValueType>(stream); 173 if (parameters_result.is_error()) 174 return parameters_result.error(); 175 auto results_result = parse_vector<ValueType>(stream); 176 if (results_result.is_error()) 177 return results_result.error(); 178 179 return FunctionType { parameters_result.release_value(), results_result.release_value() }; 180} 181 182ParseResult<Limits> Limits::parse(Stream& stream) 183{ 184 ScopeLogger<WASM_BINPARSER_DEBUG> logger("Limits"sv); 185 auto flag_or_error = stream.read_value<u8>(); 186 if (flag_or_error.is_error()) 187 return with_eof_check(stream, ParseError::ExpectedKindTag); 188 189 auto flag = flag_or_error.release_value(); 190 191 if (flag > 1) 192 return with_eof_check(stream, ParseError::InvalidTag); 193 194 auto min_or_error = stream.read_value<LEB128<size_t>>(); 195 if (min_or_error.is_error()) 196 return with_eof_check(stream, ParseError::ExpectedSize); 197 size_t min = min_or_error.release_value(); 198 199 Optional<u32> max; 200 if (flag) { 201 auto value_or_error = stream.read_value<LEB128<size_t>>(); 202 if (value_or_error.is_error()) 203 return with_eof_check(stream, ParseError::ExpectedSize); 204 max = value_or_error.release_value(); 205 } 206 207 return Limits { static_cast<u32>(min), move(max) }; 208} 209 210ParseResult<MemoryType> MemoryType::parse(Stream& stream) 211{ 212 ScopeLogger<WASM_BINPARSER_DEBUG> logger("MemoryType"sv); 213 auto limits_result = Limits::parse(stream); 214 if (limits_result.is_error()) 215 return limits_result.error(); 216 return MemoryType { limits_result.release_value() }; 217} 218 219ParseResult<TableType> TableType::parse(Stream& stream) 220{ 221 ScopeLogger<WASM_BINPARSER_DEBUG> logger("TableType"sv); 222 auto type_result = ValueType::parse(stream); 223 if (type_result.is_error()) 224 return type_result.error(); 225 if (!type_result.value().is_reference()) 226 return with_eof_check(stream, ParseError::InvalidType); 227 auto limits_result = Limits::parse(stream); 228 if (limits_result.is_error()) 229 return limits_result.error(); 230 return TableType { type_result.release_value(), limits_result.release_value() }; 231} 232 233ParseResult<GlobalType> GlobalType::parse(Stream& stream) 234{ 235 ScopeLogger<WASM_BINPARSER_DEBUG> logger("GlobalType"sv); 236 auto type_result = ValueType::parse(stream); 237 if (type_result.is_error()) 238 return type_result.error(); 239 240 auto mutable_or_error = stream.read_value<u8>(); 241 if (mutable_or_error.is_error()) 242 return with_eof_check(stream, ParseError::ExpectedKindTag); 243 244 auto mutable_ = mutable_or_error.release_value(); 245 246 if (mutable_ > 1) 247 return with_eof_check(stream, ParseError::InvalidTag); 248 249 return GlobalType { type_result.release_value(), mutable_ == 0x01 }; 250} 251 252ParseResult<BlockType> BlockType::parse(Stream& stream) 253{ 254 ScopeLogger<WASM_BINPARSER_DEBUG> logger("BlockType"sv); 255 auto kind_or_error = stream.read_value<u8>(); 256 if (kind_or_error.is_error()) 257 return with_eof_check(stream, ParseError::ExpectedKindTag); 258 259 auto kind = kind_or_error.release_value(); 260 if (kind == Constants::empty_block_tag) 261 return BlockType {}; 262 263 { 264 FixedMemoryStream value_stream { ReadonlyBytes { &kind, 1 } }; 265 if (auto value_type = ValueType::parse(value_stream); !value_type.is_error()) 266 return BlockType { value_type.release_value() }; 267 } 268 269 ReconsumableStream new_stream { stream }; 270 new_stream.unread({ &kind, 1 }); 271 272 auto index_value_or_error = stream.read_value<LEB128<ssize_t>>(); 273 if (index_value_or_error.is_error()) 274 return with_eof_check(stream, ParseError::ExpectedIndex); 275 ssize_t index_value = index_value_or_error.release_value(); 276 277 if (index_value < 0) { 278 dbgln("Invalid type index {}", index_value); 279 return with_eof_check(stream, ParseError::InvalidIndex); 280 } 281 282 return BlockType { TypeIndex(index_value) }; 283} 284 285ParseResult<Vector<Instruction>> Instruction::parse(Stream& stream, InstructionPointer& ip) 286{ 287 struct NestedInstructionState { 288 Vector<Instruction> prior_instructions; 289 OpCode opcode; 290 BlockType block_type; 291 InstructionPointer end_ip; 292 Optional<InstructionPointer> else_ip; 293 }; 294 Vector<NestedInstructionState, 4> nested_instructions; 295 Vector<Instruction> resulting_instructions; 296 297 do { 298 ScopeLogger<WASM_BINPARSER_DEBUG> logger("Instruction"sv); 299 auto byte_or_error = stream.read_value<u8>(); 300 if (byte_or_error.is_error()) 301 return with_eof_check(stream, ParseError::ExpectedKindTag); 302 303 auto byte = byte_or_error.release_value(); 304 305 if (!nested_instructions.is_empty()) { 306 auto& nested_structure = nested_instructions.last(); 307 if (byte == 0x0b) { 308 // block/loop/if end 309 nested_structure.end_ip = ip + (nested_structure.else_ip.has_value() ? 1 : 0); 310 ++ip; 311 312 // Transform op(..., instr*) -> op(...) instr* op(end(ip)) 313 auto instructions = move(nested_structure.prior_instructions); 314 instructions.ensure_capacity(instructions.size() + 2 + resulting_instructions.size()); 315 instructions.append(Instruction { nested_structure.opcode, StructuredInstructionArgs { nested_structure.block_type, nested_structure.end_ip, nested_structure.else_ip } }); 316 instructions.extend(move(resulting_instructions)); 317 instructions.append(Instruction { Instructions::structured_end }); 318 resulting_instructions = move(instructions); 319 nested_instructions.take_last(); 320 continue; 321 } 322 323 if (byte == 0x05) { 324 // if...else 325 326 // Transform op(..., instr*, instr*) -> op(...) instr* op(else(ip) instr* op(end(ip)) 327 resulting_instructions.append(Instruction { Instructions::structured_else }); 328 ++ip; 329 nested_structure.else_ip = ip.value(); 330 continue; 331 } 332 } 333 334 OpCode opcode { byte }; 335 ++ip; 336 337 switch (opcode.value()) { 338 case Instructions::block.value(): 339 case Instructions::loop.value(): 340 case Instructions::if_.value(): { 341 auto block_type = BlockType::parse(stream); 342 if (block_type.is_error()) 343 return block_type.error(); 344 345 nested_instructions.append({ move(resulting_instructions), opcode, block_type.release_value(), {}, {} }); 346 resulting_instructions = {}; 347 break; 348 } 349 case Instructions::br.value(): 350 case Instructions::br_if.value(): { 351 // branches with a single label immediate 352 auto index = GenericIndexParser<LabelIndex>::parse(stream); 353 if (index.is_error()) 354 return index.error(); 355 356 resulting_instructions.append(Instruction { opcode, index.release_value() }); 357 break; 358 } 359 case Instructions::br_table.value(): { 360 // br_table label* label 361 auto labels = parse_vector<GenericIndexParser<LabelIndex>>(stream); 362 if (labels.is_error()) 363 return labels.error(); 364 365 auto default_label = GenericIndexParser<LabelIndex>::parse(stream); 366 if (default_label.is_error()) 367 return default_label.error(); 368 369 resulting_instructions.append(Instruction { opcode, TableBranchArgs { labels.release_value(), default_label.release_value() } }); 370 break; 371 } 372 case Instructions::call.value(): { 373 // call function 374 auto function_index = GenericIndexParser<FunctionIndex>::parse(stream); 375 if (function_index.is_error()) 376 return function_index.error(); 377 378 resulting_instructions.append(Instruction { opcode, function_index.release_value() }); 379 break; 380 } 381 case Instructions::call_indirect.value(): { 382 // call_indirect type table 383 auto type_index = GenericIndexParser<TypeIndex>::parse(stream); 384 if (type_index.is_error()) 385 return type_index.error(); 386 387 auto table_index = GenericIndexParser<TableIndex>::parse(stream); 388 if (table_index.is_error()) 389 return table_index.error(); 390 391 resulting_instructions.append(Instruction { opcode, IndirectCallArgs { type_index.release_value(), table_index.release_value() } }); 392 break; 393 } 394 case Instructions::i32_load.value(): 395 case Instructions::i64_load.value(): 396 case Instructions::f32_load.value(): 397 case Instructions::f64_load.value(): 398 case Instructions::i32_load8_s.value(): 399 case Instructions::i32_load8_u.value(): 400 case Instructions::i32_load16_s.value(): 401 case Instructions::i32_load16_u.value(): 402 case Instructions::i64_load8_s.value(): 403 case Instructions::i64_load8_u.value(): 404 case Instructions::i64_load16_s.value(): 405 case Instructions::i64_load16_u.value(): 406 case Instructions::i64_load32_s.value(): 407 case Instructions::i64_load32_u.value(): 408 case Instructions::i32_store.value(): 409 case Instructions::i64_store.value(): 410 case Instructions::f32_store.value(): 411 case Instructions::f64_store.value(): 412 case Instructions::i32_store8.value(): 413 case Instructions::i32_store16.value(): 414 case Instructions::i64_store8.value(): 415 case Instructions::i64_store16.value(): 416 case Instructions::i64_store32.value(): { 417 // op (align offset) 418 auto align_or_error = stream.read_value<LEB128<size_t>>(); 419 if (align_or_error.is_error()) 420 return with_eof_check(stream, ParseError::InvalidInput); 421 size_t align = align_or_error.release_value(); 422 423 auto offset_or_error = stream.read_value<LEB128<size_t>>(); 424 if (offset_or_error.is_error()) 425 return with_eof_check(stream, ParseError::InvalidInput); 426 size_t offset = offset_or_error.release_value(); 427 428 resulting_instructions.append(Instruction { opcode, MemoryArgument { static_cast<u32>(align), static_cast<u32>(offset) } }); 429 break; 430 } 431 case Instructions::local_get.value(): 432 case Instructions::local_set.value(): 433 case Instructions::local_tee.value(): { 434 auto index = GenericIndexParser<LocalIndex>::parse(stream); 435 if (index.is_error()) 436 return index.error(); 437 438 resulting_instructions.append(Instruction { opcode, index.release_value() }); 439 break; 440 } 441 case Instructions::global_get.value(): 442 case Instructions::global_set.value(): { 443 auto index = GenericIndexParser<GlobalIndex>::parse(stream); 444 if (index.is_error()) 445 return index.error(); 446 447 resulting_instructions.append(Instruction { opcode, index.release_value() }); 448 break; 449 } 450 case Instructions::memory_size.value(): 451 case Instructions::memory_grow.value(): { 452 // op 0x0 453 // The zero is currently unused. 454 auto unused_or_error = stream.read_value<u8>(); 455 if (unused_or_error.is_error()) 456 return with_eof_check(stream, ParseError::ExpectedKindTag); 457 458 auto unused = unused_or_error.release_value(); 459 if (unused != 0x00) { 460 dbgln("Invalid tag in memory_grow {}", unused); 461 return with_eof_check(stream, ParseError::InvalidTag); 462 } 463 464 resulting_instructions.append(Instruction { opcode }); 465 break; 466 } 467 case Instructions::i32_const.value(): { 468 auto value_or_error = stream.read_value<LEB128<i32>>(); 469 if (value_or_error.is_error()) 470 return with_eof_check(stream, ParseError::ExpectedSignedImmediate); 471 i32 value = value_or_error.release_value(); 472 473 resulting_instructions.append(Instruction { opcode, value }); 474 break; 475 } 476 case Instructions::i64_const.value(): { 477 // op literal 478 auto value_or_error = stream.read_value<LEB128<i64>>(); 479 if (value_or_error.is_error()) 480 return with_eof_check(stream, ParseError::ExpectedSignedImmediate); 481 i64 value = value_or_error.release_value(); 482 483 resulting_instructions.append(Instruction { opcode, value }); 484 break; 485 } 486 case Instructions::f32_const.value(): { 487 // op literal 488 LittleEndian<u32> value; 489 if (stream.read_until_filled(value.bytes()).is_error()) 490 return with_eof_check(stream, ParseError::ExpectedFloatingImmediate); 491 492 auto floating = bit_cast<float>(static_cast<u32>(value)); 493 resulting_instructions.append(Instruction { opcode, floating }); 494 break; 495 } 496 case Instructions::f64_const.value(): { 497 // op literal 498 LittleEndian<u64> value; 499 if (stream.read_until_filled(value.bytes()).is_error()) 500 return with_eof_check(stream, ParseError::ExpectedFloatingImmediate); 501 502 auto floating = bit_cast<double>(static_cast<u64>(value)); 503 resulting_instructions.append(Instruction { opcode, floating }); 504 break; 505 } 506 case Instructions::table_get.value(): 507 case Instructions::table_set.value(): { 508 auto index = GenericIndexParser<TableIndex>::parse(stream); 509 if (index.is_error()) 510 return index.error(); 511 512 resulting_instructions.append(Instruction { opcode, index.release_value() }); 513 break; 514 } 515 case Instructions::select_typed.value(): { 516 auto types = parse_vector<ValueType>(stream); 517 if (types.is_error()) 518 return types.error(); 519 520 resulting_instructions.append(Instruction { opcode, types.release_value() }); 521 break; 522 } 523 case Instructions::ref_null.value(): { 524 auto type = ValueType::parse(stream); 525 if (type.is_error()) 526 return type.error(); 527 if (!type.value().is_reference()) 528 return ParseError::InvalidType; 529 530 resulting_instructions.append(Instruction { opcode, type.release_value() }); 531 break; 532 } 533 case Instructions::ref_func.value(): { 534 auto index = GenericIndexParser<FunctionIndex>::parse(stream); 535 if (index.is_error()) 536 return index.error(); 537 538 resulting_instructions.append(Instruction { opcode, index.release_value() }); 539 break; 540 } 541 case Instructions::ref_is_null.value(): 542 case Instructions::unreachable.value(): 543 case Instructions::nop.value(): 544 case Instructions::return_.value(): 545 case Instructions::drop.value(): 546 case Instructions::select.value(): 547 case Instructions::i32_eqz.value(): 548 case Instructions::i32_eq.value(): 549 case Instructions::i32_ne.value(): 550 case Instructions::i32_lts.value(): 551 case Instructions::i32_ltu.value(): 552 case Instructions::i32_gts.value(): 553 case Instructions::i32_gtu.value(): 554 case Instructions::i32_les.value(): 555 case Instructions::i32_leu.value(): 556 case Instructions::i32_ges.value(): 557 case Instructions::i32_geu.value(): 558 case Instructions::i64_eqz.value(): 559 case Instructions::i64_eq.value(): 560 case Instructions::i64_ne.value(): 561 case Instructions::i64_lts.value(): 562 case Instructions::i64_ltu.value(): 563 case Instructions::i64_gts.value(): 564 case Instructions::i64_gtu.value(): 565 case Instructions::i64_les.value(): 566 case Instructions::i64_leu.value(): 567 case Instructions::i64_ges.value(): 568 case Instructions::i64_geu.value(): 569 case Instructions::f32_eq.value(): 570 case Instructions::f32_ne.value(): 571 case Instructions::f32_lt.value(): 572 case Instructions::f32_gt.value(): 573 case Instructions::f32_le.value(): 574 case Instructions::f32_ge.value(): 575 case Instructions::f64_eq.value(): 576 case Instructions::f64_ne.value(): 577 case Instructions::f64_lt.value(): 578 case Instructions::f64_gt.value(): 579 case Instructions::f64_le.value(): 580 case Instructions::f64_ge.value(): 581 case Instructions::i32_clz.value(): 582 case Instructions::i32_ctz.value(): 583 case Instructions::i32_popcnt.value(): 584 case Instructions::i32_add.value(): 585 case Instructions::i32_sub.value(): 586 case Instructions::i32_mul.value(): 587 case Instructions::i32_divs.value(): 588 case Instructions::i32_divu.value(): 589 case Instructions::i32_rems.value(): 590 case Instructions::i32_remu.value(): 591 case Instructions::i32_and.value(): 592 case Instructions::i32_or.value(): 593 case Instructions::i32_xor.value(): 594 case Instructions::i32_shl.value(): 595 case Instructions::i32_shrs.value(): 596 case Instructions::i32_shru.value(): 597 case Instructions::i32_rotl.value(): 598 case Instructions::i32_rotr.value(): 599 case Instructions::i64_clz.value(): 600 case Instructions::i64_ctz.value(): 601 case Instructions::i64_popcnt.value(): 602 case Instructions::i64_add.value(): 603 case Instructions::i64_sub.value(): 604 case Instructions::i64_mul.value(): 605 case Instructions::i64_divs.value(): 606 case Instructions::i64_divu.value(): 607 case Instructions::i64_rems.value(): 608 case Instructions::i64_remu.value(): 609 case Instructions::i64_and.value(): 610 case Instructions::i64_or.value(): 611 case Instructions::i64_xor.value(): 612 case Instructions::i64_shl.value(): 613 case Instructions::i64_shrs.value(): 614 case Instructions::i64_shru.value(): 615 case Instructions::i64_rotl.value(): 616 case Instructions::i64_rotr.value(): 617 case Instructions::f32_abs.value(): 618 case Instructions::f32_neg.value(): 619 case Instructions::f32_ceil.value(): 620 case Instructions::f32_floor.value(): 621 case Instructions::f32_trunc.value(): 622 case Instructions::f32_nearest.value(): 623 case Instructions::f32_sqrt.value(): 624 case Instructions::f32_add.value(): 625 case Instructions::f32_sub.value(): 626 case Instructions::f32_mul.value(): 627 case Instructions::f32_div.value(): 628 case Instructions::f32_min.value(): 629 case Instructions::f32_max.value(): 630 case Instructions::f32_copysign.value(): 631 case Instructions::f64_abs.value(): 632 case Instructions::f64_neg.value(): 633 case Instructions::f64_ceil.value(): 634 case Instructions::f64_floor.value(): 635 case Instructions::f64_trunc.value(): 636 case Instructions::f64_nearest.value(): 637 case Instructions::f64_sqrt.value(): 638 case Instructions::f64_add.value(): 639 case Instructions::f64_sub.value(): 640 case Instructions::f64_mul.value(): 641 case Instructions::f64_div.value(): 642 case Instructions::f64_min.value(): 643 case Instructions::f64_max.value(): 644 case Instructions::f64_copysign.value(): 645 case Instructions::i32_wrap_i64.value(): 646 case Instructions::i32_trunc_sf32.value(): 647 case Instructions::i32_trunc_uf32.value(): 648 case Instructions::i32_trunc_sf64.value(): 649 case Instructions::i32_trunc_uf64.value(): 650 case Instructions::i64_extend_si32.value(): 651 case Instructions::i64_extend_ui32.value(): 652 case Instructions::i64_trunc_sf32.value(): 653 case Instructions::i64_trunc_uf32.value(): 654 case Instructions::i64_trunc_sf64.value(): 655 case Instructions::i64_trunc_uf64.value(): 656 case Instructions::f32_convert_si32.value(): 657 case Instructions::f32_convert_ui32.value(): 658 case Instructions::f32_convert_si64.value(): 659 case Instructions::f32_convert_ui64.value(): 660 case Instructions::f32_demote_f64.value(): 661 case Instructions::f64_convert_si32.value(): 662 case Instructions::f64_convert_ui32.value(): 663 case Instructions::f64_convert_si64.value(): 664 case Instructions::f64_convert_ui64.value(): 665 case Instructions::f64_promote_f32.value(): 666 case Instructions::i32_reinterpret_f32.value(): 667 case Instructions::i64_reinterpret_f64.value(): 668 case Instructions::f32_reinterpret_i32.value(): 669 case Instructions::f64_reinterpret_i64.value(): 670 case Instructions::i32_extend8_s.value(): 671 case Instructions::i32_extend16_s.value(): 672 case Instructions::i64_extend8_s.value(): 673 case Instructions::i64_extend16_s.value(): 674 case Instructions::i64_extend32_s.value(): 675 resulting_instructions.append(Instruction { opcode }); 676 break; 677 case 0xfc: { 678 // These are multibyte instructions. 679 auto selector_or_error = stream.read_value<LEB128<u32>>(); 680 if (selector_or_error.is_error()) 681 return with_eof_check(stream, ParseError::InvalidInput); 682 u32 selector = selector_or_error.release_value(); 683 switch (selector) { 684 case Instructions::i32_trunc_sat_f32_s_second: 685 case Instructions::i32_trunc_sat_f32_u_second: 686 case Instructions::i32_trunc_sat_f64_s_second: 687 case Instructions::i32_trunc_sat_f64_u_second: 688 case Instructions::i64_trunc_sat_f32_s_second: 689 case Instructions::i64_trunc_sat_f32_u_second: 690 case Instructions::i64_trunc_sat_f64_s_second: 691 case Instructions::i64_trunc_sat_f64_u_second: 692 resulting_instructions.append(Instruction { OpCode { 0xfc00 | selector } }); 693 break; 694 case Instructions::memory_init_second: { 695 auto index = GenericIndexParser<DataIndex>::parse(stream); 696 if (index.is_error()) 697 return index.error(); 698 auto unused_or_error = stream.read_value<u8>(); 699 if (unused_or_error.is_error()) 700 return with_eof_check(stream, ParseError::InvalidInput); 701 702 auto unused = unused_or_error.release_value(); 703 if (unused != 0x00) 704 return ParseError::InvalidImmediate; 705 resulting_instructions.append(Instruction { OpCode { 0xfc00 | selector }, index.release_value() }); 706 break; 707 } 708 case Instructions::data_drop_second: { 709 auto index = GenericIndexParser<DataIndex>::parse(stream); 710 if (index.is_error()) 711 return index.error(); 712 resulting_instructions.append(Instruction { OpCode { 0xfc00 | selector }, index.release_value() }); 713 break; 714 } 715 case Instructions::memory_copy_second: { 716 for (size_t i = 0; i < 2; ++i) { 717 auto unused_or_error = stream.read_value<u8>(); 718 if (unused_or_error.is_error()) 719 return with_eof_check(stream, ParseError::InvalidInput); 720 721 auto unused = unused_or_error.release_value(); 722 if (unused != 0x00) 723 return ParseError::InvalidImmediate; 724 } 725 resulting_instructions.append(Instruction { OpCode { 0xfc00 | selector } }); 726 break; 727 } 728 case Instructions::memory_fill_second: { 729 auto unused_or_error = stream.read_value<u8>(); 730 if (unused_or_error.is_error()) 731 return with_eof_check(stream, ParseError::InvalidInput); 732 733 auto unused = unused_or_error.release_value(); 734 if (unused != 0x00) 735 return ParseError::InvalidImmediate; 736 resulting_instructions.append(Instruction { OpCode { 0xfc00 | selector } }); 737 break; 738 } 739 case Instructions::table_init_second: { 740 auto element_index = GenericIndexParser<ElementIndex>::parse(stream); 741 if (element_index.is_error()) 742 return element_index.error(); 743 auto table_index = GenericIndexParser<TableIndex>::parse(stream); 744 if (table_index.is_error()) 745 return table_index.error(); 746 resulting_instructions.append(Instruction { OpCode { 0xfc00 | selector }, TableElementArgs { element_index.release_value(), table_index.release_value() } }); 747 break; 748 } 749 case Instructions::elem_drop_second: { 750 auto element_index = GenericIndexParser<ElementIndex>::parse(stream); 751 if (element_index.is_error()) 752 return element_index.error(); 753 resulting_instructions.append(Instruction { OpCode { 0xfc00 | selector }, element_index.release_value() }); 754 break; 755 } 756 case Instructions::table_copy_second: { 757 auto lhs = GenericIndexParser<TableIndex>::parse(stream); 758 if (lhs.is_error()) 759 return lhs.error(); 760 auto rhs = GenericIndexParser<TableIndex>::parse(stream); 761 if (rhs.is_error()) 762 return rhs.error(); 763 resulting_instructions.append(Instruction { OpCode { 0xfc00 | selector }, TableTableArgs { lhs.release_value(), rhs.release_value() } }); 764 break; 765 } 766 case Instructions::table_grow_second: 767 case Instructions::table_size_second: 768 case Instructions::table_fill_second: { 769 auto index = GenericIndexParser<TableIndex>::parse(stream); 770 if (index.is_error()) 771 return index.error(); 772 resulting_instructions.append(Instruction { OpCode { 0xfc00 | selector }, index.release_value() }); 773 break; 774 } 775 default: 776 return ParseError::UnknownInstruction; 777 } 778 } 779 } 780 } while (!nested_instructions.is_empty()); 781 782 return resulting_instructions; 783} 784 785ParseResult<CustomSection> CustomSection::parse(Stream& stream) 786{ 787 ScopeLogger<WASM_BINPARSER_DEBUG> logger("CustomSection"sv); 788 auto name = parse_name(stream); 789 if (name.is_error()) 790 return name.error(); 791 792 ByteBuffer data_buffer; 793 if (data_buffer.try_resize(64).is_error()) 794 return ParseError::OutOfMemory; 795 796 while (!stream.is_eof()) { 797 char buf[16]; 798 auto span_or_error = stream.read_some({ buf, 16 }); 799 if (span_or_error.is_error()) 800 break; 801 auto size = span_or_error.release_value().size(); 802 if (size == 0) 803 break; 804 if (data_buffer.try_append(buf, size).is_error()) 805 return with_eof_check(stream, ParseError::HugeAllocationRequested); 806 } 807 808 return CustomSection(name.release_value(), move(data_buffer)); 809} 810 811ParseResult<TypeSection> TypeSection::parse(Stream& stream) 812{ 813 ScopeLogger<WASM_BINPARSER_DEBUG> logger("TypeSection"sv); 814 auto types = parse_vector<FunctionType>(stream); 815 if (types.is_error()) 816 return types.error(); 817 return TypeSection { types.release_value() }; 818} 819 820ParseResult<ImportSection::Import> ImportSection::Import::parse(Stream& stream) 821{ 822 ScopeLogger<WASM_BINPARSER_DEBUG> logger("Import"sv); 823 auto module = parse_name(stream); 824 if (module.is_error()) 825 return module.error(); 826 auto name = parse_name(stream); 827 if (name.is_error()) 828 return name.error(); 829 auto tag_or_error = stream.read_value<u8>(); 830 if (tag_or_error.is_error()) 831 return with_eof_check(stream, ParseError::ExpectedKindTag); 832 833 auto tag = tag_or_error.release_value(); 834 835 switch (tag) { 836 case Constants::extern_function_tag: { 837 auto index = GenericIndexParser<TypeIndex>::parse(stream); 838 if (index.is_error()) 839 return index.error(); 840 return Import { module.release_value(), name.release_value(), index.release_value() }; 841 } 842 case Constants::extern_table_tag: 843 return parse_with_type<TableType>(stream, module, name); 844 case Constants::extern_memory_tag: 845 return parse_with_type<MemoryType>(stream, module, name); 846 case Constants::extern_global_tag: 847 return parse_with_type<GlobalType>(stream, module, name); 848 default: 849 return with_eof_check(stream, ParseError::InvalidTag); 850 } 851} 852 853ParseResult<ImportSection> ImportSection::parse(Stream& stream) 854{ 855 ScopeLogger<WASM_BINPARSER_DEBUG> logger("ImportSection"sv); 856 auto imports = parse_vector<Import>(stream); 857 if (imports.is_error()) 858 return imports.error(); 859 return ImportSection { imports.release_value() }; 860} 861 862ParseResult<FunctionSection> FunctionSection::parse(Stream& stream) 863{ 864 ScopeLogger<WASM_BINPARSER_DEBUG> logger("FunctionSection"sv); 865 auto indices = parse_vector<size_t>(stream); 866 if (indices.is_error()) 867 return indices.error(); 868 869 Vector<TypeIndex> typed_indices; 870 typed_indices.ensure_capacity(indices.value().size()); 871 for (auto entry : indices.value()) 872 typed_indices.append(entry); 873 874 return FunctionSection { move(typed_indices) }; 875} 876 877ParseResult<TableSection::Table> TableSection::Table::parse(Stream& stream) 878{ 879 ScopeLogger<WASM_BINPARSER_DEBUG> logger("Table"sv); 880 auto type = TableType::parse(stream); 881 if (type.is_error()) 882 return type.error(); 883 return Table { type.release_value() }; 884} 885 886ParseResult<TableSection> TableSection::parse(Stream& stream) 887{ 888 ScopeLogger<WASM_BINPARSER_DEBUG> logger("TableSection"sv); 889 auto tables = parse_vector<Table>(stream); 890 if (tables.is_error()) 891 return tables.error(); 892 return TableSection { tables.release_value() }; 893} 894 895ParseResult<MemorySection::Memory> MemorySection::Memory::parse(Stream& stream) 896{ 897 ScopeLogger<WASM_BINPARSER_DEBUG> logger("Memory"sv); 898 auto type = MemoryType::parse(stream); 899 if (type.is_error()) 900 return type.error(); 901 return Memory { type.release_value() }; 902} 903 904ParseResult<MemorySection> MemorySection::parse(Stream& stream) 905{ 906 ScopeLogger<WASM_BINPARSER_DEBUG> logger("MemorySection"sv); 907 auto memories = parse_vector<Memory>(stream); 908 if (memories.is_error()) 909 return memories.error(); 910 return MemorySection { memories.release_value() }; 911} 912 913ParseResult<Expression> Expression::parse(Stream& stream) 914{ 915 ScopeLogger<WASM_BINPARSER_DEBUG> logger("Expression"sv); 916 InstructionPointer ip { 0 }; 917 auto instructions = parse_until_any_of<Instruction, 0x0b>(stream, ip); 918 if (instructions.is_error()) 919 return instructions.error(); 920 921 return Expression { move(instructions.value().values) }; 922} 923 924ParseResult<GlobalSection::Global> GlobalSection::Global::parse(Stream& stream) 925{ 926 ScopeLogger<WASM_BINPARSER_DEBUG> logger("Global"sv); 927 auto type = GlobalType::parse(stream); 928 if (type.is_error()) 929 return type.error(); 930 auto exprs = Expression::parse(stream); 931 if (exprs.is_error()) 932 return exprs.error(); 933 return Global { type.release_value(), exprs.release_value() }; 934} 935 936ParseResult<GlobalSection> GlobalSection::parse(Stream& stream) 937{ 938 ScopeLogger<WASM_BINPARSER_DEBUG> logger("GlobalSection"sv); 939 auto result = parse_vector<Global>(stream); 940 if (result.is_error()) 941 return result.error(); 942 return GlobalSection { result.release_value() }; 943} 944 945ParseResult<ExportSection::Export> ExportSection::Export::parse(Stream& stream) 946{ 947 ScopeLogger<WASM_BINPARSER_DEBUG> logger("Export"sv); 948 auto name = parse_name(stream); 949 if (name.is_error()) 950 return name.error(); 951 auto tag_or_error = stream.read_value<u8>(); 952 if (tag_or_error.is_error()) 953 return with_eof_check(stream, ParseError::ExpectedKindTag); 954 955 auto tag = tag_or_error.release_value(); 956 957 auto index_or_error = stream.read_value<LEB128<size_t>>(); 958 if (index_or_error.is_error()) 959 return with_eof_check(stream, ParseError::ExpectedIndex); 960 size_t index = index_or_error.release_value(); 961 962 switch (tag) { 963 case Constants::extern_function_tag: 964 return Export { name.release_value(), ExportDesc { FunctionIndex { index } } }; 965 case Constants::extern_table_tag: 966 return Export { name.release_value(), ExportDesc { TableIndex { index } } }; 967 case Constants::extern_memory_tag: 968 return Export { name.release_value(), ExportDesc { MemoryIndex { index } } }; 969 case Constants::extern_global_tag: 970 return Export { name.release_value(), ExportDesc { GlobalIndex { index } } }; 971 default: 972 return with_eof_check(stream, ParseError::InvalidTag); 973 } 974} 975 976ParseResult<ExportSection> ExportSection::parse(Stream& stream) 977{ 978 ScopeLogger<WASM_BINPARSER_DEBUG> logger("ExportSection"sv); 979 auto result = parse_vector<Export>(stream); 980 if (result.is_error()) 981 return result.error(); 982 return ExportSection { result.release_value() }; 983} 984 985ParseResult<StartSection::StartFunction> StartSection::StartFunction::parse(Stream& stream) 986{ 987 ScopeLogger<WASM_BINPARSER_DEBUG> logger("StartFunction"sv); 988 auto index = GenericIndexParser<FunctionIndex>::parse(stream); 989 if (index.is_error()) 990 return index.error(); 991 return StartFunction { index.release_value() }; 992} 993 994ParseResult<StartSection> StartSection::parse(Stream& stream) 995{ 996 ScopeLogger<WASM_BINPARSER_DEBUG> logger("StartSection"sv); 997 auto result = StartFunction::parse(stream); 998 if (result.is_error()) 999 return result.error(); 1000 return StartSection { result.release_value() }; 1001} 1002 1003ParseResult<ElementSection::SegmentType0> ElementSection::SegmentType0::parse(Stream& stream) 1004{ 1005 auto expression = Expression::parse(stream); 1006 if (expression.is_error()) 1007 return expression.error(); 1008 auto indices = parse_vector<GenericIndexParser<FunctionIndex>>(stream); 1009 if (indices.is_error()) 1010 return indices.error(); 1011 1012 return SegmentType0 { indices.release_value(), Active { 0, expression.release_value() } }; 1013} 1014 1015ParseResult<ElementSection::SegmentType1> ElementSection::SegmentType1::parse(Stream& stream) 1016{ 1017 auto kind_or_error = stream.read_value<u8>(); 1018 if (kind_or_error.is_error()) 1019 return with_eof_check(stream, ParseError::ExpectedKindTag); 1020 1021 auto kind = kind_or_error.release_value(); 1022 if (kind != 0) 1023 return ParseError::InvalidTag; 1024 auto indices = parse_vector<GenericIndexParser<FunctionIndex>>(stream); 1025 if (indices.is_error()) 1026 return indices.error(); 1027 1028 return SegmentType1 { indices.release_value() }; 1029} 1030 1031ParseResult<ElementSection::SegmentType2> ElementSection::SegmentType2::parse(Stream& stream) 1032{ 1033 dbgln("Type 2"); 1034 (void)stream; 1035 return ParseError::NotImplemented; 1036} 1037 1038ParseResult<ElementSection::SegmentType3> ElementSection::SegmentType3::parse(Stream& stream) 1039{ 1040 dbgln("Type 3"); 1041 (void)stream; 1042 return ParseError::NotImplemented; 1043} 1044 1045ParseResult<ElementSection::SegmentType4> ElementSection::SegmentType4::parse(Stream& stream) 1046{ 1047 dbgln("Type 4"); 1048 (void)stream; 1049 return ParseError::NotImplemented; 1050} 1051 1052ParseResult<ElementSection::SegmentType5> ElementSection::SegmentType5::parse(Stream& stream) 1053{ 1054 dbgln("Type 5"); 1055 (void)stream; 1056 return ParseError::NotImplemented; 1057} 1058 1059ParseResult<ElementSection::SegmentType6> ElementSection::SegmentType6::parse(Stream& stream) 1060{ 1061 dbgln("Type 6"); 1062 (void)stream; 1063 return ParseError::NotImplemented; 1064} 1065 1066ParseResult<ElementSection::SegmentType7> ElementSection::SegmentType7::parse(Stream& stream) 1067{ 1068 dbgln("Type 7"); 1069 (void)stream; 1070 return ParseError::NotImplemented; 1071} 1072 1073ParseResult<ElementSection::Element> ElementSection::Element::parse(Stream& stream) 1074{ 1075 ScopeLogger<WASM_BINPARSER_DEBUG> logger("Element"sv); 1076 auto tag_or_error = stream.read_value<u8>(); 1077 if (tag_or_error.is_error()) 1078 return with_eof_check(stream, ParseError::ExpectedKindTag); 1079 1080 auto tag = tag_or_error.release_value(); 1081 1082 switch (tag) { 1083 case 0x00: 1084 if (auto result = SegmentType0::parse(stream); result.is_error()) { 1085 return result.error(); 1086 } else { 1087 Vector<Instruction> instructions; 1088 for (auto& index : result.value().function_indices) 1089 instructions.empend(Instructions::ref_func, index); 1090 return Element { ValueType(ValueType::FunctionReference), { Expression { move(instructions) } }, move(result.value().mode) }; 1091 } 1092 case 0x01: 1093 if (auto result = SegmentType1::parse(stream); result.is_error()) { 1094 return result.error(); 1095 } else { 1096 Vector<Instruction> instructions; 1097 for (auto& index : result.value().function_indices) 1098 instructions.empend(Instructions::ref_func, index); 1099 return Element { ValueType(ValueType::FunctionReference), { Expression { move(instructions) } }, Passive {} }; 1100 } 1101 case 0x02: 1102 if (auto result = SegmentType2::parse(stream); result.is_error()) { 1103 return result.error(); 1104 } else { 1105 return ParseError::NotImplemented; 1106 } 1107 case 0x03: 1108 if (auto result = SegmentType3::parse(stream); result.is_error()) { 1109 return result.error(); 1110 } else { 1111 return ParseError::NotImplemented; 1112 } 1113 case 0x04: 1114 if (auto result = SegmentType4::parse(stream); result.is_error()) { 1115 return result.error(); 1116 } else { 1117 return ParseError::NotImplemented; 1118 } 1119 case 0x05: 1120 if (auto result = SegmentType5::parse(stream); result.is_error()) { 1121 return result.error(); 1122 } else { 1123 return ParseError::NotImplemented; 1124 } 1125 case 0x06: 1126 if (auto result = SegmentType6::parse(stream); result.is_error()) { 1127 return result.error(); 1128 } else { 1129 return ParseError::NotImplemented; 1130 } 1131 case 0x07: 1132 if (auto result = SegmentType7::parse(stream); result.is_error()) { 1133 return result.error(); 1134 } else { 1135 return ParseError::NotImplemented; 1136 } 1137 default: 1138 return ParseError::InvalidTag; 1139 } 1140} 1141 1142ParseResult<ElementSection> ElementSection::parse(Stream& stream) 1143{ 1144 ScopeLogger<WASM_BINPARSER_DEBUG> logger("ElementSection"sv); 1145 auto result = parse_vector<Element>(stream); 1146 if (result.is_error()) 1147 return result.error(); 1148 return ElementSection { result.release_value() }; 1149} 1150 1151ParseResult<Locals> Locals::parse(Stream& stream) 1152{ 1153 ScopeLogger<WASM_BINPARSER_DEBUG> logger("Locals"sv); 1154 auto count_or_error = stream.read_value<LEB128<size_t>>(); 1155 if (count_or_error.is_error()) 1156 return with_eof_check(stream, ParseError::InvalidSize); 1157 size_t count = count_or_error.release_value(); 1158 1159 if (count > Constants::max_allowed_function_locals_per_type) 1160 return with_eof_check(stream, ParseError::HugeAllocationRequested); 1161 1162 auto type = ValueType::parse(stream); 1163 if (type.is_error()) 1164 return type.error(); 1165 1166 return Locals { static_cast<u32>(count), type.release_value() }; 1167} 1168 1169ParseResult<CodeSection::Func> CodeSection::Func::parse(Stream& stream) 1170{ 1171 ScopeLogger<WASM_BINPARSER_DEBUG> logger("Func"sv); 1172 auto locals = parse_vector<Locals>(stream); 1173 if (locals.is_error()) 1174 return locals.error(); 1175 auto body = Expression::parse(stream); 1176 if (body.is_error()) 1177 return body.error(); 1178 return Func { locals.release_value(), body.release_value() }; 1179} 1180 1181ParseResult<CodeSection::Code> CodeSection::Code::parse(Stream& stream) 1182{ 1183 ScopeLogger<WASM_BINPARSER_DEBUG> logger("Code"sv); 1184 auto size_or_error = stream.read_value<LEB128<size_t>>(); 1185 if (size_or_error.is_error()) 1186 return with_eof_check(stream, ParseError::InvalidSize); 1187 size_t size = size_or_error.release_value(); 1188 1189 auto constrained_stream = ConstrainedStream { stream, size }; 1190 1191 auto func = Func::parse(constrained_stream); 1192 if (func.is_error()) 1193 return func.error(); 1194 1195 return Code { static_cast<u32>(size), func.release_value() }; 1196} 1197 1198ParseResult<CodeSection> CodeSection::parse(Stream& stream) 1199{ 1200 ScopeLogger<WASM_BINPARSER_DEBUG> logger("CodeSection"sv); 1201 auto result = parse_vector<Code>(stream); 1202 if (result.is_error()) 1203 return result.error(); 1204 return CodeSection { result.release_value() }; 1205} 1206 1207ParseResult<DataSection::Data> DataSection::Data::parse(Stream& stream) 1208{ 1209 ScopeLogger<WASM_BINPARSER_DEBUG> logger("Data"sv); 1210 auto tag_or_error = stream.read_value<u8>(); 1211 if (tag_or_error.is_error()) 1212 return with_eof_check(stream, ParseError::ExpectedKindTag); 1213 1214 auto tag = tag_or_error.release_value(); 1215 1216 if (tag > 0x02) 1217 return with_eof_check(stream, ParseError::InvalidTag); 1218 1219 if (tag == 0x00) { 1220 auto expr = Expression::parse(stream); 1221 if (expr.is_error()) 1222 return expr.error(); 1223 auto init = parse_vector<u8>(stream); 1224 if (init.is_error()) 1225 return init.error(); 1226 return Data { Active { init.release_value(), { 0 }, expr.release_value() } }; 1227 } 1228 if (tag == 0x01) { 1229 auto init = parse_vector<u8>(stream); 1230 if (init.is_error()) 1231 return init.error(); 1232 return Data { Passive { init.release_value() } }; 1233 } 1234 if (tag == 0x02) { 1235 auto index = GenericIndexParser<MemoryIndex>::parse(stream); 1236 if (index.is_error()) 1237 return index.error(); 1238 auto expr = Expression::parse(stream); 1239 if (expr.is_error()) 1240 return expr.error(); 1241 auto init = parse_vector<u8>(stream); 1242 if (init.is_error()) 1243 return init.error(); 1244 return Data { Active { init.release_value(), index.release_value(), expr.release_value() } }; 1245 } 1246 VERIFY_NOT_REACHED(); 1247} 1248 1249ParseResult<DataSection> DataSection::parse(Stream& stream) 1250{ 1251 ScopeLogger<WASM_BINPARSER_DEBUG> logger("DataSection"sv); 1252 auto data = parse_vector<Data>(stream); 1253 if (data.is_error()) 1254 return data.error(); 1255 1256 return DataSection { data.release_value() }; 1257} 1258 1259ParseResult<DataCountSection> DataCountSection::parse([[maybe_unused]] Stream& stream) 1260{ 1261 ScopeLogger<WASM_BINPARSER_DEBUG> logger("DataCountSection"sv); 1262 auto value_or_error = stream.read_value<LEB128<u32>>(); 1263 if (value_or_error.is_error()) { 1264 if (stream.is_eof()) { 1265 // The section simply didn't contain anything. 1266 return DataCountSection { {} }; 1267 } 1268 return ParseError::ExpectedSize; 1269 } 1270 u32 value = value_or_error.release_value(); 1271 1272 return DataCountSection { value }; 1273} 1274 1275ParseResult<Module> Module::parse(Stream& stream) 1276{ 1277 ScopeLogger<WASM_BINPARSER_DEBUG> logger("Module"sv); 1278 u8 buf[4]; 1279 if (stream.read_until_filled({ buf, 4 }).is_error()) 1280 return with_eof_check(stream, ParseError::InvalidInput); 1281 if (Bytes { buf, 4 } != wasm_magic.span()) 1282 return with_eof_check(stream, ParseError::InvalidModuleMagic); 1283 1284 if (stream.read_until_filled({ buf, 4 }).is_error()) 1285 return with_eof_check(stream, ParseError::InvalidInput); 1286 if (Bytes { buf, 4 } != wasm_version.span()) 1287 return with_eof_check(stream, ParseError::InvalidModuleVersion); 1288 1289 Vector<AnySection> sections; 1290 for (;;) { 1291 auto section_id_or_error = stream.read_value<u8>(); 1292 if (stream.is_eof()) 1293 break; 1294 if (section_id_or_error.is_error()) 1295 return with_eof_check(stream, ParseError::ExpectedIndex); 1296 1297 auto section_id = section_id_or_error.release_value(); 1298 1299 auto section_size_or_error = stream.read_value<LEB128<size_t>>(); 1300 if (section_size_or_error.is_error()) 1301 return with_eof_check(stream, ParseError::ExpectedSize); 1302 size_t section_size = section_size_or_error.release_value(); 1303 1304 auto section_stream = ConstrainedStream { stream, section_size }; 1305 1306 switch (section_id) { 1307 case CustomSection::section_id: 1308 sections.append(TRY(CustomSection::parse(section_stream))); 1309 continue; 1310 case TypeSection::section_id: 1311 sections.append(TRY(TypeSection::parse(section_stream))); 1312 continue; 1313 case ImportSection::section_id: 1314 sections.append(TRY(ImportSection::parse(section_stream))); 1315 continue; 1316 case FunctionSection::section_id: 1317 sections.append(TRY(FunctionSection::parse(section_stream))); 1318 continue; 1319 case TableSection::section_id: 1320 sections.append(TRY(TableSection::parse(section_stream))); 1321 continue; 1322 case MemorySection::section_id: 1323 sections.append(TRY(MemorySection::parse(section_stream))); 1324 continue; 1325 case GlobalSection::section_id: 1326 sections.append(TRY(GlobalSection::parse(section_stream))); 1327 continue; 1328 case ExportSection::section_id: 1329 sections.append(TRY(ExportSection::parse(section_stream))); 1330 continue; 1331 case StartSection::section_id: 1332 sections.append(TRY(StartSection::parse(section_stream))); 1333 continue; 1334 case ElementSection::section_id: 1335 sections.append(TRY(ElementSection::parse(section_stream))); 1336 continue; 1337 case CodeSection::section_id: 1338 sections.append(TRY(CodeSection::parse(section_stream))); 1339 continue; 1340 case DataSection::section_id: 1341 sections.append(TRY(DataSection::parse(section_stream))); 1342 continue; 1343 case DataCountSection::section_id: 1344 sections.append(TRY(DataCountSection::parse(section_stream))); 1345 continue; 1346 default: 1347 return with_eof_check(stream, ParseError::InvalidIndex); 1348 } 1349 } 1350 1351 return Module { move(sections) }; 1352} 1353 1354bool Module::populate_sections() 1355{ 1356 auto is_ok = true; 1357 FunctionSection const* function_section { nullptr }; 1358 for_each_section_of_type<FunctionSection>([&](FunctionSection const& section) { function_section = &section; }); 1359 for_each_section_of_type<CodeSection>([&](CodeSection const& section) { 1360 if (!function_section) { 1361 is_ok = false; 1362 return; 1363 } 1364 size_t index = 0; 1365 for (auto& entry : section.functions()) { 1366 if (function_section->types().size() <= index) { 1367 is_ok = false; 1368 return; 1369 } 1370 auto& type_index = function_section->types()[index]; 1371 Vector<ValueType> locals; 1372 for (auto& local : entry.func().locals()) { 1373 for (size_t i = 0; i < local.n(); ++i) 1374 locals.append(local.type()); 1375 } 1376 m_functions.empend(type_index, move(locals), entry.func().body()); 1377 ++index; 1378 } 1379 }); 1380 return is_ok; 1381} 1382 1383DeprecatedString parse_error_to_deprecated_string(ParseError error) 1384{ 1385 switch (error) { 1386 case ParseError::UnexpectedEof: 1387 return "Unexpected end-of-file"; 1388 case ParseError::ExpectedIndex: 1389 return "Expected a valid index value"; 1390 case ParseError::ExpectedKindTag: 1391 return "Expected a valid kind tag"; 1392 case ParseError::ExpectedSize: 1393 return "Expected a valid LEB128-encoded size"; 1394 case ParseError::ExpectedValueOrTerminator: 1395 return "Expected either a terminator or a value"; 1396 case ParseError::InvalidIndex: 1397 return "An index parsed was semantically invalid"; 1398 case ParseError::InvalidInput: 1399 return "Input data contained invalid bytes"; 1400 case ParseError::InvalidModuleMagic: 1401 return "Incorrect module magic (did not match \\0asm)"; 1402 case ParseError::InvalidModuleVersion: 1403 return "Incorrect module version"; 1404 case ParseError::InvalidSize: 1405 return "A parsed size did not make sense in context"; 1406 case ParseError::InvalidTag: 1407 return "A parsed tag did not make sense in context"; 1408 case ParseError::InvalidType: 1409 return "A parsed type did not make sense in context"; 1410 case ParseError::NotImplemented: 1411 return "The parser encountered an unimplemented feature"; 1412 case ParseError::HugeAllocationRequested: 1413 return "Parsing caused an attempt to allocate a very big chunk of memory, likely malformed data"; 1414 case ParseError::OutOfMemory: 1415 return "The parser hit an OOM condition"; 1416 case ParseError::ExpectedFloatingImmediate: 1417 return "Expected a floating point immediate"; 1418 case ParseError::ExpectedSignedImmediate: 1419 return "Expected a signed integer immediate"; 1420 case ParseError::InvalidImmediate: 1421 return "A parsed instruction immediate was invalid for the instruction it was used for"; 1422 case ParseError::UnknownInstruction: 1423 return "A parsed instruction was not known to this parser"; 1424 } 1425 return "Unknown error"; 1426} 1427}