diff --git a/src/exports.c b/src/exports.c index bf89241..7dc7bc3 100644 --- a/src/exports.c +++ b/src/exports.c @@ -118,7 +118,7 @@ BOOL init(const char* init, int alertOnError) { ctx = JS_NewContext(runtime); globalAlertOnError = alertOnError; - result = JS_Eval(ctx, init, strlen(init), "", JS_EVAL_TYPE_GLOBAL); + result = JS_Eval(ctx, init, strlen(init), "", JS_EVAL_TYPE_GLOBAL); if (buildAndPrintError(result, alertOnError)) { JS_FreeValue(ctx, result); return FALSE; diff --git a/src/myjs.js b/src/myjs.js index 83dc85d..1c3515c 100644 --- a/src/myjs.js +++ b/src/myjs.js @@ -21,15 +21,20 @@ mergeInto(LibraryManager.library, { $externals__postset: "externals();", $externals: function () { - _callExternalFunction = (name, args) => { + _callExternalFunction = (name, args, isError) => { name = UTF8ToString(name); args = args !== null ? JSON.parse(UTF8ToString(args)) : []; - const result = Module["externalCall"](name, args); - if (!result) { - return null; - } + try { + const result = Module["externalCall"](name, args); + if (!result) { + return null; + } - return stringToNewUTF8(result); + return stringToNewUTF8(result); + } catch (error) { + Module["HEAPU8"][isError] = 1; + return stringToNewUTF8(error.message); + } }; }, callExternalFunction: function () {}, diff --git a/src/quickjs_extra.c b/src/quickjs_extra.c index 0823d25..0b22c8b 100644 --- a/src/quickjs_extra.c +++ b/src/quickjs_extra.c @@ -53,11 +53,12 @@ static JSValue js_dump(JSContext *ctx, JSValueConst this_val, } #define CALLEXTERNALFUNCTION JS_CFUNC_DEF("callExternalFunction", 2, js_callExternalFunction), -extern const char* callExternalFunction(const char*, const char*); +extern const char* callExternalFunction(const char*, const char*, char* isError); static JSValue js_callExternalFunction(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { const char *name, *str = NULL, *result; + char isError = 0; JSValue json, obj; if (argc < 1 || argc > 2) { @@ -83,7 +84,7 @@ static JSValue js_callExternalFunction(JSContext *ctx, JSValueConst this_val, } } - result = callExternalFunction(name, str); + result = callExternalFunction(name, str, &isError); JS_FreeCString(ctx, name); JS_FreeCString(ctx, str); @@ -91,7 +92,21 @@ static JSValue js_callExternalFunction(JSContext *ctx, JSValueConst this_val, return JS_UNDEFINED; } - obj = JS_ParseJSON(ctx, result, strlen(result), ""); + if (likely(!isError)) { + obj = JS_ParseJSON(ctx, result, strlen(result), ""); + } else { + obj = JS_NewError(ctx); + if (unlikely(JS_IsException(obj))) { + /* out of memory: throw JS_NULL to avoid recursing */ + obj = JS_NULL; + } else { + JS_DefinePropertyValue(ctx, obj, JS_ATOM_message, + JS_NewString(ctx, result), + JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); + } + + obj = JS_Throw(ctx, obj); + } #ifdef free #undef free #endif