forked from qt-creator/qt-creator
Debugger: Improve QJSValue dumper on 32 bit
Change-Id: I18937a92d5202a58d9f3d786c6cc37f8176b2692 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -772,7 +772,7 @@ class DumperBase:
|
||||
continue
|
||||
|
||||
with SubItem(self, field.name):
|
||||
self.putItem(value[field])
|
||||
self.putItem(value.extractField(field))
|
||||
|
||||
|
||||
def putMembersItem(self, value, sortorder = 10):
|
||||
@@ -2449,6 +2449,8 @@ class DumperBase:
|
||||
if typeobj.code == TypeCodeTypedef:
|
||||
strippedType = typeobj.stripTypedefs()
|
||||
self.putItem(value.cast(strippedType))
|
||||
if value.lbitsize is not None and value.lbitsize != value.type.size() * 8:
|
||||
typeName += " : %s" % value.lbitsize
|
||||
self.putBetterType(typeName)
|
||||
return
|
||||
|
||||
@@ -2478,7 +2480,9 @@ class DumperBase:
|
||||
#warn("INTEGER: %s %s" % (value.name, value))
|
||||
self.putValue(value.value())
|
||||
self.putNumChild(0)
|
||||
self.putType(typeobj.name)
|
||||
if value.lbitsize is not None and value.lbitsize != value.type.size() * 8:
|
||||
typeName += " : %s" % value.lbitsize
|
||||
self.putType(typeName)
|
||||
return
|
||||
|
||||
if typeobj.code == TypeCodeFloat:
|
||||
@@ -2579,6 +2583,7 @@ class DumperBase:
|
||||
self.laddress = None
|
||||
self.lIsInScope = True
|
||||
self.ldisplay = None
|
||||
self.lbitsize = None
|
||||
|
||||
def check(self):
|
||||
if self.laddress is not None and not self.dumper.isInt(self.laddress):
|
||||
@@ -2595,8 +2600,9 @@ class DumperBase:
|
||||
|
||||
def stringify(self):
|
||||
addr = "None" if self.laddress is None else ("0x%x" % self.laddress)
|
||||
return "Value(name='%s',type=%s,data=%s,address=%s)" \
|
||||
% (self.name, self.type.stringify(), self.dumper.hexencode(self.ldata), addr)
|
||||
return "Value(name='%s',type=%s,bsize=%s,data=%s,address=%s)" \
|
||||
% (self.name, self.type.name, self.lbitsize,
|
||||
self.dumper.hexencode(self.ldata), addr)
|
||||
|
||||
def display(self):
|
||||
if self.type.code == TypeCodeEnum:
|
||||
@@ -2686,6 +2692,7 @@ class DumperBase:
|
||||
fieldBitpos = field.bitpos()
|
||||
fieldOffset = fieldBitpos >> 3
|
||||
fieldBitpos -= fieldOffset * 8
|
||||
fieldType = field.fieldType()
|
||||
|
||||
val = self.dumper.Value(self.dumper)
|
||||
val.name = field.name
|
||||
@@ -2697,7 +2704,7 @@ class DumperBase:
|
||||
else:
|
||||
self.dumper.check(False)
|
||||
|
||||
if fieldBitsize is not None and fieldBitsize % 8 != 0:
|
||||
if fieldBitsize is not None and fieldBitsize != fieldType.size() * 8:
|
||||
data = val.extractInteger(fieldBitsize, True)
|
||||
data = data >> fieldBitpos
|
||||
data = data & ((1 << fieldBitsize) - 1)
|
||||
@@ -2705,7 +2712,6 @@ class DumperBase:
|
||||
val.ldata = bytes(struct.pack('Q', data))
|
||||
|
||||
val.type = None
|
||||
fieldType = field.fieldType()
|
||||
if val.laddress is not None and fieldType is not None:
|
||||
if fieldType.code in (TypeCodePointer, TypeCodeReference):
|
||||
baseType = fieldType.dereference()
|
||||
@@ -2771,6 +2777,7 @@ class DumperBase:
|
||||
self.check()
|
||||
val = self.dumper.Value(self.dumper)
|
||||
val.laddress = self.laddress
|
||||
val.lbitsize = self.lbitsize
|
||||
val.ldata = self.ldata
|
||||
val.type = self.dumper.createType(typish)
|
||||
return val
|
||||
@@ -2889,8 +2896,8 @@ class DumperBase:
|
||||
#error("Not implemented")
|
||||
|
||||
def stringify(self):
|
||||
return "Type(name='%s',bsize=%s,bpos=%s,code=%s,native=%s)" \
|
||||
% (self.name, self.lbitsize, self.lbitpos, self.code, self.nativeType is not None)
|
||||
return "Type(name='%s',bsize=%s,bpos=%s,code=%s,ntype=%s)" \
|
||||
% (self.name, self.lbitsize, self.lbitpos, self.code, self.nativeType)
|
||||
|
||||
def __getitem__(self, index):
|
||||
if self.dumper.isInt(index):
|
||||
|
||||
@@ -2063,11 +2063,63 @@ def qdump__QV4_Object(d, value):
|
||||
d.putValue("PTR: 0x%x" % objectPtr)
|
||||
|
||||
def qdump__QV4__Value(d, value):
|
||||
if d.ptrSize() == 4:
|
||||
qdump_32__QV4__Value(d, value)
|
||||
else:
|
||||
qdump_64__QV4__Value(d, value)
|
||||
|
||||
def qdump_32__QV4__Value(d, value):
|
||||
# QV4_Masks_SilentNaNBit = 0x00040000
|
||||
# QV4_Masks_NaN_Mask = 0x7ff80000
|
||||
# QV4_Masks_NotDouble_Mask = 0x7ffa0000
|
||||
# QV4_Masks_Type_Mask = 0xffffc000
|
||||
ns = d.qtNamespace()
|
||||
v = value.split('Q')[0]
|
||||
tag = v >> 32
|
||||
val = v & 0xffffffff
|
||||
if (tag & 0x7fff2000) == 0x7fff2000: # Int
|
||||
d.putValue(val)
|
||||
d.putBetterType("%sQV4::Value (int32)" % ns)
|
||||
elif (tag & 0x7fff4000) == 0x7fff4000: # Bool
|
||||
d.putValue(val)
|
||||
d.putBetterType("%sQV4::Value (bool)" % ns)
|
||||
elif (tag & 0x7fff0000) == 0x7fff0000: # Null
|
||||
d.putValue(val)
|
||||
d.putBetterType("%sQV4::Value (null)" % ns)
|
||||
elif (tag & 0x7ffa0000) != 0x7ffa0000: # Double
|
||||
d.putValue(value.split('d')[0])
|
||||
d.putBetterType("%sQV4::Value (double)" % ns)
|
||||
elif tag == 0x7ffa0000:
|
||||
if val == 0:
|
||||
d.putValue("(undefined)")
|
||||
d.putBetterType("%sQV4::Value (undefined)" % ns)
|
||||
else:
|
||||
managed = d.createValue(val, ns + "QV4::Heap::Base")
|
||||
qdump__QV4__Heap__Base(d, managed)
|
||||
#d.putValue("[0x%x]" % v)
|
||||
#d.putPlainChildren(value)
|
||||
if d.isExpanded():
|
||||
with Children(d):
|
||||
with SubItem(d, "[raw]"):
|
||||
d.putValue("[0x%x]" % v)
|
||||
d.putType(" ");
|
||||
d.putNumChild(0)
|
||||
with SubItem(d, "[val]"):
|
||||
d.putValue("[0x%x]" % val)
|
||||
d.putType(" ");
|
||||
d.putNumChild(0)
|
||||
with SubItem(d, "[tag]"):
|
||||
d.putValue("[0x%x]" % tag)
|
||||
d.putType(" ");
|
||||
d.putNumChild(0)
|
||||
#with SubItem(d, "[vtable]"):
|
||||
# d.putItem(d.createValue(vtable, ns + "QV4::VTable"))
|
||||
# d.putType(" ");
|
||||
# d.putNumChild(0)
|
||||
d.putFields(value)
|
||||
|
||||
def qdump_64__QV4__Value(d, value):
|
||||
v = value.split('Q')[0]
|
||||
if d.ptrSize() == 4:
|
||||
d.putValue("[0x%x]" % v)
|
||||
d.putPlainChildren(value)
|
||||
return
|
||||
tag = v >> QV4_Masks_Tag_Shift
|
||||
vtable = v & QV4_PointerMask
|
||||
ns = d.qtNamespace()
|
||||
@@ -2158,15 +2210,45 @@ def qdump__QV4__ScopedString(d, value):
|
||||
|
||||
|
||||
def qdump__QJSValue(d, value):
|
||||
if d.ptrSize() == 4:
|
||||
qdump_32__QJSValue(d, value)
|
||||
else:
|
||||
qdump_64__QJSValue(d, value)
|
||||
|
||||
def qdump_32__QJSValue(d, value):
|
||||
ns = d.qtNamespace()
|
||||
dd = value.split('Q')[0]
|
||||
if dd & 1:
|
||||
dd = value.split('I')[0]
|
||||
d.putValue("[0x%x]" % dd)
|
||||
if dd == 0:
|
||||
d.putValue("(null)")
|
||||
d.putType(value.type.name + " (null)")
|
||||
elif dd & 1:
|
||||
variant = d.createValue(dd & ~3, ns + "QVariant")
|
||||
qdump__QVariant(d, variant)
|
||||
d.putBetterType(d.currentType.value.replace('QVariant', 'QJSValue', 1))
|
||||
elif dd == 0:
|
||||
elif dd & 3 == 0:
|
||||
v4value = d.createValue(dd, ns + "QV4::Value")
|
||||
qdump_32__QV4__Value(d, v4value)
|
||||
d.putBetterType(d.currentType.value.replace('QV4::Value', 'QJSValue', 1))
|
||||
return
|
||||
if d.isExpanded():
|
||||
with Children(d):
|
||||
with SubItem(d, "[raw]"):
|
||||
d.putValue("[0x%x]" % dd)
|
||||
d.putType(" ");
|
||||
d.putNumChild(0)
|
||||
d.putFields(value)
|
||||
|
||||
def qdump_64__QJSValue(d, value):
|
||||
ns = d.qtNamespace()
|
||||
dd = value.split('Q')[0]
|
||||
if dd == 0:
|
||||
d.putValue("(null)")
|
||||
d.putType(value.type.name + " (null)")
|
||||
elif dd & 1:
|
||||
variant = d.createValue(dd & ~3, ns + "QVariant")
|
||||
qdump__QVariant(d, variant)
|
||||
d.putBetterType(d.currentType.value.replace('QVariant', 'QJSValue', 1))
|
||||
else:
|
||||
d.putEmptyValue()
|
||||
#qdump__QV4__Value(d, d.createValue(dd, ns + 'QV4::Value'))
|
||||
|
||||
@@ -5022,13 +5022,13 @@ void tst_Dumpers::dumper_data()
|
||||
|
||||
+ Check("s", "", "S")
|
||||
+ Check("s.b", "0", "bool")
|
||||
+ Check("s.c", "1", "bool")
|
||||
+ Check("s.c", "1", "bool : 1")
|
||||
+ Check("s.f", FloatValue("5"), "float")
|
||||
+ Check("s.d", FloatValue("6"), "double")
|
||||
+ Check("s.i", "7", "int")
|
||||
+ Check("s.x", "2", "unsigned int")
|
||||
+ Check("s.y", "3", "unsigned int")
|
||||
+ Check("s.z", "39", "unsigned int");
|
||||
+ Check("s.x", "2", "unsigned int : 3")
|
||||
+ Check("s.y", "3", "unsigned int : 4")
|
||||
+ Check("s.z", "39", "unsigned int : 18");
|
||||
|
||||
|
||||
QTest::newRow("Function")
|
||||
@@ -6170,9 +6170,9 @@ void tst_Dumpers::dumper_data()
|
||||
"#include <QJSEngine>\n",
|
||||
"QGuiApplication app(argc, argv);\n"
|
||||
"QJSEngine eng;\n\n"
|
||||
"QV4::Value q0; unused(&q0);\n\n"
|
||||
"QV4::Value q1; unused(&q1);\n"
|
||||
"q1.setInt_32(1);\n\n"
|
||||
"//QV4::Value q0; unused(&q0); // Uninitialized data.\n\n"
|
||||
"//QV4::Value q1; unused(&q1); // Upper 32 bit uninitialized.\n"
|
||||
"//q1.setInt_32(1);\n\n"
|
||||
"QV4::Value q2; unused(&q2);\n"
|
||||
"q2.setDouble(2.5);\n\n"
|
||||
"QJSValue v10; unused(&v10);\n"
|
||||
@@ -6181,7 +6181,7 @@ void tst_Dumpers::dumper_data()
|
||||
"QJSValue v13 = QJSValue(2.5); unused(&v13);\n"
|
||||
"QJSValue v14 = QJSValue(QLatin1String(\"latin1\")); unused(&v14);\n"
|
||||
"QJSValue v15 = QJSValue(QString(\"utf16\")); unused(&v15);\n"
|
||||
"QJSValue v16 = QJSValue(bool(true)); unused(&v12);\n"
|
||||
"QJSValue v16 = QJSValue(bool(true)); unused(&v16);\n"
|
||||
"QJSValue v17 = eng.newArray(100); unused(&v17);\n"
|
||||
"QJSValue v18 = eng.newObject(); unused(&v18);\n\n"
|
||||
"v18.setProperty(\"PropA\", 1);\n"
|
||||
@@ -6198,8 +6198,6 @@ void tst_Dumpers::dumper_data()
|
||||
)
|
||||
+ QmlPrivateProfile()
|
||||
+ QtVersion(0x50000)
|
||||
//+ Check("q0", "(null)", "@QV4::Value (null)") # Works in GUI. Why?
|
||||
+ Check("q1", "1", "@QV4::Value (int32)")
|
||||
+ Check("q2", FloatValue("2.5"), "@QV4::Value (double)")
|
||||
//+ Check("v10", "(null)", "@QJSValue (null)") # Works in GUI. Why?
|
||||
+ Check("v11", "true", "@QJSValue (bool)")
|
||||
|
||||
Reference in New Issue
Block a user