Bug 1088328 - OdinMonkey: accept (and ignore) non-semantic processing directives (r=bbouvier)

This commit is contained in:
Luke Wagner 2014-10-24 12:32:10 -05:00
Родитель d04e952d57
Коммит abecf18cfb
2 изменённых файлов: 65 добавлений и 2 удалений

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

@ -328,6 +328,21 @@ IsUseOfName(ParseNode *pn, PropertyName *name)
return pn->isKind(PNK_NAME) && pn->name() == name;
}
static inline bool
IsIgnoredDirectiveName(ExclusiveContext *cx, JSAtom *atom)
{
return atom != cx->names().useStrict;
}
static inline bool
IsIgnoredDirective(ExclusiveContext *cx, ParseNode *pn)
{
return pn->isKind(PNK_SEMI) &&
UnaryKid(pn) &&
UnaryKid(pn)->isKind(PNK_STRING) &&
IsIgnoredDirectiveName(cx, UnaryKid(pn)->pn_atom);
}
static inline bool
IsEmptyStatement(ParseNode *pn)
{
@ -3512,8 +3527,11 @@ CheckPrecedingStatements(ModuleCompiler &m, ParseNode *stmtList)
{
MOZ_ASSERT(stmtList->isKind(PNK_STATEMENTLIST));
if (ListLength(stmtList) != 0)
return m.fail(ListHead(stmtList), "invalid asm.js statement");
ParseNode *stmt = ListHead(stmtList);
for (unsigned i = 0, n = ListLength(stmtList); i < n; i++) {
if (!IsIgnoredDirective(m.cx(), stmt))
return m.fail(stmt, "invalid asm.js statement");
}
return true;
}
@ -3840,6 +3858,22 @@ CheckModuleGlobal(ModuleCompiler &m, ParseNode *var, bool isConst)
return m.fail(initNode, "unsupported import expression");
}
static bool
CheckModuleProcessingDirectives(ModuleCompiler &m)
{
TokenStream &ts = m.parser().tokenStream;
while (true) {
if (!ts.matchToken(TOK_STRING))
return true;
if (!IsIgnoredDirectiveName(m.cx(), ts.currentToken().atom()))
return m.fail(nullptr, "unsupported processing directive");
if (!ts.matchToken(TOK_SEMI))
return m.fail(nullptr, "expected semicolon after string literal");
}
}
static bool
CheckModuleGlobals(ModuleCompiler &m)
{
@ -3893,6 +3927,18 @@ CheckArgumentType(FunctionCompiler &f, ParseNode *stmt, PropertyName *name, VarT
return true;
}
static bool
CheckProcessingDirectives(ModuleCompiler &m, ParseNode **stmtIter)
{
ParseNode *stmt = *stmtIter;
while (stmt && IsIgnoredDirective(m.cx(), stmt))
stmt = NextNode(stmt);
*stmtIter = stmt;
return true;
}
static bool
CheckArguments(FunctionCompiler &f, ParseNode **stmtIter, VarTypeVector *argTypes)
{
@ -6902,6 +6948,9 @@ CheckFunction(ModuleCompiler &m, LifoAlloc &lifo, MIRGenerator **mir, ModuleComp
ParseNode *stmtIter = ListHead(FunctionStatementList(fn));
if (!CheckProcessingDirectives(m, &stmtIter))
return false;
VarTypeVector argTypes(m.lifo());
if (!CheckArguments(f, &stmtIter, &argTypes))
return false;
@ -8505,6 +8554,9 @@ CheckModule(ExclusiveContext *cx, AsmJSParser &parser, ParseNode *stmtList,
if (!CheckPrecedingStatements(m, stmtList))
return false;
if (!CheckModuleProcessingDirectives(m))
return false;
if (!CheckModuleGlobals(m))
return false;

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

@ -19,7 +19,18 @@ assertAsmTypeFail(USE_ASM + 'function f(){} var f=[f,f]; return f');
assertAsmTypeFail(USE_ASM + 'function f() 0; return f');
assertAsmTypeFail('"use strict";' + USE_ASM + 'function f() {} return f');
assertAsmTypeFail(USE_ASM + '"use strict"; function f() {} return f');
assertAsmTypeFail(USE_ASM + '"use foopy" + 1; function f() {} return f');
assertAsmTypeFail(USE_ASM + 'function f() { "use strict"; } return f');
assertEq(asmLink(asmCompile(USE_ASM + '"use asm"; function f() {} return f'))(), undefined);
assertEq(asmLink(asmCompile(USE_ASM + '"use foopy"; function f() {} return f'))(), undefined);
assertEq(asmLink(asmCompile(USE_ASM + '"use foopy"; "use blarg"; function f() {} return f'))(), undefined);
assertEq(asmLink(asmCompile(USE_ASM + 'function f() { "use asm"; } return f'))(), undefined);
assertEq(asmLink(asmCompile(USE_ASM + 'function f() { "use foopy"; } return f'))(), undefined);
assertEq(asmLink(asmCompile(USE_ASM + 'function f() { "use foopy"; "use blarg"; } return f'))(), undefined);
assertEq(asmLink(asmCompile(USE_ASM + 'function f(i) { "use foopy"; i=i|0; } return f'))(), undefined);
assertEq(asmLink(asmCompile(USE_ASM + 'function f(i) { "use foopy"; "use asm"; i=i|0; } return f'))(), undefined);
assertEq(asmLink(asmCompile(USE_ASM + '"use warm"; function f(i) { "use cold"; i=i|0 } function g() { "use hot"; return 0 } return f'))(), undefined);
assertEq(asmLink(asmCompile(USE_ASM + '"use warm"; function f(i) { "use cold"; i=i|0 } function g() { "use asm"; return 0 } return f'))(), undefined);
assertEq(asmLink(asmCompile(USE_ASM + 'function f(){} return f'))(), undefined);
assertEq(asmLink(asmCompile(USE_ASM + 'function f(){;} return f'))(), undefined);
assertAsmTypeFail(USE_ASM + 'function f(i,j){;} return f');