]> git.proxmox.com Git - rustc.git/blame - src/stdarch/crates/stdarch-test/src/wasm.rs
New upstream version 1.44.1+dfsg1
[rustc.git] / src / stdarch / crates / stdarch-test / src / wasm.rs
CommitLineData
0bf4aa26
XL
1//! Disassembly calling function for `wasm32` targets.
2use wasm_bindgen::prelude::*;
3
416331ca
XL
4use crate::Function;
5use std::collections::HashSet;
0bf4aa26
XL
6
7#[wasm_bindgen(module = "child_process")]
8extern "C" {
416331ca
XL
9 #[wasm_bindgen(js_name = execFileSync)]
10 fn exec_file_sync(cmd: &str, args: &js_sys::Array, opts: &js_sys::Object) -> Buffer;
0bf4aa26
XL
11}
12
13#[wasm_bindgen(module = "buffer")]
14extern "C" {
15 type Buffer;
16 #[wasm_bindgen(method, js_name = toString)]
17 fn to_string(this: &Buffer) -> String;
18}
19
20#[wasm_bindgen]
21extern "C" {
22 #[wasm_bindgen(js_namespace = require)]
23 fn resolve(module: &str) -> String;
24 #[wasm_bindgen(js_namespace = console, js_name = log)]
0731742a 25 pub fn js_console_log(s: &str);
0bf4aa26
XL
26}
27
416331ca 28pub(crate) fn disassemble_myself() -> HashSet<Function> {
0bf4aa26
XL
29 use std::path::Path;
30 ::console_error_panic_hook::set_once();
31 // Our wasm module in the wasm-bindgen test harness is called
32 // "wasm-bindgen-test_bg". When running in node this is actually a shim JS
33 // file. Ask node where that JS file is, and then we use that with a wasm
34 // extension to find the wasm file itself.
ba9703b0
XL
35 let js_shim = resolve("wasm-bindgen-test");
36 let js_shim = Path::new(&js_shim).with_file_name("wasm-bindgen-test_bg.wasm");
0bf4aa26
XL
37
38 // Execute `wasm2wat` synchronously, waiting for and capturing all of its
416331ca
XL
39 // output. Note that we pass in a custom `maxBuffer` parameter because we're
40 // generating a ton of output that needs to be buffered.
41 let args = js_sys::Array::new();
42 args.push(&js_shim.display().to_string().into());
43 args.push(&"--enable-simd".into());
44 let opts = js_sys::Object::new();
74b04a01 45 js_sys::Reflect::set(&opts, &"maxBuffer".into(), &(200 * 1024 * 1024).into()).unwrap();
416331ca 46 let output = exec_file_sync("wasm2wat", &args, &opts).to_string();
0bf4aa26 47
416331ca 48 let mut ret: HashSet<Function> = HashSet::new();
0bf4aa26
XL
49 let mut lines = output.lines().map(|s| s.trim());
50 while let Some(line) = lines.next() {
0bf4aa26
XL
51 // If this isn't a function, we don't care about it.
52 if !line.starts_with("(func ") {
53 continue;
54 }
55
56 let mut function = Function {
416331ca 57 name: String::new(),
0bf4aa26 58 instrs: Vec::new(),
0bf4aa26
XL
59 };
60
61 // Empty functions will end in `))` so there's nothing to do, otherwise
62 // we'll have a bunch of following lines which are instructions.
63 //
64 // Lines that have an imbalanced `)` mark the end of a function.
65 if !line.ends_with("))") {
66 while let Some(line) = lines.next() {
416331ca 67 function.instrs.push(line.to_string());
0bf4aa26
XL
68 if !line.starts_with("(") && line.ends_with(")") {
69 break;
70 }
71 }
72 }
0bf4aa26
XL
73 // The second element here split on whitespace should be the name of
74 // the function, skipping the type/params/results
416331ca
XL
75 function.name = line.split_whitespace().nth(1).unwrap().to_string();
76 if function.name.starts_with("$") {
77 function.name = function.name[1..].to_string()
78 }
79
80 if !function.name.contains("stdarch_test_shim") {
81 continue;
82 }
83
84 assert!(ret.insert(function));
0bf4aa26
XL
85 }
86 return ret;
87}