forked from pool/libqt5-qtdeclarative
23b3dad336
- Add new version of V4-Free-up-2-address-bits-in-64bit-mode.patch * Fix testcase failure (boo#989341, QTBUG#54822) - Only apply patch on AArch64 to avoid regressions where patch not needed (it's experimental) - Add upstream patches for aarch64 with VA_BITS=48 (boo#989341, QTBUG#54822) * V4-Always-set-the-tag-when-boxing-a-pointer.patch * Add-a-facility-to-version-type-information.patch * V4-Free-up-2-address-bits-in-64bit-mode.patchv4-set-tag.patch OBS-URL: https://build.opensuse.org/request/show/433174 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/libqt5-qtdeclarative?expand=0&rev=34
779 lines
41 KiB
Diff
779 lines
41 KiB
Diff
From 60c669f13fd331788a2e2aab8af926d6aa7c46a6 Mon Sep 17 00:00:00 2001
|
|
From: Erik Verbruggen <erik.verbruggen@digia.com>
|
|
Date: Fri, 23 Sep 2016 11:34:12 +0200
|
|
Subject: [PATCH] V4: Free up 2 address bits in 64bit mode
|
|
|
|
This allows for the OS to use 49 address bits. It also maps JS Undefined
|
|
to the C++ nullptr on 64bit.
|
|
|
|
Task-number: QTBUG-54822
|
|
Change-Id: I7cc90620f499be1506a61aac77d72d067308838c
|
|
---
|
|
src/qml/debugger/qqmldebug.cpp | 2 +-
|
|
src/qml/jit/qv4assembler.cpp | 38 +++++-
|
|
src/qml/jit/qv4assembler_p.h | 5 +
|
|
src/qml/jit/qv4isel_masm.cpp | 98 ++++++++++----
|
|
src/qml/jit/qv4isel_masm_p.h | 4 +-
|
|
src/qml/jsruntime/qv4scopedvalue_p.h | 2 +-
|
|
src/qml/jsruntime/qv4value_p.h | 246 ++++++++++++++++++++---------------
|
|
src/qml/jsruntime/qv4vme_moth.cpp | 26 ++--
|
|
8 files changed, 269 insertions(+), 152 deletions(-)
|
|
|
|
Index: qtdeclarative-opensource-src-5.6.1/src/qml/debugger/qqmldebug.cpp
|
|
===================================================================
|
|
--- qtdeclarative-opensource-src-5.6.1.orig/src/qml/debugger/qqmldebug.cpp
|
|
+++ qtdeclarative-opensource-src-5.6.1/src/qml/debugger/qqmldebug.cpp
|
|
@@ -132,7 +132,7 @@ quintptr Q_QML_EXPORT qtDeclarativeHookD
|
|
// TypeInformationVersion, an integral value, bumped whenever private
|
|
// object sizes or member offsets that are used in Qt Creator's
|
|
// data structure "pretty printing" change.
|
|
- 1
|
|
+ 2
|
|
};
|
|
|
|
Q_STATIC_ASSERT(HookCount == sizeof(qtDeclarativeHookData) / sizeof(qtDeclarativeHookData[0]));
|
|
Index: qtdeclarative-opensource-src-5.6.1/src/qml/jit/qv4assembler.cpp
|
|
===================================================================
|
|
--- qtdeclarative-opensource-src-5.6.1.orig/src/qml/jit/qv4assembler.cpp
|
|
+++ qtdeclarative-opensource-src-5.6.1/src/qml/jit/qv4assembler.cpp
|
|
@@ -133,8 +133,30 @@ void Assembler::generateCJumpOnNonZero(R
|
|
generateCJumpOnCompare(NotEqual, reg, TrustedImm32(0), currentBlock, trueBlock, falseBlock);
|
|
}
|
|
|
|
-void Assembler::generateCJumpOnCompare(RelationalCondition cond, RegisterID left,TrustedImm32 right,
|
|
- IR::BasicBlock *currentBlock, IR::BasicBlock *trueBlock,
|
|
+#ifdef QV4_USE_64_BIT_VALUE_ENCODING
|
|
+void Assembler::generateCJumpOnCompare(RelationalCondition cond,
|
|
+ RegisterID left,
|
|
+ TrustedImm64 right,
|
|
+ IR::BasicBlock *currentBlock,
|
|
+ IR::BasicBlock *trueBlock,
|
|
+ IR::BasicBlock *falseBlock)
|
|
+{
|
|
+ if (trueBlock == _nextBlock) {
|
|
+ Jump target = branch64(invert(cond), left, right);
|
|
+ addPatch(falseBlock, target);
|
|
+ } else {
|
|
+ Jump target = branch64(cond, left, right);
|
|
+ addPatch(trueBlock, target);
|
|
+ jumpToBlock(currentBlock, falseBlock);
|
|
+ }
|
|
+}
|
|
+#endif
|
|
+
|
|
+void Assembler::generateCJumpOnCompare(RelationalCondition cond,
|
|
+ RegisterID left,
|
|
+ TrustedImm32 right,
|
|
+ IR::BasicBlock *currentBlock,
|
|
+ IR::BasicBlock *trueBlock,
|
|
IR::BasicBlock *falseBlock)
|
|
{
|
|
if (trueBlock == _nextBlock) {
|
|
@@ -147,8 +169,11 @@ void Assembler::generateCJumpOnCompare(R
|
|
}
|
|
}
|
|
|
|
-void Assembler::generateCJumpOnCompare(RelationalCondition cond, RegisterID left, RegisterID right,
|
|
- IR::BasicBlock *currentBlock, IR::BasicBlock *trueBlock,
|
|
+void Assembler::generateCJumpOnCompare(RelationalCondition cond,
|
|
+ RegisterID left,
|
|
+ RegisterID right,
|
|
+ IR::BasicBlock *currentBlock,
|
|
+ IR::BasicBlock *trueBlock,
|
|
IR::BasicBlock *falseBlock)
|
|
{
|
|
if (trueBlock == _nextBlock) {
|
|
@@ -334,9 +359,8 @@ Assembler::Jump Assembler::genTryDoubleC
|
|
// not an int, check if it's a double:
|
|
isNoInt.link(this);
|
|
#ifdef QV4_USE_64_BIT_VALUE_ENCODING
|
|
- and32(Assembler::TrustedImm32(Value::IsDouble_Mask), Assembler::ScratchRegister);
|
|
- Assembler::Jump isNoDbl = branch32(Assembler::Equal, Assembler::ScratchRegister,
|
|
- Assembler::TrustedImm32(0));
|
|
+ rshift32(TrustedImm32(Value::IsDoubleTag_Shift), ScratchRegister);
|
|
+ Assembler::Jump isNoDbl = branch32(Equal, ScratchRegister, TrustedImm32(0));
|
|
#else
|
|
and32(Assembler::TrustedImm32(Value::NotDouble_Mask), Assembler::ScratchRegister);
|
|
Assembler::Jump isNoDbl = branch32(Assembler::Equal, Assembler::ScratchRegister,
|
|
Index: qtdeclarative-opensource-src-5.6.1/src/qml/jit/qv4assembler_p.h
|
|
===================================================================
|
|
--- qtdeclarative-opensource-src-5.6.1.orig/src/qml/jit/qv4assembler_p.h
|
|
+++ qtdeclarative-opensource-src-5.6.1/src/qml/jit/qv4assembler_p.h
|
|
@@ -374,6 +374,11 @@ public:
|
|
void addPatch(DataLabelPtr patch, IR::BasicBlock *target);
|
|
void generateCJumpOnNonZero(RegisterID reg, IR::BasicBlock *currentBlock,
|
|
IR::BasicBlock *trueBlock, IR::BasicBlock *falseBlock);
|
|
+#ifdef QV4_USE_64_BIT_VALUE_ENCODING
|
|
+ void generateCJumpOnCompare(RelationalCondition cond, RegisterID left, TrustedImm64 right,
|
|
+ IR::BasicBlock *currentBlock, IR::BasicBlock *trueBlock,
|
|
+ IR::BasicBlock *falseBlock);
|
|
+#endif
|
|
void generateCJumpOnCompare(RelationalCondition cond, RegisterID left, TrustedImm32 right,
|
|
IR::BasicBlock *currentBlock, IR::BasicBlock *trueBlock,
|
|
IR::BasicBlock *falseBlock);
|
|
Index: qtdeclarative-opensource-src-5.6.1/src/qml/jit/qv4isel_masm.cpp
|
|
===================================================================
|
|
--- qtdeclarative-opensource-src-5.6.1.orig/src/qml/jit/qv4isel_masm.cpp
|
|
+++ qtdeclarative-opensource-src-5.6.1/src/qml/jit/qv4isel_masm.cpp
|
|
@@ -703,7 +703,7 @@ void InstructionSelection::loadString(co
|
|
#else
|
|
_as->store32(Assembler::ReturnValueRegister, destAddr);
|
|
destAddr.offset += 4;
|
|
- _as->store32(Assembler::TrustedImm32(QV4::Value::Managed_Type), destAddr);
|
|
+ _as->store32(Assembler::TrustedImm32(QV4::Value::Managed_Type_Internal), destAddr);
|
|
#endif
|
|
}
|
|
|
|
@@ -1103,7 +1103,7 @@ void InstructionSelection::convertTypeTo
|
|
// not an int, check if it's NOT a double:
|
|
isNoInt.link(_as);
|
|
#ifdef QV4_USE_64_BIT_VALUE_ENCODING
|
|
- _as->and32(Assembler::TrustedImm32(Value::IsDouble_Mask), Assembler::ScratchRegister);
|
|
+ _as->rshift32(Assembler::TrustedImm32(Value::IsDoubleTag_Shift), Assembler::ScratchRegister);
|
|
Assembler::Jump isDbl = _as->branch32(Assembler::NotEqual, Assembler::ScratchRegister,
|
|
Assembler::TrustedImm32(0));
|
|
#else
|
|
@@ -1194,10 +1194,15 @@ void InstructionSelection::convertTypeTo
|
|
_as->load64(addr, Assembler::ScratchRegister);
|
|
_as->move(Assembler::ScratchRegister, Assembler::ReturnValueRegister);
|
|
|
|
- // check if it's a number
|
|
- _as->urshift64(Assembler::TrustedImm32(QV4::Value::IsNumber_Shift), Assembler::ScratchRegister);
|
|
- Assembler::Jump isInt = _as->branch32(Assembler::Equal, Assembler::ScratchRegister, Assembler::TrustedImm32(1));
|
|
- Assembler::Jump fallback = _as->branch32(Assembler::Equal, Assembler::ScratchRegister, Assembler::TrustedImm32(0));
|
|
+ // check if it's integer convertible
|
|
+ _as->urshift64(Assembler::TrustedImm32(QV4::Value::IsIntegerConvertible_Shift), Assembler::ScratchRegister);
|
|
+ Assembler::Jump isIntConvertible = _as->branch32(Assembler::Equal, Assembler::ScratchRegister, Assembler::TrustedImm32(3));
|
|
+
|
|
+ // nope, not integer convertible, so check for a double:
|
|
+ _as->urshift64(Assembler::TrustedImm32(
|
|
+ QV4::Value::IsDoubleTag_Shift - QV4::Value::IsIntegerConvertible_Shift),
|
|
+ Assembler::ScratchRegister);
|
|
+ Assembler::Jump fallback = _as->branch32(Assembler::GreaterThan, Assembler::ScratchRegister, Assembler::TrustedImm32(0));
|
|
|
|
// it's a double
|
|
_as->move(Assembler::TrustedImm64(QV4::Value::NaNEncodeMask), Assembler::ScratchRegister);
|
|
@@ -1212,7 +1217,7 @@ void InstructionSelection::convertTypeTo
|
|
generateFunctionCall(Assembler::ReturnValueRegister, Runtime::toInt,
|
|
_as->loadAddress(Assembler::ScratchRegister, source));
|
|
|
|
- isInt.link(_as);
|
|
+ isIntConvertible.link(_as);
|
|
success.link(_as);
|
|
IR::Temp *targetTemp = target->asTemp();
|
|
if (!targetTemp || targetTemp->kind == IR::Temp::StackSlot) {
|
|
@@ -1784,9 +1789,9 @@ void InstructionSelection::visitCJumpStr
|
|
{
|
|
Q_ASSERT(binop->op == IR::OpStrictEqual || binop->op == IR::OpStrictNotEqual);
|
|
|
|
- if (visitCJumpStrictNullUndefined(IR::NullType, binop, trueBlock, falseBlock))
|
|
+ if (visitCJumpStrictNull(binop, trueBlock, falseBlock))
|
|
return;
|
|
- if (visitCJumpStrictNullUndefined(IR::UndefinedType, binop, trueBlock, falseBlock))
|
|
+ if (visitCJumpStrictUndefined(binop, trueBlock, falseBlock))
|
|
return;
|
|
if (visitCJumpStrictBool(binop, trueBlock, falseBlock))
|
|
return;
|
|
@@ -1802,16 +1807,14 @@ void InstructionSelection::visitCJumpStr
|
|
}
|
|
|
|
// Only load the non-null temp.
|
|
-bool InstructionSelection::visitCJumpStrictNullUndefined(IR::Type nullOrUndef, IR::Binop *binop,
|
|
- IR::BasicBlock *trueBlock,
|
|
- IR::BasicBlock *falseBlock)
|
|
+bool InstructionSelection::visitCJumpStrictNull(IR::Binop *binop,
|
|
+ IR::BasicBlock *trueBlock,
|
|
+ IR::BasicBlock *falseBlock)
|
|
{
|
|
- Q_ASSERT(nullOrUndef == IR::NullType || nullOrUndef == IR::UndefinedType);
|
|
-
|
|
IR::Expr *varSrc = 0;
|
|
- if (binop->left->type == IR::VarType && binop->right->type == nullOrUndef)
|
|
+ if (binop->left->type == IR::VarType && binop->right->type == IR::NullType)
|
|
varSrc = binop->left;
|
|
- else if (binop->left->type == nullOrUndef && binop->right->type == IR::VarType)
|
|
+ else if (binop->left->type == IR::NullType && binop->right->type == IR::VarType)
|
|
varSrc = binop->right;
|
|
if (!varSrc)
|
|
return false;
|
|
@@ -1822,7 +1825,7 @@ bool InstructionSelection::visitCJumpStr
|
|
}
|
|
|
|
if (IR::Const *c = varSrc->asConst()) {
|
|
- if (c->type == nullOrUndef)
|
|
+ if (c->type == IR::NullType)
|
|
_as->jumpToBlock(_block, trueBlock);
|
|
else
|
|
_as->jumpToBlock(_block, falseBlock);
|
|
@@ -1835,9 +1838,54 @@ bool InstructionSelection::visitCJumpStr
|
|
_as->load32(tagAddr, tagReg);
|
|
|
|
Assembler::RelationalCondition cond = binop->op == IR::OpStrictEqual ? Assembler::Equal
|
|
- : Assembler::NotEqual;
|
|
- const Assembler::TrustedImm32 tag(nullOrUndef == IR::NullType ? int(QV4::Value::Null_Type_Internal)
|
|
- : int(QV4::Value::Undefined_Type));
|
|
+ : Assembler::NotEqual;
|
|
+ const Assembler::TrustedImm32 tag(QV4::Value::Null_Type_Internal);
|
|
+ _as->generateCJumpOnCompare(cond, tagReg, tag, _block, trueBlock, falseBlock);
|
|
+ return true;
|
|
+}
|
|
+
|
|
+bool InstructionSelection::visitCJumpStrictUndefined(IR::Binop *binop,
|
|
+ IR::BasicBlock *trueBlock,
|
|
+ IR::BasicBlock *falseBlock)
|
|
+{
|
|
+ IR::Expr *varSrc = 0;
|
|
+ if (binop->left->type == IR::VarType && binop->right->type == IR::UndefinedType)
|
|
+ varSrc = binop->left;
|
|
+ else if (binop->left->type == IR::UndefinedType && binop->right->type == IR::VarType)
|
|
+ varSrc = binop->right;
|
|
+ if (!varSrc)
|
|
+ return false;
|
|
+
|
|
+ if (varSrc->asTemp() && varSrc->asTemp()->kind == IR::Temp::PhysicalRegister) {
|
|
+ _as->jumpToBlock(_block, falseBlock);
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ if (IR::Const *c = varSrc->asConst()) {
|
|
+ if (c->type == IR::UndefinedType)
|
|
+ _as->jumpToBlock(_block, trueBlock);
|
|
+ else
|
|
+ _as->jumpToBlock(_block, falseBlock);
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ Assembler::RelationalCondition cond = binop->op == IR::OpStrictEqual ? Assembler::Equal
|
|
+ : Assembler::NotEqual;
|
|
+ const Assembler::RegisterID tagReg = Assembler::ScratchRegister;
|
|
+#ifdef QV4_USE_64_BIT_VALUE_ENCODING
|
|
+ Assembler::Pointer addr = _as->loadAddress(Assembler::ScratchRegister, varSrc);
|
|
+ _as->load64(addr, tagReg);
|
|
+ const Assembler::TrustedImm64 tag(0);
|
|
+#else // !QV4_USE_64_BIT_VALUE_ENCODING
|
|
+ Assembler::Pointer tagAddr = _as->loadAddress(Assembler::ScratchRegister, varSrc);
|
|
+ _as->load32(tagAddr, tagReg);
|
|
+ Assembler::Jump j = _as->branch32(Assembler::invert(cond), tagReg, Assembler::TrustedImm32(0));
|
|
+ _as->addPatch(falseBlock, j);
|
|
+
|
|
+ tagAddr.offset += 4;
|
|
+ _as->load32(tagAddr, tagReg);
|
|
+ const Assembler::TrustedImm32 tag(QV4::Value::Managed_Type_Internal);
|
|
+#endif
|
|
_as->generateCJumpOnCompare(cond, tagReg, tag, _block, trueBlock, falseBlock);
|
|
return true;
|
|
}
|
|
@@ -1928,10 +1976,14 @@ bool InstructionSelection::visitCJumpNul
|
|
if (binop->op == IR::OpNotEqual)
|
|
qSwap(trueBlock, falseBlock);
|
|
Assembler::Jump isNull = _as->branch32(Assembler::Equal, tagReg, Assembler::TrustedImm32(int(QV4::Value::Null_Type_Internal)));
|
|
- Assembler::Jump isUndefined = _as->branch32(Assembler::Equal, tagReg, Assembler::TrustedImm32(int(QV4::Value::Undefined_Type)));
|
|
+ Assembler::Jump isNotUndefinedTag = _as->branch32(Assembler::NotEqual, tagReg, Assembler::TrustedImm32(int(QV4::Value::Managed_Type_Internal)));
|
|
+ tagAddr.offset -= 4;
|
|
+ _as->load32(tagAddr, tagReg);
|
|
+ Assembler::Jump isNotUndefinedValue = _as->branch32(Assembler::NotEqual, tagReg, Assembler::TrustedImm32(0));
|
|
_as->addPatch(trueBlock, isNull);
|
|
- _as->addPatch(trueBlock, isUndefined);
|
|
- _as->jumpToBlock(_block, falseBlock);
|
|
+ _as->addPatch(falseBlock, isNotUndefinedTag);
|
|
+ _as->addPatch(falseBlock, isNotUndefinedValue);
|
|
+ _as->jumpToBlock(_block, trueBlock);
|
|
|
|
return true;
|
|
}
|
|
Index: qtdeclarative-opensource-src-5.6.1/src/qml/jit/qv4isel_masm_p.h
|
|
===================================================================
|
|
--- qtdeclarative-opensource-src-5.6.1.orig/src/qml/jit/qv4isel_masm_p.h
|
|
+++ qtdeclarative-opensource-src-5.6.1/src/qml/jit/qv4isel_masm_p.h
|
|
@@ -166,8 +166,8 @@ protected:
|
|
bool visitCJumpSInt32(IR::AluOp op, IR::Expr *left, IR::Expr *right,
|
|
IR::BasicBlock *iftrue, IR::BasicBlock *iffalse);
|
|
void visitCJumpStrict(IR::Binop *binop, IR::BasicBlock *trueBlock, IR::BasicBlock *falseBlock);
|
|
- bool visitCJumpStrictNullUndefined(IR::Type nullOrUndef, IR::Binop *binop,
|
|
- IR::BasicBlock *trueBlock, IR::BasicBlock *falseBlock);
|
|
+ bool visitCJumpStrictNull(IR::Binop *binop, IR::BasicBlock *trueBlock, IR::BasicBlock *falseBlock);
|
|
+ bool visitCJumpStrictUndefined(IR::Binop *binop, IR::BasicBlock *trueBlock, IR::BasicBlock *falseBlock);
|
|
bool visitCJumpStrictBool(IR::Binop *binop, IR::BasicBlock *trueBlock, IR::BasicBlock *falseBlock);
|
|
bool visitCJumpNullUndefined(IR::Type nullOrUndef, IR::Binop *binop,
|
|
IR::BasicBlock *trueBlock, IR::BasicBlock *falseBlock);
|
|
Index: qtdeclarative-opensource-src-5.6.1/src/qml/jsruntime/qv4scopedvalue_p.h
|
|
===================================================================
|
|
--- qtdeclarative-opensource-src-5.6.1.orig/src/qml/jsruntime/qv4scopedvalue_p.h
|
|
+++ qtdeclarative-opensource-src-5.6.1/src/qml/jsruntime/qv4scopedvalue_p.h
|
|
@@ -309,7 +309,7 @@ struct ScopedCallData {
|
|
{
|
|
int size = qMax(argc, (int)QV4::Global::ReservedArgumentCount) + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value);
|
|
ptr = reinterpret_cast<CallData *>(scope.alloc(size));
|
|
- ptr->tag = QV4::Value::Integer_Type;
|
|
+ ptr->tag = QV4::Value::Integer_Type_Internal;
|
|
ptr->argc = argc;
|
|
}
|
|
|
|
Index: qtdeclarative-opensource-src-5.6.1/src/qml/jsruntime/qv4value_p.h
|
|
===================================================================
|
|
--- qtdeclarative-opensource-src-5.6.1.orig/src/qml/jsruntime/qv4value_p.h
|
|
+++ qtdeclarative-opensource-src-5.6.1/src/qml/jsruntime/qv4value_p.h
|
|
@@ -70,23 +70,85 @@ private:
|
|
/*
|
|
We use two different ways of encoding JS values. One for 32bit and one for 64bit systems.
|
|
|
|
- In both cases, we use 8 bytes for a value and a different variant of NaN boxing. A Double NaN (actually -qNaN)
|
|
- is indicated by a number that has the top 13 bits set. The other values are usually set to 0 by the
|
|
- processor, and are thus free for us to store other data. We keep pointers in there for managed objects,
|
|
- and encode the other types using the free space given to use by the unused bits for NaN values. This also
|
|
- works for pointers on 64 bit systems, as they all currently only have 48 bits of addressable memory.
|
|
-
|
|
- On 32bit, we store doubles as doubles. All other values, have the high 32bits set to a value that
|
|
- will make the number a NaN. The Masks below are used for encoding the other types.
|
|
-
|
|
- On 64 bit, we xor Doubles with (0xffff8000 << 32). That has the effect that no doubles will get encoded
|
|
- with the 13 highest bits all 0. We are now using special values for bits 14-17 to encode our values. These
|
|
- can be used, as the highest valid pointer on a 64 bit system is 2^48-1.
|
|
-
|
|
- If they are all 0, we have a pointer to a Managed object. If bit 14 is set we have an integer.
|
|
- This makes testing for pointers and numbers very fast (we have a number if any of the highest 14 bits is set).
|
|
-
|
|
- Bit 15-17 is then used to encode other immediates.
|
|
+ In both cases, we use 8 bytes for a value and a different variant of NaN boxing. A Double
|
|
+ NaN (actually -qNaN) is indicated by a number that has the top 13 bits set, and for a
|
|
+ signalling NaN it is the top 14 bits. The other values are usually set to 0 by the
|
|
+ processor, and are thus free for us to store other data. We keep pointers in there for
|
|
+ managed objects, and encode the other types using the free space given to use by the unused
|
|
+ bits for NaN values. This also works for pointers on 64 bit systems, as they all currently
|
|
+ only have 48 bits of addressable memory. (Note: we do leave the lower 49 bits available for
|
|
+ pointers.)
|
|
+
|
|
+ On 32bit, we store doubles as doubles. All other values, have the high 32bits set to a value
|
|
+ that will make the number a NaN. The Masks below are used for encoding the other types.
|
|
+
|
|
+ On 64 bit, we xor Doubles with (0xffff8000 << 32). That has the effect that no doubles will
|
|
+ get encoded with bits 63-49 all set to 0. We then use bit 48 to distinguish between
|
|
+ managed/undefined (0), or Null/Int/Bool/Empty (1). So, storing a 49 bit pointer will leave
|
|
+ the top 15 bits 0, which is exactly the 'natural' representation of pointers. If bit 49 is
|
|
+ set, bit 48 indicates Empty (0) or integer-convertible (1). Then the 3 bit below that are
|
|
+ used to encode Null/Int/Bool.
|
|
+
|
|
+ On both 32bit and 64bit, Undefined is encoded as a managed pointer with value 0. This is
|
|
+ the same as a nullptr.
|
|
+
|
|
+ Specific bit-sequences:
|
|
+ 0 = always 0
|
|
+ 1 = always 1
|
|
+ x = stored value
|
|
+ a,b,c,d = specific bit values, see notes
|
|
+
|
|
+ 64bit:
|
|
+
|
|
+ 32109876 54321098 76543210 98765432 10987654 32109876 54321098 76543210 |
|
|
+ 66665555 55555544 44444444 33333333 33222222 22221111 11111100 00000000 | JS Value
|
|
+ ------------------------------------------------------------------------+--------------
|
|
+ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 | Undefined
|
|
+ 00000000 0000000x xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx | Managed (heap pointer)
|
|
+ a0000000 0000bc00 00000000 00000000 00000000 00000000 00000000 00000000 | NaN/Inf
|
|
+ dddddddd ddddddxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx | double
|
|
+ 00000000 00000010 00000000 00000000 00000000 00000000 00000000 00000000 | empty (non-sparse array hole)
|
|
+ 00000000 00000011 10000000 00000000 00000000 00000000 00000000 00000000 | Null
|
|
+ 00000000 00000011 01000000 00000000 00000000 00000000 00000000 0000000x | Bool
|
|
+ 00000000 00000011 00100000 00000000 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx | Int
|
|
+
|
|
+ Notes:
|
|
+ - a: xor-ed signbit, always 1 for NaN
|
|
+ - bc, xor-ed values: 11 = inf, 10 = sNaN, 01 = qNaN, 00 = boxed value
|
|
+ - d: xor-ed bits, where at least one bit is set, so: (val >> (64-14)) > 0
|
|
+ - Undefined maps to C++ nullptr, so the "default" initialization is the same for both C++
|
|
+ and JS
|
|
+ - Managed has the left 15 bits set to 0, so: (val >> (64-15)) == 0
|
|
+ - empty, Null, Bool, and Int have the left 14 bits set to 0, and bit 49 set to 1,
|
|
+ so: (val >> (64-15)) == 1
|
|
+ - Null, Bool, and Int have bit 48 set, indicating integer-convertible
|
|
+ - xoring _val with NaNEncodeMask will convert to a double in "natural" representation, where
|
|
+ any non double results in a NaN
|
|
+
|
|
+ 32bit:
|
|
+
|
|
+ 32109876 54321098 76543210 98765432 10987654 32109876 54321098 76543210 |
|
|
+ 66665555 55555544 44444444 33333333 33222222 22221111 11111100 00000000 | JS Value
|
|
+ ------------------------------------------------------------------------+--------------
|
|
+ 01111111 11111100 00000000 00000000 00000000 00000000 00000000 00000000 | Undefined
|
|
+ 01111111 11111100 00000000 00000000 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx | Managed (heap pointer)
|
|
+ a1111111 1111bc00 00000000 00000000 00000000 00000000 00000000 00000000 | NaN/Inf
|
|
+ xddddddd ddddddxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx | double
|
|
+ 01111111 11111110 00000000 00000000 00000000 00000000 00000000 00000000 | empty (non-sparse array hole)
|
|
+ 01111111 11111111 10000000 00000000 00000000 00000000 00000000 00000000 | Null
|
|
+ 01111111 11111111 01000000 00000000 00000000 00000000 00000000 0000000x | Bool
|
|
+ 01111111 11111111 00100000 00000000 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx | Int
|
|
+
|
|
+ Notes:
|
|
+ - the upper 32 bits are the tag, the lower 32 bits the value
|
|
+ - Undefined has a nullptr in the value, Managed has a non-nullptr stored in the value
|
|
+ - a: sign bit, always 0 for NaN
|
|
+ - b,c: 00=inf, 01 = sNaN, 10 = qNaN, 11 = boxed value
|
|
+ - d: stored double value, as long as not *all* of them are 1, because that's a boxed value
|
|
+ (see above)
|
|
+ - empty, Null, Bool, and Int have bit 63 set to 0, bits 62-50 set to 1 (same as undefined
|
|
+ and managed), and bit 49 set to 1 (where undefined and managed have it set to 0)
|
|
+ - Null, Bool, and Int have bit 48 set, indicating integer-convertible
|
|
*/
|
|
|
|
quint64 _val;
|
|
@@ -137,7 +199,7 @@ public:
|
|
{
|
|
quint32 v;
|
|
memcpy(&v, &b, 4);
|
|
- setTagValue(Managed_Type, v);
|
|
+ setTagValue(Managed_Type_Internal, v);
|
|
}
|
|
#endif
|
|
|
|
@@ -153,113 +215,96 @@ public:
|
|
|
|
Q_ALWAYS_INLINE void setEmpty()
|
|
{
|
|
- setTagValue(Empty_Type, value());
|
|
+ setTagValue(Empty_Type_Internal, value());
|
|
}
|
|
|
|
Q_ALWAYS_INLINE void setEmpty(int i)
|
|
{
|
|
- setTagValue(Empty_Type, quint32(i));
|
|
+ setTagValue(Empty_Type_Internal, quint32(i));
|
|
+ }
|
|
+
|
|
+ enum Type {
|
|
+ Undefined_Type,
|
|
+ Managed_Type,
|
|
+ Empty_Type,
|
|
+ Integer_Type,
|
|
+ Boolean_Type,
|
|
+ Null_Type,
|
|
+ Double_Type
|
|
+ };
|
|
+
|
|
+ inline Type type() const {
|
|
+ if (isUndefined()) return Undefined_Type;
|
|
+ if (isManaged()) return Managed_Type;
|
|
+ if (isEmpty()) return Empty_Type;
|
|
+ if (isInteger()) return Integer_Type;
|
|
+ if (isBoolean()) return Boolean_Type;
|
|
+ if (isNull()) return Null_Type;
|
|
+ Q_ASSERT(isDouble()); return Double_Type;
|
|
}
|
|
#ifndef QV4_USE_64_BIT_VALUE_ENCODING
|
|
enum Masks {
|
|
SilentNaNBit = 0x00040000,
|
|
NaN_Mask = 0x7ff80000,
|
|
NotDouble_Mask = 0x7ffa0000,
|
|
- Type_Mask = 0xffffc000,
|
|
- Immediate_Mask = NotDouble_Mask | 0x00004000 | SilentNaNBit,
|
|
- IsNullOrUndefined_Mask = Immediate_Mask | 0x08000,
|
|
+ Immediate_Mask = NotDouble_Mask | 0x00020000u | SilentNaNBit,
|
|
Tag_Shift = 32
|
|
};
|
|
- enum ValueType {
|
|
- Undefined_Type = Immediate_Mask | 0x00000,
|
|
- Null_Type = Immediate_Mask | 0x10000,
|
|
- Boolean_Type = Immediate_Mask | 0x08000,
|
|
- Integer_Type = Immediate_Mask | 0x18000,
|
|
- Managed_Type = NotDouble_Mask | 0x00000 | SilentNaNBit,
|
|
- Empty_Type = NotDouble_Mask | 0x18000 | SilentNaNBit
|
|
- };
|
|
-
|
|
- enum ImmediateFlags {
|
|
- ConvertibleToInt = Immediate_Mask | 0x1
|
|
- };
|
|
-
|
|
- enum ValueTypeInternal {
|
|
- Null_Type_Internal = Null_Type | ConvertibleToInt,
|
|
- Boolean_Type_Internal = Boolean_Type | ConvertibleToInt,
|
|
- Integer_Type_Internal = Integer_Type | ConvertibleToInt,
|
|
|
|
+ enum {
|
|
+ Managed_Type_Internal = NotDouble_Mask
|
|
};
|
|
#else
|
|
- static const quint64 NaNEncodeMask = 0xffff800000000000ll;
|
|
- static const quint64 IsInt32Mask = 0x0002000000000000ll;
|
|
- static const quint64 IsDoubleMask = 0xfffc000000000000ll;
|
|
- static const quint64 IsNumberMask = IsInt32Mask|IsDoubleMask;
|
|
- static const quint64 IsNullOrUndefinedMask = 0x0000800000000000ll;
|
|
- static const quint64 IsNullOrBooleanMask = 0x0001000000000000ll;
|
|
- static const quint64 IsConvertibleToIntMask = IsInt32Mask|IsNullOrBooleanMask;
|
|
+ static const quint64 NaNEncodeMask = 0xfffc000000000000ll;
|
|
+ static const quint64 Immediate_Mask = 0x00020000u; // bit 49
|
|
|
|
enum Masks {
|
|
NaN_Mask = 0x7ff80000,
|
|
- Type_Mask = 0xffff8000,
|
|
- IsDouble_Mask = 0xfffc0000,
|
|
- Immediate_Mask = 0x00018000,
|
|
- IsNullOrUndefined_Mask = 0x00008000,
|
|
- IsNullOrBoolean_Mask = 0x00010000,
|
|
- Tag_Shift = 32
|
|
- };
|
|
- enum ValueType {
|
|
- Undefined_Type = IsNullOrUndefined_Mask,
|
|
- Null_Type = IsNullOrUndefined_Mask|IsNullOrBoolean_Mask,
|
|
- Boolean_Type = IsNullOrBoolean_Mask,
|
|
- Integer_Type = 0x20000|IsNullOrBoolean_Mask,
|
|
- Managed_Type = 0,
|
|
- Empty_Type = Undefined_Type | 0x4000
|
|
};
|
|
enum {
|
|
IsDouble_Shift = 64-14,
|
|
- IsNumber_Shift = 64-15,
|
|
- IsConvertibleToInt_Shift = 64-16,
|
|
- IsManaged_Shift = 64-17
|
|
+ IsManagedOrUndefined_Shift = 64-15,
|
|
+ IsIntegerConvertible_Shift = 64-16,
|
|
+ Tag_Shift = 32,
|
|
+ IsDoubleTag_Shift = IsDouble_Shift - Tag_Shift,
|
|
+ Managed_Type_Internal = 0
|
|
};
|
|
-
|
|
-
|
|
+#endif
|
|
enum ValueTypeInternal {
|
|
- Null_Type_Internal = Null_Type,
|
|
- Boolean_Type_Internal = Boolean_Type,
|
|
- Integer_Type_Internal = Integer_Type
|
|
+ Empty_Type_Internal = Immediate_Mask | 0,
|
|
+ ConvertibleToInt = Immediate_Mask | 0x10000u, // bit 48
|
|
+ Null_Type_Internal = ConvertibleToInt | 0x08000u,
|
|
+ Boolean_Type_Internal = ConvertibleToInt | 0x04000u,
|
|
+ Integer_Type_Internal = ConvertibleToInt | 0x02000u
|
|
};
|
|
-#endif
|
|
-
|
|
- inline unsigned type() const {
|
|
- return tag() & Type_Mask;
|
|
- }
|
|
|
|
// used internally in property
|
|
- inline bool isEmpty() const { return tag() == Empty_Type; }
|
|
-
|
|
- inline bool isUndefined() const { return tag() == Undefined_Type; }
|
|
+ inline bool isEmpty() const { return tag() == Empty_Type_Internal; }
|
|
inline bool isNull() const { return tag() == Null_Type_Internal; }
|
|
- inline bool isBoolean() const { return tag ()== Boolean_Type_Internal; }
|
|
+ inline bool isBoolean() const { return tag() == Boolean_Type_Internal; }
|
|
+ inline bool isInteger() const { return tag() == Integer_Type_Internal; }
|
|
+ inline bool isNullOrUndefined() const { return isNull() || isUndefined(); }
|
|
+ inline bool isNumber() const { return isDouble() || isInteger(); }
|
|
+
|
|
#ifdef QV4_USE_64_BIT_VALUE_ENCODING
|
|
- inline bool isInteger() const { return (_val >> IsNumber_Shift) == 1; }
|
|
+ inline bool isUndefined() const { return _val == 0; }
|
|
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 isManaged() const { return !isUndefined() && ((_val >> IsManagedOrUndefined_Shift) == 0); }
|
|
+
|
|
+ inline bool integerCompatible() const {
|
|
+ return (_val >> IsIntegerConvertible_Shift) == 3;
|
|
+ }
|
|
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();
|
|
}
|
|
- inline bool isNaN() const { return (tag() & 0x7fff8000) == 0x00078000; }
|
|
+ inline bool isNaN() const { return (tag() & 0x7ffc0000 ) == 0x00040000; }
|
|
#else
|
|
- inline bool isInteger() const { return tag() == Integer_Type_Internal; }
|
|
+ inline bool isUndefined() const { return tag() == Managed_Type_Internal && value() == 0; }
|
|
inline bool isDouble() const { return (tag() & NotDouble_Mask) != NotDouble_Mask; }
|
|
- inline bool isNumber() const { return tag() == Integer_Type_Internal || (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 isManaged() const { return tag() == Managed_Type_Internal && !isUndefined(); }
|
|
inline bool integerCompatible() const { return (tag() & ConvertibleToInt) == ConvertibleToInt; }
|
|
static inline bool integerCompatible(Value a, Value b) {
|
|
return ((a.tag() & b.tag()) & ConvertibleToInt) == ConvertibleToInt;
|
|
@@ -499,14 +544,14 @@ struct Q_QML_PRIVATE_EXPORT Primitive :
|
|
inline Primitive Primitive::undefinedValue()
|
|
{
|
|
Primitive v;
|
|
- v.setTagValue(Undefined_Type, 0);
|
|
+ v.setM(Q_NULLPTR);
|
|
return v;
|
|
}
|
|
|
|
inline Primitive Primitive::emptyValue()
|
|
{
|
|
Primitive v;
|
|
- v.setTagValue(Value::Empty_Type, 0);
|
|
+ v.setEmpty(0);
|
|
return v;
|
|
}
|
|
|
|
@@ -534,7 +579,6 @@ inline Primitive Primitive::fromDouble(d
|
|
inline Primitive Primitive::fromInt32(int i)
|
|
{
|
|
Primitive v;
|
|
- v.setTagValue(Integer_Type_Internal, 0);
|
|
v.setInt_32(i);
|
|
return v;
|
|
}
|
|
@@ -552,31 +596,23 @@ inline Primitive Primitive::fromUInt32(u
|
|
|
|
struct Encode {
|
|
static ReturnedValue undefined() {
|
|
- return quint64(Value::Undefined_Type) << Value::Tag_Shift;
|
|
+ return Primitive::undefinedValue().rawValue();
|
|
}
|
|
static ReturnedValue null() {
|
|
- return quint64(Value::Null_Type_Internal) << Value::Tag_Shift;
|
|
+ return Primitive::nullValue().rawValue();
|
|
}
|
|
|
|
Encode(bool b) {
|
|
- val = (quint64(Value::Boolean_Type_Internal) << Value::Tag_Shift) | (uint)b;
|
|
+ val = Primitive::fromBoolean(b).rawValue();
|
|
}
|
|
Encode(double d) {
|
|
- Value v;
|
|
- v.setDouble(d);
|
|
- val = v.rawValue();
|
|
+ val = Primitive::fromDouble(d).rawValue();
|
|
}
|
|
Encode(int i) {
|
|
- val = (quint64(Value::Integer_Type_Internal) << Value::Tag_Shift) | (uint)i;
|
|
+ val = Primitive::fromInt32(i).rawValue();
|
|
}
|
|
Encode(uint i) {
|
|
- if (i <= INT_MAX) {
|
|
- val = (quint64(Value::Integer_Type_Internal) << Value::Tag_Shift) | i;
|
|
- } else {
|
|
- Value v;
|
|
- v.setDouble(i);
|
|
- val = v.rawValue();
|
|
- }
|
|
+ val = Primitive::fromUInt32(i).rawValue();
|
|
}
|
|
Encode(ReturnedValue v) {
|
|
val = v;
|
|
Index: qtdeclarative-opensource-src-5.6.1/src/qml/jsruntime/qv4vme_moth.cpp
|
|
===================================================================
|
|
--- qtdeclarative-opensource-src-5.6.1.orig/src/qml/jsruntime/qv4vme_moth.cpp
|
|
+++ qtdeclarative-opensource-src-5.6.1/src/qml/jsruntime/qv4vme_moth.cpp
|
|
@@ -563,7 +563,7 @@ QV4::ReturnedValue VME::run(ExecutionEng
|
|
#endif // DO_TRACE_INSTR
|
|
Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
|
|
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
|
|
- callData->tag = QV4::Value::Integer_Type;
|
|
+ callData->tag = QV4::Value::Integer_Type_Internal;
|
|
callData->argc = instr.argc;
|
|
callData->thisObject = QV4::Primitive::undefinedValue();
|
|
STOREVALUE(instr.result, Runtime::callValue(engine, VALUE(instr.dest), callData));
|
|
@@ -573,7 +573,7 @@ QV4::ReturnedValue VME::run(ExecutionEng
|
|
TRACE(property name, "%s, args=%u, argc=%u, this=%s", qPrintable(runtimeStrings[instr.name]->toQString()), instr.callData, instr.argc, (VALUE(instr.base)).toString(context)->toQString().toUtf8().constData());
|
|
Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
|
|
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
|
|
- callData->tag = QV4::Value::Integer_Type;
|
|
+ callData->tag = QV4::Value::Integer_Type_Internal;
|
|
callData->argc = instr.argc;
|
|
callData->thisObject = VALUE(instr.base);
|
|
STOREVALUE(instr.result, Runtime::callProperty(engine, instr.name, callData));
|
|
@@ -582,7 +582,7 @@ QV4::ReturnedValue VME::run(ExecutionEng
|
|
MOTH_BEGIN_INSTR(CallPropertyLookup)
|
|
Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
|
|
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
|
|
- callData->tag = QV4::Value::Integer_Type;
|
|
+ callData->tag = QV4::Value::Integer_Type_Internal;
|
|
callData->argc = instr.argc;
|
|
callData->thisObject = VALUE(instr.base);
|
|
STOREVALUE(instr.result, Runtime::callPropertyLookup(engine, instr.lookupIndex, callData));
|
|
@@ -592,7 +592,7 @@ QV4::ReturnedValue VME::run(ExecutionEng
|
|
TRACE(property name, "%s, args=%u, argc=%u, this=%s", qPrintable(runtimeStrings[instr.name]->toQString()), instr.callData, instr.argc, (VALUE(instr.base)).toString(context)->toQString().toUtf8().constData());
|
|
Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
|
|
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
|
|
- callData->tag = QV4::Value::Integer_Type;
|
|
+ callData->tag = QV4::Value::Integer_Type_Internal;
|
|
callData->argc = instr.argc;
|
|
callData->thisObject = VALUE(instr.base);
|
|
STOREVALUE(instr.result, Runtime::callQmlScopeObjectProperty(engine, instr.index, callData));
|
|
@@ -602,7 +602,7 @@ QV4::ReturnedValue VME::run(ExecutionEng
|
|
TRACE(property name, "%s, args=%u, argc=%u, this=%s", qPrintable(runtimeStrings[instr.name]->toQString()), instr.callData, instr.argc, (VALUE(instr.base)).toString(context)->toQString().toUtf8().constData());
|
|
Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
|
|
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
|
|
- callData->tag = QV4::Value::Integer_Type;
|
|
+ callData->tag = QV4::Value::Integer_Type_Internal;
|
|
callData->argc = instr.argc;
|
|
callData->thisObject = VALUE(instr.base);
|
|
STOREVALUE(instr.result, Runtime::callQmlContextObjectProperty(engine, instr.index, callData));
|
|
@@ -611,7 +611,7 @@ QV4::ReturnedValue VME::run(ExecutionEng
|
|
MOTH_BEGIN_INSTR(CallElement)
|
|
Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
|
|
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
|
|
- callData->tag = QV4::Value::Integer_Type;
|
|
+ callData->tag = QV4::Value::Integer_Type_Internal;
|
|
callData->argc = instr.argc;
|
|
callData->thisObject = VALUE(instr.base);
|
|
STOREVALUE(instr.result, Runtime::callElement(engine, VALUE(instr.index), callData));
|
|
@@ -620,7 +620,7 @@ QV4::ReturnedValue VME::run(ExecutionEng
|
|
MOTH_BEGIN_INSTR(CallActivationProperty)
|
|
Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
|
|
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
|
|
- callData->tag = QV4::Value::Integer_Type;
|
|
+ callData->tag = QV4::Value::Integer_Type_Internal;
|
|
callData->argc = instr.argc;
|
|
callData->thisObject = QV4::Primitive::undefinedValue();
|
|
STOREVALUE(instr.result, Runtime::callActivationProperty(engine, instr.name, callData));
|
|
@@ -629,7 +629,7 @@ QV4::ReturnedValue VME::run(ExecutionEng
|
|
MOTH_BEGIN_INSTR(CallGlobalLookup)
|
|
Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
|
|
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
|
|
- callData->tag = QV4::Value::Integer_Type;
|
|
+ callData->tag = QV4::Value::Integer_Type_Internal;
|
|
callData->argc = instr.argc;
|
|
callData->thisObject = QV4::Primitive::undefinedValue();
|
|
STOREVALUE(instr.result, Runtime::callGlobalLookup(engine, instr.index, callData));
|
|
@@ -735,7 +735,7 @@ QV4::ReturnedValue VME::run(ExecutionEng
|
|
MOTH_BEGIN_INSTR(CreateValue)
|
|
Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
|
|
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
|
|
- callData->tag = QV4::Value::Integer_Type;
|
|
+ callData->tag = QV4::Value::Integer_Type_Internal;
|
|
callData->argc = instr.argc;
|
|
callData->thisObject = QV4::Primitive::undefinedValue();
|
|
STOREVALUE(instr.result, Runtime::constructValue(engine, VALUE(instr.func), callData));
|
|
@@ -744,7 +744,7 @@ QV4::ReturnedValue VME::run(ExecutionEng
|
|
MOTH_BEGIN_INSTR(CreateProperty)
|
|
Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
|
|
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
|
|
- callData->tag = QV4::Value::Integer_Type;
|
|
+ callData->tag = QV4::Value::Integer_Type_Internal;
|
|
callData->argc = instr.argc;
|
|
callData->thisObject = VALUE(instr.base);
|
|
STOREVALUE(instr.result, Runtime::constructProperty(engine, instr.name, callData));
|
|
@@ -753,7 +753,7 @@ QV4::ReturnedValue VME::run(ExecutionEng
|
|
MOTH_BEGIN_INSTR(ConstructPropertyLookup)
|
|
Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
|
|
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
|
|
- callData->tag = QV4::Value::Integer_Type;
|
|
+ callData->tag = QV4::Value::Integer_Type_Internal;
|
|
callData->argc = instr.argc;
|
|
callData->thisObject = VALUE(instr.base);
|
|
STOREVALUE(instr.result, Runtime::constructPropertyLookup(engine, instr.index, callData));
|
|
@@ -762,7 +762,7 @@ QV4::ReturnedValue VME::run(ExecutionEng
|
|
MOTH_BEGIN_INSTR(CreateActivationProperty)
|
|
Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
|
|
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
|
|
- callData->tag = QV4::Value::Integer_Type;
|
|
+ callData->tag = QV4::Value::Integer_Type_Internal;
|
|
callData->argc = instr.argc;
|
|
callData->thisObject = QV4::Primitive::undefinedValue();
|
|
STOREVALUE(instr.result, Runtime::constructActivationProperty(engine, instr.name, callData));
|
|
@@ -771,7 +771,7 @@ QV4::ReturnedValue VME::run(ExecutionEng
|
|
MOTH_BEGIN_INSTR(ConstructGlobalLookup)
|
|
Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
|
|
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
|
|
- callData->tag = QV4::Value::Integer_Type;
|
|
+ callData->tag = QV4::Value::Integer_Type_Internal;
|
|
callData->argc = instr.argc;
|
|
callData->thisObject = QV4::Primitive::undefinedValue();
|
|
STOREVALUE(instr.result, Runtime::constructGlobalLookup(engine, instr.index, callData));
|