Flag ints as type INT in the incoming context if its merely a double holding an int that was too large to fit into jsval directly. Along the side exits make sure we can properly box oversized ints (by casting them to doubles). The fetch_int/store_int paths still need fixing to ensure that values are merely passed through (prim_copy) instead of explicit casting or calling to ValueToECMAInt32 etc.

This commit is contained in:
Andreas Gal 2008-07-02 02:53:24 -07:00
parent 31ef2f7b34
commit 8907cd354b

View File

@ -272,11 +272,18 @@ TraceRecorder::nativeFrameOffset(void* p) const
return offset * sizeof(double);
}
/* Return the tag of a jsval. */
/* Return the tag of a jsval. Doubles are checked whether they actually
represent an int, in which case we treat them as JSVAL_INT. */
static inline int gettag(jsval v)
{
if (JSVAL_IS_INT(v))
return JSVAL_INT;
if (JSVAL_IS_DOUBLE(v)) {
jsdouble d = *JSVAL_TO_DOUBLE(v);
jsint i;
if (JSDOUBLE_IS_INT(d, i))
return JSVAL_INT;
}
return JSVAL_TAG(v);
}
@ -302,20 +309,36 @@ TraceRecorder::unbox_jsval(jsval v, int t, double* slot) const
{
if (t != gettag(v))
return false;
if (JSVAL_IS_BOOLEAN(v))
switch (t) {
case JSVAL_BOOLEAN:
*(bool*)slot = JSVAL_TO_BOOLEAN(v);
else if (JSVAL_IS_INT(v))
*(jsint*)slot = JSVAL_TO_INT(v);
else if (JSVAL_IS_DOUBLE(v))
break;
case JSVAL_INT:
*(jsint*)slot = JSVAL_IS_INT(v);
if (JSVAL_IS_INT(v))
*(jsint*)slot = JSVAL_TO_INT(v);
else {
jsdouble d = *JSVAL_TO_DOUBLE(v);
JS_ASSERT(JSDOUBLE_IS_INT(d, t));
*(jsint*)slot = (jsint)d;
}
break;
case JSVAL_DOUBLE:
*(jsdouble*)slot = *JSVAL_TO_DOUBLE(v);
else {
break;
case JSVAL_STRING:
*(JSString**)slot = JSVAL_TO_STRING(v);
break;
default:
JS_ASSERT(JSVAL_IS_GCTHING(v));
*(void**)slot = JSVAL_TO_GCTHING(v);
}
return true;
}
/* Box a value from the native stack back into the jsval format. */
/* Box a value from the native stack back into the jsval format. Integers
that are too large to fit into a jsval are automatically boxed into
heap-allocated doubles. */
bool
TraceRecorder::box_jsval(jsval* vp, int t, double* slot) const
{
@ -324,7 +347,11 @@ TraceRecorder::box_jsval(jsval* vp, int t, double* slot) const
*vp = BOOLEAN_TO_JSVAL(*(bool*)slot);
return true;
case JSVAL_INT:
*vp = INT_TO_JSVAL(*(jsint*)slot);
jsint i = *(jsint*)slot;
if (INT_FITS_IN_JSVAL(i))
*vp = INT_TO_JSVAL(i);
else
return js_NewDoubleInRootedValue(cx, (double)i, vp);
return true;
case JSVAL_DOUBLE:
return js_NewDoubleInRootedValue(cx, *slot, vp);