if (!valueMap.isEmpty()) {
V4IR::ExprList *current;
for (QMap<QString, ObjectPropertyValue>::iterator it = valueMap.begin(); it != valueMap.end(); ) {
- if (QV4::String(it.key()).asArrayIndex() != UINT_MAX) {
+ if (QV4::String(0, it.key()).asArrayIndex() != UINT_MAX) {
++it;
continue;
}
String *ExecutionEngine::newString(const QString &s)
{
- return new (memoryManager) String(s);
+ return new (memoryManager) String(this, s);
}
String *ExecutionEngine::newIdentifier(const QString &text)
operator delete(ptr);
}
+ExecutionEngine *Managed::engine() const
+{
+ return internalClass ? internalClass->engine : 0;
+}
+
QString Managed::className() const
{
const char *s = 0;
struct ObjectPrototype;
struct ExecutionContext;
struct ScriptFunction;
+struct InternalClass;
struct BooleanObject;
struct NumberObject;
struct Value;
class RegExp;
struct Lookup;
+struct ExecutionEngine;
struct ManagedVTable
{
void operator = (const Managed &other);
protected:
- Managed()
- : _data(0), vtbl(&static_vtbl)
+ Managed(InternalClass *internal)
+ : _data(0), vtbl(&static_vtbl), internalClass(internal)
{ inUse = 1; extensible = 1; }
public:
Type_RegExp
};
+ ExecutionEngine *engine() const;
+
String *asString() { return reinterpret_cast<String *>(this); }
Object *asObject() { return reinterpret_cast<Object *>(this); }
ArrayObject *asArrayObject() { return type == Type_ArrayObject ? reinterpret_cast<ArrayObject *>(this) : 0; }
static const ManagedVTable static_vtbl;
const ManagedVTable *vtbl;
+public:
+ InternalClass *internalClass;
private:
friend class MemoryManager;
PersistentValuePrivate *persistent = m_persistentValues;
while (persistent) {
if (Managed *m = persistent->value.asManaged())
- persistent->value = Value::undefinedValue();
- persistent->engine = 0;
+ persistent->value = Value::deletedValue();
PersistentValuePrivate *n = persistent->next;
persistent->next = 0;
persistent = n;
DEFINE_MANAGED_VTABLE(Object);
Object::Object(ExecutionEngine *engine)
- : prototype(0)
- , internalClass(engine->emptyClass)
+ : Managed(engine->emptyClass)
+ , prototype(0)
, memberDataAlloc(InlinePropertySize), memberData(inlineProperties)
, arrayOffset(0), arrayDataLen(0), arrayAlloc(0), arrayAttributes(0), arrayData(0), sparseArray(0)
, externalResource(0)
}
Object::Object(ExecutionContext *context)
- : prototype(0)
- , internalClass(context->engine->emptyClass)
+ : Managed(context->engine->emptyClass)
+ , prototype(0)
, memberDataAlloc(InlinePropertySize), memberData(inlineProperties)
, arrayOffset(0), arrayDataLen(0), arrayAlloc(0), arrayAttributes(0), arrayData(0), sparseArray(0)
, externalResource(0)
}
Object::Object(ExecutionEngine *engine, InternalClass *internalClass)
- : prototype(0)
- , internalClass(internalClass)
+ : Managed(internalClass)
+ , prototype(0)
, memberDataAlloc(InlinePropertySize), memberData(inlineProperties)
, arrayOffset(0), arrayDataLen(0), arrayAlloc(0), arrayAttributes(0), arrayData(0), sparseArray(0)
, externalResource(0)
};
Object *prototype;
- InternalClass *internalClass;
uint memberDataAlloc;
Property *memberData;
}
RegExp::RegExp(ExecutionEngine* engine, const QString &pattern, bool ignoreCase, bool multiline)
- : m_pattern(pattern)
+ : Managed(engine->emptyClass)
+ , m_pattern(pattern)
, m_cache(0)
, m_subPatternCount(0)
, m_ignoreCase(ignoreCase)
Exception::Exception(ExecutionContext *throwingContext, const Value &exceptionValue)
- : exception(PersistentValue(throwingContext->engine, exceptionValue))
+ : exception(exceptionValue)
{
this->throwingContext = throwingContext->engine->current;
accepted = false;
return false;
}
+String::String(ExecutionEngine *engine, const QString &text)
+ : Managed(engine ? engine->emptyClass : 0), _text(text), stringHash(UINT_MAX), identifier(UINT_MAX)
+{
+ vtbl = &static_vtbl;
+ type = Type_String;
+ subtype = StringType_Unknown;
+}
+
uint String::toUInt(bool *ok) const
{
*ok = true;
StringType_ArrayIndex
};
- String(const QString &text)
- : _text(text), stringHash(UINT_MAX), identifier(UINT_MAX)
+ String() : Managed(0), stringHash(UINT_MAX), identifier(UINT_MAX)
{ vtbl = &static_vtbl; type = Type_String; subtype = StringType_Unknown; }
+ String(ExecutionEngine *engine, const QString &text);
~String() { _data = 0; }
inline bool isEqualTo(const String *other) const {
{
}
-PersistentValue::PersistentValue(ExecutionEngine *e, const Value &val)
- : d(new PersistentValuePrivate(e, val))
+PersistentValue::PersistentValue(const Value &val)
+ : d(new PersistentValuePrivate(val))
{
}
d->ref();
}
+PersistentValue &PersistentValue::operator =(const Value &other)
+{
+ d->value = other;
+}
+
PersistentValue::~PersistentValue()
{
d->deref();
PersistentValuePrivate::PersistentValuePrivate(const Value &v)
: value(v)
, refcount(1)
- , engine(0)
, next(0)
{
- assert(!v.asManaged());
-}
-
-
-PersistentValuePrivate::PersistentValuePrivate(ExecutionEngine *e, const Value &v)
- : value(v)
- , refcount(1)
- , engine(e)
- , next(engine->memoryManager->m_persistentValues)
-{
- engine->memoryManager->m_persistentValues = this;
+ if (Managed *m = v.asManaged()) {
+ ExecutionEngine *engine = m->engine();
+ if (engine) {
+ next = engine->memoryManager->m_persistentValues;
+ engine->memoryManager->m_persistentValues = this;
+ }
+ }
}
void PersistentValuePrivate::deref()
{
// if engine is not 0, they are registered with the memory manager
// and will get cleaned up in the next gc run
- if (!--refcount && !engine)
- delete this;
+ if (!--refcount && !next) {
+ ExecutionEngine *e = 0;
+ if (Managed *m = value.asManaged())
+ e = m->engine();
+ if (!e)
+ delete this;
+ }
}
Value property(ExecutionContext *ctx, String *name) const;
+ ExecutionEngine *engine() const {
+ Managed *m = asManaged();
+ return m ? m->engine() : 0;
+ }
+
// Section 9.12
bool sameValue(Value other) const;
PersistentValuePrivate()
: value(Value::undefinedValue())
, refcount(1)
- , engine(0)
, next(0)
{}
- PersistentValuePrivate(ExecutionEngine *e, const Value &v);
PersistentValuePrivate(const Value &v);
Value value;
int refcount;
- ExecutionEngine *engine;
PersistentValuePrivate *next;
void ref() { ++refcount; }
{
public:
PersistentValue();
- PersistentValue(ExecutionEngine *e, const Value &val);
+ PersistentValue(const Value &val);
PersistentValue(const PersistentValue &other);
PersistentValue &operator=(const PersistentValue &other);
+ PersistentValue &operator=(const Value &other);
~PersistentValue();
Value *operator->() { return &d->value; }
Value *operator*() { return &d->value; }
+ ExecutionEngine *engine() {
+ Managed *m = d->value.asManaged();
+ return m ? m->engine() : 0;
+ }
+
operator Value() const { return d->value; }
private:
*/
QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, int lineNumber)
{
+ QV4::ExecutionContext *ctx = d->m_v4Engine->current;
try {
- QV4::Function *f = QV4::EvalFunction::parseSource(d->m_v4Engine->current, fileName, program, QQmlJS::Codegen::EvalCode,
- d->m_v4Engine->current->strictMode, true);
+ QV4::Function *f = QV4::EvalFunction::parseSource(ctx, fileName, program, QQmlJS::Codegen::EvalCode,
+ d->m_v4Engine->current->strictMode, true);
if (!f)
return QJSValue();
QV4::Value result = d->m_v4Engine->run(f);
- return new QJSValuePrivate(d->m_v4Engine, result);
+ return new QJSValuePrivate(result);
} catch (QV4::Exception& ex) {
- ex.accept(d->m_v4Engine->current);
- return new QJSValuePrivate(d->m_v4Engine, ex.value());
+ ex.accept(ctx);
+ return new QJSValuePrivate(ex.value());
}
}
*/
QJSValue QJSEngine::newObject()
{
- return new QJSValuePrivate(d->m_v4Engine, d->m_v4Engine->newObject());
+ return new QJSValuePrivate(d->m_v4Engine->newObject());
}
/*!
if (length < 0x1000)
array->arrayReserve(length);
array->setArrayLengthUnchecked(length);
- return new QJSValuePrivate(d->m_v4Engine, array);
+ return new QJSValuePrivate(array);
}
/*!
*/
QJSValue QJSEngine::globalObject() const
{
- return new QJSValuePrivate(d->m_v4Engine, d->m_v4Engine->globalObject);
+ return new QJSValuePrivate(d->m_v4Engine->globalObject);
}
/*!
QJSValue QJSEngine::create(int type, const void *ptr)
{
Q_D(QJSEngine);
- return new QJSValuePrivate(QV8Engine::getV4(d), d->metaTypeToJS(type, ptr));
+ return new QJSValuePrivate(d->metaTypeToJS(type, ptr));
}
/*!
bool QJSEngine::convertV2(const QJSValue &value, int type, void *ptr)
{
QJSValuePrivate *vp = QJSValuePrivate::get(value);
- QV4::ExecutionEngine *e = vp->engine;
+ QV4::ExecutionEngine *e = vp->engine();
QV8Engine *engine = e ? QV8Engine::get(e->publicEngine) : 0;
if (engine) {
return engine->metaTypeFromJS(vp->getValue(engine->m_v4Engine), type, ptr);
*/
double QJSValue::toNumber() const
{
- QV4::ExecutionContext *ctx = d->engine ? d->engine->current : 0;
+ QV4::ExecutionEngine *e = d->engine();
+ QV4::ExecutionContext *ctx = e ? e->current : 0;
try {
return d->value.toNumber();
} catch (Exception &e) {
*/
bool QJSValue::toBool() const
{
- QV4::ExecutionContext *ctx = d->engine ? d->engine->current : 0;
+ QV4::ExecutionEngine *e = d->engine();
+ QV4::ExecutionContext *ctx = e ? e->current : 0;
try {
return d->value.toBoolean();
} catch (Exception &e) {
*/
qint32 QJSValue::toInt() const
{
- QV4::ExecutionContext *ctx = d->engine ? d->engine->current : 0;
+ QV4::ExecutionEngine *e = d->engine();
+ QV4::ExecutionContext *ctx = e ? e->current : 0;
try {
return d->value.toInt32();
} catch (Exception &e) {
*/
quint32 QJSValue::toUInt() const
{
- QV4::ExecutionContext *ctx = d->engine ? d->engine->current : 0;
+ QV4::ExecutionEngine *e = d->engine();
+ QV4::ExecutionContext *ctx = e ? e->current : 0;
try {
return d->value.toUInt32();
} catch (Exception &e) {
if (!f)
return QJSValue();
- ExecutionEngine *engine = d->engine;
+ ExecutionEngine *engine = d->engine();
assert(engine);
QVarLengthArray<Value> arguments(args.length());
arguments[i] = args.at(i).d->getValue(engine);
Value result;
- QV4::ExecutionContext *ctx = d->engine->current;
+ QV4::ExecutionContext *ctx = engine->current;
try {
- result = f->call(ctx, Value::fromObject(d->engine->globalObject), arguments.data(), arguments.size());
+ result = f->call(ctx, Value::fromObject(engine->globalObject), arguments.data(), arguments.size());
} catch (Exception &e) {
e.accept(ctx);
result = e.value();
}
- return new QJSValuePrivate(engine, result);
+ return new QJSValuePrivate(result);
}
/*!
if (!f)
return QJSValue();
- ExecutionEngine *engine = d->engine;
+ ExecutionEngine *engine = d->engine();
assert(engine);
QVarLengthArray<Value> arguments(args.length());
arguments[i] = args.at(i).d->getValue(engine);
Value result;
- QV4::ExecutionContext *ctx = d->engine->current;
+ QV4::ExecutionContext *ctx = engine->current;
try {
result = f->call(ctx, instance.d->getValue(engine), arguments.data(), arguments.size());
} catch (Exception &e) {
result = e.value();
}
- return new QJSValuePrivate(engine, result);
+ return new QJSValuePrivate(result);
}
/*!
if (!f)
return QJSValue();
- ExecutionEngine *engine = d->engine;
+ ExecutionEngine *engine = d->engine();
assert(engine);
QVarLengthArray<Value> arguments(args.length());
arguments[i] = args.at(i).d->getValue(engine);
Value result;
- QV4::ExecutionContext *ctx = d->engine->current;
+ QV4::ExecutionContext *ctx = engine->current;
try {
result = f->construct(ctx, arguments.data(), arguments.size());
} catch (Exception &e) {
result = e.value();
}
- return new QJSValuePrivate(engine, result);
+ return new QJSValuePrivate(result);
}
#ifdef QT_DEPRECATED
*/
QJSEngine* QJSValue::engine() const
{
- if (d->engine)
- return d->engine->publicEngine;
+ QV4::ExecutionEngine *engine = d->engine();
+ if (engine)
+ return engine->publicEngine;
}
#endif // QT_DEPRECATED
Object *o = d->value.asObject();
if (!o)
return QJSValue();
- return new QJSValuePrivate(d->engine, Value::fromObject(o->prototype));
+ return new QJSValuePrivate(Value::fromObject(o->prototype));
}
/*!
if (!o)
return QJSValue();
- String *s = d->engine->newString(name);
+ ExecutionEngine *engine = d->engine();
+ String *s = engine->newString(name);
uint idx = s->asArrayIndex();
if (idx < UINT_MAX)
return property(idx);
- s->makeIdentifier(d->engine->current);
- QV4::ExecutionContext *ctx = d->engine->current;
+ s->makeIdentifier(engine->current);
+ QV4::ExecutionContext *ctx = engine->current;
try {
QV4::Value v = o->get(ctx, s);
- return new QJSValuePrivate(d->engine, v);
+ return new QJSValuePrivate(v);
} catch (QV4::Exception &e) {
e.accept(ctx);
return QJSValue();
if (!o)
return QJSValue();
- QV4::ExecutionContext *ctx = d->engine->current;
+ ExecutionEngine *engine = d->engine();
+ QV4::ExecutionContext *ctx = engine->current;
try {
- QV4::Value v = arrayIndex == UINT_MAX ? o->get(ctx, ctx->engine->id_uintMax) : o->getIndexed(ctx, arrayIndex);
- return new QJSValuePrivate(d->engine, v);
+ QV4::Value v = arrayIndex == UINT_MAX ? o->get(ctx, engine->id_uintMax) : o->getIndexed(ctx, arrayIndex);
+ return new QJSValuePrivate(v);
} catch (QV4::Exception &e) {
e.accept(ctx);
return QJSValue();
if (!o)
return;
- String *s = d->engine->newString(name);
+ ExecutionEngine *engine = d->engine();
+ String *s = engine->newString(name);
uint idx = s->asArrayIndex();
if (idx < UINT_MAX) {
setProperty(idx, value);
return;
}
- QV4::ExecutionContext *ctx = d->engine->current;
+ QV4::ExecutionContext *ctx = engine->current;
s->makeIdentifier(ctx);
try {
o->put(ctx, s, value.d->value);
if (!o)
return;
- QV4::ExecutionContext *ctx = d->engine->current;
+ ExecutionEngine *engine = d->engine();
+ QV4::ExecutionContext *ctx = engine->current;
try {
if (arrayIndex != UINT_MAX)
o->putIndexed(ctx, arrayIndex, value.d->value);
else
- o->put(ctx, ctx->engine->id_uintMax, value.d->value);
+ o->put(ctx, engine->id_uintMax, value.d->value);
} catch (QV4::Exception &e) {
e.accept(ctx);
}
if (!o)
return false;
- String *s = d->engine->newIdentifier(name);
- return o->deleteProperty(d->engine->current, s);
+ ExecutionEngine *engine = d->engine();
+ String *s = engine->newIdentifier(name);
+ return o->deleteProperty(engine->current, s);
}
/*!
if (!o)
return false;
- String *s = d->engine->newIdentifier(name);
+ ExecutionEngine *engine = d->engine();
+ String *s = engine->newIdentifier(name);
return o->__hasProperty__(s);
}
if (!o)
return false;
- String *s = d->engine->newIdentifier(name);
+ ExecutionEngine *engine = d->engine();
+ String *s = engine->newIdentifier(name);
return o->__getOwnProperty__(s);
}
class QJSValuePrivate : public QV4::PersistentValuePrivate
{
public:
- QJSValuePrivate(QV4::ExecutionEngine *e, const QV4::Value &v)
- : PersistentValuePrivate(e, v)
- , string(QString())
+ QJSValuePrivate(const QV4::Value &v)
+ : PersistentValuePrivate(v)
{
if (value.isDeleted())
value = QV4::Value::undefinedValue();
}
- QJSValuePrivate(QV4::ExecutionEngine *e, QV4::Object *o)
- : PersistentValuePrivate(e, QV4::Value::fromObject(o))
- , string(QString())
+ QJSValuePrivate(QV4::Object *o)
+ : PersistentValuePrivate(QV4::Value::fromObject(o))
{}
- QJSValuePrivate(QV4::ExecutionEngine *e, QV4::String *s)
- : PersistentValuePrivate(e, QV4::Value::fromString(s))
- , string(QString())
- {}
- QJSValuePrivate(const QV4::Value &v)
- : PersistentValuePrivate(v)
- , string(QString())
+ QJSValuePrivate(QV4::String *s)
+ : PersistentValuePrivate(QV4::Value::fromString(s))
{}
QJSValuePrivate(const QString &s)
: PersistentValuePrivate()
- , string(s)
+ , string(0, s)
{
value = QV4::Value::fromString(&string);
}
QV4::Value getValue(QV4::ExecutionEngine *e) {
- if (value.asString() == &string) {
- engine = e;
+ if (value.asString() == &string)
value = QV4::Value::fromString(e->newString(string.toQString()));
- }
return value;
}
+ QV4::ExecutionEngine *engine() const {
+ return value.engine();
+ }
+
static QJSValuePrivate *get(const QJSValue &v) { return v.d; }
QV4::String string;
return QJSValue();
QV4::Object *o = d_ptr->iterator.object;
+ QV4::ExecutionContext *ctx = o->internalClass->engine->current;
try {
- QV4::Value v = o->getValue(o->internalClass->engine->current, d_ptr->currentValue, d_ptr->currentAttributes);
- return new QJSValuePrivate(o->internalClass->engine, v);
+ QV4::Value v = o->getValue(ctx, d_ptr->currentValue, d_ptr->currentAttributes);
+ return new QJSValuePrivate(v);
} catch (QV4::Exception &e) {
+ e.accept(ctx);
return QJSValue();
}
}
QV8GCCallback::registerGcPrologueCallback();
m_strongReferencer = qPersistentNew(v8::Object::New());
- m_bindingFlagKey = QV4::PersistentValue(m_v4Engine, QV4::Value::fromString(m_v4Engine->current, QStringLiteral("qml::binding")));
+ m_bindingFlagKey = QV4::Value::fromString(m_v4Engine->current, QStringLiteral("qml::binding"));
m_contextWrapper.init(this);
m_qobjectWrapper.init(this);
} else if (type == qMetaTypeId<QJSValue>()) {
const QJSValue *value = reinterpret_cast<const QJSValue *>(ptr);
QJSValuePrivate *valuep = QJSValuePrivate::get(*value);
- valuep->engine = m_v4Engine;
- return valuep->getValue(valuep->engine);
+ return valuep->getValue(m_v4Engine);
} else if (type == qMetaTypeId<QList<QObject *> >()) {
// XXX Can this be made more by using Array as a prototype and implementing
// directly against QList<QObject*>?
QV4::Value result = evaluateScript(QStringLiteral(FREEZE_SOURCE), 0);
Q_ASSERT(result.asFunctionObject());
- m_freezeObject = QV4::PersistentValue(m_v4Engine, result);
+ m_freezeObject = result;
#undef FREEZE_SOURCE
}
}
*reinterpret_cast<void* *>(data) = 0;
return true;
} else if (type == qMetaTypeId<QJSValue>()) {
- *reinterpret_cast<QJSValue*>(data) = QJSValuePrivate::get(new QJSValuePrivate(m_v4Engine, value));
+ *reinterpret_cast<QJSValue*>(data) = QJSValuePrivate::get(new QJSValuePrivate(value));
return true;
}
QJSValue QV8Engine::scriptValueFromInternal(const QV4::Value &value) const
{
- return new QJSValuePrivate(m_v4Engine, value);
+ return new QJSValuePrivate(value);
}
QJSValue QV8Engine::newArray(uint length)
{
- return new QJSValuePrivate(m_v4Engine, v8::Array::New(length).get()->v4Value());
+ return new QJSValuePrivate(v8::Array::New(length).get()->v4Value());
}
void QV8Engine::startTimer(const QString &timerName)
if (type != 0) { cleanup(); type = 0; }
if (callType == qMetaTypeId<QJSValue>()) {
- qjsValuePtr = new (&allocData) QJSValue(new QJSValuePrivate(QV8Engine::getV4(engine), value.get()->v4Value()));
+ qjsValuePtr = new (&allocData) QJSValue(new QJSValuePrivate(value.get()->v4Value()));
type = qMetaTypeId<QJSValue>();
} else if (callType == QMetaType::Int) {
intValue = quint32(value->Int32Value());