2017-10-22 22:01:00 -05:00
|
|
|
// 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 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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); },
|
2017-11-26 12:39:16 -06:00
|
|
|
log10: Math.log10,
|
|
|
|
log10f: Math.log10,
|
2017-10-22 22:01:00 -05:00
|
|
|
|
|
|
|
// 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) {
|
2017-11-26 12:39:16 -06:00
|
|
|
return Buffer.byteLength(process.argv[i + 2]);
|
2017-10-22 22:01:00 -05:00
|
|
|
},
|
|
|
|
rust_wasm_args_arg_fill: function(idx, ptr) {
|
|
|
|
let arg = process.argv[idx + 2];
|
|
|
|
let view = new Uint8Array(memory.buffer);
|
2017-11-26 12:39:16 -06:00
|
|
|
Buffer.from(arg).copy(view, ptr);
|
2017-10-22 22:01:00 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
}
|
2017-11-26 12:39:16 -06:00
|
|
|
return Buffer.byteLength(process.env[key]);
|
2017-10-22 22:01:00 -05:00
|
|
|
},
|
|
|
|
rust_wasm_getenv_data: function(a, b, ptr) {
|
|
|
|
let key = copystr(a, b);
|
|
|
|
let value = process.env[key];
|
|
|
|
let view = new Uint8Array(memory.buffer);
|
2017-11-26 12:39:16 -06:00
|
|
|
Buffer.from(value).copy(view, ptr);
|
2017-10-22 22:01:00 -05:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
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);
|