From 56f29d005c2c6eb028e3ed2d1ef8edd6d03d1403 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 12 Jun 2017 10:27:54 +0200 Subject: Pass the JSUnitGenerator into the codegen Allow registering all the required data to generate the proper compilationunit already in the codegenerator. Change-Id: I36345cc01927b3f8dc3ba6d91da175bd6abe124a Reviewed-by: Erik Verbruggen --- src/qml/jsruntime/qv4script.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 62145f36cc..c0b38bd7ef 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -126,12 +126,12 @@ void Script::parse() } } - RuntimeCodegen cg(v4, strictMode); + QV4::Compiler::JSUnitGenerator jsGenerator(&module); + RuntimeCodegen cg(v4, &jsGenerator, strictMode); cg.generateFromProgram(sourceFile, sourceCode, program, &module, QQmlJS::Codegen::EvalCode, inheritedLocals); if (v4->hasException) return; - QV4::Compiler::JSUnitGenerator jsGenerator(&module); QScopedPointer isel(v4->iselFactory->create(QQmlEnginePrivate::get(v4), v4->executableAllocator, &module, &jsGenerator)); if (inheritContext) isel->setUseFastLookups(false); @@ -230,7 +230,7 @@ QQmlRefPointer Script::precompile(IR::Module return 0; } - QQmlJS::Codegen cg(/*strict mode*/false); + QQmlJS::Codegen cg(unitGenerator, /*strict mode*/false); cg.generateFromProgram(url.toString(), source, program, module, QQmlJS::Codegen::EvalCode); errors = cg.qmlErrors(); if (!errors.isEmpty()) { -- cgit v1.2.3 From 52e3a59b1de607636926822f1016f0e264bc4ad3 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 21 Jun 2017 14:17:04 +0200 Subject: Re-enable lookups Change-Id: I02d57d2cbb4ae56c0c4626d96cbdf9935b366579 Reviewed-by: Erik Verbruggen --- src/qml/jsruntime/qv4script.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index c0b38bd7ef..cc8dfb30c2 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -128,6 +128,8 @@ void Script::parse() QV4::Compiler::JSUnitGenerator jsGenerator(&module); RuntimeCodegen cg(v4, &jsGenerator, strictMode); + if (inheritContext) + cg.setUseFastLookups(false); cg.generateFromProgram(sourceFile, sourceCode, program, &module, QQmlJS::Codegen::EvalCode, inheritedLocals); if (v4->hasException) return; @@ -231,6 +233,7 @@ QQmlRefPointer Script::precompile(IR::Module } QQmlJS::Codegen cg(unitGenerator, /*strict mode*/false); + cg.setUseFastLookups(false); cg.generateFromProgram(url.toString(), source, program, module, QQmlJS::Codegen::EvalCode); errors = cg.qmlErrors(); if (!errors.isEmpty()) { -- cgit v1.2.3 From 40e8109ceff8519920245a01d82357dc57639f46 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 22 Jun 2017 09:44:55 +0200 Subject: Don't use the ISel's anymore Move the code that generates the CompilationUnit over to Codegen, and don't use the ISel's at all anymore when compiling JS/QML. Change-Id: Iba89082c386c3d3fd58ac25a4651c5d39178cc5c Reviewed-by: Erik Verbruggen --- src/qml/jsruntime/qv4script.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index cc8dfb30c2..53adb09273 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -134,10 +134,7 @@ void Script::parse() if (v4->hasException) return; - QScopedPointer isel(v4->iselFactory->create(QQmlEnginePrivate::get(v4), v4->executableAllocator, &module, &jsGenerator)); - if (inheritContext) - isel->setUseFastLookups(false); - compilationUnit = isel->compile(); + compilationUnit = cg.generateCompilationUnit(); vmFunction = compilationUnit->linkToEngine(v4); } @@ -188,7 +185,9 @@ Function *Script::function() return vmFunction; } -QQmlRefPointer Script::precompile(IR::Module *module, Compiler::JSUnitGenerator *unitGenerator, ExecutionEngine *engine, const QUrl &url, const QString &source, QList *reportedErrors, QQmlJS::Directives *directivesCollector) +QQmlRefPointer Script::precompile(IR::Module *module, Compiler::JSUnitGenerator *unitGenerator, + const QUrl &url, const QString &source, QList *reportedErrors, + QQmlJS::Directives *directivesCollector) { using namespace QQmlJS; using namespace QQmlJS::AST; @@ -242,9 +241,7 @@ QQmlRefPointer Script::precompile(IR::Module return 0; } - QScopedPointer isel(engine->iselFactory->create(QQmlEnginePrivate::get(engine), engine->executableAllocator, module, unitGenerator)); - isel->setUseFastLookups(false); - return isel->compile(/*generate unit data*/false); + return cg.generateCompilationUnit(/*generate unit data*/false); } QV4::ReturnedValue Script::evaluate(ExecutionEngine *engine, const QString &script, QmlContext *qmlContext) -- cgit v1.2.3 From 45bba2e13d231c1b06061c7b1433c7055106815b Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 29 Jun 2017 14:17:27 +0200 Subject: Get rid of inheritedLocals in the codegen This was only causing us to create mutable bindings for variables that already existed, thus leading to an expensive noop. Change-Id: I6ed8ee891f8ec16c59e5fc43ed9eb155cb4b64ac Reviewed-by: Erik Verbruggen --- src/qml/jsruntime/qv4script.cpp | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 53adb09273..3394a93fe5 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -117,20 +117,11 @@ void Script::parse() return; } - QStringList inheritedLocals; - if (inheritContext) { - Scoped ctx(valueScope, scope); - if (ctx) { - for (Identifier * const *i = ctx->variables(), * const *ei = i + ctx->variableCount(); i < ei; ++i) - inheritedLocals.append(*i ? (*i)->string : QString()); - } - } - QV4::Compiler::JSUnitGenerator jsGenerator(&module); RuntimeCodegen cg(v4, &jsGenerator, strictMode); if (inheritContext) cg.setUseFastLookups(false); - cg.generateFromProgram(sourceFile, sourceCode, program, &module, QQmlJS::Codegen::EvalCode, inheritedLocals); + cg.generateFromProgram(sourceFile, sourceCode, program, &module, QQmlJS::Codegen::EvalCode); if (v4->hasException) return; -- cgit v1.2.3 From 6fdf0390311278d571bb4c851baa1e3a0ef550ec Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 29 Jun 2017 15:31:13 +0200 Subject: Rename Codegen::Environment to Context and pull it out of Codegen Part of refactoring and streamlining this code base. Change-Id: I324d35d1f0a74c5908b40243ffa2b247ce924304 Reviewed-by: Erik Verbruggen --- src/qml/jsruntime/qv4script.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 3394a93fe5..7ea16020a5 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -121,7 +121,7 @@ void Script::parse() RuntimeCodegen cg(v4, &jsGenerator, strictMode); if (inheritContext) cg.setUseFastLookups(false); - cg.generateFromProgram(sourceFile, sourceCode, program, &module, QQmlJS::Codegen::EvalCode); + cg.generateFromProgram(sourceFile, sourceCode, program, &module, QQmlJS::EvalCode); if (v4->hasException) return; @@ -224,7 +224,7 @@ QQmlRefPointer Script::precompile(IR::Module QQmlJS::Codegen cg(unitGenerator, /*strict mode*/false); cg.setUseFastLookups(false); - cg.generateFromProgram(url.toString(), source, program, module, QQmlJS::Codegen::EvalCode); + cg.generateFromProgram(url.toString(), source, program, module, QQmlJS::EvalCode); errors = cg.qmlErrors(); if (!errors.isEmpty()) { if (reportedErrors) -- cgit v1.2.3 From 3a9f4d3ae701c7119016a0bf8b4e65ceb17864b0 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 30 Jun 2017 08:44:09 +0200 Subject: Get rid of IR::Module and IR::Function Fold the stuff from IR::Function into QQmlJS::Context, and add a QQmlJS::Module class to replace the last pieces of the old IR. Change-Id: Ic02a6738a4f1db67a0ddf97b6c93ca32be81789d Reviewed-by: Erik Verbruggen --- src/qml/jsruntime/qv4script.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 7ea16020a5..13f84ccd0e 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -88,7 +88,7 @@ void Script::parse() ExecutionEngine *v4 = scope->engine(); Scope valueScope(v4); - IR::Module module(v4->debugger() != 0); + QQmlJS::Module module(v4->debugger() != 0); QQmlJS::Engine ee, *engine = ⅇ Lexer lexer(engine); @@ -176,7 +176,7 @@ Function *Script::function() return vmFunction; } -QQmlRefPointer Script::precompile(IR::Module *module, Compiler::JSUnitGenerator *unitGenerator, +QQmlRefPointer Script::precompile(QQmlJS::Module *module, Compiler::JSUnitGenerator *unitGenerator, const QUrl &url, const QString &source, QList *reportedErrors, QQmlJS::Directives *directivesCollector) { -- cgit v1.2.3 From 29e41a9ee61a05274f77f89e9ffd8875f90d3308 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 22 Jun 2017 10:01:17 +0200 Subject: Remove now unused files Remove all files from the old compiler pipeline that are now unused. This includes the whole IR, JIT code generation, and the old Moth Isel. Change-Id: I50d06abfbcf0e9755a54ed94638f8bb74f9512b1 Reviewed-by: Erik Verbruggen --- src/qml/jsruntime/qv4script.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 13f84ccd0e..68ed07b214 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -52,7 +52,6 @@ #include #include #include -#include #include #include -- cgit v1.2.3 From bac9b54dfb38767a34410fa55f8f46e64b458efb Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 30 Jun 2017 15:34:12 +0200 Subject: Split up qv4codegen into several files And changed the namespace of those classes to QV4::Compiler. ScanFunctions should over time also move into its own file. Change-Id: If084acea4a9a20b9c79ad47dac19e02dc720e098 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4script.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 68ed07b214..0370531579 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -80,16 +80,16 @@ void Script::parse() if (parsed) return; - using namespace QQmlJS; + using namespace QV4::Compiler; parsed = true; ExecutionEngine *v4 = scope->engine(); Scope valueScope(v4); - QQmlJS::Module module(v4->debugger() != 0); + Module module(v4->debugger() != 0); - QQmlJS::Engine ee, *engine = ⅇ + Engine ee, *engine = ⅇ Lexer lexer(engine); lexer.setCode(sourceCode, line, parseAsBinding); Parser parser(engine); @@ -97,7 +97,7 @@ void Script::parse() const bool parsed = parser.parseProgram(); const auto diagnosticMessages = parser.diagnosticMessages(); - for (const QQmlJS::DiagnosticMessage &m : diagnosticMessages) { + for (const DiagnosticMessage &m : diagnosticMessages) { if (m.isError()) { valueScope.engine->throwSyntaxError(m.message, sourceFile, m.loc.startLine, m.loc.startColumn); return; @@ -120,7 +120,7 @@ void Script::parse() RuntimeCodegen cg(v4, &jsGenerator, strictMode); if (inheritContext) cg.setUseFastLookups(false); - cg.generateFromProgram(sourceFile, sourceCode, program, &module, QQmlJS::EvalCode); + cg.generateFromProgram(sourceFile, sourceCode, program, &module, EvalCode); if (v4->hasException) return; @@ -175,26 +175,26 @@ Function *Script::function() return vmFunction; } -QQmlRefPointer Script::precompile(QQmlJS::Module *module, Compiler::JSUnitGenerator *unitGenerator, +QQmlRefPointer Script::precompile(QV4::Compiler::Module *module, Compiler::JSUnitGenerator *unitGenerator, const QUrl &url, const QString &source, QList *reportedErrors, - QQmlJS::Directives *directivesCollector) + Directives *directivesCollector) { - using namespace QQmlJS; + using namespace QV4::Compiler; using namespace QQmlJS::AST; - QQmlJS::Engine ee; + Engine ee; if (directivesCollector) ee.setDirectives(directivesCollector); - QQmlJS::Lexer lexer(&ee); + Lexer lexer(&ee); lexer.setCode(source, /*line*/1, /*qml mode*/false); - QQmlJS::Parser parser(&ee); + Parser parser(&ee); parser.parseProgram(); QList errors; const auto diagnosticMessages = parser.diagnosticMessages(); - for (const QQmlJS::DiagnosticMessage &m : diagnosticMessages) { + for (const DiagnosticMessage &m : diagnosticMessages) { if (m.isWarning()) { qWarning("%s:%d : %s", qPrintable(url.toString()), m.loc.startLine, qPrintable(m.message)); continue; @@ -221,9 +221,9 @@ QQmlRefPointer Script::precompile(QQmlJS::Mo return 0; } - QQmlJS::Codegen cg(unitGenerator, /*strict mode*/false); + Codegen cg(unitGenerator, /*strict mode*/false); cg.setUseFastLookups(false); - cg.generateFromProgram(url.toString(), source, program, module, QQmlJS::EvalCode); + cg.generateFromProgram(url.toString(), source, program, module, EvalCode); errors = cg.qmlErrors(); if (!errors.isEmpty()) { if (reportedErrors) -- cgit v1.2.3 From 1283f7c3b34ebd441b9679ce3981d216ba530e98 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 3 Jul 2017 08:08:16 +0200 Subject: Move the Runtime codegen into it's own file Change-Id: I3d09fc4b8aebe19acae0ba5a688491428a4af715 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4script.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 0370531579..30cc4c664c 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -52,7 +52,7 @@ #include #include #include -#include +#include #include #include -- cgit v1.2.3 From ef5d5a989a344ba812a91b365cd54ace65f27f26 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 3 Aug 2017 08:57:03 +0200 Subject: Get rid of the compilation unit related members in ExecutionContext And change the signature for VME::exec to take the QV4::Function that should be executed. This is in preparation to being able to run functions that will not need to allocate an execution context on their own. Change-Id: I34538a8723006f4ec24583805e88a66e750100c3 Reviewed-by: Erik Verbruggen --- src/qml/jsruntime/qv4script.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 30cc4c664c..7868b1a7d2 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -151,9 +151,7 @@ ReturnedValue Script::run() ExecutionContextSaver ctxSaver(valueScope); ContextStateSaver stateSaver(valueScope, scope); scope->d()->strictMode = vmFunction->isStrict(); - scope->d()->lookups = vmFunction->compilationUnit->runtimeLookups; - scope->d()->constantTable = vmFunction->compilationUnit->constants; - scope->d()->compilationUnit = vmFunction->compilationUnit; + scope->d()->v4Function = vmFunction; return Q_V4_PROFILE(engine, vmFunction); } else { -- cgit v1.2.3 From 50e7badd5f261bd69db9d8f03d5651e346087218 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 4 Aug 2017 18:53:51 +0200 Subject: Remove Scope::result and convert calling convention for builtins Allow for faster calling of builtins, and completely avoid scope creation in many cases. Change-Id: I0f1681e19e9908db10def85a74e134a87fc2e44c Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4script.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 7868b1a7d2..019fa54fb0 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -159,10 +159,9 @@ ReturnedValue Script::run() ScopedCallData callData(valueScope); callData->thisObject = Primitive::undefinedValue(); if (vmFunction->canUseSimpleFunction()) - qml->simpleCall(valueScope, callData, vmFunction); + return qml->simpleCall(valueScope, callData, vmFunction); else - qml->call(valueScope, callData, vmFunction); - return valueScope.result.asReturnedValue(); + return qml->call(valueScope, callData, vmFunction); } } -- cgit v1.2.3 From f284d73ccece0490b4a227c788b9415a59a38d9c Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 5 Aug 2017 00:03:52 +0200 Subject: Avoid creating a separate Scope in the ExecutionContextSaver There's no reason this class should create a scope on it's own. Change-Id: I93bddea8be42a908a1aca1bcb0ec867aae0d29f8 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4script.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 019fa54fb0..b771978def 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -148,7 +148,7 @@ ReturnedValue Script::run() if (qmlContext.isUndefined()) { TemporaryAssignment savedGlobalCode(engine->globalCode, vmFunction); - ExecutionContextSaver ctxSaver(valueScope); + ExecutionContextSaver ctxSaver(valueScope.engine); ContextStateSaver stateSaver(valueScope, scope); scope->d()->strictMode = vmFunction->isStrict(); scope->d()->v4Function = vmFunction; -- cgit v1.2.3 From 99783cd6dec326058b8db345145b1f8f71cfb6f0 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 5 Aug 2017 00:15:44 +0200 Subject: Completely avoid intermediate scopes for simple functions Change-Id: I1fe2ff987e79cf590ad5ad3fc520b17925f8b616 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4script.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index b771978def..2b97a0f1d4 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -159,9 +159,9 @@ ReturnedValue Script::run() ScopedCallData callData(valueScope); callData->thisObject = Primitive::undefinedValue(); if (vmFunction->canUseSimpleFunction()) - return qml->simpleCall(valueScope, callData, vmFunction); + return qml->simpleCall(valueScope.engine, callData, vmFunction); else - return qml->call(valueScope, callData, vmFunction); + return qml->call(valueScope.engine, callData, vmFunction); } } -- cgit v1.2.3 From fd221cf6e056b7239fc2fa2faeccd9ddeb542199 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 7 Aug 2017 08:10:15 +0200 Subject: Introduce a JS stack frame that corresponds to the C++ stack frame The frame currently contains the function itself and the current context. Change-Id: I7d3402627fbc90e860a7bdc277585f365f5b4cb5 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4script.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 2b97a0f1d4..188b66d8d3 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -153,7 +153,7 @@ ReturnedValue Script::run() scope->d()->strictMode = vmFunction->isStrict(); scope->d()->v4Function = vmFunction; - return Q_V4_PROFILE(engine, vmFunction); + return Q_V4_PROFILE(engine, vmFunction, 0); } else { Scoped qml(valueScope, qmlContext.value()); ScopedCallData callData(valueScope); -- cgit v1.2.3 From eb2c08f57493aa12850e6cddff2cc3527e7cbfd7 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 7 Aug 2017 14:43:03 +0200 Subject: Get rid of ExecutionContext::strictMode This should be done by generating different byte code for the strict/non strict cases. For now the VME has a workaround checking the isStrict() flag of QV4::Function. Change-Id: I2faa9e9184ffc5274491067e67f665d6989b54c2 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4script.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 188b66d8d3..1b28882280 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -150,7 +150,6 @@ ReturnedValue Script::run() ExecutionContextSaver ctxSaver(valueScope.engine); ContextStateSaver stateSaver(valueScope, scope); - scope->d()->strictMode = vmFunction->isStrict(); scope->d()->v4Function = vmFunction; return Q_V4_PROFILE(engine, vmFunction, 0); -- cgit v1.2.3 From 5bc4f4d958a3b76f3435d61206ca0109f07aa1a3 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 8 Aug 2017 10:56:34 +0200 Subject: Refactor context handling Fix the push/pop context instructions to not modify the JS stack anymore, as that can cause conflicts with the VME (and was an ugly hack in any case). Instead, these instructions not return the old context, that is then stored in a temporary. Get rid of Engine::current and Engine::currentContext. The StackFrame structures do now contain the only and authoritive data. This finally gives us a nice setup where we create and destroy frames on the stack when entering/leaving functions. Change-Id: If161e3e941f59865c47ecfe1e094faf62b52bfa0 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4script.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 1b28882280..ef85ce43de 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -148,11 +148,10 @@ ReturnedValue Script::run() if (qmlContext.isUndefined()) { TemporaryAssignment savedGlobalCode(engine->globalCode, vmFunction); - ExecutionContextSaver ctxSaver(valueScope.engine); ContextStateSaver stateSaver(valueScope, scope); scope->d()->v4Function = vmFunction; - return Q_V4_PROFILE(engine, vmFunction, 0); + return Q_V4_PROFILE(engine, scope->d(), vmFunction, 0); } else { Scoped qml(valueScope, qmlContext.value()); ScopedCallData callData(valueScope); -- cgit v1.2.3 From 55f17d0faad79dbb9adf793f7ce6e75ff5b70033 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 8 Aug 2017 16:56:59 +0200 Subject: Get rid of simpleCall After the recent changes this can easily be unified with the call method without loss of performance. Change-Id: I0385b47b6a86e890f97dcbada3a1be1129ae0b84 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4script.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index ef85ce43de..e5db62a749 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -156,10 +156,7 @@ ReturnedValue Script::run() Scoped qml(valueScope, qmlContext.value()); ScopedCallData callData(valueScope); callData->thisObject = Primitive::undefinedValue(); - if (vmFunction->canUseSimpleFunction()) - return qml->simpleCall(valueScope.engine, callData, vmFunction); - else - return qml->call(valueScope.engine, callData, vmFunction); + return ExecutionContext::call(qml->d(), callData, vmFunction); } } -- cgit v1.2.3 From 6a91dcba2e4fa85dc345c2d403c757ab7676e28c Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 9 Aug 2017 16:02:55 +0200 Subject: Always create a valid CallData object for interpreter calls This will allow removing a few more special cases and to simplify the code further. Change-Id: I3a958e9f68e3c103ea4f2ee6825f893e5931b11d Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4script.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index e5db62a749..d3d8c1c291 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -151,12 +151,14 @@ ReturnedValue Script::run() ContextStateSaver stateSaver(valueScope, scope); scope->d()->v4Function = vmFunction; - return Q_V4_PROFILE(engine, scope->d(), vmFunction, 0); + QV4::ScopedCallData cData(scope); + cData->thisObject = engine->globalObject; + return vmFunction->execute(scope->d(), cData); } else { Scoped qml(valueScope, qmlContext.value()); ScopedCallData callData(valueScope); callData->thisObject = Primitive::undefinedValue(); - return ExecutionContext::call(qml->d(), callData, vmFunction); + return vmFunction->call(qml->d(), callData); } } -- cgit v1.2.3 From 4e0174a88e66b9d9471c98eeb7d8be6209ba5c98 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 21 Aug 2017 10:59:53 +0200 Subject: Move line number information into a side table Don't emit any Line instructions anymore, and instead store the info in a side table in the compiled data, where it can be looked up on demand. Change-Id: Idcaf3bf4ee4129fd62f9e717bf1277dc6a34fe19 Reviewed-by: Erik Verbruggen --- src/qml/jsruntime/qv4script.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index d3d8c1c291..23dfd3fc89 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -60,7 +60,7 @@ using namespace QV4; Script::Script(ExecutionEngine *v4, QmlContext *qml, CompiledData::CompilationUnit *compilationUnit) - : line(0), column(0), scope(v4->rootContext()), strictMode(false), inheritContext(true), parsed(false) + : line(1), column(0), scope(v4->rootContext()), strictMode(false), inheritContext(true), parsed(false) , compilationUnit(compilationUnit), vmFunction(0), parseAsBinding(true) { if (qml) -- cgit v1.2.3 From 50828bc6ed9112956170a68dffe72431a21fddd9 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 30 Aug 2017 14:38:01 +0200 Subject: Use the context member in CallData Store the current context in the context member instead of passing it along as arguments. Change-Id: If3dd0d32eddb2a02bcbf65fe6e8d15142403170e Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4script.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 23dfd3fc89..d5f08041f6 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -153,12 +153,14 @@ ReturnedValue Script::run() QV4::ScopedCallData cData(scope); cData->thisObject = engine->globalObject; - return vmFunction->execute(scope->d(), cData); + cData->context = *scope; + return vmFunction->execute(cData); } else { Scoped qml(valueScope, qmlContext.value()); ScopedCallData callData(valueScope); callData->thisObject = Primitive::undefinedValue(); - return vmFunction->call(qml->d(), callData); + callData->context = *qml; + return vmFunction->call(callData); } } -- cgit v1.2.3 From 6df6f642ea382169533a0ad106be270b6d4b7d58 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 30 Aug 2017 21:53:03 +0200 Subject: Move CallContext construction into a interpreter instruction This will allow us to further cut down on function call overhead. To make this work, introduce a proper distinction between EvalCode and GlobalCode and use the correct compilation mode in all places. Change-Id: I070621142159b7416026347c9239200c5ed7a56b Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4script.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index d5f08041f6..a0aa1b1f2d 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -120,7 +120,7 @@ void Script::parse() RuntimeCodegen cg(v4, &jsGenerator, strictMode); if (inheritContext) cg.setUseFastLookups(false); - cg.generateFromProgram(sourceFile, sourceCode, program, &module, EvalCode); + cg.generateFromProgram(sourceFile, sourceCode, program, &module, compilationMode); if (v4->hasException) return; @@ -219,7 +219,7 @@ QQmlRefPointer Script::precompile(QV4::Compi Codegen cg(unitGenerator, /*strict mode*/false); cg.setUseFastLookups(false); - cg.generateFromProgram(url.toString(), source, program, module, EvalCode); + cg.generateFromProgram(url.toString(), source, program, module, GlobalCode); errors = cg.qmlErrors(); if (!errors.isEmpty()) { if (reportedErrors) -- cgit v1.2.3 From 44a68a5b9dc551e2af019e5df005e31cdf709023 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 30 Aug 2017 22:16:28 +0200 Subject: Cleanups Change-Id: Iba5a238c98617f99049dc0e529e642b924e42755 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4script.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index a0aa1b1f2d..59d418a6d3 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -154,7 +154,7 @@ ReturnedValue Script::run() QV4::ScopedCallData cData(scope); cData->thisObject = engine->globalObject; cData->context = *scope; - return vmFunction->execute(cData); + return vmFunction->call(cData); } else { Scoped qml(valueScope, qmlContext.value()); ScopedCallData callData(valueScope); -- cgit v1.2.3 From aa8f956e8d742ec25a01dfeb0d7a7ce54b49ed73 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 1 Sep 2017 10:09:45 +0200 Subject: Move ScopedCallData and ScopedStackFrame into a separate file Change-Id: I9ae42aa7a811aa93fe0950725e9d253a0c5e8dba Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4script.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 59d418a6d3..598c12ffd4 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -45,6 +45,7 @@ #include "qv4debugging_p.h" #include "qv4profiling_p.h" #include "qv4scopedvalue_p.h" +#include "qv4jscall_p.h" #include #include -- cgit v1.2.3 From 74c8fe86755af485f8d0a47799d6d50f00070f05 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 1 Sep 2017 11:48:15 +0200 Subject: Always set the correct FunctionObject when calling JS functions Renamed ScopedCallData to JSCall, enforced passing a JS FunctionObject to it, and added call() and callAsConstructor() methods to it. Change-Id: I30db65c9765c2896b5909fe2105c0934c6dad861 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4script.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 598c12ffd4..c3200fbcea 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -152,16 +152,16 @@ ReturnedValue Script::run() ContextStateSaver stateSaver(valueScope, scope); scope->d()->v4Function = vmFunction; - QV4::ScopedCallData cData(scope); - cData->thisObject = engine->globalObject; - cData->context = *scope; - return vmFunction->call(cData); + QV4::JSCall jsCall(scope, nullptr); + jsCall->thisObject = engine->globalObject; + jsCall->context = *scope; + return vmFunction->call(jsCall); } else { Scoped qml(valueScope, qmlContext.value()); - ScopedCallData callData(valueScope); - callData->thisObject = Primitive::undefinedValue(); - callData->context = *qml; - return vmFunction->call(callData); + JSCall jsCall(valueScope, nullptr); + jsCall->thisObject = Primitive::undefinedValue(); + jsCall->context = *qml; + return vmFunction->call(jsCall); } } -- cgit v1.2.3 From acd206e317fd92f20aa4985f35288f793d05f3ac Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Fri, 15 Sep 2017 10:14:58 +0200 Subject: Fix CallData setup for Script::run By calling JSCall with an ExecutionContext as first parameter, the compiler would implicitly create a temporary Scope object in order to be able to do the call. However, the scope would then wipe the stack when it is being destructed. So subsequently retrieving argc would always result in 0 arguments. To prevent accidents like this, all Scope constructors are now explicit, and the QV4::Script's ExecutionContext is renamed from scope to context. Change-Id: Iea7930748a0544382a20b6617fa9818a8a2bea7f Reviewed-by: Lars Knoll --- src/qml/jsruntime/qv4script.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index c3200fbcea..9850734aa1 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -61,7 +61,7 @@ using namespace QV4; Script::Script(ExecutionEngine *v4, QmlContext *qml, CompiledData::CompilationUnit *compilationUnit) - : line(1), column(0), scope(v4->rootContext()), strictMode(false), inheritContext(true), parsed(false) + : line(1), column(0), context(v4->rootContext()), strictMode(false), inheritContext(true), parsed(false) , compilationUnit(compilationUnit), vmFunction(0), parseAsBinding(true) { if (qml) @@ -85,7 +85,7 @@ void Script::parse() parsed = true; - ExecutionEngine *v4 = scope->engine(); + ExecutionEngine *v4 = context->engine(); Scope valueScope(v4); Module module(v4->debugger() != 0); @@ -143,18 +143,18 @@ ReturnedValue Script::run() if (!vmFunction) return Encode::undefined(); - QV4::ExecutionEngine *engine = scope->engine(); + QV4::ExecutionEngine *engine = context->engine(); QV4::Scope valueScope(engine); if (qmlContext.isUndefined()) { TemporaryAssignment savedGlobalCode(engine->globalCode, vmFunction); - ContextStateSaver stateSaver(valueScope, scope); - scope->d()->v4Function = vmFunction; + ContextStateSaver stateSaver(valueScope, context); + context->d()->v4Function = vmFunction; - QV4::JSCall jsCall(scope, nullptr); + QV4::JSCall jsCall(valueScope, nullptr); jsCall->thisObject = engine->globalObject; - jsCall->context = *scope; + jsCall->context = *context; return vmFunction->call(jsCall); } else { Scoped qml(valueScope, qmlContext.value()); -- cgit v1.2.3 From c6c79644dc869259482a011f8b737f709af02fb2 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 20 Oct 2017 15:14:41 +0200 Subject: Rename JSCall to JSCallData As, this is going to change in a simple stack based structure to keep pointers to the data to pass to calls. Change-Id: Ia9aa3f81ee3eeba36affd16aac7b2fe97d59aea9 Reviewed-by: Erik Verbruggen --- src/qml/jsruntime/qv4script.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 9850734aa1..917145c4d2 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -152,13 +152,13 @@ ReturnedValue Script::run() ContextStateSaver stateSaver(valueScope, context); context->d()->v4Function = vmFunction; - QV4::JSCall jsCall(valueScope, nullptr); + QV4::JSCallData jsCall(valueScope, nullptr); jsCall->thisObject = engine->globalObject; jsCall->context = *context; return vmFunction->call(jsCall); } else { Scoped qml(valueScope, qmlContext.value()); - JSCall jsCall(valueScope, nullptr); + JSCallData jsCall(valueScope, nullptr); jsCall->thisObject = Primitive::undefinedValue(); jsCall->context = *qml; return vmFunction->call(jsCall); -- cgit v1.2.3 From 9b25000cb41b97c9c9f49a542c9b82cf25c032db Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 20 Oct 2017 16:11:37 +0200 Subject: Get rid of the implicit cast operator to a CallData Change-Id: I1c35fbf8f7355bc2393ae931f99e591b800f2f45 Reviewed-by: Erik Verbruggen --- src/qml/jsruntime/qv4script.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 917145c4d2..c0a00032dd 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -155,13 +155,13 @@ ReturnedValue Script::run() QV4::JSCallData jsCall(valueScope, nullptr); jsCall->thisObject = engine->globalObject; jsCall->context = *context; - return vmFunction->call(jsCall); + return vmFunction->call(jsCall.callData()); } else { Scoped qml(valueScope, qmlContext.value()); JSCallData jsCall(valueScope, nullptr); jsCall->thisObject = Primitive::undefinedValue(); jsCall->context = *qml; - return vmFunction->call(jsCall); + return vmFunction->call(jsCall.callData()); } } -- cgit v1.2.3 From bc5ff76e5afe6356bebb344c9a5d8b304e852f3c Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 20 Oct 2017 16:54:10 +0200 Subject: Simplify JSCallData construction Change-Id: Ic53532edae9a209aa7125af6f00a9d993d74f1a3 Reviewed-by: Erik Verbruggen --- src/qml/jsruntime/qv4script.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index c0a00032dd..8ca4985b32 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -152,13 +152,13 @@ ReturnedValue Script::run() ContextStateSaver stateSaver(valueScope, context); context->d()->v4Function = vmFunction; - QV4::JSCallData jsCall(valueScope, nullptr); + QV4::JSCallData jsCall(valueScope); jsCall->thisObject = engine->globalObject; jsCall->context = *context; return vmFunction->call(jsCall.callData()); } else { Scoped qml(valueScope, qmlContext.value()); - JSCallData jsCall(valueScope, nullptr); + JSCallData jsCall(valueScope); jsCall->thisObject = Primitive::undefinedValue(); jsCall->context = *qml; return vmFunction->call(jsCall.callData()); -- cgit v1.2.3 From e72306a6f2aeb2bddbb462c205db8fad2fb5a1a4 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 20 Oct 2017 17:19:25 +0200 Subject: Further cleanup JSCallData Avoid allocations on the JS stack if possible Change-Id: I344cd6dceb6264314f9d22c94db22b22d1d24d14 Reviewed-by: Erik Verbruggen --- src/qml/jsruntime/qv4script.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 8ca4985b32..c3b19ac77c 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -154,14 +154,15 @@ ReturnedValue Script::run() QV4::JSCallData jsCall(valueScope); jsCall->thisObject = engine->globalObject; - jsCall->context = *context; - return vmFunction->call(jsCall.callData()); + QV4::CallData *cData = jsCall.callData(); + cData->context = *context; + return vmFunction->call(cData); } else { Scoped qml(valueScope, qmlContext.value()); JSCallData jsCall(valueScope); - jsCall->thisObject = Primitive::undefinedValue(); - jsCall->context = *qml; - return vmFunction->call(jsCall.callData()); + QV4::CallData *cData = jsCall.callData(); + cData->context = *qml; + return vmFunction->call(cData); } } -- cgit v1.2.3 From a2142203ad6cdb54ec063e259b40171e13c5d4bd Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 23 Oct 2017 10:10:28 +0200 Subject: Finally get rid of the QV4::Function pointer in the context Change-Id: Iad6018f67faa956d385087865fca9d73419e363e Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4script.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index c3b19ac77c..7ac46bf594 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -149,9 +149,6 @@ ReturnedValue Script::run() if (qmlContext.isUndefined()) { TemporaryAssignment savedGlobalCode(engine->globalCode, vmFunction); - ContextStateSaver stateSaver(valueScope, context); - context->d()->v4Function = vmFunction; - QV4::JSCallData jsCall(valueScope); jsCall->thisObject = engine->globalObject; QV4::CallData *cData = jsCall.callData(); -- cgit v1.2.3 From 831ddc54932d2681712ca9fa3e94484ae11d59f7 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 24 Oct 2017 14:57:53 +0200 Subject: Cut out one more C++ layer when doing JS function calls Change-Id: I0e2ac30b7e6d77fe41deb84a97b0a7f220437c6a Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4script.cpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 7ac46bf594..901f2574da 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -149,17 +149,10 @@ ReturnedValue Script::run() if (qmlContext.isUndefined()) { TemporaryAssignment savedGlobalCode(engine->globalCode, vmFunction); - QV4::JSCallData jsCall(valueScope); - jsCall->thisObject = engine->globalObject; - QV4::CallData *cData = jsCall.callData(); - cData->context = *context; - return vmFunction->call(cData); + return vmFunction->call(engine->globalObject, 0, 0, context); } else { Scoped qml(valueScope, qmlContext.value()); - JSCallData jsCall(valueScope); - QV4::CallData *cData = jsCall.callData(); - cData->context = *qml; - return vmFunction->call(cData); + return vmFunction->call(0, 0, 0, qml); } } -- cgit v1.2.3 From 52bc4fbfbae6aa1569dc134dd103e966f04bc2e6 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 11 Dec 2017 12:44:47 +0100 Subject: Use potentially intercepted URL as ID for compilation units We generally have to pass a URL and a file name everywhere because the logical URL might be something else than the actual file being loaded. For example a QQmlFileSelector might modify the URL to be loaded for a specific file. This resulting URL, however, should not be used to resolve further URLs defined in the file loaded that way. As we need to access QQmlTypeLoader::m_url as string more often now, cache it and avoid frequent translations between QUrl and QString. Furthermore, QQmlDataBlob's URLs are changed to follow the same semantics. The finalUrl is the one that should be used to resolve further URLs, the url is the one used to load the content, and subject to any redirects or interceptions. This changes the semantics of URL redirects. Previously a redirected URL was used as the base URL for furher URL resolution. This doesn't work because redirection occurs after interception and interception should not influence the resolution of further URLs. We now use the original URL as base URL for resolution of further URLs and rely on the server to redirect those, too. Task-number: QTBUG-61209 Change-Id: I93822f820bed2515995de3cb118099218b510ca4 Reviewed-by: Michael Brasser --- src/qml/jsruntime/qv4script.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 62145f36cc..9d1d5e2589 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -127,7 +127,8 @@ void Script::parse() } RuntimeCodegen cg(v4, strictMode); - cg.generateFromProgram(sourceFile, sourceCode, program, &module, QQmlJS::Codegen::EvalCode, inheritedLocals); + cg.generateFromProgram(sourceFile, sourceFile, sourceCode, program, &module, + QQmlJS::Codegen::EvalCode, inheritedLocals); if (v4->hasException) return; @@ -186,7 +187,10 @@ Function *Script::function() return vmFunction; } -QQmlRefPointer Script::precompile(IR::Module *module, Compiler::JSUnitGenerator *unitGenerator, ExecutionEngine *engine, const QUrl &url, const QString &source, QList *reportedErrors, QQmlJS::Directives *directivesCollector) +QQmlRefPointer Script::precompile( + IR::Module *module, Compiler::JSUnitGenerator *unitGenerator, ExecutionEngine *engine, + const QString &fileName, const QString &finalUrl, const QString &source, + QList *reportedErrors, QQmlJS::Directives *directivesCollector) { using namespace QQmlJS; using namespace QQmlJS::AST; @@ -205,12 +209,12 @@ QQmlRefPointer Script::precompile(IR::Module const auto diagnosticMessages = parser.diagnosticMessages(); for (const QQmlJS::DiagnosticMessage &m : diagnosticMessages) { if (m.isWarning()) { - qWarning("%s:%d : %s", qPrintable(url.toString()), m.loc.startLine, qPrintable(m.message)); + qWarning("%s:%d : %s", qPrintable(fileName), m.loc.startLine, qPrintable(m.message)); continue; } QQmlError error; - error.setUrl(url); + error.setUrl(QUrl(fileName)); error.setDescription(m.message); error.setLine(m.loc.startLine); error.setColumn(m.loc.startColumn); @@ -231,7 +235,7 @@ QQmlRefPointer Script::precompile(IR::Module } QQmlJS::Codegen cg(/*strict mode*/false); - cg.generateFromProgram(url.toString(), source, program, module, QQmlJS::Codegen::EvalCode); + cg.generateFromProgram(fileName, finalUrl, source, program, module, QQmlJS::Codegen::EvalCode); errors = cg.qmlErrors(); if (!errors.isEmpty()) { if (reportedErrors) -- cgit v1.2.3 From fff473c6387b0ab241a9b2e1f6e8843d777befb8 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 23 Jan 2018 14:02:49 +0100 Subject: Remove some duplicated code We can centralize the code that initializes a V4::Script instance used in worker scripts as well as in the Qt.include() function. Change-Id: I9a83f990c694eb4d793ec5ac3b1c917d8c068d06 Reviewed-by: Lars Knoll --- src/qml/jsruntime/qv4script.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 901f2574da..369ec7d67e 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -222,6 +222,26 @@ QQmlRefPointer Script::precompile(QV4::Compi return cg.generateCompilationUnit(/*generate unit data*/false); } +Script *Script::createFromFileOrCache(ExecutionEngine *engine, QmlContext *qmlContext, const QString &fileName, const QUrl &originalUrl) +{ + if (const QQmlPrivate::CachedQmlUnit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(originalUrl)) { + QV4::CompiledData::CompilationUnit *jsUnit = cachedUnit->createCompilationUnit(); + return new QV4::Script(engine, qmlContext, jsUnit); + } + + QFile f(fileName); + if (!f.open(QIODevice::ReadOnly)) + return nullptr; + + QByteArray data = f.readAll(); + QString sourceCode = QString::fromUtf8(data); + QmlIR::Document::removeScriptPragmas(sourceCode); + + auto result = new QV4::Script(engine, qmlContext, sourceCode, originalUrl.toString()); + result->parse(); + return result; +} + QV4::ReturnedValue Script::evaluate(ExecutionEngine *engine, const QString &script, QmlContext *qmlContext) { QV4::Scope scope(engine); -- cgit v1.2.3 From f9dc375fbd329e80bda8ceb6e3a425917bb1f4fd Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 23 Jan 2018 14:05:42 +0100 Subject: Fix compilation unit memory leak when using qml caching from resources The unit created via the factory function has a refcount of 1, so we need to adopt it. Change-Id: Ia7aadf02c9fc133919f97ea07fc3f3546a7e2680 Reviewed-by: Lars Knoll --- src/qml/jsruntime/qv4script.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 369ec7d67e..caddf0a3e0 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -225,7 +225,8 @@ QQmlRefPointer Script::precompile(QV4::Compi Script *Script::createFromFileOrCache(ExecutionEngine *engine, QmlContext *qmlContext, const QString &fileName, const QUrl &originalUrl) { if (const QQmlPrivate::CachedQmlUnit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(originalUrl)) { - QV4::CompiledData::CompilationUnit *jsUnit = cachedUnit->createCompilationUnit(); + QQmlRefPointer jsUnit; + jsUnit.adopt(cachedUnit->createCompilationUnit()); return new QV4::Script(engine, qmlContext, jsUnit); } -- cgit v1.2.3 From 6ef66a5dfe938a23c67c0aef0d6c7ebc98b8cca8 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 23 Jan 2018 14:14:47 +0100 Subject: Remove private API dependency of qmlcachegen generated code Since the compilation unit does not have a backend anymore, we can create it in QtQml itself instead of in generated stub code. That removes the last dependency to private headers in the generated code. Change-Id: I186fc5bd679476b1a4714e4e3ba0ac00b55676cf Reviewed-by: Lars Knoll --- src/qml/jsruntime/qv4script.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index caddf0a3e0..70ea022fe6 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -226,7 +226,7 @@ Script *Script::createFromFileOrCache(ExecutionEngine *engine, QmlContext *qmlCo { if (const QQmlPrivate::CachedQmlUnit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(originalUrl)) { QQmlRefPointer jsUnit; - jsUnit.adopt(cachedUnit->createCompilationUnit()); + jsUnit.adopt(new QV4::CompiledData::CompilationUnit(cachedUnit->qmlData)); return new QV4::Script(engine, qmlContext, jsUnit); } -- cgit v1.2.3 From eace041161a03a849d3896af65493b7885cecc04 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 23 Jan 2018 14:30:09 +0100 Subject: Get rid of internal QQmlPrivate::CachedQmlUnit interface part 1 Within QtQml we don't need to use this data structure anymore, we can use its one member directly Change-Id: Id850e12918257c7af3c97bfef41d1e93578842d2 Reviewed-by: Lars Knoll --- src/qml/jsruntime/qv4script.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 70ea022fe6..e0c0c2d403 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -224,9 +224,9 @@ QQmlRefPointer Script::precompile(QV4::Compi Script *Script::createFromFileOrCache(ExecutionEngine *engine, QmlContext *qmlContext, const QString &fileName, const QUrl &originalUrl) { - if (const QQmlPrivate::CachedQmlUnit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(originalUrl)) { + if (const QV4::CompiledData::Unit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(originalUrl)) { QQmlRefPointer jsUnit; - jsUnit.adopt(new QV4::CompiledData::CompilationUnit(cachedUnit->qmlData)); + jsUnit.adopt(new QV4::CompiledData::CompilationUnit(cachedUnit)); return new QV4::Script(engine, qmlContext, jsUnit); } -- cgit v1.2.3 From 499ec43937e926e4f2fa57a9baa455fcb3862262 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Wed, 21 Feb 2018 10:41:54 +0100 Subject: use nullptr consistently (clang-tidy) From now on we prefer nullptr instead of 0 to clarify cases where we are assigning or testing a pointer rather than a numeric zero. Also, replaced cases where 0 was passed as Qt::KeyboardModifiers with Qt::NoModifier (clang-tidy replaced them with nullptr, which waas wrong, so it was just as well to make the tests more readable rather than to revert those lines). Change-Id: I4735d35e4d9f42db5216862ce091429eadc6e65d Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4script.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 0c5f02bcfc..bb6608bec0 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -62,14 +62,14 @@ using namespace QV4; Script::Script(ExecutionEngine *v4, QmlContext *qml, CompiledData::CompilationUnit *compilationUnit) : line(1), column(0), context(v4->rootContext()), strictMode(false), inheritContext(true), parsed(false) - , compilationUnit(compilationUnit), vmFunction(0), parseAsBinding(true) + , compilationUnit(compilationUnit), vmFunction(nullptr), parseAsBinding(true) { if (qml) qmlContext.set(v4, *qml); parsed = true; - vmFunction = compilationUnit ? compilationUnit->linkToEngine(v4) : 0; + vmFunction = compilationUnit ? compilationUnit->linkToEngine(v4) : nullptr; } Script::~Script() @@ -88,7 +88,7 @@ void Script::parse() ExecutionEngine *v4 = context->engine(); Scope valueScope(v4); - Module module(v4->debugger() != 0); + Module module(v4->debugger() != nullptr); Engine ee, *engine = ⅇ Lexer lexer(engine); @@ -149,10 +149,10 @@ ReturnedValue Script::run() if (qmlContext.isUndefined()) { TemporaryAssignment savedGlobalCode(engine->globalCode, vmFunction); - return vmFunction->call(engine->globalObject, 0, 0, context); + return vmFunction->call(engine->globalObject, nullptr, 0, context); } else { Scoped qml(valueScope, qmlContext.value()); - return vmFunction->call(0, 0, 0, qml); + return vmFunction->call(nullptr, nullptr, 0, qml); } } @@ -199,14 +199,14 @@ QQmlRefPointer Script::precompile(QV4::Compi if (!errors.isEmpty()) { if (reportedErrors) *reportedErrors << errors; - return 0; + return nullptr; } Program *program = AST::cast(parser.rootNode()); if (!program) { // if parsing was successful, and we have no program, then // we're done...: - return 0; + return nullptr; } Codegen cg(unitGenerator, /*strict mode*/false); @@ -216,7 +216,7 @@ QQmlRefPointer Script::precompile(QV4::Compi if (!errors.isEmpty()) { if (reportedErrors) *reportedErrors << errors; - return 0; + return nullptr; } return cg.generateCompilationUnit(/*generate unit data*/false); -- cgit v1.2.3 From 61447075954aab99b3abc9c78294e5966ae3b6ce Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 16 Mar 2018 14:51:15 +0100 Subject: Pass "this" object when evaluating debug jobs We have to explicitly specify the "this" object on QV4::Function::call, otherwise it will assume undefined or the QML global object. Task-number: QTBUG-66942 Change-Id: I1af7742b4fee1b49e9760a413834daf3edb15d74 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4script.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index bb6608bec0..267c93952d 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -136,7 +136,7 @@ void Script::parse() } } -ReturnedValue Script::run() +ReturnedValue Script::run(const QV4::Value *thisObject) { if (!parsed) parse(); @@ -149,10 +149,11 @@ ReturnedValue Script::run() if (qmlContext.isUndefined()) { TemporaryAssignment savedGlobalCode(engine->globalCode, vmFunction); - return vmFunction->call(engine->globalObject, nullptr, 0, context); + return vmFunction->call(thisObject ? thisObject : engine->globalObject, nullptr, 0, + context); } else { Scoped qml(valueScope, qmlContext.value()); - return vmFunction->call(nullptr, nullptr, 0, qml); + return vmFunction->call(thisObject, nullptr, 0, qml); } } -- cgit v1.2.3 From 64e90f393146dadb382d154e7d67a9109ab2492a Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 9 Mar 2018 16:40:38 +0100 Subject: Fix QML data structure version checking for ahead-of-time generated files We must also do version checking for QML and JS files that were compiled ahead of time and are embedded in resources. If the lookup for the original source code fails, then we must generate an appropriate error message. As an upside we get better error reporting when trying to load an empty file and Qt.include() now reports the error message in the statusText field. The error reporting for imported scripts was not changed as importing an empty script is (oddly) allowed. Task-number: QTBUG-66986 Change-Id: Ie0ef81af371a51ecf8c66ae7954d43f5cc6c12de Reviewed-by: Erik Verbruggen --- src/qml/jsruntime/qv4script.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 267c93952d..b4d9e11716 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -223,17 +223,28 @@ QQmlRefPointer Script::precompile(QV4::Compi return cg.generateCompilationUnit(/*generate unit data*/false); } -Script *Script::createFromFileOrCache(ExecutionEngine *engine, QmlContext *qmlContext, const QString &fileName, const QUrl &originalUrl) +Script *Script::createFromFileOrCache(ExecutionEngine *engine, QmlContext *qmlContext, const QString &fileName, const QUrl &originalUrl, QString *error) { - if (const QV4::CompiledData::Unit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(originalUrl)) { + if (error) + error->clear(); + + QQmlMetaType::CachedUnitLookupError cacheError = QQmlMetaType::CachedUnitLookupError::NoError; + if (const QV4::CompiledData::Unit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(originalUrl, &cacheError)) { QQmlRefPointer jsUnit; jsUnit.adopt(new QV4::CompiledData::CompilationUnit(cachedUnit)); return new QV4::Script(engine, qmlContext, jsUnit); } QFile f(fileName); - if (!f.open(QIODevice::ReadOnly)) + if (!f.open(QIODevice::ReadOnly)) { + if (error) { + if (cacheError == QQmlMetaType::CachedUnitLookupError::VersionMismatch) + *error = originalUrl.toString() + QString::fromUtf8(" was compiled ahead of time with an incompatible version of Qt and the original source code cannot be found. Please recompile"); + else + *error = QString::fromUtf8("Error opening source file %1: %2").arg(originalUrl.toString()).arg(f.errorString()); + } return nullptr; + } QByteArray data = f.readAll(); QString sourceCode = QString::fromUtf8(data); -- cgit v1.2.3 From 8780764b274217b256aadd00114a76bdffbdb1ef Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 10 Apr 2018 11:07:24 +0200 Subject: Warn about non spec compliant extension being used eval("function(){}") would return a function object in our engine. This is not compliant with the ES spec, so warn about it, as it'll start throwing a syntax error in 5.12. Also fix the two places where we were using that syntax in our auto tests. Change-Id: I573c2ad0ec4955570b857c69edef2f75998d55a9 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4script.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index b4d9e11716..afa7d2ed52 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -90,6 +90,12 @@ void Script::parse() Module module(v4->debugger() != nullptr); + if (sourceCode.startsWith(QLatin1String("function("))) { + qWarning() << "Warning: Using function expressions as statements in scripts in not compliant with the ECMAScript specification at\n" + << (sourceCode.leftRef(70) + QLatin1String("...")) + << "\nThis will throw a syntax error in Qt 5.12. If you want a function expression, surround it by parentheses."; + } + Engine ee, *engine = ⅇ Lexer lexer(engine); lexer.setCode(sourceCode, line, parseAsBinding); -- cgit v1.2.3 From 1a3447a0405831fa5502247f9eaff48afdfe0dea Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 23 Apr 2018 13:28:58 +0200 Subject: Clean up manual reference of QQmlTypeData and QQmlPropertyCache We have a few places in the type loader where we do adventurous manual reference counting, where getType() returns a raw pointer that has been addref()'ed and then sometimes somehow we call release() later. Commit 0b394e30bba4f6bb7e6f7dbe5585a2e15aa0f21d is an example of where this can easily go wrong. As a consequence and also in preparation for future work on the type loader, this patch starts replacing the manual reference counting there. Changing the return type from QQmlTypeData *getType() to a QQmlRefPointer<> itself is not sufficient though, as the implicit operator T*() will still allow the caller to store the result as a raw pointer. Therefore this patch removes the "unsafe" implicit extraction operator. As a result of that change, other types that are sometimes stored in QQmlRefPointer are also affected and their usage needs to be adapted to QQmlRefPointer usage or manual raw pointer extraction with .data(). Change-Id: I18fd40634047f13196a237f4e6766cbef3bfbea2 Reviewed-by: Lars Knoll --- src/qml/jsruntime/qv4script.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index afa7d2ed52..01d6bfd368 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -60,7 +60,7 @@ using namespace QV4; -Script::Script(ExecutionEngine *v4, QmlContext *qml, CompiledData::CompilationUnit *compilationUnit) +Script::Script(ExecutionEngine *v4, QmlContext *qml, const QQmlRefPointer &compilationUnit) : line(1), column(0), context(v4->rootContext()), strictMode(false), inheritContext(true), parsed(false) , compilationUnit(compilationUnit), vmFunction(nullptr), parseAsBinding(true) { -- cgit v1.2.3 From e9492e7b7b44c1f8cd5489d93463fc2b1f8b6d72 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 26 Mar 2018 21:32:05 +0200 Subject: Rename the CompilationMode enum to ContextType And make it an enum class. The new name fits better, as it's mainly used to determine the type of the context when parsing. Also already added the 'Block' value that will be needed. Change-Id: I70d963b6a0b22db1a3c607cce6bdd2054b29e000 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4script.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 01d6bfd368..daff1c659a 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -127,7 +127,7 @@ void Script::parse() RuntimeCodegen cg(v4, &jsGenerator, strictMode); if (inheritContext) cg.setUseFastLookups(false); - cg.generateFromProgram(sourceFile, sourceFile, sourceCode, program, &module, compilationMode); + cg.generateFromProgram(sourceFile, sourceFile, sourceCode, program, &module, contextType); if (v4->hasException) return; @@ -218,7 +218,7 @@ QQmlRefPointer Script::precompile(QV4::Compi Codegen cg(unitGenerator, /*strict mode*/false); cg.setUseFastLookups(false); - cg.generateFromProgram(fileName, finalUrl, source, program, module, GlobalCode); + cg.generateFromProgram(fileName, finalUrl, source, program, module, ContextType::Global); errors = cg.qmlErrors(); if (!errors.isEmpty()) { if (reportedErrors) -- cgit v1.2.3 From 0ee2d9be1f8ab706a193e4f0cf095ee79e8210a8 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 27 Apr 2018 15:47:52 +0200 Subject: Fix heap-use-after-free Commit a1e5364b492610adf0636fefa3fc400558e211b6 introduced the use of AST elements at qml compilation unit generation time, which uncovered the issue that for scripts imported from qml files, the memory pool for the AST was local to QV4::Script::precompile. Therefore the memory where the AST stored was freed afterwards and any use after ::precompile() would produce ASAN errors. There's no good reason for Script::precompile to have its own local memory pool. Change-Id: I4f8eb5ee4e9d62d8874241bc95fc71a912e26cea Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4script.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index daff1c659a..ca6e4c50b1 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -170,19 +170,16 @@ Function *Script::function() return vmFunction; } -QQmlRefPointer Script::precompile(QV4::Compiler::Module *module, Compiler::JSUnitGenerator *unitGenerator, +QQmlRefPointer Script::precompile(QV4::Compiler::Module *module, QQmlJS::Engine *jsEngine, Compiler::JSUnitGenerator *unitGenerator, const QString &fileName, const QString &finalUrl, const QString &source, - QList *reportedErrors, Directives *directivesCollector) + QList *reportedErrors) { using namespace QV4::Compiler; using namespace QQmlJS::AST; - Engine ee; - if (directivesCollector) - ee.setDirectives(directivesCollector); - Lexer lexer(&ee); + Lexer lexer(jsEngine); lexer.setCode(source, /*line*/1, /*qml mode*/false); - Parser parser(&ee); + Parser parser(jsEngine); parser.parseProgram(); -- cgit v1.2.3 From fceb04cf29764c815fb539d3d62ed26edcb78448 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Wed, 20 Jun 2018 17:01:29 +0200 Subject: Script::parse(): improve "function expressions as statement" error msg Change-Id: I3c54c90bfa48d2f6ba78b898413133e49b66c208 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4script.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index afa7d2ed52..5cd62c90f1 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -91,9 +91,10 @@ void Script::parse() Module module(v4->debugger() != nullptr); if (sourceCode.startsWith(QLatin1String("function("))) { - qWarning() << "Warning: Using function expressions as statements in scripts in not compliant with the ECMAScript specification at\n" - << (sourceCode.leftRef(70) + QLatin1String("...")) - << "\nThis will throw a syntax error in Qt 5.12. If you want a function expression, surround it by parentheses."; + static const int snippetLength = 70; + qWarning() << "Warning: Using function expressions as statements in scripts is not compliant with the ECMAScript specification:\n" + << (sourceCode.leftRef(snippetLength) + QLatin1String("...")) + << "\nThis will throw a syntax error in Qt 5.12. If you want a function expression, surround it by parentheses."; } Engine ee, *engine = ⅇ -- cgit v1.2.3 From 6b53e7e16df0a2451d2b7948ad35485301c564b6 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 11 Jul 2018 14:55:08 +0200 Subject: Get rid of TemporaryAssignment We can use QScopedValueRollback from QtCore for the same purpose. Change-Id: I5ca37a52bde5469cdb76928913835140241d42b1 Reviewed-by: Erik Verbruggen --- src/qml/jsruntime/qv4script.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index efd528860f..37c4f27ca9 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -57,6 +57,7 @@ #include #include +#include using namespace QV4; @@ -154,7 +155,7 @@ ReturnedValue Script::run(const QV4::Value *thisObject) QV4::Scope valueScope(engine); if (qmlContext.isUndefined()) { - TemporaryAssignment savedGlobalCode(engine->globalCode, vmFunction); + QScopedValueRollback savedGlobalCode(engine->globalCode, vmFunction); return vmFunction->call(thisObject ? thisObject : engine->globalObject, nullptr, 0, context); -- cgit v1.2.3 From f43c1d902d908c6cd523b0174338ac0c98a30647 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 16 Aug 2018 10:57:25 +0200 Subject: Add support for importing ES modules in .qml files This is a straight-forward hook into the module implementation in QV4::ExecutionEngine. Modules are pre-compiled in the QML type loader thread. That thread keeps track of all pending loading scripts through the type loader's m_scriptCache. Once a module is compiled, it's thread-safely registered with the execution engine. Script instantiation and evaluation is done solely in the QQmlEngine's thread. ES Modules are identified in imports as well as qmldir files by the .mjs extension. Change-Id: Ie9c59785118afcb49f43a1e176a9f7db00f09428 Reviewed-by: Lars Knoll --- src/qml/jsruntime/qv4script.cpp | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 37c4f27ca9..070c048c8f 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -185,23 +185,7 @@ QQmlRefPointer Script::precompile(QV4::Compi parser.parseProgram(); - QList errors; - - const auto diagnosticMessages = parser.diagnosticMessages(); - for (const DiagnosticMessage &m : diagnosticMessages) { - if (m.isWarning()) { - qWarning("%s:%d : %s", qPrintable(fileName), m.loc.startLine, qPrintable(m.message)); - continue; - } - - QQmlError error; - error.setUrl(QUrl(fileName)); - error.setDescription(m.message); - error.setLine(m.loc.startLine); - error.setColumn(m.loc.startColumn); - errors << error; - } - + QList errors = QQmlEnginePrivate::qmlErrorFromDiagnostics(fileName, parser.diagnosticMessages()); if (!errors.isEmpty()) { if (reportedErrors) *reportedErrors << errors; -- cgit v1.2.3 From 8b418d9be73dafd25c9c528127274a3573f1a7e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCri=20Valdmann?= Date: Fri, 5 Oct 2018 14:17:05 +0200 Subject: Clone ContextType::Global as ContextType::ScriptImportedByQML Add new enum value QV4::Compiler::ContextType::ScriptImportedByQML, which behaves exactly the same as ContextType::Global. A follow-up patch will change the behavior slightly. Task-number: QTBUG-69408 Change-Id: I20d27804fd1433f2229704546bcd78a0ac108c01 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4script.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 070c048c8f..951675b468 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -174,7 +174,8 @@ Function *Script::function() QQmlRefPointer Script::precompile(QV4::Compiler::Module *module, QQmlJS::Engine *jsEngine, Compiler::JSUnitGenerator *unitGenerator, const QString &fileName, const QString &finalUrl, const QString &source, - QList *reportedErrors) + QList *reportedErrors, + QV4::Compiler::ContextType contextType) { using namespace QV4::Compiler; using namespace QQmlJS::AST; @@ -201,7 +202,7 @@ QQmlRefPointer Script::precompile(QV4::Compi Codegen cg(unitGenerator, /*strict mode*/false); cg.setUseFastLookups(false); - cg.generateFromProgram(fileName, finalUrl, source, program, module, ContextType::Global); + cg.generateFromProgram(fileName, finalUrl, source, program, module, contextType); errors = cg.qmlErrors(); if (!errors.isEmpty()) { if (reportedErrors) -- cgit v1.2.3 From ae6f850ab50bfe07625df4f810c7bf975c224877 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 7 Nov 2018 10:38:09 +0100 Subject: Generate lookups into the global object more aggressively Since change 9333ea8649838d7e0400b0e94c8cbd4fa5d216b0, we lookup properties in the QML context object before the global object to have proper scoping rules for QML. Unfortunately this lead to a performance regression when using global properties such as Math in imported script files, as the lookup would always go through the qml context first. This can be fixed, as we know that the global object is frozen in qml mode, and the standard names of properties in the global object are illegal to use in QML. So simply check for those names in the code generator and create lookups into the global object for those. Change-Id: I4b2089178c9e5f9440abdfd834cf7d92c3c0e2c3 Fixes: QTBUG-71591 Reviewed-by: Erik Verbruggen --- src/qml/jsruntime/qv4script.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 951675b468..3d8c037910 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -241,6 +241,7 @@ Script *Script::createFromFileOrCache(ExecutionEngine *engine, QmlContext *qmlCo QmlIR::Document::removeScriptPragmas(sourceCode); auto result = new QV4::Script(engine, qmlContext, sourceCode, originalUrl.toString()); + result->contextType = QV4::Compiler::ContextType::ScriptImportedByQML; result->parse(); return result; } -- cgit v1.2.3 From 2fa1c92cb7e60f89e200eff48cf7e76d8d2febe6 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 29 Nov 2018 11:05:04 +0100 Subject: Fix parsing of js files via Qt.include() Make sure to parse them as JavaScript, not as QML, so that certain keywords such as char or double map to identifiers as expected. Also removed an unused function. Fixes: QTBUG-71524 Change-Id: Ie8a8dabe717ee12def6af512943e6d01efcf9876 Reviewed-by: Lars Knoll --- src/qml/jsruntime/qv4script.cpp | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) (limited to 'src/qml/jsruntime/qv4script.cpp') diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 951675b468..f80db86be5 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -240,23 +240,7 @@ Script *Script::createFromFileOrCache(ExecutionEngine *engine, QmlContext *qmlCo QString sourceCode = QString::fromUtf8(data); QmlIR::Document::removeScriptPragmas(sourceCode); - auto result = new QV4::Script(engine, qmlContext, sourceCode, originalUrl.toString()); + auto result = new QV4::Script(engine, qmlContext, /*parseAsBinding*/false, sourceCode, originalUrl.toString()); result->parse(); return result; } - -QV4::ReturnedValue Script::evaluate(ExecutionEngine *engine, const QString &script, QmlContext *qmlContext) -{ - QV4::Scope scope(engine); - QV4::Script qmlScript(engine, qmlContext, script, QString()); - - qmlScript.parse(); - QV4::ScopedValue result(scope); - if (!scope.engine->hasException) - result = qmlScript.run(); - if (scope.engine->hasException) { - scope.engine->catchException(); - return Encode::undefined(); - } - return result->asReturnedValue(); -} -- cgit v1.2.3