Skip to content

Add WASI support #264

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,22 @@ jobs:
emmake make -C build qjs_wasm -j$(getconf _NPROCESSORS_ONLN)
- name: result
run: ls -lh build
wasi:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: jcbhmr/setup-wasmtime@v2
- name: setup wasi-sdk
run: |
wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-21/wasi-sdk_21.0_amd64.deb -P /tmp
sudo apt install /tmp/wasi-sdk*.deb
- name: test
run: |
cmake -B build -DCMAKE_TOOLCHAIN_FILE=/opt/wasi-sdk/share/cmake/wasi-sdk.cmake
make -C build qjs_exe
wasmtime run build/qjs -qd
echo "console.log('hello wasi!');" > t.js
wasmtime run --dir . build/qjs t.js

cygwin:
runs-on: windows-latest
Expand Down
11 changes: 11 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,17 @@ if(MSVC)
add_compile_definitions(WIN32_LEAN_AND_MEAN)
endif()

if(CMAKE_SYSTEM_NAME STREQUAL "WASI")
add_compile_definitions(
_WASI_EMULATED_PROCESS_CLOCKS
_WASI_EMULATED_SIGNAL
)
add_link_options(
-lwasi-emulated-process-clocks
-lwasi-emulated-signal
)
endif()

if(CMAKE_BUILD_TYPE MATCHES "Debug")
add_compile_options(-O0)
xcheck_add_c_compiler_flag(-ggdb)
Expand Down
50 changes: 38 additions & 12 deletions quickjs-libc.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,13 @@
#define getcwd _getcwd
#define chdir _chdir
#else
#include <sys/ioctl.h>
#if !defined(__wasi__)
#include <dlfcn.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#include <sys/wait.h>
#endif

#if defined(__APPLE__)
typedef sig_t sighandler_t;
Expand All @@ -76,10 +78,12 @@ typedef sig_t sighandler_t;
extern char **environ;
#endif

#endif /* _WIN32 */

#if !defined(_WIN32) && !defined(__wasi__)
/* enable the os.Worker API. IT relies on POSIX threads */
#define USE_WORKER

#endif /* _WIN32 */
#endif

#ifdef USE_WORKER
#include <pthread.h>
Expand Down Expand Up @@ -472,7 +476,7 @@ typedef JSModuleDef *(JSInitModuleFunc)(JSContext *ctx,
const char *module_name);


