Push a STMT_BLOCK for functions, avoiding having to do extremely fancy footwork for let declarations. This also simplifies the concept of being at the "top level" in a script.
git-svn-id: svn://10.0.0.236/branches/JS_1_7_ALPHA_BRANCH@199863 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -142,9 +142,6 @@ struct JSTreeContext { /* tree context for semantic checks */
|
||||
#define TREE_CONTEXT_FINISH(tc) \
|
||||
((void)0)
|
||||
|
||||
#define TREE_CONTEXT_AT_TOP_LEVEL(tc) \
|
||||
(!((tc)->flags & TCF_IN_FUNCTION) && !(tc)->topStmt)
|
||||
|
||||
/*
|
||||
* Span-dependent instructions are jumps whose span (from the jump bytecode to
|
||||
* the jump target) may require 2 or 4 bytes of immediate operand.
|
||||
|
||||
@@ -691,6 +691,7 @@ FunctionBody(JSContext *cx, JSTokenStream *ts, JSFunction *fun,
|
||||
{
|
||||
JSStackFrame *fp, frame;
|
||||
JSObject *funobj;
|
||||
JSStmtInfo stmtInfo;
|
||||
uintN oldflags;
|
||||
JSParseNode *pn;
|
||||
|
||||
@@ -707,11 +708,15 @@ FunctionBody(JSContext *cx, JSTokenStream *ts, JSFunction *fun,
|
||||
cx->fp = &frame;
|
||||
}
|
||||
|
||||
js_PushStatement(tc, &stmtInfo, STMT_BLOCK, -1);
|
||||
|
||||
oldflags = tc->flags;
|
||||
tc->flags &= ~(TCF_RETURN_EXPR | TCF_RETURN_VOID);
|
||||
tc->flags |= TCF_IN_FUNCTION;
|
||||
pn = Statements(cx, ts, tc);
|
||||
|
||||
js_PopStatement(tc);
|
||||
|
||||
/* Check for falling off the end of a function that returns a value. */
|
||||
if (pn && JS_HAS_STRICT_OPTION(cx) && (tc->flags & TCF_RETURN_EXPR)) {
|
||||
if (!CheckFinalReturn(cx, ts, pn))
|
||||
@@ -1119,7 +1124,7 @@ Statements(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
||||
ts->flags |= TSF_OPERAND;
|
||||
|
||||
/* If compiling top-level statements, emit as we go to save space. */
|
||||
if (TREE_CONTEXT_AT_TOP_LEVEL(tc) && (tc->flags & TCF_COMPILING)) {
|
||||
if (!tc->topStmt && (tc->flags & TCF_COMPILING)) {
|
||||
if (cx->fp->fun &&
|
||||
JS_HAS_STRICT_OPTION(cx) &&
|
||||
(tc->flags & TCF_RETURN_EXPR)) {
|
||||
@@ -2888,45 +2893,43 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
||||
if (!pn)
|
||||
return NULL;
|
||||
} else {
|
||||
if (TREE_CONTEXT_AT_TOP_LEVEL(tc)) {
|
||||
/*
|
||||
* XXX This is a hard case that requires more work. In
|
||||
* particular, in many cases, we're trying to emit code as we
|
||||
* go. However, this means that we haven't necessarily
|
||||
* finished processing all let declarations in the implicit
|
||||
* top-level block when we emit a reference to one of them.
|
||||
* For now, punt on this and pretend this is a var
|
||||
* declaration.
|
||||
*/
|
||||
CURRENT_TOKEN(ts).type = TOK_VAR;
|
||||
CURRENT_TOKEN(ts).t_op = JSOP_DEFVAR;
|
||||
|
||||
pn = Variables(cx, ts, tc);
|
||||
if (!pn)
|
||||
return NULL;
|
||||
pn->pn_extra |= PNX_POPVAR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set up the block object. */
|
||||
stmt = FindBlockStatement(tc);
|
||||
if (stmt && stmt->type == STMT_BLOCK_SCOPE) {
|
||||
JS_ASSERT(stmt->blockObj);
|
||||
obj = stmt->blockObj;
|
||||
} else {
|
||||
obj = js_NewBlockObject(cx);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
if (stmt) {
|
||||
/* Convert the block statement into a scope statement. */
|
||||
obj = js_NewBlockObject(cx);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
JS_ASSERT(stmt->type == STMT_BLOCK);
|
||||
JS_ASSERT(stmt->downScope == NULL);
|
||||
stmt->type = STMT_BLOCK_SCOPE;
|
||||
stmt->downScope = tc->topScopeStmt;
|
||||
tc->topScopeStmt = stmt;
|
||||
obj->slots[JSSLOT_PARENT] =
|
||||
OBJECT_TO_JSVAL(tc->blockChain);
|
||||
tc->blockChain = stmt->blockObj = obj;
|
||||
} else {
|
||||
js_PushBlockScope(tc, &stmtInfo, obj, -1);
|
||||
/*
|
||||
* XXX This is a hard case that requires more work. In
|
||||
* particular, in many cases, we're trying to emit code as
|
||||
* we go. However, this means that we haven't necessarily
|
||||
* finished processing all let declarations in the
|
||||
* implicit top-level block when we emit a reference to
|
||||
* one of them. For now, punt on this and pretend this is
|
||||
* a var declaration.
|
||||
*/
|
||||
CURRENT_TOKEN(ts).type = TOK_VAR;
|
||||
CURRENT_TOKEN(ts).t_op = JSOP_DEFVAR;
|
||||
|
||||
pn = Variables(cx, ts, tc);
|
||||
if (!pn)
|
||||
return NULL;
|
||||
pn->pn_extra |= PNX_POPVAR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user