30 ExecutionEngine *v4, QmlContext *qml,
31 const QQmlRefPointer<ExecutableCompilationUnit> &compilationUnit)
32 : m_compilationUnit(compilationUnit)
33 , m_context(v4->rootContext())
34 , m_parseAsBinding(
true)
35 , m_inheritContext(
true)
39 m_qmlContext.set(v4, *qml);
41 m_vmFunction.set(v4, compilationUnit ? compilationUnit->rootFunction() :
nullptr);
55 ExecutionEngine *v4 = m_context->engine();
58 QV4::Compiler::Module module(m_sourceFile, m_sourceFile, v4->debugger() !=
nullptr);
60 if (m_sourceCode.startsWith(QLatin1String(
"function("))) {
61 static const int snippetLength = 70;
64 "Using function expressions as statements in scripts is not compliant "
65 "with the ECMAScript specification:"
67 "If you want a function expression, surround it by parentheses.")
68 .arg(QStringView{m_sourceCode}.left(snippetLength)));
72 Engine ee, *engine = ⅇ
74 lexer.setCode(m_sourceCode, m_line, m_parseAsBinding);
75 Parser parser(engine);
77 const bool parsed = parser.parseProgram();
79 const auto diagnosticMessages = parser.diagnosticMessages();
80 for (
const DiagnosticMessage &m : diagnosticMessages) {
82 valueScope.engine->throwSyntaxError(
83 m.message, m_sourceFile, m.loc.startLine, m.loc.startColumn);
86 qWarning() << m_sourceFile <<
':' << m.loc.startLine <<
':' << m.loc.startColumn
87 <<
": warning: " << m.message;
93 Program *program = AST::cast<Program *>(parser.rootNode());
100 QV4::Compiler::JSUnitGenerator jsGenerator(&module);
101 RuntimeCodegen cg(v4, &jsGenerator, m_strictMode);
102 if (m_inheritContext)
103 cg.setUseFastLookups(
false);
104 cg.generateFromProgram(m_sourceCode, program, &module, m_contextType);
105 if (v4->hasException)
108 m_compilationUnit = v4->insertCompilationUnit(cg.generateCompilationUnit());
109 m_vmFunction.set(v4, m_compilationUnit->rootFunction());
114 ScopedObject error(valueScope, v4->newSyntaxErrorObject(QStringLiteral(
"Syntax error")));
115 v4->throwError(error);
119ReturnedValue Script::run(
const QV4::Value *thisObject)
124 return Encode::undefined();
126 QV4::ExecutionEngine *engine = m_context->engine();
127 QV4::Scope valueScope(engine);
129 if (m_qmlContext.isUndefined()) {
130 QScopedValueRollback<Function*> savedGlobalCode(engine->globalCode, m_vmFunction);
132 return m_vmFunction->call(thisObject ? thisObject : engine->globalObject,
nullptr, 0,
135 Scoped<QmlContext> qml(valueScope, m_qmlContext.value());
136 return m_vmFunction->call(thisObject,
nullptr, 0, qml);
147QQmlRefPointer<QV4::CompiledData::CompilationUnit> Script::precompile(
148 QV4::Compiler::Module *module, QQmlJS::Engine *jsEngine,
149 Compiler::JSUnitGenerator *unitGenerator,
const QString &fileName,
150 const QString &source, QList<QQmlError> *reportedErrors,
151 QV4::Compiler::ContextType contextType, InheritContext inheritContext)
153 using namespace QV4::Compiler;
154 using namespace QQmlJS::AST;
156 Lexer lexer(jsEngine);
157 lexer.setCode(source, 1,
false);
158 Parser parser(jsEngine);
160 parser.parseProgram();
162 QList<QQmlError> errors
163 = QQmlEnginePrivate::qmlErrorFromDiagnostics(fileName, parser.diagnosticMessages());
164 if (!errors.isEmpty()) {
166 *reportedErrors << errors;
170 Program *program = AST::cast<Program *>(parser.rootNode());
177 Codegen cg(unitGenerator,
false);
178 if (inheritContext == InheritContext::Yes)
179 cg.setUseFastLookups(
false);
180 cg.generateFromProgram(source, program, module, contextType);
182 if (reportedErrors) {
183 const auto v4Error = cg.error();
185 error.setUrl(cg.url());
186 error.setLine(qmlConvertSourceCoordinate<quint32,
int>(v4Error.loc.startLine));
187 error.setColumn(qmlConvertSourceCoordinate<quint32,
int>(v4Error.loc.startColumn));
188 error.setDescription(v4Error.message);
189 reportedErrors->append(error);
194 return cg.generateCompilationUnit(
false);