Beispiel #1
0
/* ToString() on a value */
const char *jsV_tostring(js_State *J, js_Value *v)
{
	char buf[32];
	const char *p;
	switch (v->type) {
	default:
	case JS_TSHRSTR: return v->u.shrstr;
	case JS_TUNDEFINED: return "undefined";
	case JS_TNULL: return "null";
	case JS_TBOOLEAN: return v->u.boolean ? "true" : "false";
	case JS_TLITSTR: return v->u.litstr;
	case JS_TMEMSTR: return v->u.memstr->p;
	case JS_TNUMBER:
		p = jsV_numbertostring(J, buf, v->u.number);
		if (p == buf) {
			unsigned int n = strlen(p);
			if (n <= offsetof(js_Value, type)) {
				char *s = v->u.shrstr;
				while (n--) *s++ = *p++;
				*s = 0;
				v->type = JS_TSHRSTR;
				return v->u.shrstr;
			} else {
				v->type = JS_TMEMSTR;
				v->u.memstr = jsV_newmemstring(J, p, n);
				return v->u.memstr->p;
			}
		}
		return p;
	case JS_TOBJECT:
		jsV_toprimitive(J, v, JS_HSTRING);
		return jsV_tostring(J, v);
	}
}
Beispiel #2
0
int js_equal(js_State *J)
{
	js_Value *x = js_tovalue(J, -2);
	js_Value *y = js_tovalue(J, -1);

retry:
	if (JSV_ISSTRING(x) && JSV_ISSTRING(y))
		return !strcmp(JSV_TOSTRING(x), JSV_TOSTRING(y));
	if (x->type == y->type) {
		if (x->type == JS_TUNDEFINED) return 1;
		if (x->type == JS_TNULL) return 1;
		if (x->type == JS_TNUMBER) return x->u.number == y->u.number;
		if (x->type == JS_TBOOLEAN) return x->u.boolean == y->u.boolean;
		if (x->type == JS_TOBJECT) return x->u.object == y->u.object;
		return 0;
	}

	if (x->type == JS_TNULL && y->type == JS_TUNDEFINED) return 1;
	if (x->type == JS_TUNDEFINED && y->type == JS_TNULL) return 1;

	if (x->type == JS_TNUMBER && JSV_ISSTRING(y))
		return x->u.number == jsV_tonumber(J, y);
	if (JSV_ISSTRING(x) && y->type == JS_TNUMBER)
		return jsV_tonumber(J, x) == y->u.number;

	if (x->type == JS_TBOOLEAN) {
		x->type = JS_TNUMBER;
		x->u.number = x->u.boolean;
		goto retry;
	}
	if (y->type == JS_TBOOLEAN) {
		y->type = JS_TNUMBER;
		y->u.number = y->u.boolean;
		goto retry;
	}
	if ((JSV_ISSTRING(x) || x->type == JS_TNUMBER) && y->type == JS_TOBJECT) {
		jsV_toprimitive(J, y, JS_HNONE);
		goto retry;
	}
	if (x->type == JS_TOBJECT && (JSV_ISSTRING(y) || y->type == JS_TNUMBER)) {
		jsV_toprimitive(J, x, JS_HNONE);
		goto retry;
	}

	return 0;
}
Beispiel #3
0
int js_equal(js_State *J)
{
	js_Value x = js_tovalue(J, -2);
	js_Value y = js_tovalue(J, -1);

retry:
	if (x.type == y.type) {
		if (x.type == JS_TUNDEFINED) return 1;
		if (x.type == JS_TNULL) return 1;
		if (x.type == JS_TNUMBER) return x.u.number == y.u.number;
		if (x.type == JS_TBOOLEAN) return x.u.boolean == y.u.boolean;
		if (x.type == JS_TSTRING) return !strcmp(x.u.string, y.u.string);
		if (x.type == JS_TOBJECT) return x.u.object == y.u.object;
		return 0;
	}

	if (x.type == JS_TNULL && y.type == JS_TUNDEFINED) return 1;
	if (x.type == JS_TUNDEFINED && y.type == JS_TNULL) return 1;

	if (x.type == JS_TNUMBER && y.type == JS_TSTRING)
		return x.u.number == jsV_tonumber(J, &y);
	if (x.type == JS_TSTRING && y.type == JS_TNUMBER)
		return jsV_tonumber(J, &x) == y.u.number;

	if (x.type == JS_TBOOLEAN) {
		x.type = JS_TNUMBER;
		x.u.number = x.u.boolean;
		goto retry;
	}
	if (y.type == JS_TBOOLEAN) {
		y.type = JS_TNUMBER;
		y.u.number = y.u.boolean;
		goto retry;
	}
	if ((x.type == JS_TSTRING || x.type == JS_TNUMBER) && y.type == JS_TOBJECT) {
		y = jsV_toprimitive(J, &y, JS_HNONE);
		goto retry;
	}
	if (x.type == JS_TOBJECT && (y.type == JS_TSTRING || y.type == JS_TNUMBER)) {
		x = jsV_toprimitive(J, &x, JS_HNONE);
		goto retry;
	}

	return 0;
}
Beispiel #4
0
/* ToNumber() on a value */
double jsV_tonumber(js_State *J, js_Value *v)
{
	switch (v->type) {
	default:
	case JS_TSHRSTR: return jsV_stringtonumber(J, v->u.shrstr);
	case JS_TUNDEFINED: return NAN;
	case JS_TNULL: return 0;
	case JS_TBOOLEAN: return v->u.boolean;
	case JS_TNUMBER: return v->u.number;
	case JS_TLITSTR: return jsV_stringtonumber(J, v->u.litstr);
	case JS_TMEMSTR: return jsV_stringtonumber(J, v->u.memstr->p);
	case JS_TOBJECT:
		jsV_toprimitive(J, v, JS_HNUMBER);
		return jsV_tonumber(J, v);
	}
}
Beispiel #5
0
/* ToString() on a value */
const char *jsV_tostring(js_State *J, const js_Value *v)
{
	switch (v->type) {
	default:
	case JS_TUNDEFINED: return "undefined";
	case JS_TNULL: return "null";
	case JS_TBOOLEAN: return v->u.boolean ? "true" : "false";
	case JS_TNUMBER: return jsV_numbertostring(J, v->u.number);
	case JS_TSTRING: return v->u.string;
	case JS_TOBJECT:
		{
			js_Value vv = jsV_toprimitive(J, v, JS_HSTRING);
			return jsV_tostring(J, &vv);
		}
	}
}
Beispiel #6
0
/* ToNumber() on a value */
double jsV_tonumber(js_State *J, const js_Value *v)
{
	switch (v->type) {
	default:
	case JS_TUNDEFINED: return NAN;
	case JS_TNULL: return 0;
	case JS_TBOOLEAN: return v->u.boolean;
	case JS_TNUMBER: return v->u.number;
	case JS_TSTRING: return jsV_stringtonumber(J, v->u.string);
	case JS_TOBJECT:
		{
			js_Value vv = jsV_toprimitive(J, v, JS_HNUMBER);
			return jsV_tonumber(J, &vv);
		}
	}
}
Beispiel #7
0
void js_toprimitive(js_State *J, int idx, int hint)
{
	jsV_toprimitive(J, stackidx(J, idx), hint);
}