tinywasm_wasmparser/readers/core/tables.rs
1/* Copyright 2018 Mozilla Foundation
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16use crate::{BinaryReader, ConstExpr, FromReader, Result, SectionLimited, TableType};
17
18/// A reader for the table section of a WebAssembly module.
19pub type TableSectionReader<'a> = SectionLimited<'a, Table<'a>>;
20
21/// Type information about a table defined in the table section of a WebAssembly
22/// module.
23#[derive(Debug)]
24pub struct Table<'a> {
25 /// The type of this table, including its element type and its limits.
26 pub ty: TableType,
27 /// The initialization expression for the table.
28 pub init: TableInit<'a>,
29}
30
31/// Different modes of initializing a table.
32#[derive(Debug)]
33pub enum TableInit<'a> {
34 /// The table is initialized to all null elements.
35 RefNull,
36 /// Each element in the table is initialized with the specified constant
37 /// expression.
38 Expr(ConstExpr<'a>),
39}
40
41impl<'a> FromReader<'a> for Table<'a> {
42 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
43 let has_init_expr = if reader.peek()? == 0x40 {
44 reader.read_u8()?;
45 true
46 } else {
47 false
48 };
49
50 if has_init_expr {
51 if reader.read_u8()? != 0x00 {
52 bail!(reader.original_position() - 1, "invalid table encoding");
53 }
54 }
55
56 let ty = reader.read::<TableType>()?;
57 let init = if has_init_expr {
58 TableInit::Expr(reader.read()?)
59 } else {
60 TableInit::RefNull
61 };
62 Ok(Table { ty, init })
63 }
64}
65
66impl<'a> FromReader<'a> for TableType {
67 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
68 let element_type = reader.read()?;
69 let has_max = match reader.read_u8()? {
70 0x00 => false,
71 0x01 => true,
72 _ => {
73 bail!(
74 reader.original_position() - 1,
75 "invalid table resizable limits flags",
76 )
77 }
78 };
79 let initial = reader.read()?;
80 let maximum = if has_max { Some(reader.read()?) } else { None };
81 Ok(TableType {
82 element_type,
83 initial,
84 maximum,
85 })
86 }
87}