]>
git.proxmox.com Git - rustc.git/blob - 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.
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.
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
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.
21 const fs
= require('fs');
22 const process
= require('process');
23 const buffer
= fs
.readFileSync(process
.argv
[2]);
25 Error
.stackTraceLimit
= 20;
27 let m
= new WebAssembly
.Module(buffer
);
31 function viewstruct(data
, fields
) {
32 return new Uint32Array(memory
.buffer
).subarray(data
/4, data/4 + fields
);
35 function copystr(a
, b
) {
36 let view
= new Uint8Array(memory
.buffer
).subarray(a
, a
+ b
);
37 return String
.fromCharCode
.apply(null, view
);
40 function syscall_write([fd
, ptr
, len
]) {
41 let s
= copystr(ptr
, len
);
43 case 1: process
.stdout
.write(s
); break;
44 case 2: process
.stderr
.write(s
); break;
48 function syscall_exit([code
]) {
52 function syscall_args(params
) {
53 let [ptr
, len
] = params
;
55 // Calculate total required buffer size
57 for (let i
= 2; i
< process
.argv
.length
; ++i
) {
58 totalLen
+= Buffer
.byteLength(process
.argv
[i
]) + 1;
60 if (totalLen
< 0) { totalLen
= 0; }
63 // If buffer is large enough, copy data
64 if (len
>= totalLen
) {
65 let view
= new Uint8Array(memory
.buffer
);
66 for (let i
= 2; i
< process
.argv
.length
; ++i
) {
67 let value
= process
.argv
[i
];
68 Buffer
.from(value
).copy(view
, ptr
);
69 ptr
+= Buffer
.byteLength(process
.argv
[i
]) + 1;
74 function syscall_getenv(params
) {
75 let [keyPtr
, keyLen
, valuePtr
, valueLen
] = params
;
77 let key
= copystr(keyPtr
, keyLen
);
78 let value
= process
.env
[key
];
81 params
[4] = 0xFFFFFFFF;
83 let view
= new Uint8Array(memory
.buffer
);
84 let totalLen
= Buffer
.byteLength(value
);
86 if (valueLen
>= totalLen
) {
87 Buffer
.from(value
).copy(view
, valuePtr
);
92 function syscall_time(params
) {
94 let secs
= Math
.floor(t
/ 1000);
95 let millis
= t
% 1000;
96 params
[1] = Math
.floor(secs
/ 0x100000000);
97 params
[2] = secs
% 0x100000000;
98 params
[3] = Math
.floor(millis
* 1000000);
103 // These are generated by LLVM itself for various intrinsic calls. Hopefully
104 // one day this is not necessary and something will automatically do this.
105 fmod: function(x
, y
) { return x
% y
; },
106 exp2: function(x
) { return Math
.pow(2, x
); },
107 exp2f: function(x
) { return Math
.pow(2, x
); },
108 ldexp: function(x
, y
) { return x
* Math
.pow(2, y
); },
109 ldexpf: function(x
, y
) { return x
* Math
.pow(2, y
); },
119 rust_wasm_syscall: function(index
, data
) {
121 case 1: syscall_write(viewstruct(data
, 3)); return true;
122 case 2: syscall_exit(viewstruct(data
, 1)); return true;
123 case 3: syscall_args(viewstruct(data
, 3)); return true;
124 case 4: syscall_getenv(viewstruct(data
, 5)); return true;
125 case 6: syscall_time(viewstruct(data
, 4)); return true;
127 console
.log("Unsupported syscall: " + index
);
133 let instance
= new WebAssembly
.Instance(m
, imports
);
134 memory
= instance
.exports
.memory
;
136 instance
.exports
.main();