119 lines
3.4 KiB
C
119 lines
3.4 KiB
C
#include "asprintf.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <quickjs.h>
|
|
|
|
#include "com_thebrokenrail_scriptcraft_quickjs_QuickJS.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);
|
|
} |