]> git.proxmox.com Git - rustc.git/blob - src/etc/wasm32-shim.js
New upstream version 1.24.1+dfsg1
[rustc.git] / src / etc / wasm32-shim.js
1 // Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 // This is a small "shim" program which is used when wasm32 unit tests are run
12 // in this repository. This program is intended to be run in node.js and will
13 // load a wasm module into memory, instantiate it with a set of imports, and
14 // then run it.
15 //
16 // There's a bunch of helper functions defined here in `imports.env`, but note
17 // that most of them aren't actually needed to execute most programs. Many of
18 // these are just intended for completeness or debugging. Hopefully over time
19 // nothing here is needed for completeness.
20
21 const fs = require('fs');
22 const process = require('process');
23 const buffer = fs.readFileSync(process.argv[2]);
24
25 Error.stackTraceLimit = 20;
26
27 let m = new WebAssembly.Module(buffer);
28
29 let memory = null;
30
31 function copystr(a, b) {
32 if (memory === null) {
33 return null
34 }
35 let view = new Uint8Array(memory.buffer).slice(a, a + b);
36 return String.fromCharCode.apply(null, view);
37 }
38
39 let imports = {};
40 imports.env = {
41 // These are generated by LLVM itself for various intrinsic calls. Hopefully
42 // one day this is not necessary and something will automatically do this.
43 fmod: function(x, y) { return x % y; },
44 exp2: function(x) { return Math.pow(2, x); },
45 exp2f: function(x) { return Math.pow(2, x); },
46 ldexp: function(x, y) { return x * Math.pow(2, y); },
47 ldexpf: function(x, y) { return x * Math.pow(2, y); },
48 log10: Math.log10,
49 log10f: Math.log10,
50
51 // These are called in src/libstd/sys/wasm/stdio.rs and are used when
52 // debugging is enabled.
53 rust_wasm_write_stdout: function(a, b) {
54 let s = copystr(a, b);
55 if (s !== null) {
56 process.stdout.write(s);
57 }
58 },
59 rust_wasm_write_stderr: function(a, b) {
60 let s = copystr(a, b);
61 if (s !== null) {
62 process.stderr.write(s);
63 }
64 },
65
66 // These are called in src/libstd/sys/wasm/args.rs and are used when
67 // debugging is enabled.
68 rust_wasm_args_count: function() {
69 if (memory === null)
70 return 0;
71 return process.argv.length - 2;
72 },
73 rust_wasm_args_arg_size: function(i) {
74 return Buffer.byteLength(process.argv[i + 2]);
75 },
76 rust_wasm_args_arg_fill: function(idx, ptr) {
77 let arg = process.argv[idx + 2];
78 let view = new Uint8Array(memory.buffer);
79 Buffer.from(arg).copy(view, ptr);
80 },
81
82 // These are called in src/libstd/sys/wasm/os.rs and are used when
83 // debugging is enabled.
84 rust_wasm_getenv_len: function(a, b) {
85 let key = copystr(a, b);
86 if (key === null) {
87 return -1;
88 }
89 if (!(key in process.env)) {
90 return -1;
91 }
92 return Buffer.byteLength(process.env[key]);
93 },
94 rust_wasm_getenv_data: function(a, b, ptr) {
95 let key = copystr(a, b);
96 let value = process.env[key];
97 let view = new Uint8Array(memory.buffer);
98 Buffer.from(value).copy(view, ptr);
99 },
100 };
101
102 let module_imports = WebAssembly.Module.imports(m);
103
104 for (var i = 0; i < module_imports.length; i++) {
105 let imp = module_imports[i];
106 if (imp.module != 'env') {
107 continue
108 }
109 if (imp.name == 'memory' && imp.kind == 'memory') {
110 memory = new WebAssembly.Memory({initial: 20});
111 imports.env.memory = memory;
112 }
113 }
114
115 let instance = new WebAssembly.Instance(m, imports);