Make Managed inherit Value
This completes the first milestone towards being able to move objects across the GC heap. Change-Id: I8e6ce90254ea767188a31f0dc85b133534c87eb0 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
This commit is contained in:
parent
74c658bb63
commit
e7b66a6058
|
@ -302,7 +302,7 @@ QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, in
|
|||
QV4::ExecutionEngine *v4 = d->m_v4Engine;
|
||||
QV4::Scope scope(v4);
|
||||
QV4::ScopedContext ctx(scope, v4->currentContext());
|
||||
if (ctx != v4->rootContext())
|
||||
if (ctx->d() != v4->rootContext())
|
||||
ctx = v4->pushGlobalContext();
|
||||
QV4::ScopedValue result(scope);
|
||||
|
||||
|
@ -314,7 +314,7 @@ QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, in
|
|||
result = script.run();
|
||||
if (scope.engine->hasException)
|
||||
result = v4->catchException();
|
||||
if (ctx != v4->rootContext())
|
||||
if (ctx->d() != v4->rootContext())
|
||||
v4->popContext();
|
||||
return new QJSValuePrivate(v4, result);
|
||||
}
|
||||
|
|
|
@ -48,8 +48,8 @@ namespace QV4 {
|
|||
static const QV4::ArrayVTable static_vtbl; \
|
||||
static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl.managedVTable; } \
|
||||
V4_MANAGED_SIZE_TEST \
|
||||
const QV4::Heap::Data *d() const { return &static_cast<const QV4::Heap::Data &>(Managed::data); } \
|
||||
QV4::Heap::Data *d() { return &static_cast<QV4::Heap::Data &>(Managed::data); }
|
||||
const QV4::Heap::Data *d() const { return static_cast<const QV4::Heap::Data *>(m); } \
|
||||
QV4::Heap::Data *d() { return static_cast<QV4::Heap::Data *>(m); }
|
||||
|
||||
|
||||
struct ArrayData;
|
||||
|
|
|
@ -288,7 +288,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
|
|||
Q_ASSERT(argumentsObjectClass->vtable == ArgumentsObject::staticVTable());
|
||||
Q_ASSERT(strictArgumentsObjectClass->vtable == ArgumentsObject::staticVTable());
|
||||
|
||||
m_globalObject = ScopedObject(scope, newObject()).getPointer();
|
||||
m_globalObject = newObject();
|
||||
Q_ASSERT(globalObject()->internalClass()->vtable);
|
||||
initRootContext();
|
||||
|
||||
|
|
|
@ -110,8 +110,8 @@ public:
|
|||
QV4::Debugging::Debugger *debugger;
|
||||
QV4::Profiling::Profiler *profiler;
|
||||
|
||||
Object *m_globalObject;
|
||||
Object *globalObject() { return m_globalObject; }
|
||||
Value m_globalObject;
|
||||
Object *globalObject() { return reinterpret_cast<Object *>(&m_globalObject); }
|
||||
|
||||
Function *globalCode;
|
||||
|
||||
|
|
|
@ -586,8 +586,9 @@ ReturnedValue BuiltinFunction::call(Managed *that, CallData *callData)
|
|||
ctx.strictMode = f->scope()->strictMode; // ### needed? scope or parent context?
|
||||
ctx.callData = callData;
|
||||
Q_ASSERT(v4->currentContext() == &ctx);
|
||||
Scoped<CallContext> sctx(scope, &ctx);
|
||||
|
||||
return f->d()->code(reinterpret_cast<CallContext *>(&ctx));
|
||||
return f->d()->code(sctx);
|
||||
}
|
||||
|
||||
ReturnedValue IndexedBuiltinFunction::call(Managed *that, CallData *callData)
|
||||
|
@ -605,8 +606,9 @@ ReturnedValue IndexedBuiltinFunction::call(Managed *that, CallData *callData)
|
|||
ctx.strictMode = f->scope()->strictMode; // ### needed? scope or parent context?
|
||||
ctx.callData = callData;
|
||||
Q_ASSERT(v4->currentContext() == &ctx);
|
||||
Scoped<CallContext> sctx(scope, &ctx);
|
||||
|
||||
return f->d()->code(reinterpret_cast<CallContext *>(&ctx), f->d()->index);
|
||||
return f->d()->code(sctx, f->d()->index);
|
||||
}
|
||||
|
||||
DEFINE_OBJECT_VTABLE(IndexedBuiltinFunction);
|
||||
|
|
|
@ -68,7 +68,7 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
|
|||
static const QV4::ManagedVTable static_vtbl; \
|
||||
static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl; } \
|
||||
V4_MANAGED_SIZE_TEST \
|
||||
QV4::Heap::DataClass *d() const { return &static_cast<QV4::Heap::DataClass &>(const_cast<QV4::Heap::Base &>(Managed::data)); }
|
||||
QV4::Heap::DataClass *d() const { return static_cast<QV4::Heap::DataClass *>(m); }
|
||||
|
||||
#define V4_OBJECT(superClass) \
|
||||
public: \
|
||||
|
@ -77,7 +77,7 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
|
|||
static const QV4::ObjectVTable static_vtbl; \
|
||||
static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl.managedVTable; } \
|
||||
V4_MANAGED_SIZE_TEST \
|
||||
Data *d() const { return &static_cast<Data &>(const_cast<QV4::Heap::Base &>(Managed::data)); }
|
||||
Data *d() const { return static_cast<Data *>(m); }
|
||||
|
||||
#define V4_OBJECT2(DataClass, superClass) \
|
||||
public: \
|
||||
|
@ -87,7 +87,7 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
|
|||
static const QV4::ObjectVTable static_vtbl; \
|
||||
static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl.managedVTable; } \
|
||||
V4_MANAGED_SIZE_TEST \
|
||||
QV4::Heap::DataClass *d() const { return &static_cast<QV4::Heap::DataClass &>(const_cast<QV4::Heap::Base &>(Managed::data)); }
|
||||
QV4::Heap::DataClass *d() const { return static_cast<QV4::Heap::DataClass *>(m); }
|
||||
|
||||
#define Q_MANAGED_TYPE(type) \
|
||||
public: \
|
||||
|
@ -182,9 +182,8 @@ const QV4::ObjectVTable classname::static_vtbl = \
|
|||
advanceIterator \
|
||||
}
|
||||
|
||||
struct Q_QML_PRIVATE_EXPORT Managed
|
||||
struct Q_QML_PRIVATE_EXPORT Managed : Value
|
||||
{
|
||||
Heap::Base data;
|
||||
V4_MANAGED(Base, Managed)
|
||||
enum {
|
||||
IsExecutionContext = false,
|
||||
|
@ -196,12 +195,9 @@ struct Q_QML_PRIVATE_EXPORT Managed
|
|||
};
|
||||
private:
|
||||
void *operator new(size_t);
|
||||
Managed();
|
||||
Managed(const Managed &other);
|
||||
void operator = (const Managed &other);
|
||||
Managed(InternalClass *internal)
|
||||
: data(internal)
|
||||
{
|
||||
}
|
||||
void *operator new(size_t size, MemoryManager *mm);
|
||||
void *operator new(size_t, Managed *m) { return m; }
|
||||
|
||||
|
@ -339,14 +335,7 @@ inline Value Value::fromManaged(Managed *m)
|
|||
{
|
||||
if (!m)
|
||||
return QV4::Primitive::undefinedValue();
|
||||
Value v;
|
||||
#if QT_POINTER_SIZE == 8
|
||||
v.m = &m->data;
|
||||
#else
|
||||
v.tag = Managed_Type;
|
||||
v.m = &m->data;
|
||||
#endif
|
||||
return v;
|
||||
return *m;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ Heap::MemberData *MemberData::reallocate(ExecutionEngine *e, Heap::MemberData *o
|
|||
Scope scope(e);
|
||||
Scoped<MemberData> newMemberData(scope, static_cast<Heap::MemberData *>(e->memoryManager->allocManaged(alloc)));
|
||||
if (old)
|
||||
memcpy(newMemberData, old, sizeof(Heap::MemberData) + s*sizeof(Value));
|
||||
memcpy(newMemberData->d(), old, sizeof(Heap::MemberData) + s*sizeof(Value));
|
||||
else
|
||||
new (newMemberData->d()) Heap::MemberData(e->memberDataClass);
|
||||
newMemberData->d()->size = newAlloc;
|
||||
|
|
|
@ -52,7 +52,7 @@ DEFINE_OBJECT_VTABLE(Object);
|
|||
|
||||
Heap::Object::Object(InternalClass *internalClass, QV4::Object *prototype)
|
||||
: Heap::Base(internalClass),
|
||||
prototype(prototype->d())
|
||||
prototype(prototype ? prototype->d() : 0)
|
||||
{
|
||||
if (internalClass->size) {
|
||||
Scope scope(internalClass->engine);
|
||||
|
|
|
@ -64,8 +64,8 @@ ObjectIterator::ObjectIterator(Scope &scope, Object *o, uint flags)
|
|||
|
||||
void ObjectIterator::init(Object *o)
|
||||
{
|
||||
object->m = o ? &o->data : 0;
|
||||
current->m = o ? &o->data : 0;
|
||||
object->m = o ? o->m : 0;
|
||||
current->m = o ? o->m : 0;
|
||||
|
||||
#if QT_POINTER_SIZE == 4
|
||||
object->tag = QV4::Value::Managed_Type;
|
||||
|
|
|
@ -206,9 +206,9 @@ struct Scoped
|
|||
|
||||
inline void setPointer(Managed *p) {
|
||||
#if QT_POINTER_SIZE == 8
|
||||
ptr->val = (quint64)(p ? &p->data : 0);
|
||||
ptr->m = p ? p->m : 0;
|
||||
#else
|
||||
*ptr = p ? QV4::Value::fromManaged(p) : QV4::Primitive::undefinedValue();
|
||||
*ptr = QV4::Value::fromManaged(p);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -437,7 +437,7 @@ inline Value &Value::operator=(const ValueRef v)
|
|||
template<typename T>
|
||||
inline TypedValue<T> &TypedValue<T>::operator =(T *t)
|
||||
{
|
||||
m = t ? &t->data : 0;
|
||||
m = t ? t->m : 0;
|
||||
#if QT_POINTER_SIZE == 4
|
||||
tag = Managed_Type;
|
||||
#endif
|
||||
|
|
|
@ -49,13 +49,13 @@ inline bool Value::isString() const
|
|||
{
|
||||
if (!isManaged())
|
||||
return false;
|
||||
return m && static_cast<Heap::Base *>(m)->internalClass->vtable->isString;
|
||||
return m && m->internalClass->vtable->isString;
|
||||
}
|
||||
inline bool Value::isObject() const
|
||||
{
|
||||
if (!isManaged())
|
||||
return false;
|
||||
return m && static_cast<Heap::Base *>(m)->internalClass->vtable->isObject;
|
||||
return m && m->internalClass->vtable->isObject;
|
||||
}
|
||||
|
||||
inline bool Value::isPrimitive() const
|
||||
|
|
|
@ -301,13 +301,13 @@ struct Q_QML_PRIVATE_EXPORT Value
|
|||
}
|
||||
|
||||
String *stringValue() const {
|
||||
return m ? reinterpret_cast<String*>(m) : 0;
|
||||
return m ? reinterpret_cast<String*>(const_cast<Value *>(this)) : 0;
|
||||
}
|
||||
Object *objectValue() const {
|
||||
return m ? reinterpret_cast<Object*>(m) : 0;
|
||||
return m ? reinterpret_cast<Object*>(const_cast<Value *>(this)) : 0;
|
||||
}
|
||||
Managed *managed() const {
|
||||
return m ? reinterpret_cast<Managed*>(m) : 0;
|
||||
return m ? reinterpret_cast<Managed*>(const_cast<Value *>(this)) : 0;
|
||||
}
|
||||
Heap::Base *heapObject() const {
|
||||
return m;
|
||||
|
|
|
@ -145,7 +145,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
|
|||
|
||||
QV4::Scope scope(engine);
|
||||
QV4::ScopedContext context(scope, engine->currentContext());
|
||||
context->d()->lineNumber = -1;
|
||||
engine->currentContext()->lineNumber = -1;
|
||||
|
||||
#ifdef DO_TRACE_INSTR
|
||||
qDebug("Starting VME with context=%p and code=%p", context, code);
|
||||
|
@ -616,14 +616,14 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
|
|||
MOTH_END_INSTR(Ret)
|
||||
|
||||
MOTH_BEGIN_INSTR(Debug)
|
||||
context->d()->lineNumber = instr.lineNumber;
|
||||
engine->currentContext()->lineNumber = instr.lineNumber;
|
||||
QV4::Debugging::Debugger *debugger = context->engine()->debugger;
|
||||
if (debugger && debugger->pauseAtNextOpportunity())
|
||||
debugger->maybeBreakAtInstruction();
|
||||
MOTH_END_INSTR(Debug)
|
||||
|
||||
MOTH_BEGIN_INSTR(Line)
|
||||
context->d()->lineNumber = instr.lineNumber;
|
||||
engine->currentContext()->lineNumber = instr.lineNumber;
|
||||
MOTH_END_INSTR(Debug)
|
||||
|
||||
MOTH_BEGIN_INSTR(LoadThis)
|
||||
|
|
|
@ -1838,6 +1838,7 @@ void tst_QJSEngine::errorConstructors()
|
|||
QJSValue ret = eng.evaluate(code);
|
||||
QVERIFY(ret.isError());
|
||||
QVERIFY(ret.toString().startsWith(name));
|
||||
qDebug() << ret.property("stack").toString();
|
||||
QCOMPARE(ret.property("lineNumber").toInt(), i+2);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue