remove js stdlib for better compatibility

This commit is contained in:
Alexander Klingenbeck 2023-05-23 17:45:10 +02:00
parent 3129168b27
commit c8b1892307
3 changed files with 207 additions and 9 deletions

View File

@ -11,13 +11,13 @@ set(quickjs_version 2021-03-27)
set(quickjs_sources_root ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/quickjs)
set(quickjs_sources
${quickjs_sources_root}/quickjs.h
${quickjs_sources_root}/quickjs-libc.h
#${quickjs_sources_root}/quickjs-libc.h
${quickjs_sources_root}/quickjs.c
${quickjs_sources_root}/libregexp.c
${quickjs_sources_root}/libunicode.c
${quickjs_sources_root}/libbf.c
${quickjs_sources_root}/cutils.c
${quickjs_sources_root}/quickjs-libc.c
#${quickjs_sources_root}/quickjs-libc.c
)
add_library(quickjs STATIC
${quickjs_sources}

View File

@ -1,8 +1,8 @@
import { Timers } from "./common/timers.js"
const timers = new Timers()
console.log(clamp(-1.5,0,5))
console.log(vector2Distance(new Vector2(0,0), new Vector2(1,0)))
traceLog(LOG_INFO, clamp(-1.5,0,5))
traceLog(LOG_INFO, vector2Distance(new Vector2(0,0), new Vector2(1,0)))
initWindow(640, 480, "Javascript Tests")
const pos = new Vector2(getScreenWidth()/2,getScreenHeight()/2)

View File

@ -1,5 +1,9 @@
#include <stdbool.h>
#include <assert.h>
#include <limits.h>
#include <errno.h>
#include <quickjs.h>
#include <quickjs-libc.h>
//#include <quickjs-libc.h>
#include <raylib.h>
@ -12,6 +16,72 @@ static int eval_buf(JSContext *ctx, const void *buf, int buf_len,
static JSRuntime* rt;
static JSContext* ctx;
static void pstrcpy(char *buf, int buf_size, const char *str)
{
int c;
char *q = buf;
if (buf_size <= 0)
return;
for(;;) {
c = *str++;
if (c == 0 || q >= buf + buf_size - 1)
break;
*q++ = c;
}
*q = '\0';
}
/* strcat and truncate. */
static char *pstrcat(char *buf, int buf_size, const char *s)
{
int len;
len = strlen(buf);
if (len < buf_size)
pstrcpy(buf + len, buf_size - len, s);
return buf;
}
static void js_dump_obj(JSContext *ctx, FILE *f, JSValueConst val)
{
const char *str;
str = JS_ToCString(ctx, val);
if (str) {
fprintf(f, "%s\n", str);
JS_FreeCString(ctx, str);
} else {
fprintf(f, "[exception]\n");
}
}
static void js_std_dump_error1(JSContext *ctx, JSValueConst exception_val)
{
JSValue val;
bool is_error;
is_error = JS_IsError(ctx, exception_val);
js_dump_obj(ctx, stderr, exception_val);
if (is_error) {
val = JS_GetPropertyStr(ctx, exception_val, "stack");
if (!JS_IsUndefined(val)) {
js_dump_obj(ctx, stderr, val);
}
JS_FreeValue(ctx, val);
}
}
static void js_std_dump_error(JSContext *ctx)
{
JSValue exception_val;
exception_val = JS_GetException(ctx);
js_std_dump_error1(ctx, exception_val);
JS_FreeValue(ctx, exception_val);
}
int app_update_quickjs(){
JSContext *ctx1;
int err;
@ -29,6 +99,104 @@ int app_update_quickjs(){
return 0;
}
static int js_module_set_import_meta(JSContext *ctx, JSValueConst func_val,
JS_BOOL use_realpath, JS_BOOL is_main)
{
JSModuleDef *m;
char buf[1024 + 16];
JSValue meta_obj;
JSAtom module_name_atom;
const char *module_name;
assert(JS_VALUE_GET_TAG(func_val) == JS_TAG_MODULE);
m = JS_VALUE_GET_PTR(func_val);
module_name_atom = JS_GetModuleName(ctx, m);
module_name = JS_AtomToCString(ctx, module_name_atom);
JS_FreeAtom(ctx, module_name_atom);
if (!module_name)
return -1;
if (!strchr(module_name, ':')) {
strcpy(buf, "file://");
#if !defined(_WIN32)
/* realpath() cannot be used with modules compiled with qjsc
because the corresponding module source code is not
necessarily present */
if (use_realpath) {
char *res = realpath(module_name, buf + strlen(buf));
if (!res) {
JS_ThrowTypeError(ctx, "realpath failure");
JS_FreeCString(ctx, module_name);
return -1;
}
} else
#endif
{
pstrcat(buf, sizeof(buf), module_name);
}
} else {
pstrcpy(buf, sizeof(buf), module_name);
}
JS_FreeCString(ctx, module_name);
meta_obj = JS_GetImportMeta(ctx, m);
if (JS_IsException(meta_obj))
return -1;
JS_DefinePropertyValueStr(ctx, meta_obj, "url",
JS_NewString(ctx, buf),
JS_PROP_C_W_E);
JS_DefinePropertyValueStr(ctx, meta_obj, "main",
JS_NewBool(ctx, is_main),
JS_PROP_C_W_E);
JS_FreeValue(ctx, meta_obj);
return 0;
}
static uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename)
{
FILE *f;
uint8_t *buf;
size_t buf_len;
long lret;
f = fopen(filename, "rb");
if (!f)
return NULL;
if (fseek(f, 0, SEEK_END) < 0)
goto fail;
lret = ftell(f);
if (lret < 0)
goto fail;
/* XXX: on Linux, ftell() return LONG_MAX for directories */
if (lret == LONG_MAX) {
errno = EISDIR;
goto fail;
}
buf_len = lret;
if (fseek(f, 0, SEEK_SET) < 0)
goto fail;
if (ctx)
buf = js_malloc(ctx, buf_len + 1);
else
buf = malloc(buf_len + 1);
if (!buf)
goto fail;
if (fread(buf, 1, buf_len, f) != buf_len) {
errno = EIO;
if (ctx)
js_free(ctx, buf);
else
free(buf);
fail:
fclose(f);
return NULL;
}
buf[buf_len] = '\0';
fclose(f);
*pbuf_len = buf_len;
return buf;
}
void SetModelMaterial(Model *model, int materialIndex, Material material)
{
if(model->materialCount <= materialIndex) return;
@ -38,6 +206,36 @@ void SetModelMaterial(Model *model, int materialIndex, Material material)
#include "bindings/js_raylib_core.h"
JSModuleDef *js_module_loader(JSContext *ctx,
const char *module_name, void *opaque)
{
JSModuleDef *m;
size_t buf_len;
uint8_t *buf;
JSValue func_val;
buf = js_load_file(ctx, &buf_len, module_name);
if (!buf) {
JS_ThrowReferenceError(ctx, "could not load module filename '%s'", module_name);
return NULL;
}
/* compile the module */
func_val = JS_Eval(ctx, (char *)buf, buf_len, module_name,
JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
js_free(ctx, buf);
if (JS_IsException(func_val))
return NULL;
/* XXX: could propagate the exception */
js_module_set_import_meta(ctx, func_val, true, false);
/* the module is already referenced, so we must free it */
m = JS_VALUE_GET_PTR(func_val);
JS_FreeValue(ctx, func_val);
return m;
}
int app_init_quickjs(int argc, char** argv){
TraceLog(LOG_INFO, "Starting QuickJS");
rt = JS_NewRuntime();
@ -46,8 +244,8 @@ int app_init_quickjs(int argc, char** argv){
fprintf(stderr, "qjs: cannot allocate JS runtime\n");
return -1;
}
js_std_set_worker_new_context_func(JS_NewCustomContext);
js_std_init_handlers(rt);
//js_std_set_worker_new_context_func(JS_NewCustomContext);
//js_std_init_handlers(rt);
ctx = JS_NewCustomContext(rt);
if (!ctx) {
fprintf(stderr, "qjs: cannot allocate JS context\n");
@ -56,7 +254,7 @@ int app_init_quickjs(int argc, char** argv){
JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
js_std_add_helpers(ctx, argc, argv);
//js_std_add_helpers(ctx, argc, argv);
const char *str = "import * as rl from 'raylib'\n"
"for (const key in rl) { globalThis[key] = rl[key] }\n";
@ -118,7 +316,7 @@ static JSContext *JS_NewCustomContext(JSRuntime *rt)
return NULL;
/* system modules */
js_init_module_std(ctx, "std");
//js_init_module_std(ctx, "std");
//js_init_module_os(ctx, "os");
js_init_module_raylib_core(ctx, "raylib");
return ctx;