aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2014-11-24 15:38:41 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2014-12-11 15:52:13 +0100
commit8afc1f7fe24c625cdb84406cc7665f1dcabf88c4 (patch)
tree04c5d73167544182e509ce7e40bd18c29909d0a7
parent4322c8d7686c7cbbdf348146d32d705007b21d56 (diff)
Move prototype back from the vtable into Object
This is the only way we can support a GC that moves objects around in memory. Change-Id: I1d168fae4aa9f575b730e469e762bc5b5549b886 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
-rw-r--r--src/qml/jsapi/qjsengine.cpp6
-rw-r--r--src/qml/jsruntime/qv4argumentsobject.cpp3
-rw-r--r--src/qml/jsruntime/qv4arraybuffer.cpp2
-rw-r--r--src/qml/jsruntime/qv4dataview.cpp2
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4dateobject_p.h16
-rw-r--r--src/qml/jsruntime/qv4engine.cpp177
-rw-r--r--src/qml/jsruntime/qv4engine_p.h28
-rw-r--r--src/qml/jsruntime/qv4errorobject.cpp38
-rw-r--r--src/qml/jsruntime/qv4errorobject_p.h8
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp47
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h6
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp66
-rw-r--r--src/qml/jsruntime/qv4internalclass_p.h8
-rw-r--r--src/qml/jsruntime/qv4jsonobject.cpp6
-rw-r--r--src/qml/jsruntime/qv4jsonobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4lookup.cpp6
-rw-r--r--src/qml/jsruntime/qv4mathobject.cpp6
-rw-r--r--src/qml/jsruntime/qv4mathobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4object.cpp17
-rw-r--r--src/qml/jsruntime/qv4object_p.h104
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp8
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp10
-rw-r--r--src/qml/jsruntime/qv4regexpobject_p.h9
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp2
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp4
-rw-r--r--src/qml/jsruntime/qv4string.cpp8
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp10
-rw-r--r--src/qml/jsruntime/qv4stringobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4typedarray.cpp2
-rw-r--r--src/qml/jsruntime/qv4variantobject.cpp7
-rw-r--r--src/qml/jsruntime/qv4variantobject_p.h4
-rw-r--r--src/qml/qml/qqmllocale.cpp12
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp4
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp2
35 files changed, 309 insertions, 327 deletions
diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp
index bd78b7d051..e25d166172 100644
--- a/src/qml/jsapi/qjsengine.cpp
+++ b/src/qml/jsapi/qjsengine.cpp
@@ -264,8 +264,8 @@ void QJSEngine::installTranslatorFunctions(const QJSValue &object)
obj->defineDefaultProperty(QStringLiteral("QT_TRID_NOOP"), QV4::GlobalExtensions::method_qsTrIdNoOp);
// string prototype extension
- v4->stringObjectClass->prototype->defineDefaultProperty(QStringLiteral("arg"),
- QV4::GlobalExtensions::method_string_arg);
+ v4->stringPrototype.asObject()->defineDefaultProperty(QStringLiteral("arg"),
+ QV4::GlobalExtensions::method_string_arg);
#endif
}
@@ -301,7 +301,7 @@ QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, in
{
QV4::ExecutionEngine *v4 = d->m_v4Engine;
QV4::Scope scope(v4);
- QV4::ExecutionContext *ctx = v4->currentContext();
+ QV4::ScopedContext ctx(scope, v4->currentContext());
if (ctx != v4->rootContext())
ctx = v4->pushGlobalContext();
QV4::ScopedValue result(scope);
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp
index 78c8d6fccf..d283537292 100644
--- a/src/qml/jsruntime/qv4argumentsobject.cpp
+++ b/src/qml/jsruntime/qv4argumentsobject.cpp
@@ -39,7 +39,8 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(ArgumentsObject);
Heap::ArgumentsObject::ArgumentsObject(QV4::CallContext *context)
- : Heap::Object(context->d()->strictMode ? context->d()->engine->strictArgumentsObjectClass : context->d()->engine->argumentsObjectClass)
+ : Heap::Object(context->d()->strictMode ? context->d()->engine->strictArgumentsObjectClass : context->d()->engine->argumentsObjectClass,
+ context->d()->engine->objectPrototype.asObject())
, context(context->d())
, fullyCreated(false)
{
diff --git a/src/qml/jsruntime/qv4arraybuffer.cpp b/src/qml/jsruntime/qv4arraybuffer.cpp
index b8b9971635..9fc3114751 100644
--- a/src/qml/jsruntime/qv4arraybuffer.cpp
+++ b/src/qml/jsruntime/qv4arraybuffer.cpp
@@ -84,7 +84,7 @@ ReturnedValue ArrayBufferCtor::method_isView(CallContext *ctx)
Heap::ArrayBuffer::ArrayBuffer(ExecutionEngine *e, int length)
- : Heap::Object(e->arrayBufferClass)
+ : Heap::Object(e->arrayBufferClass, e->arrayBufferPrototype.asObject())
{
data = QTypedArrayData<char>::allocate(length + 1);
if (!data) {
diff --git a/src/qml/jsruntime/qv4dataview.cpp b/src/qml/jsruntime/qv4dataview.cpp
index 61a009187d..36d597fb6e 100644
--- a/src/qml/jsruntime/qv4dataview.cpp
+++ b/src/qml/jsruntime/qv4dataview.cpp
@@ -77,7 +77,7 @@ ReturnedValue DataViewCtor::call(Managed *that, CallData *callData)
Heap::DataView::DataView(ExecutionEngine *e)
- : Heap::Object(e->dataViewClass),
+ : Heap::Object(e->dataViewClass, e->dataViewPrototype.asObject()),
buffer(0),
byteLength(0),
byteOffset(0)
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp
index c5d25e42ae..811d2f0acb 100644
--- a/src/qml/jsruntime/qv4dateobject.cpp
+++ b/src/qml/jsruntime/qv4dateobject.cpp
@@ -635,7 +635,7 @@ static double getLocalTZA()
DEFINE_OBJECT_VTABLE(DateObject);
Heap::DateObject::DateObject(QV4::ExecutionEngine *engine, const QDateTime &date)
- : Heap::Object(engine->dateClass)
+ : Heap::Object(engine->dateClass, engine->datePrototype.asObject())
{
setVTable(QV4::DateObject::staticVTable());
value.setDouble(date.isValid() ? date.toMSecsSinceEpoch() : qSNaN());
diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h
index 4eba963fac..b164de6baa 100644
--- a/src/qml/jsruntime/qv4dateobject_p.h
+++ b/src/qml/jsruntime/qv4dateobject_p.h
@@ -46,13 +46,18 @@ namespace QV4 {
namespace Heap {
struct DateObject : Object {
+ DateObject(InternalClass *ic, QV4::Object *prototype)
+ : Object(ic, prototype)
+ {
+ value = Encode(qSNaN());
+ }
+
DateObject(QV4::ExecutionEngine *engine, const ValueRef date)
- : Object(engine->dateClass)
+ : Object(engine->dateClass, engine->datePrototype.asObject())
{
value = date;
}
DateObject(QV4::ExecutionEngine *engine, const QDateTime &date);
- inline DateObject(InternalClass *ic);
Value value;
};
@@ -74,13 +79,6 @@ struct DateObject: Object {
QDateTime toQDateTime() const;
};
-Heap::DateObject::DateObject(InternalClass *ic)
- : Heap::Object(ic)
-{
- Q_ASSERT(internalClass->vtable == QV4::DateObject::staticVTable());
- value = Primitive::fromDouble(qSNaN());
-}
-
struct DateCtor: FunctionObject
{
V4_OBJECT2(DateCtor, FunctionObject)
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index ddee344114..160dbe4352 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -219,10 +219,9 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
classPool = new InternalClassPool;
emptyClass = new (classPool) InternalClass(this);
- executionContextClass = InternalClass::create(this, ExecutionContext::staticVTable(), 0);
- constructClass = InternalClass::create(this, Object::staticVTable(), 0);
- stringClass = InternalClass::create(this, String::staticVTable(), 0);
- regExpValueClass = InternalClass::create(this, RegExp::staticVTable(), 0);
+ executionContextClass = InternalClass::create(this, ExecutionContext::staticVTable());
+ stringClass = InternalClass::create(this, String::staticVTable());
+ regExpValueClass = InternalClass::create(this, RegExp::staticVTable());
id_empty = newIdentifier(QString());
id_undefined = newIdentifier(QStringLiteral("undefined"));
@@ -261,20 +260,19 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
id_buffer = newIdentifier(QStringLiteral("buffer"));
id_lastIndex = newIdentifier(QStringLiteral("lastIndex"));
- memberDataClass = InternalClass::create(this, MemberData::staticVTable(), 0);
+ memberDataClass = InternalClass::create(this, MemberData::staticVTable());
- ScopedObject objectPrototype(scope, memoryManager->alloc<ObjectPrototype>(InternalClass::create(this, ObjectPrototype::staticVTable(), 0)));
- objectClass = InternalClass::create(this, Object::staticVTable(), objectPrototype);
+ objectPrototype = memoryManager->alloc<ObjectPrototype>(InternalClass::create(this, ObjectPrototype::staticVTable()), (QV4::Object *)0);
+ objectClass = InternalClass::create(this, Object::staticVTable());
Q_ASSERT(objectClass->vtable == Object::staticVTable());
- arrayClass = InternalClass::create(this, ArrayObject::staticVTable(), objectPrototype);
+ arrayClass = InternalClass::create(this, ArrayObject::staticVTable());
arrayClass = arrayClass->addMember(id_length, Attr_NotConfigurable|Attr_NotEnumerable);
- ScopedObject arrayPrototype(scope, memoryManager->alloc<ArrayPrototype>(arrayClass));
- arrayClass = arrayClass->changePrototype(arrayPrototype);
+ arrayPrototype = memoryManager->alloc<ArrayPrototype>(arrayClass, objectPrototype.asObject());
- simpleArrayDataClass = InternalClass::create(this, SimpleArrayData::staticVTable(), 0);
+ simpleArrayDataClass = InternalClass::create(this, SimpleArrayData::staticVTable());
- InternalClass *argsClass = InternalClass::create(this, ArgumentsObject::staticVTable(), objectPrototype);
+ InternalClass *argsClass = InternalClass::create(this, ArgumentsObject::staticVTable());
argsClass = argsClass->addMember(id_length, Attr_NotEnumerable);
argumentsObjectClass = argsClass->addMember(id_callee, Attr_Data|Attr_NotEnumerable);
strictArgumentsObjectClass = argsClass->addMember(id_callee, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
@@ -286,57 +284,56 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
Q_ASSERT(globalObject()->internalClass()->vtable);
initRootContext();
- ScopedObject stringPrototype(scope, memoryManager->alloc<StringPrototype>(InternalClass::create(this, StringPrototype::staticVTable(), objectPrototype)));
- stringObjectClass = InternalClass::create(this, String::staticVTable(), stringPrototype);
+ stringPrototype = memoryManager->alloc<StringPrototype>(InternalClass::create(this, StringPrototype::staticVTable()), objectPrototype.asObject());
+ stringObjectClass = InternalClass::create(this, String::staticVTable());
- ScopedObject numberPrototype(scope, memoryManager->alloc<NumberPrototype>(InternalClass::create(this, NumberPrototype::staticVTable(), objectPrototype)));
- numberClass = InternalClass::create(this, NumberObject::staticVTable(), numberPrototype);
+ numberPrototype = memoryManager->alloc<NumberPrototype>(InternalClass::create(this, NumberPrototype::staticVTable()), objectPrototype.asObject());
+ numberClass = InternalClass::create(this, NumberObject::staticVTable());
- ScopedObject booleanPrototype(scope, memoryManager->alloc<BooleanPrototype>(InternalClass::create(this, BooleanPrototype::staticVTable(), objectPrototype)));
- booleanClass = InternalClass::create(this, BooleanObject::staticVTable(), booleanPrototype);
+ booleanPrototype = memoryManager->alloc<BooleanPrototype>(InternalClass::create(this, BooleanPrototype::staticVTable()), objectPrototype.asObject());
+ booleanClass = InternalClass::create(this, BooleanObject::staticVTable());
- ScopedObject datePrototype(scope, memoryManager->alloc<DatePrototype>(InternalClass::create(this, DatePrototype::staticVTable(), objectPrototype)));
- dateClass = InternalClass::create(this, DateObject::staticVTable(), datePrototype);
+ datePrototype = memoryManager->alloc<DatePrototype>(InternalClass::create(this, DatePrototype::staticVTable()), objectPrototype.asObject());
+ dateClass = InternalClass::create(this, DateObject::staticVTable());
- InternalClass *functionProtoClass = InternalClass::create(this, FunctionObject::staticVTable(), objectPrototype);
+ InternalClass *functionProtoClass = InternalClass::create(this, FunctionObject::staticVTable());
uint index;
functionProtoClass = functionProtoClass->addMember(id_prototype, Attr_NotEnumerable, &index);
Q_ASSERT(index == Heap::FunctionObject::Index_Prototype);
- ScopedObject functionPrototype(scope, memoryManager->alloc<FunctionPrototype>(functionProtoClass));
- functionClass = InternalClass::create(this, FunctionObject::staticVTable(), functionPrototype);
+ functionPrototype = memoryManager->alloc<FunctionPrototype>(functionProtoClass, objectPrototype.asObject());
+ functionClass = InternalClass::create(this, FunctionObject::staticVTable());
functionClass = functionClass->addMember(id_prototype, Attr_NotEnumerable|Attr_NotConfigurable, &index);
Q_ASSERT(index == Heap::FunctionObject::Index_Prototype);
protoClass = objectClass->addMember(id_constructor, Attr_NotEnumerable, &index);
Q_ASSERT(index == Heap::FunctionObject::Index_ProtoConstructor);
- Scoped<RegExpPrototype> regExpPrototype(scope, memoryManager->alloc<RegExpPrototype>(InternalClass::create(this, RegExpPrototype::staticVTable(), objectPrototype)));
- regExpClass = InternalClass::create(this, RegExpObject::staticVTable(), regExpPrototype.getPointer());
+ regExpPrototype = memoryManager->alloc<RegExpPrototype>(this);
+ regExpClass = InternalClass::create(this, RegExpObject::staticVTable());
regExpExecArrayClass = arrayClass->addMember(id_index, Attr_Data, &index);
Q_ASSERT(index == RegExpObject::Index_ArrayIndex);
regExpExecArrayClass = regExpExecArrayClass->addMember(id_input, Attr_Data, &index);
Q_ASSERT(index == RegExpObject::Index_ArrayInput);
- ScopedObject errorPrototype(scope, memoryManager->alloc<ErrorPrototype>(InternalClass::create(this, ErrorObject::staticVTable(), objectPrototype)));
- errorClass = InternalClass::create(this, ErrorObject::staticVTable(), errorPrototype);
- ScopedObject evalErrorPrototype(scope, memoryManager->alloc<EvalErrorPrototype>(errorClass));
- evalErrorClass = InternalClass::create(this, EvalErrorObject::staticVTable(), evalErrorPrototype);
- ScopedObject rangeErrorPrototype(scope, memoryManager->alloc<RangeErrorPrototype>(errorClass));
- rangeErrorClass = InternalClass::create(this, RangeErrorObject::staticVTable(), rangeErrorPrototype);
- ScopedObject referenceErrorPrototype(scope, memoryManager->alloc<ReferenceErrorPrototype>(errorClass));
- referenceErrorClass = InternalClass::create(this, ReferenceErrorObject::staticVTable(), referenceErrorPrototype);
- ScopedObject syntaxErrorPrototype(scope, memoryManager->alloc<SyntaxErrorPrototype>(errorClass));
- syntaxErrorClass = InternalClass::create(this, SyntaxErrorObject::staticVTable(), syntaxErrorPrototype);
- ScopedObject typeErrorPrototype(scope, memoryManager->alloc<TypeErrorPrototype>(errorClass));
- typeErrorClass = InternalClass::create(this, TypeErrorObject::staticVTable(), typeErrorPrototype);
- ScopedObject uRIErrorPrototype(scope, memoryManager->alloc<URIErrorPrototype>(errorClass));
- uriErrorClass = InternalClass::create(this, URIErrorObject::staticVTable(), uRIErrorPrototype);
-
- ScopedObject variantPrototype(scope, memoryManager->alloc<VariantPrototype>(InternalClass::create(this, VariantPrototype::staticVTable(), objectPrototype)));
- variantClass = InternalClass::create(this, VariantObject::staticVTable(), variantPrototype);
- Q_ASSERT(variantClass->prototype == variantPrototype);
- Q_ASSERT(variantPrototype->internalClass()->prototype == objectPrototype);
-
- sequencePrototype = ScopedValue(scope, memoryManager->alloc<SequencePrototype>(arrayClass));
+ errorPrototype = memoryManager->alloc<ErrorPrototype>(InternalClass::create(this, ErrorObject::staticVTable()), objectPrototype.asObject());
+ errorClass = InternalClass::create(this, ErrorObject::staticVTable());
+ evalErrorPrototype = memoryManager->alloc<EvalErrorPrototype>(errorClass, errorPrototype.asObject());
+ evalErrorClass = InternalClass::create(this, EvalErrorObject::staticVTable());
+ rangeErrorPrototype = memoryManager->alloc<RangeErrorPrototype>(errorClass, errorPrototype.asObject());
+ rangeErrorClass = InternalClass::create(this, RangeErrorObject::staticVTable());
+ referenceErrorPrototype = memoryManager->alloc<ReferenceErrorPrototype>(errorClass, errorPrototype.asObject());
+ referenceErrorClass = InternalClass::create(this, ReferenceErrorObject::staticVTable());
+ syntaxErrorPrototype = memoryManager->alloc<SyntaxErrorPrototype>(errorClass, errorPrototype.asObject());
+ syntaxErrorClass = InternalClass::create(this, SyntaxErrorObject::staticVTable());
+ typeErrorPrototype = memoryManager->alloc<TypeErrorPrototype>(errorClass, errorPrototype.asObject());
+ typeErrorClass = InternalClass::create(this, TypeErrorObject::staticVTable());
+ uRIErrorPrototype = memoryManager->alloc<URIErrorPrototype>(errorClass, errorPrototype.asObject());
+ uriErrorClass = InternalClass::create(this, URIErrorObject::staticVTable());
+
+ variantPrototype = memoryManager->alloc<VariantPrototype>(InternalClass::create(this, VariantPrototype::staticVTable()), objectPrototype.asObject());
+ variantClass = InternalClass::create(this, VariantObject::staticVTable());
+ Q_ASSERT(variantPrototype.asObject()->prototype() == objectPrototype.asObject());
+
+ sequencePrototype = ScopedValue(scope, memoryManager->alloc<SequencePrototype>(arrayClass, arrayPrototype.asObject()));
objectCtor = memoryManager->alloc<ObjectCtor>(rootContext());
stringCtor = memoryManager->alloc<StringCtor>(rootContext());
@@ -354,43 +351,43 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
typeErrorCtor = memoryManager->alloc<TypeErrorCtor>(rootContext());
uRIErrorCtor = memoryManager->alloc<URIErrorCtor>(rootContext());
- static_cast<ObjectPrototype *>(objectPrototype.getPointer())->init(this, objectCtor.asObject());
- static_cast<StringPrototype *>(stringPrototype.getPointer())->init(this, stringCtor.asObject());
- static_cast<NumberPrototype *>(numberPrototype.getPointer())->init(this, numberCtor.asObject());
- static_cast<BooleanPrototype *>(booleanPrototype.getPointer())->init(this, booleanCtor.asObject());
- static_cast<ArrayPrototype *>(arrayPrototype.getPointer())->init(this, arrayCtor.asObject());
- static_cast<DatePrototype *>(datePrototype.getPointer())->init(this, dateCtor.asObject());
- static_cast<FunctionPrototype *>(functionPrototype.getPointer())->init(this, functionCtor.asObject());
- static_cast<RegExpPrototype *>(regExpPrototype.getPointer())->init(this, regExpCtor.asObject());
- static_cast<ErrorPrototype *>(errorPrototype.getPointer())->init(this, errorCtor.asObject());
- static_cast<EvalErrorPrototype *>(evalErrorPrototype.getPointer())->init(this, evalErrorCtor.asObject());
- static_cast<RangeErrorPrototype *>(rangeErrorPrototype.getPointer())->init(this, rangeErrorCtor.asObject());
- static_cast<ReferenceErrorPrototype *>(referenceErrorPrototype.getPointer())->init(this, referenceErrorCtor.asObject());
- static_cast<SyntaxErrorPrototype *>(syntaxErrorPrototype.getPointer())->init(this, syntaxErrorCtor.asObject());
- static_cast<TypeErrorPrototype *>(typeErrorPrototype.getPointer())->init(this, typeErrorCtor.asObject());
- static_cast<URIErrorPrototype *>(uRIErrorPrototype.getPointer())->init(this, uRIErrorCtor.asObject());
-
- static_cast<VariantPrototype *>(variantPrototype.getPointer())->init();
+ static_cast<ObjectPrototype *>(objectPrototype.asObject())->init(this, objectCtor.asObject());
+ static_cast<StringPrototype *>(stringPrototype.asObject())->init(this, stringCtor.asObject());
+ static_cast<NumberPrototype *>(numberPrototype.asObject())->init(this, numberCtor.asObject());
+ static_cast<BooleanPrototype *>(booleanPrototype.asObject())->init(this, booleanCtor.asObject());
+ static_cast<ArrayPrototype *>(arrayPrototype.asObject())->init(this, arrayCtor.asObject());
+ static_cast<DatePrototype *>(datePrototype.asObject())->init(this, dateCtor.asObject());
+ static_cast<FunctionPrototype *>(functionPrototype.asObject())->init(this, functionCtor.asObject());
+ static_cast<RegExpPrototype *>(regExpPrototype.asObject())->init(this, regExpCtor.asObject());
+ static_cast<ErrorPrototype *>(errorPrototype.asObject())->init(this, errorCtor.asObject());
+ static_cast<EvalErrorPrototype *>(evalErrorPrototype.asObject())->init(this, evalErrorCtor.asObject());
+ static_cast<RangeErrorPrototype *>(rangeErrorPrototype.asObject())->init(this, rangeErrorCtor.asObject());
+ static_cast<ReferenceErrorPrototype *>(referenceErrorPrototype.asObject())->init(this, referenceErrorCtor.asObject());
+ static_cast<SyntaxErrorPrototype *>(syntaxErrorPrototype.asObject())->init(this, syntaxErrorCtor.asObject());
+ static_cast<TypeErrorPrototype *>(typeErrorPrototype.asObject())->init(this, typeErrorCtor.asObject());
+ static_cast<URIErrorPrototype *>(uRIErrorPrototype.asObject())->init(this, uRIErrorCtor.asObject());
+
+ static_cast<VariantPrototype *>(variantPrototype.asObject())->init();
sequencePrototype.cast<SequencePrototype>()->init();
// typed arrays
arrayBufferCtor = memoryManager->alloc<ArrayBufferCtor>(rootContext());
- Scoped<ArrayBufferPrototype> arrayBufferPrototype(scope, memoryManager->alloc<ArrayBufferPrototype>(objectClass));
- arrayBufferPrototype->init(this, arrayBufferCtor.asObject());
- arrayBufferClass = InternalClass::create(this, ArrayBuffer::staticVTable(), arrayBufferPrototype);
+ arrayBufferPrototype = memoryManager->alloc<ArrayBufferPrototype>(objectClass, objectPrototype.asObject());
+ static_cast<ArrayBufferPrototype *>(arrayBufferPrototype.asObject())->init(this, arrayBufferCtor.asObject());
+ arrayBufferClass = InternalClass::create(this, ArrayBuffer::staticVTable());
dataViewCtor = memoryManager->alloc<DataViewCtor>(rootContext());
- Scoped<DataViewPrototype> dataViewPrototype(scope, memoryManager->alloc<DataViewPrototype>(objectClass));
- dataViewPrototype->init(this, dataViewCtor.asObject());
- dataViewClass = InternalClass::create(this, DataView::staticVTable(), dataViewPrototype);
+ dataViewPrototype = memoryManager->alloc<DataViewPrototype>(objectClass, objectPrototype.asObject());
+ static_cast<DataViewPrototype *>(dataViewPrototype.asObject())->init(this, dataViewCtor.asObject());
+ dataViewClass = InternalClass::create(this, DataView::staticVTable());
for (int i = 0; i < Heap::TypedArray::NTypes; ++i) {
typedArrayCtors[i] = memoryManager->alloc<TypedArrayCtor>(rootContext(), Heap::TypedArray::Type(i));
- Scoped<TypedArrayPrototype> typedArrayPrototype(scope, memoryManager->alloc<TypedArrayPrototype>(this, Heap::TypedArray::Type(i)));
- typedArrayPrototype->init(this, static_cast<TypedArrayCtor *>(typedArrayCtors[i].asObject()));
- typedArrayClasses[i] = InternalClass::create(this, TypedArray::staticVTable(), typedArrayPrototype);
+ typedArrayPrototype[i] = memoryManager->alloc<TypedArrayPrototype>(this, Heap::TypedArray::Type(i));
+ typedArrayPrototype[i].as<TypedArrayPrototype>()->init(this, static_cast<TypedArrayCtor *>(typedArrayCtors[i].asObject()));
+ typedArrayClasses[i] = InternalClass::create(this, TypedArray::staticVTable());
}
//
@@ -422,8 +419,8 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
for (int i = 0; i < Heap::TypedArray::NTypes; ++i)
globalObject()->defineDefaultProperty((str = typedArrayCtors[i].asFunctionObject()->name())->toQString(), typedArrayCtors[i]);
ScopedObject o(scope);
- globalObject()->defineDefaultProperty(QStringLiteral("Math"), (o = memoryManager->alloc<MathObject>(QV4::InternalClass::create(this, MathObject::staticVTable(), objectPrototype))));
- globalObject()->defineDefaultProperty(QStringLiteral("JSON"), (o = memoryManager->alloc<JsonObject>(QV4::InternalClass::create(this, JsonObject::staticVTable(), objectPrototype))));
+ globalObject()->defineDefaultProperty(QStringLiteral("Math"), (o = memoryManager->alloc<MathObject>(this)));
+ globalObject()->defineDefaultProperty(QStringLiteral("JSON"), (o = memoryManager->alloc<JsonObject>(this)));
globalObject()->defineReadonlyProperty(QStringLiteral("undefined"), Primitive::undefinedValue());
globalObject()->defineReadonlyProperty(QStringLiteral("NaN"), Primitive::fromDouble(std::numeric_limits<double>::quiet_NaN()));
@@ -526,10 +523,10 @@ Heap::Object *ExecutionEngine::newObject()
return object->d();
}
-Heap::Object *ExecutionEngine::newObject(InternalClass *internalClass)
+Heap::Object *ExecutionEngine::newObject(InternalClass *internalClass, QV4::Object *prototype)
{
Scope scope(this);
- ScopedObject object(scope, memoryManager->alloc<Object>(internalClass));
+ ScopedObject object(scope, memoryManager->alloc<Object>(internalClass, prototype));
return object->d();
}
@@ -585,10 +582,10 @@ Heap::ArrayObject *ExecutionEngine::newArrayObject(const QStringList &list)
return object->d();
}
-Heap::ArrayObject *ExecutionEngine::newArrayObject(InternalClass *ic)
+Heap::ArrayObject *ExecutionEngine::newArrayObject(InternalClass *ic, Object *prototype)
{
Scope scope(this);
- ScopedArrayObject object(scope, memoryManager->alloc<ArrayObject>(ic));
+ ScopedArrayObject object(scope, memoryManager->alloc<ArrayObject>(ic, prototype));
return object->d();
}
@@ -639,7 +636,7 @@ Heap::RegExpObject *ExecutionEngine::newRegExpObject(const QRegExp &re)
Heap::Object *ExecutionEngine::newErrorObject(const ValueRef value)
{
Scope scope(this);
- ScopedObject object(scope, memoryManager->alloc<ErrorObject>(errorClass, value));
+ ScopedObject object(scope, memoryManager->alloc<ErrorObject>(errorClass, errorPrototype.asObject(), value));
return object->d();
}
@@ -951,8 +948,30 @@ void ExecutionEngine::markObjects()
dataViewCtor.mark(this);
for (int i = 0; i < Heap::TypedArray::NTypes; ++i)
typedArrayCtors[i].mark(this);
+
+ objectPrototype.mark(this);
+ arrayPrototype.mark(this);
+ stringPrototype.mark(this);
+ numberPrototype.mark(this);
+ booleanPrototype.mark(this);
+ datePrototype.mark(this);
+ functionPrototype.mark(this);
+ regExpPrototype.mark(this);
+ errorPrototype.mark(this);
+ evalErrorPrototype.mark(this);
+ rangeErrorPrototype.mark(this);
+ referenceErrorPrototype.mark(this);
+ syntaxErrorPrototype.mark(this);
+ typeErrorPrototype.mark(this);
+ uRIErrorPrototype.mark(this);
+ variantPrototype.mark(this);
sequencePrototype.mark(this);
+ arrayBufferPrototype.mark(this);
+ dataViewPrototype.mark(this);
+ for (int i = 0; i < Heap::TypedArray::NTypes; ++i)
+ typedArrayPrototype[i].mark(this);
+
exceptionValue.mark(this);
thrower->mark(this);
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index ad9fde3d86..dc75d37a86 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -141,16 +141,36 @@ public:
Value syntaxErrorCtor;
Value typeErrorCtor;
Value uRIErrorCtor;
- Value sequencePrototype;
Value arrayBufferCtor;
Value dataViewCtor;
enum { NTypedArrayTypes = 9 }; // avoid header dependency
Value typedArrayCtors[NTypedArrayTypes];
+ Value objectPrototype;
+ Value arrayPrototype;
+ Value stringPrototype;
+ Value numberPrototype;
+ Value booleanPrototype;
+ Value datePrototype;
+ Value functionPrototype;
+ Value regExpPrototype;
+ Value errorPrototype;
+ Value evalErrorPrototype;
+ Value rangeErrorPrototype;
+ Value referenceErrorPrototype;
+ Value syntaxErrorPrototype;
+ Value typeErrorPrototype;
+ Value uRIErrorPrototype;
+ Value variantPrototype;
+ Value sequencePrototype;
+
+ Value arrayBufferPrototype;
+ Value dataViewPrototype;
+ Value typedArrayPrototype[NTypedArrayTypes]; // TypedArray::NValues, avoid including the header here
+
InternalClassPool *classPool;
InternalClass *emptyClass;
InternalClass *executionContextClass;
- InternalClass *constructClass;
InternalClass *stringClass;
InternalClass *objectClass;
@@ -264,7 +284,7 @@ public:
ExecutionContext *popContext();
Heap::Object *newObject();
- Heap::Object *newObject(InternalClass *internalClass);
+ Heap::Object *newObject(InternalClass *internalClass, Object *prototype);
Heap::String *newString(const QString &s);
Heap::String *newIdentifier(const QString &text);
@@ -275,7 +295,7 @@ public:
Heap::ArrayObject *newArrayObject(int count = 0);
Heap::ArrayObject *newArrayObject(const QStringList &list);
- Heap::ArrayObject *newArrayObject(InternalClass *ic);
+ Heap::ArrayObject *newArrayObject(InternalClass *ic, Object *prototype);
Heap::DateObject *newDateObject(const ValueRef value);
Heap::DateObject *newDateObject(const QDateTime &dt);
diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp
index 7fe0574d6b..d08619f881 100644
--- a/src/qml/jsruntime/qv4errorobject.cpp
+++ b/src/qml/jsruntime/qv4errorobject.cpp
@@ -63,8 +63,8 @@
using namespace QV4;
-Heap::ErrorObject::ErrorObject(InternalClass *ic)
- : Heap::Object(ic)
+Heap::ErrorObject::ErrorObject(InternalClass *ic, QV4::Object *prototype)
+ : Heap::Object(ic, prototype)
{
Scope scope(ic->engine);
Scoped<QV4::ErrorObject> e(scope, this);
@@ -73,8 +73,8 @@ Heap::ErrorObject::ErrorObject(InternalClass *ic)
e->defineDefaultProperty(QStringLiteral("name"), s);
}
-Heap::ErrorObject::ErrorObject(InternalClass *ic, const ValueRef message, ErrorType t)
- : Heap::Object(ic)
+Heap::ErrorObject::ErrorObject(InternalClass *ic, QV4::Object *prototype, const ValueRef message, ErrorType t)
+ : Heap::Object(ic, prototype)
{
subtype = t;
@@ -95,8 +95,8 @@ Heap::ErrorObject::ErrorObject(InternalClass *ic, const ValueRef message, ErrorT
}
}
-Heap::ErrorObject::ErrorObject(InternalClass *ic, const QString &message, ErrorObject::ErrorType t)
- : Heap::Object(ic)
+Heap::ErrorObject::ErrorObject(InternalClass *ic, QV4::Object *prototype, const QString &message, ErrorObject::ErrorType t)
+ : Heap::Object(ic, prototype)
{
subtype = t;
@@ -117,8 +117,8 @@ Heap::ErrorObject::ErrorObject(InternalClass *ic, const QString &message, ErrorO
}
}
-Heap::ErrorObject::ErrorObject(InternalClass *ic, const QString &message, const QString &fileName, int line, int column, ErrorObject::ErrorType t)
- : Heap::Object(ic)
+Heap::ErrorObject::ErrorObject(InternalClass *ic, QV4::Object *prototype, const QString &message, const QString &fileName, int line, int column, ErrorObject::ErrorType t)
+ : Heap::Object(ic, prototype)
{
subtype = t;
@@ -183,57 +183,57 @@ DEFINE_OBJECT_VTABLE(ErrorObject);
DEFINE_OBJECT_VTABLE(SyntaxErrorObject);
Heap::SyntaxErrorObject::SyntaxErrorObject(ExecutionEngine *engine, const ValueRef msg)
- : Heap::ErrorObject(engine->syntaxErrorClass, msg, SyntaxError)
+ : Heap::ErrorObject(engine->syntaxErrorClass, engine->syntaxErrorPrototype.asObject(), msg, SyntaxError)
{
}
Heap::SyntaxErrorObject::SyntaxErrorObject(ExecutionEngine *engine, const QString &msg, const QString &fileName, int lineNumber, int columnNumber)
- : Heap::ErrorObject(engine->syntaxErrorClass, msg, fileName, lineNumber, columnNumber, SyntaxError)
+ : Heap::ErrorObject(engine->syntaxErrorClass, engine->syntaxErrorPrototype.asObject(), msg, fileName, lineNumber, columnNumber, SyntaxError)
{
}
Heap::EvalErrorObject::EvalErrorObject(ExecutionEngine *engine, const ValueRef message)
- : Heap::ErrorObject(engine->evalErrorClass, message, EvalError)
+ : Heap::ErrorObject(engine->evalErrorClass, engine->evalErrorPrototype.asObject(), message, EvalError)
{
}
Heap::RangeErrorObject::RangeErrorObject(ExecutionEngine *engine, const ValueRef message)
- : Heap::ErrorObject(engine->rangeErrorClass, message, RangeError)
+ : Heap::ErrorObject(engine->rangeErrorClass, engine->rangeErrorPrototype.asObject(), message, RangeError)
{
}
Heap::RangeErrorObject::RangeErrorObject(ExecutionEngine *engine, const QString &message)
- : Heap::ErrorObject(engine->rangeErrorClass, message, RangeError)
+ : Heap::ErrorObject(engine->rangeErrorClass, engine->rangeErrorPrototype.asObject(), message, RangeError)
{
}
Heap::ReferenceErrorObject::ReferenceErrorObject(ExecutionEngine *engine, const ValueRef message)
- : Heap::ErrorObject(engine->referenceErrorClass, message, ReferenceError)
+ : Heap::ErrorObject(engine->referenceErrorClass, engine->referenceErrorPrototype.asObject(), message, ReferenceError)
{
}
Heap::ReferenceErrorObject::ReferenceErrorObject(ExecutionEngine *engine, const QString &message)
- : Heap::ErrorObject(engine->referenceErrorClass, message, ReferenceError)
+ : Heap::ErrorObject(engine->referenceErrorClass, engine->referenceErrorPrototype.asObject(), message, ReferenceError)
{
}
Heap::ReferenceErrorObject::ReferenceErrorObject(ExecutionEngine *engine, const QString &msg, const QString &fileName, int lineNumber, int columnNumber)
- : Heap::ErrorObject(engine->referenceErrorClass, msg, fileName, lineNumber, columnNumber, ReferenceError)
+ : Heap::ErrorObject(engine->referenceErrorClass, engine->referenceErrorPrototype.asObject(), msg, fileName, lineNumber, columnNumber, ReferenceError)
{
}
Heap::TypeErrorObject::TypeErrorObject(ExecutionEngine *engine, const ValueRef message)
- : Heap::ErrorObject(engine->typeErrorClass, message, TypeError)
+ : Heap::ErrorObject(engine->typeErrorClass, engine->typeErrorPrototype.asObject(), message, TypeError)
{
}
Heap::TypeErrorObject::TypeErrorObject(ExecutionEngine *engine, const QString &message)
- : Heap::ErrorObject(engine->typeErrorClass, message, TypeError)
+ : Heap::ErrorObject(engine->typeErrorClass, engine->typeErrorPrototype.asObject(), message, TypeError)
{
}
Heap::URIErrorObject::URIErrorObject(ExecutionEngine *engine, const ValueRef message)
- : Heap::ErrorObject(engine->uriErrorClass, message, URIError)
+ : Heap::ErrorObject(engine->uriErrorClass, engine->uRIErrorPrototype.asObject(), message, URIError)
{
}
diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h
index 589d466429..71a811c189 100644
--- a/src/qml/jsruntime/qv4errorobject_p.h
+++ b/src/qml/jsruntime/qv4errorobject_p.h
@@ -55,10 +55,10 @@ struct ErrorObject : Object {
URIError
};
- ErrorObject(InternalClass *ic);
- ErrorObject(InternalClass *ic, const ValueRef message, ErrorType t = Error);
- ErrorObject(InternalClass *ic, const QString &message, ErrorType t = Error);
- ErrorObject(InternalClass *ic, const QString &message, const QString &fileName, int line, int column, ErrorType t = Error);
+ ErrorObject(InternalClass *ic, QV4::Object *prototype);
+ ErrorObject(InternalClass *ic, QV4::Object *prototype, const ValueRef message, ErrorType t = Error);
+ ErrorObject(InternalClass *ic, QV4::Object *prototype, const QString &message, ErrorType t = Error);
+ ErrorObject(InternalClass *ic, QV4::Object *prototype, const QString &message, const QString &fileName, int line, int column, ErrorType t = Error);
StackTrace stackTrace;
String *stack;
};
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index 22ed62cf18..42e0f5389d 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -63,7 +63,7 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(FunctionObject);
Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, QV4::String *name, bool createProto)
- : Heap::Object(scope->d()->engine->functionClass)
+ : Heap::Object(scope->d()->engine->functionClass, scope->d()->engine->functionPrototype.asObject())
, scope(scope->d())
{
Scope s(scope->engine());
@@ -72,7 +72,7 @@ Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, QV4::String *
}
Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, Function *function, bool createProto)
- : Heap::Object(scope->d()->engine->functionClass)
+ : Heap::Object(scope->d()->engine->functionClass, scope->d()->engine->functionPrototype.asObject())
, scope(scope->d())
{
Scope s(scope->engine());
@@ -82,7 +82,7 @@ Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, Function *fun
}
Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, const QString &name, bool createProto)
- : Heap::Object(scope->d()->engine->functionClass)
+ : Heap::Object(scope->d()->engine->functionClass, scope->d()->engine->functionPrototype.asObject())
, scope(scope->d())
{
Scope s(scope->engine());
@@ -92,7 +92,7 @@ Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, const QString
}
Heap::FunctionObject::FunctionObject(ExecutionContext *scope, const QString &name, bool createProto)
- : Heap::Object(scope->engine->functionClass)
+ : Heap::Object(scope->engine->functionClass, scope->engine->functionPrototype.asObject())
, scope(scope)
{
Scope s(scope->engine);
@@ -102,7 +102,7 @@ Heap::FunctionObject::FunctionObject(ExecutionContext *scope, const QString &nam
}
Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, const ReturnedValue name)
- : Heap::Object(scope->d()->engine->functionClass)
+ : Heap::Object(scope->d()->engine->functionClass, scope->d()->engine->functionPrototype.asObject())
, scope(scope->d())
{
Scope s(scope);
@@ -112,7 +112,7 @@ Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, const Returne
}
Heap::FunctionObject::FunctionObject(ExecutionContext *scope, const ReturnedValue name)
- : Heap::Object(scope->engine->functionClass)
+ : Heap::Object(scope->engine->functionClass, scope->engine->functionPrototype.asObject())
, scope(scope)
{
Scope s(scope->engine);
@@ -121,8 +121,8 @@ Heap::FunctionObject::FunctionObject(ExecutionContext *scope, const ReturnedValu
f->init(n.getPointer(), false);
}
-Heap::FunctionObject::FunctionObject(InternalClass *ic)
- : Heap::Object(ic)
+Heap::FunctionObject::FunctionObject(InternalClass *ic, QV4::Object *prototype)
+ : Heap::Object(ic, prototype)
, scope(ic->engine->rootContext()->d())
{
Scope scope(ic->engine);
@@ -148,7 +148,7 @@ void FunctionObject::init(String *n, bool createProto)
ensureMemberIndex(s.engine, Heap::FunctionObject::Index_Prototype);
if (createProto) {
- Scoped<Object> proto(s, scope()->engine->newObject(scope()->engine->protoClass));
+ Scoped<Object> proto(s, scope()->engine->newObject(s.engine->protoClass, s.engine->objectPrototype.asObject()));
proto->ensureMemberIndex(s.engine, Heap::FunctionObject::Index_ProtoConstructor);
proto->memberData()->data[Heap::FunctionObject::Index_ProtoConstructor] = this->asReturnedValue();
memberData()->data[Heap::FunctionObject::Index_Prototype] = proto.asReturnedValue();
@@ -268,8 +268,8 @@ ReturnedValue FunctionCtor::call(Managed *that, CallData *callData)
DEFINE_OBJECT_VTABLE(FunctionPrototype);
-Heap::FunctionPrototype::FunctionPrototype(InternalClass *ic)
- : Heap::FunctionObject(ic)
+Heap::FunctionPrototype::FunctionPrototype(InternalClass *ic, QV4::Object *prototype)
+ : Heap::FunctionObject(ic, prototype)
{
}
@@ -393,8 +393,9 @@ ReturnedValue ScriptFunction::construct(Managed *that, CallData *callData)
Scope scope(v4);
Scoped<ScriptFunction> f(scope, static_cast<ScriptFunction *>(that));
- InternalClass *ic = f->internalClassForConstructor();
- ScopedObject obj(scope, v4->newObject(ic));
+ InternalClass *ic = scope.engine->objectClass;
+ ScopedObject proto(scope, f->protoForConstructor());
+ ScopedObject obj(scope, v4->newObject(ic, proto));
ExecutionContext *context = v4->currentContext();
callData->thisObject = obj.asReturnedValue();
@@ -477,8 +478,9 @@ ReturnedValue SimpleScriptFunction::construct(Managed *that, CallData *callData)
Scope scope(v4);
Scoped<SimpleScriptFunction> f(scope, static_cast<SimpleScriptFunction *>(that));
- InternalClass *ic = f->internalClassForConstructor();
- callData->thisObject = v4->newObject(ic);
+ InternalClass *ic = scope.engine->objectClass;
+ ScopedObject proto(scope, f->protoForConstructor());
+ callData->thisObject = v4->newObject(ic, proto);
ExecutionContext *context = v4->currentContext();
ExecutionContextSaver ctxSaver(context);
@@ -542,18 +544,13 @@ ReturnedValue SimpleScriptFunction::call(Managed *that, CallData *callData)
return result.asReturnedValue();
}
-InternalClass *SimpleScriptFunction::internalClassForConstructor()
+Heap::Object *SimpleScriptFunction::protoForConstructor()
{
- ReturnedValue proto = protoProperty();
- InternalClass *classForConstructor;
- Scope scope(internalClass()->engine);
- ScopedObject p(scope, proto);
+ Scope scope(engine());
+ ScopedObject p(scope, protoProperty());
if (p)
- classForConstructor = internalClass()->engine->constructClass->changePrototype(p.getPointer());
- else
- classForConstructor = scope.engine->objectClass;
-
- return classForConstructor;
+ return p->d();
+ return scope.engine->objectPrototype.asObject()->d();
}
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index 711b16a498..5d2715fa2f 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -63,7 +63,7 @@ struct Q_QML_PRIVATE_EXPORT FunctionObject : Object {
FunctionObject(ExecutionContext *scope, const QString &name = QString(), bool createProto = false);
FunctionObject(QV4::ExecutionContext *scope, const ReturnedValue name);
FunctionObject(ExecutionContext *scope, const ReturnedValue name);
- FunctionObject(InternalClass *ic);
+ FunctionObject(InternalClass *ic, QV4::Object *prototype);
~FunctionObject();
unsigned int formalParameterCount() { return function ? function->compiledFunction->nFormals : 0; }
@@ -78,7 +78,7 @@ struct FunctionCtor : FunctionObject {
};
struct FunctionPrototype : FunctionObject {
- FunctionPrototype(InternalClass *ic);
+ FunctionPrototype(InternalClass *ic, QV4::Object *prototype);
};
struct Q_QML_EXPORT BuiltinFunction : FunctionObject {
@@ -213,7 +213,7 @@ struct SimpleScriptFunction: FunctionObject {
static ReturnedValue construct(Managed *, CallData *callData);
static ReturnedValue call(Managed *that, CallData *callData);
- InternalClass *internalClassForConstructor();
+ Heap::Object *protoForConstructor();
};
struct ScriptFunction: SimpleScriptFunction {
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp
index d3e6bdd57b..0f88dd4d5a 100644
--- a/src/qml/jsruntime/qv4internalclass.cpp
+++ b/src/qml/jsruntime/qv4internalclass.cpp
@@ -42,9 +42,9 @@ QT_BEGIN_NAMESPACE
uint QV4::qHash(const QV4::InternalClassTransition &t, uint)
{
- if (t.flags == QV4::InternalClassTransition::ProtoChange)
+ if (t.flags & QV4::InternalClassTransition::VTableChange)
// INT_MAX is prime, so this should give a decent distribution of keys
- return (uint)((quintptr)t.prototype * INT_MAX);
+ return (uint)((quintptr)t.vtable * INT_MAX);
return t.id->hashValue ^ t.flags;
}
@@ -120,7 +120,6 @@ uint PropertyHash::lookup(const Identifier *identifier) const
InternalClass::InternalClass(ExecutionEngine *engine)
: engine(engine)
- , prototype(0)
, vtable(&QV4::Managed::static_vtbl)
, m_sealed(0)
, m_frozen(0)
@@ -132,7 +131,6 @@ InternalClass::InternalClass(ExecutionEngine *engine)
InternalClass::InternalClass(const QV4::InternalClass &other)
: QQmlJS::Managed()
, engine(other.engine)
- , prototype(other.prototype)
, vtable(other.vtable)
, propertyTable(other.propertyTable)
, nameMap(other.nameMap)
@@ -180,7 +178,6 @@ InternalClass *InternalClass::changeMember(Identifier *identifier, PropertyAttri
// create a new class and add it to the tree
InternalClass *newClass = engine->emptyClass->changeVTable(vtable);
- newClass = newClass->changePrototype(prototype);
for (uint i = 0; i < size; ++i) {
if (i == idx) {
newClass = newClass->addMember(nameMap.at(i), data);
@@ -193,43 +190,9 @@ InternalClass *InternalClass::changeMember(Identifier *identifier, PropertyAttri
return newClass;
}
-InternalClass *InternalClass::create(ExecutionEngine *engine, const ManagedVTable *vtable, Object *proto)
+InternalClass *InternalClass::create(ExecutionEngine *engine, const ManagedVTable *vtable)
{
- InternalClass *c = engine->emptyClass->changeVTable(vtable);
- if (!proto)
- return c;
- return c->changePrototype(proto);
-}
-
-InternalClass *InternalClass::changePrototype(Object *proto)
-{
- if (prototype == proto)
- return this;
-
- Transition t;
- t.prototype = proto;
- t.flags = Transition::ProtoChange;
-
- QHash<Transition, InternalClass *>::const_iterator tit = transitions.constFind(t);
- if (tit != transitions.constEnd())
- return tit.value();
-
- // create a new class and add it to the tree
- InternalClass *newClass;
- if (!size) {
- newClass = engine->newClass(*this);
- newClass->prototype = proto;
- } else {
- newClass = engine->emptyClass->changeVTable(vtable);
- newClass = newClass->changePrototype(proto);
- for (uint i = 0; i < size; ++i) {
- if (!propertyData.at(i).isEmpty())
- newClass = newClass->addMember(nameMap.at(i), propertyData.at(i));
- }
- }
-
- transitions.insert(t, newClass);
- return newClass;
+ return engine->emptyClass->changeVTable(vtable);
}
InternalClass *InternalClass::changeVTable(const ManagedVTable *vt)
@@ -252,7 +215,6 @@ InternalClass *InternalClass::changeVTable(const ManagedVTable *vt)
newClass->vtable = vt;
} else {
newClass = engine->emptyClass->changeVTable(vt);
- newClass = newClass->changePrototype(prototype);
for (uint i = 0; i < size; ++i) {
if (!propertyData.at(i).isEmpty())
newClass = newClass->addMember(nameMap.at(i), propertyData.at(i));
@@ -340,7 +302,6 @@ void InternalClass::removeMember(Object *object, Identifier *id)
} else {
// create a new class and add it to the tree
InternalClass *newClass = oldClass->engine->emptyClass->changeVTable(oldClass->vtable);
- newClass = newClass->changePrototype(oldClass->prototype);
for (uint i = 0; i < oldClass->size; ++i) {
if (i == propIdx)
continue;
@@ -384,7 +345,6 @@ InternalClass *InternalClass::sealed()
m_sealed = engine->emptyClass;
m_sealed = m_sealed->changeVTable(vtable);
- m_sealed = m_sealed->changePrototype(prototype);
for (uint i = 0; i < size; ++i) {
PropertyAttributes attrs = propertyData.at(i);
if (attrs.isEmpty())
@@ -404,7 +364,6 @@ InternalClass *InternalClass::frozen()
m_frozen = engine->emptyClass;
m_frozen = m_frozen->changeVTable(vtable);
- m_frozen = m_frozen->changePrototype(prototype);
for (uint i = 0; i < size; ++i) {
PropertyAttributes attrs = propertyData.at(i);
if (attrs.isEmpty())
@@ -441,24 +400,9 @@ void InternalClass::destroy()
}
}
-struct InternalClassPoolVisitor
-{
- ExecutionEngine *engine;
- void operator()(InternalClass *klass)
- {
- // all prototype changes are done on the empty class
- Q_ASSERT(!klass->prototype || klass != engine->emptyClass);
-
- if (klass->prototype)
- klass->prototype->mark(engine);
- }
-};
-
void InternalClassPool::markObjects(ExecutionEngine *engine)
{
- InternalClassPoolVisitor v;
- v.engine = engine;
- visitManagedPool<InternalClass, InternalClassPoolVisitor>(v);
+ Q_UNUSED(engine);
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4internalclass_p.h b/src/qml/jsruntime/qv4internalclass_p.h
index 14dbbe713f..4367f6576d 100644
--- a/src/qml/jsruntime/qv4internalclass_p.h
+++ b/src/qml/jsruntime/qv4internalclass_p.h
@@ -191,14 +191,12 @@ struct InternalClassTransition
{
union {
Identifier *id;
- Object *prototype;
const ManagedVTable *vtable;
};
int flags;
enum {
// range 0-0xff is reserved for attribute changes
- ProtoChange = 0x100,
- VTableChange = 0x200
+ VTableChange = 0x100
};
bool operator==(const InternalClassTransition &other) const
@@ -208,7 +206,6 @@ uint qHash(const QV4::InternalClassTransition &t, uint = 0);
struct InternalClass : public QQmlJS::Managed {
ExecutionEngine *engine;
- Object *prototype;
const ManagedVTable *vtable;
PropertyHash propertyTable; // id to valueIndex
@@ -223,8 +220,7 @@ struct InternalClass : public QQmlJS::Managed {
uint size;
- static InternalClass *create(ExecutionEngine *engine, const ManagedVTable *vtable, Object *proto);
- InternalClass *changePrototype(Object *proto);
+ static InternalClass *create(ExecutionEngine *engine, const ManagedVTable *vtable);
InternalClass *changeVTable(const ManagedVTable *vt);
static void addMember(Object *object, String *string, PropertyAttributes data, uint *index);
InternalClass *addMember(String *string, PropertyAttributes data, uint *index = 0);
diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp
index 76bc757a8c..c4a8ac13b9 100644
--- a/src/qml/jsruntime/qv4jsonobject.cpp
+++ b/src/qml/jsruntime/qv4jsonobject.cpp
@@ -877,10 +877,10 @@ QString Stringify::JA(ArrayObject *a)
}
-Heap::JsonObject::JsonObject(InternalClass *ic)
- : Heap::Object(ic)
+Heap::JsonObject::JsonObject(ExecutionEngine *e)
+ : Heap::Object(QV4::InternalClass::create(e, QV4::JsonObject::staticVTable()), e->objectPrototype.asObject())
{
- Scope scope(ic->engine);
+ Scope scope(e);
ScopedObject o(scope, this);
o->defineDefaultProperty(QStringLiteral("parse"), QV4::JsonObject::method_parse, 2);
diff --git a/src/qml/jsruntime/qv4jsonobject_p.h b/src/qml/jsruntime/qv4jsonobject_p.h
index e1202095a9..4004a06dec 100644
--- a/src/qml/jsruntime/qv4jsonobject_p.h
+++ b/src/qml/jsruntime/qv4jsonobject_p.h
@@ -45,7 +45,7 @@ namespace QV4 {
namespace Heap {
struct JsonObject : Object {
- JsonObject(InternalClass *ic);
+ JsonObject(ExecutionEngine *e);
};
}
diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp
index e6f997d5df..ebdc7be200 100644
--- a/src/qml/jsruntime/qv4lookup.cpp
+++ b/src/qml/jsruntime/qv4lookup.cpp
@@ -243,11 +243,11 @@ ReturnedValue Lookup::getterGeneric(Lookup *l, ExecutionEngine *engine, const Va
case Value::Null_Type:
return engine->throwTypeError();
case Value::Boolean_Type:
- proto = engine->booleanClass->prototype;
+ proto = engine->booleanPrototype.asObject();
break;
case Value::Managed_Type: {
Q_ASSERT(object->isString());
- proto = engine->stringObjectClass->prototype;
+ proto = engine->stringPrototype.asObject();
Scope scope(engine);
ScopedString name(scope, engine->currentContext()->d()->compilationUnit->runtimeStrings[l->nameIndex]);
if (name->equals(engine->id_length.getPointer())) {
@@ -259,7 +259,7 @@ ReturnedValue Lookup::getterGeneric(Lookup *l, ExecutionEngine *engine, const Va
}
case Value::Integer_Type:
default: // Number
- proto = engine->numberClass->prototype;
+ proto = engine->numberPrototype.asObject();
}
PropertyAttributes attrs;
diff --git a/src/qml/jsruntime/qv4mathobject.cpp b/src/qml/jsruntime/qv4mathobject.cpp
index 65302cd804..222a6fd97c 100644
--- a/src/qml/jsruntime/qv4mathobject.cpp
+++ b/src/qml/jsruntime/qv4mathobject.cpp
@@ -47,10 +47,10 @@ DEFINE_OBJECT_VTABLE(MathObject);
static const double qt_PI = 2.0 * ::asin(1.0);
-Heap::MathObject::MathObject(InternalClass *ic)
- : Heap::Object(ic)
+Heap::MathObject::MathObject(ExecutionEngine *e)
+ : Heap::Object(QV4::InternalClass::create(e, QV4::MathObject::staticVTable()), e->objectPrototype.asObject())
{
- Scope scope(ic->engine);
+ Scope scope(e);
ScopedObject m(scope, this);
m->defineReadonlyProperty(QStringLiteral("E"), Primitive::fromDouble(::exp(1.0)));
diff --git a/src/qml/jsruntime/qv4mathobject_p.h b/src/qml/jsruntime/qv4mathobject_p.h
index 1ff5e5a081..feff968a17 100644
--- a/src/qml/jsruntime/qv4mathobject_p.h
+++ b/src/qml/jsruntime/qv4mathobject_p.h
@@ -42,7 +42,7 @@ namespace QV4 {
namespace Heap {
struct MathObject : Object {
- MathObject(InternalClass *ic);
+ MathObject(ExecutionEngine *e);
};
}
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index a9ce9b42f2..70152274e4 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -50,8 +50,9 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(Object);
-Heap::Object::Object(InternalClass *internalClass)
- : Heap::Base(internalClass)
+Heap::Object::Object(InternalClass *internalClass, QV4::Object *prototype)
+ : Heap::Base(internalClass),
+ prototype(prototype->d())
{
if (internalClass->size) {
Scope scope(internalClass->engine);
@@ -62,13 +63,13 @@ Heap::Object::Object(InternalClass *internalClass)
bool Object::setPrototype(Object *proto)
{
- Object *pp = proto;
+ Heap::Object *pp = proto->d();
while (pp) {
- if (pp == this)
+ if (pp == d())
return false;
- pp = pp->prototype();
+ pp = pp->prototype;
}
- setInternalClass(internalClass()->changePrototype(proto));
+ d()->prototype = proto->d();
return true;
}
@@ -187,6 +188,8 @@ void Object::markObjects(Heap::Base *that, ExecutionEngine *e)
o->memberData->mark(e);
if (o->arrayData)
o->arrayData->mark(e);
+ if (o->prototype)
+ o->prototype->mark(e);
}
void Object::ensureMemberIndex(uint idx)
@@ -1135,7 +1138,7 @@ void Object::initSparseArray()
DEFINE_OBJECT_VTABLE(ArrayObject);
Heap::ArrayObject::ArrayObject(ExecutionEngine *engine, const QStringList &list)
- : Heap::Object(engine->arrayClass)
+ : Heap::Object(engine->arrayClass, engine->arrayPrototype.asObject())
{
init();
Scope scope(engine);
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 379ff2fde6..fed05893ca 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -45,47 +45,17 @@ namespace Heap {
struct Object : Base {
Object(ExecutionEngine *engine)
- : Base(engine->objectClass)
+ : Base(engine->objectClass),
+ prototype(static_cast<Object *>(engine->objectPrototype.m))
{
}
- Object(InternalClass *internal = 0);
+ Object(InternalClass *internal, QV4::Object *prototype);
+ Heap::Object *prototype;
MemberData *memberData;
ArrayData *arrayData;
};
-struct BooleanObject : Object {
- BooleanObject(ExecutionEngine *engine, const ValueRef val)
- : Object(engine->booleanClass)
- {
- value = val;
- }
- inline BooleanObject(InternalClass *ic);
- Value value;
-};
-
-struct NumberObject : Object {
- NumberObject(ExecutionEngine *engine, const ValueRef val)
- : Object(engine->numberClass) {
- value = val;
- }
- inline NumberObject(InternalClass *ic);
- Value value;
-};
-
-struct ArrayObject : Object {
- enum {
- LengthPropertyIndex = 0
- };
-
- ArrayObject(ExecutionEngine *engine) : Heap::Object(engine->arrayClass) { init(); }
- ArrayObject(ExecutionEngine *engine, const QStringList &list);
- ArrayObject(InternalClass *ic) : Heap::Object(ic) { init(); }
- void init()
- { memberData->data[LengthPropertyIndex] = Primitive::fromInt32(0); }
-};
-
-
}
struct Q_QML_EXPORT Object: Managed {
@@ -105,7 +75,8 @@ struct Q_QML_EXPORT Object: Managed {
Property *propertyAt(uint index) { return reinterpret_cast<Property *>(memberData()->data + index); }
const ObjectVTable *vtable() const { return reinterpret_cast<const ObjectVTable *>(internalClass()->vtable); }
- Object *prototype() const { return internalClass()->prototype; }
+ // ### GC
+ Object *prototype() const { return reinterpret_cast<Object *>(d()->prototype); }
bool setPrototype(Object *proto);
Property *__getOwnProperty__(String *name, PropertyAttributes *attrs = 0);
@@ -294,6 +265,56 @@ private:
friend struct ObjectPrototype;
};
+namespace Heap {
+
+struct BooleanObject : Object {
+ BooleanObject(InternalClass *ic, QV4::Object *prototype)
+ : Object(ic, prototype)
+ {
+ value = Encode((bool)false);
+ }
+
+ BooleanObject(ExecutionEngine *engine, const ValueRef val)
+ : Object(engine->booleanClass, engine->booleanPrototype.asObject())
+ {
+ value = val;
+ }
+ Value value;
+};
+
+struct NumberObject : Object {
+ NumberObject(InternalClass *ic, QV4::Object *prototype)
+ : Object(ic, prototype)
+ {
+ value = Encode((int)0);
+ }
+
+ NumberObject(ExecutionEngine *engine, const ValueRef val)
+ : Object(engine->numberClass, engine->numberPrototype.asObject())
+ {
+ value = val;
+ }
+ Value value;
+};
+
+struct ArrayObject : Object {
+ enum {
+ LengthPropertyIndex = 0
+ };
+
+ ArrayObject(ExecutionEngine *engine)
+ : Heap::Object(engine->arrayClass, engine->arrayPrototype.asObject())
+ { init(); }
+ ArrayObject(ExecutionEngine *engine, const QStringList &list);
+ ArrayObject(InternalClass *ic, QV4::Object *prototype)
+ : Heap::Object(ic, prototype)
+ { init(); }
+ void init()
+ { memberData->data[LengthPropertyIndex] = Primitive::fromInt32(0); }
+};
+
+}
+
struct BooleanObject: Object {
V4_OBJECT2(BooleanObject, Object)
Q_MANAGED_TYPE(BooleanObject)
@@ -302,13 +323,6 @@ struct BooleanObject: Object {
};
-Heap::BooleanObject::BooleanObject(InternalClass *ic)
- : Heap::Object(ic)
-{
- Q_ASSERT(internalClass->vtable == QV4::BooleanObject::staticVTable());
- value = Encode(false);
-}
-
struct NumberObject: Object {
V4_OBJECT2(NumberObject, Object)
Q_MANAGED_TYPE(NumberObject)
@@ -316,12 +330,6 @@ struct NumberObject: Object {
Value value() const { return d()->value; }
};
-Heap::NumberObject::NumberObject(InternalClass *ic)
- : Heap::Object(ic) {
- Q_ASSERT(internalClass->vtable == QV4::NumberObject::staticVTable());
- value = Encode((int)0);
-}
-
struct ArrayObject: Object {
V4_OBJECT2(ArrayObject, Object)
Q_MANAGED_TYPE(ArrayObject)
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 3744d5617c..23d5115c6d 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -242,8 +242,8 @@ Heap::QObjectWrapper::QObjectWrapper(ExecutionEngine *engine, QObject *object)
void QObjectWrapper::initializeBindings(ExecutionEngine *engine)
{
- engine->functionClass->prototype->defineDefaultProperty(QStringLiteral("connect"), method_connect);
- engine->functionClass->prototype->defineDefaultProperty(QStringLiteral("disconnect"), method_disconnect);
+ engine->functionPrototype.asObject()->defineDefaultProperty(QStringLiteral("connect"), method_connect);
+ engine->functionPrototype.asObject()->defineDefaultProperty(QStringLiteral("disconnect"), method_disconnect);
}
QQmlPropertyData *QObjectWrapper::findProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local) const
@@ -345,8 +345,8 @@ ReturnedValue QObjectWrapper::getProperty(QObject *object, ExecutionContext *ctx
QV4::ScopedString connect(scope, ctx->d()->engine->newIdentifier(QStringLiteral("connect")));
QV4::ScopedString disconnect(scope, ctx->d()->engine->newIdentifier(QStringLiteral("disconnect")));
- handler->put(connect.getPointer(), QV4::ScopedValue(scope, ctx->d()->engine->functionClass->prototype->get(connect.getPointer())));
- handler->put(disconnect.getPointer(), QV4::ScopedValue(scope, ctx->d()->engine->functionClass->prototype->get(disconnect.getPointer())));
+ handler->put(connect.getPointer(), QV4::ScopedValue(scope, ctx->d()->engine->functionPrototype.asObject()->get(connect.getPointer())));
+ handler->put(disconnect.getPointer(), QV4::ScopedValue(scope, ctx->d()->engine->functionPrototype.asObject()->get(disconnect.getPointer())));
return handler.asReturnedValue();
} else {
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index 7758cd8483..7191a16235 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -65,8 +65,8 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(RegExpObject);
DEFINE_OBJECT_VTABLE(RegExpPrototype);
-Heap::RegExpObject::RegExpObject(InternalClass *ic)
- : Heap::Object(ic)
+Heap::RegExpObject::RegExpObject(InternalClass *ic, QV4::Object *prototype)
+ : Heap::Object(ic, prototype)
{
setVTable(QV4::RegExpObject::staticVTable());
@@ -78,7 +78,7 @@ Heap::RegExpObject::RegExpObject(InternalClass *ic)
}
Heap::RegExpObject::RegExpObject(QV4::ExecutionEngine *engine, QV4::RegExp *value, bool global)
- : Heap::Object(engine->regExpClass)
+ : Heap::Object(engine->regExpClass, engine->regExpPrototype.asObject())
, value(value->d())
, global(global)
{
@@ -93,7 +93,7 @@ Heap::RegExpObject::RegExpObject(QV4::ExecutionEngine *engine, QV4::RegExp *valu
// The conversion is not 100% exact since ECMA regexp and QRegExp
// have different semantics/flags, but we try to do our best.
Heap::RegExpObject::RegExpObject(QV4::ExecutionEngine *engine, const QRegExp &re)
- : Heap::Object(engine->regExpClass)
+ : Heap::Object(engine->regExpClass, engine->regExpPrototype.asObject())
{
setVTable(QV4::RegExpObject::staticVTable());
@@ -380,7 +380,7 @@ ReturnedValue RegExpPrototype::method_exec(CallContext *ctx)
}
// fill in result data
- Scoped<ArrayObject> array(scope, ctx->d()->engine->newArrayObject(ctx->d()->engine->regExpExecArrayClass));
+ Scoped<ArrayObject> array(scope, scope.engine->newArrayObject(scope.engine->regExpExecArrayClass, scope.engine->arrayPrototype.asObject()));
int len = r->value()->captureCount();
array->arrayReserve(len);
ScopedValue v(scope);
diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h
index febd0dd7b2..1320527fe1 100644
--- a/src/qml/jsruntime/qv4regexpobject_p.h
+++ b/src/qml/jsruntime/qv4regexpobject_p.h
@@ -57,9 +57,9 @@ namespace QV4 {
namespace Heap {
struct RegExpObject : Object {
+ RegExpObject(InternalClass *ic, QV4::Object *prototype);
RegExpObject(QV4::ExecutionEngine *engine, QV4::RegExp *value, bool global);
RegExpObject(QV4::ExecutionEngine *engine, const QRegExp &re);
- RegExpObject(InternalClass *ic);
RegExp *value;
bool global;
@@ -76,7 +76,7 @@ struct RegExpCtor : FunctionObject {
struct RegExpPrototype : RegExpObject
{
- inline RegExpPrototype(InternalClass *ic);
+ inline RegExpPrototype(ExecutionEngine *e);
};
}
@@ -145,10 +145,9 @@ struct RegExpPrototype: RegExpObject
static ReturnedValue method_get_rightContext(CallContext *ctx);
};
-inline Heap::RegExpPrototype::RegExpPrototype(InternalClass *ic)
- : RegExpObject(ic)
+inline Heap::RegExpPrototype::RegExpPrototype(ExecutionEngine *e)
+ : RegExpObject(InternalClass::create(e, QV4::RegExpPrototype::staticVTable()), e->objectPrototype.asObject())
{
- setVTable(QV4::RegExpPrototype::staticVTable());
}
}
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 147e81b627..5d9eb6d55e 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -1187,7 +1187,7 @@ ReturnedValue Runtime::objectLiteral(ExecutionEngine *engine, const QV4::Value *
{
Scope scope(engine);
QV4::InternalClass *klass = engine->currentContext()->d()->compilationUnit->runtimeClasses[classId];
- Scoped<Object> o(scope, engine->newObject(klass));
+ Scoped<Object> o(scope, engine->newObject(klass, engine->objectPrototype.asObject()));
{
bool needSparseArray = arrayGetterSetterCountAndFlags >> 30;
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp
index 20dad8a6d6..5e45f65ae7 100644
--- a/src/qml/jsruntime/qv4sequenceobject.cpp
+++ b/src/qml/jsruntime/qv4sequenceobject.cpp
@@ -500,7 +500,7 @@ public:
template <typename Container>
Heap::QQmlSequence<Container>::QQmlSequence(QV4::ExecutionEngine *engine, const Container &container)
- : Heap::Object(InternalClass::create(engine, QV4::QQmlSequence<Container>::staticVTable(), engine->sequencePrototype.asObject()))
+ : Heap::Object(InternalClass::create(engine, QV4::QQmlSequence<Container>::staticVTable()), engine->sequencePrototype.asObject())
, container(container)
, propertyIndex(-1)
, isReference(false)
@@ -513,7 +513,7 @@ Heap::QQmlSequence<Container>::QQmlSequence(QV4::ExecutionEngine *engine, const
template <typename Container>
Heap::QQmlSequence<Container>::QQmlSequence(QV4::ExecutionEngine *engine, QObject *object, int propertyIndex)
- : Heap::Object(InternalClass::create(engine, QV4::QQmlSequence<Container>::staticVTable(), engine->sequencePrototype.asObject()))
+ : Heap::Object(InternalClass::create(engine, QV4::QQmlSequence<Container>::staticVTable()), engine->sequencePrototype.asObject())
, object(object)
, propertyIndex(propertyIndex)
, isReference(true)
diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp
index 5c020ddc8e..e6a7a2f7a7 100644
--- a/src/qml/jsruntime/qv4string.cpp
+++ b/src/qml/jsruntime/qv4string.cpp
@@ -138,7 +138,7 @@ ReturnedValue String::get(Managed *m, String *name, bool *hasProperty)
return Primitive::fromInt32(that->d()->text->size).asReturnedValue();
}
PropertyAttributes attrs;
- Property *pd = v4->stringObjectClass->prototype->__getPropertyDescriptor__(name, &attrs);
+ Property *pd = v4->stringPrototype.asObject()->__getPropertyDescriptor__(name, &attrs);
if (!pd || attrs.isGeneric()) {
if (hasProperty)
*hasProperty = false;
@@ -146,7 +146,7 @@ ReturnedValue String::get(Managed *m, String *name, bool *hasProperty)
}
if (hasProperty)
*hasProperty = true;
- return v4->stringObjectClass->prototype->getValue(that, pd, attrs);
+ return v4->stringPrototype.asObject()->getValue(that, pd, attrs);
}
ReturnedValue String::getIndexed(Managed *m, uint index, bool *hasProperty)
@@ -161,7 +161,7 @@ ReturnedValue String::getIndexed(Managed *m, uint index, bool *hasProperty)
return Encode(engine->newString(that->toQString().mid(index, 1)));
}
PropertyAttributes attrs;
- Property *pd = engine->stringObjectClass->prototype->__getPropertyDescriptor__(index, &attrs);
+ Property *pd = engine->stringPrototype.asObject()->__getPropertyDescriptor__(index, &attrs);
if (!pd || attrs.isGeneric()) {
if (hasProperty)
*hasProperty = false;
@@ -169,7 +169,7 @@ ReturnedValue String::getIndexed(Managed *m, uint index, bool *hasProperty)
}
if (hasProperty)
*hasProperty = true;
- return engine->stringObjectClass->prototype->getValue(that, pd, attrs);
+ return engine->stringPrototype.asObject()->getValue(that, pd, attrs);
}
void String::put(Managed *m, String *name, const ValueRef value)
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index ed29c84ff9..8c864803af 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -70,8 +70,8 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(StringObject);
-Heap::StringObject::StringObject(InternalClass *ic)
- : Heap::Object(ic)
+Heap::StringObject::StringObject(InternalClass *ic, QV4::Object *prototype)
+ : Heap::Object(ic, prototype)
{
Q_ASSERT(internalClass->vtable == QV4::StringObject::staticVTable());
value = ic->engine->newString(QStringLiteral(""))->asReturnedValue();
@@ -83,7 +83,7 @@ Heap::StringObject::StringObject(InternalClass *ic)
}
Heap::StringObject::StringObject(ExecutionEngine *engine, const ValueRef val)
- : Heap::Object(engine->stringObjectClass)
+ : Heap::Object(engine->stringObjectClass, engine->stringPrototype.asObject())
{
value = val;
Q_ASSERT(value.isString());
@@ -386,8 +386,8 @@ ReturnedValue StringPrototype::method_match(CallContext *context)
bool global = rx->global();
// ### use the standard builtin function, not the one that might be redefined in the proto
- ScopedString execString(scope, context->d()->engine->newString(QStringLiteral("exec")));
- Scoped<FunctionObject> exec(scope, context->d()->engine->regExpClass->prototype->get(execString.getPointer()));
+ ScopedString execString(scope, scope.engine->newString(QStringLiteral("exec")));
+ Scoped<FunctionObject> exec(scope, scope.engine->regExpPrototype.asObject()->get(execString.getPointer()));
ScopedCallData callData(scope, 1);
callData->thisObject = rx;
diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h
index b82cf08a8b..031b09c093 100644
--- a/src/qml/jsruntime/qv4stringobject_p.h
+++ b/src/qml/jsruntime/qv4stringobject_p.h
@@ -44,8 +44,8 @@ namespace QV4 {
namespace Heap {
struct StringObject : Object {
+ StringObject(InternalClass *ic, QV4::Object *prototype);
StringObject(ExecutionEngine *engine, const ValueRef value);
- StringObject(InternalClass *ic);
Value value;
// ### get rid of tmpProperty
mutable Property tmpProperty;
diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp
index 3149e0485a..cc5ea2aad5 100644
--- a/src/qml/jsruntime/qv4typedarray.cpp
+++ b/src/qml/jsruntime/qv4typedarray.cpp
@@ -334,7 +334,7 @@ ReturnedValue TypedArrayCtor::call(Managed *that, CallData *callData)
}
Heap::TypedArray::TypedArray(ExecutionEngine *e, Type t)
- : Heap::Object(e->typedArrayClasses[t]),
+ : Heap::Object(e->typedArrayClasses[t], e->typedArrayPrototype[t].asObject()),
type(operations + t)
{
}
diff --git a/src/qml/jsruntime/qv4variantobject.cpp b/src/qml/jsruntime/qv4variantobject.cpp
index fe23b8aa15..3e659eec5a 100644
--- a/src/qml/jsruntime/qv4variantobject.cpp
+++ b/src/qml/jsruntime/qv4variantobject.cpp
@@ -43,13 +43,8 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(VariantObject);
-Heap::VariantObject::VariantObject(InternalClass *ic)
- : Heap::Object(ic)
-{
-}
-
Heap::VariantObject::VariantObject(QV4::ExecutionEngine *engine, const QVariant &value)
- : Heap::Object(engine->variantClass)
+ : Heap::Object(engine->variantClass, engine->variantPrototype.asObject())
{
data = value;
if (isScarce())
diff --git a/src/qml/jsruntime/qv4variantobject_p.h b/src/qml/jsruntime/qv4variantobject_p.h
index c231db44a6..14ef167e6f 100644
--- a/src/qml/jsruntime/qv4variantobject_p.h
+++ b/src/qml/jsruntime/qv4variantobject_p.h
@@ -60,7 +60,9 @@ namespace Heap {
struct VariantObject : Object, public ExecutionEngine::ScarceResourceData
{
- VariantObject(InternalClass *ic);
+ VariantObject(InternalClass *ic, QV4::Object *prototype)
+ : Object(ic, prototype)
+ {}
VariantObject(QV4::ExecutionEngine *engine, const QVariant &value);
~VariantObject() {
if (isScarce())
diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp
index bed6c4c57e..592318e561 100644
--- a/src/qml/qml/qqmllocale.cpp
+++ b/src/qml/qml/qqmllocale.cpp
@@ -65,9 +65,9 @@ static bool isLocaleObject(const QV4::ValueRef val)
void QQmlDateExtension::registerExtension(QV4::ExecutionEngine *engine)
{
- engine->dateClass->prototype->defineDefaultProperty(QStringLiteral("toLocaleString"), method_toLocaleString);
- engine->dateClass->prototype->defineDefaultProperty(QStringLiteral("toLocaleTimeString"), method_toLocaleTimeString);
- engine->dateClass->prototype->defineDefaultProperty(QStringLiteral("toLocaleDateString"), method_toLocaleDateString);
+ engine->datePrototype.asObject()->defineDefaultProperty(QStringLiteral("toLocaleString"), method_toLocaleString);
+ engine->datePrototype.asObject()->defineDefaultProperty(QStringLiteral("toLocaleTimeString"), method_toLocaleTimeString);
+ engine->datePrototype.asObject()->defineDefaultProperty(QStringLiteral("toLocaleDateString"), method_toLocaleDateString);
engine->dateCtor.objectValue()->defineDefaultProperty(QStringLiteral("fromLocaleString"), method_fromLocaleString);
engine->dateCtor.objectValue()->defineDefaultProperty(QStringLiteral("fromLocaleTimeString"), method_fromLocaleTimeString);
engine->dateCtor.objectValue()->defineDefaultProperty(QStringLiteral("fromLocaleDateString"), method_fromLocaleDateString);
@@ -347,8 +347,8 @@ QV4::ReturnedValue QQmlDateExtension::method_timeZoneUpdated(QV4::CallContext *c
void QQmlNumberExtension::registerExtension(QV4::ExecutionEngine *engine)
{
- engine->numberClass->prototype->defineDefaultProperty(QStringLiteral("toLocaleString"), method_toLocaleString);
- engine->numberClass->prototype->defineDefaultProperty(QStringLiteral("toLocaleCurrencyString"), method_toLocaleCurrencyString);
+ engine->numberPrototype.asObject()->defineDefaultProperty(QStringLiteral("toLocaleString"), method_toLocaleString);
+ engine->numberPrototype.asObject()->defineDefaultProperty(QStringLiteral("toLocaleCurrencyString"), method_toLocaleCurrencyString);
engine->numberCtor.objectValue()->defineDefaultProperty(QStringLiteral("fromLocaleString"), method_fromLocaleString);
}
@@ -817,7 +817,7 @@ QV4::ReturnedValue QQmlLocale::wrap(QV8Engine *engine, const QLocale &locale)
void QQmlLocale::registerStringLocaleCompare(QV4::ExecutionEngine *engine)
{
- engine->stringObjectClass->prototype->defineDefaultProperty(QStringLiteral("localeCompare"), method_localeCompare);
+ engine->stringPrototype.asObject()->defineDefaultProperty(QStringLiteral("localeCompare"), method_localeCompare);
}
QV4::ReturnedValue QQmlLocale::method_localeCompare(QV4::CallContext *ctx)
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index 346e745234..fc6eb50ed6 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -154,7 +154,7 @@ ReturnedValue QmlValueTypeWrapper::create(QV8Engine *v8, QObject *object, int pr
initProto(v4);
Scoped<QmlValueTypeReference> r(scope, v4->memoryManager->alloc<QmlValueTypeReference>(v8));
- r->d()->internalClass = r->d()->internalClass->changePrototype(v4->qmlExtensions()->valueTypeWrapperPrototype);
+ r->setPrototype(v4->qmlExtensions()->valueTypeWrapperPrototype->asObject());
r->d()->type = type; r->d()->object = object; r->d()->property = property;
return r->asReturnedValue();
}
@@ -166,7 +166,7 @@ ReturnedValue QmlValueTypeWrapper::create(QV8Engine *v8, const QVariant &value,
initProto(v4);
Scoped<QmlValueTypeCopy> r(scope, v4->memoryManager->alloc<QmlValueTypeCopy>(v8));
- r->d()->internalClass = r->d()->internalClass->changePrototype(v4->qmlExtensions()->valueTypeWrapperPrototype);
+ r->setPrototype(v4->qmlExtensions()->valueTypeWrapperPrototype->asObject());
r->d()->type = type; r->d()->value = value;
return r->asReturnedValue();
}
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index cdc76e5c97..c6e97445c0 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -1587,7 +1587,7 @@ void QV4::GlobalExtensions::init(QQmlEngine *qmlEngine, Object *globalObject)
globalObject->defineDefaultProperty(QStringLiteral("Qt"), qt);
// string prototype extension
- v4->stringObjectClass->prototype->defineDefaultProperty(QStringLiteral("arg"), method_string_arg);
+ v4->stringPrototype.asObject()->defineDefaultProperty(QStringLiteral("arg"), method_string_arg);
}