// Copyright 2017 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. // This is a small "shim" program which is used when wasm32 unit tests are run // in this repository. This program is intended to be run in node.js and will // load a wasm module into memory, instantiate it with a set of imports, and // then run it. // // There's a bunch of helper functions defined here in `imports.env`, but note // that most of them aren't actually needed to execute most programs. Many of // these are just intended for completeness or debugging. Hopefully over time // nothing here is needed for completeness. const fs = require('fs'); const process = require('process'); const buffer = fs.readFileSync(process.argv[2]); Error.stackTraceLimit = 20; let m = new WebAssembly.Module(buffer); let memory = null; function copystr(a, b) { if (memory === null) { return null } let view = new Uint8Array(memory.buffer).slice(a, a + b); return String.fromCharCode.apply(null, view); } let imports = {}; imports.env = { // These are generated by LLVM itself for various intrinsic calls. Hopefully // one day this is not necessary and something will automatically do this. fmod: function(x, y) { return x % y; }, exp2: function(x) { return Math.pow(2, x); }, exp2f: function(x) { return Math.pow(2, x); }, ldexp: function(x, y) { return x * Math.pow(2, y); }, ldexpf: function(x, y) { return x * Math.pow(2, y); }, log10: Math.log10, log10f: Math.log10, // These are called in src/libstd/sys/wasm/stdio.rs and are used when // debugging is enabled. rust_wasm_write_stdout: function(a, b) { let s = copystr(a, b); if (s !== null) { process.stdout.write(s); } }, rust_wasm_write_stderr: function(a, b) { let s = copystr(a, b); if (s !== null) { process.stderr.write(s); } }, // These are called in src/libstd/sys/wasm/args.rs and are used when // debugging is enabled. rust_wasm_args_count: function() { if (memory === null) return 0; return process.argv.length - 2; }, rust_wasm_args_arg_size: function(i) { return Buffer.byteLength(process.argv[i + 2]); }, rust_wasm_args_arg_fill: function(idx, ptr) { let arg = process.argv[idx + 2]; let view = new Uint8Array(memory.buffer); Buffer.from(arg).copy(view, ptr); }, // These are called in src/libstd/sys/wasm/os.rs and are used when // debugging is enabled. rust_wasm_getenv_len: function(a, b) { let key = copystr(a, b); if (key === null) { return -1; } if (!(key in process.env)) { return -1; } return Buffer.byteLength(process.env[key]); }, rust_wasm_getenv_data: function(a, b, ptr) { let key = copystr(a, b); let value = process.env[key]; let view = new Uint8Array(memory.buffer); Buffer.from(value).copy(view, ptr); }, }; let module_imports = WebAssembly.Module.imports(m); for (var i = 0; i < module_imports.length; i++) { let imp = module_imports[i]; if (imp.module != 'env') { continue } if (imp.name == 'memory' && imp.kind == 'memory') { memory = new WebAssembly.Memory({initial: 20}); imports.env.memory = memory; } } let instance = new WebAssembly.Instance(m, imports);