diff --git a/jsbboolean.c b/jsbboolean.c index ee43517..67eae5f 100644 --- a/jsbboolean.c +++ b/jsbboolean.c @@ -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)); { diff --git a/jsbfunction.c b/jsbfunction.c index 16549b0..6a9fd91 100644 --- a/jsbfunction.c +++ b/jsbfunction.c @@ -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)); { diff --git a/jsbnumber.c b/jsbnumber.c index 9ce4902..ee704d7 100644 --- a/jsbnumber.c +++ b/jsbnumber.c @@ -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)); { diff --git a/jsbobject.c b/jsbobject.c index a56cf23..23109b5 100644 --- a/jsbobject.c +++ b/jsbobject.c @@ -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; } diff --git a/jsbstring.c b/jsbstring.c index 53bbefa..5c28822 100644 --- a/jsbstring.c +++ b/jsbstring.c @@ -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)); { diff --git a/jsdump.c b/jsdump.c index cfe00c1..b0f9fef 100644 --- a/jsdump.c +++ b/jsdump.c @@ -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("", v.u.object); break; } break; diff --git a/jsgc.c b/jsgc.c index d179c60..23f8a02 100644 --- a/jsgc.c +++ b/jsgc.c @@ -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) diff --git a/jsobject.c b/jsobject.c index 1652581..17dfbcc 100644 --- a/jsobject.c +++ b/jsobject.c @@ -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; } diff --git a/jsobject.h b/jsobject.h index 480d5a9..b62368f 100644 --- a/jsobject.h +++ b/jsobject.h @@ -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 */ diff --git a/jsproperty.c b/jsproperty.c index 95463ce..6b761db 100644 --- a/jsproperty.c +++ b/jsproperty.c @@ -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; } diff --git a/jsrun.c b/jsrun.c index e78e8e3..036f2e5 100644 --- a/jsrun.c +++ b/jsrun.c @@ -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);