summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@digia.com>2013-03-18 20:53:26 +0100
committerLars Knoll <lars.knoll@digia.com>2013-03-18 20:58:15 +0100
commite0a5c8cbde9f67a61d34868a4c9e588eee125fe8 (patch)
tree23d2a6b4ef13b880b7119b1e36a33ec594b45cc5
parent30321555e34ce27f45ae98045a1bf981e7530f23 (diff)
Check if "use strict" has no escaped chars.
Change-Id: I7dc172eba02d454467ead1e18a1a59e98890dd54 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
-rw-r--r--src/v4/qv4codegen.cpp28
-rw-r--r--src/v4/qv4codegen_p.h12
-rw-r--r--src/v4/qv4functionobject.cpp2
-rw-r--r--src/v4/qv4globalobject.cpp2
-rw-r--r--tests/TestExpectations1
-rw-r--r--tools/v4/main.cpp2
6 files changed, 34 insertions, 13 deletions
diff --git a/src/v4/qv4codegen.cpp b/src/v4/qv4codegen.cpp
index 3c7e074e..b60ce225 100644
--- a/src/v4/qv4codegen.cpp
+++ b/src/v4/qv4codegen.cpp
@@ -621,8 +621,9 @@ class Codegen::ScanFunctions: Visitor
{
typedef TemporaryAssignment<bool> TemporaryBoolAssignment;
public:
- ScanFunctions(Codegen *cg)
+ ScanFunctions(Codegen *cg, const QString &sourceCode)
: _cg(cg)
+ , _sourceCode(sourceCode)
, _env(0)
, _inFuncBody(false)
, _allowFuncDecls(true)
@@ -660,7 +661,13 @@ protected:
if (StatementSourceElement *stmt = cast<StatementSourceElement *>(it->element)) {
if (ExpressionStatement *expr = cast<ExpressionStatement *>(stmt->statement)) {
if (StringLiteral *strLit = cast<StringLiteral *>(expr->expression)) {
- if (strLit->value == QLatin1String("use strict")) {
+ // Use the source code, because the StringLiteral's
+ // value might have escape sequences in it, which is not
+ // allowed.
+ if (strLit->literalToken.length < 2)
+ continue;
+ QStringRef str = _sourceCode.midRef(strLit->literalToken.offset + 1, strLit->literalToken.length - 2);
+ if (str == QStringLiteral("use strict")) {
_env->isStrict = true;
} else {
// TODO: give a warning.
@@ -964,6 +971,7 @@ private:
private: // fields:
Codegen *_cg;
+ const QString _sourceCode;
Environment *_env;
QStack<Environment *> _envStack;
@@ -1009,8 +1017,11 @@ Codegen::Codegen(ErrorHandler *errorHandler, bool strictMode)
{
}
-IR::Function *Codegen::operator()(const QString &fileName, Program *node,
- IR::Module *module, Mode mode,
+IR::Function *Codegen::operator()(const QString &fileName,
+ const QString &sourceCode,
+ Program *node,
+ IR::Module *module,
+ Mode mode,
const QStringList &inheritedLocals)
{
assert(node);
@@ -1019,7 +1030,7 @@ IR::Function *Codegen::operator()(const QString &fileName, Program *node,
_module = module;
_env = 0;
- ScanFunctions scan(this);
+ ScanFunctions scan(this, sourceCode);
scan(node);
IR::Function *globalCode = defineFunction(QStringLiteral("%entry"), node, 0,
@@ -1041,13 +1052,16 @@ IR::Function *Codegen::operator()(const QString &fileName, Program *node,
return globalCode;
}
-IR::Function *Codegen::operator()(const QString &fileName, AST::FunctionExpression *ast, IR::Module *module)
+IR::Function *Codegen::operator()(const QString &fileName,
+ const QString &sourceCode,
+ AST::FunctionExpression *ast,
+ IR::Module *module)
{
_fileName = fileName;
_module = module;
_env = 0;
- ScanFunctions scan(this);
+ ScanFunctions scan(this, sourceCode);
// fake a global environment
scan.enterEnvironment(0);
scan(ast);
diff --git a/src/v4/qv4codegen_p.h b/src/v4/qv4codegen_p.h
index 85525c00..1e1e19b1 100644
--- a/src/v4/qv4codegen_p.h
+++ b/src/v4/qv4codegen_p.h
@@ -80,8 +80,16 @@ public:
FunctionCode
};
- IR::Function *operator()(const QString &fileName, AST::Program *ast, IR::Module *module, Mode mode = GlobalCode, const QStringList &inheritedLocals = QStringList());
- IR::Function *operator()(const QString &fileName, AST::FunctionExpression *ast, IR::Module *module);
+ IR::Function *operator()(const QString &fileName,
+ const QString &sourceCode,
+ AST::Program *ast,
+ IR::Module *module,
+ Mode mode = GlobalCode,
+ const QStringList &inheritedLocals = QStringList());
+ IR::Function *operator()(const QString &fileName,
+ const QString &sourceCode,
+ AST::FunctionExpression *ast,
+ IR::Module *module);
protected:
enum Format { ex, cx, nx };
diff --git a/src/v4/qv4functionobject.cpp b/src/v4/qv4functionobject.cpp
index e43410ef..6cf9989c 100644
--- a/src/v4/qv4functionobject.cpp
+++ b/src/v4/qv4functionobject.cpp
@@ -208,7 +208,7 @@ Value FunctionCtor::construct(Managed *that, ExecutionContext *ctx, Value *args,
IR::Module module;
Codegen cg(ctx, f->strictMode);
- IR::Function *irf = cg(QString(), fe, &module);
+ IR::Function *irf = cg(QString(), function, fe, &module);
QScopedPointer<EvalInstructionSelection> isel(ctx->engine->iselFactory->create(ctx->engine, &module));
VM::Function *vmf = isel->vmFunction(irf);
diff --git a/src/v4/qv4globalobject.cpp b/src/v4/qv4globalobject.cpp
index 1283bc15..6e87ef6b 100644
--- a/src/v4/qv4globalobject.cpp
+++ b/src/v4/qv4globalobject.cpp
@@ -488,7 +488,7 @@ QQmlJS::VM::Function *EvalFunction::parseSource(QQmlJS::VM::ExecutionContext *ct
inheritedLocals.append(*i ? (*i)->toQString() : QString());
Codegen cg(ctx, strictMode);
- IR::Function *globalIRCode = cg(fileName, program, &module, mode, inheritedLocals);
+ IR::Function *globalIRCode = cg(fileName, source, program, &module, mode, inheritedLocals);
QScopedPointer<EvalInstructionSelection> isel(ctx->engine->iselFactory->create(vm, &module));
if (inheritContext)
isel->setUseFastLookups(false);
diff --git a/tests/TestExpectations b/tests/TestExpectations
index ba02c3ea..b8eef677 100644
--- a/tests/TestExpectations
+++ b/tests/TestExpectations
@@ -12,7 +12,6 @@ S11.5.3_A4_T2 failing
S11.8.6_A5_T2 failing
S13_A15_T4 failing
S13.2.3_A1 failing
-14.1-5-s failing
15.4.4.14-9-a-10 failing
15.4.4.14-9-a-17 failing
15.4.4.14-9-a-7 failing
diff --git a/tools/v4/main.cpp b/tools/v4/main.cpp
index 17ddecba..86d5ae6e 100644
--- a/tools/v4/main.cpp
+++ b/tools/v4/main.cpp
@@ -211,7 +211,7 @@ int compile(const QString &fileName, const QString &source, QQmlJS::LLVMOutputTy
Codegen cg(&errorHandler, false);
// FIXME: if the program is empty, we should we generate an empty %entry, or give an error?
- /*IR::Function *globalCode =*/ cg(fileName, program, &module);
+ /*IR::Function *globalCode =*/ cg(fileName, source, program, &module);
int (*exec)(void *) = outputType == LLVMOutputJit ? executeLLVMCode : 0;
return compileWithLLVM(&module, fileName, outputType, exec);