diff options
Diffstat (limited to 'src/script/qscriptcompiler.cpp')
-rw-r--r-- | src/script/qscriptcompiler.cpp | 2111 |
1 files changed, 0 insertions, 2111 deletions
diff --git a/src/script/qscriptcompiler.cpp b/src/script/qscriptcompiler.cpp deleted file mode 100644 index 157e466..0000000 --- a/src/script/qscriptcompiler.cpp +++ /dev/null @@ -1,2111 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtScript module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptcompiler_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptast_p.h" -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" - -#include <QtCore/QtDebug> - -QT_BEGIN_NAMESPACE - -namespace QScript { - -class Compare : protected AST::Visitor -{ -public: - bool operator()(AST::ExpressionNode *e1, AST::ExpressionNode *e2) - { - if (!e1 || !e2) - return (e1 == e2); - - if (e1->kind != e2->kind) - return false; - - m_e2 = e2; - m_equal = false; - e1->accept(this); - return m_equal; - } - -protected: - virtual bool visit(AST::ThisExpression *) - { - m_equal = true; - return false; - } - virtual bool visit(AST::NullExpression *) - { - m_equal = true; - return false; - } - virtual bool visit(AST::VoidExpression *) - { - m_equal = true; - return false; - } - virtual bool visit(AST::FalseLiteral *) - { - m_equal = true; - return false; - } - virtual bool visit(AST::TrueLiteral *) - { - m_equal = true; - return false; - } - virtual bool visit(AST::NumericLiteral *e1) - { - AST::NumericLiteral *e2 = static_cast<AST::NumericLiteral*>(m_e2); - m_equal = (e1->value == e2->value); - return false; - } - virtual bool visit(AST::RegExpLiteral *e1) - { - AST::RegExpLiteral *e2 = static_cast<AST::RegExpLiteral*>(m_e2); - m_equal = (e1->pattern == e2->pattern) - && (e1->flags == e2->flags); - return false; - } - virtual bool visit(AST::StringLiteral *e1) - { - AST::StringLiteral *e2 = static_cast<AST::StringLiteral*>(m_e2); - m_equal = (e1->value == e2->value); - return false; - } - virtual bool visit(AST::IdentifierExpression *e1) - { - AST::IdentifierExpression *e2 = static_cast<AST::IdentifierExpression*>(m_e2); - m_equal = (e1->name == e2->name); - return false; - } - virtual bool visit(AST::ArrayMemberExpression *e1) - { - AST::ArrayMemberExpression *e2 = static_cast<AST::ArrayMemberExpression*>(m_e2); - m_equal = operator()(e1->base, e2->base) - && operator()(e1->expression, e2->expression); - return false; - } - virtual bool visit(AST::FieldMemberExpression *e1) - { - AST::FieldMemberExpression *e2 = static_cast<AST::FieldMemberExpression*>(m_e2); - m_equal = (e1->name == e2->name) && operator()(e1->base, e2->base); - return false; - } - virtual bool visit(AST::BinaryExpression *e1) - { - AST::BinaryExpression *e2 = static_cast<AST::BinaryExpression*>(m_e2); - m_equal = (e1->op == e2->op) && operator()(e1->left, e2->left) - && operator()(e1->right, e2->right); - return false; - } - virtual bool visit(AST::ConditionalExpression *e1) - { - AST::ConditionalExpression *e2 = static_cast<AST::ConditionalExpression*>(m_e2); - m_equal = operator()(e1->expression, e2->expression) - && operator()(e1->ok, e2->ok) - && operator()(e1->ko, e2->ko); - return false; - } - virtual bool visit(AST::TypeOfExpression *e1) - { - AST::TypeOfExpression *e2 = static_cast<AST::TypeOfExpression*>(m_e2); - m_equal = operator()(e1->expression, e2->expression); - return false; - } - virtual bool visit(AST::UnaryPlusExpression *e1) - { - AST::UnaryPlusExpression *e2 = static_cast<AST::UnaryPlusExpression*>(m_e2); - m_equal = operator()(e1->expression, e2->expression); - return false; - } - virtual bool visit(AST::UnaryMinusExpression *e1) - { - AST::UnaryMinusExpression *e2 = static_cast<AST::UnaryMinusExpression*>(m_e2); - m_equal = operator()(e1->expression, e2->expression); - return false; - } - virtual bool visit(AST::TildeExpression *e1) - { - AST::TildeExpression *e2 = static_cast<AST::TildeExpression*>(m_e2); - m_equal = operator()(e1->expression, e2->expression); - return false; - } - virtual bool visit(AST::NotExpression *e1) - { - AST::NotExpression *e2 = static_cast<AST::NotExpression*>(m_e2); - m_equal = operator()(e1->expression, e2->expression); - return false; - } - virtual bool visit(AST::Expression *) - { return false; } - virtual bool visit(AST::ArrayLiteral *) - { return false; } - virtual bool visit(AST::ObjectLiteral *) - { return false; } - virtual bool visit(AST::CallExpression *) - { return false; } - virtual bool visit(AST::DeleteExpression *) - { return false; } - virtual bool visit(AST::FunctionExpression *) - { return false; } - virtual bool visit(AST::NewExpression *) - { return false; } - virtual bool visit(AST::NewMemberExpression *) - { return false; } - virtual bool visit(AST::PostDecrementExpression *) - { return false; } - virtual bool visit(AST::PostIncrementExpression *) - { return false; } - virtual bool visit(AST::PreDecrementExpression *) - { return false; } - virtual bool visit(AST::PreIncrementExpression *) - { return false; } - -private: - AST::ExpressionNode *m_e2; - bool m_equal; -}; - -class FetchName: protected AST::Visitor -{ -public: - inline FetchName(QScriptEnginePrivate *e): - eng(e), name(0) {} - - QScriptNameIdImpl *operator() (AST::PropertyName *node) - { - name = 0; - node->accept(this); - return name; - } - -protected: - virtual bool visit(AST::IdentifierPropertyName *node) - { - name = node->id; - return false; - } - - virtual bool visit(AST::StringLiteralPropertyName *node) - { - name = node->id; - return false; - } - - virtual bool visit(AST::NumericLiteralPropertyName *node) - { - name = eng->nameId(QString::number(node->id), /*persistent=*/false); // ### don't use QString::number - name->persistent = true; // ### remove - return false; - } - -private: - QScriptEnginePrivate *eng; - QScriptNameIdImpl *name; -}; - -class EmptySourceElements: protected AST::Visitor -{ -public: - EmptySourceElements(QScriptEngine *d): - driver(d), empty(false) {} - - inline bool operator () (AST::Node *) - { - empty = false; - return empty; - } - -private: - QScriptEngine *driver; - bool empty; -}; - -class DeclareLocals: protected AST::Visitor -{ -public: - DeclareLocals(Compiler *c): - compiler(c), - eng(c->engine()) - { - } - - void operator () (AST::Node *node) - { - if (node) - node->accept(this); - } - -protected: - virtual bool visit(AST::FunctionDeclaration *node) - { - compiler->iDeclareLocal(node->name, /*readOnly=*/false); - return false; - } - - virtual bool visit(AST::FunctionExpression *) - { return false; } - - virtual bool visit(AST::VariableDeclaration *node) - { - compiler->iDeclareLocal(node->name, node->readOnly); - return false; - } - -private: - Compiler *compiler; - QScriptEnginePrivate *eng; -}; - -Compiler::Compiler(QScriptEnginePrivate *eng): - m_eng(eng), - m_generateReferences(0), m_iterationStatement(0), - m_switchStatement(0), m_withStatement(0), - m_generateLeaveWithOnBreak(0), m_generateFastArgumentLookup(0), - m_parseStatements(0), m_pad(0), - m_topLevelCompiler(false), - m_activeLoop(0) -{ -} - -Compiler::~Compiler() -{ -} - -bool Compiler::topLevelCompiler() const -{ - return m_topLevelCompiler; -} - -void Compiler::setTopLevelCompiler(bool b) -{ - m_topLevelCompiler = b; -} - - CompilationUnit Compiler::compile(AST::Node *node, const QList<QScriptNameIdImpl *> &formals) -{ - m_formals = formals; - m_generateReferences = 0; - m_iterationStatement = 0; - m_switchStatement = 0; - m_withStatement = 0; - m_generateLeaveWithOnBreak = 0; - m_generateFastArgumentLookup = 0; - m_parseStatements = 0; - m_pad = 0; - m_instructions.clear(); - m_exceptionHandlers.clear(); - m_generateFastArgumentLookup = false; // ### !formals.isEmpty(); // ### disabled for now.. it's buggy :( - - m_compilationUnit = CompilationUnit(); - - if (node) - node->accept(this); - - // add a terminator - if (topLevelCompiler()) { - iHalt(); - } else if (m_instructions.isEmpty() || m_instructions.last().op != QScriptInstruction::OP_Ret) { - iLoadUndefined(); - iRet(); - } - - m_compilationUnit.setInstructions(m_instructions); - m_compilationUnit.setExceptionHandlers(m_exceptionHandlers); - return m_compilationUnit; -} - -bool Compiler::preVisit(AST::Node *) -{ - return m_compilationUnit.isValid(); -} - -bool Compiler::visit(AST::SourceElements *node) -{ - DeclareLocals declareLocals(this); - declareLocals(node); - - bool was = changeParseStatements(false); - - for (AST::SourceElements *it = node; it != 0; it = it->next) - it->element->accept(this); - - changeParseStatements(true); - - for (AST::SourceElements *it = node; it != 0; it = it->next) - it->element->accept(this); - - changeParseStatements(was); - - return false; -} - -bool Compiler::visit(AST::StatementList *) -{ - return true; -} - -bool Compiler::visit(AST::FunctionSourceElement *) -{ - return m_parseStatements == 0; -} - -bool Compiler::visit(AST::StatementSourceElement *) -{ - return m_parseStatements; -} - -bool Compiler::visit(AST::ThisExpression *) -{ - iLoadThis(); - return false; -} - -bool Compiler::visit(AST::NullExpression *) -{ - iLoadNull(); - return false; -} - -bool Compiler::visit(AST::RegExpLiteral *node) -{ - Q_ASSERT(node->pattern != 0); - - if (node->flags) - iNewRegExp(node->pattern, node->flags); - else - iNewRegExp(node->pattern); - - return false; -} - -bool Compiler::visit(AST::NumericLiteral *node) -{ - iLoadNumber(node->value); - return false; -} - -bool Compiler::visit(AST::StringLiteral *node) -{ - iNewString(node->value); - - return false; -} - -bool Compiler::visit(AST::ObjectLiteral *node) -{ - iNewObject(); - - FetchName fetchName(m_eng); - bool was = generateReferences(false); - for (AST::PropertyNameAndValueList *it = node->properties; it != 0; it = it->next) { - iLine(it->value); - iDuplicate(); - - QScriptNameIdImpl *name = fetchName(it->name); - Q_ASSERT(name != 0); - iLoadString(name); - iMakeReference(); - - it->value->accept(this); - iPutField(); - } - generateReferences(was); - - return false; -} - -bool Compiler::visit(AST::IdentifierExpression *node) -{ - Q_ASSERT(node->name != 0); - - if (node->name == m_eng->idTable()->id_arguments) - iLazyArguments(); - if (m_generateReferences) - iResolve(node->name); - else - iFetch(node->name); - - return false; -} - -bool Compiler::visit(AST::FunctionDeclaration *node) -{ - iLoadActivation(); - iLoadString(node->name); - iMakeReference(); - iNewClosure(node); - iPutField(); - return false; -} - -bool Compiler::visit(AST::FunctionExpression *node) -{ - iNewClosure(node); - if (node->name) { - iDuplicate(); - iLoadActivation(); - iSwap(); - iLoadString(node->name); - iSwap(); - iMakeReference(); - iSwap(); - iPutField(); - } - return false; -} - -bool Compiler::visit(AST::CallExpression *node) -{ - bool was = generateReferences(true); - node->base->accept(this); - generateReferences(false); - - int argc = 0; - for (AST::ArgumentList *it = node->arguments; it != 0; it = it->next) { - it->expression->accept(this); - ++argc; - } - - generateReferences(was); - - iCall(argc); - return false; -} - -bool Compiler::visit(AST::NewExpression *node) -{ - bool was = generateReferences(true); - node->expression->accept(this); - generateReferences(was); - iNew(0); - return false; -} - -bool Compiler::visit(AST::NewMemberExpression *node) -{ - bool was = generateReferences(true); - node->base->accept(this); - generateReferences(false); - - int argc = 0; - for (AST::ArgumentList *it = node->arguments; it != 0; it = it->next) { - it->expression->accept(this); - ++argc; - } - - generateReferences(was); - - iNew(argc); - return false; -} - -bool Compiler::visit(AST::FieldMemberExpression *node) -{ - bool was = generateReferences(false); - node->base->accept(this); - generateReferences(was); - - iLoadString(node->name); - - if (! was) - iFetchField(); - else - iMakeReference(); - - return false; -} - -bool Compiler::visit(AST::ArrayMemberExpression *node) -{ - bool was = generateReferences(false); - node->base->accept(this); - node->expression->accept(this); - generateReferences(was); - - if (! was) - iFetchField(); - else - iMakeReference(); - - return false; -} - -bool Compiler::visit(AST::PostIncrementExpression *node) -{ - bool was = generateReferences(true); - node->base->accept(this); - generateReferences(was); - iPostIncr(); - - return false; -} - -bool Compiler::visit(AST::PostDecrementExpression *node) -{ - bool was = generateReferences(true); - node->base->accept(this); - generateReferences(was); - iPostDecr(); - - return false; -} - -bool Compiler::visit(AST::PreIncrementExpression *node) -{ - bool was = generateReferences(true); - node->expression->accept(this); - generateReferences(was); - iIncr(); - return false; -} - -bool Compiler::visit(AST::PreDecrementExpression *node) -{ - bool was = generateReferences(true); - node->expression->accept(this); - generateReferences(was); - iDecr(); - return false; -} - -void Compiler::endVisit(AST::NotExpression *) -{ - iNot(); -} - -void Compiler::endVisit(AST::TildeExpression *) -{ - iBitNot(); -} - -bool Compiler::visit(AST::ThrowStatement *node) -{ - iLine(node); - return true; -} - -bool Compiler::visit(AST::TryStatement *node) -{ - int start = nextInstructionOffset(); - if (node->statement) - node->statement->accept(this); - int end = nextInstructionOffset(); - if (node->catchExpression) { - iBranch(0); // skip the catch if no exception - ExceptionHandlerDescriptor ehd(start, end, nextInstructionOffset()); - m_exceptionHandlers.append(ehd); - iBeginCatch(node->catchExpression->name); - node->catchExpression->statement->accept(this); - iEndCatch(); - patchInstruction(end, nextInstructionOffset() - end); - } - if (node->finallyExpression) { - if (!node->catchExpression) { - ExceptionHandlerDescriptor ehd(start, end, nextInstructionOffset()); - m_exceptionHandlers.prepend(ehd); - } - node->finallyExpression->statement->accept(this); - } - return false; -} - -void Compiler::endVisit(AST::ThrowStatement *node) -{ - if (! node->expression) - iLoadUndefined(); - - iThrow(); -} - -void Compiler::endVisit(AST::VoidExpression *) -{ - iPop(); - iLoadUndefined(); -} - -bool Compiler::visit(AST::TypeOfExpression *node) -{ - bool was = generateReferences(true); - node->expression->accept(this); - generateReferences(was); - iTypeOf(); - return false; -} - -bool Compiler::visit(AST::DeleteExpression *node) -{ - bool was = generateReferences(true); - node->expression->accept(this); - generateReferences(was); - iDelete(); - return false; -} - -bool Compiler::visit(AST::ReturnStatement *node) -{ - if (topLevelCompiler()) { - m_compilationUnit.setError(QString::fromUtf8("return outside function body"), - node->startLine); - return false; - } - iLine(node); - return true; -} - -void Compiler::endVisit(AST::ReturnStatement *node) -{ - if (! node->expression) - iLoadUndefined(); - - iRet(); -} - -bool Compiler::visit(AST::VariableStatement *node) -{ - AST::VariableDeclarationList *lst = node->declarations; - while (lst) { - if (lst->declaration->expression) { - iLine(node); - break; - } - lst = lst->next; - } - return true; -} - -bool Compiler::visit(AST::VariableDeclaration *node) -{ - if (node->expression != 0) { - iResolve(node->name); - node->expression->accept(this); - iAssign(); - iPop(); - } - - return false; -} - -bool Compiler::visit(AST::ConditionalExpression *node) -{ - node->expression->accept(this); - - int cond = nextInstructionOffset(); - iBranchFalse(0); - - node->ok->accept(this); - - if (! node->ko) { - patchInstruction(cond, nextInstructionOffset() - cond); - } else { - int terminator = nextInstructionOffset(); - iBranch(0); - node->ko->accept(this); - - patchInstruction(cond, terminator + 1 - cond); - patchInstruction(terminator, nextInstructionOffset() - terminator); - } - - return false; -} - -bool Compiler::visit(AST::IfStatement *node) -{ - iLine(node); - node->expression->accept(this); - - int cond = nextInstructionOffset(); - iBranchFalse(0); - - node->ok->accept(this); - - if (! node->ko) { - patchInstruction(cond, nextInstructionOffset() - cond); - } else { - int terminator = nextInstructionOffset(); - iBranch(0); - node->ko->accept(this); - - patchInstruction(cond, terminator + 1 - cond); - patchInstruction(terminator, nextInstructionOffset() - terminator); - } - if (!m_instructions.isEmpty() && m_instructions.last().op == QScriptInstruction::OP_Ret) - iNop(); - - return false; -} - -bool Compiler::visit(AST::Block *node) -{ - if (node->statements && m_loops.contains(node)) { - Loop &loop = m_loops[node]; - - node->statements->accept(this); - - loop.breakLabel.offset = nextInstructionOffset(); - - foreach (int index, loop.breakLabel.uses) { - patchInstruction(index, loop.breakLabel.offset - index); - } - - return false; - } - - return true; -} - -bool Compiler::visit(AST::WhileStatement *node) -{ - Loop *previousLoop = changeActiveLoop(&m_loops[node]); - m_activeLoop->continueLabel.offset = nextInstructionOffset(); - - iLine(node); - int again = nextInstructionOffset(); - node->expression->accept(this); - - int cond = nextInstructionOffset(); - iBranchFalse(0); - - bool was = iterationStatement(true); - bool was2 = generateLeaveOnBreak(false); - node->statement->accept(this); - generateLeaveOnBreak(was2); - iterationStatement(was); - - iBranch(again - nextInstructionOffset()); - patchInstruction(cond, nextInstructionOffset() - cond); - - m_activeLoop->breakLabel.offset = nextInstructionOffset(); - - foreach (int index, m_activeLoop->breakLabel.uses) { - patchInstruction(index, m_activeLoop->breakLabel.offset - index); - } - - foreach (int index, m_activeLoop->continueLabel.uses) { - patchInstruction(index, m_activeLoop->continueLabel.offset - index); - } - - changeActiveLoop(previousLoop); - m_loops.remove(node); - - return false; -} - -bool Compiler::visit(AST::DoWhileStatement *node) -{ - Loop *previousLoop = changeActiveLoop(&m_loops[node]); - int again = nextInstructionOffset(); - iLine(node); - bool was = iterationStatement(true); - node->statement->accept(this); - iterationStatement(was); - - m_activeLoop->continueLabel.offset = nextInstructionOffset(); - - node->expression->accept(this); - - iBranchTrue(again - nextInstructionOffset()); - m_activeLoop->breakLabel.offset = nextInstructionOffset(); - - foreach (int index, m_activeLoop->breakLabel.uses) { - patchInstruction(index, m_activeLoop->breakLabel.offset - index); - } - - foreach (int index, m_activeLoop->continueLabel.uses) { - patchInstruction(index, m_activeLoop->continueLabel.offset - index); - } - - changeActiveLoop(previousLoop); - m_loops.remove(node); - - return false; -} - -bool Compiler::visit(AST::ForEachStatement *node) -{ - Loop *previousLoop = changeActiveLoop(&m_loops[node]); - - iLine(node); - node->expression->accept(this); - iNewEnumeration(); - iDuplicate(); - iToFirstElement(); - - int again = nextInstructionOffset(); - m_activeLoop->continueLabel.offset = again; - iDuplicate(); - iHasNextElement(); - int cond = nextInstructionOffset(); - iBranchFalse(0); - bool was = generateReferences(true); - node->initialiser->accept(this); - generateReferences(was); - iNextElement(); - iAssign(); - iPop(); - was = iterationStatement(true); - node->statement->accept(this); - iterationStatement(was); - iBranch(again - nextInstructionOffset()); - patchInstruction(cond, nextInstructionOffset() - cond); - - m_activeLoop->breakLabel.offset = nextInstructionOffset(); - iPop(); // pop the Enumeration - - foreach (int index, m_activeLoop->breakLabel.uses) { - patchInstruction(index, m_activeLoop->breakLabel.offset - index); - } - - foreach (int index, m_activeLoop->continueLabel.uses) { - patchInstruction(index, m_activeLoop->continueLabel.offset - index); - } - - changeActiveLoop(previousLoop); - m_loops.remove(node); - - return false; -} - -bool Compiler::visit(AST::LocalForEachStatement *node) -{ - Loop *previousLoop = changeActiveLoop(&m_loops[node]); - - iLine(node); - node->declaration->accept(this); - node->expression->accept(this); - iNewEnumeration(); - iDuplicate(); - iToFirstElement(); - - int again = nextInstructionOffset(); - m_activeLoop->continueLabel.offset = again; - iDuplicate(); - iHasNextElement(); - int cond = nextInstructionOffset(); - iBranchFalse(0); - iResolve(node->declaration->name); - iNextElement(); - iAssign(); - iPop(); - bool was = iterationStatement(true); - node->statement->accept(this); - iterationStatement(was); - iBranch(again - nextInstructionOffset()); - patchInstruction(cond, nextInstructionOffset() - cond); - - m_activeLoop->breakLabel.offset = nextInstructionOffset(); - iPop(); // pop the Enumeration - - foreach (int index, m_activeLoop->breakLabel.uses) { - patchInstruction(index, m_activeLoop->breakLabel.offset - index); - } - - foreach (int index, m_activeLoop->continueLabel.uses) { - patchInstruction(index, m_activeLoop->continueLabel.offset - index); - } - - changeActiveLoop(previousLoop); - m_loops.remove(node); - - return false; -} - -void Compiler::visitForInternal(AST::Statement *node, AST::ExpressionNode *condition, AST::Statement *statement, AST::ExpressionNode *expression) -{ - Q_ASSERT(statement != 0); - - int again = nextInstructionOffset(); - if (condition != 0) { -// iLine(condition); - condition->accept(this); - } else { -// iLine(node); - iLoadNumber(1); - } - - int cond = nextInstructionOffset(); - iBranchFalse(0); - - Loop *previousLoop = changeActiveLoop(&m_loops[node]); - - bool was = iterationStatement(true); - statement->accept(this); - iterationStatement(was); - - m_activeLoop->continueLabel.offset = nextInstructionOffset(); - - if (expression != 0) { - expression->accept(this); - iPop(); - } - - iBranch(again - nextInstructionOffset()); - patchInstruction(cond, nextInstructionOffset() - cond); - - m_activeLoop->breakLabel.offset = nextInstructionOffset(); - - foreach (int index, m_activeLoop->breakLabel.uses) { - patchInstruction(index, m_activeLoop->breakLabel.offset - index); - } - - foreach (int index, m_activeLoop->continueLabel.uses) { - patchInstruction(index, m_activeLoop->continueLabel.offset - index); - } - - changeActiveLoop(previousLoop); - m_loops.remove(node); -} - -bool Compiler::visit(AST::ForStatement *node) -{ - iLine(node); - - if (node->initialiser != 0) { - node->initialiser->accept(this); - iPop(); - } - - visitForInternal(node, node->condition, node->statement, node->expression); - return false; -} - -bool Compiler::visit(AST::LocalForStatement *node) -{ - iLine(node); - - if (node->declarations) - node->declarations->accept(this); - - visitForInternal(node, node->condition, node->statement, node->expression); - return false; -} - -bool Compiler::isAssignmentOperator(int op) const -{ - switch (op) { - - case QSOperator::Assign: - case QSOperator::InplaceAnd: - case QSOperator::InplaceSub: - case QSOperator::InplaceDiv: - case QSOperator::InplaceAdd: - case QSOperator::InplaceLeftShift: - case QSOperator::InplaceMod: - case QSOperator::InplaceMul: - case QSOperator::InplaceOr: - case QSOperator::InplaceRightShift: - case QSOperator::InplaceURightShift: - case QSOperator::InplaceXor: - return true; - - default: - break; - - } - - return false; -} - -int Compiler::inplaceAssignmentOperator(int op) const -{ - switch (op) { - case QSOperator::BitAnd: - return QSOperator::InplaceAnd; - case QSOperator::Sub: - return QSOperator::InplaceSub; - case QSOperator::Div: - return QSOperator::InplaceDiv; - case QSOperator::Add: - return QSOperator::InplaceAdd; - case QSOperator::LShift: - return QSOperator::InplaceLeftShift; - case QSOperator::Mod: - return QSOperator::InplaceMod; - case QSOperator::Mul: - return QSOperator::InplaceMul; - case QSOperator::BitOr: - return QSOperator::InplaceOr; - case QSOperator::RShift: - return QSOperator::InplaceRightShift; - case QSOperator::URShift: - return QSOperator::InplaceURightShift; - case QSOperator::BitXor: - return QSOperator::InplaceXor; - - default: - break; - - } - - return(-1); -} - -bool Compiler::visit(AST::Expression *node) -{ - node->left->accept(this); - iPop(); // ### or iSync? - node->right->accept(this); - return false; -} - -bool Compiler::visit(AST::BinaryExpression *node) -{ - if (isAssignmentOperator(node->op)) { - bool was = generateReferences(true); - node->left->accept(this); - generateReferences(was); - } else { - node->left->accept(this); - } - - int address = 0; - if (node->op == QSOperator::Or || node->op == QSOperator::And) { - iDuplicate(); - address = nextInstructionOffset(); - if (node->op == QSOperator::Or) - iBranchTrue(0); - else - iBranchFalse(0); - iPop(); - } - - int op = node->op; - Compare compare; - if ((op == QSOperator::Assign) && node->right->binaryExpressionCast() - && (inplaceAssignmentOperator(node->right->binaryExpressionCast()->op) != -1) - && compare(node->left, node->right->binaryExpressionCast()->left)) { - // node->left is equivalent to node->right->left, so we generate - // x op= y rather than x = x op y - op = inplaceAssignmentOperator(node->right->binaryExpressionCast()->op); - node->right->binaryExpressionCast()->right->accept(this); - } else { - node->right->accept(this); - } - - switch (op) { - - case QSOperator::Assign: - iAssign(); - break; - - case QSOperator::InplaceAnd: - iInplaceAnd(); - break; - - case QSOperator::InplaceSub: - iInplaceSub(); - break; - - case QSOperator::InplaceDiv: - iInplaceDiv(); - break; - - case QSOperator::InplaceAdd: - iInplaceAdd(); - break; - - case QSOperator::InplaceLeftShift: - iInplaceLeftShift(); - break; - - case QSOperator::InplaceMod: - iInplaceMod(); - break; - - case QSOperator::InplaceMul: - iInplaceMul(); - break; - - case QSOperator::InplaceOr: - iInplaceOr(); - break; - - case QSOperator::InplaceRightShift: - iInplaceRightShift(); - break; - - case QSOperator::InplaceURightShift: - iInplaceURightShift(); - break; - - case QSOperator::InplaceXor: - iInplaceXor(); - break; - - case QSOperator::BitAnd: - iBitAnd(); - break; - - case QSOperator::BitOr: - iBitOr(); - break; - - case QSOperator::BitXor: - iBitXor(); - break; - - case QSOperator::LShift: - iLeftShift(); - break; - - case QSOperator::Mod: - iMod(); - break; - - case QSOperator::RShift: - iRightShift(); - break; - - case QSOperator::URShift: - iURightShift(); - break; - - case QSOperator::InstanceOf: - iInstanceOf(); - break; - - case QSOperator::Add: - iAdd(); - break; - - case QSOperator::And: - patchInstruction(address, nextInstructionOffset() - address); - break; - - case QSOperator::Div: - iDiv(); - break; - - case QSOperator::Equal: - iEqual(); - break; - - case QSOperator::Ge: - iGreatOrEqual(); - break; - - case QSOperator::Gt: - iGreatThan(); - break; - - case QSOperator::Le: - iLessOrEqual(); - break; - - case QSOperator::Lt: - iLessThan(); - break; - - case QSOperator::Mul: - iMul(); - break; - - case QSOperator::NotEqual: - iNotEqual(); - break; - - case QSOperator::Or: - patchInstruction(address, nextInstructionOffset() - address); - break; - - case QSOperator::Sub: - iSub(); - break; - - case QSOperator::StrictEqual: - iStrictEqual(); - break; - - case QSOperator::StrictNotEqual: - iStrictNotEqual(); - break; - - case QSOperator::In: - iIn(); - break; - } - - return false; -} - -bool Compiler::visit(AST::TrueLiteral *) -{ - iLoadTrue(); - return false; -} - -bool Compiler::visit(AST::FalseLiteral *) -{ - iLoadFalse(); - return false; -} - -bool Compiler::visit(AST::SwitchStatement *node) -{ - iLine(node); - Loop *previousLoop = changeActiveLoop(&m_loops[node]); - - node->expression->accept(this); - - bool was = switchStatement(true); - - AST::CaseClauses *clauses; - int skipIndex = -1; - int fallthroughIndex = -1; - // ### make a function for this - for (clauses = node->block->clauses; clauses != 0; clauses = clauses->next) { - AST::CaseClause *clause = clauses->clause; - if (skipIndex != -1) - patchInstruction(skipIndex, nextInstructionOffset() - skipIndex); - - iDuplicate(); // expression - clause->expression->accept(this); - iStrictEqual(); - skipIndex = nextInstructionOffset(); - iBranchFalse(0); // next case - - if (fallthroughIndex != -1) // previous case falls through to here - patchInstruction(fallthroughIndex, nextInstructionOffset() - fallthroughIndex); - - int breaksBefore = m_activeLoop->breakLabel.uses.count(); - if (clause->statements) - clause->statements->accept(this); - int breaksAfter = m_activeLoop->breakLabel.uses.count(); - if (breaksAfter == breaksBefore) { // fallthrough - fallthroughIndex = nextInstructionOffset(); - iBranch(0); - } else { // no fallthrough (break) - fallthroughIndex = -1; - } - } - - if (fallthroughIndex != -1) { - patchInstruction(fallthroughIndex, nextInstructionOffset() - fallthroughIndex); - fallthroughIndex = -1; - } - - int defaultIndex = -1; - if (node->block->defaultClause) { - int skipDefaultIndex = -1; - if (!node->block->clauses && node->block->moreClauses) { - skipDefaultIndex = nextInstructionOffset(); - iBranch(0); - } - defaultIndex = nextInstructionOffset(); - int breaksBefore = m_activeLoop->breakLabel.uses.count(); - if (node->block->defaultClause->statements) - node->block->defaultClause->statements->accept(this); - int breaksAfter = m_activeLoop->breakLabel.uses.count(); - if (breaksAfter == breaksBefore) { // fallthrough - fallthroughIndex = nextInstructionOffset(); - iBranch(0); - } else { // no fallthrough (break) - fallthroughIndex = -1; - } - if (skipDefaultIndex != -1) - patchInstruction(skipDefaultIndex, nextInstructionOffset() - skipDefaultIndex); - } - - for (clauses = node->block->moreClauses; clauses != 0; clauses = clauses->next) { - AST::CaseClause *clause = clauses->clause; - if (skipIndex != -1) - patchInstruction(skipIndex, nextInstructionOffset() - skipIndex); - - iDuplicate(); // expression - clause->expression->accept(this); - iStrictEqual(); - skipIndex = nextInstructionOffset(); - iBranchFalse(0); // next case - - if (fallthroughIndex != -1) // previous case falls through to here - patchInstruction(fallthroughIndex, nextInstructionOffset() - fallthroughIndex); - - int breaksBefore = m_activeLoop->breakLabel.uses.count(); - if (clause->statements) - clause->statements->accept(this); - int breaksAfter = m_activeLoop->breakLabel.uses.count(); - if (breaksAfter == breaksBefore) { // fallthrough - fallthroughIndex = nextInstructionOffset(); - iBranch(0); - } else { // no fallthrough (break) - fallthroughIndex = -1; - } - } - - if (skipIndex != -1) { - patchInstruction(skipIndex, nextInstructionOffset() - skipIndex); - if (defaultIndex != -1) - iBranch(defaultIndex - nextInstructionOffset()); // goto default - } - - if (fallthroughIndex != -1) - patchInstruction(fallthroughIndex, nextInstructionOffset() - fallthroughIndex); - - // backpatch the breaks - int term = nextInstructionOffset(); - foreach (int index, m_activeLoop->breakLabel.uses) { - patchInstruction(index, term - index); - } - - iPop(); // expression - - if (previousLoop && !m_activeLoop->continueLabel.uses.isEmpty()) { - // join the continues and add to outer loop - iBranch(3); - foreach (int index, m_activeLoop->continueLabel.uses) { - patchInstruction(index, nextInstructionOffset() - index); - } - iPop(); - iBranch(0); - previousLoop->continueLabel.uses.append(nextInstructionOffset() - 1); - } - - switchStatement(was); - changeActiveLoop(previousLoop); - m_loops.remove(node); - return false; -} - -bool Compiler::visit(AST::LabelledStatement *node) -{ - Loop *loop = findLoop(node->label); - if (loop != 0) { - QString str = m_eng->toString(node->label); - m_compilationUnit.setError(QString::fromUtf8("duplicate label `%1'").arg(str), - node->startLine); - return false; - } - - loop = &m_loops[node->statement]; - loop->name = node->label; - node->statement->accept(this); - if (m_loops.contains(node->statement)) { - loop->breakLabel.offset = nextInstructionOffset(); - foreach (int index, loop->breakLabel.uses) { - patchInstruction(index, loop->breakLabel.offset - index); - } - m_loops.remove(node->statement); - } - return false; -} - -bool Compiler::visit(AST::ExpressionStatement *node) -{ - if (node->expression) - iLine(node->expression); - return true; -} - -void Compiler::endVisit(AST::ExpressionStatement *) -{ - if (topLevelCompiler()) - iSync(); - else - iPop(); -} - -void Compiler::endVisit(AST::UnaryPlusExpression *) -{ - iUnaryPlus(); -} - -void Compiler::endVisit(AST::UnaryMinusExpression *) -{ - iUnaryMinus(); -} - -bool Compiler::visit(AST::ContinueStatement *node) -{ - iLine(node); - return true; -} - -void Compiler::endVisit(AST::ContinueStatement *node) -{ - int offset = nextInstructionOffset(); - iBranch(0); - - Loop *loop = findLoop(node->label); - if (!loop || !m_iterationStatement) { - m_compilationUnit.setError(QString::fromUtf8("label not found"), - node->startLine); - return; - } - - loop->continueLabel.uses.append(offset); -} - -bool Compiler::visit(AST::BreakStatement *node) -{ - iLine(node); - return true; -} - -void Compiler::endVisit(AST::BreakStatement *node) -{ - Loop *loop = findLoop(node->label); - if (! loop) { - m_compilationUnit.setError(QString::fromUtf8("label not found"), - node->startLine); - return; - } - - if (m_generateLeaveWithOnBreak) - iLeaveWith(); - int offset = nextInstructionOffset(); - iBranch(0); - loop->breakLabel.uses.append(offset); -} - -void Compiler::endVisit(AST::EmptyStatement *node) -{ - iLine(node); -} - -bool Compiler::visit(AST::DebuggerStatement *node) -{ - iLine(node); - iDebugger(); - return false; -} - -void Compiler::patchInstruction(int index, int offset) -{ - QScriptInstruction &i = m_instructions[index]; - - switch (i.op) { - case QScriptInstruction::OP_Branch: - case QScriptInstruction::OP_BranchFalse: - case QScriptInstruction::OP_BranchTrue: - m_eng->newInteger(&i.operand[0], offset); - break; - - default: - Q_ASSERT_X(0, "Compiler::patchInstruction()", "expected a branch instruction"); - break; - } -} - -bool Compiler::visit(AST::WithStatement *node) -{ - iLine(node); - node->expression->accept(this); - iEnterWith(); - bool was = withStatement(true); - bool was2 = generateLeaveOnBreak(true); - node->statement->accept(this); - generateLeaveOnBreak(was2); - withStatement(was); - iLeaveWith(); - return false; -} - -bool Compiler::visit(AST::ArrayLiteral *node) -{ - iNewArray(); - - int length = 0; - - for (AST::ElementList *it = node->elements; it != 0; it = it->next) { - for (AST::Elision *eit = it->elision; eit != 0; eit = eit->next) { - iDuplicate(); - iLoadNumber(length); - iMakeReference(); - iLoadUndefined(); - iAssign(); - iPop(); - ++length; - } - - if (it->expression) { - iDuplicate(); - iLoadNumber(length); - iMakeReference(); - it->expression->accept(this); - iAssign(); - iPop(); - ++length; - } - } - - for (AST::Elision *eit = node->elision; eit != 0; eit = eit->next) { - iDuplicate(); - iLoadNumber(length); - iMakeReference(); - iLoadUndefined(); - iAssign(); - iPop(); - ++length; - } - - return false; -} - -void Compiler::iLoadUndefined() -{ - pushInstruction(QScriptInstruction::OP_LoadUndefined); -} - -void Compiler::iLoadThis() -{ - pushInstruction(QScriptInstruction::OP_LoadThis); -} - -void Compiler::iLoadActivation() -{ - pushInstruction(QScriptInstruction::OP_LoadActivation); -} - -void Compiler::iLoadNull() -{ - pushInstruction(QScriptInstruction::OP_LoadNull); -} - -void Compiler::iLoadNumber(double number) -{ - QScriptValueImpl arg0(number); - pushInstruction(QScriptInstruction::OP_LoadNumber, arg0); -} - -void Compiler::iLoadString(QScriptNameIdImpl *id) -{ - QScriptValueImpl arg0; - id->persistent = true; - m_eng->newNameId(&arg0, id); - pushInstruction(QScriptInstruction::OP_LoadString, arg0); -} - -void Compiler::iDuplicate() -{ - pushInstruction(QScriptInstruction::OP_Duplicate); -} - -void Compiler::iSwap() -{ - pushInstruction(QScriptInstruction::OP_Swap); -} - -void Compiler::iResolve(QScriptNameIdImpl *id) -{ - QScriptValueImpl arg0; - id->persistent = true; - m_eng->newNameId(&arg0, id); - pushInstruction(QScriptInstruction::OP_Resolve, arg0); -} - -void Compiler::iPutField() -{ - pushInstruction(QScriptInstruction::OP_PutField); -} - -void Compiler::iCall(int argc) -{ - QScriptValueImpl arg0; - m_eng->newInteger(&arg0, argc); - pushInstruction(QScriptInstruction::OP_Call, arg0); -} - -void Compiler::iNew(int argc) -{ - QScriptValueImpl arg0; - m_eng->newInteger(&arg0, argc); - pushInstruction(QScriptInstruction::OP_New, arg0); -} - -void Compiler::iFetchField() -{ - pushInstruction(QScriptInstruction::OP_FetchField); -} - -void Compiler::iLazyArguments() -{ - pushInstruction(QScriptInstruction::OP_LazyArguments); -} - -void Compiler::iRet() -{ - pushInstruction(QScriptInstruction::OP_Ret); -} - -void Compiler::iDeclareLocal(QScriptNameIdImpl *id, bool readOnly) -{ - QScriptValueImpl arg0; - id->persistent = true; - m_eng->newNameId(&arg0, id); - QScriptValueImpl arg1; - m_eng->newInteger(&arg1, readOnly); - pushInstruction(QScriptInstruction::OP_DeclareLocal, arg0, arg1); -} - -void Compiler::iAssign() -{ - pushInstruction(QScriptInstruction::OP_Assign); -} - -void Compiler::iBitAnd() -{ - pushInstruction(QScriptInstruction::OP_BitAnd); -} - -void Compiler::iBitOr() -{ - pushInstruction(QScriptInstruction::OP_BitOr); -} - -void Compiler::iBitXor() -{ - pushInstruction(QScriptInstruction::OP_BitXor); -} - -void Compiler::iLeftShift() -{ - pushInstruction(QScriptInstruction::OP_LeftShift); -} - -void Compiler::iMod() -{ - pushInstruction(QScriptInstruction::OP_Mod); -} - -void Compiler::iRightShift() -{ - pushInstruction(QScriptInstruction::OP_RightShift); -} - -void Compiler::iURightShift() -{ - pushInstruction(QScriptInstruction::OP_URightShift); -} - -void Compiler::iAdd() -{ - pushInstruction(QScriptInstruction::OP_Add); -} - -void Compiler::iDiv() -{ - pushInstruction(QScriptInstruction::OP_Div); -} - -void Compiler::iEqual() -{ - pushInstruction(QScriptInstruction::OP_Equal); -} - -void Compiler::iGreatOrEqual() -{ - pushInstruction(QScriptInstruction::OP_GreatOrEqual); -} - -void Compiler::iGreatThan() -{ - pushInstruction(QScriptInstruction::OP_GreatThan); -} - -void Compiler::iLessOrEqual() -{ - pushInstruction(QScriptInstruction::OP_LessOrEqual); -} - -void Compiler::iLessThan() -{ - pushInstruction(QScriptInstruction::OP_LessThan); -} - -void Compiler::iMul() -{ - pushInstruction(QScriptInstruction::OP_Mul); -} - -void Compiler::iNotEqual() -{ - pushInstruction(QScriptInstruction::OP_NotEqual); -} - -void Compiler::iSub() -{ - pushInstruction(QScriptInstruction::OP_Sub); -} - -void Compiler::iStrictEqual() -{ - pushInstruction(QScriptInstruction::OP_StrictEqual); -} - -void Compiler::iStrictNotEqual() -{ - pushInstruction(QScriptInstruction::OP_StrictNotEqual); -} - -void Compiler::iBranch(int index) -{ - QScriptValueImpl arg0; - m_eng->newInteger(&arg0, index); - pushInstruction(QScriptInstruction::OP_Branch, arg0); -} - -void Compiler::iBranchFalse(int index) -{ - QScriptValueImpl arg0; - m_eng->newInteger(&arg0, index); - pushInstruction(QScriptInstruction::OP_BranchFalse, arg0); -} - -void Compiler::iBranchTrue(int index) -{ - QScriptValueImpl arg0; - m_eng->newInteger(&arg0, index); - pushInstruction(QScriptInstruction::OP_BranchTrue, arg0); -} - -void Compiler::iNewClosure(AST::FunctionExpression *expr) -{ - QScriptValueImpl arg0; - m_eng->newPointer(&arg0, expr); - - pushInstruction(QScriptInstruction::OP_NewClosure, arg0); -} - -void Compiler::iIncr() -{ - pushInstruction(QScriptInstruction::OP_Incr); -} - -void Compiler::iDecr() -{ - pushInstruction(QScriptInstruction::OP_Decr); -} - -void Compiler::iPop() -{ - pushInstruction(QScriptInstruction::OP_Pop); -} - -void Compiler::iFetch(QScriptNameIdImpl *id) -{ - if (m_generateFastArgumentLookup) { - int index = m_formals.indexOf(id); - - if (index != -1) { - QScriptValueImpl arg0; - m_eng->newInteger(&arg0, index); - pushInstruction(QScriptInstruction::OP_Receive, arg0); - return; - } - } - - QScriptValueImpl arg0; - id->persistent = true; - m_eng->newNameId(&arg0, id); - pushInstruction(QScriptInstruction::OP_Fetch, arg0); -} - -void Compiler::iLoadTrue() -{ - pushInstruction(QScriptInstruction::OP_LoadTrue); -} - -void Compiler::iLoadFalse() -{ - pushInstruction(QScriptInstruction::OP_LoadFalse); -} - -void Compiler::iUnaryMinus() -{ - pushInstruction(QScriptInstruction::OP_UnaryMinus); -} - -void Compiler::iUnaryPlus() -{ - pushInstruction(QScriptInstruction::OP_UnaryPlus); -} - -void Compiler::iPostIncr() -{ - pushInstruction(QScriptInstruction::OP_PostIncr); -} - -void Compiler::iPostDecr() -{ - pushInstruction(QScriptInstruction::OP_PostDecr); -} - -void Compiler::iNewArray() -{ - pushInstruction(QScriptInstruction::OP_NewArray); -} - -void Compiler::iNewObject() -{ - pushInstruction(QScriptInstruction::OP_NewObject); -} - -void Compiler::iTypeOf() -{ - pushInstruction(QScriptInstruction::OP_TypeOf); -} - -void Compiler::iDelete() -{ - pushInstruction(QScriptInstruction::OP_Delete); -} - -void Compiler::iInstanceOf() -{ - pushInstruction(QScriptInstruction::OP_InstanceOf); -} - -void Compiler::iInplaceAnd() -{ - pushInstruction(QScriptInstruction::OP_InplaceAnd); -} - -void Compiler::iInplaceSub() -{ - pushInstruction(QScriptInstruction::OP_InplaceSub); -} - -void Compiler::iInplaceDiv() -{ - pushInstruction(QScriptInstruction::OP_InplaceDiv); -} - -void Compiler::iInplaceAdd() -{ - pushInstruction(QScriptInstruction::OP_InplaceAdd); -} - -void Compiler::iInplaceLeftShift() -{ - pushInstruction(QScriptInstruction::OP_InplaceLeftShift); -} - -void Compiler::iInplaceMod() -{ - pushInstruction(QScriptInstruction::OP_InplaceMod); -} - -void Compiler::iInplaceMul() -{ - pushInstruction(QScriptInstruction::OP_InplaceMul); -} - -void Compiler::iInplaceOr() -{ - pushInstruction(QScriptInstruction::OP_InplaceOr); -} - -void Compiler::iInplaceRightShift() -{ - pushInstruction(QScriptInstruction::OP_InplaceRightShift); -} - -void Compiler::iInplaceURightShift() -{ - pushInstruction(QScriptInstruction::OP_InplaceURightShift); -} - -void Compiler::iInplaceXor() -{ - pushInstruction(QScriptInstruction::OP_InplaceXor); -} - -void Compiler::iThrow() -{ - pushInstruction(QScriptInstruction::OP_Throw); -} - -void Compiler::iLine(AST::Node *node) -{ - if (! node) - return; - - QScriptValueImpl arg0; - m_eng->newInteger(&arg0, node->startLine); - - QScriptValueImpl arg1; - m_eng->newInteger(&arg1, node->startColumn); - - pushInstruction(QScriptInstruction::OP_Line, arg0, arg1); -} - -void Compiler::iBitNot() -{ - pushInstruction(QScriptInstruction::OP_BitNot); -} - -void Compiler::iNot() -{ - pushInstruction(QScriptInstruction::OP_Not); -} - -void Compiler::iNewRegExp(QScriptNameIdImpl *pattern) -{ - QScriptValueImpl arg0; - pattern->persistent = true; - m_eng->newNameId(&arg0, pattern); - pushInstruction(QScriptInstruction::OP_NewRegExp, arg0); -} - -void Compiler::iNewRegExp(QScriptNameIdImpl *pattern, int flags) -{ - QScriptValueImpl arg0; - pattern->persistent = true; - m_eng->newNameId(&arg0, pattern); - - QScriptValueImpl arg1; - m_eng->newInteger(&arg1, flags); - - pushInstruction(QScriptInstruction::OP_NewRegExp, arg0, arg1); -} - -void Compiler::iNewEnumeration() -{ - pushInstruction(QScriptInstruction::OP_NewEnumeration); -} - -void Compiler::iToFirstElement() -{ - pushInstruction(QScriptInstruction::OP_ToFirstElement); -} - -void Compiler::iHasNextElement() -{ - pushInstruction(QScriptInstruction::OP_HasNextElement); -} - -void Compiler::iNextElement() -{ - pushInstruction(QScriptInstruction::OP_NextElement); -} - -void Compiler::iEnterWith() -{ - pushInstruction(QScriptInstruction::OP_EnterWith); -} - -void Compiler::iLeaveWith() -{ - pushInstruction(QScriptInstruction::OP_LeaveWith); -} - -void Compiler::iBeginCatch(QScriptNameIdImpl *id) -{ - QScriptValueImpl arg0; - id->persistent = true; - m_eng->newNameId(&arg0, id); - pushInstruction(QScriptInstruction::OP_BeginCatch, arg0); -} - -void Compiler::iEndCatch() -{ - pushInstruction(QScriptInstruction::OP_EndCatch); -} - -void Compiler::iSync() -{ - pushInstruction(QScriptInstruction::OP_Sync); -} - -void Compiler::iHalt() -{ - pushInstruction(QScriptInstruction::OP_Halt); -} - -void Compiler::iMakeReference() -{ - pushInstruction(QScriptInstruction::OP_MakeReference); -} - -void Compiler::iIn() -{ - pushInstruction(QScriptInstruction::OP_In); -} - -void Compiler::iNop() -{ - pushInstruction(QScriptInstruction::OP_Nop); -} - -void Compiler::iNewString(QScriptNameIdImpl *id) -{ - QScriptValueImpl arg0; - id->persistent = true; - m_eng->newNameId(&arg0, id); - pushInstruction(QScriptInstruction::OP_NewString, arg0); -} - -void Compiler::iDebugger() -{ - pushInstruction(QScriptInstruction::OP_Debugger); -} - -Compiler::Loop *Compiler::findLoop(QScriptNameIdImpl *name) -{ - if (! name) - return m_activeLoop; - - QMap<AST::Statement*, Loop>::iterator it = m_loops.begin(); - - for (; it != m_loops.end(); ++it) { - Loop &loop = *it; - - if (loop.name == name) - return &loop; - } - - return 0; -} - - -} // namespace QScript - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT |