diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2013-08-15 15:54:36 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@digia.com> | 2013-08-16 10:14:13 +0200 |
commit | b88626a3a59f7dcd01be6fe2a8236b14ca1176f5 (patch) | |
tree | f3a1f6db220f2d6a7d71f2ddc7b466e205658f40 /src | |
parent | 214680abec598bc01c4f90b3cecc60c7968c0c41 (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.cpp | 18 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata_p.h | 22 | ||||
-rw-r--r-- | src/qml/compiler/qv4compiler.cpp | 24 | ||||
-rw-r--r-- | src/qml/compiler/qv4compiler_p.h | 4 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_masm.cpp | 6 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4context.cpp | 10 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4context_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 7 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime_p.h | 1 |
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); |