Catch let vs. const errors (349507, r=mrbkap).

This commit is contained in:
brendan%mozilla.org 2006-08-21 19:30:45 +00:00
Родитель 3f00d8e147
Коммит 42e6f711ed
3 изменённых файлов: 52 добавлений и 32 удалений

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

@ -1511,18 +1511,8 @@ js_DefineCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom,
return JS_TRUE;
}
/*
* Find a lexically scoped variable (one declared by let, catch, or an array
* comprehension) named by atom, looking in tc's compile-time scopes.
*
* If a WITH statement is reached along the scope stack, return its statement
* info record, so callers can tell that atom is ambiguous. If atom is found,
* set *slotp to its stack slot, and return the statement info record in which
* it was found directly. Otherwise (atom was not found and no WITH statement
* was reached) return null.
*/
static JSStmtInfo *
LexicalLookup(JSTreeContext *tc, JSAtom *atom, jsint *slotp)
JSStmtInfo *
js_LexicalLookup(JSTreeContext *tc, JSAtom *atom, jsint *slotp)
{
JSStmtInfo *stmt;
JSObject *obj;
@ -1530,10 +1520,9 @@ LexicalLookup(JSTreeContext *tc, JSAtom *atom, jsint *slotp)
JSScopeProperty *sprop;
jsval v;
*slotp = -1;
for (stmt = tc->topScopeStmt; stmt; stmt = stmt->downScope) {
if (stmt->type == STMT_WITH)
return stmt;
break;
JS_ASSERT(stmt->flags & SIF_SCOPE);
obj = ATOM_TO_OBJECT(stmt->atom);
@ -1543,18 +1532,22 @@ LexicalLookup(JSTreeContext *tc, JSAtom *atom, jsint *slotp)
if (sprop) {
JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID);
/*
* Use LOCKED_OBJ_GET_SLOT since we know obj is single-threaded
* and owned by this compiler activation.
*/
v = LOCKED_OBJ_GET_SLOT(obj, JSSLOT_BLOCK_DEPTH);
JS_ASSERT(JSVAL_IS_INT(v) && JSVAL_TO_INT(v) >= 0);
*slotp = JSVAL_TO_INT(v) + sprop->shortid;
if (slotp) {
/*
* Use LOCKED_OBJ_GET_SLOT since we know obj is single-
* threaded and owned by this compiler activation.
*/
v = LOCKED_OBJ_GET_SLOT(obj, JSSLOT_BLOCK_DEPTH);
JS_ASSERT(JSVAL_IS_INT(v) && JSVAL_TO_INT(v) >= 0);
*slotp = JSVAL_TO_INT(v) + sprop->shortid;
}
return stmt;
}
}
return NULL;
if (slotp)
*slotp = -1;
return stmt;
}
JSBool
@ -1586,7 +1579,7 @@ js_LookupCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom,
obj = fp->varobj;
if (obj == fp->scopeChain) {
/* XXX this will need revising when 'let const' is added. */
stmt = LexicalLookup(&cg->treeContext, atom, &slot);
stmt = js_LexicalLookup(&cg->treeContext, atom, &slot);
if (stmt)
return JS_TRUE;
@ -1878,7 +1871,7 @@ BindNameToSlot(JSContext *cx, JSTreeContext *tc, JSParseNode *pn)
* block-locals.
*/
atom = pn->pn_atom;
stmt = LexicalLookup(tc, atom, &slot);
stmt = js_LexicalLookup(tc, atom, &slot);
if (stmt) {
if (stmt->type == STMT_WITH)
return JS_TRUE;

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

@ -424,6 +424,23 @@ extern JSBool
js_LookupCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom,
jsval *vp);
/*
* Find a lexically scoped variable (one declared by let, catch, or an array
* comprehension) named by atom, looking in tc's compile-time scopes.
*
* If a WITH statement is reached along the scope stack, return its statement
* info record, so callers can tell that atom is ambiguous. If slotp is not
* null, then if atom is found, set *slotp to its stack slot, otherwise to -1.
* This means that if slotp is not null, all the block objects on the lexical
* scope chain must have had their depth slots computed by the code generator,
* so the caller must be under js_EmitTree.
*
* In any event, directly return the statement info record in which atom was
* found. Otherwise return null.
*/
extern JSStmtInfo *
js_LexicalLookup(JSTreeContext *tc, JSAtom *atom, jsint *slotp);
/*
* Emit code into cg for the tree rooted at pn.
*/

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

@ -1618,23 +1618,30 @@ BindLet(JSContext *cx, BindData *data, JSAtom *atom, JSTreeContext *tc)
JSObject *blockObj;
JSScope *scope;
JSScopeProperty *sprop;
JSAtomListElement *ale;
blockObj = data->obj;
scope = OBJ_SCOPE(blockObj);
sprop = SCOPE_GET_PROPERTY(scope, ATOM_TO_JSID(atom));
if (sprop) {
ATOM_LIST_SEARCH(ale, &tc->decls, atom);
if (sprop || (ale && ALE_JSOP(ale) == JSOP_DEFCONST)) {
const char *name;
JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID);
JS_ASSERT((uint16)sprop->shortid < data->u.let.index);
OBJ_DROP_PROPERTY(cx, blockObj, (JSProperty *) sprop);
if (sprop) {
JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID);
JS_ASSERT((uint16)sprop->shortid < data->u.let.index);
OBJ_DROP_PROPERTY(cx, blockObj, (JSProperty *) sprop);
}
name = js_AtomToPrintableString(cx, atom);
if (name) {
js_ReportCompileErrorNumber(cx,
BIND_DATA_REPORT_ARGS(data,
JSREPORT_ERROR),
JSMSG_REDECLARED_VAR, "variable",
JSMSG_REDECLARED_VAR,
(ale && ALE_JSOP(ale) == JSOP_DEFCONST)
? js_const_str
: "variable",
name);
}
return JS_FALSE;
@ -1661,6 +1668,7 @@ BindLet(JSContext *cx, BindData *data, JSAtom *atom, JSTreeContext *tc)
static JSBool
BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom, JSTreeContext *tc)
{
JSStmtInfo *stmt;
JSAtomListElement *ale;
JSOp op, prevop;
const char *name;
@ -1671,10 +1679,11 @@ BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom, JSTreeContext *tc)
JSPropertyOp currentGetter, currentSetter;
JSScopeProperty *sprop;
stmt = js_LexicalLookup(tc, atom, NULL);
ATOM_LIST_SEARCH(ale, &tc->decls, atom);
op = data->op;
if (ale) {
prevop = ALE_JSOP(ale);
if ((stmt && stmt->type != STMT_WITH) || ale) {
prevop = ale ? ALE_JSOP(ale) : JSOP_DEFVAR;
if (JS_HAS_STRICT_OPTION(cx)
? op != JSOP_DEFVAR || prevop != JSOP_DEFVAR
: op == JSOP_DEFCONST || prevop == JSOP_DEFCONST) {
@ -1700,7 +1709,8 @@ BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom, JSTreeContext *tc)
}
if (op == JSOP_DEFVAR && prevop == JSOP_CLOSURE)
tc->flags |= TCF_FUN_CLOSURE_VS_VAR;
} else {
}
if (!ale) {
ale = js_IndexAtom(cx, atom, &tc->decls);
if (!ale)
return JS_FALSE;