shithub: libmujs

Download patch

ref: 222ae8067b179597ab9e99529c39ff30533d6475
parent: b24fe47378839db220e747adba2d9b21386d0b85
author: Tor Andersson <tor@ccxvii.net>
date: Thu Mar 6 17:00:39 EST 2014

Add user customisable panic function.

Intended to let the user longjmp to their own error recovery, if an
error occurs in an unprotected call.

Protected calls so far are only js_newstate, js_dofile and js_dostring.

--- a/js.h
+++ b/js.h
@@ -27,10 +27,12 @@
 typedef struct js_State js_State;
 
 typedef void *(*js_Alloc)(void *memctx, void *ptr, unsigned int size);
+typedef void (*js_Panic)(js_State *J);
 typedef void (*js_CFunction)(js_State *J, unsigned int argc);
 
 /* Basic functions */
-js_State *js_newstate(js_Alloc afun, void *actx);
+js_State *js_newstate(js_Alloc alloc, void *actx);
+js_Panic js_atpanic(js_State *J, js_Panic panic);
 void js_freestate(js_State *J);
 int js_dostring(js_State *J, const char *source, int report);
 int js_dofile(js_State *J, const char *filename);
--- a/jsi.h
+++ b/jsi.h
@@ -103,6 +103,7 @@
 {
 	void *actx;
 	js_Alloc alloc;
+	js_Panic panic;
 
 	js_StringNode *strings;
 
--- a/jsrun.c
+++ b/jsrun.c
@@ -989,7 +989,8 @@
 		js_pushvalue(J, v);
 		longjmp(J->trybuf[J->trylen].buf, 1);
 	}
-	fprintf(stderr, "libjs: uncaught exception!\n");
+	if (J->panic)
+		J->panic(J);
 	abort();
 }
 
--- a/jsstate.c
+++ b/jsstate.c
@@ -16,6 +16,12 @@
 	return realloc(ptr, size);
 }
 
+static void js_defaultpanic(js_State *J)
+{
+	fprintf(stderr, "libjs: uncaught exception: %s\n", js_tostring(J, -1));
+	/* return to javascript to abort */
+}
+
 void js_loadstring(js_State *J, const char *filename, const char *source)
 {
 	js_Ast *P;
@@ -112,6 +118,13 @@
 	return 0;
 }
 
+js_Panic js_atpanic(js_State *J, js_Panic panic)
+{
+	js_Panic old = J->panic;
+	J->panic = panic;
+	return old;
+}
+
 js_State *js_newstate(js_Alloc alloc, void *actx)
 {
 	js_State *J;
@@ -125,6 +138,8 @@
 	memset(J, 0, sizeof(*J));
 	J->actx = actx;
 	J->alloc = alloc;
+
+	J->panic = js_defaultpanic;
 
 	J->stack = alloc(actx, NULL, JS_STACKSIZE * sizeof *J->stack);
 	if (!J->stack) {