@@ -43,6 +43,7 @@ pub struct Context<'a> {
43
43
pub exported_classes : HashMap < String , ExportedClass > ,
44
44
pub function_table_needed : bool ,
45
45
pub interpreter : & ' a mut Interpreter ,
46
+ pub memory_init : Option < ResizableLimits > ,
46
47
}
47
48
48
49
#[ derive( Default ) ]
@@ -377,6 +378,7 @@ impl<'a> Context<'a> {
377
378
) )
378
379
} ) ?;
379
380
381
+ self . create_memory_export ( ) ;
380
382
self . unexport_unused_internal_exports ( ) ;
381
383
self . gc ( ) ?;
382
384
@@ -685,6 +687,20 @@ impl<'a> Context<'a> {
685
687
}
686
688
}
687
689
690
+ fn create_memory_export ( & mut self ) {
691
+ let limits = match self . memory_init . clone ( ) {
692
+ Some ( limits) => limits,
693
+ None => return ,
694
+ } ;
695
+ let mut initializer = String :: from ( "new WebAssembly.Memory({" ) ;
696
+ initializer. push_str ( & format ! ( "initial:{}" , limits. initial( ) ) ) ;
697
+ if let Some ( max) = limits. maximum ( ) {
698
+ initializer. push_str ( & format ! ( ",maximum:{}" , max) ) ;
699
+ }
700
+ initializer. push_str ( "})" ) ;
701
+ self . export ( "memory" , & initializer, None ) ;
702
+ }
703
+
688
704
fn rewrite_imports ( & mut self , module_name : & str ) {
689
705
for ( name, contents) in self . _rewrite_imports ( module_name) {
690
706
self . export ( & name, & contents, None ) ;
@@ -715,6 +731,15 @@ impl<'a> Context<'a> {
715
731
continue ;
716
732
}
717
733
734
+ // If memory is imported we'll have exported it from the shim module
735
+ // so let's import it from there.
736
+ if import. field ( ) == "memory" {
737
+ import. module_mut ( ) . truncate ( 0 ) ;
738
+ import. module_mut ( ) . push_str ( "./" ) ;
739
+ import. module_mut ( ) . push_str ( module_name) ;
740
+ continue
741
+ }
742
+
718
743
let renamed_import = format ! ( "__wbindgen_{}" , import. field( ) ) ;
719
744
let mut bind_math = |expr : & str | {
720
745
math_imports. push ( ( renamed_import. clone ( ) , format ! ( "function{}" , expr) ) ) ;
@@ -1333,18 +1358,20 @@ impl<'a> Context<'a> {
1333
1358
if !self . exposed_globals . insert ( name) {
1334
1359
return ;
1335
1360
}
1361
+ let mem = self . memory ( ) ;
1336
1362
self . global ( & format ! (
1337
1363
"
1338
1364
let cache{name} = null;
1339
1365
function {name}() {{
1340
- if (cache{name} === null || cache{name}.buffer !== wasm.memory .buffer) {{
1341
- cache{name} = new {js}(wasm.memory .buffer);
1366
+ if (cache{name} === null || cache{name}.buffer !== {mem} .buffer) {{
1367
+ cache{name} = new {js}({mem} .buffer);
1342
1368
}}
1343
1369
return cache{name};
1344
1370
}}
1345
1371
" ,
1346
1372
name = name,
1347
1373
js = js,
1374
+ mem = mem,
1348
1375
) ) ;
1349
1376
}
1350
1377
@@ -1690,6 +1717,29 @@ impl<'a> Context<'a> {
1690
1717
fn use_node_require ( & self ) -> bool {
1691
1718
self . config . nodejs && !self . config . nodejs_experimental_modules
1692
1719
}
1720
+
1721
+ fn memory ( & mut self ) -> & ' static str {
1722
+ if self . module . memory_section ( ) . is_some ( ) {
1723
+ return "wasm.memory" ;
1724
+ }
1725
+
1726
+ let ( entry, mem) = self . module . import_section ( )
1727
+ . expect ( "must import memory" )
1728
+ . entries ( )
1729
+ . iter ( )
1730
+ . filter_map ( |i| {
1731
+ match i. external ( ) {
1732
+ External :: Memory ( m) => Some ( ( i, m) ) ,
1733
+ _ => None ,
1734
+ }
1735
+ } )
1736
+ . next ( )
1737
+ . expect ( "must import memory" ) ;
1738
+ assert_eq ! ( entry. module( ) , "env" ) ;
1739
+ assert_eq ! ( entry. field( ) , "memory" ) ;
1740
+ self . memory_init = Some ( mem. limits ( ) . clone ( ) ) ;
1741
+ "memory"
1742
+ }
1693
1743
}
1694
1744
1695
1745
impl < ' a , ' b > SubContext < ' a , ' b > {
0 commit comments