Skip to content

Commit 856892d

Browse files
authored
Merge pull request #750 from alexcrichton/import-memory
Add support for modules importing memory
2 parents 0cd04ca + 335c0b1 commit 856892d

File tree

3 files changed

+53
-15
lines changed

3 files changed

+53
-15
lines changed

crates/cli-support/src/js/mod.rs

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ pub struct Context<'a> {
4343
pub exported_classes: HashMap<String, ExportedClass>,
4444
pub function_table_needed: bool,
4545
pub interpreter: &'a mut Interpreter,
46+
pub memory_init: Option<ResizableLimits>,
4647
}
4748

4849
#[derive(Default)]
@@ -377,6 +378,7 @@ impl<'a> Context<'a> {
377378
))
378379
})?;
379380

381+
self.create_memory_export();
380382
self.unexport_unused_internal_exports();
381383
self.gc()?;
382384

@@ -685,6 +687,20 @@ impl<'a> Context<'a> {
685687
}
686688
}
687689

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+
688704
fn rewrite_imports(&mut self, module_name: &str) {
689705
for (name, contents) in self._rewrite_imports(module_name) {
690706
self.export(&name, &contents, None);
@@ -715,6 +731,15 @@ impl<'a> Context<'a> {
715731
continue;
716732
}
717733

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+
718743
let renamed_import = format!("__wbindgen_{}", import.field());
719744
let mut bind_math = |expr: &str| {
720745
math_imports.push((renamed_import.clone(), format!("function{}", expr)));
@@ -1333,18 +1358,20 @@ impl<'a> Context<'a> {
13331358
if !self.exposed_globals.insert(name) {
13341359
return;
13351360
}
1361+
let mem = self.memory();
13361362
self.global(&format!(
13371363
"
13381364
let cache{name} = null;
13391365
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);
13421368
}}
13431369
return cache{name};
13441370
}}
13451371
",
13461372
name = name,
13471373
js = js,
1374+
mem = mem,
13481375
));
13491376
}
13501377

@@ -1690,6 +1717,29 @@ impl<'a> Context<'a> {
16901717
fn use_node_require(&self) -> bool {
16911718
self.config.nodejs && !self.config.nodejs_experimental_modules
16921719
}
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+
}
16931743
}
16941744

16951745
impl<'a, 'b> SubContext<'a, 'b> {

crates/cli-support/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ impl Bindgen {
200200
module: &mut module,
201201
function_table_needed: false,
202202
interpreter: &mut instance,
203+
memory_init: None,
203204
};
204205
for program in programs.iter() {
205206
js::SubContext {

crates/cli-support/src/wasm2es6js.rs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -150,19 +150,6 @@ impl Output {
150150
if let Some(i) = self.module.import_section() {
151151
let mut set = HashSet::new();
152152
for entry in i.entries() {
153-
match *entry.external() {
154-
External::Function(_) => {}
155-
External::Table(_) => {
156-
bail!("wasm imports a table which isn't supported yet");
157-
}
158-
External::Memory(_) => {
159-
bail!("wasm imports memory which isn't supported yet");
160-
}
161-
External::Global(_) => {
162-
bail!("wasm imports globals which aren't supported yet");
163-
}
164-
}
165-
166153
if !set.insert(entry.module()) {
167154
continue;
168155
}

0 commit comments

Comments
 (0)