diff --git a/arch/wasm32/wasm.js b/arch/wasm32/wasm.js index 60365390..2211c533 100644 --- a/arch/wasm32/wasm.js +++ b/arch/wasm32/wasm.js @@ -21,15 +21,17 @@ * both as a hobbling libc and a linker/loader, including dynamic linking. */ -var heap_size_bytes; -var heap; -var heap_uint8; +var heap_size_bytes = 16 * 1024 * 1024; +var heap_size_pages = heap_size_bytes / (64 * 1024); +var memory = new WebAssembly.Memory({initial: heap_size_pages, maximum: heap_size_pages}) +var heap = memory.buffer; +var heap_uint8 = new Uint8Array(heap); // Heap access helpers. function charFromHeap(ptr) { return String.fromCharCode(heap_uint8[ptr]); } function stringFromHeap(ptr) { var str = ''; - for (var i = ptr; heap_uint8[i] != 0; ++i) + for (var i = ptr; i < heap_size_bytes && heap_uint8[i] != 0; ++i) str += charFromHeap(i); return str; } @@ -522,9 +524,12 @@ var string = (function() { strchr: function(str, character) { character &= 0xff; var i = 0; - for (; heap_uint8[str + i] != 0; ++i) + for (; heap_uint8[str + i] != 0; ++i) { + if (str + i >= heap_size_bytes) + return 0; if (heap_uint8[str + i] == character) return str + i; + } return character == 0 ? str + i : 0; }, strcspn: NYI('strcspn'), @@ -930,7 +935,7 @@ var syscall = (function() { // Start with the stub implementations. Further module loads may shadow them. var ffi = (function() { - var functions = {env:{}}; + var functions = {env:{memory: memory}}; var libraries = [ musl_hack, // Keep first, overriden later. builtins, ctype, math, runtime, stdio, stdlib, string, unix, @@ -959,9 +964,14 @@ if (arguments[0] == '--dump-ffi-symbols') { ? new Uint8Array(readbuffer(file_path)) : read(file_path, 'binary'); instance = new WebAssembly.Instance(new WebAssembly.Module(buf), ffi) - heap = instance.exports.memory.buffer; - heap_uint8 = new Uint8Array(heap); - heap_size_bytes = heap.byteLength; + // For the application exports its memory, we use that rather than + // the one we created. In this way this code works with modules that + // import or export their memory. + if (instance.exports.memory) { + heap = instance.exports.memory.buffer; + heap_uint8 = new Uint8Array(heap); + heap_size_bytes = heap.byteLength; + } return instance; } @@ -973,12 +983,13 @@ if (arguments[0] == '--dump-ffi-symbols') { for (var i = arguments.length - 1; i > 0; --i) { var path = arguments[i]; modules[i] = load_wasm(path); - for (var f in modules[i]) { + for (var f in modules[i].exports) { // TODO wasm modules don't have hasOwnProperty. They probably should. // The code should look like: // if (modules[i].hasOwnProperty(f) && // modules[i][f] instanceof Function) - ffi[f] = modules[i][f]; + if (modules[i].exports[f] instanceof Function) + ffi['env'][f] = modules[i].exports[f]; } } diff --git a/libc.py b/libc.py index db5a83fb..e5d013be 100755 --- a/libc.py +++ b/libc.py @@ -171,6 +171,7 @@ class AsmCompiler(Compiler): return os.path.basename(src)[:-1] + 'll' # .c -> .ll def binary(self): + max_memory = str(16 * 1024 * 1024) bytecode = change_extension(self.out, '.bc') assembly = os.path.join(self.tmpdir, self.outbase + '.s') check_output([os.path.join(self.clang_dir, 'llvm-link'), @@ -180,7 +181,8 @@ class AsmCompiler(Compiler): bytecode, '-o', assembly], cwd=self.tmpdir) check_output([os.path.join(self.binaryen_dir, 's2wasm'), - assembly, '--ignore-unknown', '-o', self.out], + assembly, '--ignore-unknown', '-o', self.out, + '--import-memory', '-m', max_memory], cwd=self.tmpdir) if self.sexpr_wasm: