aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/qml/jsruntime/qv4engine.cpp4
-rw-r--r--src/qml/jsruntime/qv4enginebase_p.h3
-rw-r--r--src/qml/jsruntime/qv4lookup.cpp33
-rw-r--r--src/qml/jsruntime/qv4object.cpp10
4 files changed, 48 insertions, 2 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index c94b24b263..4e8b29e33d 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -867,6 +867,7 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
QV4::QObjectWrapper::initializeBindings(this);
m_delayedCallQueue.init(this);
+ isInitialized = true;
}
ExecutionEngine::~ExecutionEngine()
@@ -2182,8 +2183,11 @@ const QSet<QString> &ExecutionEngine::illegalNames() const
void ExecutionEngine::setQmlEngine(QQmlEngine *engine)
{
+ // Second stage of initialization. We're updating some more prototypes here.
+ isInitialized = false;
m_qmlEngine = engine;
initQmlGlobalObject();
+ isInitialized = true;
}
static void freeze_recursive(QV4::ExecutionEngine *v4, QV4::Object *object)
diff --git a/src/qml/jsruntime/qv4enginebase_p.h b/src/qml/jsruntime/qv4enginebase_p.h
index dc69529860..dd85f17717 100644
--- a/src/qml/jsruntime/qv4enginebase_p.h
+++ b/src/qml/jsruntime/qv4enginebase_p.h
@@ -44,7 +44,8 @@ struct Q_QML_EXPORT EngineBase {
#endif
quint8 isExecutingInRegExpJIT = false;
- quint8 padding[3];
+ quint8 isInitialized = false;
+ quint8 padding[2];
MemoryManager *memoryManager = nullptr;
qint32 callDepth = 0;
diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp
index ddd6f0174d..4e41fd60ce 100644
--- a/src/qml/jsruntime/qv4lookup.cpp
+++ b/src/qml/jsruntime/qv4lookup.cpp
@@ -38,6 +38,9 @@ ReturnedValue Lookup::resolveGetter(ExecutionEngine *engine, const Object *objec
ReturnedValue Lookup::resolvePrimitiveGetter(ExecutionEngine *engine, const Value &object)
{
+ // Otherwise we cannot trust the protoIds
+ Q_ASSERT(engine->isInitialized);
+
primitiveLookup.type = object.type();
switch (primitiveLookup.type) {
case Value::Undefined_Type:
@@ -83,6 +86,9 @@ ReturnedValue Lookup::resolvePrimitiveGetter(ExecutionEngine *engine, const Valu
ReturnedValue Lookup::resolveGlobalGetter(ExecutionEngine *engine)
{
+ // Otherwise we cannot trust the protoIds
+ Q_ASSERT(engine->isInitialized);
+
Object *o = engine->globalObject;
PropertyKey name = engine->identifierTable->asPropertyKey(engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
protoLookup.protoId = o->internalClass()->protoId;
@@ -220,6 +226,9 @@ ReturnedValue Lookup::getter0Inline(Lookup *l, ExecutionEngine *engine, const Va
ReturnedValue Lookup::getterProto(Lookup *l, ExecutionEngine *engine, const Value &object)
{
+ // Otherwise we cannot trust the protoIds
+ Q_ASSERT(engine->isInitialized);
+
// we can safely cast to a QV4::Object here. If object is actually a string,
// the internal class won't match
Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
@@ -277,6 +286,9 @@ ReturnedValue Lookup::getter0MemberDatagetter0MemberData(Lookup *l, ExecutionEng
ReturnedValue Lookup::getterProtoTwoClasses(Lookup *l, ExecutionEngine *engine, const Value &object)
{
+ // Otherwise we cannot trust the protoIds
+ Q_ASSERT(engine->isInitialized);
+
// we can safely cast to a QV4::Object here. If object is actually a string,
// the internal class won't match
Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
@@ -312,6 +324,9 @@ ReturnedValue Lookup::getterAccessor(Lookup *l, ExecutionEngine *engine, const V
ReturnedValue Lookup::getterProtoAccessor(Lookup *l, ExecutionEngine *engine, const Value &object)
{
+ // Otherwise we cannot trust the protoIds
+ Q_ASSERT(engine->isInitialized);
+
// we can safely cast to a QV4::Object here. If object is actually a string,
// the internal class won't match
Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
@@ -328,6 +343,9 @@ ReturnedValue Lookup::getterProtoAccessor(Lookup *l, ExecutionEngine *engine, co
ReturnedValue Lookup::getterProtoAccessorTwoClasses(Lookup *l, ExecutionEngine *engine, const Value &object)
{
+ // Otherwise we cannot trust the protoIds
+ Q_ASSERT(engine->isInitialized);
+
// we can safely cast to a QV4::Object here. If object is actually a string,
// the internal class won't match
Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
@@ -381,6 +399,9 @@ ReturnedValue Lookup::getterQObject(Lookup *lookup, ExecutionEngine *engine, con
ReturnedValue Lookup::primitiveGetterProto(Lookup *l, ExecutionEngine *engine, const Value &object)
{
+ // Otherwise we cannot trust the protoIds
+ Q_ASSERT(engine->isInitialized);
+
if (object.type() == l->primitiveLookup.type && !object.isObject()) {
Heap::Object *o = l->primitiveLookup.proto;
if (l->primitiveLookup.protoId == o->internalClass->protoId)
@@ -392,6 +413,9 @@ ReturnedValue Lookup::primitiveGetterProto(Lookup *l, ExecutionEngine *engine, c
ReturnedValue Lookup::primitiveGetterAccessor(Lookup *l, ExecutionEngine *engine, const Value &object)
{
+ // Otherwise we cannot trust the protoIds
+ Q_ASSERT(engine->isInitialized);
+
if (object.type() == l->primitiveLookup.type && !object.isObject()) {
Heap::Object *o = l->primitiveLookup.proto;
if (l->primitiveLookup.protoId == o->internalClass->protoId) {
@@ -423,6 +447,9 @@ ReturnedValue Lookup::globalGetterGeneric(Lookup *l, ExecutionEngine *engine)
ReturnedValue Lookup::globalGetterProto(Lookup *l, ExecutionEngine *engine)
{
+ // Otherwise we cannot trust the protoIds
+ Q_ASSERT(engine->isInitialized);
+
Heap::Object *o = engine->globalObject->d();
if (l->protoLookup.protoId == o->internalClass->protoId)
return l->protoLookup.data->asReturnedValue();
@@ -432,6 +459,9 @@ ReturnedValue Lookup::globalGetterProto(Lookup *l, ExecutionEngine *engine)
ReturnedValue Lookup::globalGetterProtoAccessor(Lookup *l, ExecutionEngine *engine)
{
+ // Otherwise we cannot trust the protoIds
+ Q_ASSERT(engine->isInitialized);
+
Heap::Object *o = engine->globalObject->d();
if (l->protoLookup.protoId == o->internalClass->protoId) {
const Value *getter = l->protoLookup.data;
@@ -551,6 +581,9 @@ bool Lookup::setter0setter0(Lookup *l, ExecutionEngine *engine, Value &object, c
bool Lookup::setterInsert(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
{
+ // Otherwise we cannot trust the protoIds
+ Q_ASSERT(engine->isInitialized);
+
Object *o = static_cast<Object *>(object.managed());
if (o && o->internalClass()->protoId == l->insertionLookup.protoId) {
o->setInternalClass(l->insertionLookup.newClass);
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index aec04b167d..ef4a40f4f3 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -68,7 +68,9 @@ void Object::setInternalClass(Heap::InternalClass *ic)
}
}
- if (ic->isUsedAsProto())
+ // Before the engine is done initializing, we cannot have any lookups.
+ // Therefore, there is no point in updating the proto IDs.
+ if (ic->engine->isInitialized && ic->isUsedAsProto())
ic->updateProtoUsage(p);
}
@@ -734,6 +736,9 @@ ReturnedValue Object::virtualInstanceOf(const Object *typeObject, const Value &v
ReturnedValue Object::virtualResolveLookupGetter(const Object *object, ExecutionEngine *engine, Lookup *lookup)
{
+ // Otherwise we cannot trust the protoIds
+ Q_ASSERT(engine->isInitialized);
+
Heap::Object *obj = object->d();
PropertyKey name = engine->identifierTable->asPropertyKey(engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[lookup->nameIndex]);
if (name.isArrayIndex()) {
@@ -769,6 +774,9 @@ ReturnedValue Object::virtualResolveLookupGetter(const Object *object, Execution
bool Object::virtualResolveLookupSetter(Object *object, ExecutionEngine *engine, Lookup *lookup, const Value &value)
{
+ // Otherwise we cannot trust the protoIds
+ Q_ASSERT(engine->isInitialized);
+
Scope scope(engine);
ScopedString name(scope, scope.engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[lookup->nameIndex]);