Types.h 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054
  1. /*
  2. * Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Badge.h>
  8. #include <AK/ByteString.h>
  9. #include <AK/DistinctNumeric.h>
  10. #include <AK/LEB128.h>
  11. #include <AK/Result.h>
  12. #include <AK/String.h>
  13. #include <AK/UFixedBigInt.h>
  14. #include <AK/Variant.h>
  15. #include <AK/WeakPtr.h>
  16. #include <LibWasm/Constants.h>
  17. #include <LibWasm/Forward.h>
  18. #include <LibWasm/Opcode.h>
  19. namespace Wasm {
  20. template<size_t M>
  21. using NativeIntegralType = Conditional<M == 8, u8, Conditional<M == 16, u16, Conditional<M == 32, u32, Conditional<M == 64, u64, void>>>>;
  22. template<size_t M>
  23. using NativeFloatingType = Conditional<M == 32, f32, Conditional<M == 64, f64, void>>;
  24. template<size_t M, size_t N, template<typename> typename SetSign, typename ElementType = SetSign<NativeIntegralType<M>>>
  25. using NativeVectorType __attribute__((vector_size(N * sizeof(ElementType)))) = ElementType;
  26. template<size_t M, size_t N, typename ElementType = NativeFloatingType<M>>
  27. using NativeFloatingVectorType __attribute__((vector_size(N * sizeof(ElementType)))) = ElementType;
  28. template<typename T, template<typename> typename SetSign>
  29. using Native128ByteVectorOf = NativeVectorType<sizeof(T) * 8, 16 / sizeof(T), SetSign, T>;
  30. enum class ParseError {
  31. UnexpectedEof,
  32. UnknownInstruction,
  33. ExpectedFloatingImmediate,
  34. ExpectedIndex,
  35. ExpectedKindTag,
  36. ExpectedSignedImmediate,
  37. ExpectedSize,
  38. ExpectedValueOrTerminator,
  39. InvalidImmediate,
  40. InvalidIndex,
  41. InvalidInput,
  42. InvalidModuleMagic,
  43. InvalidModuleVersion,
  44. InvalidSize,
  45. InvalidTag,
  46. InvalidType,
  47. HugeAllocationRequested,
  48. OutOfMemory,
  49. SectionSizeMismatch,
  50. InvalidUtf8,
  51. DuplicateSection,
  52. SectionOutOfOrder,
  53. };
  54. ByteString parse_error_to_byte_string(ParseError);
  55. template<typename T>
  56. using ParseResult = ErrorOr<T, ParseError>;
  57. AK_TYPEDEF_DISTINCT_ORDERED_ID(size_t, TypeIndex);
  58. AK_TYPEDEF_DISTINCT_ORDERED_ID(size_t, FunctionIndex);
  59. AK_TYPEDEF_DISTINCT_ORDERED_ID(size_t, TableIndex);
  60. AK_TYPEDEF_DISTINCT_ORDERED_ID(size_t, ElementIndex);
  61. AK_TYPEDEF_DISTINCT_ORDERED_ID(size_t, MemoryIndex);
  62. AK_TYPEDEF_DISTINCT_ORDERED_ID(size_t, LocalIndex);
  63. AK_TYPEDEF_DISTINCT_ORDERED_ID(size_t, GlobalIndex);
  64. AK_TYPEDEF_DISTINCT_ORDERED_ID(size_t, LabelIndex);
  65. AK_TYPEDEF_DISTINCT_ORDERED_ID(size_t, DataIndex);
  66. AK_TYPEDEF_DISTINCT_NUMERIC_GENERAL(u64, InstructionPointer, Arithmetic, Comparison, Flags, Increment);
  67. ParseError with_eof_check(Stream const& stream, ParseError error_if_not_eof);
  68. template<typename T>
  69. struct GenericIndexParser {
  70. static ParseResult<T> parse(Stream& stream)
  71. {
  72. auto value_or_error = stream.read_value<LEB128<u32>>();
  73. if (value_or_error.is_error())
  74. return with_eof_check(stream, ParseError::ExpectedIndex);
  75. size_t value = value_or_error.release_value();
  76. return T { value };
  77. }
  78. };
  79. class ReconsumableStream : public Stream {
  80. public:
  81. explicit ReconsumableStream(Stream& stream)
  82. : m_stream(stream)
  83. {
  84. }
  85. void unread(ReadonlyBytes data) { m_buffer.append(data.data(), data.size()); }
  86. private:
  87. virtual ErrorOr<Bytes> read_some(Bytes bytes) override
  88. {
  89. auto original_bytes = bytes;
  90. size_t bytes_read_from_buffer = 0;
  91. if (!m_buffer.is_empty()) {
  92. auto read_size = min(bytes.size(), m_buffer.size());
  93. m_buffer.span().slice(0, read_size).copy_to(bytes);
  94. bytes = bytes.slice(read_size);
  95. for (size_t i = 0; i < read_size; ++i)
  96. m_buffer.take_first();
  97. bytes_read_from_buffer = read_size;
  98. }
  99. return original_bytes.trim(TRY(m_stream.read_some(bytes)).size() + bytes_read_from_buffer);
  100. }
  101. virtual bool is_eof() const override
  102. {
  103. return m_buffer.is_empty() && m_stream.is_eof();
  104. }
  105. virtual ErrorOr<void> discard(size_t count) override
  106. {
  107. size_t bytes_discarded_from_buffer = 0;
  108. if (!m_buffer.is_empty()) {
  109. auto read_size = min(count, m_buffer.size());
  110. for (size_t i = 0; i < read_size; ++i)
  111. m_buffer.take_first();
  112. bytes_discarded_from_buffer = read_size;
  113. }
  114. return m_stream.discard(count - bytes_discarded_from_buffer);
  115. }
  116. virtual ErrorOr<size_t> write_some(ReadonlyBytes) override
  117. {
  118. return Error::from_errno(EBADF);
  119. }
  120. virtual bool is_open() const override
  121. {
  122. return m_stream.is_open();
  123. }
  124. virtual void close() override
  125. {
  126. m_stream.close();
  127. }
  128. Stream& m_stream;
  129. Vector<u8, 8> m_buffer;
  130. };
  131. // https://webassembly.github.io/spec/core/bikeshed/#value-types%E2%91%A2
  132. class ValueType {
  133. public:
  134. enum Kind {
  135. I32,
  136. I64,
  137. F32,
  138. F64,
  139. V128,
  140. FunctionReference,
  141. ExternReference,
  142. };
  143. explicit ValueType(Kind kind)
  144. : m_kind(kind)
  145. {
  146. }
  147. bool operator==(ValueType const&) const = default;
  148. auto is_reference() const { return m_kind == ExternReference || m_kind == FunctionReference; }
  149. auto is_vector() const { return m_kind == V128; }
  150. auto is_numeric() const { return !is_reference() && !is_vector(); }
  151. auto kind() const { return m_kind; }
  152. static ParseResult<ValueType> parse(Stream& stream);
  153. static ByteString kind_name(Kind kind)
  154. {
  155. switch (kind) {
  156. case I32:
  157. return "i32";
  158. case I64:
  159. return "i64";
  160. case F32:
  161. return "f32";
  162. case F64:
  163. return "f64";
  164. case V128:
  165. return "v128";
  166. case FunctionReference:
  167. return "funcref";
  168. case ExternReference:
  169. return "externref";
  170. }
  171. VERIFY_NOT_REACHED();
  172. }
  173. private:
  174. Kind m_kind;
  175. };
  176. // https://webassembly.github.io/spec/core/bikeshed/#result-types%E2%91%A2
  177. class ResultType {
  178. public:
  179. explicit ResultType(Vector<ValueType> types)
  180. : m_types(move(types))
  181. {
  182. }
  183. auto const& types() const { return m_types; }
  184. static ParseResult<ResultType> parse(Stream& stream);
  185. private:
  186. Vector<ValueType> m_types;
  187. };
  188. // https://webassembly.github.io/spec/core/bikeshed/#function-types%E2%91%A4
  189. class FunctionType {
  190. public:
  191. FunctionType(Vector<ValueType> parameters, Vector<ValueType> results)
  192. : m_parameters(move(parameters))
  193. , m_results(move(results))
  194. {
  195. }
  196. auto& parameters() const { return m_parameters; }
  197. auto& results() const { return m_results; }
  198. static ParseResult<FunctionType> parse(Stream& stream);
  199. private:
  200. Vector<ValueType> m_parameters;
  201. Vector<ValueType> m_results;
  202. };
  203. // https://webassembly.github.io/spec/core/bikeshed/#limits%E2%91%A5
  204. class Limits {
  205. public:
  206. explicit Limits(u32 min, Optional<u32> max = {})
  207. : m_min(min)
  208. , m_max(move(max))
  209. {
  210. }
  211. auto min() const { return m_min; }
  212. auto& max() const { return m_max; }
  213. bool is_subset_of(Limits other) const
  214. {
  215. return m_min >= other.min()
  216. && (!other.max().has_value() || (m_max.has_value() && *m_max <= *other.max()));
  217. }
  218. static ParseResult<Limits> parse(Stream& stream);
  219. private:
  220. u32 m_min { 0 };
  221. Optional<u32> m_max;
  222. };
  223. // https://webassembly.github.io/spec/core/bikeshed/#memory-types%E2%91%A4
  224. class MemoryType {
  225. public:
  226. explicit MemoryType(Limits limits)
  227. : m_limits(move(limits))
  228. {
  229. }
  230. auto& limits() const { return m_limits; }
  231. static ParseResult<MemoryType> parse(Stream& stream);
  232. private:
  233. Limits m_limits;
  234. };
  235. // https://webassembly.github.io/spec/core/bikeshed/#table-types%E2%91%A4
  236. class TableType {
  237. public:
  238. explicit TableType(ValueType element_type, Limits limits)
  239. : m_element_type(element_type)
  240. , m_limits(move(limits))
  241. {
  242. VERIFY(m_element_type.is_reference());
  243. }
  244. auto& limits() const { return m_limits; }
  245. auto& element_type() const { return m_element_type; }
  246. static ParseResult<TableType> parse(Stream& stream);
  247. private:
  248. ValueType m_element_type;
  249. Limits m_limits;
  250. };
  251. // https://webassembly.github.io/spec/core/bikeshed/#global-types%E2%91%A4
  252. class GlobalType {
  253. public:
  254. GlobalType(ValueType type, bool is_mutable)
  255. : m_type(type)
  256. , m_is_mutable(is_mutable)
  257. {
  258. }
  259. auto& type() const { return m_type; }
  260. auto is_mutable() const { return m_is_mutable; }
  261. static ParseResult<GlobalType> parse(Stream& stream);
  262. private:
  263. ValueType m_type;
  264. bool m_is_mutable { false };
  265. };
  266. // https://webassembly.github.io/spec/core/bikeshed/#binary-blocktype
  267. class BlockType {
  268. public:
  269. enum Kind {
  270. Empty,
  271. Type,
  272. Index,
  273. };
  274. BlockType()
  275. : m_kind(Empty)
  276. , m_empty(0)
  277. {
  278. }
  279. explicit BlockType(ValueType type)
  280. : m_kind(Type)
  281. , m_value_type(type)
  282. {
  283. }
  284. explicit BlockType(TypeIndex index)
  285. : m_kind(Index)
  286. , m_type_index(index)
  287. {
  288. }
  289. auto kind() const { return m_kind; }
  290. auto& value_type() const
  291. {
  292. VERIFY(kind() == Type);
  293. return m_value_type;
  294. }
  295. auto& type_index() const
  296. {
  297. VERIFY(kind() == Index);
  298. return m_type_index;
  299. }
  300. static ParseResult<BlockType> parse(Stream& stream);
  301. private:
  302. Kind m_kind { Empty };
  303. union {
  304. ValueType m_value_type;
  305. TypeIndex m_type_index;
  306. u8 m_empty;
  307. };
  308. };
  309. // https://webassembly.github.io/spec/core/bikeshed/#binary-instr
  310. // https://webassembly.github.io/spec/core/bikeshed/#reference-instructions%E2%91%A6
  311. // https://webassembly.github.io/spec/core/bikeshed/#parametric-instructions%E2%91%A6
  312. // https://webassembly.github.io/spec/core/bikeshed/#variable-instructions%E2%91%A6
  313. // https://webassembly.github.io/spec/core/bikeshed/#table-instructions%E2%91%A6
  314. // https://webassembly.github.io/spec/core/bikeshed/#memory-instructions%E2%91%A6
  315. // https://webassembly.github.io/spec/core/bikeshed/#numeric-instructions%E2%91%A6
  316. class Instruction {
  317. public:
  318. explicit Instruction(OpCode opcode)
  319. : m_opcode(opcode)
  320. , m_arguments(static_cast<u8>(0))
  321. {
  322. }
  323. struct TableElementArgs {
  324. ElementIndex element_index;
  325. TableIndex table_index;
  326. };
  327. struct TableTableArgs {
  328. TableIndex lhs;
  329. TableIndex rhs;
  330. };
  331. struct StructuredInstructionArgs {
  332. BlockType block_type;
  333. InstructionPointer end_ip;
  334. Optional<InstructionPointer> else_ip;
  335. };
  336. struct TableBranchArgs {
  337. Vector<LabelIndex> labels;
  338. LabelIndex default_;
  339. };
  340. struct IndirectCallArgs {
  341. TypeIndex type;
  342. TableIndex table;
  343. };
  344. struct MemoryArgument {
  345. u32 align;
  346. u32 offset;
  347. MemoryIndex memory_index { 0 };
  348. };
  349. struct MemoryAndLaneArgument {
  350. MemoryArgument memory;
  351. u8 lane;
  352. };
  353. struct LaneIndex {
  354. u8 lane;
  355. };
  356. // Proposal "multi-memory"
  357. struct MemoryCopyArgs {
  358. MemoryIndex src_index;
  359. MemoryIndex dst_index;
  360. };
  361. struct MemoryInitArgs {
  362. DataIndex data_index;
  363. MemoryIndex memory_index;
  364. };
  365. struct MemoryIndexArgument {
  366. MemoryIndex memory_index;
  367. };
  368. struct ShuffleArgument {
  369. explicit ShuffleArgument(u8 (&lanes)[16])
  370. : lanes {
  371. lanes[0], lanes[1], lanes[2], lanes[3], lanes[4], lanes[5], lanes[6], lanes[7],
  372. lanes[8], lanes[9], lanes[10], lanes[11], lanes[12], lanes[13], lanes[14], lanes[15]
  373. }
  374. {
  375. }
  376. u8 lanes[16];
  377. };
  378. template<typename T>
  379. explicit Instruction(OpCode opcode, T argument)
  380. : m_opcode(opcode)
  381. , m_arguments(move(argument))
  382. {
  383. }
  384. static ParseResult<Instruction> parse(Stream& stream);
  385. auto& opcode() const { return m_opcode; }
  386. auto& arguments() const { return m_arguments; }
  387. auto& arguments() { return m_arguments; }
  388. private:
  389. OpCode m_opcode { 0 };
  390. Variant<
  391. BlockType,
  392. DataIndex,
  393. ElementIndex,
  394. FunctionIndex,
  395. GlobalIndex,
  396. IndirectCallArgs,
  397. LabelIndex,
  398. LaneIndex,
  399. LocalIndex,
  400. MemoryArgument,
  401. MemoryAndLaneArgument,
  402. MemoryCopyArgs,
  403. MemoryIndexArgument,
  404. MemoryInitArgs,
  405. StructuredInstructionArgs,
  406. ShuffleArgument,
  407. TableBranchArgs,
  408. TableElementArgs,
  409. TableIndex,
  410. TableTableArgs,
  411. ValueType,
  412. Vector<ValueType>,
  413. double,
  414. float,
  415. i32,
  416. i64,
  417. u128,
  418. u8> // Empty state
  419. m_arguments;
  420. };
  421. struct SectionId {
  422. public:
  423. enum class SectionIdKind : u8 {
  424. Custom,
  425. Type,
  426. Import,
  427. Function,
  428. Table,
  429. Memory,
  430. Global,
  431. Export,
  432. Start,
  433. Element,
  434. DataCount,
  435. Code,
  436. Data,
  437. };
  438. explicit SectionId(SectionIdKind kind)
  439. : m_kind(kind)
  440. {
  441. }
  442. SectionIdKind kind() const { return m_kind; }
  443. static ParseResult<SectionId> parse(Stream& stream);
  444. private:
  445. SectionIdKind m_kind;
  446. };
  447. class CustomSection {
  448. public:
  449. CustomSection(ByteString name, ByteBuffer contents)
  450. : m_name(move(name))
  451. , m_contents(move(contents))
  452. {
  453. }
  454. auto& name() const { return m_name; }
  455. auto& contents() const { return m_contents; }
  456. static ParseResult<CustomSection> parse(Stream& stream);
  457. private:
  458. ByteString m_name;
  459. ByteBuffer m_contents;
  460. };
  461. class TypeSection {
  462. public:
  463. TypeSection() = default;
  464. explicit TypeSection(Vector<FunctionType> types)
  465. : m_types(move(types))
  466. {
  467. }
  468. auto& types() const { return m_types; }
  469. static ParseResult<TypeSection> parse(Stream& stream);
  470. private:
  471. Vector<FunctionType> m_types;
  472. };
  473. class ImportSection {
  474. public:
  475. class Import {
  476. public:
  477. using ImportDesc = Variant<TypeIndex, TableType, MemoryType, GlobalType, FunctionType>;
  478. Import(ByteString module, ByteString name, ImportDesc description)
  479. : m_module(move(module))
  480. , m_name(move(name))
  481. , m_description(move(description))
  482. {
  483. }
  484. auto& module() const { return m_module; }
  485. auto& name() const { return m_name; }
  486. auto& description() const { return m_description; }
  487. static ParseResult<Import> parse(Stream& stream);
  488. private:
  489. template<typename T>
  490. static ParseResult<Import> parse_with_type(auto&& stream, auto&& module, auto&& name)
  491. {
  492. auto result = TRY(T::parse(stream));
  493. return Import { module, name, result };
  494. }
  495. ByteString m_module;
  496. ByteString m_name;
  497. ImportDesc m_description;
  498. };
  499. public:
  500. ImportSection() = default;
  501. explicit ImportSection(Vector<Import> imports)
  502. : m_imports(move(imports))
  503. {
  504. }
  505. auto& imports() const { return m_imports; }
  506. static ParseResult<ImportSection> parse(Stream& stream);
  507. private:
  508. Vector<Import> m_imports;
  509. };
  510. class FunctionSection {
  511. public:
  512. FunctionSection() = default;
  513. explicit FunctionSection(Vector<TypeIndex> types)
  514. : m_types(move(types))
  515. {
  516. }
  517. auto& types() const { return m_types; }
  518. static ParseResult<FunctionSection> parse(Stream& stream);
  519. private:
  520. Vector<TypeIndex> m_types;
  521. };
  522. class TableSection {
  523. public:
  524. class Table {
  525. public:
  526. explicit Table(TableType type)
  527. : m_type(move(type))
  528. {
  529. }
  530. auto& type() const { return m_type; }
  531. static ParseResult<Table> parse(Stream& stream);
  532. private:
  533. TableType m_type;
  534. };
  535. public:
  536. TableSection() = default;
  537. explicit TableSection(Vector<Table> tables)
  538. : m_tables(move(tables))
  539. {
  540. }
  541. auto& tables() const { return m_tables; }
  542. static ParseResult<TableSection> parse(Stream& stream);
  543. private:
  544. Vector<Table> m_tables;
  545. };
  546. class MemorySection {
  547. public:
  548. class Memory {
  549. public:
  550. explicit Memory(MemoryType type)
  551. : m_type(move(type))
  552. {
  553. }
  554. auto& type() const { return m_type; }
  555. static ParseResult<Memory> parse(Stream& stream);
  556. private:
  557. MemoryType m_type;
  558. };
  559. public:
  560. MemorySection() = default;
  561. explicit MemorySection(Vector<Memory> memories)
  562. : m_memories(move(memories))
  563. {
  564. }
  565. auto& memories() const { return m_memories; }
  566. static ParseResult<MemorySection> parse(Stream& stream);
  567. private:
  568. Vector<Memory> m_memories;
  569. };
  570. class Expression {
  571. public:
  572. explicit Expression(Vector<Instruction> instructions)
  573. : m_instructions(move(instructions))
  574. {
  575. }
  576. auto& instructions() const { return m_instructions; }
  577. static ParseResult<Expression> parse(Stream& stream, Optional<size_t> size_hint = {});
  578. private:
  579. Vector<Instruction> m_instructions;
  580. };
  581. class GlobalSection {
  582. public:
  583. class Global {
  584. public:
  585. explicit Global(GlobalType type, Expression expression)
  586. : m_type(move(type))
  587. , m_expression(move(expression))
  588. {
  589. }
  590. auto& type() const { return m_type; }
  591. auto& expression() const { return m_expression; }
  592. static ParseResult<Global> parse(Stream& stream);
  593. private:
  594. GlobalType m_type;
  595. Expression m_expression;
  596. };
  597. public:
  598. GlobalSection() = default;
  599. explicit GlobalSection(Vector<Global> entries)
  600. : m_entries(move(entries))
  601. {
  602. }
  603. auto& entries() const { return m_entries; }
  604. static ParseResult<GlobalSection> parse(Stream& stream);
  605. private:
  606. Vector<Global> m_entries;
  607. };
  608. class ExportSection {
  609. private:
  610. using ExportDesc = Variant<FunctionIndex, TableIndex, MemoryIndex, GlobalIndex>;
  611. public:
  612. class Export {
  613. public:
  614. explicit Export(ByteString name, ExportDesc description)
  615. : m_name(move(name))
  616. , m_description(move(description))
  617. {
  618. }
  619. auto& name() const { return m_name; }
  620. auto& description() const { return m_description; }
  621. static ParseResult<Export> parse(Stream& stream);
  622. private:
  623. ByteString m_name;
  624. ExportDesc m_description;
  625. };
  626. ExportSection() = default;
  627. explicit ExportSection(Vector<Export> entries)
  628. : m_entries(move(entries))
  629. {
  630. }
  631. auto& entries() const { return m_entries; }
  632. static ParseResult<ExportSection> parse(Stream& stream);
  633. private:
  634. Vector<Export> m_entries;
  635. };
  636. class StartSection {
  637. public:
  638. class StartFunction {
  639. public:
  640. explicit StartFunction(FunctionIndex index)
  641. : m_index(index)
  642. {
  643. }
  644. auto& index() const { return m_index; }
  645. static ParseResult<StartFunction> parse(Stream& stream);
  646. private:
  647. FunctionIndex m_index;
  648. };
  649. StartSection() = default;
  650. explicit StartSection(Optional<StartFunction> func)
  651. : m_function(move(func))
  652. {
  653. }
  654. auto& function() const { return m_function; }
  655. static ParseResult<StartSection> parse(Stream& stream);
  656. private:
  657. Optional<StartFunction> m_function;
  658. };
  659. class ElementSection {
  660. public:
  661. struct Active {
  662. TableIndex index;
  663. Expression expression;
  664. };
  665. struct Declarative {
  666. };
  667. struct Passive {
  668. };
  669. struct Element {
  670. static ParseResult<Element> parse(Stream&);
  671. ValueType type;
  672. Vector<Expression> init;
  673. Variant<Active, Passive, Declarative> mode;
  674. };
  675. ElementSection() = default;
  676. explicit ElementSection(Vector<Element> segs)
  677. : m_segments(move(segs))
  678. {
  679. }
  680. auto& segments() const { return m_segments; }
  681. static ParseResult<ElementSection> parse(Stream& stream);
  682. private:
  683. Vector<Element> m_segments;
  684. };
  685. class Locals {
  686. public:
  687. explicit Locals(u32 n, ValueType type)
  688. : m_n(n)
  689. , m_type(type)
  690. {
  691. }
  692. // Yikes...
  693. auto n() const { return m_n; }
  694. auto& type() const { return m_type; }
  695. static ParseResult<Locals> parse(Stream& stream);
  696. private:
  697. u32 m_n { 0 };
  698. ValueType m_type;
  699. };
  700. class CodeSection {
  701. public:
  702. // https://webassembly.github.io/spec/core/bikeshed/#binary-func
  703. class Func {
  704. public:
  705. explicit Func(Vector<Locals> locals, Expression body)
  706. : m_locals(move(locals))
  707. , m_body(move(body))
  708. {
  709. }
  710. auto& locals() const { return m_locals; }
  711. auto& body() const { return m_body; }
  712. static ParseResult<Func> parse(Stream& stream, size_t size_hint);
  713. private:
  714. Vector<Locals> m_locals;
  715. Expression m_body;
  716. };
  717. class Code {
  718. public:
  719. explicit Code(u32 size, Func func)
  720. : m_size(size)
  721. , m_func(move(func))
  722. {
  723. }
  724. auto size() const { return m_size; }
  725. auto& func() const { return m_func; }
  726. static ParseResult<Code> parse(Stream& stream);
  727. private:
  728. u32 m_size { 0 };
  729. Func m_func;
  730. };
  731. CodeSection() = default;
  732. explicit CodeSection(Vector<Code> funcs)
  733. : m_functions(move(funcs))
  734. {
  735. }
  736. auto& functions() const { return m_functions; }
  737. static ParseResult<CodeSection> parse(Stream& stream);
  738. private:
  739. Vector<Code> m_functions;
  740. };
  741. class DataSection {
  742. public:
  743. class Data {
  744. public:
  745. struct Passive {
  746. Vector<u8> init;
  747. };
  748. struct Active {
  749. Vector<u8> init;
  750. MemoryIndex index;
  751. Expression offset;
  752. };
  753. using Value = Variant<Passive, Active>;
  754. explicit Data(Value value)
  755. : m_value(move(value))
  756. {
  757. }
  758. auto& value() const { return m_value; }
  759. static ParseResult<Data> parse(Stream& stream);
  760. private:
  761. Value m_value;
  762. };
  763. DataSection() = default;
  764. explicit DataSection(Vector<Data> data)
  765. : m_data(move(data))
  766. {
  767. }
  768. auto& data() const { return m_data; }
  769. static ParseResult<DataSection> parse(Stream& stream);
  770. private:
  771. Vector<Data> m_data;
  772. };
  773. class DataCountSection {
  774. public:
  775. DataCountSection() = default;
  776. explicit DataCountSection(Optional<u32> count)
  777. : m_count(move(count))
  778. {
  779. }
  780. auto& count() const { return m_count; }
  781. static ParseResult<DataCountSection> parse(Stream& stream);
  782. private:
  783. Optional<u32> m_count;
  784. };
  785. class Module : public RefCounted<Module>
  786. , public Weakable<Module> {
  787. public:
  788. enum class ValidationStatus {
  789. Unchecked,
  790. Invalid,
  791. Valid,
  792. };
  793. static constexpr Array<u8, 4> wasm_magic { 0, 'a', 's', 'm' };
  794. static constexpr Array<u8, 4> wasm_version { 1, 0, 0, 0 };
  795. Module() = default;
  796. auto& custom_sections() { return m_custom_sections; }
  797. auto& custom_sections() const { return m_custom_sections; }
  798. auto& type_section() const { return m_type_section; }
  799. auto& type_section() { return m_type_section; }
  800. auto& import_section() const { return m_import_section; }
  801. auto& import_section() { return m_import_section; }
  802. auto& function_section() { return m_function_section; }
  803. auto& function_section() const { return m_function_section; }
  804. auto& table_section() { return m_table_section; }
  805. auto& table_section() const { return m_table_section; }
  806. auto& memory_section() { return m_memory_section; }
  807. auto& memory_section() const { return m_memory_section; }
  808. auto& global_section() { return m_global_section; }
  809. auto& global_section() const { return m_global_section; }
  810. auto& export_section() { return m_export_section; }
  811. auto& export_section() const { return m_export_section; }
  812. auto& start_section() { return m_start_section; }
  813. auto& start_section() const { return m_start_section; }
  814. auto& element_section() { return m_element_section; }
  815. auto& element_section() const { return m_element_section; }
  816. auto& code_section() { return m_code_section; }
  817. auto& code_section() const { return m_code_section; }
  818. auto& data_section() { return m_data_section; }
  819. auto& data_section() const { return m_data_section; }
  820. auto& data_count_section() { return m_data_count_section; }
  821. auto& data_count_section() const { return m_data_count_section; }
  822. void set_validation_status(ValidationStatus status, Badge<Validator>) { set_validation_status(status); }
  823. ValidationStatus validation_status() const { return m_validation_status; }
  824. StringView validation_error() const { return *m_validation_error; }
  825. void set_validation_error(ByteString error) { m_validation_error = move(error); }
  826. static ParseResult<NonnullRefPtr<Module>> parse(Stream& stream);
  827. private:
  828. void set_validation_status(ValidationStatus status) { m_validation_status = status; }
  829. Vector<CustomSection> m_custom_sections;
  830. TypeSection m_type_section;
  831. ImportSection m_import_section;
  832. FunctionSection m_function_section;
  833. TableSection m_table_section;
  834. MemorySection m_memory_section;
  835. GlobalSection m_global_section;
  836. ExportSection m_export_section;
  837. StartSection m_start_section;
  838. ElementSection m_element_section;
  839. CodeSection m_code_section;
  840. DataSection m_data_section;
  841. DataCountSection m_data_count_section;
  842. ValidationStatus m_validation_status { ValidationStatus::Unchecked };
  843. Optional<ByteString> m_validation_error;
  844. };
  845. }