Skip to content

Commit fb03ca2

Browse files
committed
Add WASI support
1 parent 7f928d2 commit fb03ca2

File tree

5 files changed

+75
-14
lines changed

5 files changed

+75
-14
lines changed

.github/workflows/ci.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,22 @@ jobs:
395395
emmake make -C build qjs_wasm -j$(getconf _NPROCESSORS_ONLN)
396396
- name: result
397397
run: ls -lh build
398+
wasi:
399+
runs-on: ubuntu-latest
400+
steps:
401+
- uses: actions/checkout@v3
402+
- uses: jcbhmr/setup-wasmtime@v2
403+
- name: setup wasi-sdk
404+
run: |
405+
wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-21/wasi-sdk_21.0_amd64.deb -P /tmp
406+
sudo apt install /tmp/wasi-sdk*.deb
407+
- name: test
408+
run: |
409+
cmake -B build -DCMAKE_TOOLCHAIN_FILE=/opt/wasi-sdk/share/cmake/wasi-sdk.cmake
410+
make -C build qjs_exe
411+
wasmtime run build/qjs -qd
412+
echo "console.log('hello wasi!');" > t.js
413+
wasmtime run --dir . build/qjs t.js
398414
399415
cygwin:
400416
runs-on: windows-latest

CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,17 @@ if(MSVC)
5454
add_compile_definitions(WIN32_LEAN_AND_MEAN)
5555
endif()
5656

57+
if(CMAKE_SYSTEM_NAME STREQUAL "WASI")
58+
add_compile_definitions(
59+
_WASI_EMULATED_PROCESS_CLOCKS
60+
_WASI_EMULATED_SIGNAL
61+
)
62+
add_link_options(
63+
-lwasi-emulated-process-clocks
64+
-lwasi-emulated-signal
65+
)
66+
endif()
67+
5768
if(CMAKE_BUILD_TYPE MATCHES "Debug")
5869
add_compile_options(-O0)
5970
xcheck_add_c_compiler_flag(-ggdb)

quickjs-libc.c

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,13 @@
5959
#define getcwd _getcwd
6060
#define chdir _chdir
6161
#else
62+
#include <sys/ioctl.h>
63+
#if !defined(__wasi__)
6264
#include <dlfcn.h>
6365
#include <termios.h>
64-
#include <sys/ioctl.h>
6566
#include <sys/resource.h>
6667
#include <sys/wait.h>
68+
#endif
6769

6870
#if defined(__APPLE__)
6971
typedef sig_t sighandler_t;
@@ -76,10 +78,12 @@ typedef sig_t sighandler_t;
7678
extern char **environ;
7779
#endif
7880

81+
#endif /* _WIN32 */
82+
83+
#if !defined(_WIN32) && !defined(__wasi__)
7984
/* enable the os.Worker API. IT relies on POSIX threads */
8085
#define USE_WORKER
81-
82-
#endif /* _WIN32 */
86+
#endif
8387

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

474478

