1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
use ui;
use lang:bs:macro;
/**
* View hints. A part of the hints given to the visualization as a whole, dictates how data from a
* particular language should be extracted and viewed.
*/
class ViewHints on Render {
// Should we pause on function entry?
Bool pauseOnEntry() { true; }
// Are barriers available?
Bool barriersAvailable() { false; }
// Create an element for an object found during traversal. Return 'null' to leave handling to
// the default implementation. If 'root' is non-null, then it is a pointer to the root of an
// allocation. This allows other implementations to examine the object to take additional
// aspects into account when deciding how to interpret it.
Data? createData(World:Traversal t, TypeInfo type, unsafe:RawPtr root) : abstract;
// Allow special-case for global variables. The original Named is passed in case the
// implementation wishes to inspect it. The default implementation simply calls 'createData'.
Data? createGlobal(World:Traversal t, TypeInfo type, core:lang:GlobalVar global) {
return createData(t, type, unsafe:RawPtr());
}
// Create an allocation for the given data. This is called for the ViewHints object that created
// the data object. The default implementation just uses a simple Allocation object.
Allocation createAllocation(unsafe:RawPtr ptr, Data data) {
Allocation(ptr, data);
}
// Get a title for a type.
Str? typeTitle(World t, TypeInfo type) : abstract;
// Create a drawable from a Data object.
progvis:view:Drawable? createView(World world, Data data) { null; }
// Modify the proposed decoration for an allocation.
progvis:view:Drawable decorateAllocation(Allocation alloc, progvis:view:Drawable data) { data; }
}
/**
* Default hints. Strives to be a good default behavior for most cases.
*/
class DefaultViewHints extends ViewHints {
// Default behavior, works for most of Basic Storm.
Data? createData(World:Traversal t, TypeInfo info, unsafe:RawPtr root) : override {
if (info.isRef) {
// A reference to a value. This is not supported.
return Unknown();
} else if (!info.isValue) {
// A reference.
return Pointer(info.type);
} else if (info.type is named{progvis:program:ThreadId}) {
return ThreadId();
} else if (info.type is named{progvis:program:MaybePositive}) {
return MaybePositive();
} else if (info.type is named{Str}) {
return String();
} else if (isPrimitive(info.type)) {
return Primitive(info.type);
} else if (type = info.type as core:lang:ArrayType) {
if (t = type.param.type)
return StdArray(type, t);
else
return Unknown();
} else {
return createComposite(t, info.type);
}
}
// Create a composite object.
private Data createComposite(World:Traversal t, core:lang:Type type) {
var members = t.findMembers(type);
if (members.empty)
return Unknown();
Composite result(type);
for (m in members) {
result.add(m.name, m.offset, t.create(m.type), m.first);
}
result;
}
// Type names.
Str? typeTitle(World world, TypeInfo info) : override {
if (type = info.type as core:lang:ArrayType) {
if (t = type.param.type) {
TypeInfo info(t, true, false);
return world.typeTitle(info) + "[]";
}
}
info.type.name;
}
// Create a drawable from a Data object. This is the default mapping of objects.
progvis:view:Drawable? createView(World world, Data data) : override {
progvis:view:defaultView(world, data);
}
// Default decoration.
progvis:view:Drawable decorateAllocation(Allocation alloc, progvis:view:Drawable data) {
progvis:view:defaultDecorate(alloc, data);
}
}
|