@@ -4,7 +4,7 @@ use core::fmt::Debug;
4
4
5
5
use crate :: {
6
6
func:: { FromWasmValueTuple , IntoWasmValueTuple , ValTypesFromTuple } ,
7
- Result ,
7
+ LinkingError , Result ,
8
8
} ;
9
9
use alloc:: {
10
10
collections:: BTreeMap ,
@@ -263,19 +263,79 @@ impl Imports {
263
263
None
264
264
}
265
265
266
- fn compare_types < T > ( import : & Import , expected : & T , actual : & T ) -> Result < ( ) >
266
+ fn compare_types < T > ( import : & Import , actual : & T , expected : & T ) -> Result < ( ) >
267
267
where
268
268
T : Debug + PartialEq ,
269
269
{
270
270
if expected != actual {
271
271
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 ( ) )
275
330
}
276
- . into ( ) ) ;
331
+ _ => { }
277
332
}
278
333
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
+
279
339
Ok ( ( ) )
280
340
}
281
341
@@ -304,13 +364,11 @@ impl Imports {
304
364
imports. globals . push ( store. add_global ( extern_global. ty , extern_global. val . into ( ) , idx) ?) ;
305
365
}
306
366
( 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) ?;
309
368
imports. tables . push ( store. add_table ( extern_table. ty , idx) ?) ;
310
369
}
311
370
( 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 ) ?;
314
372
imports. memories . push ( store. add_mem ( extern_memory. ty , idx) ?) ;
315
373
}
316
374
( Extern :: Function ( extern_func) , ImportKind :: Function ( ty) ) => {
@@ -352,14 +410,16 @@ impl Imports {
352
410
}
353
411
( ExternVal :: Table ( table_addr) , ImportKind :: Table ( ty) ) => {
354
412
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) ?;
357
414
imports. tables . push ( table_addr) ;
358
415
}
359
416
( ExternVal :: Mem ( memory_addr) , ImportKind :: Memory ( ty) ) => {
360
417
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) ) ?;
363
423
imports. memories . push ( memory_addr) ;
364
424
}
365
425
( ExternVal :: Func ( func_addr) , ImportKind :: Function ( ty) ) => {
0 commit comments