From 941ece2658cf16cb02f135656b4ddc488d253ef4 Mon Sep 17 00:00:00 2001 From: "brendan%mozilla.org" Date: Tue, 22 Nov 2005 00:47:05 +0000 Subject: [PATCH] Root me harder (316885 r/sr=igor/shaver). git-svn-id: svn://10.0.0.236/trunk@185107 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/js/src/jsemit.c | 10 +++++++++ mozilla/js/src/jsinterp.c | 47 +++++++++++++++++++++++++++++---------- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/mozilla/js/src/jsemit.c b/mozilla/js/src/jsemit.c index ba45e23b55b..0a39cce6112 100644 --- a/mozilla/js/src/jsemit.c +++ b/mozilla/js/src/jsemit.c @@ -4345,6 +4345,16 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn) case TOK_DOT: if (!EmitPropOp(cx, pn2, op, cg)) return JS_FALSE; + /* + * Allocate an extra stack slot for GC protection in case the + * initial value being post-incremented or -decremented is not + * a number, but converts to a jsdouble. See jsinterp.c, the + * JSOP_PROPINC and JSOP_PROPDEC cases. + */ + if ((js_CodeSpec[op].format & JOF_POST) && + (uintN)cg->stackDepth == cg->maxStackDepth) { + ++cg->maxStackDepth; + } break; case TOK_LB: if (!EmitElemOp(cx, pn2, op, cg)) diff --git a/mozilla/js/src/jsinterp.c b/mozilla/js/src/jsinterp.c index e6aa8ecb87d..93fe8ad77d0 100644 --- a/mozilla/js/src/jsinterp.c +++ b/mozilla/js/src/jsinterp.c @@ -2827,6 +2827,7 @@ interrupt: } \ } else { \ VALUE_TO_PRIMITIVE(cx, lval, JSTYPE_NUMBER, &lval); \ + sp[-2] = lval; \ VALUE_TO_PRIMITIVE(cx, rval, JSTYPE_NUMBER, &rval); \ if (JSVAL_IS_STRING(lval) && JSVAL_IS_STRING(rval)) { \ str = JSVAL_TO_STRING(lval); \ @@ -2913,10 +2914,12 @@ interrupt: cond = 1 OP 0; \ } else { \ if (ltmp == JSVAL_OBJECT) { \ - VALUE_TO_PRIMITIVE(cx, lval, JSTYPE_VOID, &lval); \ + VALUE_TO_PRIMITIVE(cx, lval, JSTYPE_VOID, &sp[-2]); \ + lval = sp[-2]; \ ltmp = JSVAL_TAG(lval); \ } else if (rtmp == JSVAL_OBJECT) { \ - VALUE_TO_PRIMITIVE(cx, rval, JSTYPE_VOID, &rval); \ + VALUE_TO_PRIMITIVE(cx, rval, JSTYPE_VOID, &sp[-1]); \ + rval = sp[-1]; \ rtmp = JSVAL_TAG(rval); \ } \ if (ltmp == JSVAL_STRING && rtmp == JSVAL_STRING) { \ @@ -3048,16 +3051,18 @@ interrupt: } else #endif { - VALUE_TO_PRIMITIVE(cx, lval, JSTYPE_VOID, <mp); - VALUE_TO_PRIMITIVE(cx, rval, JSTYPE_VOID, &rtmp); - if ((cond = JSVAL_IS_STRING(ltmp)) || JSVAL_IS_STRING(rtmp)) { - SAVE_SP_AND_PC(fp); + VALUE_TO_PRIMITIVE(cx, lval, JSTYPE_VOID, &sp[-2]); + lval = sp[-2]; + VALUE_TO_PRIMITIVE(cx, rval, JSTYPE_VOID, &sp[-1]); + rval = sp[-1]; + if ((cond = JSVAL_IS_STRING(lval)) || JSVAL_IS_STRING(rval)) { + SAVE_SP(fp); if (cond) { - str = JSVAL_TO_STRING(ltmp); - ok = (str2 = js_ValueToString(cx, rtmp)) != NULL; + str = JSVAL_TO_STRING(lval); + ok = (str2 = js_ValueToString(cx, rval)) != NULL; } else { - str2 = JSVAL_TO_STRING(rtmp); - ok = (str = js_ValueToString(cx, ltmp)) != NULL; + str2 = JSVAL_TO_STRING(rval); + ok = (str = js_ValueToString(cx, lval)) != NULL; } if (!ok) goto out; @@ -3405,7 +3410,9 @@ interrupt: /* * Initially, rval contains the value to increment or decrement, which is not * yet converted. As above, the expression result goes in rtmp, the updated - * value goes in rval. + * value goes in rval. Our caller must set vp to point at a GC-rooted jsval + * in which we home rtmp, to protect it from GC in case the unconverted rval + * is not a number. */ #define NONINT_INCREMENT_OP_MIDDLE() \ JS_BEGIN_MACRO \ @@ -3416,6 +3423,7 @@ interrupt: ok = js_NewNumberValue(cx, d, &rtmp); \ if (!ok) \ goto out; \ + *vp = rtmp; \ } \ (cs->format & JOF_INC) ? d++ : d--; \ ok = js_NewNumberValue(cx, d, &rval); \ @@ -3428,6 +3436,19 @@ interrupt: goto out; \ JS_END_MACRO + if ((cs->format & JOF_POST) && i != -2) { + /* + * We must push early to protect the postfix increment + * or decrement result, if converted to a jsdouble from + * a non-number value, from GC nesting in the setter. + */ + vp = sp++; + SAVE_SP(fp); + --i; + } +#ifdef __GNUC__ + else vp = NULL; /* suppress bogus gcc warnings */ +#endif NONINT_INCREMENT_OP_MIDDLE(); } @@ -3537,9 +3558,11 @@ interrupt: { const JSCodeSpec *cs = &js_CodeSpec[op]; + vp = sp++; + SAVE_SP(fp); NONINT_INCREMENT_OP_MIDDLE(); OBJ_SET_SLOT(cx, obj, slot, rval); - PUSH_OPND(rtmp); + STORE_OPND(-1, rtmp); len = cs->length; DO_NEXT_OP(len); }