475-
#if defined(_WIN32)
479+
#if defined(_WIN32) || defined(__wasi__)
476480
static JSModuleDef *js_module_loader_so(JSContext *ctx,
477481
const char *module_name)
478482
{
@@ -549,7 +553,7 @@ int js_module_set_import_meta(JSContext *ctx, JSValue func_val,
549553
return -1;
550554
if (!strchr(module_name, ':')) {
551555
strcpy(buf, "file://");
552-
#if !defined(_WIN32)
556+
#if !defined(_WIN32) && !defined(__wasi__)
553557
/* realpath() cannot be used with modules compiled with qjsc
554558
because the corresponding module source code is not
555559
necessarily present */
@@ -816,9 +820,11 @@ static void js_std_file_finalizer(JSRuntime *rt, JSValue val)
816820
JSSTDFile *s = JS_GetOpaque(val, js_std_file_class_id);
817821
if (s) {
818822
if (s->f && s->close_in_finalizer) {
823+
#if !defined(__wasi__)
819824
if (s->is_popen)
820825
pclose(s->f);
821826
else
827+
#endif
822828
fclose(s->f);
823829
}
824830
js_free_rt(rt, s);
@@ -905,6 +911,7 @@ static JSValue js_std_open(JSContext *ctx, JSValue this_val,
905911
return JS_EXCEPTION;
906912
}
907913

914+
#if !defined(__wasi__)
908915
static JSValue js_std_popen(JSContext *ctx, JSValue this_val,
909916
int argc, JSValue *argv)
910917
{
@@ -940,6 +947,7 @@ static JSValue js_std_popen(JSContext *ctx, JSValue this_val,
940947
JS_FreeCString(ctx, mode);
941948
return JS_EXCEPTION;
942949
}
950+
#endif // !defined(__wasi__)
943951

944952
static JSValue js_std_fdopen(JSContext *ctx, JSValue this_val,
945953
int argc, JSValue *argv)
@@ -974,6 +982,7 @@ static JSValue js_std_fdopen(JSContext *ctx, JSValue this_val,
974982
return JS_EXCEPTION;
975983
}
976984

985+
#if !defined(__wasi__)
977986
static JSValue js_std_tmpfile(JSContext *ctx, JSValue this_val,
978987
int argc, JSValue *argv)
979988
{
@@ -985,6 +994,7 @@ static JSValue js_std_tmpfile(JSContext *ctx, JSValue this_val,
985994
return JS_NULL;
986995
return js_new_std_file(ctx, f, TRUE, FALSE);
987996
}
997+
#endif
988998

989999
static JSValue js_std_sprintf(JSContext *ctx, JSValue this_val,
9901000
int argc, JSValue *argv)
@@ -1045,9 +1055,11 @@ static JSValue js_std_file_close(JSContext *ctx, JSValue this_val,
10451055
return JS_EXCEPTION;
10461056
if (!s->f)
10471057
return JS_ThrowTypeError(ctx, "invalid file handle");
1058+
#if !defined(__wasi__)
10481059
if (s->is_popen)
10491060
err = js_get_errno(pclose(s->f));
10501061
else
1062+
#endif
10511063
err = js_get_errno(fclose(s->f));
10521064
s->f = NULL;
10531065
return JS_NewInt32(ctx, err);
@@ -1277,6 +1289,7 @@ static JSValue js_std_file_putByte(JSContext *ctx, JSValue this_val,
12771289
}
12781290

12791291
/* urlGet */
1292+
#if !defined(__wasi__)
12801293

12811294
#define URL_GET_PROGRAM "curl -s -i"
12821295
#define URL_GET_BUF_SIZE 4096
@@ -1461,6 +1474,7 @@ static JSValue js_std_urlGet(JSContext *ctx, JSValue this_val,
14611474
JS_FreeValue(ctx, response);
14621475
return JS_EXCEPTION;
14631476
}
1477+
#endif // !defined(__wasi__)
14641478

14651479
static JSClassDef js_std_file_class = {
14661480
"FILE",
@@ -1493,15 +1507,19 @@ static const JSCFunctionListEntry js_std_funcs[] = {
14931507
JS_CFUNC_DEF("setenv", 1, js_std_setenv ),
14941508
JS_CFUNC_DEF("unsetenv", 1, js_std_unsetenv ),
14951509
JS_CFUNC_DEF("getenviron", 1, js_std_getenviron ),
1510+
#if !defined(__wasi__)
14961511
JS_CFUNC_DEF("urlGet", 1, js_std_urlGet ),
1512+
#endif
14971513
JS_CFUNC_DEF("loadFile", 1, js_std_loadFile ),
14981514
JS_CFUNC_DEF("strerror", 1, js_std_strerror ),
14991515

15001516
/* FILE I/O */
15011517
JS_CFUNC_DEF("open", 2, js_std_open ),
1518+
#if !defined(__wasi__)
15021519
JS_CFUNC_DEF("popen", 2, js_std_popen ),
1503-
JS_CFUNC_DEF("fdopen", 2, js_std_fdopen ),
15041520
JS_CFUNC_DEF("tmpfile", 0, js_std_tmpfile ),
1521+
#endif
1522+
JS_CFUNC_DEF("fdopen", 2, js_std_fdopen ),
15051523
JS_CFUNC_MAGIC_DEF("puts", 1, js_std_file_puts, 0 ),
15061524
JS_CFUNC_DEF("printf", 1, js_std_printf ),
15071525
JS_CFUNC_DEF("sprintf", 1, js_std_sprintf ),
@@ -1714,7 +1732,7 @@ static JSValue js_os_ttySetRaw(JSContext *ctx, JSValue this_val,
17141732
}
17151733
return JS_UNDEFINED;
17161734
}
1717-
#else
1735+
#elif !defined(__wasi__)
17181736
static JSValue js_os_ttyGetWinSize(JSContext *ctx, JSValue this_val,
17191737
int argc, JSValue *argv)
17201738
{
@@ -1773,7 +1791,7 @@ static JSValue js_os_ttySetRaw(JSContext *ctx, JSValue this_val,
17731791
return JS_UNDEFINED;
17741792
}
17751793

1776-
#endif /* !_WIN32 */
1794+
#endif /* !_WIN32 && !__wasi__ */
17771795

17781796
static JSValue js_os_remove(JSContext *ctx, JSValue this_val,
17791797
int argc, JSValue *argv)
@@ -1967,7 +1985,7 @@ static JSValue js_os_signal(JSContext *ctx, JSValue this_val,
19671985
return JS_UNDEFINED;
19681986
}
19691987

1970-
#ifndef _WIN32
1988+
#if !defined(_WIN32) && !defined(__wasi__)
19711989
static JSValue js_os_cputime(JSContext *ctx, JSValue this_val,
19721990
int argc, JSValue *argv)
19731991
{
@@ -2658,6 +2676,7 @@ static char *realpath(const char *path, char *buf)
26582676
}
26592677
#endif
26602678

2679+
#if !defined(__wasi__)
26612680
/* return [path, errorcode] */
26622681
static JSValue js_os_realpath(JSContext *ctx, JSValue this_val,
26632682
int argc, JSValue *argv)
@@ -2679,8 +2698,9 @@ static JSValue js_os_realpath(JSContext *ctx, JSValue this_val,
26792698
}
26802699
return make_string_error(ctx, buf, err);
26812700
}
2701+
#endif
26822702

2683-
#if !defined(_WIN32)
2703+
#if !defined(_WIN32) && !defined(__wasi__)
26842704
static JSValue js_os_symlink(JSContext *ctx, JSValue this_val,
26852705
int argc, JSValue *argv)
26862706
{
@@ -3593,6 +3613,8 @@ void js_std_set_worker_new_context_func(JSContext *(*func)(JSRuntime *rt))
35933613
#define OS_PLATFORM "netbsd"
35943614
#elif defined(__FreeBSD__)
35953615
#define OS_PLATFORM "freebsd"
3616+
#elif defined(__wasi__)
3617+
#define OS_PLATFORM "wasi"
35963618
#else
35973619
#define OS_PLATFORM "unknown"
35983620
#endif
@@ -3617,8 +3639,10 @@ static const JSCFunctionListEntry js_os_funcs[] = {
36173639
JS_CFUNC_MAGIC_DEF("read", 4, js_os_read_write, 0 ),
36183640
JS_CFUNC_MAGIC_DEF("write", 4, js_os_read_write, 1 ),
36193641
JS_CFUNC_DEF("isatty", 1, js_os_isatty ),
3642+
#if !defined(__wasi__)
36203643
JS_CFUNC_DEF("ttyGetWinSize", 1, js_os_ttyGetWinSize ),
36213644
JS_CFUNC_DEF("ttySetRaw", 1, js_os_ttySetRaw ),
3645+
#endif
36223646
JS_CFUNC_DEF("remove", 1, js_os_remove ),
36233647
JS_CFUNC_DEF("rename", 2, js_os_rename ),
36243648
JS_CFUNC_MAGIC_DEF("setReadHandler", 2, js_os_setReadHandler, 0 ),
@@ -3630,7 +3654,7 @@ static const JSCFunctionListEntry js_os_funcs[] = {
36303654
OS_FLAG(SIGILL),
36313655
OS_FLAG(SIGSEGV),
36323656
OS_FLAG(SIGTERM),
3633-
#if !defined(_WIN32)
3657+
#if !defined(_WIN32) && !defined(__wasi__)
36343658
OS_FLAG(SIGQUIT),
36353659
OS_FLAG(SIGPIPE),
36363660
OS_FLAG(SIGALRM),
@@ -3668,8 +3692,10 @@ static const JSCFunctionListEntry js_os_funcs[] = {
36683692
JS_CFUNC_MAGIC_DEF("stat", 1, js_os_stat, 0 ),
36693693
JS_CFUNC_DEF("utimes", 3, js_os_utimes ),
36703694
JS_CFUNC_DEF("sleep", 1, js_os_sleep ),
3695+
#if !defined(__wasi__)
36713696
JS_CFUNC_DEF("realpath", 1, js_os_realpath ),
3672-
#if !defined(_WIN32)
3697+
#endif
3698+
#if !defined(_WIN32) && !defined(__wasi__)
36733699
JS_CFUNC_MAGIC_DEF("lstat", 1, js_os_stat, 1 ),
36743700
JS_CFUNC_DEF("symlink", 2, js_os_symlink ),
36753701
JS_CFUNC_DEF("readlink", 1, js_os_readlink ),

quickjs.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
#include "libregexp.h"
4444
#include "libbf.h"
4545

46-
#if defined(EMSCRIPTEN) || defined(_MSC_VER)
46+
#if defined(EMSCRIPTEN) || defined(_MSC_VER) || defined(__wasi__)
4747
#define DIRECT_DISPATCH 0
4848
#else
4949
#define DIRECT_DISPATCH 1
@@ -55,7 +55,7 @@
5555
#define MALLOC_OVERHEAD 8
5656
#endif
5757

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

23192319
static void update_stack_limit(JSRuntime *rt)
23202320
{
2321+
#if defined(__wasi__)
2322+
rt->stack_limit = 0; /* no limit */
2323+
#else
23212324
if (rt->stack_size == 0) {
23222325
rt->stack_limit = 0; /* no limit */
23232326
} else {
23242327
rt->stack_limit = rt->stack_top - rt->stack_size;
23252328
}
2329+
#endif
23262330
}
23272331

23282332
void JS_SetMaxStackSize(JSRuntime *rt, size_t stack_size)

quickjs.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,11 @@ static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
249249
#define JS_PROP_DEFINE_PROPERTY (1 << 18) /* internal use */
250250
#define JS_PROP_REFLECT_DEFINE_PROPERTY (1 << 19) /* internal use */
251251

252+
#if defined(__wasi__)
253+
#define JS_DEFAULT_STACK_SIZE 0
254+
#else
252255
#define JS_DEFAULT_STACK_SIZE (256 * 1024)
256+
#endif
253257

254258
/* JS_Eval() flags */
255259
#define JS_EVAL_TYPE_GLOBAL (0 << 0) /* global code (default) */

0 commit comments

Comments
 (0)