@@ -4,7 +4,7 @@ use core::fmt::Debug;
44
55use crate :: {
66 func:: { FromWasmValueTuple , IntoWasmValueTuple , ValTypesFromTuple } ,
7- Result ,
7+ LinkingError , Result ,
88} ;
99use alloc:: {
1010 collections:: BTreeMap ,
@@ -263,19 +263,79 @@ impl Imports {
263263 None
264264 }
265265
266- fn compare_types < T > ( import : & Import , expected : & T , actual : & T ) -> Result < ( ) >
266+ fn compare_types < T > ( import : & Import , actual : & T , expected : & T ) -> Result < ( ) >
267267 where
268268 T : Debug + PartialEq ,
269269 {
270270 if expected != actual {
271271 log:: error!( "failed to link import {}, expected {:?}, got {:?}" , import. name, expected, actual) ;
272- return Err ( crate :: LinkingError :: IncompatibleImportType {
273- module : import. module . to_string ( ) ,
274- name : import. name . to_string ( ) ,
272+ return Err ( LinkingError :: incompatible_import_type ( import) . into ( ) ) ;
273+ }
274+
275+ Ok ( ( ) )
276+ }
277+
278+ fn compare_table_types ( import : & Import , expected : & TableType , actual : & TableType ) -> Result < ( ) > {
279+ Self :: compare_types ( import, & actual. element_type , & expected. element_type ) ?;
280+
281+ if actual. size_initial > expected. size_initial {
282+ return Err ( LinkingError :: incompatible_import_type ( import) . into ( ) ) ;
283+ }
284+
285+ match ( expected. size_max , actual. size_max ) {
286+ ( None , Some ( _) ) => return Err ( LinkingError :: incompatible_import_type ( import) . into ( ) ) ,
287+ ( Some ( expected_max) , Some ( actual_max) ) if actual_max < expected_max => {
288+ return Err ( LinkingError :: incompatible_import_type ( import) . into ( ) )
289+ }
290+ _ => { }
291+ }
292+
293+ // if expected.size_max.is_none() && actual.size_max.is_some() {
294+ // return Err(LinkingError::incompatible_import_type(import).into());
295+ // }
296+
297+ // if expected.size_max.unwrap_or(0) < actual.size_max.unwrap_or(0) {
298+ // return Err(LinkingError::incompatible_import_type(import).into());
299+ // }
300+
301+ log:: error!( "size_initial: expected: {:?} got: {:?}" , expected. size_initial, actual. size_initial) ;
302+ log:: error!( "size_max: expected: {:?} got: {:?}" , expected. size_max, actual. size_max) ;
303+ // TODO: check limits
304+
305+ Ok ( ( ) )
306+ }
307+
308+ fn compare_memory_types (
309+ import : & Import ,
310+ expected : & MemoryType ,
311+ actual : & MemoryType ,
312+ real_size : Option < usize > ,
313+ ) -> Result < ( ) > {
314+ Self :: compare_types ( import, & expected. arch , & actual. arch ) ?;
315+
316+ if actual. page_count_initial > expected. page_count_initial {
317+ if let Some ( real_size) = real_size {
318+ if actual. page_count_initial > real_size as u64 {
319+ return Err ( LinkingError :: incompatible_import_type ( import) . into ( ) ) ;
320+ }
321+ } else {
322+ return Err ( LinkingError :: incompatible_import_type ( import) . into ( ) ) ;
323+ }
324+ }
325+
326+ match ( expected. page_count_max , actual. page_count_max ) {
327+ ( None , Some ( _) ) => return Err ( LinkingError :: incompatible_import_type ( import) . into ( ) ) ,
328+ ( Some ( expected_max) , Some ( actual_max) ) if actual_max < expected_max => {
329+ return Err ( LinkingError :: incompatible_import_type ( import) . into ( ) )
275330 }
276- . into ( ) ) ;
331+ _ => { }
277332 }
278333
334+ log:: error!( "size_initial: {:?} {:?}" , expected. page_count_initial, actual. page_count_initial) ;
335+ log:: error!( "size_max: {:?} {:?}" , expected. page_count_max, actual. page_count_max) ;
336+
337+ // TODO: check limits
338+
279339 Ok ( ( ) )
280340 }
281341
@@ -304,13 +364,11 @@ impl Imports {
304364 imports. globals . push ( store. add_global ( extern_global. ty , extern_global. val . into ( ) , idx) ?) ;
305365 }
306366 ( Extern :: Table ( extern_table) , ImportKind :: Table ( ty) ) => {
307- Self :: compare_types ( import, & extern_table. ty . element_type , & ty. element_type ) ?;
308- // TODO: do we need to check any limits?
367+ Self :: compare_table_types ( import, & extern_table. ty , & ty) ?;
309368 imports. tables . push ( store. add_table ( extern_table. ty , idx) ?) ;
310369 }
311370 ( Extern :: Memory ( extern_memory) , ImportKind :: Memory ( ty) ) => {
312- Self :: compare_types ( import, & extern_memory. ty . arch , & ty. arch ) ?;
313- // TODO: do we need to check any limits?
371+ Self :: compare_memory_types ( import, & extern_memory. ty , & ty, None ) ?;
314372 imports. memories . push ( store. add_mem ( extern_memory. ty , idx) ?) ;
315373 }
316374 ( Extern :: Function ( extern_func) , ImportKind :: Function ( ty) ) => {
@@ -352,14 +410,16 @@ impl Imports {
352410 }
353411 ( ExternVal :: Table ( table_addr) , ImportKind :: Table ( ty) ) => {
354412 let table = store. get_table ( table_addr as usize ) ?;
355- // TODO: do we need to check any limits?
356- Self :: compare_types ( import, & table. borrow ( ) . kind . element_type , & ty. element_type ) ?;
413+ Self :: compare_table_types ( import, & table. borrow ( ) . kind , & ty) ?;
357414 imports. tables . push ( table_addr) ;
358415 }
359416 ( ExternVal :: Mem ( memory_addr) , ImportKind :: Memory ( ty) ) => {
360417 let mem = store. get_mem ( memory_addr as usize ) ?;
361- // TODO: do we need to check any limits?
362- Self :: compare_types ( import, & mem. borrow ( ) . kind . arch , & ty. arch ) ?;
418+ let ( size, kind) = {
419+ let mem = mem. borrow ( ) ;
420+ ( mem. page_count ( ) , mem. kind . clone ( ) )
421+ } ;
422+ Self :: compare_memory_types ( import, & kind, & ty, Some ( size) ) ?;
363423 imports. memories . push ( memory_addr) ;
364424 }
365425 ( ExternVal :: Func ( func_addr) , ImportKind :: Function ( ty) ) => {
0 commit comments