js_State *js_newstate(js_Alloc alloc, void *actx) { js_State *J; if (!alloc) alloc = js_defaultalloc; J = alloc(actx, NULL, sizeof *J); if (!J) return NULL; memset(J, 0, sizeof(*J)); J->actx = actx; J->alloc = alloc; J->panic = js_defaultpanic; J->stack = alloc(actx, NULL, JS_STACKSIZE * sizeof *J->stack); if (!J->stack) { alloc(actx, NULL, 0); return NULL; } 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); J->GE = J->E; jsB_init(J); return J; }
static js_Object *jsV_newstring(js_State *J, const char *v) { js_Object *obj = jsV_newobject(J, JS_CSTRING, J->String_prototype); obj->u.s.string = js_intern(J, v); /* TODO: js_String */ obj->u.s.length = utflen(v); return obj; }
static void O_create(js_State *J) { js_Object *obj; js_Object *proto; js_Object *props; js_Property *ref; if (js_isobject(J, 1)) proto = js_toobject(J, 1); else if (js_isnull(J, 1)) proto = NULL; else js_typeerror(J, "not an object or null"); obj = jsV_newobject(J, JS_COBJECT, proto); js_pushobject(J, obj); if (js_isdefined(J, 2)) { if (!js_isobject(J, 2)) js_typeerror(J, "not an object"); props = js_toobject(J, 2); for (ref = props->head; ref; ref = ref->next) { if (!(ref->atts & JS_DONTENUM)) { if (ref->value.type != JS_TOBJECT) js_typeerror(J, "not an object"); ToPropertyDescriptor(J, obj, ref->name, ref->value.u.object); } } } }
void jsB_initmath(js_State *J) { js_pushobject(J, jsV_newobject(J, JS_CMATH, J->Object_prototype)); { jsB_propn(J, "E", 2.7182818284590452354); jsB_propn(J, "LN10", 2.302585092994046); jsB_propn(J, "LN2", 0.6931471805599453); jsB_propn(J, "LOG2E", 1.4426950408889634); jsB_propn(J, "LOG10E", 0.4342944819032518); jsB_propn(J, "PI", 3.1415926535897932); jsB_propn(J, "SQRT1_2", 0.7071067811865476); jsB_propn(J, "SQRT2", 1.4142135623730951); jsB_propf(J, "abs", Math_abs, 1); jsB_propf(J, "acos", Math_acos, 1); jsB_propf(J, "asin", Math_asin, 1); jsB_propf(J, "atan", Math_atan, 1); jsB_propf(J, "atan2", Math_atan2, 2); jsB_propf(J, "ceil", Math_ceil, 1); jsB_propf(J, "cos", Math_cos, 1); jsB_propf(J, "exp", Math_exp, 1); jsB_propf(J, "floor", Math_floor, 1); jsB_propf(J, "log", Math_log, 1); jsB_propf(J, "max", Math_max, 0); jsB_propf(J, "min", Math_min, 0); jsB_propf(J, "pow", Math_pow, 2); jsB_propf(J, "random", Math_random, 0); jsB_propf(J, "round", Math_round, 1); jsB_propf(J, "sin", Math_sin, 1); jsB_propf(J, "sqrt", Math_sqrt, 1); jsB_propf(J, "tan", Math_tan, 1); } js_defglobal(J, "Math", JS_DONTENUM); }
void js_newscript(js_State *J, js_Function *fun, js_Environment *scope) { js_Object *obj = jsV_newobject(J, JS_CSCRIPT, NULL); obj->u.f.function = fun; obj->u.f.scope = scope; js_pushobject(J, obj); }
js_Object *jsV_newiterator(js_State *J, js_Object *obj, int own) { js_Object *io = jsV_newobject(J, JS_CITERATOR, NULL); io->u.iter.target = obj; io->u.iter.head = NULL; itwalk(J, io, obj, own); return io; }
void js_newobjectx(js_State *J) { js_Object *prototype = NULL; if (js_isobject(J, -1)) prototype = js_toobject(J, -1); js_pop(J, 1); js_pushobject(J, jsV_newobject(J, JS_COBJECT, prototype)); }
js_State *js_newstate(js_Alloc alloc, void *actx, int flags) { js_State *J; assert(sizeof(js_Value) == 16); assert(offsetof(js_Value, type) == 15); if (!alloc) alloc = js_defaultalloc; J = alloc(actx, NULL, sizeof *J); if (!J) return NULL; memset(J, 0, sizeof(*J)); J->actx = actx; J->alloc = alloc; if (flags & JS_STRICT) J->strict = 1; J->trace[0].name = "?"; J->trace[0].file = "[C]"; J->trace[0].line = 0; J->panic = js_defaultpanic; J->stack = alloc(actx, NULL, JS_STACKSIZE * sizeof *J->stack); if (!J->stack) { alloc(actx, NULL, 0); return NULL; } 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); J->GE = J->E; jsB_init(J); return J; }
void js_newuserdata(js_State *J, const char *tag, void *data) { js_Object *prototype = NULL; js_Object *obj; if (js_isobject(J, -1)) prototype = js_toobject(J, -1); js_pop(J, 1); obj = jsV_newobject(J, JS_CUSERDATA, prototype); obj->u.user.tag = tag; obj->u.user.data = data; js_pushobject(J, obj); }
void js_construct(js_State *J, int n) { js_Object *obj; js_Object *prototype; js_Object *newobj; if (!js_iscallable(J, -n-1)) js_typeerror(J, "called object is not a function"); obj = js_toobject(J, -n-1); /* built-in constructors create their own objects, give them a 'null' this */ if (obj->type == JS_CCFUNCTION && obj->u.c.constructor) { int savebot = BOT; js_pushnull(J); if (n > 0) js_rot(J, n + 1); BOT = TOP - n - 1; jsR_pushtrace(J, obj->u.c.name, "[C]", 0); jsR_callcfunction(J, n, obj->u.c.length, obj->u.c.constructor); --J->tracetop; BOT = savebot; return; } /* extract the function object's prototype property */ js_getproperty(J, -n - 1, "prototype"); if (js_isobject(J, -1)) prototype = js_toobject(J, -1); else prototype = J->Object_prototype; js_pop(J, 1); /* create a new object with above prototype, and shift it into the 'this' slot */ newobj = jsV_newobject(J, JS_COBJECT, prototype); js_pushobject(J, newobj); if (n > 0) js_rot(J, n + 1); /* call the function */ js_call(J, n); /* if result is not an object, return the original object we created */ if (!js_isobject(J, -1)) { js_pop(J, 1); js_pushobject(J, newobj); } }
/* prototype -- constructor */ void js_newcconstructor(js_State *J, js_CFunction cfun, js_CFunction ccon, unsigned int length) { js_Object *obj = jsV_newobject(J, JS_CCFUNCTION, J->Function_prototype); obj->u.c.function = cfun; obj->u.c.constructor = ccon; js_pushobject(J, obj); /* proto obj */ { js_pushnumber(J, length); js_defproperty(J, -2, "length", JS_READONLY | JS_DONTENUM | JS_DONTCONF); js_rot2(J); /* obj proto */ js_copy(J, -2); /* obj proto obj */ js_defproperty(J, -2, "constructor", JS_DONTENUM); js_defproperty(J, -2, "prototype", JS_READONLY | JS_DONTENUM | JS_DONTCONF); } }
void js_newfunction(js_State *J, js_Function *fun, js_Environment *scope) { js_Object *obj = jsV_newobject(J, JS_CFUNCTION, J->Function_prototype); obj->u.f.function = fun; obj->u.f.scope = scope; js_pushobject(J, obj); { js_pushnumber(J, fun->numparams); js_defproperty(J, -2, "length", JS_READONLY | JS_DONTENUM | JS_DONTCONF); js_newobject(J); { js_copy(J, -2); js_defproperty(J, -2, "constructor", JS_DONTENUM); } js_defproperty(J, -2, "prototype", JS_DONTCONF); } }
void js_newuserdatax(js_State *J, const char *tag, void *data, js_HasProperty has, js_Put put, js_Delete jdelete, js_Finalize finalize) { js_Object *prototype = NULL; js_Object *obj; if (js_isobject(J, -1)) prototype = js_toobject(J, -1); js_pop(J, 1); obj = jsV_newobject(J, JS_CUSERDATA, prototype); obj->u.user.tag = tag; obj->u.user.data = data; obj->u.user.has = has; obj->u.user.put = put; obj->u.user.jdelete = jdelete; obj->u.user.finalize = finalize; js_pushobject(J, obj); }
static void jsR_callfunction(js_State *J, unsigned int n, js_Function *F, js_Environment *scope) { js_Value v; unsigned int i; scope = jsR_newenvironment(J, jsV_newobject(J, JS_COBJECT, NULL), scope); jsR_savescope(J, scope); if (F->arguments) { js_newobject(J); if (!J->strict) { js_currentfunction(J); js_defproperty(J, -2, "callee", JS_DONTENUM); } js_pushnumber(J, n); js_defproperty(J, -2, "length", JS_DONTENUM); for (i = 0; i < n; ++i) { js_copy(J, i + 1); js_setindex(J, -2, i); } js_initvar(J, "arguments", -1); js_pop(J, 1); } for (i = 0; i < F->numparams; ++i) { if (i < n) js_initvar(J, F->vartab[i], i + 1); else { js_pushundefined(J); js_initvar(J, F->vartab[i], -1); js_pop(J, 1); } } js_pop(J, n); jsR_run(J, F); v = *stackidx(J, -1); TOP = --BOT; /* clear stack */ js_pushvalue(J, v); jsR_restorescope(J); }
void js_newcfunction(js_State *J, js_CFunction cfun, const char *name, unsigned int length) { js_Object *obj = jsV_newobject(J, JS_CCFUNCTION, J->Function_prototype); obj->u.c.name = name; obj->u.c.function = cfun; obj->u.c.constructor = NULL; obj->u.c.length = length; js_pushobject(J, obj); { js_pushnumber(J, length); js_defproperty(J, -2, "length", JS_READONLY | JS_DONTENUM | JS_DONTCONF); js_newobject(J); { js_copy(J, -2); js_defproperty(J, -2, "constructor", JS_DONTENUM); } js_defproperty(J, -2, "prototype", JS_DONTCONF); } }
void js_newobject(js_State *J) { js_pushobject(J, jsV_newobject(J, JS_COBJECT, J->Object_prototype)); }
static void jsR_run(js_State *J, js_Function *F) { js_Function **FT = F->funtab; double *NT = F->numtab; const char **ST = F->strtab; js_Instruction *pcstart = F->code; js_Instruction *pc = F->code; enum js_OpCode opcode; int offset; const char *str; js_Object *obj; double x, y; unsigned int ux, uy; int ix, iy, okay; int b; while (1) { if (J->gccounter > JS_GCLIMIT) { J->gccounter = 0; js_gc(J, 0); } opcode = *pc++; switch (opcode) { case OP_POP: js_pop(J, 1); break; case OP_DUP: js_dup(J); break; case OP_DUP2: js_dup2(J); break; case OP_ROT2: js_rot2(J); break; case OP_ROT3: js_rot3(J); break; case OP_ROT4: js_rot4(J); break; case OP_NUMBER_0: js_pushnumber(J, 0); break; case OP_NUMBER_1: js_pushnumber(J, 1); break; case OP_NUMBER_POS: js_pushnumber(J, *pc++); break; case OP_NUMBER_NEG: js_pushnumber(J, -(*pc++)); break; case OP_NUMBER: js_pushnumber(J, NT[*pc++]); break; case OP_STRING: js_pushliteral(J, ST[*pc++]); break; case OP_CLOSURE: js_newfunction(J, FT[*pc++], J->E); break; case OP_NEWOBJECT: js_newobject(J); break; case OP_NEWARRAY: js_newarray(J); break; case OP_NEWREGEXP: js_newregexp(J, ST[pc[0]], pc[1]); pc += 2; break; case OP_UNDEF: js_pushundefined(J); break; case OP_NULL: js_pushnull(J); break; case OP_TRUE: js_pushboolean(J, 1); break; case OP_FALSE: js_pushboolean(J, 0); break; case OP_THIS: js_copy(J, 0); break; case OP_GLOBAL: js_pushobject(J, J->G); break; case OP_CURRENT: js_currentfunction(J); break; case OP_INITLOCAL: STACK[BOT + *pc++] = STACK[--TOP]; break; case OP_GETLOCAL: CHECKSTACK(1); STACK[TOP++] = STACK[BOT + *pc++]; break; case OP_SETLOCAL: STACK[BOT + *pc++] = STACK[TOP-1]; break; case OP_DELLOCAL: ++pc; js_pushboolean(J, 0); break; case OP_INITVAR: js_initvar(J, ST[*pc++], -1); js_pop(J, 1); break; case OP_DEFVAR: js_defvar(J, ST[*pc++]); break; case OP_GETVAR: str = ST[*pc++]; if (!js_hasvar(J, str)) js_referenceerror(J, "'%s' is not defined", str); break; case OP_HASVAR: if (!js_hasvar(J, ST[*pc++])) js_pushundefined(J); break; case OP_SETVAR: js_setvar(J, ST[*pc++]); break; case OP_DELVAR: b = js_delvar(J, ST[*pc++]); js_pushboolean(J, b); break; case OP_IN: str = js_tostring(J, -2); if (!js_isobject(J, -1)) js_typeerror(J, "operand to 'in' is not an object"); b = js_hasproperty(J, -1, str); js_pop(J, 2 + b); js_pushboolean(J, b); break; case OP_INITPROP: obj = js_toobject(J, -3); str = js_tostring(J, -2); jsR_setproperty(J, obj, str, stackidx(J, -1)); js_pop(J, 2); break; case OP_INITGETTER: obj = js_toobject(J, -3); str = js_tostring(J, -2); jsR_defproperty(J, obj, str, 0, NULL, jsR_tofunction(J, -1), NULL); js_pop(J, 2); break; case OP_INITSETTER: obj = js_toobject(J, -3); str = js_tostring(J, -2); jsR_defproperty(J, obj, str, 0, NULL, NULL, jsR_tofunction(J, -1)); js_pop(J, 2); break; case OP_GETPROP: str = js_tostring(J, -1); obj = js_toobject(J, -2); jsR_getproperty(J, obj, str); js_rot3pop2(J); break; case OP_GETPROP_S: str = ST[*pc++]; obj = js_toobject(J, -1); jsR_getproperty(J, obj, str); js_rot2pop1(J); break; case OP_SETPROP: str = js_tostring(J, -2); obj = js_toobject(J, -3); jsR_setproperty(J, obj, str, stackidx(J, -1)); js_rot3pop2(J); break; case OP_SETPROP_S: str = ST[*pc++]; obj = js_toobject(J, -2); jsR_setproperty(J, obj, str, stackidx(J, -1)); js_rot2pop1(J); break; case OP_DELPROP: str = js_tostring(J, -1); obj = js_toobject(J, -2); b = jsR_delproperty(J, obj, str); js_pop(J, 2); js_pushboolean(J, b); break; case OP_DELPROP_S: str = ST[*pc++]; obj = js_toobject(J, -1); b = jsR_delproperty(J, obj, str); js_pop(J, 1); js_pushboolean(J, b); break; case OP_ITERATOR: if (!js_isundefined(J, -1) && !js_isnull(J, -1)) { obj = jsV_newiterator(J, js_toobject(J, -1), 0); js_pop(J, 1); js_pushobject(J, obj); } break; case OP_NEXTITER: obj = js_toobject(J, -1); str = jsV_nextiterator(J, obj); if (str) { js_pushliteral(J, str); js_pushboolean(J, 1); } else { js_pop(J, 1); js_pushboolean(J, 0); } break; /* Function calls */ case OP_EVAL: js_eval(J); break; case OP_CALL: js_call(J, *pc++); break; case OP_NEW: js_construct(J, *pc++); break; /* Unary operators */ case OP_TYPEOF: str = js_typeof(J, -1); js_pop(J, 1); js_pushliteral(J, str); break; case OP_POS: x = js_tonumber(J, -1); js_pop(J, 1); js_pushnumber(J, x); break; case OP_NEG: x = js_tonumber(J, -1); js_pop(J, 1); js_pushnumber(J, -x); break; case OP_BITNOT: ix = js_toint32(J, -1); js_pop(J, 1); js_pushnumber(J, ~ix); break; case OP_LOGNOT: b = js_toboolean(J, -1); js_pop(J, 1); js_pushboolean(J, !b); break; case OP_INC: x = js_tonumber(J, -1); js_pop(J, 1); js_pushnumber(J, x + 1); break; case OP_DEC: x = js_tonumber(J, -1); js_pop(J, 1); js_pushnumber(J, x - 1); break; case OP_POSTINC: x = js_tonumber(J, -1); js_pop(J, 1); js_pushnumber(J, x + 1); js_pushnumber(J, x); break; case OP_POSTDEC: x = js_tonumber(J, -1); js_pop(J, 1); js_pushnumber(J, x - 1); js_pushnumber(J, x); break; /* Multiplicative operators */ case OP_MUL: x = js_tonumber(J, -2); y = js_tonumber(J, -1); js_pop(J, 2); js_pushnumber(J, x * y); break; case OP_DIV: x = js_tonumber(J, -2); y = js_tonumber(J, -1); js_pop(J, 2); js_pushnumber(J, x / y); break; case OP_MOD: x = js_tonumber(J, -2); y = js_tonumber(J, -1); js_pop(J, 2); js_pushnumber(J, fmod(x, y)); break; /* Additive operators */ case OP_ADD: js_concat(J); break; case OP_SUB: x = js_tonumber(J, -2); y = js_tonumber(J, -1); js_pop(J, 2); js_pushnumber(J, x - y); break; /* Shift operators */ case OP_SHL: ix = js_toint32(J, -2); uy = js_touint32(J, -1); js_pop(J, 2); js_pushnumber(J, ix << (uy & 0x1F)); break; case OP_SHR: ix = js_toint32(J, -2); uy = js_touint32(J, -1); js_pop(J, 2); js_pushnumber(J, ix >> (uy & 0x1F)); break; case OP_USHR: ux = js_touint32(J, -2); uy = js_touint32(J, -1); js_pop(J, 2); js_pushnumber(J, ux >> (uy & 0x1F)); break; /* Relational operators */ case OP_LT: b = js_compare(J, &okay); js_pop(J, 2); js_pushboolean(J, okay && b < 0); break; case OP_GT: b = js_compare(J, &okay); js_pop(J, 2); js_pushboolean(J, okay && b > 0); break; case OP_LE: b = js_compare(J, &okay); js_pop(J, 2); js_pushboolean(J, okay && b <= 0); break; case OP_GE: b = js_compare(J, &okay); js_pop(J, 2); js_pushboolean(J, okay && b >= 0); break; case OP_INSTANCEOF: b = js_instanceof(J); js_pop(J, 2); js_pushboolean(J, b); break; /* Equality */ case OP_EQ: b = js_equal(J); js_pop(J, 2); js_pushboolean(J, b); break; case OP_NE: b = js_equal(J); js_pop(J, 2); js_pushboolean(J, !b); break; case OP_STRICTEQ: b = js_strictequal(J); js_pop(J, 2); js_pushboolean(J, b); break; case OP_STRICTNE: b = js_strictequal(J); js_pop(J, 2); js_pushboolean(J, !b); break; case OP_JCASE: offset = *pc++; b = js_strictequal(J); if (b) { js_pop(J, 2); pc = pcstart + offset; } else { js_pop(J, 1); } break; /* Binary bitwise operators */ case OP_BITAND: ix = js_toint32(J, -2); iy = js_toint32(J, -1); js_pop(J, 2); js_pushnumber(J, ix & iy); break; case OP_BITXOR: ix = js_toint32(J, -2); iy = js_toint32(J, -1); js_pop(J, 2); js_pushnumber(J, ix ^ iy); break; case OP_BITOR: ix = js_toint32(J, -2); iy = js_toint32(J, -1); js_pop(J, 2); js_pushnumber(J, ix | iy); break; /* Try and Catch */ case OP_THROW: js_throw(J); case OP_TRY: offset = *pc++; if (js_trypc(J, pc)) { pc = J->trybuf[J->trytop].pc; } else { pc = pcstart + offset; } break; case OP_ENDTRY: js_endtry(J); break; case OP_CATCH: str = ST[*pc++]; obj = jsV_newobject(J, JS_COBJECT, NULL); js_pushobject(J, obj); js_rot2(J); js_setproperty(J, -2, str); J->E = jsR_newenvironment(J, obj, J->E); js_pop(J, 1); break; case OP_ENDCATCH: J->E = J->E->outer; break; /* With */ case OP_WITH: obj = js_toobject(J, -1); J->E = jsR_newenvironment(J, obj, J->E); js_pop(J, 1); break; case OP_ENDWITH: J->E = J->E->outer; break; /* Branching */ case OP_DEBUGGER: js_trap(J, (int)(pc - pcstart) - 1); break; case OP_JUMP: pc = pcstart + *pc; break; case OP_JTRUE: offset = *pc++; b = js_toboolean(J, -1); js_pop(J, 1); if (b) pc = pcstart + offset; break; case OP_JFALSE: offset = *pc++; b = js_toboolean(J, -1); js_pop(J, 1); if (!b) pc = pcstart + offset; break; case OP_RETURN: return; case OP_LINE: J->trace[J->tracetop].line = *pc++; break; } } }
void jsB_init(js_State *J) { /* Create the prototype objects here, before the constructors */ J->Object_prototype = jsV_newobject(J, JS_COBJECT, NULL); J->Array_prototype = jsV_newobject(J, JS_CARRAY, J->Object_prototype); J->Function_prototype = jsV_newobject(J, JS_CCFUNCTION, J->Object_prototype); J->Boolean_prototype = jsV_newobject(J, JS_CBOOLEAN, J->Object_prototype); J->Number_prototype = jsV_newobject(J, JS_CNUMBER, J->Object_prototype); J->String_prototype = jsV_newobject(J, JS_CSTRING, J->Object_prototype); J->RegExp_prototype = jsV_newobject(J, JS_COBJECT, J->Object_prototype); J->Date_prototype = jsV_newobject(J, JS_CDATE, J->Object_prototype); /* All the native error types */ J->Error_prototype = jsV_newobject(J, JS_CERROR, J->Object_prototype); J->EvalError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype); J->RangeError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype); J->ReferenceError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype); J->SyntaxError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype); J->TypeError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype); J->URIError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype); /* Create the constructors and fill out the prototype objects */ jsB_initobject(J); jsB_initarray(J); jsB_initfunction(J); jsB_initboolean(J); jsB_initnumber(J); jsB_initstring(J); jsB_initregexp(J); jsB_initdate(J); jsB_initerror(J); jsB_initmath(J); jsB_initjson(J); /* Initialize the global object */ js_pushnumber(J, NAN); js_defglobal(J, "NaN", JS_READONLY | JS_DONTENUM | JS_DONTCONF); js_pushnumber(J, INFINITY); js_defglobal(J, "Infinity", JS_READONLY | JS_DONTENUM | JS_DONTCONF); js_pushundefined(J); js_defglobal(J, "undefined", JS_READONLY | JS_DONTENUM | JS_DONTCONF); jsB_globalf(J, "eval", jsB_eval, 1); jsB_globalf(J, "parseInt", jsB_parseInt, 1); jsB_globalf(J, "parseFloat", jsB_parseFloat, 1); jsB_globalf(J, "isNaN", jsB_isNaN, 1); jsB_globalf(J, "isFinite", jsB_isFinite, 1); jsB_globalf(J, "decodeURI", jsB_decodeURI, 1); jsB_globalf(J, "decodeURIComponent", jsB_decodeURIComponent, 1); jsB_globalf(J, "encodeURI", jsB_encodeURI, 1); jsB_globalf(J, "encodeURIComponent", jsB_encodeURIComponent, 1); }
void js_newarray(js_State *J) { js_pushobject(J, jsV_newobject(J, JS_CARRAY, J->Array_prototype)); }
void js_newarguments(js_State *J) { js_pushobject(J, jsV_newobject(J, JS_CARGUMENTS, J->Object_prototype)); }
static js_Object *jsV_newnumber(js_State *J, double v) { js_Object *obj = jsV_newobject(J, JS_CNUMBER, J->Number_prototype); obj->u.number = v; return obj; }
static js_Object *jsV_newboolean(js_State *J, int v) { js_Object *obj = jsV_newobject(J, JS_CBOOLEAN, J->Boolean_prototype); obj->u.boolean = v; return obj; }