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");