Skip to content

Commit f6271ee

Browse files
author
Jakub Konka
committed
Draft out js-polyfill using wasi-common crate
This commit drafts out js-polyfill using `wasi-common` crate.
1 parent 12d831f commit f6271ee

File tree

8 files changed

+931
-0
lines changed

8 files changed

+931
-0
lines changed

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ members = [
5454
"crates/misc/rust",
5555
"crates/misc/py",
5656
]
57+
exclude = [
58+
"crates/wasi-common/js-polyfill",
59+
]
5760

5861
[features]
5962
lightbeam = [
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[build]
2+
target = "wasm32-unknown-emscripten"
3+
rustflags = [
4+
"-C",
5+
"link-args=--js-library assets/load-files.js --shell-file assets/shell.html --pre-js assets/wasi.js -s EXPORTED_FUNCTIONS=['_main','_get_wasi_context','_handleFiles','_old_wasi_common_args_get','_old_wasi_common_args_sizes_get','_old_wasi_common_clock_res_get','_old_wasi_common_clock_time_get','_old_wasi_common_environ_get','_old_wasi_common_environ_sizes_get','_old_wasi_common_fd_advise','_old_wasi_common_fd_allocate','_old_wasi_common_fd_close','_old_wasi_common_fd_datasync','_old_wasi_common_fd_fdstat_get','_old_wasi_common_fd_fdstat_set_flags','_old_wasi_common_fd_fdstat_set_rights','_old_wasi_common_fd_filestat_get','_old_wasi_common_fd_filestat_set_size','_old_wasi_common_fd_filestat_set_times','_old_wasi_common_fd_pread','_old_wasi_common_fd_prestat_dir_name','_old_wasi_common_fd_prestat_get','_old_wasi_common_fd_pwrite','_old_wasi_common_fd_read','_old_wasi_common_fd_readdir','_old_wasi_common_fd_renumber','_old_wasi_common_fd_seek','_old_wasi_common_fd_sync','_old_wasi_common_fd_tell','_old_wasi_common_fd_write','_old_wasi_common_path_create_directory','_old_wasi_common_path_filestat_get','_old_wasi_common_path_filestat_set_times','_old_wasi_common_path_link','_old_wasi_common_path_open','_old_wasi_common_path_readlink','_old_wasi_common_path_remove_directory','_old_wasi_common_path_rename','_old_wasi_common_path_symlink','_old_wasi_common_path_unlink_file','_old_wasi_common_poll_oneoff','_old_wasi_common_proc_exit','_old_wasi_common_proc_raise','_old_wasi_common_random_get','_old_wasi_common_sched_yield','_old_wasi_common_sock_recv','_old_wasi_common_sock_send','_old_wasi_common_sock_shutdown'] -o assets/polyfill.html"
6+
]
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "polyfill"
3+
version = "0.1.0"
4+
authors = ["The Wasmtime Project Developers"]
5+
edition = "2018"
6+
7+
[dependencies]
8+
wasi-common = { path = ".." }
Loading
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
mergeInto(LibraryManager.library, {
2+
loadFiles: function() {
3+
const imports = { wasi_unstable: WASIPolyfill };
4+
let file = document.getElementById('input').files[0];
5+
let file_with_mime_type = file.slice(0, file.size, 'application/wasm');
6+
let response = new Response(file_with_mime_type);
7+
wasi_instantiateStreaming(response, imports)
8+
.then(obj => {
9+
setInstance(obj.instance);
10+
try {
11+
obj.instance.exports._start();
12+
} catch (e) {
13+
if (e instanceof WASIExit) {
14+
handleWASIExit(e);
15+
} else {
16+
}
17+
}
18+
})
19+
.catch(error => {
20+
console.log('error! ' + error);
21+
});
22+
},
23+
});
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<!doctype html>
2+
<!-- This file is derived from src/shell_minimal.html in Emscripten. -->
3+
<html lang="en-us">
4+
<head>
5+
<meta charset="utf-8">
6+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
7+
<title>WASI Web Polyfill</title>
8+
<style>
9+
.wasi { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
10+
textarea.wasi { font-family: monospace; width: 80%; }
11+
div.wasi { text-align: center; }
12+
div.wasi_border { border: 1px solid black; }
13+
</style>
14+
</head>
15+
<body>
16+
<figure style="overflow:visible;" id="spinner"><div class="spinner"></div><center style="margin-top:0.5em"><strong>WASI</strong></center></figure>
17+
<div class="wasi" id="status">Downloading...</div>
18+
<div class="wasi">
19+
<progress value="0" max="100" id="progress" hidden=1></progress>
20+
</div>
21+
<img class="wasi" src="WASI-small.png" width="200" height="200" border="0" alt="WASI logo">
22+
<input class="wasi" type="file" id="input" onchange="_handleFiles(this.files)">
23+
<hr>
24+
<textarea class="wasi" id="output" rows="8"></textarea>
25+
<script type='text/javascript'>
26+
var statusElement = document.getElementById('status');
27+
var progressElement = document.getElementById('progress');
28+
var spinnerElement = document.getElementById('spinner');
29+
30+
var Module = {
31+
preRun: [],
32+
postRun: [],
33+
print: (function() {
34+
var element = document.getElementById('output');
35+
if (element) element.value = ''; // clear browser cache
36+
return function(text) {
37+
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
38+
console.log(text);
39+
if (element) {
40+
element.value += text + "\n";
41+
element.scrollTop = element.scrollHeight; // focus on bottom
42+
}
43+
};
44+
})(),
45+
printErr: function(text) {
46+
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
47+
console.error(text);
48+
},
49+
setStatus: function(text) {
50+
if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' };
51+
if (text === Module.setStatus.last.text) return;
52+
var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
53+
var now = Date.now();
54+
if (m && now - Module.setStatus.last.time < 30) return; // if this is a progress update, skip it if too soon
55+
Module.setStatus.last.time = now;
56+
Module.setStatus.last.text = text;
57+
if (m) {
58+
text = m[1];
59+
progressElement.value = parseInt(m[2])*100;
60+
progressElement.max = parseInt(m[4])*100;
61+
progressElement.hidden = false;
62+
spinnerElement.hidden = false;
63+
} else {
64+
progressElement.value = null;
65+
progressElement.max = null;
66+
progressElement.hidden = true;
67+
if (!text) spinnerElement.hidden = true;
68+
}
69+
statusElement.innerHTML = text;
70+
},
71+
totalDependencies: 0,
72+
monitorRunDependencies: function(left) {
73+
this.totalDependencies = Math.max(this.totalDependencies, left);
74+
Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
75+
}
76+
};
77+
Module.setStatus('Downloading...');
78+
window.onerror = function() {
79+
Module.setStatus('Exception thrown, see JavaScript console');
80+
spinnerElement.style.display = 'none';
81+
Module.setStatus = function(text) {
82+
if (text) Module.printErr('[post-exception status] ' + text);
83+
};
84+
};
85+
</script>
86+
{{{ SCRIPT }}}
87+
</body>
88+
</html>

0 commit comments

Comments
 (0)