shithub: libmujs

Download patch

ref: abd59674ccfd3d4285e475e667458d7c2dc65b74
parent: 67b33c5a86ad6656744f6eb51b3d9ed0686fc4f2
author: Tor Andersson <tor@ccxvii.net>
date: Fri Feb 28 12:13:01 EST 2014

Allow custom allocator.

--- a/js.h
+++ b/js.h
@@ -26,10 +26,11 @@
 
 typedef struct js_State js_State;
 
+typedef void *(*js_Alloc)(void *memctx, void *ptr, unsigned int size);
 typedef void (*js_CFunction)(js_State *J, unsigned int argc);
 
 /* Basic functions */
-js_State *js_newstate(void);
+js_State *js_newstate(js_Alloc afun, void *actx);
 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/jsgc.c
+++ b/jsgc.c
@@ -204,6 +204,6 @@
 	jsS_freestrings(J);
 
 	js_free(J, J->lexbuf.text);
-	free(J->stack);
-	free(J);
+	J->alloc(J->actx, J->stack, 0);
+	J->alloc(J->actx, J, 0);
 }
--- a/jsi.h
+++ b/jsi.h
@@ -29,8 +29,8 @@
 
 #define nelem(a) (sizeof (a) / sizeof (a)[0])
 
-void *js_malloc(js_State *J, size_t size);
-void *js_realloc(js_State *J, void *ptr, size_t size);
+void *js_malloc(js_State *J, unsigned int size);
+void *js_realloc(js_State *J, void *ptr, unsigned int size);
 void js_free(js_State *J, void *ptr);
 
 typedef struct js_Regexp js_Regexp;
@@ -101,6 +101,9 @@
 
 struct js_State
 {
+	void *actx;
+	js_Alloc alloc;
+
 	js_StringNode *strings;
 
 	/* parser input source */
@@ -109,7 +112,7 @@
 	int line;
 
 	/* lexer state */
-	struct { char *text; size_t len, cap; } lexbuf;
+	struct { char *text; unsigned int len, cap; } lexbuf;
 	int lexline;
 	int lexchar;
 	int lasttoken;
--- a/jsrun.c
+++ b/jsrun.c
@@ -29,17 +29,17 @@
 	js_throw(J);
 }
 
-void *js_malloc(js_State *J, size_t size)
+void *js_malloc(js_State *J, unsigned int size)
 {
-	void *ptr = malloc(size);
+	void *ptr = J->alloc(J->actx, NULL, size);
 	if (!ptr)
 		js_outofmemory(J);
 	return ptr;
 }
 
-void *js_realloc(js_State *J, void *ptr, size_t size)
+void *js_realloc(js_State *J, void *ptr, unsigned int size)
 {
-	ptr = realloc(ptr, size);
+	ptr = J->alloc(J->actx, ptr, size);
 	if (!ptr)
 		js_outofmemory(J);
 	return ptr;
@@ -47,7 +47,7 @@
 
 void js_free(js_State *J, void *ptr)
 {
-	free(ptr);
+	J->alloc(J->actx, ptr, 0);
 }
 
 #define CHECKSTACK(n) if (TOP + n >= JS_STACKSIZE) js_stackoverflow(J)
--- a/jsstate.c
+++ b/jsstate.c
@@ -5,6 +5,17 @@
 #include "jsrun.h"
 #include "jsbuiltin.h"
 
+static void *js_defaultalloc(void *actx, void *ptr, unsigned int size)
+{
+	if (size == 0) {
+		free(ptr);
+		return NULL;
+	}
+	if (!ptr)
+		return malloc(size);
+	return realloc(ptr, size);
+}
+
 void js_loadstring(js_State *J, const char *filename, const char *source)
 {
 	js_Ast *P;
@@ -101,16 +112,23 @@
 	return 0;
 }
 
-js_State *js_newstate(void)
+js_State *js_newstate(js_Alloc alloc, void *actx)
 {
-	js_State *J = malloc(sizeof *J);
+	js_State *J;
+
+	if (!alloc)
+		alloc = js_defaultalloc;
+
+	J = alloc(actx, NULL, sizeof *J);
 	if (!J)
 		return NULL;
 	memset(J, 0, sizeof(*J));
+	J->actx = actx;
+	J->alloc = alloc;
 
-	J->stack = malloc(JS_STACKSIZE * sizeof *J->stack);
+	J->stack = alloc(actx, NULL, JS_STACKSIZE * sizeof *J->stack);
 	if (!J->stack) {
-		free(J);
+		alloc(actx, NULL, 0);
 		return NULL;
 	}
 
--- a/main.c
+++ b/main.c
@@ -37,7 +37,7 @@
 	js_State *J;
 	int i;
 
-	J = js_newstate();
+	J = js_newstate(NULL, NULL);
 
 	js_newcfunction(J, jsB_gc, 0);
 	js_setglobal(J, "gc");