If we expect a concrete value but see an undefined come into the trace, convert undefined to the concerete value.

This commit is contained in:
Andreas Gal 2008-08-21 00:43:45 -07:00
parent a7b0f45c3f
commit fcd8670fec

View File

@ -850,27 +850,32 @@ TraceRecorder::trackNativeStackUse(unsigned slots)
/* Unbox a jsval into a slot. Slots are wide enough to hold double values
directly (instead of storing a pointer to them). */
static bool
ValueToNative(jsval v, uint8 type, double* slot)
ValueToNative(JSContext* cx, jsval v, uint8 type, double* slot)
{
if (type == JSVAL_INT) {
unsigned tag = JSVAL_TAG(v);
switch (type) {
case JSVAL_INT:
jsint i;
if (JSVAL_IS_INT(v))
*(jsint*)slot = JSVAL_TO_INT(v);
else if (JSVAL_IS_DOUBLE(v) && JSDOUBLE_IS_INT(*JSVAL_TO_DOUBLE(v), i))
else if ((tag == JSVAL_DOUBLE) && JSDOUBLE_IS_INT(*JSVAL_TO_DOUBLE(v), i))
*(jsint*)slot = i;
else if (v == JSVAL_VOID)
*(jsint*)slot = 0;
else {
debug_only_v(printf("int != tag%lu(value=%lu) ", JSVAL_TAG(v), v);)
return false;
}
debug_only_v(printf("int<%d> ", *(jsint*)slot);)
return true;
}
if (type == JSVAL_DOUBLE) {
case JSVAL_DOUBLE:
jsdouble d;
if (JSVAL_IS_INT(v))
d = JSVAL_TO_INT(v);
else if (JSVAL_IS_DOUBLE(v))
else if (tag == JSVAL_DOUBLE)
d = *JSVAL_TO_DOUBLE(v);
else if (v == JSVAL_VOID)
d = js_NaN;
else {
debug_only_v(printf("double != tag%lu ", JSVAL_TAG(v));)
return false;
@ -878,30 +883,40 @@ ValueToNative(jsval v, uint8 type, double* slot)
*(jsdouble*)slot = d;
debug_only_v(printf("double<%g> ", d);)
return true;
}
if (JSVAL_TAG(v) != type) {
debug_only_v(printf("%d != tag%lu ", type, JSVAL_TAG(v));)
case JSVAL_BOOLEAN:
if (tag != JSVAL_BOOLEAN) {
debug_only_v(printf("bool != tag%u ", tag);)
return false;
}
switch (JSVAL_TAG(v)) {
case JSVAL_BOOLEAN:
*(JSBool*)slot = JSVAL_TO_BOOLEAN(v);
debug_only_v(printf("boolean<%d> ", *(bool*)slot);)
break;
return true;
case JSVAL_STRING:
if (v == JSVAL_VOID) {
*(JSString**)slot = ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]);
return true;
}
if (tag != JSVAL_STRING) {
debug_only_v(printf("string != tag%u ", tag);)
return false;
}
*(JSString**)slot = JSVAL_TO_STRING(v);
debug_only_v(printf("string<%p> ", *(JSString**)slot);)
break;
return true;
default:
JS_ASSERT(JSVAL_IS_OBJECT(v));
JS_ASSERT(type == JSVAL_OBJECT);
if (tag != JSVAL_OBJECT) {
debug_only_v(printf("object != tag%u ", tag);)
return false;
}
*(JSObject**)slot = JSVAL_TO_OBJECT(v);
debug_only_v(printf("object<%p:%s> ", JSVAL_TO_OBJECT(v),
JSVAL_IS_NULL(v)
? "null"
: STOBJ_GET_CLASS(JSVAL_TO_OBJECT(v))->name);)
}
return true;
}
}
/* 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
@ -958,7 +973,7 @@ BuildNativeGlobalFrame(JSContext* cx, unsigned ngslots, uint16* gslots, uint8* m
{
debug_only_v(printf("global: ");)
FORALL_GLOBAL_SLOTS(cx, ngslots, gslots,
if (!ValueToNative(*vp, *mp, np + gslots[n]))
if (!ValueToNative(cx, *vp, *mp, np + gslots[n]))
return false;
++mp;
);
@ -974,7 +989,7 @@ BuildNativeStackFrame(JSContext* cx, unsigned callDepth, uint8* mp, double* np)
debug_only_v(printf("stack: ");)
FORALL_SLOTS_IN_PENDING_FRAMES(cx, callDepth,
debug_only_v(printf("%s%u=", vpname, vpnum);)
if (!ValueToNative(*vp, *mp, np))
if (!ValueToNative(cx, *vp, *mp, np))
return false;
++mp; ++np;
);