Eliminate broken old pre-ECMA switch case compile-time evaluation (144834, r=khanson, sr=shaver).

This commit is contained in:
brendan%mozilla.org 2002-07-09 02:15:49 +00:00
Родитель 121039b4c7
Коммит 0465e3ac35
2 изменённых файлов: 39 добавлений и 79 удалений

Просмотреть файл

@ -90,7 +90,7 @@ MSG_DEF(JSMSG_TOO_MANY_LITERALS, 14, 0, JSEXN_INTERNALERR, "too many liter
MSG_DEF(JSMSG_CANT_WATCH, 15, 1, JSEXN_NONE, "can't watch non-native objects of class {0}")
MSG_DEF(JSMSG_STACK_UNDERFLOW, 16, 2, JSEXN_INTERNALERR, "internal error compiling {0}: stack underflow at pc {1}")
MSG_DEF(JSMSG_NEED_DIET, 17, 1, JSEXN_INTERNALERR, "{0} too large")
MSG_DEF(JSMSG_BAD_CASE, 18, 0, JSEXN_SYNTAXERR, "invalid case expression")
MSG_DEF(JSMSG_UNUSED18, 18, 0, JSEXN_NONE, "<Error #18 is currently unused>")
MSG_DEF(JSMSG_READ_ONLY, 19, 1, JSEXN_ERR, "{0} is read-only")
MSG_DEF(JSMSG_BAD_FORMAL, 20, 0, JSEXN_SYNTAXERR, "malformed formal parameter")
MSG_DEF(JSMSG_SAME_FORMAL, 21, 1, JSEXN_NONE, "duplicate formal argument {0}")
@ -211,7 +211,7 @@ MSG_DEF(JSMSG_BAD_PROTOTYPE, 135, 1, JSEXN_TYPEERR, "'prototype' prop
MSG_DEF(JSMSG_MISSING_EXPONENT, 136, 0, JSEXN_SYNTAXERR, "missing exponent")
MSG_DEF(JSMSG_OUT_OF_MEMORY, 137, 0, JSEXN_ERR, "out of memory")
MSG_DEF(JSMSG_UNTERMINATED_STRING, 138, 0, JSEXN_SYNTAXERR, "unterminated string literal")
MSG_DEF(JSMSG_UNUSED0, 139, 0, JSEXN_NONE, "<Error #139 is currently unused>")
MSG_DEF(JSMSG_UNUSED139, 139, 0, JSEXN_NONE, "<Error #139 is currently unused>")
MSG_DEF(JSMSG_UNTERMINATED_COMMENT, 140, 0, JSEXN_SYNTAXERR, "unterminated comment")
MSG_DEF(JSMSG_UNTERMINATED_REGEXP, 141, 0, JSEXN_SYNTAXERR, "unterminated regular expression literal")
MSG_DEF(JSMSG_BAD_REGEXP_FLAG, 142, 0, JSEXN_SYNTAXERR, "invalid flag after regular expression")

Просмотреть файл

@ -1823,7 +1823,6 @@ JSBool
js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
{
JSBool ok, useful;
JSCodeGenerator cg2;
JSStmtInfo *stmt, stmtInfo;
ptrdiff_t top, off, tmp, beq, jmp;
JSParseNode *pn2, *pn3, *pn4;
@ -1845,6 +1844,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
switch (pn->pn_type) {
case TOK_FUNCTION:
{
JSCodeGenerator cg2;
JSFunction *fun;
/* Generate code for the function's body. */
@ -1906,7 +1906,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
uintN slot;
jsbytecode *pc;
obj = OBJ_GET_PARENT(cx, pn->pn_fun->object);
obj = OBJ_GET_PARENT(cx, fun->object);
if (!js_LookupProperty(cx, obj, (jsid)fun->atom, &pobj,
(JSProperty **)&sprop)) {
return JS_FALSE;
@ -2024,15 +2024,12 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
{
JSOp switchop;
uint32 ncases, tablen = 0;
JSScript *script;
jsint i, low, high;
jsdouble d;
size_t switchsize, tablesize;
JSParseNode **table;
jsbytecode *pc;
JSBool hasDefault = JS_FALSE;
JSBool isEcmaSwitch = cx->version == JSVERSION_DEFAULT ||
cx->version >= JSVERSION_1_4;
ptrdiff_t defaultOffset = -1;
/* Try for most optimal, fall back if not dense ints, and per ECMAv2. */
@ -2063,7 +2060,6 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
low = JSVAL_INT_MAX;
high = JSVAL_INT_MIN;
cg2.current = NULL;
for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
if (pn3->pn_type == TOK_DEFAULT) {
@ -2071,78 +2067,47 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
ncases--; /* one of the "cases" was the default */
continue;
}
JS_ASSERT(pn3->pn_type == TOK_CASE);
if (switchop == JSOP_CONDSWITCH)
continue;
pn4 = pn3->pn_left;
if (isEcmaSwitch) {
if (switchop == JSOP_CONDSWITCH)
continue;
switch (pn4->pn_type) {
case TOK_NUMBER:
d = pn4->pn_dval;
if (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i)) {
pn3->pn_val = INT_TO_JSVAL(i);
} else {
atom = js_AtomizeDouble(cx, d, 0);
if (!atom) {
ok = JS_FALSE;
goto release;
}
pn3->pn_val = ATOM_KEY(atom);
switch (pn4->pn_type) {
case TOK_NUMBER:
d = pn4->pn_dval;
if (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i)) {
pn3->pn_val = INT_TO_JSVAL(i);
} else {
atom = js_AtomizeDouble(cx, d, 0);
if (!atom) {
ok = JS_FALSE;
goto release;
}
pn3->pn_val = ATOM_KEY(atom);
}
break;
case TOK_STRING:
pn3->pn_val = ATOM_KEY(pn4->pn_atom);
break;
case TOK_PRIMARY:
if (pn4->pn_op == JSOP_TRUE) {
pn3->pn_val = JSVAL_TRUE;
break;
case TOK_STRING:
pn3->pn_val = ATOM_KEY(pn4->pn_atom);
}
if (pn4->pn_op == JSOP_FALSE) {
pn3->pn_val = JSVAL_FALSE;
break;
case TOK_PRIMARY:
if (pn4->pn_op == JSOP_TRUE) {
pn3->pn_val = JSVAL_TRUE;
break;
}
if (pn4->pn_op == JSOP_FALSE) {
pn3->pn_val = JSVAL_FALSE;
break;
}
/* FALL THROUGH */
default:
switchop = JSOP_CONDSWITCH;
continue;
}
} else {
/* Pre-ECMAv2 switch evals case exprs at compile time. */
ok = js_InitCodeGenerator(cx, &cg2, cg->filename,
pn3->pn_pos.begin.lineno,
cg->principals);
if (!ok)
goto release;
cg2.currentLine = pn4->pn_pos.begin.lineno;
ok = js_EmitTree(cx, &cg2, pn4);
if (!ok)
goto release;
if (js_Emit1(cx, &cg2, JSOP_POPV) < 0) {
ok = JS_FALSE;
goto release;
}
script = js_NewScriptFromCG(cx, &cg2, NULL);
if (!script) {
ok = JS_FALSE;
goto release;
}
ok = js_Execute(cx, cx->fp->scopeChain, script, cx->fp, 0,
&pn3->pn_val);
js_DestroyScript(cx, script);
if (!ok)
goto release;
/* FALL THROUGH */
default:
switchop = JSOP_CONDSWITCH;
continue;
}
if (!JSVAL_IS_NUMBER(pn3->pn_val) &&
!JSVAL_IS_STRING(pn3->pn_val) &&
!JSVAL_IS_BOOLEAN(pn3->pn_val)) {
cg->currentLine = pn3->pn_pos.begin.lineno;
js_ReportCompileErrorNumber(cx, NULL, cg, JSREPORT_ERROR,
JSMSG_BAD_CASE);
ok = JS_FALSE;
goto release;
}
JS_ASSERT(JSVAL_IS_NUMBER(pn3->pn_val) ||
JSVAL_IS_STRING(pn3->pn_val) ||
JSVAL_IS_BOOLEAN(pn3->pn_val));
if (switchop != JSOP_TABLESWITCH)
continue;
@ -2181,8 +2146,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
* sizeof(jsbitmap));
if (!intmap) {
JS_ReportOutOfMemory(cx);
ok = JS_FALSE;
goto release;
return JS_FALSE;
}
}
memset(intmap, 0, intmap_bitlen >> JS_BITS_PER_BYTE_LOG2);
@ -2200,11 +2164,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
if (!ok)
return JS_FALSE;
if (switchop == JSOP_CONDSWITCH) {
JS_ASSERT(!cg2.current);
} else {
if (cg2.current)
js_FinishCodeGenerator(cx, &cg2);
if (switchop != JSOP_CONDSWITCH) {
if (switchop == JSOP_TABLESWITCH) {
tablen = (uint32)(high - low + 1);
if (tablen >= JS_BIT(16) || tablen > 2 * ncases)