11use core:: sync:: atomic:: { AtomicUsize , Ordering } ;
22
33use alloc:: { format, rc:: Rc , vec:: Vec } ;
4- use tinywasm_types:: { FuncAddr , Function , Instruction , ModuleInstanceAddr , TypeAddr , ValType } ;
4+ use tinywasm_types:: {
5+ Addr , Data , Element , ElementKind , FuncAddr , Function , Global , GlobalType , Instruction , MemAddr , MemoryType ,
6+ ModuleInstanceAddr , TableAddr , TableType , TypeAddr , ValType ,
7+ } ;
58
69use crate :: {
710 runtime:: { self , DefaultRuntime } ,
@@ -69,42 +72,19 @@ impl Default for Store {
6972 }
7073}
7174
72- #[ derive( Debug ) ]
73- /// A WebAssembly Function Instance
74- ///
75- /// See <https://webassembly.github.io/spec/core/exec/runtime.html#function-instances>
76- pub struct FunctionInstance {
77- pub ( crate ) func : Function ,
78- pub ( crate ) _module_instance : ModuleInstanceAddr , // index into store.module_instances
79- }
80-
81- impl FunctionInstance {
82- pub ( crate ) fn _module_instance_addr ( & self ) -> ModuleInstanceAddr {
83- self . _module_instance
84- }
85-
86- pub ( crate ) fn locals ( & self ) -> & [ ValType ] {
87- & self . func . locals
88- }
89-
90- pub ( crate ) fn instructions ( & self ) -> & [ Instruction ] {
91- & self . func . instructions
92- }
93-
94- pub ( crate ) fn ty_addr ( & self ) -> TypeAddr {
95- self . func . ty
96- }
97- }
98-
9975#[ derive( Debug , Default ) ]
10076/// Global state that can be manipulated by WebAssembly programs
77+ ///
78+ /// Data should only be addressable by the module that owns it
79+ /// See <https://webassembly.github.io/spec/core/exec/runtime.html#store>
80+ // TODO: Arena allocate these?
10181pub ( crate ) struct StoreData {
10282 pub ( crate ) funcs : Vec < Rc < FunctionInstance > > ,
103- // pub tables: Vec<TableAddr >,
104- // pub mems: Vec<MemAddr >,
105- // pub globals: Vec<GlobalAddr >,
106- // pub elems: Vec<ElmAddr >,
107- // pub datas: Vec<DataAddr >,
83+ pub ( crate ) tables : Vec < TableInstance > ,
84+ pub ( crate ) mems : Vec < Rc < MemoryInstance > > ,
85+ pub ( crate ) globals : Vec < Rc < GlobalInstance > > ,
86+ pub ( crate ) elems : Vec < ElemInstance > ,
87+ pub ( crate ) datas : Vec < DataInstance > ,
10888}
10989
11090impl Store {
@@ -129,15 +109,69 @@ impl Store {
129109 let func_count = self . data . funcs . len ( ) ;
130110 let mut func_addrs = Vec :: with_capacity ( func_count) ;
131111 for ( i, func) in funcs. into_iter ( ) . enumerate ( ) {
132- self . data . funcs . push ( Rc :: new ( FunctionInstance {
133- func,
134- _module_instance : idx,
135- } ) ) ;
112+ self . data . funcs . push ( Rc :: new ( FunctionInstance { func, owner : idx } ) ) ;
136113 func_addrs. push ( ( i + func_count) as FuncAddr ) ;
137114 }
138115 func_addrs
139116 }
140117
118+ /// Add tables to the store, returning their addresses in the store
119+ pub ( crate ) fn add_tables ( & mut self , tables : Vec < TableType > , idx : ModuleInstanceAddr ) -> Vec < TableAddr > {
120+ let table_count = self . data . tables . len ( ) ;
121+ let mut table_addrs = Vec :: with_capacity ( table_count) ;
122+ for ( i, table) in tables. into_iter ( ) . enumerate ( ) {
123+ self . data . tables . push ( TableInstance :: new ( table, idx) ) ;
124+ table_addrs. push ( ( i + table_count) as TableAddr ) ;
125+ }
126+ table_addrs
127+ }
128+
129+ /// Add memories to the store, returning their addresses in the store
130+ pub ( crate ) fn add_mems ( & mut self , mems : Vec < MemoryType > , idx : ModuleInstanceAddr ) -> Vec < MemAddr > {
131+ let mem_count = self . data . mems . len ( ) ;
132+ let mut mem_addrs = Vec :: with_capacity ( mem_count) ;
133+ for ( i, mem) in mems. into_iter ( ) . enumerate ( ) {
134+ self . data . mems . push ( Rc :: new ( MemoryInstance :: new ( mem, idx) ) ) ;
135+ mem_addrs. push ( ( i + mem_count) as MemAddr ) ;
136+ }
137+ mem_addrs
138+ }
139+
140+ /// Add globals to the store, returning their addresses in the store
141+ pub ( crate ) fn add_globals ( & mut self , globals : Vec < Global > , idx : ModuleInstanceAddr ) -> Vec < Addr > {
142+ let global_count = self . data . globals . len ( ) ;
143+ let mut global_addrs = Vec :: with_capacity ( global_count) ;
144+ for ( i, global) in globals. into_iter ( ) . enumerate ( ) {
145+ // TODO: initialize globals
146+ // Don't fail here yet - we'll fail when we try to use the global
147+ self . data . globals . push ( Rc :: new ( GlobalInstance :: new ( global. ty , 0 , idx) ) ) ;
148+ global_addrs. push ( ( i + global_count) as Addr ) ;
149+ }
150+ global_addrs
151+ }
152+
153+ /// Add elements to the store, returning their addresses in the store
154+ pub ( crate ) fn add_elems ( & mut self , elems : Vec < Element > , idx : ModuleInstanceAddr ) -> Vec < Addr > {
155+ let elem_count = self . data . elems . len ( ) ;
156+ let mut elem_addrs = Vec :: with_capacity ( elem_count) ;
157+ for ( i, elem) in elems. into_iter ( ) . enumerate ( ) {
158+ self . data . elems . push ( ElemInstance :: new ( elem. kind , idx) ) ;
159+ elem_addrs. push ( ( i + elem_count) as Addr ) ;
160+ }
161+ elem_addrs
162+ }
163+
164+ /// Add data to the store, returning their addresses in the store
165+ pub ( crate ) fn add_datas ( & mut self , datas : Vec < Data > , idx : ModuleInstanceAddr ) -> Vec < Addr > {
166+ let data_count = self . data . datas . len ( ) ;
167+ let mut data_addrs = Vec :: with_capacity ( data_count) ;
168+ for ( i, data) in datas. into_iter ( ) . enumerate ( ) {
169+ self . data . datas . push ( DataInstance :: new ( data. data . to_vec ( ) , idx) ) ;
170+ data_addrs. push ( ( i + data_count) as Addr ) ;
171+ }
172+ data_addrs
173+ }
174+
141175 /// Get the function at the actual index in the store
142176 pub ( crate ) fn get_func ( & self , addr : usize ) -> Result < & Rc < FunctionInstance > > {
143177 self . data
@@ -146,3 +180,116 @@ impl Store {
146180 . ok_or_else ( || Error :: Other ( format ! ( "function {} not found" , addr) ) )
147181 }
148182}
183+
184+ #[ derive( Debug ) ]
185+ /// A WebAssembly Function Instance
186+ ///
187+ /// See <https://webassembly.github.io/spec/core/exec/runtime.html#function-instances>
188+ pub struct FunctionInstance {
189+ pub ( crate ) func : Function ,
190+ pub ( crate ) owner : ModuleInstanceAddr , // index into store.module_instances
191+ }
192+
193+ impl FunctionInstance {
194+ pub ( crate ) fn _module_instance_addr ( & self ) -> ModuleInstanceAddr {
195+ self . owner
196+ }
197+
198+ pub ( crate ) fn locals ( & self ) -> & [ ValType ] {
199+ & self . func . locals
200+ }
201+
202+ pub ( crate ) fn instructions ( & self ) -> & [ Instruction ] {
203+ & self . func . instructions
204+ }
205+
206+ pub ( crate ) fn ty_addr ( & self ) -> TypeAddr {
207+ self . func . ty
208+ }
209+ }
210+
211+ /// A WebAssembly Table Instance
212+ ///
213+ /// See <https://webassembly.github.io/spec/core/exec/runtime.html#table-instances>
214+ #[ derive( Debug ) ]
215+ pub ( crate ) struct TableInstance {
216+ pub ( crate ) kind : TableType ,
217+ pub ( crate ) elements : Vec < Addr > ,
218+ pub ( crate ) owner : ModuleInstanceAddr , // index into store.module_instances
219+ }
220+
221+ impl TableInstance {
222+ pub ( crate ) fn new ( kind : TableType , owner : ModuleInstanceAddr ) -> Self {
223+ Self {
224+ kind,
225+ elements : Vec :: new ( ) ,
226+ owner,
227+ }
228+ }
229+ }
230+
231+ /// A WebAssembly Memory Instance
232+ ///
233+ /// See <https://webassembly.github.io/spec/core/exec/runtime.html#memory-instances>
234+ #[ derive( Debug ) ]
235+ pub ( crate ) struct MemoryInstance {
236+ pub ( crate ) kind : MemoryType ,
237+ pub ( crate ) data : Vec < u8 > ,
238+ pub ( crate ) owner : ModuleInstanceAddr , // index into store.module_instances
239+ }
240+
241+ impl MemoryInstance {
242+ pub ( crate ) fn new ( kind : MemoryType , owner : ModuleInstanceAddr ) -> Self {
243+ Self {
244+ kind,
245+ data : Vec :: new ( ) ,
246+ owner,
247+ }
248+ }
249+ }
250+
251+ /// A WebAssembly Global Instance
252+ ///
253+ /// See <https://webassembly.github.io/spec/core/exec/runtime.html#global-instances>
254+ #[ derive( Debug ) ]
255+ pub ( crate ) struct GlobalInstance {
256+ pub ( crate ) ty : GlobalType ,
257+ pub ( crate ) value : Addr ,
258+ owner : ModuleInstanceAddr , // index into store.module_instances
259+ }
260+
261+ impl GlobalInstance {
262+ pub ( crate ) fn new ( ty : GlobalType , value : Addr , owner : ModuleInstanceAddr ) -> Self {
263+ Self { ty, value, owner }
264+ }
265+ }
266+
267+ /// A WebAssembly Element Instance
268+ ///
269+ /// See <https://webassembly.github.io/spec/core/exec/runtime.html#element-instances>
270+ #[ derive( Debug ) ]
271+ pub ( crate ) struct ElemInstance {
272+ kind : ElementKind ,
273+ owner : ModuleInstanceAddr , // index into store.module_instances
274+ }
275+
276+ impl ElemInstance {
277+ pub ( crate ) fn new ( kind : ElementKind , owner : ModuleInstanceAddr ) -> Self {
278+ Self { kind, owner }
279+ }
280+ }
281+
282+ /// A WebAssembly Data Instance
283+ ///
284+ /// See <https://webassembly.github.io/spec/core/exec/runtime.html#data-instances>
285+ #[ derive( Debug ) ]
286+ pub ( crate ) struct DataInstance {
287+ pub ( crate ) data : Vec < u8 > ,
288+ owner : ModuleInstanceAddr , // index into store.module_instances
289+ }
290+
291+ impl DataInstance {
292+ pub ( crate ) fn new ( data : Vec < u8 > , owner : ModuleInstanceAddr ) -> Self {
293+ Self { data, owner }
294+ }
295+ }
0 commit comments