linera_wasmer/externals/
table.rs1#[cfg(feature = "js")]
2use crate::js::externals::table as table_impl;
3#[cfg(feature = "jsc")]
4use crate::jsc::externals::table as table_impl;
5#[cfg(feature = "sys")]
6use crate::sys::externals::table as table_impl;
7
8use crate::exports::{ExportError, Exportable};
9use crate::store::{AsStoreMut, AsStoreRef};
10use crate::vm::{VMExtern, VMExternTable};
11use crate::Extern;
12use crate::RuntimeError;
13use crate::TableType;
14use crate::Value;
15
16#[derive(Debug, Clone, PartialEq)]
26#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
27pub struct Table(pub(crate) table_impl::Table);
28
29impl Table {
30 pub fn new(
36 store: &mut impl AsStoreMut,
37 ty: TableType,
38 init: Value,
39 ) -> Result<Self, RuntimeError> {
40 Ok(Self(table_impl::Table::new(store, ty, init)?))
41 }
42
43 pub fn ty(&self, store: &impl AsStoreRef) -> TableType {
45 self.0.ty(store)
46 }
47
48 pub fn get(&self, store: &mut impl AsStoreMut, index: u32) -> Option<Value> {
50 self.0.get(store, index)
51 }
52
53 pub fn set(
55 &self,
56 store: &mut impl AsStoreMut,
57 index: u32,
58 val: Value,
59 ) -> Result<(), RuntimeError> {
60 self.0.set(store, index, val)
61 }
62
63 pub fn size(&self, store: &impl AsStoreRef) -> u32 {
65 self.0.size(store)
66 }
67
68 pub fn grow(
78 &self,
79 store: &mut impl AsStoreMut,
80 delta: u32,
81 init: Value,
82 ) -> Result<u32, RuntimeError> {
83 self.0.grow(store, delta, init)
84 }
85
86 pub fn copy(
94 store: &mut impl AsStoreMut,
95 dst_table: &Self,
96 dst_index: u32,
97 src_table: &Self,
98 src_index: u32,
99 len: u32,
100 ) -> Result<(), RuntimeError> {
101 table_impl::Table::copy(store, &dst_table.0, dst_index, &src_table.0, src_index, len)
102 }
103
104 pub(crate) fn from_vm_extern(store: &mut impl AsStoreMut, extern_: VMExternTable) -> Self {
105 Self(table_impl::Table::from_vm_extern(store, extern_))
106 }
107
108 pub fn is_from_store(&self, store: &impl AsStoreRef) -> bool {
110 self.0.is_from_store(store)
111 }
112
113 pub(crate) fn to_vm_extern(&self) -> VMExtern {
114 self.0.to_vm_extern()
115 }
116}
117
118impl std::cmp::Eq for Table {}
119
120impl<'a> Exportable<'a> for Table {
121 fn get_self_from_extern(_extern: &'a Extern) -> Result<&'a Self, ExportError> {
122 match _extern {
123 Extern::Table(table) => Ok(table),
124 _ => Err(ExportError::IncompatibleType),
125 }
126 }
127}
128
129#[test]
131fn test_table_grow_issue_3197() {
132 use crate::{imports, Instance, Module, Store, Table, TableType, Type, Value};
133
134 const WAT: &str = r#"(module (table (import "env" "table") 100 funcref))"#;
135
136 let mut store = Store::default();
139 let module = Module::new(&store, WAT).unwrap();
140 let ty = TableType::new(Type::FuncRef, 0, None);
141 let table = Table::new(&mut store, ty, Value::FuncRef(None)).unwrap();
142 table.grow(&mut store, 100, Value::FuncRef(None)).unwrap();
143 assert_eq!(table.ty(&store).minimum, 0);
144 let imports = imports! {"env" => {"table" => table}};
145 let _instance = Instance::new(&mut store, &module, &imports).unwrap();
146}