shithub: libmujs

Download patch

ref: 95ac24c7cf5e4e73d60fcf8179c40463a25df680
parent: 0feb630124c74afff1d21473060c3f37f74e6e54
author: Tor Andersson <tor@ccxvii.net>
date: Sun Jan 19 08:29:38 EST 2014

Put js_Object contents in a union.

--- a/jsbboolean.c
+++ b/jsbboolean.c
@@ -17,23 +17,23 @@
 
 static int Bp_toString(js_State *J, int n)
 {
-	js_Object *T = js_toobject(J, 0);
-	if (T->type != JS_CBOOLEAN) jsR_error(J, "TypeError");
-	js_pushliteral(J, T->primitive.boolean ? "true" : "false");
+	js_Object *self = js_toobject(J, 0);
+	if (self->type != JS_CBOOLEAN) jsR_error(J, "TypeError");
+	js_pushliteral(J, self->u.boolean ? "true" : "false");
 	return 1;
 }
 
 static int Bp_valueOf(js_State *J, int n)
 {
-	js_Object *T = js_toobject(J, 0);
-	if (T->type != JS_CBOOLEAN) jsR_error(J, "TypeError");
-	js_pushboolean(J, T->primitive.boolean);
+	js_Object *self = js_toobject(J, 0);
+	if (self->type != JS_CBOOLEAN) jsR_error(J, "TypeError");
+	js_pushboolean(J, self->u.boolean);
 	return 1;
 }
 
 void jsB_initboolean(js_State *J)
 {
-	J->Boolean_prototype->primitive.boolean = 0;
+	J->Boolean_prototype->u.boolean = 0;
 
 	js_pushobject(J, jsR_newcconstructor(J, jsB_Boolean, jsB_new_Boolean));
 	{
--- a/jsbfunction.c
+++ b/jsbfunction.c
@@ -61,8 +61,8 @@
 
 void jsB_initfunction(js_State *J)
 {
-	J->Function_prototype->cfunction = jsB_Function_prototype;
-	J->Function_prototype->cconstructor = NULL;
+	J->Function_prototype->u.c.function = jsB_Function_prototype;
+	J->Function_prototype->u.c.constructor = NULL;
 
 	js_pushobject(J, jsR_newcconstructor(J, jsB_Function, jsB_new_Function));
 	{
--- a/jsbnumber.c
+++ b/jsbnumber.c
@@ -17,17 +17,17 @@
 
 static int Np_valueOf(js_State *J, int n)
 {
-	js_Object *T = js_toobject(J, 0);
-	if (T->type != JS_CNUMBER) jsR_error(J, "TypeError");
-	js_pushnumber(J, T->primitive.number);
+	js_Object *self = js_toobject(J, 0);
+	if (self->type != JS_CNUMBER) jsR_error(J, "TypeError");
+	js_pushnumber(J, self->u.number);
 	return 1;
 }
 
 static int Np_toString(js_State *J, int n)
 {
-	js_Object *T = js_toobject(J, 0);
-	if (T->type != JS_CNUMBER) jsR_error(J, "TypeError");
-	js_pushliteral(J, jsR_numbertostring(J, T->primitive.number));
+	js_Object *self = js_toobject(J, 0);
+	if (self->type != JS_CNUMBER) jsR_error(J, "TypeError");
+	js_pushliteral(J, jsR_numbertostring(J, self->u.number));
 	return 1;
 }
 
@@ -34,10 +34,10 @@
 static int Np_toFixed(js_State *J, int n)
 {
 	char buf[40];
-	js_Object *T = js_toobject(J, 0);
+	js_Object *self = js_toobject(J, 0);
 	int width = js_tonumber(J, 1);
-	if (T->type != JS_CNUMBER) jsR_error(J, "TypeError");
-	sprintf(buf, "%*f", width, T->primitive.number);
+	if (self->type != JS_CNUMBER) jsR_error(J, "TypeError");
+	sprintf(buf, "%*f", width, self->u.number);
 	js_pushstring(J, buf);
 	return 1;
 }
@@ -45,10 +45,10 @@
 static int Np_toExponential(js_State *J, int n)
 {
 	char buf[40];
-	js_Object *T = js_toobject(J, 0);
+	js_Object *self = js_toobject(J, 0);
 	int width = js_tonumber(J, 1);
-	if (T->type != JS_CNUMBER) jsR_error(J, "TypeError");
-	sprintf(buf, "%*e", width, T->primitive.number);
+	if (self->type != JS_CNUMBER) jsR_error(J, "TypeError");
+	sprintf(buf, "%*e", width, self->u.number);
 	js_pushstring(J, buf);
 	return 1;
 }
@@ -56,10 +56,10 @@
 static int Np_toPrecision(js_State *J, int n)
 {
 	char buf[40];
-	js_Object *T = js_toobject(J, 0);
+	js_Object *self = js_toobject(J, 0);
 	int width = js_tonumber(J, 1);
-	if (T->type != JS_CNUMBER) jsR_error(J, "TypeError");
-	sprintf(buf, "%*g", width, T->primitive.number);
+	if (self->type != JS_CNUMBER) jsR_error(J, "TypeError");
+	sprintf(buf, "%*g", width, self->u.number);
 	js_pushstring(J, buf);
 	return 1;
 }
@@ -66,7 +66,7 @@
 
 void jsB_initnumber(js_State *J)
 {
-	J->Number_prototype->primitive.number = 0;
+	J->Number_prototype->u.number = 0;
 
 	js_pushobject(J, jsR_newcconstructor(J, jsB_Number, jsB_new_Number));
 	{
--- a/jsbobject.c
+++ b/jsbobject.c
@@ -23,8 +23,8 @@
 
 static int Op_toString(js_State *J, int n)
 {
-	js_Object *T = js_toobject(J, 0);
-	switch (T->type) {
+	js_Object *self = js_toobject(J, 0);
+	switch (self->type) {
 	case JS_COBJECT: js_pushliteral(J, "[object Object]"); break;
 	case JS_CARRAY: js_pushliteral(J, "[object Array]"); break;
 	case JS_CFUNCTION: js_pushliteral(J, "[object Function]"); break;
@@ -50,9 +50,9 @@
 
 static int Op_hasOwnProperty(js_State *J, int n)
 {
-	js_Object *T = js_toobject(J, 0);
+	js_Object *self = js_toobject(J, 0);
 	const char *name = js_tostring(J, 1);
-	js_Property *ref = jsR_getownproperty(J, T, name);
+	js_Property *ref = jsR_getownproperty(J, self, name);
 	js_pushboolean(J, ref != NULL);
 	return 1;
 }
@@ -59,12 +59,12 @@
 
 static int Op_isPrototypeOf(js_State *J, int n)
 {
-	js_Object *T = js_toobject(J, 0);
+	js_Object *self = js_toobject(J, 0);
 	if (js_isobject(J, 1)) {
 		js_Object *V = js_toobject(J, 1);
 		do {
 			V = V->prototype;
-			if (V == T) {
+			if (V == self) {
 				js_pushboolean(J, 1);
 				return 1;
 			}
@@ -76,10 +76,10 @@
 
 static int Op_propertyIsEnumerable(js_State *J, int n)
 {
-	js_Object *T = js_toobject(J, 0);
+	js_Object *self = js_toobject(J, 0);
 	const char *name = js_tostring(J, 1);
-	js_Property *ref = jsR_getownproperty(J, T, name);
-	js_pushboolean(J, ref && (ref->flags & JS_PENUMERABLE));
+	js_Property *ref = jsR_getownproperty(J, self, name);
+	js_pushboolean(J, ref && !ref->dontenum);
 	return 1;
 }
 
--- a/jsbstring.c
+++ b/jsbstring.c
@@ -18,17 +18,17 @@
 
 static int Sp_toString(js_State *J, int n)
 {
-	js_Object *T = js_toobject(J, 0);
-	if (T->type != JS_CSTRING) jsR_error(J, "TypeError");
-	js_pushliteral(J, T->primitive.string);
+	js_Object *self = js_toobject(J, 0);
+	if (self->type != JS_CSTRING) jsR_error(J, "TypeError");
+	js_pushliteral(J, self->u.string);
 	return 1;
 }
 
 static int Sp_valueOf(js_State *J, int n)
 {
-	js_Object *T = js_toobject(J, 0);
-	if (T->type != JS_CSTRING) jsR_error(J, "TypeError");
-	js_pushliteral(J, T->primitive.string);
+	js_Object *self = js_toobject(J, 0);
+	if (self->type != JS_CSTRING) jsR_error(J, "TypeError");
+	js_pushliteral(J, self->u.string);
 	return 1;
 }
 
@@ -50,7 +50,7 @@
 
 void jsB_initstring(js_State *J)
 {
-	J->String_prototype->primitive.string = "";
+	J->String_prototype->u.string = "";
 
 	js_pushobject(J, jsR_newcconstructor(J, jsB_String, jsB_new_String));
 	{
--- a/jsdump.c
+++ b/jsdump.c
@@ -674,15 +674,15 @@
 		case JS_CFUNCTION:
 			printf("function(%p, %s, %s:%d)",
 				v.u.object,
-				v.u.object->function->name,
-				v.u.object->function->filename,
-				v.u.object->function->line);
+				v.u.object->u.f.function->name,
+				v.u.object->u.f.function->filename,
+				v.u.object->u.f.function->line);
 			break;
-		case JS_CSCRIPT: printf("script(%s)", v.u.object->function->filename); break;
-		case JS_CCFUNCTION: printf("cfunction(%p)", v.u.object->cfunction); break;
-		case JS_CBOOLEAN: printf("boolean(%d)", v.u.object->primitive.boolean); break;
-		case JS_CNUMBER: printf("number(%g)", v.u.object->primitive.number); break;
-		case JS_CSTRING: printf("string('%s')", v.u.object->primitive.string); break;
+		case JS_CSCRIPT: printf("script(%s)", v.u.object->u.f.function->filename); break;
+		case JS_CCFUNCTION: printf("cfunction(%p)", v.u.object->u.c.function); break;
+		case JS_CBOOLEAN: printf("boolean(%d)", v.u.object->u.boolean); break;
+		case JS_CNUMBER: printf("number(%g)", v.u.object->u.number); break;
+		case JS_CSTRING: printf("string('%s')", v.u.object->u.string); break;
 		default: printf("<unknown %p>", v.u.object); break;
 		}
 		break;
--- a/jsgc.c
+++ b/jsgc.c
@@ -69,10 +69,12 @@
 		jsG_markproperty(J, mark, obj->properties);
 	if (obj->prototype && obj->prototype->gcmark != mark)
 		jsG_markobject(J, mark, obj->prototype);
-	if (obj->scope && obj->scope->gcmark != mark)
-		jsG_markenvironment(J, mark, obj->scope);
-	if (obj->function && obj->function->gcmark != mark)
-		jsG_markfunction(J, mark, obj->function);
+	if (obj->type == JS_CFUNCTION || obj->type == JS_CSCRIPT) {
+		if (obj->u.f.scope && obj->u.f.scope->gcmark != mark)
+			jsG_markenvironment(J, mark, obj->u.f.scope);
+		if (obj->u.f.function && obj->u.f.function->gcmark != mark)
+			jsG_markfunction(J, mark, obj->u.f.function);
+	}
 }
 
 static void jsG_markstack(js_State *J, int mark)
--- a/jsobject.c
+++ b/jsobject.c
@@ -7,8 +7,8 @@
 static js_Object *jsR_newfunction(js_State *J, js_Function *function, js_Environment *scope)
 {
 	js_Object *obj = jsR_newobject(J, JS_CFUNCTION, J->Function_prototype);
-	obj->function = function;
-	obj->scope = scope;
+	obj->u.f.function = function;
+	obj->u.f.scope = scope;
 	return obj;
 }
 
@@ -15,7 +15,8 @@
 static js_Object *jsR_newscript(js_State *J, js_Function *function)
 {
 	js_Object *obj = jsR_newobject(J, JS_CSCRIPT, NULL);
-	obj->function = function;
+	obj->u.f.function = function;
+	obj->u.f.scope = NULL;
 	return obj;
 }
 
@@ -22,8 +23,8 @@
 static js_Object *jsR_newcfunction(js_State *J, js_CFunction cfunction)
 {
 	js_Object *obj = jsR_newobject(J, JS_CCFUNCTION, J->Function_prototype);
-	obj->cfunction = cfunction;
-	obj->cconstructor = NULL;
+	obj->u.c.function = cfunction;
+	obj->u.c.constructor = NULL;
 	return obj;
 }
 
@@ -30,8 +31,8 @@
 js_Object *jsR_newcconstructor(js_State *J, js_CFunction cfunction, js_CFunction cconstructor)
 {
 	js_Object *obj = jsR_newobject(J, JS_CCFUNCTION, J->Function_prototype);
-	obj->cfunction = cfunction;
-	obj->cconstructor = cconstructor;
+	obj->u.c.function = cfunction;
+	obj->u.c.constructor = cconstructor;
 	return obj;
 }
 
@@ -38,7 +39,7 @@
 js_Object *jsR_newboolean(js_State *J, int v)
 {
 	js_Object *obj = jsR_newobject(J, JS_CBOOLEAN, J->Boolean_prototype);
-	obj->primitive.boolean = v;
+	obj->u.boolean = v;
 	return obj;
 }
 
@@ -45,7 +46,7 @@
 js_Object *jsR_newnumber(js_State *J, double v)
 {
 	js_Object *obj = jsR_newobject(J, JS_CNUMBER, J->Number_prototype);
-	obj->primitive.number = v;
+	obj->u.number = v;
 	return obj;
 }
 
@@ -52,7 +53,7 @@
 js_Object *jsR_newstring(js_State *J, const char *v)
 {
 	js_Object *obj = jsR_newobject(J, JS_CSTRING, J->String_prototype);
-	obj->primitive.string = v;
+	obj->u.string = v;
 	return obj;
 }
 
--- a/jsobject.h
+++ b/jsobject.h
@@ -32,12 +32,6 @@
 };
 
 enum {
-	JS_PWRITABLE = 1,
-	JS_PENUMERABLE = 2,
-	JS_PCONFIGURABLE = 4,
-};
-
-enum {
 	JS_HNONE,
 	JS_HNUMBER,
 	JS_HSTRING,
@@ -63,12 +57,15 @@
 		int boolean;
 		double number;
 		const char *string;
-	} primitive;
-	js_Environment *scope;
-	js_Function *function;
-	js_CFunction cfunction;
-	js_CFunction cconstructor;
-
+		struct {
+			js_Function *function;
+			js_Environment *scope;
+		} f;
+		struct {
+			js_CFunction function;
+			js_CFunction constructor;
+		} c;
+	} u;
 	js_Object *gcnext;
 	int gcmark;
 };
@@ -78,8 +75,8 @@
 	const char *name;
 	js_Property *left, *right;
 	int level;
+	unsigned short readonly, dontenum, dontconf;
 	js_Value value;
-	int flags;
 };
 
 /* jsvalue.c */
--- a/jsproperty.c
+++ b/jsproperty.c
@@ -27,9 +27,11 @@
 	node->name = js_intern(J, name);
 	node->left = node->right = &sentinel;
 	node->level = 1;
+	node->readonly = 0;
+	node->dontenum = 0;
+	node->dontconf = 0;
 	node->value.type = JS_TUNDEFINED;
 	node->value.u.number = 0;
-	node->flags = 0;
 	return node;
 }
 
@@ -132,7 +134,7 @@
 
 js_Object *jsR_newobject(js_State *J, js_Class type, js_Object *prototype)
 {
-	js_Object *obj = malloc(sizeof(js_Object));
+	js_Object *obj = calloc(sizeof(js_Object), 1);
 	obj->gcmark = 0;
 	obj->gcnext = J->gcobj;
 	J->gcobj = obj;
@@ -141,10 +143,6 @@
 	obj->type = type;
 	obj->properties = &sentinel;
 	obj->prototype = prototype;
-	obj->primitive.number = 0;
-	obj->scope = NULL;
-	obj->function = NULL;
-	obj->cfunction = NULL;
 	return obj;
 }
 
--- a/jsrun.c
+++ b/jsrun.c
@@ -393,11 +393,11 @@
 	int savebot = BOT;
 	BOT = TOP - n - 1;
 	if (obj->type == JS_CFUNCTION)
-		jsR_callfunction(J, n, obj->function, obj->scope);
+		jsR_callfunction(J, n, obj->u.f.function, obj->u.f.scope);
 	else if (obj->type == JS_CSCRIPT)
-		jsR_callscript(J, n, obj->function);
+		jsR_callscript(J, n, obj->u.f.function);
 	else if (obj->type == JS_CCFUNCTION)
-		jsR_callcfunction(J, n, obj->cfunction);
+		jsR_callcfunction(J, n, obj->u.c.function);
 	else
 		jsR_error(J, "TypeError (not a function)");
 	BOT = savebot;
@@ -409,10 +409,10 @@
 	js_Object *prototype;
 
 	/* built-in constructors create their own objects */
-	if (obj->type == JS_CCFUNCTION && obj->cconstructor) {
+	if (obj->type == JS_CCFUNCTION && obj->u.c.constructor) {
 		int savebot = BOT;
 		BOT = TOP - n;
-		jsR_callcfunction(J, n, obj->cconstructor);
+		jsR_callcfunction(J, n, obj->u.c.constructor);
 		BOT = savebot;
 		return;
 	}
@@ -459,8 +459,8 @@
 
 void js_trap(js_State *J, int pc)
 {
-	fprintf(stderr, "trap at %d in ", pc);
-	js_Function *F = STACK[BOT-1].u.object->function;
+	js_Function *F = STACK[BOT-1].u.object->u.f.function;
+	printf("trap at %d in ", pc);
 	jsC_dumpfunction(J, F);
 	jsR_dumpstack(J);
 	jsR_dumpenvironment(J, J->E, 0);