diff options
Diffstat (limited to 'src/qml/compiler/qv4codegen_p.h')
-rw-r--r-- | src/qml/compiler/qv4codegen_p.h | 175 |
1 files changed, 134 insertions, 41 deletions
diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h index 1db788154e..49607256f9 100644 --- a/src/qml/compiler/qv4codegen_p.h +++ b/src/qml/compiler/qv4codegen_p.h @@ -53,19 +53,11 @@ #include "private/qv4global_p.h" #include <private/qqmljsastvisitor_p.h> #include <private/qqmljsast_p.h> -#include <private/qqmljsengine_p.h> -#include <private/qv4instr_moth_p.h> #include <private/qv4compiler_p.h> #include <private/qv4compilercontext_p.h> -#include <private/qqmlrefcount_p.h> -#include <QtCore/QStringList> -#include <QtCore/QDateTime> -#include <QStack> -#ifndef V4_BOOTSTRAP -#include <qqmlerror.h> -#endif #include <private/qv4util_p.h> #include <private/qv4bytecodegenerator_p.h> +#include <private/qv4stackframe_p.h> QT_BEGIN_NAMESPACE @@ -101,7 +93,13 @@ public: const QString &sourceCode, AST::Program *ast, Module *module, - CompilationMode mode = GlobalCode); + ContextType contextType = ContextType::Global); + + void generateFromModule(const QString &fileName, + const QString &finalUrl, + const QString &sourceCode, + AST::ESModule *ast, + Module *module); public: class VolatileMemoryLocationScanner; @@ -172,16 +170,20 @@ public: } Q_REQUIRED_RESULT RValue storeOnStack() const; + void loadInAccumulator() const; }; struct Reference { enum Type { Invalid, Accumulator, + Super, + SuperProperty, StackSlot, ScopedLocal, Name, Member, Subscript, + Import, QmlScopeObject, QmlContextObject, LastLValue = QmlContextObject, @@ -192,11 +194,14 @@ public: Reference(Codegen *cg, Type type = Invalid) : type(type), codegen(cg) {} Reference() {} - Reference(const Reference &other); - - Reference &operator =(const Reference &other); + Reference(const Reference &) = default; + Reference(Reference &&) = default; + Reference &operator =(const Reference &) = default; + Reference &operator =(Reference &&) = default; bool operator==(const Reference &other) const; + bool operator!=(const Reference &other) const + { return !(*this == other); } bool isValid() const { return type != Invalid; } bool loadTriggersSideEffect() const { @@ -208,13 +213,16 @@ public: case Name: case Member: case Subscript: + case SuperProperty: return true; default: - return false; + return requiresTDZCheck; } } - bool isConst() const { return type == Const; } + bool isConstant() const { return type == Const; } bool isAccumulator() const { return type == Accumulator; } + bool isSuper() const { return type == Super; } + bool isSuperProperty() const { return type == SuperProperty; } bool isStackSlot() const { return type == StackSlot; } bool isRegister() const { return isStackSlot(); @@ -245,6 +253,9 @@ public: static Reference fromAccumulator(Codegen *cg) { return Reference(cg, Accumulator); } + static Reference fromSuper(Codegen *cg) { + return Reference(cg, Super); + } static Reference fromStackSlot(Codegen *cg, int tempIndex = -1, bool isLocal = false) { Reference r(cg, StackSlot); if (tempIndex == -1) @@ -266,6 +277,11 @@ public: r.scope = scope; return r; } + static Reference fromImport(Codegen *cg, int index) { + Reference r(cg, Import); + r.index = index; + return r; + } static Reference fromName(Codegen *cg, const QString &name) { Reference r(cg, Name); r.name = name; @@ -275,6 +291,14 @@ public: Reference r(baseRef.codegen, Member); r.propertyBase = baseRef.asRValue(); r.propertyNameIndex = r.codegen->registerString(name); + r.requiresTDZCheck = baseRef.requiresTDZCheck; + return r; + } + static Reference fromSuperProperty(const Reference &property) { + Q_ASSERT(property.isStackSlot()); + Reference r(property.codegen, SuperProperty); + r.property = property.stackSlot(); + r.subscriptRequiresTDZCheck = property.requiresTDZCheck; return r; } static Reference fromSubscript(const Reference &baseRef, const Reference &subscript) { @@ -282,6 +306,8 @@ public: Reference r(baseRef.codegen, Subscript); r.elementBase = baseRef.stackSlot(); r.elementSubscript = subscript.asRValue(); + r.requiresTDZCheck = baseRef.requiresTDZCheck; + r.subscriptRequiresTDZCheck = subscript.requiresTDZCheck; return r; } static Reference fromConst(Codegen *cg, QV4::ReturnedValue constant) { @@ -309,6 +335,9 @@ public: static Reference fromThis(Codegen *cg) { Reference r = fromStackSlot(cg, CallData::This); r.isReadonly = true; + // ### Optimize this. Functions that are not derived constructors or arrow functions can't have an + // empty this object + r.requiresTDZCheck = true; return r; } @@ -326,6 +355,8 @@ public: Q_REQUIRED_RESULT Reference storeRetainAccumulator() const; Reference storeConsumeAccumulator() const; + Q_REQUIRED_RESULT Reference baseObject() const; + bool storeWipesAccumulator() const; void loadInAccumulator() const; @@ -361,10 +392,14 @@ public: qint16 qmlNotifyIndex; PropertyCapturePolicy capturePolicy; }; + Moth::StackSlot property; // super property }; QString name; mutable bool isArgOrEval = false; bool isReadonly = false; + bool isReferenceToConst = false; + bool requiresTDZCheck = false; + bool subscriptRequiresTDZCheck = false; bool stackSlotIsLocalOrArgument = false; bool isVolatile = false; bool global = false; @@ -468,7 +503,10 @@ protected: void enterContext(AST::Node *node); int leaveContext(); - +public: + Context *enterBlock(AST::Node *node); + int leaveBlock() { return leaveContext(); } +protected: void leaveLoop(); enum UnaryOperation { @@ -486,6 +524,7 @@ protected: void addCJump(); +public: int registerString(const QString &name) { return jsUnitGenerator->registerString(name); } @@ -497,33 +536,37 @@ protected: // Returns index in _module->functions virtual int defineFunction(const QString &name, AST::Node *ast, AST::FormalParameterList *formals, - AST::SourceElements *body); + AST::StatementList *body); +protected: void statement(AST::Statement *ast); void statement(AST::ExpressionNode *ast); void condition(AST::ExpressionNode *ast, const BytecodeGenerator::Label *iftrue, const BytecodeGenerator::Label *iffalse, bool trueBlockFollowsCondition); Reference expression(AST::ExpressionNode *ast); - Result sourceElement(AST::SourceElement *ast); void accept(AST::Node *node); - void functionBody(AST::FunctionBody *ast); void program(AST::Program *ast); - void sourceElements(AST::SourceElements *ast); void statementList(AST::StatementList *ast); - void variableDeclaration(AST::VariableDeclaration *ast); + void variableDeclaration(AST::PatternElement *ast); void variableDeclarationList(AST::VariableDeclarationList *ast); - Reference referenceForName(const QString &name, bool lhs); + Reference targetForPatternElement(AST::PatternElement *p); + void initializeAndDestructureBindingElement(AST::PatternElement *e, const Reference &baseRef = Reference(), bool isDefinition = false); + void destructurePropertyList(const Reference &object, AST::PatternPropertyList *bindingList, bool isDefinition = false); + void destructureElementList(const Reference &array, AST::PatternElementList *bindingList, bool isDefinition = false); + void destructurePattern(AST::Pattern *p, const Reference &rhs); - void loadClosure(int index); + Reference referenceForPropertyName(const Codegen::Reference &object, AST::PropertyName *name); // Hook provided to implement QML lookup semantics virtual Reference fallbackNameLookup(const QString &name); virtual void beginFunctionBodyHook() {} + void emitReturn(const Reference &expr); + // nodes bool visit(AST::ArgumentList *ast) override; bool visit(AST::CaseBlock *ast) override; @@ -531,16 +574,10 @@ protected: bool visit(AST::CaseClauses *ast) override; bool visit(AST::Catch *ast) override; bool visit(AST::DefaultClause *ast) override; - bool visit(AST::ElementList *ast) override; bool visit(AST::Elision *ast) override; bool visit(AST::Finally *ast) override; bool visit(AST::FormalParameterList *ast) override; - bool visit(AST::FunctionBody *ast) override; bool visit(AST::Program *ast) override; - bool visit(AST::PropertyNameAndValue *ast) override; - bool visit(AST::PropertyAssignmentList *ast) override; - bool visit(AST::PropertyGetterSetter *ast) override; - bool visit(AST::SourceElements *ast) override; bool visit(AST::StatementList *ast) override; bool visit(AST::UiArrayMemberList *ast) override; bool visit(AST::UiImport *ast) override; @@ -551,20 +588,27 @@ protected: bool visit(AST::UiParameterList *ast) override; bool visit(AST::UiProgram *ast) override; bool visit(AST::UiQualifiedId *ast) override; - bool visit(AST::UiQualifiedPragmaId *ast) override; - bool visit(AST::VariableDeclaration *ast) override; bool visit(AST::VariableDeclarationList *ast) override; + bool visit(AST::PatternElement *ast) override; + bool visit(AST::PatternElementList *ast) override; + bool visit(AST::PatternProperty *ast) override; + bool visit(AST::PatternPropertyList *ast) override; + + bool visit(AST::ExportDeclaration *ast) override; + // expressions bool visit(AST::Expression *ast) override; - bool visit(AST::ArrayLiteral *ast) override; + bool visit(AST::ArrayPattern *ast) override; bool visit(AST::ArrayMemberExpression *ast) override; bool visit(AST::BinaryExpression *ast) override; bool visit(AST::CallExpression *ast) override; bool visit(AST::ConditionalExpression *ast) override; bool visit(AST::DeleteExpression *ast) override; bool visit(AST::FalseLiteral *ast) override; + bool visit(AST::SuperLiteral *ast) override; bool visit(AST::FieldMemberExpression *ast) override; + bool visit(AST::TaggedTemplate *ast) override; bool visit(AST::FunctionExpression *ast) override; bool visit(AST::IdentifierExpression *ast) override; bool visit(AST::NestedExpression *ast) override; @@ -573,13 +617,14 @@ protected: bool visit(AST::NotExpression *ast) override; bool visit(AST::NullExpression *ast) override; bool visit(AST::NumericLiteral *ast) override; - bool visit(AST::ObjectLiteral *ast) override; + bool visit(AST::ObjectPattern *ast) override; bool visit(AST::PostDecrementExpression *ast) override; bool visit(AST::PostIncrementExpression *ast) override; bool visit(AST::PreDecrementExpression *ast) override; bool visit(AST::PreIncrementExpression *ast) override; bool visit(AST::RegExpLiteral *ast) override; bool visit(AST::StringLiteral *ast) override; + bool visit(AST::TemplateLiteral *ast) override; bool visit(AST::ThisExpression *ast) override; bool visit(AST::TildeExpression *ast) override; bool visit(AST::TrueLiteral *ast) override; @@ -588,10 +633,9 @@ protected: bool visit(AST::UnaryPlusExpression *ast) override; bool visit(AST::VoidExpression *ast) override; bool visit(AST::FunctionDeclaration *ast) override; - - // source elements - bool visit(AST::FunctionSourceElement *ast) override; - bool visit(AST::StatementSourceElement *ast) override; + bool visit(AST::YieldExpression *ast) override; + bool visit(AST::ClassExpression *ast) override; + bool visit(AST::ClassDeclaration *ast) override; // statements bool visit(AST::Block *ast) override; @@ -605,8 +649,6 @@ protected: bool visit(AST::ForStatement *ast) override; bool visit(AST::IfStatement *ast) override; bool visit(AST::LabelledStatement *ast) override; - bool visit(AST::LocalForEachStatement *ast) override; - bool visit(AST::LocalForStatement *ast) override; bool visit(AST::ReturnStatement *ast) override; bool visit(AST::SwitchStatement *ast) override; bool visit(AST::ThrowStatement *ast) override; @@ -635,18 +677,36 @@ public: Reference binopHelper(QSOperator::Op oper, Reference &left, Reference &right); Reference jumpBinop(QSOperator::Op oper, Reference &left, Reference &right); - struct Arguments { int argc; int argv; }; + struct Arguments { int argc; int argv; bool hasSpread; }; Arguments pushArgs(AST::ArgumentList *args); + void handleCall(Reference &base, Arguments calldata, int slotForFunction, int slotForThisObject); + + Arguments pushTemplateArgs(AST::TemplateLiteral *args); + int createTemplateArray(AST::TemplateLiteral *t); void setUseFastLookups(bool b) { useFastLookups = b; } void handleTryCatch(AST::TryStatement *ast); void handleTryFinally(AST::TryStatement *ast); + + Reference referenceForName(const QString &name, bool lhs, const QQmlJS::AST::SourceLocation &accessLocation = QQmlJS::AST::SourceLocation()); + QQmlRefPointer<QV4::CompiledData::CompilationUnit> generateCompilationUnit(bool generateUnitData = true); static QQmlRefPointer<QV4::CompiledData::CompilationUnit> createUnitForLoading(); Context *currentContext() const { return _context; } + BytecodeGenerator *generator() const { return bytecodeGenerator; } + + void loadClosure(int index); + + Module *module() const { return _module; } + + BytecodeGenerator::Label returnLabel() { + if (!_returnLabel) + _returnLabel = new BytecodeGenerator::Label(bytecodeGenerator->newLabel()); + return *_returnLabel; + } protected: friend class ScanFunctions; @@ -654,23 +714,56 @@ protected: friend struct ControlFlowCatch; friend struct ControlFlowFinally; Result _expr; - VolatileMemoryLocations _volataleMemoryLocations; + VolatileMemoryLocations _volatileMemoryLocations; Module *_module; int _returnAddress; Context *_context; + Context *_functionContext = nullptr; AST::LabelledStatement *_labelledStatement; QV4::Compiler::JSUnitGenerator *jsUnitGenerator; BytecodeGenerator *bytecodeGenerator = nullptr; + Moth::BytecodeGenerator::Label *_returnLabel = nullptr; bool _strictMode; bool useFastLookups = true; bool requiresReturnValue = false; + bool insideSwitch = false; + bool inFormalParameterList = false; + bool functionEndsWithReturn = false; + bool _tailCallsAreAllowed = true; + + ControlFlow *controlFlow = nullptr; bool _fileNameIsUrl; bool hasError; QList<QQmlJS::DiagnosticMessage> _errors; + class TailCallBlocker + { + public: + TailCallBlocker(Codegen *cg, bool onoff = false) + : _cg(cg) + , _saved(_cg->_tailCallsAreAllowed) + , _onoff(onoff) + { _cg->_tailCallsAreAllowed = onoff; } + + ~TailCallBlocker() + { _cg->_tailCallsAreAllowed = _saved; } + + void unblock() const + { _cg->_tailCallsAreAllowed = _saved; } + + void reblock() const + { _cg->_tailCallsAreAllowed = _onoff; } + + private: + Codegen *_cg; + bool _saved; + bool _onoff; + }; + private: VolatileMemoryLocations scanVolatileMemoryLocations(AST::Node *ast) const; + void handleConstruct(const Reference &base, AST::ArgumentList *args); }; } |