Make CodeGen usable without a context.
authorErik Verbruggen <erik.verbruggen@me.com>
Wed, 16 Jan 2013 12:36:14 +0000 (13:36 +0100)
committerLars Knoll <lars.knoll@digia.com>
Wed, 16 Jan 2013 14:56:02 +0000 (15:56 +0100)
When running with the LLVM backend, there is no VM context.

Change-Id: Ib4e95a3c3b92f20118269da1a9430a9278beb349
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
main.cpp
qv4codegen.cpp
qv4codegen_p.h

index 748294b..a948544 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -54,6 +54,7 @@
 #include "qv4ecmaobjects_p.h"
 #include "qv4isel_p.h"
 #include "qv4mm.h"
+#include "qmljs_environment.h"
 
 #include <QtCore>
 #include <private/qqmljsengine_p.h>
@@ -189,8 +190,10 @@ int compile(const QString &fileName, const QString &source, QQmlJS::LLVMOutputTy
     const bool parsed = parser.parseProgram();
 
     foreach (const DiagnosticMessage &m, parser.diagnosticMessages()) {
-        std::cerr << qPrintable(fileName) << ':' << m.loc.startLine << ':' << m.loc.startColumn
-                  << ": error: " << qPrintable(m.message) << std::endl;
+        std::cerr << qPrintable(fileName) << ':'
+                  << m.loc.startLine << ':'
+                  << m.loc.startColumn << ": error: "
+                  << qPrintable(m.message) << std::endl;
     }
 
     if (!parsed)
@@ -199,7 +202,20 @@ int compile(const QString &fileName, const QString &source, QQmlJS::LLVMOutputTy
     using namespace AST;
     Program *program = AST::cast<Program *>(parser.rootNode());
 
-    Codegen cg(0);
+    class MyErrorHandler: public ErrorHandler {
+    public:
+        virtual void syntaxError(QQmlJS::VM::DiagnosticMessage *message) {
+            for (; message; message = message->next) {
+                std::cerr << qPrintable(message->fileName) << ':'
+                          << message->startLine << ':'
+                          << message->startColumn << ": "
+                          << (message->type == QQmlJS::VM::DiagnosticMessage::Error ? "error" : "warning") << ": "
+                          << qPrintable(message->message) << std::endl;
+            }
+        }
+    } errorHandler;
+
+    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);
 
index 7acdde5..7461aaa 100644 (file)
@@ -204,7 +204,7 @@ public:
     {
         Environment *e = _cg->newEnvironment(node, _env);
         if (!e->isStrict)
-            e->isStrict = _cg->_context->strictMode;
+            e->isStrict = _cg->_strictMode;
         _envStack.append(e);
         _env = e;
     }
@@ -413,7 +413,28 @@ Codegen::Codegen(VM::ExecutionContext *context)
     , _labelledStatement(0)
     , _tryCleanup(0)
     , _context(context)
+    , _strictMode(context->strictMode)
     , _debugger(context->engine->debugger)
+    , _errorHandler(0)
+{
+}
+
+Codegen::Codegen(ErrorHandler *errorHandler, bool strictMode)
+    : _module(0)
+    , _function(0)
+    , _block(0)
+    , _exitBlock(0)
+    , _throwBlock(0)
+    , _returnAddress(0)
+    , _mode(GlobalCode)
+    , _env(0)
+    , _loop(0)
+    , _labelledStatement(0)
+    , _tryCleanup(0)
+    , _context(0)
+    , _strictMode(strictMode)
+    , _debugger(0)
+    , _errorHandler(errorHandler)
 {
 }
 
@@ -2490,5 +2511,10 @@ void Codegen::throwSyntaxError(const SourceLocation &loc, const QString &detail)
     msg->startLine = loc.startLine;
     msg->startColumn = loc.startColumn;
     msg->message = detail;
-    _context->throwSyntaxError(msg);
+    if (_context)
+        _context->throwSyntaxError(msg);
+    else if (_errorHandler)
+        _errorHandler->syntaxError(msg);
+    else
+        Q_ASSERT(!"No error handler available.");
 }
index 4ee9c5a..e6308ac 100644 (file)
@@ -52,6 +52,7 @@ class UiParameterList;
 }
 
 namespace VM {
+struct DiagnosticMessage;
 struct ExecutionContext;
 }
 
@@ -59,10 +60,17 @@ namespace Debugging {
 class Debugger;
 } // namespace Debugging
 
+class ErrorHandler
+{
+public:
+    virtual void syntaxError(VM::DiagnosticMessage *message) = 0;
+};
+
 class Codegen: protected AST::Visitor
 {
 public:
     Codegen(VM::ExecutionContext *ctx);
+    Codegen(ErrorHandler *errorHandler, bool strictMode);
 
     enum Mode {
         GlobalCode,
@@ -391,7 +399,9 @@ private:
     QHash<AST::Node *, Environment *> _envMap;
     QHash<AST::FunctionExpression *, int> _functionMap;
     VM::ExecutionContext *_context;
+    bool _strictMode;
     Debugging::Debugger *_debugger;
+    ErrorHandler *_errorHandler;
 
     class ScanFunctions;
 };