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