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}