Bug 835587 - Add syntax only mode to parser, r=jorendorff.

This commit is contained in:
Brian Hackett
2013-02-26 08:41:57 -07:00
parent fbad24c6d9
commit 11987ef777
22 changed files with 2901 additions and 1878 deletions

View File

@@ -17,6 +17,7 @@
#include "jsinferinlines.h"
#include "frontend/ParseMaps-inl.h"
#include "frontend/ParseNode-inl.h"
#include "frontend/Parser-inl.h"
#include "frontend/SharedContext-inl.h"
@@ -47,12 +48,12 @@ SetSourceMap(JSContext *cx, TokenStream &tokenStream, ScriptSource *ss, Unrooted
}
static bool
CheckArgumentsWithinEval(JSContext *cx, Parser &parser, HandleFunction fun)
CheckArgumentsWithinEval(JSContext *cx, Parser<FullParseHandler> &parser, HandleFunction fun)
{
if (fun->hasRest()) {
// It's an error to use |arguments| in a function that has a rest
// parameter.
parser.reportError(NULL, JSMSG_ARGUMENTS_AND_REST);
parser.report(ParseError, false, NULL, JSMSG_ARGUMENTS_AND_REST);
return false;
}
@@ -119,14 +120,14 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain,
break;
}
Parser parser(cx, options, chars, length, /* foldConstants = */ true);
Parser<FullParseHandler> parser(cx, options, chars, length, /* foldConstants = */ true);
if (!parser.init())
return UnrootedScript(NULL);
parser.sct = sct;
GlobalSharedContext globalsc(cx, scopeChain, StrictModeFromContext(cx));
ParseContext pc(&parser, &globalsc, staticLevel, /* bodyid = */ 0);
ParseContext<FullParseHandler> pc(&parser, &globalsc, staticLevel, /* bodyid = */ 0);
if (!pc.init())
return UnrootedScript(NULL);
@@ -185,10 +186,9 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain,
}
}
TokenStream &tokenStream = parser.tokenStream;
bool canHaveDirectives = true;
for (;;) {
TokenKind tt = tokenStream.peekToken(TSF_OPERAND);
TokenKind tt = parser.tokenStream.peekToken(TSF_OPERAND);
if (tt <= TOK_EOF) {
if (tt == TOK_EOF)
break;
@@ -213,10 +213,10 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain,
if (!EmitTree(cx, &bce, pn))
return UnrootedScript(NULL);
parser.freeTree(pn);
parser.handler.freeTree(pn);
}
if (!SetSourceMap(cx, tokenStream, ss, script))
if (!SetSourceMap(cx, parser.tokenStream, ss, script))
return UnrootedScript(NULL);
if (evalCaller && evalCaller->functionOrCallerFunction()) {
@@ -273,6 +273,46 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain,
return script;
}
bool
frontend::ParseScript(JSContext *cx, HandleObject scopeChain,
const CompileOptions &options, StableCharPtr chars, size_t length)
{
if (!CheckLength(cx, length))
return false;
Parser<SyntaxParseHandler> parser(cx, options, chars.get(), length, /* foldConstants = */ false);
if (!parser.init()) {
cx->clearPendingException();
return false;
}
GlobalSharedContext globalsc(cx, scopeChain, StrictModeFromContext(cx));
ParseContext<SyntaxParseHandler> pc(&parser, &globalsc, 0, /* bodyid = */ 0);
if (!pc.init()) {
cx->clearPendingException();
return false;
}
for (;;) {
TokenKind tt = parser.tokenStream.peekToken(TSF_OPERAND);
if (tt <= TOK_EOF) {
if (tt == TOK_EOF)
break;
JS_ASSERT(tt == TOK_ERROR);
cx->clearPendingException();
return false;
}
if (!parser.statement()) {
cx->clearPendingException();
return false;
}
}
return true;
}
// Compile a JS function body, which might appear as the value of an event
// handler attribute in an HTML <INPUT> tag, or in a Function() constructor.
bool
@@ -293,7 +333,7 @@ frontend::CompileFunctionBody(JSContext *cx, HandleFunction fun, CompileOptions
}
options.setCompileAndGo(false);
Parser parser(cx, options, chars, length, /* foldConstants = */ true);
Parser<FullParseHandler> parser(cx, options, chars, length, /* foldConstants = */ true);
if (!parser.init())
return false;
parser.sct = &sct;
@@ -303,7 +343,7 @@ frontend::CompileFunctionBody(JSContext *cx, HandleFunction fun, CompileOptions
fun->setArgCount(formals.length());
/* FIXME: make Function format the source for a function definition. */
ParseNode *fn = CodeNode::create(PNK_FUNCTION, &parser);
ParseNode *fn = CodeNode::create(PNK_FUNCTION, &parser.handler);
if (!fn)
return false;
@@ -311,7 +351,7 @@ frontend::CompileFunctionBody(JSContext *cx, HandleFunction fun, CompileOptions
fn->pn_funbox = NULL;
fn->pn_cookie.makeFree();
ParseNode *argsbody = ListNode::create(PNK_ARGSBODY, &parser);
ParseNode *argsbody = ListNode::create(PNK_ARGSBODY, &parser.handler);
if (!argsbody)
return false;
argsbody->setOp(JSOP_NOP);