145 lines
3.2 KiB
C
145 lines
3.2 KiB
C
#include "script.h"
|
|
#include "jsffi.h"
|
|
#include "stb_ds.h"
|
|
#include <inttypes.h>
|
|
#include <limits.h>
|
|
#include <sys/stat.h>
|
|
#include <errno.h>
|
|
#include <stdarg.h>
|
|
#include "jsffi.h"
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
|
|
static JSContext *js = NULL;
|
|
static JSRuntime *rt = NULL;
|
|
|
|
JSContext *global_js = NULL;
|
|
|
|
JSValue on_exception = JS_UNDEFINED;
|
|
|
|
#ifndef NDEBUG
|
|
#define JS_EVAL_FLAGS JS_EVAL_FLAG_STRICT
|
|
#else
|
|
#define JS_EVAL_FLAGS JS_EVAL_FLAG_STRICT | JS_EVAL_FLAG_STRIP
|
|
#endif
|
|
|
|
static JSValue report_gc;
|
|
|
|
char* read_file(const char* filename) {
|
|
// Open the file in read mode
|
|
FILE *file = fopen(filename, "r");
|
|
if (!file) {
|
|
perror("Failed to open file");
|
|
return NULL;
|
|
}
|
|
|
|
// Seek to the end of the file to get its size
|
|
fseek(file, 0, SEEK_END);
|
|
long file_size = ftell(file);
|
|
fseek(file, 0, SEEK_SET);
|
|
|
|
// Allocate memory for the file content, including the null terminator
|
|
char *content = (char*)malloc(file_size + 1);
|
|
if (!content) {
|
|
perror("Failed to allocate memory");
|
|
fclose(file);
|
|
return NULL;
|
|
}
|
|
|
|
// Read the entire file into the content buffer
|
|
fread(content, 1, file_size, file);
|
|
|
|
// Null-terminate the string
|
|
content[file_size] = '\0';
|
|
|
|
fclose(file);
|
|
return content;
|
|
}
|
|
|
|
int js_interrupt(JSRuntime *rt, void *data)
|
|
{
|
|
// printf("INTERRUPT\n");
|
|
}
|
|
|
|
void script_startup(int argc, char **argv) {
|
|
rt = JS_NewRuntime();
|
|
js = JS_NewContextRaw(rt);
|
|
JS_AddIntrinsicBaseObjects(js);
|
|
JS_AddIntrinsicEval(js);
|
|
JS_AddIntrinsicRegExp(js);
|
|
JS_AddIntrinsicJSON(js);
|
|
JS_AddIntrinsicMapSet(js);
|
|
JS_AddIntrinsicTypedArrays(js);
|
|
JS_AddIntrinsicPromise(js);
|
|
JS_AddIntrinsicProxy(js);
|
|
JS_AddIntrinsicBigInt(js);
|
|
JS_AddIntrinsicBigFloat(js);
|
|
JS_AddIntrinsicBigDecimal(js);
|
|
JS_AddIntrinsicOperators(js);
|
|
|
|
ffi_load(js, argc, argv);
|
|
|
|
char *eng = read_file("core/scripts/engine.js");
|
|
JSValue v = script_eval(js, "core/scripts/engine.js", eng);
|
|
uncaught_exception(js,v);
|
|
free(eng);
|
|
}
|
|
|
|
void script_stop()
|
|
{
|
|
JS_FreeContext(js);
|
|
JS_FreeRuntime(rt);
|
|
JS_FreeValue(js,on_exception);
|
|
|
|
rt = NULL;
|
|
js = NULL;
|
|
}
|
|
|
|
void uncaught_exception(JSContext *js, JSValue v)
|
|
{
|
|
if (!JS_IsException(v)) {
|
|
JS_FreeValue(js,v);
|
|
return;
|
|
}
|
|
|
|
if (!JS_IsUndefined(on_exception)) {
|
|
JSValue ex = JS_GetException(js);
|
|
JSValue ret = JS_Call(js, on_exception, JS_UNDEFINED, 1, &ex);
|
|
JS_FreeValue(js,ret);
|
|
JS_FreeValue(js,ex);
|
|
} else {
|
|
JSValue ex = JS_GetException(js);
|
|
JSValue stack = JS_GetPropertyStr(js,ex,"stack");
|
|
const char *st = JS_ToCString(js,stack);
|
|
printf("Unhandled exception:\n%s\n", st);
|
|
JS_FreeValue(js,stack);
|
|
JS_FreeValue(js,ex);
|
|
}
|
|
|
|
JS_FreeValue(js,v);
|
|
}
|
|
|
|
void script_evalf(const char *format, ...)
|
|
{
|
|
JSValue obj;
|
|
va_list args;
|
|
va_start(args, format);
|
|
int len = vsnprintf(NULL, 0, format, args);
|
|
va_end(args);
|
|
|
|
char *eval = malloc(len+1);
|
|
va_start(args, format);
|
|
vsnprintf(eval, len+1, format, args);
|
|
va_end(args);
|
|
|
|
obj = JS_Eval(js, eval, len, "C eval", JS_EVAL_FLAGS);
|
|
free(eval);
|
|
|
|
uncaught_exception(js,obj);
|
|
}
|
|
|
|
JSValue script_eval(JSContext *js, const char *file, const char *script)
|
|
{
|
|
return JS_Eval(js, script, strlen(script), file, JS_EVAL_FLAGS);
|
|
}
|