Put js_Object contents in a union.

This commit is contained in:
Tor Andersson
2014-01-19 13:29:38 +01:00
parent 0feb630124
commit 95ac24c7cf
11 changed files with 87 additions and 89 deletions

View File

@@ -17,23 +17,23 @@ static int jsB_Boolean(js_State *J, int n)
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));
{

View File

@@ -61,8 +61,8 @@ static int Fp_call(js_State *J, int n)
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));
{

View File

@@ -17,27 +17,27 @@ static int jsB_Number(js_State *J, int n)
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;
}
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_toFixed(js_State *J, int n)
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,17 +56,17 @@ static int Np_toExponential(js_State *J, int n)
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;
}
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));
{

View File

@@ -23,8 +23,8 @@ static int jsB_Object(js_State *J, int n)
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,21 +50,21 @@ static int Op_valueOf(js_State *J, int n)
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;
}
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_isPrototypeOf(js_State *J, int n)
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;
}

View File

@@ -18,17 +18,17 @@ static int jsB_String(js_State *J, int n)
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 @@ static int S_fromCharCode(js_State *J, int n)
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));
{

View File

@@ -674,15 +674,15 @@ void js_dumpvalue(js_State *J, js_Value v)
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;

10
jsgc.c
View File

@@ -69,10 +69,12 @@ static void jsG_markobject(js_State *J, int mark, js_Object *obj)
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)

View File

@@ -7,52 +7,53 @@
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}

View File

@@ -31,12 +31,6 @@ enum js_Class {
JS_CMATH,
};
enum {
JS_PWRITABLE = 1,
JS_PENUMERABLE = 2,
JS_PCONFIGURABLE = 4,
};
enum {
JS_HNONE,
JS_HNUMBER,
@@ -63,12 +57,15 @@ struct js_Object
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 @@ struct js_Property
const char *name;
js_Property *left, *right;
int level;
unsigned short readonly, dontenum, dontconf;
js_Value value;
int flags;
};
/* jsvalue.c */

View File

@@ -27,9 +27,11 @@ static js_Property *newproperty(js_State *J, const char *name)
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 @@ found:
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 @@ js_Object *jsR_newobject(js_State *J, js_Class type, js_Object *prototype)
obj->type = type;
obj->properties = &sentinel;
obj->prototype = prototype;
obj->primitive.number = 0;
obj->scope = NULL;
obj->function = NULL;
obj->cfunction = NULL;
return obj;
}

14
jsrun.c
View File

@@ -393,11 +393,11 @@ void js_call(js_State *J, int n)
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 @@ void js_construct(js_State *J, int n)
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 jsR_dumpenvironment(js_State *J, js_Environment *E, int d)
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);