currentBlockMask = 0x00000001;
- for (int i = 0; i < blocks.size(); ++i) {
+ for (int i = 0; !_discarded && i < blocks.size(); ++i) {
IR::BasicBlock *block = blocks.at(i);
IR::BasicBlock *next = i + 1 < blocks.size() ? blocks.at(i + 1) : 0;
if (IR::Stmt *terminator = block->terminator()) {
blockop.block(currentBlockMask);
gen(blockop);
- foreach (IR::Stmt *s, block->statements)
- s->accept(this);
+ foreach (IR::Stmt *s, block->statements) {
+ if (! _discarded)
+ s->accept(this);
+ }
qSwap(usedSubscriptionIdsChanged, usic);
return;
}
currentBlockMask <<= 1;
- } else {
+ } else if (! _discarded) {
const int adjust = bytecode.remove(blockopIndex);
// Correct patches
for (int ii = patchesCount; ii < patches.count(); ++ii)
#endif
- // back patching
- foreach (const Patch &patch, patches) {
- Instr &instr = bytecode[patch.offset];
- instr.branchop.offset = patch.block->offset - patch.offset - instr.size();
- }
+ if (! _discarded) {
+ // back patching
+ foreach (const Patch &patch, patches) {
+ Instr &instr = bytecode[patch.offset];
+ instr.branchop.offset = patch.block->offset - patch.offset - instr.size();
+ }
- patches.clear();
+ patches.clear();
+ }
}
void QDeclarativeV4CompilerPrivate::trace(QVector<IR::BasicBlock *> *blocks)
int rv = committed.count();
committed.offsets << committed.bytecode.count();
committed.dependencies << usedSubscriptionIds;
- committed.bytecode += bytecode.code();
+ committed.bytecode.append(bytecode.constData(), bytecode.size());
committed.data = data;
committed.exceptions = exceptions;
committed.subscriptionIds = subscriptionIds;
}
- QByteArray bytecode = bc.code();
- bytecode += d->committed.bytecode;
+ QByteArray bytecode;
+ bytecode.reserve(bc.size() + d->committed.bytecode.size());
+ bytecode.append(bc.constData(), bc.size());
+ bytecode.append(d->committed.bytecode.constData(), d->committed.bytecode.size());
QByteArray data = d->committed.data;
while (data.count() % 4) data.append('\0');
Bytecode::Bytecode()
{
+ d.reserve(8 * 1024);
+
#ifdef QML_THREADED_INTERPRETER
decodeInstr = QDeclarativeV4Bindings::getDecodeInstrTable();
#endif
d.append(it, instr.size());
}
-void Bytecode::append(const QVector<Instr> &instrs)
-{
- foreach (const Instr &i, instrs)
- append(i);
-}
-
int Bytecode::remove(int offset)
{
const Instr *instr = (const Instr *) (d.begin() + offset);
#include <QtCore/qglobal.h>
#include <QtCore/qbytearray.h>
#include <QtCore/qvector.h>
+#include <QtCore/qvarlengtharray.h>
QT_BEGIN_HEADER
public:
Bytecode();
- QByteArray code() const { return d; }
const char *constData() const { return d.constData(); }
int size() const { return d.size(); }
int count() const { return d.count(); }
void clear() { d.clear(); }
bool isEmpty() const { return d.isEmpty(); }
void append(const Instr &instr);
- void append(const QVector<Instr> &instrs);
+
+ template <typename _It>
+ void append(_It it, _It last)
+ {
+ for (; it != last; ++it)
+ append(*it);
+ }
+
int remove(int index);
const Instr &operator[](int offset) const;
Instr &operator[](int offset);
private:
- QByteArray d;
+ QVarLengthArray<char, 4 * 1024> d;
#ifdef QML_THREADED_INTERPRETER
void **decodeInstr;
#endif
return discarded?0:function;
}
-bool QDeclarativeV4IRBuilder::buildName(QStringList &name,
+bool QDeclarativeV4IRBuilder::buildName(QList<QStringRef> &name,
AST::Node *node,
QList<AST::ExpressionNode *> *nodes)
{
if (node->kind == AST::Node::Kind_IdentifierExpression) {
- name << static_cast<AST::IdentifierExpression*>(node)->name.toString();
+ name << static_cast<AST::IdentifierExpression*>(node)->name;
if (nodes) *nodes << static_cast<AST::IdentifierExpression*>(node);
} else if (node->kind == AST::Node::Kind_FieldMemberExpression) {
AST::FieldMemberExpression *expr =
if (!buildName(name, expr->base, nodes))
return false;
- name << expr->name.toString();
+ name << expr->name;
if (nodes) *nodes << expr;
} else {
return false;
return false;
}
+bool QDeclarativeV4IRBuilder::preVisit(AST::Node *ast)
+{
+ return ! _discard;
+}
+
bool QDeclarativeV4IRBuilder::visit(AST::NewMemberExpression *)
{
return false;
bool QDeclarativeV4IRBuilder::visit(AST::CallExpression *ast)
{
- QStringList names;
+ QList<QStringRef> names;
QList<AST::ExpressionNode *> nameNodes;
+
+ names.reserve(4);
+ nameNodes.reserve(4);
+
if (buildName(names, ast->base, &nameNodes)) {
//ExprResult base = expression(ast->base);
- const QString id = names.join(QLatin1String("."));
- const quint32 line = nameNodes.last()->firstSourceLocation().startLine;
- const quint32 column = nameNodes.last()->firstSourceLocation().startColumn;
- IR::Expr *base = _block->NAME(id, line, column);
+ QString id;
+ for (int i = 0; i < names.size(); ++i) {
+ if (! i)
+ id += QLatin1Char('.');
+ id += names.at(i);
+ }
+ const AST::SourceLocation loc = nameNodes.last()->firstSourceLocation();
+ IR::Expr *base = _block->NAME(id, loc.startLine, loc.startColumn);
IR::ExprList *args = 0, **argsInserter = &args;
for (AST::ArgumentList *it = ast->arguments; it; it = it->next) {
void implicitCvt(ExprResult &expr, QDeclarativeJS::IR::Type type);
+ virtual bool preVisit(QDeclarativeJS::AST::Node *ast);
+
// QML
virtual bool visit(QDeclarativeJS::AST::UiProgram *ast);
virtual bool visit(QDeclarativeJS::AST::UiImportList *ast);
virtual bool visit(QDeclarativeJS::AST::DebuggerStatement *ast);
private:
- bool buildName(QStringList &name, QDeclarativeJS::AST::Node *node,
+ bool buildName(QList<QStringRef> &name, QDeclarativeJS::AST::Node *node,
QList<QDeclarativeJS::AST::ExpressionNode *> *nodes);
void discard();