Remove the polyfill from the master branch.
The polyfill now lives on the polyfill branch. Add a README.md file pointing to the new location.
This commit is contained in:
2
wasmtime-wasi/js-polyfill/README.md
Normal file
2
wasmtime-wasi/js-polyfill/README.md
Normal file
@@ -0,0 +1,2 @@
|
||||
For the current polyfill sources, please checkout this same directory in
|
||||
[the polyfill branch](https://github.com/CraneStation/wasmtime/tree/polyfill/).
|
||||
@@ -1,18 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
EMCC=emcc
|
||||
|
||||
# TODO: Remove the clang include once Emscripten supports <stdatomic.h>
|
||||
|
||||
"$EMCC" ../sandboxed-system-primitives/src/*.c \
|
||||
-DWASMTIME_SSP_WASI_API \
|
||||
-DWASMTIME_SSP_STATIC_CURFDS \
|
||||
-I../sandboxed-system-primitives/include \
|
||||
-Iclang \
|
||||
--shell-file shell.html \
|
||||
polyfill.c \
|
||||
-s WARN_ON_UNDEFINED_SYMBOLS=0 \
|
||||
-s EXPORTED_FUNCTIONS="['_main', '_handleFiles', '___wasi_args_get', '___wasi_args_sizes_get', '___wasi_clock_res_get', '___wasi_clock_time_get', '___wasi_environ_get', '___wasi_environ_sizes_get', '___wasi_fd_prestat_get', '___wasi_fd_prestat_dir_name', '___wasi_fd_close', '___wasi_fd_datasync', '___wasi_fd_pread', '___wasi_fd_pwrite', '___wasi_fd_read', '___wasi_fd_renumber', '___wasi_fd_seek', '___wasi_fd_tell', '___wasi_fd_fdstat_get', '___wasi_fd_fdstat_set_flags', '___wasi_fd_fdstat_set_rights', '___wasi_fd_sync', '___wasi_fd_write', '___wasi_fd_advise', '___wasi_fd_allocate', '___wasi_path_create_directory', '___wasi_path_link', '___wasi_path_open', '___wasi_fd_readdir', '___wasi_path_readlink', '___wasi_path_rename', '___wasi_fd_filestat_get', '___wasi_fd_filestat_set_times', '___wasi_fd_filestat_set_size', '___wasi_path_filestat_get', '___wasi_path_filestat_set_times', '___wasi_path_symlink', '___wasi_path_unlink_file', '___wasi_path_remove_directory', '___wasi_poll_oneoff', '___wasi_proc_exit', '___wasi_proc_raise', '___wasi_random_get', '___wasi_sched_yield', '___wasi_sock_recv', '___wasi_sock_send', '___wasi_sock_shutdown']" \
|
||||
--pre-js wasi.js \
|
||||
-o polyfill.html
|
||||
@@ -1,190 +0,0 @@
|
||||
/*===---- stdatomic.h - Standard header for atomic types and operations -----===
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*===-----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#ifndef __CLANG_STDATOMIC_H
|
||||
#define __CLANG_STDATOMIC_H
|
||||
|
||||
/* If we're hosted, fall back to the system's stdatomic.h. FreeBSD, for
|
||||
* example, already has a Clang-compatible stdatomic.h header.
|
||||
*/
|
||||
#if __STDC_HOSTED__ && __has_include_next(<stdatomic.h>)
|
||||
# include_next <stdatomic.h>
|
||||
#else
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* 7.17.1 Introduction */
|
||||
|
||||
#define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE
|
||||
#define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE
|
||||
#define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
|
||||
#define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
|
||||
#define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
|
||||
#define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE
|
||||
#define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE
|
||||
#define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE
|
||||
#define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE
|
||||
#define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE
|
||||
|
||||
/* 7.17.2 Initialization */
|
||||
|
||||
#define ATOMIC_VAR_INIT(value) (value)
|
||||
#define atomic_init __c11_atomic_init
|
||||
|
||||
/* 7.17.3 Order and consistency */
|
||||
|
||||
typedef enum memory_order {
|
||||
memory_order_relaxed = __ATOMIC_RELAXED,
|
||||
memory_order_consume = __ATOMIC_CONSUME,
|
||||
memory_order_acquire = __ATOMIC_ACQUIRE,
|
||||
memory_order_release = __ATOMIC_RELEASE,
|
||||
memory_order_acq_rel = __ATOMIC_ACQ_REL,
|
||||
memory_order_seq_cst = __ATOMIC_SEQ_CST
|
||||
} memory_order;
|
||||
|
||||
#define kill_dependency(y) (y)
|
||||
|
||||
/* 7.17.4 Fences */
|
||||
|
||||
/* These should be provided by the libc implementation. */
|
||||
void atomic_thread_fence(memory_order);
|
||||
void atomic_signal_fence(memory_order);
|
||||
|
||||
#define atomic_thread_fence(order) __c11_atomic_thread_fence(order)
|
||||
#define atomic_signal_fence(order) __c11_atomic_signal_fence(order)
|
||||
|
||||
/* 7.17.5 Lock-free property */
|
||||
|
||||
#define atomic_is_lock_free(obj) __c11_atomic_is_lock_free(sizeof(*(obj)))
|
||||
|
||||
/* 7.17.6 Atomic integer types */
|
||||
|
||||
#ifdef __cplusplus
|
||||
typedef _Atomic(bool) atomic_bool;
|
||||
#else
|
||||
typedef _Atomic(_Bool) atomic_bool;
|
||||
#endif
|
||||
typedef _Atomic(char) atomic_char;
|
||||
typedef _Atomic(signed char) atomic_schar;
|
||||
typedef _Atomic(unsigned char) atomic_uchar;
|
||||
typedef _Atomic(short) atomic_short;
|
||||
typedef _Atomic(unsigned short) atomic_ushort;
|
||||
typedef _Atomic(int) atomic_int;
|
||||
typedef _Atomic(unsigned int) atomic_uint;
|
||||
typedef _Atomic(long) atomic_long;
|
||||
typedef _Atomic(unsigned long) atomic_ulong;
|
||||
typedef _Atomic(long long) atomic_llong;
|
||||
typedef _Atomic(unsigned long long) atomic_ullong;
|
||||
typedef _Atomic(uint_least16_t) atomic_char16_t;
|
||||
typedef _Atomic(uint_least32_t) atomic_char32_t;
|
||||
typedef _Atomic(wchar_t) atomic_wchar_t;
|
||||
typedef _Atomic(int_least8_t) atomic_int_least8_t;
|
||||
typedef _Atomic(uint_least8_t) atomic_uint_least8_t;
|
||||
typedef _Atomic(int_least16_t) atomic_int_least16_t;
|
||||
typedef _Atomic(uint_least16_t) atomic_uint_least16_t;
|
||||
typedef _Atomic(int_least32_t) atomic_int_least32_t;
|
||||
typedef _Atomic(uint_least32_t) atomic_uint_least32_t;
|
||||
typedef _Atomic(int_least64_t) atomic_int_least64_t;
|
||||
typedef _Atomic(uint_least64_t) atomic_uint_least64_t;
|
||||
typedef _Atomic(int_fast8_t) atomic_int_fast8_t;
|
||||
typedef _Atomic(uint_fast8_t) atomic_uint_fast8_t;
|
||||
typedef _Atomic(int_fast16_t) atomic_int_fast16_t;
|
||||
typedef _Atomic(uint_fast16_t) atomic_uint_fast16_t;
|
||||
typedef _Atomic(int_fast32_t) atomic_int_fast32_t;
|
||||
typedef _Atomic(uint_fast32_t) atomic_uint_fast32_t;
|
||||
typedef _Atomic(int_fast64_t) atomic_int_fast64_t;
|
||||
typedef _Atomic(uint_fast64_t) atomic_uint_fast64_t;
|
||||
typedef _Atomic(intptr_t) atomic_intptr_t;
|
||||
typedef _Atomic(uintptr_t) atomic_uintptr_t;
|
||||
typedef _Atomic(size_t) atomic_size_t;
|
||||
typedef _Atomic(ptrdiff_t) atomic_ptrdiff_t;
|
||||
typedef _Atomic(intmax_t) atomic_intmax_t;
|
||||
typedef _Atomic(uintmax_t) atomic_uintmax_t;
|
||||
|
||||
/* 7.17.7 Operations on atomic types */
|
||||
|
||||
#define atomic_store(object, desired) __c11_atomic_store(object, desired, __ATOMIC_SEQ_CST)
|
||||
#define atomic_store_explicit __c11_atomic_store
|
||||
|
||||
#define atomic_load(object) __c11_atomic_load(object, __ATOMIC_SEQ_CST)
|
||||
#define atomic_load_explicit __c11_atomic_load
|
||||
|
||||
#define atomic_exchange(object, desired) __c11_atomic_exchange(object, desired, __ATOMIC_SEQ_CST)
|
||||
#define atomic_exchange_explicit __c11_atomic_exchange
|
||||
|
||||
#define atomic_compare_exchange_strong(object, expected, desired) __c11_atomic_compare_exchange_strong(object, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
|
||||
#define atomic_compare_exchange_strong_explicit __c11_atomic_compare_exchange_strong
|
||||
|
||||
#define atomic_compare_exchange_weak(object, expected, desired) __c11_atomic_compare_exchange_weak(object, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
|
||||
#define atomic_compare_exchange_weak_explicit __c11_atomic_compare_exchange_weak
|
||||
|
||||
#define atomic_fetch_add(object, operand) __c11_atomic_fetch_add(object, operand, __ATOMIC_SEQ_CST)
|
||||
#define atomic_fetch_add_explicit __c11_atomic_fetch_add
|
||||
|
||||
#define atomic_fetch_sub(object, operand) __c11_atomic_fetch_sub(object, operand, __ATOMIC_SEQ_CST)
|
||||
#define atomic_fetch_sub_explicit __c11_atomic_fetch_sub
|
||||
|
||||
#define atomic_fetch_or(object, operand) __c11_atomic_fetch_or(object, operand, __ATOMIC_SEQ_CST)
|
||||
#define atomic_fetch_or_explicit __c11_atomic_fetch_or
|
||||
|
||||
#define atomic_fetch_xor(object, operand) __c11_atomic_fetch_xor(object, operand, __ATOMIC_SEQ_CST)
|
||||
#define atomic_fetch_xor_explicit __c11_atomic_fetch_xor
|
||||
|
||||
#define atomic_fetch_and(object, operand) __c11_atomic_fetch_and(object, operand, __ATOMIC_SEQ_CST)
|
||||
#define atomic_fetch_and_explicit __c11_atomic_fetch_and
|
||||
|
||||
/* 7.17.8 Atomic flag type and operations */
|
||||
|
||||
typedef struct atomic_flag { atomic_bool _Value; } atomic_flag;
|
||||
|
||||
#define ATOMIC_FLAG_INIT { 0 }
|
||||
|
||||
/* These should be provided by the libc implementation. */
|
||||
#ifdef __cplusplus
|
||||
bool atomic_flag_test_and_set(volatile atomic_flag *);
|
||||
bool atomic_flag_test_and_set_explicit(volatile atomic_flag *, memory_order);
|
||||
#else
|
||||
_Bool atomic_flag_test_and_set(volatile atomic_flag *);
|
||||
_Bool atomic_flag_test_and_set_explicit(volatile atomic_flag *, memory_order);
|
||||
#endif
|
||||
void atomic_flag_clear(volatile atomic_flag *);
|
||||
void atomic_flag_clear_explicit(volatile atomic_flag *, memory_order);
|
||||
|
||||
#define atomic_flag_test_and_set(object) __c11_atomic_exchange(&(object)->_Value, 1, __ATOMIC_SEQ_CST)
|
||||
#define atomic_flag_test_and_set_explicit(object, order) __c11_atomic_exchange(&(object)->_Value, 1, order)
|
||||
|
||||
#define atomic_flag_clear(object) __c11_atomic_store(&(object)->_Value, 0, __ATOMIC_SEQ_CST)
|
||||
#define atomic_flag_clear_explicit(object, order) __c11_atomic_store(&(object)->_Value, 0, order)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STDC_HOSTED__ */
|
||||
#endif /* __CLANG_STDATOMIC_H */
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
#include <emscripten.h>
|
||||
#include "wasmtime_ssp.h"
|
||||
#include "../src/posix.h"
|
||||
|
||||
static __thread struct fd_table curfds_pointee;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void handleFiles(void) {
|
||||
struct fd_table *curfds = &curfds_pointee;
|
||||
|
||||
fd_table_init(curfds);
|
||||
|
||||
// Prepopulate curfds with stdin, stdout, and stderr file descriptors.
|
||||
if (!fd_table_insert_existing(curfds, 0, 0))
|
||||
__builtin_trap();
|
||||
if (!fd_table_insert_existing(curfds, 1, 1))
|
||||
__builtin_trap();
|
||||
if (!fd_table_insert_existing(curfds, 2, 2))
|
||||
__builtin_trap();
|
||||
|
||||
EM_ASM(" \
|
||||
const imports = { wasi_unstable: WASIPolyfill }; \
|
||||
let file = document.getElementById('input').files[0]; \
|
||||
let file_with_mime_type = file.slice(0, file.size, 'application/wasm'); \
|
||||
let response = new Response(file_with_mime_type); \
|
||||
wasi_instantiateStreaming(response, imports) \
|
||||
.then(obj => { \
|
||||
setInstance(obj.instance); \
|
||||
try { \
|
||||
obj.instance.exports._start(); \
|
||||
} catch (e) { \
|
||||
if (e instanceof WASIExit) { \
|
||||
handleWASIExit(e); \
|
||||
} else { \
|
||||
} \
|
||||
} \
|
||||
}) \
|
||||
.catch(error => { \
|
||||
console.log('error! ' + error); \
|
||||
}); \
|
||||
");
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
<!doctype html>
|
||||
<!-- This file is derived from src/shell_minimal.html in Emscripten. -->
|
||||
<html lang="en-us">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>WASI Web Polyfill</title>
|
||||
<style>
|
||||
.wasi { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
|
||||
textarea.wasi { font-family: monospace; width: 80%; }
|
||||
div.wasi { text-align: center; }
|
||||
div.wasi_border { border: 1px solid black; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<figure style="overflow:visible;" id="spinner"><div class="spinner"></div><center style="margin-top:0.5em"><strong>WASI</strong></center></figure>
|
||||
<div class="wasi" id="status">Downloading...</div>
|
||||
<div class="wasi">
|
||||
<progress value="0" max="100" id="progress" hidden=1></progress>
|
||||
</div>
|
||||
<img class="wasi" src="WASI-small.png" width="200" height="200" border="0" alt="WASI logo">
|
||||
<input class="wasi" type="file" id="input" onchange="_handleFiles(this.files)">
|
||||
<hr>
|
||||
<textarea class="wasi" id="output" rows="8"></textarea>
|
||||
<script type='text/javascript'>
|
||||
var statusElement = document.getElementById('status');
|
||||
var progressElement = document.getElementById('progress');
|
||||
var spinnerElement = document.getElementById('spinner');
|
||||
|
||||
var Module = {
|
||||
preRun: [],
|
||||
postRun: [],
|
||||
print: (function() {
|
||||
var element = document.getElementById('output');
|
||||
if (element) element.value = ''; // clear browser cache
|
||||
return function(text) {
|
||||
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
|
||||
console.log(text);
|
||||
if (element) {
|
||||
element.value += text + "\n";
|
||||
element.scrollTop = element.scrollHeight; // focus on bottom
|
||||
}
|
||||
};
|
||||
})(),
|
||||
printErr: function(text) {
|
||||
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
|
||||
console.error(text);
|
||||
},
|
||||
setStatus: function(text) {
|
||||
if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' };
|
||||
if (text === Module.setStatus.last.text) return;
|
||||
var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
|
||||
var now = Date.now();
|
||||
if (m && now - Module.setStatus.last.time < 30) return; // if this is a progress update, skip it if too soon
|
||||
Module.setStatus.last.time = now;
|
||||
Module.setStatus.last.text = text;
|
||||
if (m) {
|
||||
text = m[1];
|
||||
progressElement.value = parseInt(m[2])*100;
|
||||
progressElement.max = parseInt(m[4])*100;
|
||||
progressElement.hidden = false;
|
||||
spinnerElement.hidden = false;
|
||||
} else {
|
||||
progressElement.value = null;
|
||||
progressElement.max = null;
|
||||
progressElement.hidden = true;
|
||||
if (!text) spinnerElement.hidden = true;
|
||||
}
|
||||
statusElement.innerHTML = text;
|
||||
},
|
||||
totalDependencies: 0,
|
||||
monitorRunDependencies: function(left) {
|
||||
this.totalDependencies = Math.max(this.totalDependencies, left);
|
||||
Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
|
||||
}
|
||||
};
|
||||
Module.setStatus('Downloading...');
|
||||
window.onerror = function() {
|
||||
Module.setStatus('Exception thrown, see JavaScript console');
|
||||
spinnerElement.style.display = 'none';
|
||||
Module.setStatus = function(text) {
|
||||
if (text) Module.printErr('[post-exception status] ' + text);
|
||||
};
|
||||
};
|
||||
</script>
|
||||
{{{ SCRIPT }}}
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,497 +0,0 @@
|
||||
// To implement `proc_exit`, we define a custom exception object
|
||||
// that we can throw to unwind the stack and carry the exit value.
|
||||
function WASIExit(return_value, message, fileName, lineNumber) {
|
||||
let instance = new Error(message, fileName, lineNumber);
|
||||
instance.return_value = return_value;
|
||||
Object.setPrototypeOf(instance, Object.getPrototypeOf(this));
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(instance, WASIExit);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
WASIExit.prototype = Object.create(Error.prototype, {
|
||||
constructor: {
|
||||
value: Error,
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
configurable: true
|
||||
}
|
||||
});
|
||||
|
||||
if (Object.setPrototypeOf) {
|
||||
Object.setPrototypeOf(WASIExit, Error);
|
||||
} else {
|
||||
WASIExit.__proto__ = Error;
|
||||
}
|
||||
|
||||
function handleWASIExit(e) {
|
||||
if (e.return_value != 0) {
|
||||
console.log('program exited with non-zero exit status ' + e.return_value);
|
||||
}
|
||||
}
|
||||
|
||||
// Safari doesn't have instantiateStreaming
|
||||
function wasi_instantiateStreaming(response, imports) {
|
||||
if (WebAssembly && WebAssembly.instantiateStreaming) {
|
||||
return WebAssembly.instantiateStreaming(response, imports);
|
||||
}
|
||||
return response.arrayBuffer()
|
||||
.then(function(buffer) {
|
||||
return WebAssembly.instantiate(buffer, imports);
|
||||
});
|
||||
}
|
||||
|
||||
// The current guest wasm instance.
|
||||
var currentInstance;
|
||||
|
||||
// There are two heaps in play, the guest heap, which belongs to the WASI-using
|
||||
// program, and the host heap, which belongs to the Emscripten-compiled polyfill
|
||||
// library. The following declare support for the guest heap in a similar manner
|
||||
// to Emscripten's heap.
|
||||
|
||||
var GUEST_HEAP,
|
||||
/** @type {ArrayBuffer} */
|
||||
GUEST_buffer,
|
||||
/** @type {Int8Array} */
|
||||
GUEST_HEAP8,
|
||||
/** @type {Uint8Array} */
|
||||
GUEST_HEAPU8,
|
||||
/** @type {Int16Array} */
|
||||
GUEST_HEAP16,
|
||||
/** @type {Uint16Array} */
|
||||
GUEST_HEAPU16,
|
||||
/** @type {Int32Array} */
|
||||
GUEST_HEAP32,
|
||||
/** @type {Uint32Array} */
|
||||
GUEST_HEAPU32,
|
||||
/** @type {Float32Array} */
|
||||
GUEST_HEAPF32,
|
||||
/** @type {Float64Array} */
|
||||
GUEST_HEAPF64;
|
||||
|
||||
function setInstance(instance) {
|
||||
currentInstance = instance;
|
||||
updateGuestBuffer();
|
||||
}
|
||||
|
||||
/// We call updateGuestBuffer any time the guest's memory may have changed,
|
||||
/// such as when creating a new instance, or after calling _malloc.
|
||||
function updateGuestBuffer() {
|
||||
var buf = currentInstance.exports.memory.buffer;
|
||||
Module['GUEST_buffer'] = GUEST_buffer = buf;
|
||||
Module['GUEST_HEAP8'] = GUEST_HEAP8 = new Int8Array(GUEST_buffer);
|
||||
Module['GUEST_HEAP16'] = GUEST_HEAP16 = new Int16Array(GUEST_buffer);
|
||||
Module['GUEST_HEAP32'] = GUEST_HEAP32 = new Int32Array(GUEST_buffer);
|
||||
Module['GUEST_HEAPU8'] = GUEST_HEAPU8 = new Uint8Array(GUEST_buffer);
|
||||
Module['GUEST_HEAPU16'] = GUEST_HEAPU16 = new Uint16Array(GUEST_buffer);
|
||||
Module['GUEST_HEAPU32'] = GUEST_HEAPU32 = new Uint32Array(GUEST_buffer);
|
||||
Module['GUEST_HEAPF32'] = GUEST_HEAPF32 = new Float32Array(GUEST_buffer);
|
||||
Module['GUEST_HEAPF64'] = GUEST_HEAPF64 = new Float64Array(GUEST_buffer);
|
||||
}
|
||||
|
||||
function copyin_bytes(src, len) {
|
||||
let dst = _malloc(len);
|
||||
updateGuestBuffer();
|
||||
|
||||
for (let i = 0; i < len; ++i) {
|
||||
HEAP8[dst + i] = GUEST_HEAP8[src + i];
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
function copyout_bytes(dst, src, len) {
|
||||
updateGuestBuffer();
|
||||
|
||||
for (let i = 0; i < len; ++i) {
|
||||
GUEST_HEAP8[dst + i] = HEAP8[src + i];
|
||||
}
|
||||
_free(src);
|
||||
}
|
||||
|
||||
function copyout_i32(dst, src) {
|
||||
updateGuestBuffer();
|
||||
|
||||
GUEST_HEAP32[dst>>2] = HEAP32[src>>2];
|
||||
_free(src);
|
||||
}
|
||||
|
||||
function copyout_i64(dst, src) {
|
||||
updateGuestBuffer();
|
||||
|
||||
GUEST_HEAP32[dst>>2] = HEAP32[src>>2];
|
||||
GUEST_HEAP32[(dst + 4)>>2] = HEAP32[(src + 4)>>2];
|
||||
_free(src);
|
||||
}
|
||||
|
||||
function translate_ciovs(iovs, iovs_len) {
|
||||
host_iovs = _malloc(8 * iovs_len);
|
||||
updateGuestBuffer();
|
||||
|
||||
for (let i = 0; i < iovs_len; ++i) {
|
||||
let ptr = GUEST_HEAP32[(iovs + i * 8 + 0) >> 2];
|
||||
let len = GUEST_HEAP32[(iovs + i * 8 + 4) >> 2];
|
||||
let buf = copyin_bytes(ptr, len);
|
||||
HEAP32[(host_iovs + i * 8 + 0)>>2] = buf;
|
||||
HEAP32[(host_iovs + i * 8 + 4)>>2] = len;
|
||||
}
|
||||
return host_iovs;
|
||||
}
|
||||
|
||||
function free_ciovs(host_iovs, iovs_len) {
|
||||
for (let i = 0; i < iovs_len; ++i) {
|
||||
let buf = HEAP32[(host_iovs + i * 8 + 0) >> 2];
|
||||
_free(buf);
|
||||
}
|
||||
_free(host_iovs);
|
||||
}
|
||||
|
||||
function translate_iovs(iovs, iovs_len) {
|
||||
host_iovs = _malloc(8 * iovs_len);
|
||||
updateGuestBuffer();
|
||||
|
||||
for (let i = 0; i < iovs_len; ++i) {
|
||||
let len = GUEST_HEAP32[(iovs + i * 8 + 4) >> 2];
|
||||
let buf = _malloc(len);
|
||||
updateGuestBuffer();
|
||||
HEAP32[(host_iovs + i * 8 + 0)>>2] = buf;
|
||||
HEAP32[(host_iovs + i * 8 + 4)>>2] = len;
|
||||
}
|
||||
return host_iovs;
|
||||
}
|
||||
|
||||
function free_iovs(host_iovs, iovs_len, iovs) {
|
||||
updateGuestBuffer();
|
||||
for (let i = 0; i < iovs_len; ++i) {
|
||||
let buf = HEAP32[(host_iovs + i * 8 + 0) >> 2];
|
||||
let len = HEAP32[(host_iovs + i * 8 + 4) >> 2];
|
||||
let ptr = GUEST_HEAP32[(iovs + i * 8 + 0) >> 2];
|
||||
copyout_bytes(ptr, buf, len);
|
||||
}
|
||||
_free(host_iovs);
|
||||
}
|
||||
|
||||
var WASIPolyfill = {
|
||||
|
||||
args_get: function(argv, argv_buf) {
|
||||
return 0;
|
||||
},
|
||||
|
||||
args_sizes_get: function(argc, argv_buf_size) {
|
||||
updateGuestBuffer();
|
||||
|
||||
// TODO: Implement command-line arguments.
|
||||
GUEST_HEAP32[(argc) >> 2] = 0;
|
||||
GUEST_HEAP32[(argv_buf_size) >> 2] = 0;
|
||||
return 0;
|
||||
},
|
||||
|
||||
clock_res_get: function(clock_id, resolution) {
|
||||
let host_resolution = _malloc(8);
|
||||
let ret = ___wasi_clock_res_get(clock_id, host_resolution);
|
||||
copyout_i64(resolution, host_resolution);
|
||||
return ret;
|
||||
},
|
||||
|
||||
clock_time_get: function(clock_id, precision, time) {
|
||||
let host_time = _malloc(8);
|
||||
let ret = ___wasi_clock_time_get(clock_id, precision, host_time);
|
||||
copyout_i64(time, host_time);
|
||||
return ret;
|
||||
},
|
||||
|
||||
environ_get: function(environ, environ_buf) {
|
||||
return 0;
|
||||
},
|
||||
|
||||
environ_sizes_get: function(environ_size, environ_buf_size) {
|
||||
updateGuestBuffer();
|
||||
|
||||
// TODO: Implement environment variables.
|
||||
GUEST_HEAP32[(environ_size) >> 2] = 0;
|
||||
GUEST_HEAP32[(environ_buf_size) >> 2] = 0;
|
||||
return 0;
|
||||
},
|
||||
|
||||
fd_prestat_get: function(fd, buf) {
|
||||
let host_buf = _malloc(8); // sizeof __wasi_prestat_t
|
||||
let ret = ___wasi_fd_prestat_get(fd, host_buf);
|
||||
copyout_bytes(buf, host_buf, 8);
|
||||
return ret;
|
||||
},
|
||||
|
||||
fd_prestat_dir_name: function(fd, path, path_len) {
|
||||
let host_buf = _malloc(path_len);
|
||||
let ret = ___wasi_fd_prestat_get(fd, host_buf, path_len);
|
||||
copyout_bytes(buf, host_buf, path_len);
|
||||
return ret;
|
||||
},
|
||||
|
||||
fd_close: function(fd) {
|
||||
return ___wasi_fd_close(fd);
|
||||
},
|
||||
|
||||
fd_datasync: function(fd) {
|
||||
return ___wasi_fd_datasync(fd);
|
||||
},
|
||||
|
||||
fd_pread: function(fd, iovs, iovs_len, offset, nread) {
|
||||
let host_iovs = translate_iovs(iovs, iovs_len);
|
||||
let host_nread = _malloc(4);
|
||||
let ret = ___wasi_fd_pread(fd, host_iovs, iovs_len, offset, host_nread);
|
||||
copyout_i32(nread, host_nread);
|
||||
free_iovs(host_iovs, iovs_len, iovs);
|
||||
return ret;
|
||||
},
|
||||
|
||||
fd_pwrite: function(fd, iovs, iovs_len, offset, nwritten) {
|
||||
let host_iovs = translate_ciovs(iovs, iovs_len);
|
||||
let host_nwritten = _malloc(4);
|
||||
let ret = ___wasi_fd_pwrite(fd, host_iovs, iovs_len, offset, host_nwritten);
|
||||
copyout_i32(nwritten, host_nwritten);
|
||||
free_ciovs(host_iovs, iovs_len);
|
||||
return ret;
|
||||
},
|
||||
|
||||
fd_read: function(fd, iovs, iovs_len, nread) {
|
||||
let host_iovs = translate_iovs(iovs, iovs_len);
|
||||
let host_nread = _malloc(4);
|
||||
let ret = ___wasi_fd_read(fd, host_iovs, iovs_len, host_nread);
|
||||
copyout_i32(nread, host_nread);
|
||||
free_iovs(host_iovs, iovs_len, iovs);
|
||||
return ret;
|
||||
},
|
||||
|
||||
fd_renumber: function(from, to) {
|
||||
return ___wasi_fd_renumber(from, to);
|
||||
},
|
||||
|
||||
fd_seek: function(fd, offset, whence, newoffset) {
|
||||
let host_newoffset = _malloc(8);
|
||||
let ret = ___wasi_fd_seek(fd, offset, whence, host_newoffset);
|
||||
copyout_i64(newoffset, host_newoffset);
|
||||
return ret;
|
||||
},
|
||||
|
||||
fd_tell: function(fd, newoffset) {
|
||||
let host_newoffset = _malloc(8);
|
||||
let ret = ___wasi_fd_seek(fd, host_newoffset);
|
||||
copyout_i64(newoffset, host_newoffset);
|
||||
return ret;
|
||||
},
|
||||
|
||||
fd_fdstat_get: function(fd, buf) {
|
||||
let host_buf = _malloc(24); // sizeof __wasi_fdstat_t
|
||||
let ret = ___wasi_fd_fdstat_get(fd, host_buf);
|
||||
copyout_bytes(buf, host_buf, 24);
|
||||
return ret;
|
||||
},
|
||||
|
||||
fd_fdstat_set_flags: function(fd, flags) {
|
||||
return ___wasi_fd_fdstat_set_flags(fd, flags);
|
||||
},
|
||||
|
||||
fd_fdstat_set_rights: function(fd, fs_rights_base, fs_rights_inheriting) {
|
||||
return ___wasi_fd_fdstat_set_rights(fd, fs_rights_base, fs_rights_inheriting);
|
||||
},
|
||||
|
||||
fd_sync: function(fd) {
|
||||
return ___wasi_fd_sync(fd);
|
||||
},
|
||||
|
||||
fd_write: function(fd, iovs, iovs_len, nwritten) {
|
||||
let host_iovs = translate_ciovs(iovs, iovs_len);
|
||||
let host_nwritten = _malloc(4);
|
||||
let ret = ___wasi_fd_write(fd, host_iovs, iovs_len, host_nwritten);
|
||||
copyout_i32(nwritten, host_nwritten);
|
||||
free_ciovs(host_iovs, iovs_len);
|
||||
return ret;
|
||||
},
|
||||
|
||||
fd_advise: function(fd, offset, len, advice) {
|
||||
return ___wasi_fd_advise(fd, offset, len, advice);
|
||||
},
|
||||
|
||||
fd_allocate: function(fd, offset, len) {
|
||||
return ___wasi_fd_allocate(fd, offset, len);
|
||||
},
|
||||
|
||||
path_create_directory: function(fd, path, path_len) {
|
||||
let host_path = copyin_bytes(path, path_len);
|
||||
let ret = ___wasi_path_create_directory(fd, host_path, path_len);
|
||||
_free(host_path);
|
||||
return ret;
|
||||
},
|
||||
|
||||
path_link: function(fd0, path0, path_len0, fd1, path1, path_len1) {
|
||||
let host_path0 = copyin_bytes(path0, path_len0);
|
||||
let host_path1 = copyin_bytes(path1, path_len1);
|
||||
let ret = ___wasi_path_link(fd, host_path0, path_len0, fd1, host_path1, path1_len);
|
||||
_free(host_path1);
|
||||
_free(host_path0);
|
||||
return ret;
|
||||
},
|
||||
|
||||
path_open: function(dirfd, dirflags, path, path_len, oflags, fs_rights_base, fs_rights_inheriting, fs_flags, fd) {
|
||||
let host_path = copyin_bytes(path, path_len);
|
||||
let host_fd = _malloc(4);
|
||||
let ret = ___wasi_path_open(dirfd, dirflags, host_path, path_len, oflags, fs_rights_base, fs_rights_inheriting, fs_flags, host_fd);
|
||||
copyout_i32(fd, host_fd);
|
||||
_free(host_path);
|
||||
return ret;
|
||||
},
|
||||
|
||||
fd_readdir: function(fd, buf, buf_len, cookie, buf_used) {
|
||||
let host_buf = _malloc(buf_len);
|
||||
let host_buf_used = _malloc(4);
|
||||
let ret = ___wasi_fd_readdir(fd, buf, buf_len, cookie, host_buf_used);
|
||||
copyout_i32(buf_used, host_buf_used);
|
||||
copyout_bytes(buf, host_buf, buf_len);
|
||||
return ret;
|
||||
},
|
||||
|
||||
path_readlink: function(fd, path, path_len, buf, buf_len, buf_used) {
|
||||
let host_path = copyin_bytes(path, path_len);
|
||||
let host_buf = _malloc(buf_len);
|
||||
let host_buf_used = _malloc(4);
|
||||
let ret = ___wasi_path_readlink(fd, path, path_len, buf, buf_len, host_buf_used);
|
||||
copyout_i32(buf_used, host_buf_used);
|
||||
copyout_bytes(buf, host_buf, buf_len);
|
||||
_free(host_path);
|
||||
return ret;
|
||||
},
|
||||
|
||||
path_rename: function(fd0, path0, path_len0, fd1, path1, path_len1) {
|
||||
let host_path0 = copyin_bytes(path0, path_len0);
|
||||
let host_path1 = copyin_bytes(path1, path_len1);
|
||||
let ret = ___wasi_path_rename(fd, host_path0, path_len0, fd1, host_path1, path1_len);
|
||||
_free(host_path1);
|
||||
_free(host_path0);
|
||||
return ret;
|
||||
},
|
||||
|
||||
fd_filestat_get: function(fd, buf) {
|
||||
let host_buf = _malloc(56); // sizeof __wasi_filestat_t
|
||||
let ret = ___wasi_fd_filestat_get(host_buf);
|
||||
copyout_bytes(buf, host_buf, 56);
|
||||
return ret;
|
||||
},
|
||||
|
||||
fd_filestat_set_size: function(fd, size) {
|
||||
return ___wasi_fd_filestat_set_size(fd, size);
|
||||
},
|
||||
|
||||
fd_filestat_set_times: function(fd, st_atim, st_mtim, fstflags) {
|
||||
return ___wasi_fd_filestat_set_times(fd, st_atim, st_mtim, fstflags);
|
||||
},
|
||||
|
||||
path_filestat_get: function(fd, path, path_len, buf) {
|
||||
let host_path = copyin_bytes(path, path_len);
|
||||
let host_buf = _malloc(56); // sizeof __wasi_filestat_t
|
||||
let ret = ___wasi_path_filestat_get(fd, host_path, path_len, host_buf);
|
||||
copyout_bytes(buf, host_buf, 56);
|
||||
_free(host_path);
|
||||
return ret;
|
||||
},
|
||||
|
||||
path_filestat_set_times: function(fd, path, path_len, st_atim, st_mtim, flags) {
|
||||
let host_path = copyin_bytes(path, path_len);
|
||||
let ret = ___wasi_path_filestat_set_times(fd, host_path, st_atim, st_mtim, fstflags);
|
||||
_free(host_path);
|
||||
return ret;
|
||||
},
|
||||
|
||||
path_symlink: function(path0, path_len0, fd, path1, path_len1) {
|
||||
let host_path0 = copyin_bytes(path0, path0_len);
|
||||
let host_path1 = copyin_bytes(path1, path1_len);
|
||||
let ret = ___wasi_path_symlink(host_path0, path_len0, fd, host_path1, path_len1);
|
||||
_free(host_path1);
|
||||
_free(host_path0);
|
||||
return ret;
|
||||
},
|
||||
|
||||
path_unlink_file: function(fd, path, path_len, flags) {
|
||||
let host_path = copyin_bytes(path, path_len);
|
||||
let ret = ___wasi_path_unlink_file(fd, host_path, path_len, flags);
|
||||
_free(host_path);
|
||||
return ret;
|
||||
},
|
||||
|
||||
path_remove_directory: function(fd, path, path_len, flags) {
|
||||
let host_path = copyin_bytes(path, path_len);
|
||||
let ret = ___wasi_path_remove_directory(fd, host_path, path_len, flags);
|
||||
_free(host_path);
|
||||
return ret;
|
||||
},
|
||||
|
||||
poll_oneoff: function(in_, out, nsubscriptions, nevents) {
|
||||
let host_in = copyin_bytes(in_, nsubscriptions * 56); // sizeof __wasi_subscription_t
|
||||
let host_out = _malloc(nsubscriptions * 32); // sizeof __wasi_event_t
|
||||
let host_nevents = _malloc(4);
|
||||
let ret = ___wasi_poll_oneoff(host_in, host_out, host_nevents);
|
||||
copyout_bytes(out, host_out, nsubscriptions * 32);
|
||||
copyout_i32(nevents, host_nevents);
|
||||
_free(host_in);
|
||||
return ret;
|
||||
},
|
||||
|
||||
proc_exit: function(rval) {
|
||||
let message;
|
||||
if (rval == 0) {
|
||||
message = "success";
|
||||
} else {
|
||||
message = "error code " + rval;
|
||||
}
|
||||
throw new WASIExit(rval, message);
|
||||
},
|
||||
|
||||
proc_raise: function(sig) {
|
||||
if (sig == 18 || // SIGSTOP
|
||||
sig == 19 || // SIGTSTP
|
||||
sig == 20 || // SIGTTIN
|
||||
sig == 21 || // SIGTTOU
|
||||
sig == 22 || // SIGURG
|
||||
sig == 16 || // SIGCHLD
|
||||
sig == 13) // SIGPIPE
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
let message = "raised signal " + sig;
|
||||
throw new WASIExit(128 + sig, message);
|
||||
},
|
||||
|
||||
random_get: function(buf, buf_len) {
|
||||
let host_buf = _malloc(buf_len);
|
||||
let ret = ___wasi_random_get(host_buf, buf_len);
|
||||
copyout_bytes(buf, host_buf, buf_len);
|
||||
return ret;
|
||||
},
|
||||
|
||||
sched_yield: function() {
|
||||
return ___wasi_sched_yield();
|
||||
},
|
||||
|
||||
sock_recv: function(sock, ri_data, ri_data_len, ri_flags, ro_datalen, ro_flags) {
|
||||
let host_ri_data = translate_iovs(ri_data, ri_data_len);
|
||||
let host_ro_datalen = _malloc(4);
|
||||
let ret = ___wasi_sock_recv(sock, host_ri_data, ri_data_len, ri_flags, host_ro_data, ro_flags);
|
||||
copyout_i32(ro_datalen, host_ro_datalen);
|
||||
free_iovs(host_ri_data, ri_data_len, ri_data);
|
||||
return ret;
|
||||
},
|
||||
|
||||
sock_send: function(sock, si_data, si_data_len, si_flags, so_datalen) {
|
||||
let host_si_data = translate_ciovs(si_data, si_data_len);
|
||||
let host_so_datalen = _malloc(4);
|
||||
let ret = ___wasi_sock_send(sock, host_si_data, si_data_len, si_flags, host_so_datalen);
|
||||
copyout_i32(so_datalen, host_so_datalen);
|
||||
free_ciovs(host_si_data, si_data_len);
|
||||
return ret;
|
||||
},
|
||||
|
||||
sock_shutdown: function(sock, how) {
|
||||
return ___wasi_sock_shutdown(sock, how);
|
||||
}
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user