aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2013-08-15 15:54:36 +0200
committerLars Knoll <lars.knoll@digia.com>2013-08-16 10:14:13 +0200
commitb88626a3a59f7dcd01be6fe2a8236b14ca1176f5 (patch)
treef3a1f6db220f2d6a7d71f2ddc7b466e205658f40 /src
parent214680abec598bc01c4f90b3cecc60c7968c0c41 (diff)
Ported regular expressions over to be run-time generated data
Change-Id: I04e693d4923c97c3d869a5beb17011f6aad85f03 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/qml/compiler/qv4compileddata.cpp18
-rw-r--r--src/qml/compiler/qv4compileddata_p.h22
-rw-r--r--src/qml/compiler/qv4compiler.cpp24
-rw-r--r--src/qml/compiler/qv4compiler_p.h4
-rw-r--r--src/qml/compiler/qv4isel_masm.cpp6
-rw-r--r--src/qml/jsruntime/qv4context.cpp10
-rw-r--r--src/qml/jsruntime/qv4context_p.h2
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp7
-rw-r--r--src/qml/jsruntime/qv4runtime_p.h1
9 files changed, 88 insertions, 6 deletions
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index 38461af88c..08c4d80b4e 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -44,6 +44,7 @@
#include <private/qv4engine_p.h>
#include <private/qv4function_p.h>
#include <private/qv4lookup_p.h>
+#include <private/qv4regexpobject_p.h>
namespace QV4 {
@@ -60,6 +61,7 @@ CompilationUnit::~CompilationUnit()
free(data);
free(runtimeStrings);
delete [] runtimeLookups;
+ delete [] runtimeRegularExpressions;
}
QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
@@ -73,6 +75,20 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
for (int i = 0; i < data->stringTableSize; ++i)
runtimeStrings[i] = engine->newIdentifier(data->stringAt(i)->qString());
+ runtimeRegularExpressions = new QV4::Value[data->regexpTableSize];
+ for (int i = 0; i < data->regexpTableSize; ++i) {
+ const CompiledData::RegExp *re = data->regexpAt(i);
+ int flags = 0;
+ if (re->flags & CompiledData::RegExp::RegExp_Global)
+ flags |= QQmlJS::V4IR::RegExp::RegExp_Global;
+ if (re->flags & CompiledData::RegExp::RegExp_IgnoreCase)
+ flags |= QQmlJS::V4IR::RegExp::RegExp_IgnoreCase;
+ if (re->flags & CompiledData::RegExp::RegExp_Multiline)
+ flags |= QQmlJS::V4IR::RegExp::RegExp_Multiline;
+ QV4::RegExpObject *obj = engine->newRegExpObject(data->stringAt(re->stringIndex)->qString(), flags);
+ runtimeRegularExpressions[i] = QV4::Value::fromObject(obj);
+ }
+
if (data->lookupTableSize) {
runtimeLookups = new QV4::Lookup[data->lookupTableSize];
const CompiledData::Lookup *compiledLookups = data->lookupTable();
@@ -101,6 +117,8 @@ void CompilationUnit::markObjects()
{
for (int i = 0; i < data->stringTableSize; ++i)
runtimeStrings[i]->mark();
+ for (int i = 0; i < data->regexpTableSize; ++i)
+ runtimeRegularExpressions[i].mark();
}
}
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index cd8a76b7c1..e267f0fecb 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -65,6 +65,20 @@ namespace CompiledData {
struct String;
struct Function;
struct Lookup;
+struct RegExp;
+
+struct RegExp
+{
+ enum Flags {
+ RegExp_Global = 0x01,
+ RegExp_IgnoreCase = 0x02,
+ RegExp_Multiline = 0x04
+ };
+ quint32 flags;
+ quint32 stringIndex;
+
+ static int calculateSize() { return sizeof(RegExp); }
+};
static const char magic_str[] = "qv4cdata";
@@ -85,6 +99,8 @@ struct Unit
uint offsetToFunctionTable;
uint lookupTableSize;
uint offsetToLookupTable;
+ uint regexpTableSize;
+ uint offsetToRegexpTable;
uint indexOfRootFunction;
quint32 sourceFileIndex;
@@ -101,8 +117,11 @@ struct Unit
}
const Lookup *lookupTable() const { return reinterpret_cast<const Lookup*>(reinterpret_cast<const char *>(this) + offsetToLookupTable); }
+ const RegExp *regexpAt(int index) const {
+ return reinterpret_cast<const RegExp*>(reinterpret_cast<const char *>(this) + offsetToRegexpTable + index * sizeof(RegExp));
+ }
- static int calculateSize(uint nStrings, uint nFunctions) { return (sizeof(Unit) + (nStrings + nFunctions) * sizeof(uint) + 7) & ~7; }
+ static int calculateSize(uint nStrings, uint nFunctions, uint nRegExps) { return (sizeof(Unit) + (nStrings + nFunctions ) * sizeof(uint) + nRegExps * RegExp::calculateSize() + 7) & ~7; }
};
struct Function
@@ -274,6 +293,7 @@ struct CompilationUnit
QV4::String **runtimeStrings; // Array
QV4::Lookup *runtimeLookups;
+ QV4::Value *runtimeRegularExpressions;
QV4::Function *linkToEngine(QV4::ExecutionEngine *engine);
diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp
index 6707283d93..d67b7deef7 100644
--- a/src/qml/compiler/qv4compiler.cpp
+++ b/src/qml/compiler/qv4compiler.cpp
@@ -94,6 +94,23 @@ uint QV4::Compiler::JSUnitGenerator::registerGlobalGetterLookup(const QString &n
return lookups.size() - 1;
}
+int QV4::Compiler::JSUnitGenerator::registerRegExp(QQmlJS::V4IR::RegExp *regexp)
+{
+ CompiledData::RegExp re;
+ re.stringIndex = registerString(*regexp->value);
+
+ re.flags = 0;
+ if (regexp->flags & QQmlJS::V4IR::RegExp::RegExp_Global)
+ re.flags |= CompiledData::RegExp::RegExp_Global;
+ if (regexp->flags & QQmlJS::V4IR::RegExp::RegExp_IgnoreCase)
+ re.flags |= CompiledData::RegExp::RegExp_IgnoreCase;
+ if (regexp->flags & QQmlJS::V4IR::RegExp::RegExp_Multiline)
+ re.flags |= CompiledData::RegExp::RegExp_Multiline;
+
+ regexps.append(re);
+ return regexps.size() - 1;
+}
+
QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit()
{
registerString(irModule->fileName);
@@ -105,7 +122,7 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit()
registerString(*f->locals.at(i));
}
- int unitSize = QV4::CompiledData::Unit::calculateSize(strings.size(), irModule->functions.size());
+ int unitSize = QV4::CompiledData::Unit::calculateSize(strings.size(), irModule->functions.size(), regexps.size());
uint functionDataSize = 0;
for (int i = 0; i < irModule->functions.size(); ++i) {
@@ -128,6 +145,8 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit()
unit->functionTableSize = irModule->functions.size();
unit->offsetToFunctionTable = unit->offsetToStringTable + unit->stringTableSize * sizeof(uint);
unit->lookupTableSize = lookups.count();
+ unit->regexpTableSize = regexps.size();
+ unit->offsetToRegexpTable = unit->offsetToFunctionTable + unit->functionTableSize * sizeof(uint);
unit->offsetToLookupTable = unitSize + stringDataSize + functionDataSize;
unit->sourceFileIndex = getStringId(irModule->fileName);
@@ -169,6 +188,9 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit()
foreach (const CompiledData::Lookup &l, lookups)
*lookupsToWrite++ = l;
+ CompiledData::RegExp *regexpTable = (CompiledData::RegExp *)(data + unit->offsetToRegexpTable);
+ memcpy(regexpTable, regexps.constData(), regexps.size() * sizeof(*regexpTable));
+
return unit;
}
diff --git a/src/qml/compiler/qv4compiler_p.h b/src/qml/compiler/qv4compiler_p.h
index e7385a0174..753e4627e7 100644
--- a/src/qml/compiler/qv4compiler_p.h
+++ b/src/qml/compiler/qv4compiler_p.h
@@ -51,6 +51,7 @@ namespace QV4 {
namespace CompiledData {
struct Unit;
struct Lookup;
+struct RegExp;
}
namespace Compiler {
@@ -67,6 +68,8 @@ struct JSUnitGenerator {
uint registerSetterLookup(const QString &name);
uint registerGlobalGetterLookup(const QString &name);
+ int registerRegExp(QQmlJS::V4IR::RegExp *regexp);
+
QV4::CompiledData::Unit *generateUnit();
void writeFunction(char *f, int index, QQmlJS::V4IR::Function *irFunction);
@@ -75,6 +78,7 @@ struct JSUnitGenerator {
int stringDataSize;
QHash<QQmlJS::V4IR::Function *, uint> functionOffsets;
QList<CompiledData::Lookup> lookups;
+ QVector<CompiledData::RegExp> regexps;
};
}
diff --git a/src/qml/compiler/qv4isel_masm.cpp b/src/qml/compiler/qv4isel_masm.cpp
index 3907cb1300..d93a67a163 100644
--- a/src/qml/compiler/qv4isel_masm.cpp
+++ b/src/qml/compiler/qv4isel_masm.cpp
@@ -1056,10 +1056,8 @@ void InstructionSelection::loadString(const QString &str, V4IR::Temp *targetTemp
void InstructionSelection::loadRegexp(V4IR::RegExp *sourceRegexp, V4IR::Temp *targetTemp)
{
- Value v = Value::fromObject(engine()->newRegExpObject(*sourceRegexp->value,
- sourceRegexp->flags));
- _vmFunction->generatedValues.append(v);
- _as->storeValue(v, targetTemp);
+ int id = jsUnitGenerator.registerRegExp(sourceRegexp);
+ generateFunctionCall(Assembler::Void, __qmljs_lookup_runtime_regexp, Assembler::ContextRegister, Assembler::PointerToValue(targetTemp), Assembler::TrustedImm32(id));
}
void InstructionSelection::getActivationProperty(const V4IR::Name *name, V4IR::Temp *temp)
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index 57d559b3ff..0effad944c 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -610,6 +610,16 @@ void ExecutionContext::throwURIError(Value msg)
throwError(Value::fromObject(engine->newURIErrorObject(msg)));
}
+const Function *ExecutionContext::runtimeFunction() const
+{
+ if (type >= Type_CallContext) {
+ const QV4::FunctionObject *f = asCallContext()->function;
+ Q_ASSERT(f);
+ return f ? f->function : 0;
+ }
+ Q_ASSERT(type == Type_GlobalContext);
+ return engine->globalCode;
+}
void SimpleCallContext::initSimpleCallContext(ExecutionEngine *engine)
{
diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h
index 3bae120098..7c111139e6 100644
--- a/src/qml/jsruntime/qv4context_p.h
+++ b/src/qml/jsruntime/qv4context_p.h
@@ -152,6 +152,8 @@ struct Q_QML_EXPORT ExecutionContext
inline CallContext *asCallContext();
inline const CallContext *asCallContext() const;
+
+ const Function *runtimeFunction() const;
};
struct SimpleCallContext : public ExecutionContext
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 8dcf65a0da..7d99a8e8f5 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -1226,6 +1226,13 @@ void __qmljs_value_from_string(Value *result, String *string)
*result = Value::fromString(string);
}
+void __qmljs_lookup_runtime_regexp(ExecutionContext *ctx, Value *result, int id)
+{
+ const QV4::Function *runtimeFunction = ctx->runtimeFunction();
+ Q_ASSERT(runtimeFunction);
+ *result = runtimeFunction->compilationUnit->runtimeRegularExpressions[id];
+}
+
} // namespace QV4
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4runtime_p.h b/src/qml/jsruntime/qv4runtime_p.h
index 31ee819b84..6f00d5bf94 100644
--- a/src/qml/jsruntime/qv4runtime_p.h
+++ b/src/qml/jsruntime/qv4runtime_p.h
@@ -127,6 +127,7 @@ void __qmljs_builtin_define_getter_setter(QV4::ExecutionContext *ctx, const QV4:
void __qmljs_builtin_define_object_literal(QV4::ExecutionContext *ctx, QV4::Value *result, const QV4::Value *args, QV4::InternalClass *klass);
void __qmljs_value_from_string(QV4::Value *result, QV4::String *string);
+void __qmljs_lookup_runtime_regexp(QV4::ExecutionContext *ctx, QV4::Value *result, int id);
// constructors
void __qmljs_init_closure(QV4::ExecutionContext *ctx, QV4::Value *result, QV4::Function *clos);