Skip to content

Commit 3140ba2

Browse files
authored
feat(compiler): Allow importing a memory (#1661)
* feat: Allow importing a memory * add import_memory linking test
1 parent b13b062 commit 3140ba2

File tree

5 files changed

+45
-0
lines changed

5 files changed

+45
-0
lines changed

cli/bin/grain.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ class GrainCommand extends commander.Command {
118118
"maximum number of WebAssembly memory pages",
119119
num
120120
);
121+
cmd.forwardOption("--import-memory", "import the memory from `env.memory`");
121122
cmd.forwardOption(
122123
"--compilation-mode <mode>",
123124
"compilation mode (advanced use only)"

compiler/src/linking/link.re

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,10 @@ let link_all = (linked_mod, dependencies, signature) => {
530530
-1,
531531
Type.funcref,
532532
);
533+
534+
if (Config.import_memory^) {
535+
Import.add_memory_import(linked_mod, "memory", "env", "memory", false);
536+
};
533537
let (initial_memory, maximum_memory) =
534538
switch (Config.initial_memory_pages^, Config.maximum_memory_pages^) {
535539
| (initial_memory, Some(maximum_memory)) => (

compiler/src/utils/config.re

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,13 @@ let maximum_memory_pages =
445445
None,
446446
);
447447

448+
let import_memory =
449+
toggle_flag(
450+
~names=["import-memory"],
451+
~doc="Import the memory from `env.memory`",
452+
false,
453+
);
454+
448455
let compilation_mode =
449456
opt(
450457
~names=["compilation-mode"],

compiler/src/utils/config.rei

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ let initial_memory_pages: ref(int);
7878

7979
let maximum_memory_pages: ref(option(int));
8080

81+
/** Import the memory from `env.memory` */
82+
83+
let import_memory: ref(bool);
84+
8185
/** Compilation mode to use when compiling */
8286

8387
let compilation_mode: ref(option(string));

compiler/test/suites/linking.re

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ describe("linking", ({test, testSkip}) => {
4949
);
5050

5151
let tuple_equal = ((a1, a2), (b1, b2)) => a1 == b1 && a2 == b2;
52+
let triple_equal = ((a1, a2, a3), (b1, b2, b3)) =>
53+
a1 == b1 && a2 == b2 && a3 == b3;
5254
test("no_start_section", ({expect}) => {
5355
let name = "no_start_section";
5456
let outfile = wasmfile(name);
@@ -119,4 +121,31 @@ describe("linking", ({test, testSkip}) => {
119121
(WasmFunction, "_start"),
120122
);
121123
});
124+
125+
test("import_memory", ({expect}) => {
126+
let name = "import_memory";
127+
let outfile = wasmfile(name);
128+
ignore @@
129+
compile(
130+
~config_fn=() => {Grain_utils.Config.import_memory := true},
131+
name,
132+
{|module Test; print("Hello, world!")|},
133+
);
134+
let ic = open_in_bin(outfile);
135+
let sections = Grain_utils.Wasm_utils.get_wasm_sections(ic);
136+
close_in(ic);
137+
let imports =
138+
List.find_map(
139+
(sec: Grain_utils.Wasm_utils.wasm_bin_section) =>
140+
switch (sec) {
141+
| {sec_type: Import(imports)} => Some(imports)
142+
| _ => None
143+
},
144+
sections,
145+
);
146+
expect.list(Option.get(imports)).toContainEqual(
147+
~equals=triple_equal,
148+
(WasmMemory, "env", "memory"),
149+
);
150+
});
122151
});

0 commit comments

Comments
 (0)