aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@digia.com>2015-07-08 10:52:59 +0200
committerErik Verbruggen <erik.verbruggen@theqtcompany.com>2015-07-24 11:44:05 +0000
commit92836d052efb6d8073136e8507083f93fb60bb80 (patch)
treeb540fb91fb1a580ac7bd11134fa36ee8fc64df51
parent2cc48fbdb2eb10858045eb4877c45d981fa55698 (diff)
Remove type punning from QV4::Value.
The union in QV4::Value is used to do type punning. In C++, this is compiler-defined behavior. For example, Clang and GCC will try to detect it and try to do the proper thing. However, it can play havoc with Alias Analysis, and it is not guaranteed that some Undefined Behavior (or Compiler depenedent behavior) might occur. The really problematic part is the struct inside the union: depending on the calling convention and the register size, it results in some exciting code. For example, the AMD64 ABI specifies that a struct of two values of INTEGER class can be passed in separate registers when doing a function call. Now, if the AA in the compiler looses track of the fact that the tag overlaps with the double, you might get: ecx := someTag ... conditional jumps double_case: rdx := xorredDoubleValue callq someWhere If the someWhere function checks for the tag first, mayhem ensues: the double value in rdx does not overwrite the tag that is passed in ecx. Changing the code to do reinterpret_cast<>s might also give problems on 32bit architectures, because there is a double, whose size is not the same as the size of the tag, which could confuse AA. So, to fix this, the following is changed: - only have a quint64 field in the QV4::Value, which has the added benefit that it's very clear for the compiler that it's a POD - as memcpy is the only approved way to ensure bit-by-bit "conversion" between types (esp. FP<->non-FP types), change all conversions to use memcpy. Use bitops (shift/and/or) for anything else. - only use accessor functions for non-quint64 values As any modern compiler has memcpy as an intrinsic, the call will be replaced with one or a few move instructions. The accessor functions also get inlined, the bitops get optimized, so in all cases the compiler can generate the most compact code possible. This patch obsoletes f558bc48585c69de36151248c969a484a969ebb4 (which had the exact aliassing problem of the double and the tag as described above). Change-Id: I60a39d8564be5ce6106403a56a8de90943217006 Reviewed-by: Ulf Hermann <ulf.hermann@theqtcompany.com>
-rw-r--r--src/qml/jit/qv4assembler_p.h24
-rw-r--r--src/qml/jit/qv4isel_masm.cpp34
-rw-r--r--src/qml/jsruntime/qv4arraydata.cpp65
-rw-r--r--src/qml/jsruntime/qv4arraydata_p.h10
-rw-r--r--src/qml/jsruntime/qv4context.cpp8
-rw-r--r--src/qml/jsruntime/qv4context_p.h2
-rw-r--r--src/qml/jsruntime/qv4dateobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4debugging.cpp2
-rw-r--r--src/qml/jsruntime/qv4engine_p.h2
-rw-r--r--src/qml/jsruntime/qv4errorobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4jsonobject.cpp6
-rw-r--r--src/qml/jsruntime/qv4managed_p.h4
-rw-r--r--src/qml/jsruntime/qv4object.cpp10
-rw-r--r--src/qml/jsruntime/qv4object_p.h14
-rw-r--r--src/qml/jsruntime/qv4objectiterator.cpp16
-rw-r--r--src/qml/jsruntime/qv4objectiterator_p.h2
-rw-r--r--src/qml/jsruntime/qv4persistent.cpp18
-rw-r--r--src/qml/jsruntime/qv4property_p.h4
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp8
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper_p.h2
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp4
-rw-r--r--src/qml/jsruntime/qv4runtime_p.h2
-rw-r--r--src/qml/jsruntime/qv4scopedvalue_p.h50
-rw-r--r--src/qml/jsruntime/qv4script_p.h6
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp6
-rw-r--r--src/qml/jsruntime/qv4string_p.h2
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp4
-rw-r--r--src/qml/jsruntime/qv4stringobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4typedarray.cpp4
-rw-r--r--src/qml/jsruntime/qv4value.cpp20
-rw-r--r--src/qml/jsruntime/qv4value_p.h249
-rw-r--r--src/qml/qml/qqmllistwrapper.cpp4
-rw-r--r--src/qml/qml/qqmllistwrapper_p.h2
-rw-r--r--src/qml/qml/v8/qv8engine_p.h2
35 files changed, 306 insertions, 288 deletions
diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h
index f4b44ce882..ab74211d23 100644
--- a/src/qml/jit/qv4assembler_p.h
+++ b/src/qml/jit/qv4assembler_p.h
@@ -478,7 +478,7 @@ public:
load64(addr, dest);
} else {
QV4::Value undefined = QV4::Primitive::undefinedValue();
- move(TrustedImm64(undefined.val), dest);
+ move(TrustedImm64(undefined.rawValue()), dest);
}
}
@@ -491,7 +491,7 @@ public:
load64(addr, dest);
} else {
QV4::Value undefined = QV4::Primitive::undefinedValue();
- move(TrustedImm64(undefined.val), dest);
+ move(TrustedImm64(undefined.rawValue()), dest);
}
}
@@ -500,7 +500,7 @@ public:
Q_UNUSED(argumentNumber);
QV4::Value v = convertToValue(c);
- move(TrustedImm64(v.val), dest);
+ move(TrustedImm64(v.rawValue()), dest);
}
void loadArgumentInRegister(IR::Expr* expr, RegisterID dest, int argumentNumber)
@@ -509,7 +509,7 @@ public:
if (!expr) {
QV4::Value undefined = QV4::Primitive::undefinedValue();
- move(TrustedImm64(undefined.val), dest);
+ move(TrustedImm64(undefined.rawValue()), dest);
} else if (IR::Temp *t = expr->asTemp()){
loadArgumentInRegister(t, dest, argumentNumber);
} else if (IR::ArgLocal *al = expr->asArgLocal()) {
@@ -791,11 +791,11 @@ public:
void storeValue(QV4::Primitive value, Address destination)
{
#ifdef VALUE_FITS_IN_REGISTER
- store64(TrustedImm64(value.val), destination);
+ store64(TrustedImm64(value.rawValue()), destination);
#else
- store32(TrustedImm32(value.int_32), destination);
+ store32(TrustedImm32(value.int_32()), destination);
destination.offset += 4;
- store32(TrustedImm32(value.tag), destination);
+ store32(TrustedImm32(value.tag()), destination);
#endif
}
@@ -957,8 +957,8 @@ public:
tagAddr.offset += 4;
QV4::Primitive v = convertToValue(c);
- store32(TrustedImm32(v.int_32), addr);
- store32(TrustedImm32(v.tag), tagAddr);
+ store32(TrustedImm32(v.int_32()), addr);
+ store32(TrustedImm32(v.tag()), tagAddr);
return Pointer(addr);
}
@@ -973,7 +973,7 @@ public:
{
store32(reg, addr);
addr.offset += 4;
- store32(TrustedImm32(QV4::Primitive::fromBoolean(0).tag), addr);
+ store32(TrustedImm32(QV4::Primitive::fromBoolean(0).tag()), addr);
}
void storeBool(RegisterID src, RegisterID dest)
@@ -1017,7 +1017,7 @@ public:
{
store32(reg, addr);
addr.offset += 4;
- store32(TrustedImm32(QV4::Primitive::fromInt32(0).tag), addr);
+ store32(TrustedImm32(QV4::Primitive::fromInt32(0).tag()), addr);
}
void storeInt32(RegisterID reg, IR::Expr *target)
@@ -1096,7 +1096,7 @@ public:
RegisterID toInt32Register(IR::Expr *e, RegisterID scratchReg)
{
if (IR::Const *c = e->asConst()) {
- move(TrustedImm32(convertToValue(c).int_32), scratchReg);
+ move(TrustedImm32(convertToValue(c).int_32()), scratchReg);
return scratchReg;
}
diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp
index 09e295e4f0..87a7a4a895 100644
--- a/src/qml/jit/qv4isel_masm.cpp
+++ b/src/qml/jit/qv4isel_masm.cpp
@@ -614,7 +614,7 @@ void InstructionSelection::loadConst(IR::Const *sourceConst, IR::Expr *target)
_as->toUInt32Register(sourceConst, (Assembler::RegisterID) targetTemp->index);
} else if (targetTemp->type == IR::BoolType) {
Q_ASSERT(sourceConst->type == IR::BoolType);
- _as->move(Assembler::TrustedImm32(convertToValue(sourceConst).int_32),
+ _as->move(Assembler::TrustedImm32(convertToValue(sourceConst).int_32()),
(Assembler::RegisterID) targetTemp->index);
} else {
Q_UNREACHABLE();
@@ -1297,11 +1297,11 @@ void InstructionSelection::visitCJump(IR::CJump *s)
} else {
Address temp = _as->loadAddress(Assembler::ScratchRegister, s->cond);
Address tag = temp;
- tag.offset += qOffsetOf(QV4::Value, tag);
+ tag.offset += QV4::Value::tagOffset();
Assembler::Jump booleanConversion = _as->branch32(Assembler::NotEqual, tag, Assembler::TrustedImm32(QV4::Value::Boolean_Type));
Address data = temp;
- data.offset += qOffsetOf(QV4::Value, int_32);
+ data.offset += QV4::Value::valueOffset();
_as->load32(data, Assembler::ReturnValueRegister);
Assembler::Jump testBoolean = _as->jump();
@@ -1475,16 +1475,16 @@ void InstructionSelection::visitRet(IR::Ret *s)
} else if (IR::Const *c = s->expr->asConst()) {
QV4::Primitive retVal = convertToValue(c);
#if CPU(X86)
- _as->move(Assembler::TrustedImm32(retVal.int_32), JSC::X86Registers::eax);
- _as->move(Assembler::TrustedImm32(retVal.tag), JSC::X86Registers::edx);
+ _as->move(Assembler::TrustedImm32(retVal.int_32()), JSC::X86Registers::eax);
+ _as->move(Assembler::TrustedImm32(retVal.tag()), JSC::X86Registers::edx);
#elif CPU(ARM)
- _as->move(Assembler::TrustedImm32(retVal.int_32), JSC::ARMRegisters::r0);
- _as->move(Assembler::TrustedImm32(retVal.tag), JSC::ARMRegisters::r1);
+ _as->move(Assembler::TrustedImm32(retVal.int_32()), JSC::ARMRegisters::r0);
+ _as->move(Assembler::TrustedImm32(retVal.tag()), JSC::ARMRegisters::r1);
#elif CPU(MIPS)
- _as->move(Assembler::TrustedImm32(retVal.int_32), JSC::MIPSRegisters::v0);
- _as->move(Assembler::TrustedImm32(retVal.tag), JSC::MIPSRegisters::v1);
+ _as->move(Assembler::TrustedImm32(retVal.int_32()), JSC::MIPSRegisters::v0);
+ _as->move(Assembler::TrustedImm32(retVal.tag()), JSC::MIPSRegisters::v1);
#else
- _as->move(Assembler::TrustedImm64(retVal.val), Assembler::ReturnValueRegister);
+ _as->move(Assembler::TrustedImm64(retVal.rawValue()), Assembler::ReturnValueRegister);
#endif
} else {
Q_UNREACHABLE();
@@ -1505,16 +1505,16 @@ void InstructionSelection::visitRet(IR::Ret *s)
_as->exceptionReturnLabel = _as->label();
QV4::Primitive retVal = Primitive::undefinedValue();
#if CPU(X86)
- _as->move(Assembler::TrustedImm32(retVal.int_32), JSC::X86Registers::eax);
- _as->move(Assembler::TrustedImm32(retVal.tag), JSC::X86Registers::edx);
+ _as->move(Assembler::TrustedImm32(retVal.int_32()), JSC::X86Registers::eax);
+ _as->move(Assembler::TrustedImm32(retVal.tag()), JSC::X86Registers::edx);
#elif CPU(ARM)
- _as->move(Assembler::TrustedImm32(retVal.int_32), JSC::ARMRegisters::r0);
- _as->move(Assembler::TrustedImm32(retVal.tag), JSC::ARMRegisters::r1);
+ _as->move(Assembler::TrustedImm32(retVal.int_32()), JSC::ARMRegisters::r0);
+ _as->move(Assembler::TrustedImm32(retVal.tag()), JSC::ARMRegisters::r1);
#elif CPU(MIPS)
- _as->move(Assembler::TrustedImm32(retVal.int_32), JSC::MIPSRegisters::v0);
- _as->move(Assembler::TrustedImm32(retVal.tag), JSC::MIPSRegisters::v1);
+ _as->move(Assembler::TrustedImm32(retVal.int_32()), JSC::MIPSRegisters::v0);
+ _as->move(Assembler::TrustedImm32(retVal.tag()), JSC::MIPSRegisters::v1);
#else
- _as->move(Assembler::TrustedImm64(retVal.val), Assembler::ReturnValueRegister);
+ _as->move(Assembler::TrustedImm64(retVal.rawValue()), Assembler::ReturnValueRegister);
#endif
_as->jump(leaveStackFrame);
}
diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp
index 627aed0192..da91db6aae 100644
--- a/src/qml/jsruntime/qv4arraydata.cpp
+++ b/src/qml/jsruntime/qv4arraydata.cpp
@@ -91,6 +91,13 @@ const ArrayVTable SparseArrayData::static_vtbl =
Q_STATIC_ASSERT(sizeof(Heap::ArrayData) == sizeof(Heap::SimpleArrayData));
Q_STATIC_ASSERT(sizeof(Heap::ArrayData) == sizeof(Heap::SparseArrayData));
+static Q_ALWAYS_INLINE void storeValue(ReturnedValue *target, uint value)
+{
+ Value v = Value::fromReturnedValue(*target);
+ v.setValue(value);
+ *target = v.asReturnedValue();
+}
+
void ArrayData::realloc(Object *o, Type newType, uint requested, bool enforceAttributes)
{
Scope scope(o->engine());
@@ -166,7 +173,7 @@ void ArrayData::realloc(Object *o, Type newType, uint requested, bool enforceAtt
Heap::SparseArrayData *sparse = static_cast<Heap::SparseArrayData *>(newData->d());
- uint *lastFree;
+ ReturnedValue *lastFree;
if (d && d->type() == Heap::ArrayData::Sparse) {
Heap::SparseArrayData *old = static_cast<Heap::SparseArrayData *>(d->d());
sparse->sparse = old->sparse;
@@ -181,20 +188,20 @@ void ArrayData::realloc(Object *o, Type newType, uint requested, bool enforceAtt
SparseArrayNode *n = sparse->sparse->insert(i);
n->value = i;
} else {
- *lastFree = i;
- sparse->arrayData[i].tag = Value::Empty_Type;
- lastFree = &sparse->arrayData[i].uint_32;
+ storeValue(lastFree, i);
+ sparse->arrayData[i].setTag(Value::Empty_Type);
+ lastFree = &sparse->arrayData[i].rawValueRef();
}
}
}
if (toCopy < sparse->alloc) {
for (uint i = toCopy; i < sparse->alloc; ++i) {
- *lastFree = i;
- sparse->arrayData[i].tag = Value::Empty_Type;
- lastFree = &sparse->arrayData[i].uint_32;
+ storeValue(lastFree, i);
+ sparse->arrayData[i].setTag(Value::Empty_Type);
+ lastFree = &sparse->arrayData[i].rawValueRef();
}
- *lastFree = UINT_MAX;
+ storeValue(lastFree, UINT_MAX);
}
// ### Could explicitly free the old data
}
@@ -338,13 +345,10 @@ void SparseArrayData::free(Heap::ArrayData *d, uint idx)
Value *v = d->arrayData + idx;
if (d->attrs && d->attrs[idx].isAccessor()) {
// double slot, free both. Order is important, so we have a double slot for allocation again afterwards.
- v[1].tag = Value::Empty_Type;
- v[1].uint_32 = d->freeList;
- v[0].tag = Value::Empty_Type;
- v[0].uint_32 = idx + 1;
+ v[1].setTagValue(Value::Empty_Type, Value::fromReturnedValue(d->freeList).value());
+ v[0].setTagValue(Value::Empty_Type, idx + 1);
} else {
- v->tag = Value::Empty_Type;
- v->uint_32 = d->freeList;
+ v->setTagValue(Value::Empty_Type, Value::fromReturnedValue(d->freeList).value());
}
d->freeList = idx;
if (d->attrs)
@@ -372,33 +376,35 @@ uint SparseArrayData::allocate(Object *o, bool doubleSlot)
Q_ASSERT(o->d()->arrayData->type == Heap::ArrayData::Sparse);
Heap::SimpleArrayData *dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
if (doubleSlot) {
- uint *last = &dd->freeList;
+ ReturnedValue *last = &dd->freeList;
while (1) {
- if (*last == UINT_MAX) {
+ if (Value::fromReturnedValue(*last).value() == UINT_MAX) {
reallocate(o, dd->alloc + 2, true);
dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
last = &dd->freeList;
- Q_ASSERT(*last != UINT_MAX);
+ Q_ASSERT(Value::fromReturnedValue(*last).value() != UINT_MAX);
}
- Q_ASSERT(dd->arrayData[*last].uint_32 != *last);
- if (dd->arrayData[*last].uint_32 == (*last + 1)) {
+ Q_ASSERT(dd->arrayData[Value::fromReturnedValue(*last).value()].value() != Value::fromReturnedValue(*last).value());
+ if (dd->arrayData[Value::fromReturnedValue(*last).value()].value() == (Value::fromReturnedValue(*last).value() + 1)) {
// found two slots in a row
- uint idx = *last;
- *last = dd->arrayData[*last + 1].uint_32;
+ uint idx = Value::fromReturnedValue(*last).uint_32();
+ Value lastV = Value::fromReturnedValue(*last);
+ lastV.setValue(dd->arrayData[lastV.value() + 1].value());
+ *last = lastV.rawValue();
dd->attrs[idx] = Attr_Accessor;
return idx;
}
- last = &dd->arrayData[*last].uint_32;
+ last = &dd->arrayData[Value::fromReturnedValue(*last).value()].rawValueRef();
}
} else {
- if (dd->freeList == UINT_MAX) {
+ if (Value::fromReturnedValue(dd->freeList).value() == UINT_MAX) {
reallocate(o, dd->alloc + 1, false);
dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
}
- uint idx = dd->freeList;
+ uint idx = Value::fromReturnedValue(dd->freeList).value();
Q_ASSERT(idx != UINT_MAX);
- dd->freeList = dd->arrayData[idx].uint_32;
+ dd->freeList = dd->arrayData[idx].uint_32();
if (dd->attrs)
dd->attrs[idx] = Attr_Data;
return idx;
@@ -453,13 +459,10 @@ bool SparseArrayData::del(Object *o, uint index)
if (isAccessor) {
// free up both indices
- dd->arrayData[pidx + 1].tag = Value::Empty_Type;
- dd->arrayData[pidx + 1].uint_32 = dd->freeList;
- dd->arrayData[pidx].tag = Value::Undefined_Type;
- dd->arrayData[pidx].uint_32 = pidx + 1;
+ dd->arrayData[pidx + 1].setTagValue(Value::Empty_Type, Value::fromReturnedValue(dd->freeList).value());
+ dd->arrayData[pidx].setTagValue(Value::Undefined_Type, pidx + 1);
} else {
- dd->arrayData[pidx].tag = Value::Empty_Type;
- dd->arrayData[pidx].uint_32 = dd->freeList;
+ dd->arrayData[pidx].setTagValue(Value::Empty_Type, Value::fromReturnedValue(dd->freeList).value());
}
dd->freeList = pidx;
diff --git a/src/qml/jsruntime/qv4arraydata_p.h b/src/qml/jsruntime/qv4arraydata_p.h
index 667827d1e9..8be15fc866 100644
--- a/src/qml/jsruntime/qv4arraydata_p.h
+++ b/src/qml/jsruntime/qv4arraydata_p.h
@@ -49,8 +49,8 @@ namespace QV4 {
static const QV4::ArrayVTable static_vtbl; \
static inline const QV4::VTable *staticVTable() { return &static_vtbl.vTable; } \
V4_MANAGED_SIZE_TEST \
- const Data *d() const { return static_cast<const Data *>(m); } \
- Data *d() { return static_cast<Data *>(m); }
+ const Data *d() const { return static_cast<const Data *>(m()); } \
+ Data *d() { return static_cast<Data *>(m()); }
struct ArrayData;
@@ -86,7 +86,7 @@ struct ArrayData : public Base {
PropertyAttributes *attrs;
union {
uint len;
- uint freeList;
+ ReturnedValue freeList;
};
union {
uint offset;
@@ -239,8 +239,8 @@ struct Q_QML_EXPORT SparseArrayData : public ArrayData
V4_ARRAYDATA(SparseArrayData)
V4_NEEDS_DESTROY
- uint &freeList() { return d()->freeList; }
- uint freeList() const { return d()->freeList; }
+ ReturnedValue &freeList() { return d()->freeList; }
+ ReturnedValue freeList() const { return d()->freeList; }
SparseArray *sparse() const { return d()->sparse; }
void setSparse(SparseArray *s) { d()->sparse = s; }
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index 20ed07fa2e..667ea7025a 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -453,11 +453,11 @@ ReturnedValue ExecutionContext::getProperty(String *name)
return engine()->throwReferenceError(n);
}
-ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Heap::Object **base)
+ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Value *base)
{
Scope scope(this);
ScopedValue v(scope);
- *base = (Heap::Object *)0;
+ base->setM(0);
name->makeIdentifier(scope.engine);
if (name->equals(d()->engine->id_this()))
@@ -481,7 +481,7 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Heap::Object **
bool hasProperty = false;
v = w->get(name, &hasProperty);
if (hasProperty) {
- *base = w->d();
+ base->setM(w->d());
return v->asReturnedValue();
}
break;
@@ -523,7 +523,7 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Heap::Object **
bool hasProperty = false;
v = qml->get(name, &hasProperty);
if (hasProperty) {
- *base = qml->d();
+ base->setM(qml->d());
return v->asReturnedValue();
}
break;
diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h
index 8eda4ed12c..c698a6c9c3 100644
--- a/src/qml/jsruntime/qv4context_p.h
+++ b/src/qml/jsruntime/qv4context_p.h
@@ -155,7 +155,7 @@ struct Q_QML_EXPORT ExecutionContext : public Managed
void setProperty(String *name, const Value &value);
ReturnedValue getProperty(String *name);
- ReturnedValue getPropertyAndBase(String *name, Heap::Object **base);
+ ReturnedValue getPropertyAndBase(String *name, Value *base);
bool deleteProperty(String *name);
inline CallContext *asCallContext();
diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h
index 133a8d27e8..4bf0fd50a9 100644
--- a/src/qml/jsruntime/qv4dateobject_p.h
+++ b/src/qml/jsruntime/qv4dateobject_p.h
@@ -81,7 +81,7 @@ struct DateObject: Object {
template<>
inline const DateObject *Value::as() const {
- return isManaged() && m && m->vtable->type == Managed::Type_DateObject ? static_cast<const DateObject *>(this) : 0;
+ return isManaged() && m() && m()->vtable->type == Managed::Type_DateObject ? static_cast<const DateObject *>(this) : 0;
}
struct DateCtor: FunctionObject
diff --git a/src/qml/jsruntime/qv4debugging.cpp b/src/qml/jsruntime/qv4debugging.cpp
index 7bd5d49f3c..ab8cd629c5 100644
--- a/src/qml/jsruntime/qv4debugging.cpp
+++ b/src/qml/jsruntime/qv4debugging.cpp
@@ -800,7 +800,7 @@ void Debugger::Collector::collect(const QString &name, const ScopedValue &value)
addObject(name, value);
break;
case Value::Integer_Type:
- addInteger(name, value->int_32);
+ addInteger(name, value->int_32());
break;
default: // double
addDouble(name, value->doubleValue());
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index d4bcf363a2..7643e1fa66 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -485,7 +485,7 @@ void Heap::Base::mark(QV4::ExecutionEngine *engine)
inline void Value::mark(ExecutionEngine *e)
{
- if (!val)
+ if (!_val)
return;
Managed *m = as<Managed>();
if (m)
diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h
index da2c978e5f..2595801bf2 100644
--- a/src/qml/jsruntime/qv4errorobject_p.h
+++ b/src/qml/jsruntime/qv4errorobject_p.h
@@ -142,7 +142,7 @@ struct ErrorObject: Object {
template<>
inline const ErrorObject *Value::as() const {
- return isManaged() && m && m->vtable->isErrorObject ? reinterpret_cast<const ErrorObject *>(this) : 0;
+ return isManaged() && m() && m()->vtable->isErrorObject ? reinterpret_cast<const ErrorObject *>(this) : 0;
}
struct EvalErrorObject: ErrorObject {
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index 930b65156f..2ce3068dbd 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -149,7 +149,7 @@ struct Q_QML_EXPORT FunctionObject: Object {
template<>
inline const FunctionObject *Value::as() const {
- return isManaged() && m && m->vtable->isFunctionObject ? reinterpret_cast<const FunctionObject *>(this) : 0;
+ return isManaged() && m() && m()->vtable->isFunctionObject ? reinterpret_cast<const FunctionObject *>(this) : 0;
}
diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp
index d634e783bd..f703e85399 100644
--- a/src/qml/jsruntime/qv4jsonobject.cpp
+++ b/src/qml/jsruntime/qv4jsonobject.cpp
@@ -905,11 +905,11 @@ ReturnedValue JsonObject::method_stringify(CallContext *ctx)
if (v->as<NumberObject>() || v->as<StringObject>() || v->isNumber())
*v = RuntimeHelpers::toString(scope.engine, *v);
if (!v->isString()) {
- v->m = 0;
+ v->setM(0);
} else {
for (uint j = 0; j <i; ++j) {
- if (stringify.propertyList[j].m == v->m) {
- v->m = 0;
+ if (stringify.propertyList[j].m() == v->m()) {
+ v->setM(0);
break;
}
}
diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h
index 7cce80d087..e0ad0d89e3 100644
--- a/src/qml/jsruntime/qv4managed_p.h
+++ b/src/qml/jsruntime/qv4managed_p.h
@@ -68,7 +68,7 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
static const QV4::VTable static_vtbl; \
static inline const QV4::VTable *staticVTable() { return &static_vtbl; } \
V4_MANAGED_SIZE_TEST \
- QV4::Heap::DataClass *d() const { return static_cast<QV4::Heap::DataClass *>(m); }
+ QV4::Heap::DataClass *d() const { return static_cast<QV4::Heap::DataClass *>(m()); }
#define Q_MANAGED_TYPE(type) \
public: \
@@ -180,7 +180,7 @@ inline const Managed *Value::as() const {
template<>
inline const Object *Value::as() const {
- return isManaged() && m && m->vtable->isObject ? objectValue() : 0;
+ return isManaged() && m() && m()->vtable->isObject ? objectValue() : 0;
}
}
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index b4ad477e89..e5608a280f 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -514,10 +514,10 @@ void Object::setLookup(Managed *m, Lookup *l, const Value &value)
l->setter = Lookup::setterGeneric;
}
-void Object::advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name, uint *index, Property *pd, PropertyAttributes *attrs)
+void Object::advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *pd, PropertyAttributes *attrs)
{
Object *o = static_cast<Object *>(m);
- *name = 0;
+ name->setM(0);
*index = UINT_MAX;
if (o->arrayData()) {
@@ -572,7 +572,7 @@ void Object::advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name
PropertyAttributes a = o->internalClass()->propertyData[it->memberIndex];
++it->memberIndex;
if (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable()) {
- *name = o->engine()->newString(n->string);
+ name->setM(o->engine()->newString(n->string));
*attrs = a;
pd->copy(p, a);
return;
@@ -1028,9 +1028,9 @@ bool Object::__defineOwnProperty__(ExecutionEngine *engine, uint index, String *
} else { // clause 10
Q_ASSERT(cattrs.isAccessor() && attrs.isAccessor());
if (!cattrs.isConfigurable()) {
- if (!p->value.isEmpty() && current->value.val != p->value.val)
+ if (!p->value.isEmpty() && current->value.rawValue() != p->value.rawValue())
goto reject;
- if (!p->set.isEmpty() && current->set.val != p->set.val)
+ if (!p->set.isEmpty() && current->set.rawValue() != p->set.rawValue())
goto reject;
}
}
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 671e207489..24efaffd8d 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -68,7 +68,7 @@ struct Object : Base {
static const QV4::ObjectVTable static_vtbl; \
static inline const QV4::VTable *staticVTable() { return &static_vtbl.vTable; } \
V4_MANAGED_SIZE_TEST \
- Data *d() const { return static_cast<Data *>(m); }
+ Data *d() const { return static_cast<Data *>(m()); }
#define V4_OBJECT2(DataClass, superClass) \
public: \
@@ -78,7 +78,7 @@ struct Object : Base {
static const QV4::ObjectVTable static_vtbl; \
static inline const QV4::VTable *staticVTable() { return &static_vtbl.vTable; } \
V4_MANAGED_SIZE_TEST \
- QV4::Heap::DataClass *d() const { return static_cast<QV4::Heap::DataClass *>(m); }
+ QV4::Heap::DataClass *d() const { return static_cast<QV4::Heap::DataClass *>(m()); }
struct ObjectVTable
{
@@ -96,7 +96,7 @@ struct ObjectVTable
ReturnedValue (*getLookup)(const Managed *m, Lookup *l);
void (*setLookup)(Managed *m, Lookup *l, const Value &v);
uint (*getLength)(const Managed *m);
- void (*advanceIterator)(Managed *m, ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attributes);
+ void (*advanceIterator)(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
};
#define DEFINE_OBJECT_VTABLE(classname) \
@@ -291,7 +291,7 @@ public:
{ return vtable()->getLookup(this, l); }
void setLookup(Lookup *l, const Value &v)
{ vtable()->setLookup(this, l, v); }
- void advanceIterator(ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attributes)
+ void advanceIterator(ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes)
{ vtable()->advanceIterator(this, it, name, index, p, attributes); }
uint getLength() const { return vtable()->getLength(this); }
@@ -313,7 +313,7 @@ protected:
static bool deleteIndexedProperty(Managed *m, uint index);
static ReturnedValue getLookup(const Managed *m, Lookup *l);
static void setLookup(Managed *m, Lookup *l, const Value &v);
- static void advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attributes);
+ static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
static uint getLength(const Managed *m);
private:
@@ -332,7 +332,7 @@ namespace Heap {
inline Object::Object(ExecutionEngine *engine)
: internalClass(engine->emptyClass),
- prototype(static_cast<Object *>(engine->objectPrototype()->m))
+ prototype(static_cast<Object *>(engine->objectPrototype()->m()))
{
}
@@ -462,7 +462,7 @@ inline void Object::arraySet(uint index, const Value &value)
template<>
inline const ArrayObject *Value::as() const {
- return isManaged() && m && m->vtable->type == Managed::Type_ArrayObject ? static_cast<const ArrayObject *>(this) : 0;
+ return isManaged() && m() && m()->vtable->type == Managed::Type_ArrayObject ? static_cast<const ArrayObject *>(this) : 0;
}
#ifndef V4_BOOTSTRAP
diff --git a/src/qml/jsruntime/qv4objectiterator.cpp b/src/qml/jsruntime/qv4objectiterator.cpp
index d0e2650feb..585f9f5c2e 100644
--- a/src/qml/jsruntime/qv4objectiterator.cpp
+++ b/src/qml/jsruntime/qv4objectiterator.cpp
@@ -65,12 +65,12 @@ ObjectIterator::ObjectIterator(Scope &scope, const Object *o, uint flags)
void ObjectIterator::init(const Object *o)
{
- object->m = o ? o->m : 0;
- current->m = o ? o->m : 0;
+ object->setM(o ? o->m() : 0);
+ current->setM(o ? o->m() : 0);
#if QT_POINTER_SIZE == 4
- object->tag = QV4::Value::Managed_Type;
- current->tag = QV4::Value::Managed_Type;
+ object->setTag(QV4::Value::Managed_Type);
+ current->setTag(QV4::Value::Managed_Type);
#endif
if (object->as<ArgumentsObject>()) {
@@ -79,9 +79,9 @@ void ObjectIterator::init(const Object *o)
}
}
-void ObjectIterator::next(Heap::String **name, uint *index, Property *pd, PropertyAttributes *attrs)
+void ObjectIterator::next(Value *name, uint *index, Property *pd, PropertyAttributes *attrs)
{
- *name = 0;
+ name->setM(0);
*index = UINT_MAX;
if (!object->as<Object>()) {
@@ -120,9 +120,9 @@ void ObjectIterator::next(Heap::String **name, uint *index, Property *pd, Proper
}
if (flags & WithProtoChain)
- current->m = current->objectValue()->prototype();
+ current->setM(current->objectValue()->prototype());
else
- current->m = (Heap::Base *)0;
+ current->setM(0);
arrayIndex = 0;
memberIndex = 0;
diff --git a/src/qml/jsruntime/qv4objectiterator_p.h b/src/qml/jsruntime/qv4objectiterator_p.h
index ff568ba893..bfe04b33aa 100644
--- a/src/qml/jsruntime/qv4objectiterator_p.h
+++ b/src/qml/jsruntime/qv4objectiterator_p.h
@@ -59,7 +59,7 @@ struct Q_QML_EXPORT ObjectIterator
ObjectIterator(ExecutionEngine *e, Value *scratch1, Value *scratch2, Object *o, uint flags);
ObjectIterator(Scope &scope, const Object *o, uint flags);
void init(const Object *o);
- void next(Heap::String **name, uint *index, Property *pd, PropertyAttributes *attributes = 0);
+ void next(Value *name, uint *index, Property *pd, PropertyAttributes *attributes = 0);
ReturnedValue nextPropertyName(Value *value);
ReturnedValue nextPropertyNameAsString(Value *value);
ReturnedValue nextPropertyNameAsString();
diff --git a/src/qml/jsruntime/qv4persistent.cpp b/src/qml/jsruntime/qv4persistent.cpp
index a21bf696aa..7eca12f153 100644
--- a/src/qml/jsruntime/qv4persistent.cpp
+++ b/src/qml/jsruntime/qv4persistent.cpp
@@ -78,11 +78,11 @@ Page *allocatePage(PersistentValueStorage *storage)
if (p->header.next)
p->header.next->header.prev = &p->header.next;
for (int i = 0; i < kEntriesPerPage - 1; ++i) {
- p->values[i].tag = QV4::Value::Empty_Type;
- p->values[i].int_32 = i + 1;
+ p->values[i].setTag(QV4::Value::Empty_Type);
+ p->values[i].setInt_32(i + 1);
}
- p->values[kEntriesPerPage - 1].tag = QV4::Value::Empty_Type;
- p->values[kEntriesPerPage - 1].int_32 = -1;
+ p->values[kEntriesPerPage - 1].setTag(QV4::Value::Empty_Type);
+ p->values[kEntriesPerPage - 1].setInt_32(-1);
storage->firstPage = p;
@@ -97,7 +97,7 @@ PersistentValueStorage::Iterator &PersistentValueStorage::Iterator::operator++()
while (p) {
while (index < kEntriesPerPage - 1) {
++index;
- if (static_cast<Page *>(p)->values[index].tag != QV4::Value::Empty_Type)
+ if (static_cast<Page *>(p)->values[index].tag() != QV4::Value::Empty_Type)
return *this;
}
index = -1;
@@ -147,10 +147,10 @@ Value *PersistentValueStorage::allocate()
p = allocatePage(this);
Value *v = p->values + p->header.freeList;
- p->header.freeList = v->int_32;
+ p->header.freeList = v->int_32();
++p->header.refCount;
- v->val = Encode::undefined();
+ v->setRawValue(Encode::undefined());
return v;
}
@@ -162,8 +162,8 @@ void PersistentValueStorage::free(Value *v)
Page *p = getPage(v);
- v->tag = QV4::Value::Empty_Type;
- v->int_32 = p->header.freeList;
+ v->setTag(QV4::Value::Empty_Type);
+ v->setInt_32(p->header.freeList);
p->header.freeList = v - p->values;
if (!--p->header.refCount) {
if (p->header.prev)
diff --git a/src/qml/jsruntime/qv4property_p.h b/src/qml/jsruntime/qv4property_p.h
index 34d9cdadeb..db8c6017e1 100644
--- a/src/qml/jsruntime/qv4property_p.h
+++ b/src/qml/jsruntime/qv4property_p.h
@@ -88,8 +88,8 @@ struct Property {
set = reinterpret_cast<Managed *>(setter);
}
Property(Heap::FunctionObject *getter, Heap::FunctionObject *setter) {
- value.m = reinterpret_cast<Heap::Base *>(getter);
- set.m = reinterpret_cast<Heap::Base *>(setter);
+ value.setM(reinterpret_cast<Heap::Base *>(getter));
+ set.setM(reinterpret_cast<Heap::Base *>(setter));
}
Property &operator=(Value v) { value = v; return *this; }
private:
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 4f6331c54b..2ac1dfd446 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -733,14 +733,14 @@ PropertyAttributes QObjectWrapper::query(const Managed *m, String *name)
return QV4::Object::query(m, name);
}
-void QObjectWrapper::advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attributes)
+void QObjectWrapper::advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes)
{
// Used to block access to QObject::destroyed() and QObject::deleteLater() from QML
static const int destroyedIdx1 = QObject::staticMetaObject.indexOfSignal("destroyed(QObject*)");
static const int destroyedIdx2 = QObject::staticMetaObject.indexOfSignal("destroyed()");
static const int deleteLaterIdx = QObject::staticMetaObject.indexOfSlot("deleteLater()");
- *name = (Heap::String *)0;
+ name->setM(0);
*index = UINT_MAX;
QObjectWrapper *that = static_cast<QObjectWrapper*>(m);
@@ -753,7 +753,7 @@ void QObjectWrapper::advanceIterator(Managed *m, ObjectIterator *it, Heap::Strin
if (it->arrayIndex < static_cast<uint>(propertyCount)) {
Scope scope(that->engine());
ScopedString propName(scope, that->engine()->newString(QString::fromUtf8(mo->property(it->arrayIndex).name())));
- *name = propName->d();
+ name->setM(propName->d());
++it->arrayIndex;
*attributes = QV4::Attr_Data;
p->value = that->get(propName);
@@ -768,7 +768,7 @@ void QObjectWrapper::advanceIterator(Managed *m, ObjectIterator *it, Heap::Strin
continue;
Scope scope(that->engine());
ScopedString methodName(scope, that->engine()->newString(QString::fromUtf8(method.name())));
- *name = methodName->d();
+ name->setM(methodName->d());
*attributes = QV4::Attr_Data;
p->value = that->get(methodName);
return;
diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h
index 324f598ad9..f1bca6211c 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper_p.h
+++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h
@@ -131,7 +131,7 @@ private:
static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
static void put(Managed *m, String *name, const Value &value);
static PropertyAttributes query(const Managed *, String *name);
- static void advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attributes);
+ static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
static void markObjects(Heap::Base *that, QV4::ExecutionEngine *e);
static void destroy(Heap::Base *that);
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 3006ec9fe5..059df275db 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -468,7 +468,7 @@ Heap::String *RuntimeHelpers::convertToString(ExecutionEngine *engine, const Val
return RuntimeHelpers::convertToString(engine, prim);
}
case Value::Integer_Type:
- return RuntimeHelpers::stringFromNumber(engine, value.int_32);
+ return RuntimeHelpers::stringFromNumber(engine, value.int_32());
default: // double
return RuntimeHelpers::stringFromNumber(engine, value.doubleValue());
} // switch
@@ -499,7 +499,7 @@ static Heap::String *convert_to_string_add(ExecutionEngine *engine, const Value
return RuntimeHelpers::convertToString(engine, prim);
}
case Value::Integer_Type:
- return RuntimeHelpers::stringFromNumber(engine, value.int_32);
+ return RuntimeHelpers::stringFromNumber(engine, value.int_32());
default: // double
return RuntimeHelpers::stringFromNumber(engine, value.doubleValue());
} // switch
diff --git a/src/qml/jsruntime/qv4runtime_p.h b/src/qml/jsruntime/qv4runtime_p.h
index e8ebccc17b..f825732a6c 100644
--- a/src/qml/jsruntime/qv4runtime_p.h
+++ b/src/qml/jsruntime/qv4runtime_p.h
@@ -263,7 +263,7 @@ inline ReturnedValue Runtime::uPlus(const Value &value)
if (value.isNumber())
return value.asReturnedValue();
if (value.integerCompatible())
- return Encode(value.int_32);
+ return Encode(value.int_32());
double n = value.toNumberImpl();
return Encode(n);
diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h
index 02b038f247..e19aeaf882 100644
--- a/src/qml/jsruntime/qv4scopedvalue_p.h
+++ b/src/qml/jsruntime/qv4scopedvalue_p.h
@@ -107,7 +107,7 @@ struct ScopedValue
ScopedValue(const Scope &scope)
{
ptr = scope.engine->jsStackTop++;
- ptr->val = 0;
+ ptr->setRawValue(0);
#ifndef QT_NO_DEBUG
++scope.size;
#endif
@@ -125,9 +125,9 @@ struct ScopedValue
ScopedValue(const Scope &scope, Heap::Base *o)
{
ptr = scope.engine->jsStackTop++;
- ptr->m = o;
+ ptr->setM(o);
#if QT_POINTER_SIZE == 4
- ptr->tag = QV4::Value::Managed_Type;
+ ptr->setTag(QV4::Value::Managed_Type);
#endif
#ifndef QT_NO_DEBUG
++scope.size;
@@ -137,7 +137,7 @@ struct ScopedValue
ScopedValue(const Scope &scope, Managed *m)
{
ptr = scope.engine->jsStackTop++;
- ptr->val = m->asReturnedValue();
+ ptr->setRawValue(m->asReturnedValue());
#ifndef QT_NO_DEBUG
++scope.size;
#endif
@@ -146,7 +146,7 @@ struct ScopedValue
ScopedValue(const Scope &scope, const ReturnedValue &v)
{
ptr = scope.engine->jsStackTop++;
- ptr->val = v;
+ ptr->setRawValue(v);
#ifndef QT_NO_DEBUG
++scope.size;
#endif
@@ -158,9 +158,9 @@ struct ScopedValue
}
ScopedValue &operator=(Heap::Base *o) {
- ptr->m = o;
+ ptr->setM(o);
#if QT_POINTER_SIZE == 4
- ptr->tag = QV4::Value::Managed_Type;
+ ptr->setTag(QV4::Value::Managed_Type);
#endif
return *this;
}
@@ -171,7 +171,7 @@ struct ScopedValue
}
ScopedValue &operator=(const ReturnedValue &v) {
- ptr->val = v;
+ ptr->setRawValue(v);
return *this;
}
@@ -200,18 +200,18 @@ struct Scoped
enum _Convert { Convert };
inline void setPointer(const Managed *p) {
- ptr->m = p ? p->m : 0;
+ ptr->setM(p ? p->m() : 0);
#if QT_POINTER_SIZE == 4
- ptr->tag = QV4::Value::Managed_Type;
+ ptr->setTag(QV4::Value::Managed_Type);
#endif
}
Scoped(const Scope &scope)
{
ptr = scope.engine->jsStackTop++;
- ptr->m = 0;
+ ptr->setM(0);
#if QT_POINTER_SIZE == 4
- ptr->tag = QV4::Value::Managed_Type;
+ ptr->setTag(QV4::Value::Managed_Type);
#endif
#ifndef QT_NO_DEBUG
++scope.size;
@@ -248,7 +248,7 @@ struct Scoped
Scoped(const Scope &scope, const Value &v, _Convert)
{
ptr = scope.engine->jsStackTop++;
- ptr->val = value_convert<T>(scope.engine, v);
+ ptr->setRawValue(value_convert<T>(scope.engine, v));
#ifndef QT_NO_DEBUG
++scope.size;
#endif
@@ -291,7 +291,7 @@ struct Scoped
Scoped(const Scope &scope, const ReturnedValue &v, _Convert)
{
ptr = scope.engine->jsStackTop++;
- ptr->val = value_convert<T>(scope.engine, QV4::Value::fromReturnedValue(v));
+ ptr->setRawValue(value_convert<T>(scope.engine, QV4::Value::fromReturnedValue(v)));
#ifndef QT_NO_DEBUG
++scope.size;
#endif
@@ -341,21 +341,21 @@ struct Scoped
}
bool operator!() const {
- return !ptr->m;
+ return !ptr->m();
}
operator void *() const {
- return ptr->m;
+ return ptr->m();
}
T *getPointer() {
return ptr->cast<T>();
}
- typename T::Data **getRef() {
- return reinterpret_cast<typename T::Data **>(&ptr->m);
+ Value *getRef() {
+ return ptr;
}
ReturnedValue asReturnedValue() const {
- return ptr->m ? ptr->val : Encode::undefined();
+ return ptr->m() ? ptr->rawValue() : Encode::undefined();
}
Value *ptr;
@@ -384,14 +384,14 @@ struct ScopedCallData {
inline Value &Value::operator =(const ScopedValue &v)
{
- val = v.ptr->val;
+ _val = v.ptr->val();
return *this;
}
template<typename T>
inline Value &Value::operator=(const Scoped<T> &t)
{
- val = t.ptr->val;
+ _val = t.ptr->val();
return *this;
}
@@ -420,18 +420,18 @@ struct ExecutionContextSaver
: engine(context->d()->engine)
, savedContext(scope.alloc(1))
{
- savedContext->m = context->d();
+ savedContext->setM(context->d());
#if QT_POINTER_SIZE == 4
- savedContext->tag = QV4::Value::Managed_Type;
+ savedContext->setTag(QV4::Value::Managed_Type);
#endif
}
ExecutionContextSaver(Scope &scope, Heap::ExecutionContext *context)
: engine(context->engine)
, savedContext(scope.alloc(1))
{
- savedContext->m = context;
+ savedContext->setM(context);
#if QT_POINTER_SIZE == 4
- savedContext->tag = QV4::Value::Managed_Type;
+ savedContext->setTag(QV4::Value::Managed_Type);
#endif
}
~ExecutionContextSaver()
diff --git a/src/qml/jsruntime/qv4script_p.h b/src/qml/jsruntime/qv4script_p.h
index 015bfff56a..77784dfc4f 100644
--- a/src/qml/jsruntime/qv4script_p.h
+++ b/src/qml/jsruntime/qv4script_p.h
@@ -63,7 +63,7 @@ struct ContextStateSaver {
, compilationUnit(context->d()->compilationUnit)
, lineNumber(context->d()->lineNumber)
{
- savedContext->m = context->d();
+ savedContext->setM(context->d());
}
ContextStateSaver(Scope &scope, Heap::ExecutionContext *context)
: savedContext(scope.alloc(1))
@@ -72,12 +72,12 @@ struct ContextStateSaver {
, compilationUnit(context->compilationUnit)
, lineNumber(context->lineNumber)
{
- savedContext->m = context;
+ savedContext->setM(context);
}
~ContextStateSaver()
{
- Heap::ExecutionContext *ctx = static_cast<Heap::ExecutionContext *>(savedContext->m);
+ Heap::ExecutionContext *ctx = static_cast<Heap::ExecutionContext *>(savedContext->m());
ctx->strictMode = strictMode;
ctx->lookups = lookups;
ctx->compilationUnit = compilationUnit;
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp
index 4fba65d396..23bbcc60e1 100644
--- a/src/qml/jsruntime/qv4sequenceobject.cpp
+++ b/src/qml/jsruntime/qv4sequenceobject.cpp
@@ -316,9 +316,9 @@ public:
return (signedIdx < d()->container.count()) ? QV4::Attr_Data : QV4::Attr_Invalid;
}
- void containerAdvanceIterator(ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attrs)
+ void containerAdvanceIterator(ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attrs)
{
- *name = (Heap::String *)0;
+ name->setM(0);
*index = UINT_MAX;
if (d()->isReference) {
@@ -536,7 +536,7 @@ public:
{ return static_cast<QQmlSequence<Container> *>(that)->containerDeleteIndexedProperty(index); }
static bool isEqualTo(Managed *that, Managed *other)
{ return static_cast<QQmlSequence<Container> *>(that)->containerIsEqualTo(other); }
- static void advanceIterator(Managed *that, ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attrs)
+ static void advanceIterator(Managed *that, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attrs)
{ return static_cast<QQmlSequence<Container> *>(that)->containerAdvanceIterator(it, name, index, p, attrs); }
};
diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h
index b133f68b20..cf796a03c6 100644
--- a/src/qml/jsruntime/qv4string_p.h
+++ b/src/qml/jsruntime/qv4string_p.h
@@ -186,7 +186,7 @@ public:
template<>
inline const String *Value::as() const {
- return isManaged() && m && m->vtable->isString ? static_cast<const String *>(this) : 0;
+ return isManaged() && m() && m()->vtable->isString ? static_cast<const String *>(this) : 0;
}
#ifndef V4_BOOTSTRAP
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index 402ab420fc..a6b59b0b53 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -116,9 +116,9 @@ bool StringObject::deleteIndexedProperty(Managed *m, uint index)
return true;
}
-void StringObject::advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attrs)
+void StringObject::advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attrs)
{
- *name = (Heap::String *)0;
+ name->setM(0);
StringObject *s = static_cast<StringObject *>(m);
uint slen = s->d()->string->toQString().length();
if (it->arrayIndex <= slen) {
diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h
index 709b73f0bb..aa56a79bc3 100644
--- a/src/qml/jsruntime/qv4stringobject_p.h
+++ b/src/qml/jsruntime/qv4stringobject_p.h
@@ -72,7 +72,7 @@ struct StringObject: Object {
static bool deleteIndexedProperty(Managed *m, uint index);
protected:
- static void advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attrs);
+ static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attrs);
static void markObjects(Heap::Base *that, ExecutionEngine *e);
};
diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp
index f5b81fb6f7..fcc6f3dc5d 100644
--- a/src/qml/jsruntime/qv4typedarray.cpp
+++ b/src/qml/jsruntime/qv4typedarray.cpp
@@ -258,7 +258,7 @@ ReturnedValue TypedArrayCtor::construct(const Managed *m, CallData *callData)
TypedArrayWrite write =array->d()->type->write;
for (uint i = 0; i < l; ++i) {
Primitive val;
- val.val = read(src, i*srcElementSize);
+ val.setRawValue(read(src, i*srcElementSize));
write(scope.engine, dest, i*destElementSize, val);
}
}
@@ -524,7 +524,7 @@ ReturnedValue TypedArrayPrototype::method_set(CallContext *ctx)
TypedArrayWrite write = a->d()->type->write;
for (uint i = 0; i < l; ++i) {
Primitive val;
- val.val = read(src, i*srcElementSize);
+ val.setRawValue(read(src, i*srcElementSize));
write(scope.engine, dest, i*elementSize, val);
}
diff --git a/src/qml/jsruntime/qv4value.cpp b/src/qml/jsruntime/qv4value.cpp
index d659d02c3b..4c81199a07 100644
--- a/src/qml/jsruntime/qv4value.cpp
+++ b/src/qml/jsruntime/qv4value.cpp
@@ -77,7 +77,7 @@ bool Value::toBoolean() const
return false;
case Value::Boolean_Type:
case Value::Integer_Type:
- return (bool)int_32;
+ return (bool)int_32();
case Value::Managed_Type:
#ifdef V4_BOOTSTRAP
Q_UNIMPLEMENTED();
@@ -94,7 +94,7 @@ bool Value::toBoolean() const
double Value::toInteger() const
{
if (integerCompatible())
- return int_32;
+ return int_32();
return Primitive::toInteger(toNumber());
}
@@ -122,7 +122,7 @@ double Value::toNumberImpl() const
case QV4::Value::Null_Type:
case QV4::Value::Boolean_Type:
case QV4::Value::Integer_Type:
- return int_32;
+ return int_32();
default: // double
Q_UNREACHABLE();
}
@@ -171,7 +171,7 @@ QString Value::toQStringNoThrow() const
}
case Value::Integer_Type: {
QString str;
- RuntimeHelpers::numberToString(&str, (double)int_32, 10);
+ RuntimeHelpers::numberToString(&str, (double)int_32(), 10);
return str;
}
default: { // double
@@ -207,7 +207,7 @@ QString Value::toQString() const
}
case Value::Integer_Type: {
QString str;
- RuntimeHelpers::numberToString(&str, (double)int_32, 10);
+ RuntimeHelpers::numberToString(&str, (double)int_32(), 10);
return str;
}
default: { // double
@@ -220,14 +220,14 @@ QString Value::toQString() const
#endif // V4_BOOTSTRAP
bool Value::sameValue(Value other) const {
- if (val == other.val)
+ if (_val == other._val)
return true;
if (isString() && other.isString())
return stringValue()->isEqualTo(other.stringValue());
if (isInteger() && other.isDouble())
- return int_32 ? (double(int_32) == other.doubleValue()) : (other.val == 0);
+ return int_32() ? (double(int_32()) == other.doubleValue()) : (other._val == 0);
if (isDouble() && other.isInteger())
- return other.int_32 ? (doubleValue() == double(other.int_32)) : (val == 0);
+ return other.int_32() ? (doubleValue() == double(other.int_32())) : (_val == 0);
return false;
}
@@ -308,8 +308,8 @@ uint Value::asArrayLength(bool *ok) const
{
*ok = true;
if (isInteger()) {
- if (int_32 >= 0) {
- return (uint)int_32;
+ if (int_32() >= 0) {
+ return (uint)int_32();
} else {
*ok = false;
return UINT_MAX;
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index 7454cbfff4..30cdcaa1cb 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -39,6 +39,14 @@
#include "qv4global_p.h"
#include <private/qv4heap_p.h>
+#if defined(Q_CC_GNU)
+# define Q_ALWAYS_INLINE inline __attribute__((always_inline))
+#elif defined(Q_CC_MSVC)
+# define Q_ALWAYS_INLINE __forceinline
+#else
+# define Q_ALWAYS_INLINE inline
+#endif
+
QT_BEGIN_NAMESPACE
namespace QV4 {
@@ -73,30 +81,38 @@ struct Q_QML_PRIVATE_EXPORT Value
Bit 15-17 is then used to encode other immediates.
*/
+ quint64 _val;
+
+ Q_ALWAYS_INLINE quint64 val() const { return _val; }
+ Q_ALWAYS_INLINE void setVal(quint64 v) { _val = v; }
+ Q_ALWAYS_INLINE void setValue(quint32 v) { setTagValue(tag(), v); }
+ Q_ALWAYS_INLINE void setTag(quint32 t) { setTagValue(t, value()); }
- union {
- quint64 val;
-#if QT_POINTER_SIZE == 8
- Heap::Base *m;
-#else
- double dbl;
-#endif
- struct {
-#if Q_BYTE_ORDER != Q_LITTLE_ENDIAN
- uint tag;
-#endif
- union {
- uint uint_32;
- int int_32;
-#if QT_POINTER_SIZE == 4
- Heap::Base *m;
-#endif
- };
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- uint tag;
+ static inline int valueOffset() { return 0; }
+ static inline int tagOffset() { return 4; }
+ Q_ALWAYS_INLINE void setTagValue(quint32 tag, quint32 value) { _val = quint64(tag) << 32 | value; }
+ Q_ALWAYS_INLINE quint32 value() const { return _val & quint64(~quint32(0)); }
+ Q_ALWAYS_INLINE quint32 tag() const { return _val >> 32; }
+#else // !Q_LITTLE_ENDIAN
+ static inline int valueOffset() { return 4; }
+ static inline int tagOffset() { return 0; }
+ Q_ALWAYS_INLINE void setTagValue(quint32 tag, quint32 value) { _val = quint64(value) << 32 | tag; }
+ Q_ALWAYS_INLINE quint32 tag() const { return _val & quint64(~quint32(0)); }
+ Q_ALWAYS_INLINE quint32 value() const { return _val >> 32; }
+#endif
+
+#if QT_POINTER_SIZE == 8
+ Q_ALWAYS_INLINE Heap::Base *m() const { Heap::Base *b; memcpy(&b, &_val, 8); return b; }
+ Q_ALWAYS_INLINE void setM(Heap::Base *b) { memcpy(&_val, &b, 8); }
+#else // QT_POINTER_SIZE == 4
+ Q_ALWAYS_INLINE Heap::Base *m() const { Heap::Base *b; quint32 v = value(); memcpy(&b, &v, 4); return b; }
+ Q_ALWAYS_INLINE void setM(Heap::Base *b) { quint32 v; memcpy(&v, &b, 4); setValue(v); }
#endif
- };
- };
+
+ Q_ALWAYS_INLINE int int_32() const { int i; quint32 v = value(); memcpy(&i, &v, 4); return i; }
+ Q_ALWAYS_INLINE void setInt_32(int i) { quint32 u; memcpy(&u, &i, 4); setValue(u); }
+ Q_ALWAYS_INLINE uint uint_32() const { return value(); }
#if QT_POINTER_SIZE == 4
enum Masks {
@@ -169,116 +185,118 @@ struct Q_QML_PRIVATE_EXPORT Value
#endif
inline unsigned type() const {
- return tag & Type_Mask;
+ return tag() & Type_Mask;
}
// used internally in property
- inline bool isEmpty() const { return tag == Empty_Type; }
+ inline bool isEmpty() const { return tag() == Empty_Type; }
- inline bool isUndefined() const { return tag == Undefined_Type; }
- inline bool isNull() const { return tag == _Null_Type; }
- inline bool isBoolean() const { return tag == _Boolean_Type; }
+ inline bool isUndefined() const { return tag() == Undefined_Type; }
+ inline bool isNull() const { return tag() == _Null_Type; }
+ inline bool isBoolean() const { return tag ()== _Boolean_Type; }
#if QT_POINTER_SIZE == 8
- inline bool isInteger() const { return (val >> IsNumber_Shift) == 1; }
- inline bool isDouble() const { return (val >> IsDouble_Shift); }
- inline bool isNumber() const { return (val >> IsNumber_Shift); }
- inline bool isManaged() const { return !(val >> IsManaged_Shift); }
- inline bool isNullOrUndefined() const { return ((val >> IsManaged_Shift) & ~2) == 1; }
- inline bool integerCompatible() const { return ((val >> IsConvertibleToInt_Shift) & ~2) == 1; }
+ inline bool isInteger() const { return (_val >> IsNumber_Shift) == 1; }
+ inline bool isDouble() const { return (_val >> IsDouble_Shift); }
+ inline bool isNumber() const { return (_val >> IsNumber_Shift); }
+ inline bool isManaged() const { return !(_val >> IsManaged_Shift); }
+ inline bool isNullOrUndefined() const { return ((_val >> IsManaged_Shift) & ~2) == 1; }
+ inline bool integerCompatible() const { return ((_val >> IsConvertibleToInt_Shift) & ~2) == 1; }
static inline bool integerCompatible(Value a, Value b) {
return a.integerCompatible() && b.integerCompatible();
}
static inline bool bothDouble(Value a, Value b) {
return a.isDouble() && b.isDouble();
}
- double doubleValue() const {
- Q_ASSERT(isDouble());
- union {
- quint64 i;
- double d;
- } v;
- v.i = val ^ NaNEncodeMask;
- return v.d;
- }
- void setDouble(double d) {
- union {
- quint64 i;
- double d;
- } v;
- v.d = d;
- val = v.i ^ NaNEncodeMask;
- Q_ASSERT(isDouble());
- }
- inline bool isNaN() const { return (tag & 0x7fff8000) == 0x00078000; }
+ inline bool isNaN() const { return (tag() & 0x7fff8000) == 0x00078000; }
#else
- inline bool isInteger() const { return tag == _Integer_Type; }
- inline bool isDouble() const { return (tag & NotDouble_Mask) != NotDouble_Mask; }
- inline bool isNumber() const { return tag == _Integer_Type || (tag & NotDouble_Mask) != NotDouble_Mask; }
- inline bool isManaged() const { return tag == Managed_Type; }
- inline bool isNullOrUndefined() const { return (tag & IsNullOrUndefined_Mask) == Undefined_Type; }
- inline bool integerCompatible() const { return (tag & ConvertibleToInt) == ConvertibleToInt; }
+ inline bool isInteger() const { return tag() == _Integer_Type; }
+ inline bool isDouble() const { return (tag() & NotDouble_Mask) != NotDouble_Mask; }
+ inline bool isNumber() const { return tag() == _Integer_Type || (tag() & NotDouble_Mask) != NotDouble_Mask; }
+ inline bool isManaged() const { return tag() == Managed_Type; }
+ inline bool isNullOrUndefined() const { return (tag() & IsNullOrUndefined_Mask) == Undefined_Type; }
+ inline bool integerCompatible() const { return (tag() & ConvertibleToInt) == ConvertibleToInt; }
static inline bool integerCompatible(Value a, Value b) {
- return ((a.tag & b.tag) & ConvertibleToInt) == ConvertibleToInt;
+ return ((a.tag() & b.tag()) & ConvertibleToInt) == ConvertibleToInt;
}
static inline bool bothDouble(Value a, Value b) {
- return ((a.tag | b.tag) & NotDouble_Mask) != NotDouble_Mask;
+ return ((a.tag() | b.tag()) & NotDouble_Mask) != NotDouble_Mask;
+ }
+ inline bool isNaN() const { return (tag() & QV4::Value::NotDouble_Mask) == QV4::Value::NaN_Mask; }
+#endif
+ Q_ALWAYS_INLINE double doubleValue() const {
+ Q_ASSERT(isDouble());
+ double d;
+ quint64 v = _val;
+#if QT_POINTER_SIZE == 8
+ v ^= NaNEncodeMask;
+#endif
+ memcpy(&d, &v, 8);
+ return d;
}
- double doubleValue() const { Q_ASSERT(isDouble()); return dbl; }
- void setDouble(double d) { dbl = d; Q_ASSERT(isDouble()); }
- inline bool isNaN() const { return (tag & QV4::Value::NotDouble_Mask) == QV4::Value::NaN_Mask; }
+ Q_ALWAYS_INLINE void setDouble(double d) {
+ memcpy(&_val, &d, 8);
+#if QT_POINTER_SIZE == 8
+ _val ^= NaNEncodeMask;
#endif
+ Q_ASSERT(isDouble());
+ }
inline bool isString() const;
inline bool isObject() const;
inline bool isInt32() {
- if (tag == _Integer_Type)
+ if (tag() == _Integer_Type)
return true;
if (isDouble()) {
double d = doubleValue();
int i = (int)d;
if (i == d) {
- int_32 = i;
- tag = _Integer_Type;
+ setInt_32(i);
+ setTag(_Integer_Type);
return true;
}
}
return false;
}
double asDouble() const {
- if (tag == _Integer_Type)
- return int_32;
+ if (tag() == _Integer_Type)
+ return int_32();
return doubleValue();
}
bool booleanValue() const {
- return int_32;
+ return int_32();
}
int integerValue() const {
- return int_32;
+ return int_32();
}
- String *stringValue() const {
- return m ? reinterpret_cast<String*>(const_cast<Value *>(this)) : 0;
+ Q_ALWAYS_INLINE String *stringValue() const {
+ return m() ? reinterpret_cast<String*>(const_cast<Value *>(this)) : 0;
}
- Object *objectValue() const {
- return m ? reinterpret_cast<Object*>(const_cast<Value *>(this)) : 0;
+ Q_ALWAYS_INLINE Object *objectValue() const {
+ return m() ? reinterpret_cast<Object*>(const_cast<Value *>(this)) : 0;
}
- Managed *managed() const {
- return m ? reinterpret_cast<Managed*>(const_cast<Value *>(this)) : 0;
+ Q_ALWAYS_INLINE Managed *managed() const {
+ return m() ? reinterpret_cast<Managed*>(const_cast<Value *>(this)) : 0;
}
- Heap::Base *heapObject() const {
- return m;
+ Q_ALWAYS_INLINE Heap::Base *heapObject() const {
+ return m();
}
- quint64 rawValue() const {
- return val;
+ Q_ALWAYS_INLINE quint64 &rawValueRef() {
+ return _val;
+ }
+ Q_ALWAYS_INLINE quint64 rawValue() const {
+ return _val;
}
+ Q_ALWAYS_INLINE void setRawValue(quint64 raw) { _val = raw; }
static inline Value fromHeapObject(Heap::Base *m)
{
Value v;
- v.m = m;
+ v.setRawValue(0);
+ v.setM(m);
#if QT_POINTER_SIZE == 4
- v.tag = Managed_Type;
+ v.setTag(Managed_Type);
#endif
return v;
}
@@ -300,20 +318,20 @@ struct Q_QML_PRIVATE_EXPORT Value
inline bool tryIntegerConversion() {
bool b = integerCompatible();
if (b)
- tag = _Integer_Type;
+ setTag(_Integer_Type);
return b;
}
template <typename T>
const T *as() const {
- if (!m || !isManaged())
+ if (!m() || !isManaged())
return 0;
- Q_ASSERT(m->vtable);
+ Q_ASSERT(m()->vtable);
#if !defined(QT_NO_QOBJECT_CHECK)
static_cast<const T *>(this)->qt_check_for_QMANAGED_macro(static_cast<const T *>(this));
#endif
- const VTable *vt = m->vtable;
+ const VTable *vt = m()->vtable;
while (vt) {
if (vt == T::staticVTable())
return static_cast<const T *>(this);
@@ -338,8 +356,8 @@ struct Q_QML_PRIVATE_EXPORT Value
uint asArrayLength(bool *ok) const;
#endif
- ReturnedValue asReturnedValue() const { return val; }
- static Value fromReturnedValue(ReturnedValue val) { Value v; v.val = val; return v; }
+ ReturnedValue asReturnedValue() const { return _val; }
+ static Value fromReturnedValue(ReturnedValue val) { Value v; v._val = val; return v; }
// Section 9.12
bool sameValue(Value other) const;
@@ -347,20 +365,19 @@ struct Q_QML_PRIVATE_EXPORT Value
inline void mark(ExecutionEngine *e);
Value &operator =(const ScopedValue &v);
- Value &operator=(ReturnedValue v) { val = v; return *this; }
+ Value &operator=(ReturnedValue v) { _val = v; return *this; }
Value &operator=(Managed *m) {
if (!m) {
- tag = Undefined_Type;
- uint_32 = 0;
+ setTagValue(Undefined_Type, 0);
} else {
- val = reinterpret_cast<Value *>(m)->val;
+ _val = reinterpret_cast<Value *>(m)->_val;
}
return *this;
}
Value &operator=(Heap::Base *o) {
- m = o;
+ setM(o);
#if QT_POINTER_SIZE == 4
- tag = Managed_Type;
+ setTag(Managed_Type);
#endif
return *this;
}
@@ -368,7 +385,7 @@ struct Q_QML_PRIVATE_EXPORT Value
template<typename T>
Value &operator=(const Scoped<T> &t);
Value &operator=(const Value &v) {
- val = v.val;
+ _val = v._val;
return *this;
}
};
@@ -377,13 +394,13 @@ inline bool Value::isString() const
{
if (!isManaged())
return false;
- return m && m->vtable->isString;
+ return m() && m()->vtable->isString;
}
inline bool Value::isObject() const
{
if (!isManaged())
return false;
- return m && m->vtable->isObject;
+ return m() && m()->vtable->isObject;
}
inline bool Value::isPrimitive() const
@@ -394,7 +411,7 @@ inline bool Value::isPrimitive() const
inline double Value::toNumber() const
{
if (isInteger())
- return int_32;
+ return int_32();
if (isDouble())
return doubleValue();
return toNumberImpl();
@@ -408,10 +425,10 @@ inline uint Value::asArrayIndex() const
if (!isNumber())
return UINT_MAX;
if (isInteger())
- return int_32 >= 0 ? (uint)int_32 : UINT_MAX;
+ return int_32() >= 0 ? (uint)int_32() : UINT_MAX;
#else
- if (isInteger() && int_32 >= 0)
- return (uint)int_32;
+ if (isInteger() && int_32() >= 0)
+ return (uint)int_32();
if (!isDouble())
return UINT_MAX;
#endif
@@ -453,10 +470,11 @@ inline Primitive Primitive::undefinedValue()
{
Primitive v;
#if QT_POINTER_SIZE == 8
- v.val = quint64(Undefined_Type) << Tag_Shift;
+ v.setRawValue(quint64(Undefined_Type) << Tag_Shift);
#else
- v.tag = Undefined_Type;
- v.int_32 = 0;
+ v.setRawValue(0);
+ v.setTag(Undefined_Type);
+ v.setValue(0);
#endif
return v;
}
@@ -464,8 +482,7 @@ inline Primitive Primitive::undefinedValue()
inline Primitive Primitive::emptyValue()
{
Primitive v;
- v.tag = Value::Empty_Type;
- v.uint_32 = 0;
+ v.setTagValue(Value::Empty_Type, 0);
return v;
}
@@ -473,10 +490,9 @@ inline Primitive Primitive::nullValue()
{
Primitive v;
#if QT_POINTER_SIZE == 8
- v.val = quint64(_Null_Type) << Tag_Shift;
+ v.setRawValue(quint64(_Null_Type) << Tag_Shift);
#else
- v.tag = _Null_Type;
- v.int_32 = 0;
+ v.setTagValue(_Null_Type, 0);
#endif
return v;
}
@@ -484,8 +500,7 @@ inline Primitive Primitive::nullValue()
inline Primitive Primitive::fromBoolean(bool b)
{
Primitive v;
- v.tag = _Boolean_Type;
- v.int_32 = (bool)b;
+ v.setTagValue(_Boolean_Type, b);
return v;
}
@@ -499,8 +514,8 @@ inline Primitive Primitive::fromDouble(double d)
inline Primitive Primitive::fromInt32(int i)
{
Primitive v;
- v.tag = _Integer_Type;
- v.int_32 = i;
+ v.setTagValue(_Integer_Type, 0); // For mingw482, because it complains, and for VS9, because of internal compiler errors.
+ v.setInt_32(i);
return v;
}
@@ -508,8 +523,8 @@ inline Primitive Primitive::fromUInt32(uint i)
{
Primitive v;
if (i < INT_MAX) {
- v.tag = _Integer_Type;
- v.int_32 = (int)i;
+ v.setTagValue(_Integer_Type, 0); // For mingw482, because it complains, and for VS9, because of internal compiler errors.
+ v.setInt_32((int)i);
} else {
v.setDouble(i);
}
@@ -530,7 +545,7 @@ struct Encode {
Encode(double d) {
Value v;
v.setDouble(d);
- val = v.val;
+ val = v.rawValue();
}
Encode(int i) {
val = (quint64(Value::_Integer_Type) << Value::Tag_Shift) | (uint)i;
@@ -541,7 +556,7 @@ struct Encode {
} else {
Value v;
v.setDouble(i);
- val = v.val;
+ val = v.rawValue();
}
}
Encode(ReturnedValue v) {
@@ -567,7 +582,7 @@ ReturnedValue value_convert(ExecutionEngine *e, const Value &v);
inline int Value::toInt32() const
{
if (isInteger())
- return int_32;
+ return int_32();
double d = isNumber() ? doubleValue() : toNumberImpl();
const double D32 = 4294967296.0;
diff --git a/src/qml/qml/qqmllistwrapper.cpp b/src/qml/qml/qqmllistwrapper.cpp
index e9ecefb56d..d09f4df54c 100644
--- a/src/qml/qml/qqmllistwrapper.cpp
+++ b/src/qml/qml/qqmllistwrapper.cpp
@@ -138,9 +138,9 @@ void QmlListWrapper::put(Managed *m, String *name, const Value &value)
Q_UNUSED(value);
}
-void QmlListWrapper::advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attrs)
+void QmlListWrapper::advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attrs)
{
- *name = (Heap::String *)0;
+ name->setM(0);
*index = UINT_MAX;
Q_ASSERT(m->as<QmlListWrapper>());
QmlListWrapper *w = static_cast<QmlListWrapper *>(m);
diff --git a/src/qml/qml/qqmllistwrapper_p.h b/src/qml/qml/qqmllistwrapper_p.h
index 7e305b9e43..ff006d4302 100644
--- a/src/qml/qml/qqmllistwrapper_p.h
+++ b/src/qml/qml/qqmllistwrapper_p.h
@@ -84,7 +84,7 @@ struct Q_QML_EXPORT QmlListWrapper : Object
static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty);
static void put(Managed *m, String *name, const Value &value);
- static void advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attributes);
+ static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
};
}
diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h
index 55e4b15b77..5d12244dcb 100644
--- a/src/qml/qml/v8/qv8engine_p.h
+++ b/src/qml/qml/v8/qv8engine_p.h
@@ -133,7 +133,7 @@ private:
const QV4::Value &global, QQmlContextData *c, QV4::ExecutionEngine *e)
: callData(callData), retVal(retVal), ctx(c), e(e)
{
- callData->thisObject.val = global.asReturnedValue();
+ callData->thisObject = QV4::Value::fromReturnedValue(global.asReturnedValue());
}
QV4::CallData *callData;