#include "asprintf.h" #include #include #include #include "com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative.h" static JSValue js_print_internal(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int err, int prepend_throw) { int i; char *out; if (prepend_throw) { out = (char *) "Throw: "; } else { out = (char *) ""; } const char *str; for (i = 0; i < argc; i++) { if (i != 0) { asprintf(&out, "%s ", out); } str = JS_ToCString(ctx, argv[i]); if (!str) { return JS_EXCEPTION; } asprintf(&out, "%s%s", out, str); JS_FreeCString(ctx, str); } print_data(out, err); free(out); return JS_UNDEFINED; } static JSValue js_print(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { return js_print_internal(ctx, this_val, argc, argv, 0, 0); } static JSValue js_print_err(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { return js_print_internal(ctx, this_val, argc, argv, 1, 0); } static JSValue js_assert(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { int i; const char *str; if (argc < 1) { return JS_EXCEPTION; } int bool_val = JS_ToBool(ctx, argv[0]); if (bool_val == -1) { return JS_EXCEPTION; } if (!bool_val) { char *out = (char *) "Assertion failed"; for (i = 1; i < argc; i++) { if (i != 1) { asprintf(&out, "%s ", out); } else { asprintf(&out, "%s: ", out); } str = JS_ToCString(ctx, argv[i]); if (!str) { return JS_EXCEPTION; } asprintf(&out, "%s%s", out, str); JS_FreeCString(ctx, str); } print_data(out, 1); free(out); } return JS_UNDEFINED; } static const JSCFunctionListEntry js_console_funcs[] = { JS_CFUNC_DEF("log", 1, js_print), JS_CFUNC_DEF("info", 1, js_print), JS_CFUNC_DEF("warn", 1, js_print), JS_CFUNC_DEF("error", 1, js_print_err), JS_CFUNC_DEF("dir", 1, js_print), JS_CFUNC_DEF("debug", 1, js_print), JS_CFUNC_DEF("trace", 1, js_print), JS_CFUNC_DEF("assert", 1, js_assert), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "Console", JS_PROP_CONFIGURABLE) }; void js_console_init(JSContext *ctx) { JSValue global_obj, console; /* XXX: should these global definitions be enumerable? */ global_obj = JS_GetGlobalObject(ctx); console = JS_NewObject(ctx); JS_SetPropertyFunctionList(ctx, console, js_console_funcs, sizeof js_console_funcs / sizeof (JSCFunctionListEntry)); JS_SetPropertyStr(ctx, global_obj, "console", console); JS_FreeValue(ctx, global_obj); } void js_std_dump_error(JSContext *ctx) { JSValue exception_val, val; const char *stack; int is_error; exception_val = JS_GetException(ctx); is_error = JS_IsError(ctx, exception_val); js_print_internal(ctx, JS_NULL, 1, (JSValueConst *) &exception_val, 1, !is_error); if (is_error) { val = JS_GetPropertyStr(ctx, exception_val, "stack"); if (JS_ToBool(ctx, val)) { stack = JS_ToCString(ctx, val); print_data((char *) stack, 1); JS_FreeCString(ctx, stack); } JS_FreeValue(ctx, val); } JS_FreeValue(ctx, exception_val); }