#if defined(_WIN32)
#if defined(_WIN32) || defined(__wasi__)
static JSModuleDef *js_module_loader_so(JSContext *ctx,
const char *module_name)
{
Expand Down Expand Up @@ -549,7 +553,7 @@ int js_module_set_import_meta(JSContext *ctx, JSValue func_val,
return -1;
if (!strchr(module_name, ':')) {
strcpy(buf, "file://");
#if !defined(_WIN32)
#if !defined(_WIN32) && !defined(__wasi__)
/* realpath() cannot be used with modules compiled with qjsc
because the corresponding module source code is not
necessarily present */
Expand Down Expand Up @@ -816,9 +820,11 @@ static void js_std_file_finalizer(JSRuntime *rt, JSValue val)
JSSTDFile *s = JS_GetOpaque(val, js_std_file_class_id);
if (s) {
if (s->f && s->close_in_finalizer) {
#if !defined(__wasi__)
if (s->is_popen)
pclose(s->f);
else
#endif
fclose(s->f);
}
js_free_rt(rt, s);
Expand Down Expand Up @@ -905,6 +911,7 @@ static JSValue js_std_open(JSContext *ctx, JSValue this_val,
return JS_EXCEPTION;
}

#if !defined(__wasi__)
static JSValue js_std_popen(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv)
{
Expand Down Expand Up @@ -940,6 +947,7 @@ static JSValue js_std_popen(JSContext *ctx, JSValue this_val,
JS_FreeCString(ctx, mode);
return JS_EXCEPTION;
}
#endif // !defined(__wasi__)

static JSValue js_std_fdopen(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv)
Expand Down Expand Up @@ -974,6 +982,7 @@ static JSValue js_std_fdopen(JSContext *ctx, JSValue this_val,
return JS_EXCEPTION;
}

#if !defined(__wasi__)
static JSValue js_std_tmpfile(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv)
{
Expand All @@ -985,6 +994,7 @@ static JSValue js_std_tmpfile(JSContext *ctx, JSValue this_val,
return JS_NULL;
return js_new_std_file(ctx, f, TRUE, FALSE);
}
#endif

static JSValue js_std_sprintf(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv)
Expand Down Expand Up @@ -1045,9 +1055,11 @@ static JSValue js_std_file_close(JSContext *ctx, JSValue this_val,
return JS_EXCEPTION;
if (!s->f)
return JS_ThrowTypeError(ctx, "invalid file handle");
#if !defined(__wasi__)
if (s->is_popen)
err = js_get_errno(pclose(s->f));
else
#endif
err = js_get_errno(fclose(s->f));
s->f = NULL;
return JS_NewInt32(ctx, err);
Expand Down Expand Up @@ -1277,6 +1289,7 @@ static JSValue js_std_file_putByte(JSContext *ctx, JSValue this_val,
}

/* urlGet */
#if !defined(__wasi__)

#define URL_GET_PROGRAM "curl -s -i"
#define URL_GET_BUF_SIZE 4096
Expand Down Expand Up @@ -1461,6 +1474,7 @@ static JSValue js_std_urlGet(JSContext *ctx, JSValue this_val,
JS_FreeValue(ctx, response);
return JS_EXCEPTION;
}
#endif // !defined(__wasi__)

static JSClassDef js_std_file_class = {
"FILE",
Expand Down Expand Up @@ -1493,15 +1507,19 @@ static const JSCFunctionListEntry js_std_funcs[] = {
JS_CFUNC_DEF("setenv", 1, js_std_setenv ),
JS_CFUNC_DEF("unsetenv", 1, js_std_unsetenv ),
JS_CFUNC_DEF("getenviron", 1, js_std_getenviron ),
#if !defined(__wasi__)
JS_CFUNC_DEF("urlGet", 1, js_std_urlGet ),
#endif
JS_CFUNC_DEF("loadFile", 1, js_std_loadFile ),
JS_CFUNC_DEF("strerror", 1, js_std_strerror ),

/* FILE I/O */
JS_CFUNC_DEF("open", 2, js_std_open ),
#if !defined(__wasi__)
JS_CFUNC_DEF("popen", 2, js_std_popen ),
JS_CFUNC_DEF("fdopen", 2, js_std_fdopen ),
JS_CFUNC_DEF("tmpfile", 0, js_std_tmpfile ),
#endif
JS_CFUNC_DEF("fdopen", 2, js_std_fdopen ),
JS_CFUNC_MAGIC_DEF("puts", 1, js_std_file_puts, 0 ),
JS_CFUNC_DEF("printf", 1, js_std_printf ),
JS_CFUNC_DEF("sprintf", 1, js_std_sprintf ),
Expand Down Expand Up @@ -1714,7 +1732,7 @@ static JSValue js_os_ttySetRaw(JSContext *ctx, JSValue this_val,
}
return JS_UNDEFINED;
}
#else
#elif !defined(__wasi__)
static JSValue js_os_ttyGetWinSize(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv)
{
Expand Down Expand Up @@ -1773,7 +1791,7 @@ static JSValue js_os_ttySetRaw(JSContext *ctx, JSValue this_val,
return JS_UNDEFINED;
}

#endif /* !_WIN32 */
#endif /* !_WIN32 && !__wasi__ */

static JSValue js_os_remove(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv)
Expand Down Expand Up @@ -1967,7 +1985,7 @@ static JSValue js_os_signal(JSContext *ctx, JSValue this_val,
return JS_UNDEFINED;
}

#ifndef _WIN32
#if !defined(_WIN32) && !defined(__wasi__)
static JSValue js_os_cputime(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv)
{
Expand Down Expand Up @@ -2658,6 +2676,7 @@ static char *realpath(const char *path, char *buf)
}
#endif

#if !defined(__wasi__)
/* return [path, errorcode] */
static JSValue js_os_realpath(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv)
Expand All @@ -2679,8 +2698,9 @@ static JSValue js_os_realpath(JSContext *ctx, JSValue this_val,
}
return make_string_error(ctx, buf, err);
}
#endif

#if !defined(_WIN32)
#if !defined(_WIN32) && !defined(__wasi__)
static JSValue js_os_symlink(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv)
{
Expand Down Expand Up @@ -3593,6 +3613,8 @@ void js_std_set_worker_new_context_func(JSContext *(*func)(JSRuntime *rt))
#define OS_PLATFORM "netbsd"
#elif defined(__FreeBSD__)
#define OS_PLATFORM "freebsd"
#elif defined(__wasi__)
#define OS_PLATFORM "wasi"
#else
#define OS_PLATFORM "unknown"
#endif
Expand All @@ -3617,8 +3639,10 @@ static const JSCFunctionListEntry js_os_funcs[] = {
JS_CFUNC_MAGIC_DEF("read", 4, js_os_read_write, 0 ),
JS_CFUNC_MAGIC_DEF("write", 4, js_os_read_write, 1 ),
JS_CFUNC_DEF("isatty", 1, js_os_isatty ),
#if !defined(__wasi__)
JS_CFUNC_DEF("ttyGetWinSize", 1, js_os_ttyGetWinSize ),
JS_CFUNC_DEF("ttySetRaw", 1, js_os_ttySetRaw ),
#endif
JS_CFUNC_DEF("remove", 1, js_os_remove ),
JS_CFUNC_DEF("rename", 2, js_os_rename ),
JS_CFUNC_MAGIC_DEF("setReadHandler", 2, js_os_setReadHandler, 0 ),
Expand All @@ -3630,7 +3654,7 @@ static const JSCFunctionListEntry js_os_funcs[] = {
OS_FLAG(SIGILL),
OS_FLAG(SIGSEGV),
OS_FLAG(SIGTERM),
#if !defined(_WIN32)
#if !defined(_WIN32) && !defined(__wasi__)
OS_FLAG(SIGQUIT),
OS_FLAG(SIGPIPE),
OS_FLAG(SIGALRM),
Expand Down Expand Up @@ -3668,8 +3692,10 @@ static const JSCFunctionListEntry js_os_funcs[] = {
JS_CFUNC_MAGIC_DEF("stat", 1, js_os_stat, 0 ),
JS_CFUNC_DEF("utimes", 3, js_os_utimes ),
JS_CFUNC_DEF("sleep", 1, js_os_sleep ),
#if !defined(__wasi__)
JS_CFUNC_DEF("realpath", 1, js_os_realpath ),
#if !defined(_WIN32)
#endif
#if !defined(_WIN32) && !defined(__wasi__)
JS_CFUNC_MAGIC_DEF("lstat", 1, js_os_stat, 1 ),
JS_CFUNC_DEF("symlink", 2, js_os_symlink ),
JS_CFUNC_DEF("readlink", 1, js_os_readlink ),
Expand Down
8 changes: 6 additions & 2 deletions quickjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
#include "libregexp.h"
#include "libbf.h"

#if defined(EMSCRIPTEN) || defined(_MSC_VER)
#if defined(EMSCRIPTEN) || defined(_MSC_VER) || defined(__wasi__)
#define DIRECT_DISPATCH 0
#else
#define DIRECT_DISPATCH 1
Expand All @@ -55,7 +55,7 @@
#define MALLOC_OVERHEAD 8
#endif

#if !defined(_WIN32)
#if !defined(_WIN32) && !defined(__wasi__)
/* define it if printf uses the RNDN rounding mode instead of RNDNA */
#define CONFIG_PRINTF_RNDN
#endif
Expand Down Expand Up @@ -2318,11 +2318,15 @@ JSRuntime *JS_GetRuntime(JSContext *ctx)

static void update_stack_limit(JSRuntime *rt)
{
#if defined(__wasi__)
rt->stack_limit = 0; /* no limit */
#else
if (rt->stack_size == 0) {
rt->stack_limit = 0; /* no limit */
} else {
rt->stack_limit = rt->stack_top - rt->stack_size;
}
#endif
}

void JS_SetMaxStackSize(JSRuntime *rt, size_t stack_size)
Expand Down
4 changes: 4 additions & 0 deletions quickjs.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,11 @@ static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
#define JS_PROP_DEFINE_PROPERTY (1 << 18) /* internal use */
#define JS_PROP_REFLECT_DEFINE_PROPERTY (1 << 19) /* internal use */

#if defined(__wasi__)
#define JS_DEFAULT_STACK_SIZE 0
#else
#define JS_DEFAULT_STACK_SIZE (256 * 1024)
#endif

/* JS_Eval() flags */
#define JS_EVAL_TYPE_GLOBAL (0 << 0) /* global code (default) */
Expand Down