Fix foo += bar for undefined foo to throw, not bind foo to undefined (321757, r=mrbkap).

This commit is contained in:
brendan%mozilla.org 2006-01-31 20:53:30 +00:00
parent 622be3e058
commit 7fa34ea903
5 changed files with 38 additions and 15 deletions

View File

@ -1669,6 +1669,7 @@ EmitAtomIndexOp(JSContext *cx, JSOp op, jsatomid atomIndex, JSCodeGenerator *cg)
case JSOP_FORNAME: op = JSOP_FORELEM; break;
case JSOP_FORPROP: op = JSOP_FORELEM; break;
case JSOP_GETPROP: op = JSOP_GETELEM; break;
case JSOP_GETXPROP: op = JSOP_GETXELEM; break;
case JSOP_IMPORTPROP: op = JSOP_IMPORTELEM; break;
case JSOP_INCNAME: op = JSOP_INCELEM; break;
case JSOP_INCPROP: op = JSOP_INCELEM; break;
@ -4139,7 +4140,10 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
case TOK_DOT:
if (js_Emit1(cx, cg, JSOP_DUP) < 0)
return JS_FALSE;
EMIT_ATOM_INDEX_OP(JSOP_GETPROP, atomIndex);
EMIT_ATOM_INDEX_OP((pn2->pn_type == TOK_NAME)
? JSOP_GETXPROP
: JSOP_GETPROP,
atomIndex);
break;
case TOK_LB:
#if JS_HAS_LVALUE_RETURN

View File

@ -3593,6 +3593,7 @@ interrupt:
}
BEGIN_CASE(JSOP_GETPROP)
BEGIN_CASE(JSOP_GETXPROP)
/* Get an immediate atom naming the property. */
atom = GET_ATOM(cx, script, pc);
id = ATOM_TO_JSID(atom);
@ -3614,6 +3615,7 @@ interrupt:
END_CASE(JSOP_SETPROP)
BEGIN_CASE(JSOP_GETELEM)
BEGIN_CASE(JSOP_GETXELEM)
ELEMENT_OP(-1, CACHED_GET(OBJ_GET_PROPERTY(cx, obj, id, &rval)));
sp--;
STORE_OPND(-1, rval);

View File

@ -2905,6 +2905,7 @@ js_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
return JS_FALSE;
if (!prop) {
jsval default_val;
jsbytecode *pc;
#if JS_BUG_NULL_INDEX_PROPS
/* Indexed properties defaulted to null in old versions. */
@ -2923,27 +2924,34 @@ js_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
* Give a strict warning if foo.bar is evaluated by a script for an
* object foo with no property named 'bar'.
*/
if (JS_HAS_STRICT_OPTION(cx) &&
*vp == default_val &&
cx->fp && cx->fp->pc &&
(*cx->fp->pc == JSOP_GETPROP || *cx->fp->pc == JSOP_GETELEM))
{
jsbytecode *pc;
if (*vp == default_val && cx->fp && (pc = cx->fp->pc)) {
JSOp op;
uintN flags;
JSString *str;
/* Kludge to allow (typeof foo == "undefined") tests. */
JS_ASSERT(cx->fp->script);
pc = cx->fp->pc;
pc += js_CodeSpec[*pc].length;
if (Detecting(cx, pc))
return JS_TRUE;
op = *pc;
if (op == JSOP_GETXPROP || op == JSOP_GETXELEM) {
flags = JSREPORT_ERROR;
} else {
if (!JS_HAS_STRICT_OPTION(cx) ||
(op != JSOP_GETPROP && op != JSOP_GETELEM)) {
return JS_TRUE;
}
/* Kludge to allow (typeof foo == "undefined") tests. */
JS_ASSERT(cx->fp->script);
pc += js_CodeSpec[op].length;
if (Detecting(cx, pc))
return JS_TRUE;
flags = JSREPORT_WARNING | JSREPORT_STRICT;
}
/* Ok, bad undefined property reference: whine about it. */
str = js_DecompileValueGenerator(cx, JSDVG_IGNORE_STACK,
ID_TO_VALUE(id), NULL);
if (!str ||
!JS_ReportErrorFlagsAndNumber(cx,
JSREPORT_WARNING|JSREPORT_STRICT,
!JS_ReportErrorFlagsAndNumber(cx, flags,
js_GetErrorMessage, NULL,
JSMSG_UNDEFINED_PROP,
JS_GetStringBytes(str))) {

View File

@ -1917,6 +1917,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
/* FALL THROUGH */
case JSOP_GETPROP:
case JSOP_GETXPROP:
atom = GET_ATOM(cx, jp->script, pc);
do_getprop:
@ -1968,6 +1969,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
/* FALL THROUGH */
case JSOP_GETELEM:
case JSOP_GETXELEM:
op = JSOP_NOP; /* turn off parens */
xval = POP_STR();
op = JSOP_GETELEM;

View File

@ -398,3 +398,10 @@ OPDEF(JSOP_SETMETHOD, 194,"setmethod", NULL, 3, 2, 1, 1, JOF_CONST|
* interpreter an extra branch test on every DO_NEXT_OP (see jsinterp.c).
*/
OPDEF(JSOP_STOP, 195,"stop", NULL, 1, 0, 0, 0, JOF_BYTE)
/*
* Get an extant property or element value, throwing ReferenceError if the
* identified property does not exist.
*/
OPDEF(JSOP_GETXPROP, 196,"getxprop", NULL, 3, 1, 1, 11, JOF_CONST|JOF_PROP)
OPDEF(JSOP_GETXELEM, 197,"getxelem", NULL, 1, 2, 1, 11, JOF_BYTE |JOF_ELEM|JOF_LEFTASSOC)