d = -d;
js_FoldConstants(JSContext *cx, JSParseNode *pn){    JSParseNode *pn1, *pn2, *pn3;    switch (pn->pn_arity) {      case PN_FUNC:	if (!js_FoldConstants(cx, pn->pn_body))	    return JS_FALSE;	break;      case PN_LIST:	for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {	    if (!js_FoldConstants(cx, pn2))		return JS_FALSE;	}	break;      case PN_TERNARY:	/* Any kid may be null (e.g. for (;;)). */	pn1 = pn->pn_kid1;	pn2 = pn->pn_kid2;	pn3 = pn->pn_kid3;	if (pn1 && !js_FoldConstants(cx, pn1))	    return JS_FALSE;	if (pn2 && !js_FoldConstants(cx, pn2))	    return JS_FALSE;	if (pn3 && !js_FoldConstants(cx, pn3))	    return JS_FALSE;	break;      case PN_BINARY:	/* First kid may be null (for default case in switch). */	pn1 = pn->pn_left;	pn2 = pn->pn_right;	if (pn1 && !js_FoldConstants(cx, pn1))	    return JS_FALSE;	if (!js_FoldConstants(cx, pn2))	    return JS_FALSE;	break;      case PN_UNARY:	/* Our kid may be null (e.g. return; vs. return e;). */	pn1 = pn->pn_kid;	if (pn1 && !js_FoldConstants(cx, pn1))	    return JS_FALSE;	break;      case PN_NAME:	pn1 = pn->pn_expr;	if (pn1 && !js_FoldConstants(cx, pn1))	    return JS_FALSE;	break;      case PN_NULLARY:	break;    }    switch (pn->pn_type) {      case TOK_PLUS:	if (pn1->pn_type == TOK_STRING && pn2->pn_type == TOK_STRING) {	    JSString *str1, *str2;	    size_t length, length1, length2, nbytes;	    void *mark;	    jschar *chars;	    /* Concatenate string constants. */	    str1 = ATOM_TO_STRING(pn1->pn_atom);	    str2 = ATOM_TO_STRING(pn2->pn_atom);	    length1 = str1->length;	    length2 = str2->length;	    length = length1 + length2;	    nbytes = (length + 1) * sizeof(jschar);	    mark = PR_ARENA_MARK(&cx->tempPool);	    PR_ARENA_ALLOCATE(chars, &cx->tempPool, nbytes);	    if (!chars) {		JS_ReportOutOfMemory(cx);		return JS_FALSE;	    }	    js_strncpy(chars, str1->chars, length1);	    js_strncpy(chars + length1, str2->chars, length2);	    chars[length] = 0;	    pn->pn_atom = js_AtomizeChars(cx, chars, length, 0);	    if (!pn->pn_atom)		return JS_FALSE;	    PR_ARENA_RELEASE(&cx->tempPool, mark);	    pn->pn_type = TOK_STRING;	    pn->pn_op = JSOP_STRING;	    pn->pn_arity = PN_NULLARY;	    break;	}	/* FALL THROUGH */      case TOK_SHOP:      case TOK_MINUS:      case TOK_STAR:      case TOK_DIVOP:	if (pn1->pn_type == TOK_NUMBER && pn2->pn_type == TOK_NUMBER) {	    jsdouble d, d2;	    int32 i, j;	    uint32 u;	    /* Fold two numeric constants. */	    d = pn1->pn_dval;	    d2 = pn2->pn_dval;	    switch (pn->pn_op) {	      case JSOP_LSH:	      case JSOP_RSH:		if (!js_DoubleToECMAInt32(cx, d, &i))		    return JS_FALSE;		if (!js_DoubleToECMAInt32(cx, d2, &j))		    return JS_FALSE;		j &= 31;		d = (pn->pn_op == JSOP_LSH) ? i << j : i >> j;		break;	      case JSOP_URSH:		if (!js_DoubleToECMAUint32(cx, d, &u))		    return JS_FALSE;		if (!js_DoubleToECMAInt32(cx, d2, &j))		    return JS_FALSE;		j &= 31;		d = u >> j;		break;	      case JSOP_ADD:		d += d2;		break;	      case JSOP_SUB:		d -= d2;		break;	      case JSOP_MUL:		d *= d2;		break;	      case JSOP_DIV:		if (d2 == 0) {#ifdef XP_PC		    /* XXX MSVC miscompiles such that (NaN == 0) */		    if (JSDOUBLE_IS_NaN(d2))			d = *cx->runtime->jsNaN;		    else#endif		    if (d == 0 || JSDOUBLE_IS_NaN(d))			d = *cx->runtime->jsNaN;		    else if ((JSDOUBLE_HI32(d) ^ JSDOUBLE_HI32(d2)) >> 31)			d = *cx->runtime->jsNegativeInfinity;		    else			d = *cx->runtime->jsPositiveInfinity;		} else {		    d /= d2;		}		break;	      case JSOP_MOD:		if (d2 == 0) {		    d = *cx->runtime->jsNaN;		} else {#ifdef XP_PC		  /* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. */		  if (!(JSDOUBLE_IS_FINITE(d) && JSDOUBLE_IS_INFINITE(d2)))#endif		    d = fmod(d, d2);		}		break;	      default:;	    }	    pn->pn_type = TOK_NUMBER;	    pn->pn_op = JSOP_NUMBER;	    pn->pn_arity = PN_NULLARY;	    pn->pn_dval = d;	}	break;      case TOK_UNARYOP:	if (pn1->pn_type == TOK_NUMBER) {	    jsdouble d;	    int32 i;	    /* Operate on one numeric constants. */	    d = pn1->pn_dval;	    switch (pn->pn_op) {	      case JSOP_BITNOT:		if (!js_DoubleToECMAInt32(cx, d, &i))		    return JS_FALSE;		d = ~i;		break;	      case JSOP_NEG:		d = -d;		break;	      case JSOP_POS:		break;	      case JSOP_NOT:		pn->pn_type = TOK_PRIMARY;		pn->pn_op = (d == 0) ? JSOP_TRUE : JSOP_FALSE;		pn->pn_arity = PN_NULLARY;		/* FALL THROUGH */	      default:		/* Return early to dodge the common TOK_NUMBER code. */		return JS_TRUE;	    }	    pn->pn_type = TOK_NUMBER;	    pn->pn_op = JSOP_NUMBER;	    pn->pn_arity = PN_NULLARY;	    pn->pn_dval = d;	}	break;      default:;    }    return JS_TRUE;}