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