shithub: libmujs

Download patch

ref: 3cef8607dca6efac918085f0a1d9aebbbc7da2a8
parent: b22dc395c99510adc9e7f15906accd8897be289c
author: Tor Andersson <[email protected]>
date: Fri Jan 24 11:17:43 EST 2014

Add a registry for stashing hidden javascript objects from C code.

--- a/js.h
+++ b/js.h
@@ -79,6 +79,13 @@
 void js_call(js_State *J, int n);
 void js_construct(js_State *J, int n);
 
+const char *js_ref(js_State *J);
+void js_unref(js_State *J, const char *ref);
+
+void js_getregistry(js_State *J, const char *name);
+void js_setregistry(js_State *J, const char *name);
+void js_delregistry(js_State *J, const char *name);
+
 void js_getglobal(js_State *J, const char *name);
 void js_setglobal(js_State *J, const char *name);
 void js_defglobal(js_State *J, const char *name, int atts);
--- a/jsgc.c
+++ b/jsgc.c
@@ -124,6 +124,7 @@
 	jsG_markobject(J, mark, J->TypeError_prototype);
 	jsG_markobject(J, mark, J->URIError_prototype);
 
+	jsG_markobject(J, mark, J->R);
 	jsG_markobject(J, mark, J->G);
 
 	jsG_markstack(J, mark);
--- a/jsi.h
+++ b/jsi.h
@@ -106,8 +106,10 @@
 	js_Object *TypeError_prototype;
 	js_Object *URIError_prototype;
 
-	js_Object *G;
-	js_Environment *E;
+	int nextref; /* for js_ref use */
+	js_Object *R; /* registry of hidden values */
+	js_Object *G; /* the global object */
+	js_Environment *E; /* current environment scope */
 
 	/* execution stack */
 	int top, bot;
--- a/jsrun.c
+++ b/jsrun.c
@@ -251,7 +251,58 @@
 	STACK[TOP-i] = tmp;
 }
 
-/* Global and object property accessors */
+/* Registry, global and object property accessors */
+
+void js_getregistry(js_State *J, const char *name)
+{
+	js_Property *ref = jsV_getproperty(J, J->R, name);
+	if (ref)
+		js_pushvalue(J, ref->value);
+	else
+		js_pushundefined(J);
+}
+
+void js_setregistry(js_State *J, const char *name)
+{
+	js_Property *ref = jsV_setproperty(J, J->R, name);
+	if (ref)
+		ref->value = js_tovalue(J, -1);
+	js_pop(J, 1);
+}
+
+void js_delregistry(js_State *J, const char *name)
+{
+	// TODO
+}
+
+const char *js_ref(js_State *J)
+{
+	const js_Value *v = stackidx(J, -1);
+	const char *s;
+	char buf[32];
+	switch (v->type) {
+	case JS_TUNDEFINED: s = "_Undefined"; break;
+	case JS_TNULL: s = "_Null"; break;
+	case JS_TBOOLEAN:
+		s = v->u.boolean ? "_True" : "_False";
+		break;
+	case JS_TOBJECT:
+		sprintf(buf, "%p", v->u.object);
+		s = js_intern(J, buf);
+		break;
+	default:
+		sprintf(buf, "%d", J->nextref++);
+		s = js_intern(J, buf);
+		break;
+	}
+	js_setregistry(J, s);
+	return s;
+}
+
+void js_unref(js_State *J, const char *ref)
+{
+	js_delregistry(J, ref);
+}
 
 void js_getglobal(js_State *J, const char *name)
 {
--- a/jsstate.c
+++ b/jsstate.c
@@ -107,7 +107,9 @@
 	J->stack = malloc(JS_STACKSIZE * sizeof *J->stack);
 
 	J->gcmark = 1;
+	J->nextref = 0;
 
+	J->R = jsV_newobject(J, JS_COBJECT, NULL);
 	J->G = jsV_newobject(J, JS_COBJECT, NULL);
 	J->E = jsR_newenvironment(J, J->G, NULL);