@@ -34,28 +34,186 @@ distribution.
3434#include " tinythread.h"
3535// must be last due to MS stupidity
3636#include " DataDefs.h"
37+ #include " DataIdentity.h"
3738
3839#include " MiscUtils.h"
3940
4041using namespace DFHack ;
4142
43+
44+ void *type_identity::do_allocate_pod () {
45+ void *p = malloc (size);
46+ memset (p, 0 , size);
47+ return p;
48+ }
49+
50+ void type_identity::do_copy_pod (void *tgt, const void *src) {
51+ memmove (tgt, src, size);
52+ };
53+
54+ void *type_identity::allocate () {
55+ if (can_allocate ())
56+ return do_allocate ();
57+ else
58+ return NULL ;
59+ }
60+
61+ bool type_identity::copy (void *tgt, const void *src) {
62+ if (can_allocate () && tgt && src)
63+ do_copy (tgt, src);
64+ else
65+ return false ;
66+ }
67+
68+ void *enum_identity::do_allocate () {
69+ void *p = malloc (byte_size ());
70+ memcpy (p, &first_item_value, std::min (byte_size (), sizeof (int64_t )));
71+ return p;
72+ }
73+
4274/* The order of global object constructor calls is
4375 * undefined between compilation units. Therefore,
4476 * this list has to be plain data, so that it gets
4577 * initialized by the loader in the initial mmap.
4678 */
47- virtual_identity *virtual_identity::list = NULL ;
79+ compound_identity *compound_identity::list = NULL ;
80+ std::vector<compound_identity*> compound_identity::top_scope;
4881
49- virtual_identity::virtual_identity ( const char *dfhack_name, const char *original_name, virtual_identity *parent)
50- : dfhack_name(dfhack_name), original_name(original_name), parent(parent),
51- prev( NULL ), vtable_ptr( NULL ), has_children( true )
82+ compound_identity::compound_identity ( size_t size, TAllocateFn alloc,
83+ compound_identity *scope_parent, const char *dfhack_name)
84+ : constructed_identity(size, alloc ), scope_parent(scope_parent ), dfhack_name(dfhack_name )
5285{
53- // Link into the static list. Nothing else can be safely done at this point.
54- next = list; list = this ;
86+ next = list; list = this ;
87+ }
88+
89+ void compound_identity::doInit (Core *)
90+ {
91+ if (scope_parent)
92+ scope_parent->scope_children .push_back (this );
93+ else
94+ top_scope.push_back (this );
95+ }
96+
97+ std::string compound_identity::getFullName ()
98+ {
99+ if (scope_parent)
100+ return scope_parent->getFullName () + " ." + getName ();
101+ else
102+ return getName ();
55103}
56104
57- /* Vtable to identity lookup. */
58105static tthread::mutex *known_mutex = NULL ;
106+
107+ void compound_identity::Init (Core *core)
108+ {
109+ if (!known_mutex)
110+ known_mutex = new tthread::mutex ();
111+
112+ // This cannot be done in the constructors, because
113+ // they are called in an undefined order.
114+ for (compound_identity *p = list; p; p = p->next )
115+ p->doInit (core);
116+
117+ // FIXME: ... nuked. the group was empty...
118+ /*
119+ // Read pre-filled vtable ptrs
120+ OffsetGroup *ptr_table = core->vinfo->getGroup("vtable");
121+ for (virtual_identity *p = list; p; p = p->next) {
122+ void * tmp;
123+ if (ptr_table->getSafeAddress(p->getName(),tmp))
124+ p->vtable_ptr = tmp;
125+ }
126+ */
127+ }
128+
129+ bitfield_identity::bitfield_identity (size_t size,
130+ compound_identity *scope_parent, const char *dfhack_name,
131+ int num_bits, const bitfield_item_info *bits)
132+ : compound_identity(size, NULL , scope_parent, dfhack_name), bits(bits), num_bits(num_bits)
133+ {
134+ }
135+
136+ enum_identity::enum_identity (size_t size,
137+ compound_identity *scope_parent, const char *dfhack_name,
138+ type_identity *base_type,
139+ int64_t first_item_value, int64_t last_item_value,
140+ const char *const *keys)
141+ : compound_identity(size, NULL , scope_parent, dfhack_name),
142+ first_item_value(first_item_value), last_item_value(last_item_value),
143+ keys(keys), base_type(base_type)
144+ {
145+ }
146+
147+ struct_identity::struct_identity (size_t size, TAllocateFn alloc,
148+ compound_identity *scope_parent, const char *dfhack_name,
149+ struct_identity *parent, const struct_field_info *fields)
150+ : compound_identity(size, alloc, scope_parent, dfhack_name),
151+ parent(parent), has_children(false ), fields(fields)
152+ {
153+ }
154+
155+ void struct_identity::doInit (Core *core)
156+ {
157+ compound_identity::doInit (core);
158+
159+ if (parent) {
160+ parent->children .push_back (this );
161+ parent->has_children = true ;
162+ }
163+ }
164+
165+ bool struct_identity::is_subclass (struct_identity *actual)
166+ {
167+ for (; actual; actual = actual->getParent ())
168+ if (actual == this ) return true ;
169+
170+ return false ;
171+ }
172+
173+ std::string pointer_identity::getFullName ()
174+ {
175+ return (target ? target->getFullName () : std::string (" void" )) + " *" ;
176+ }
177+
178+ std::string container_identity::getFullName (type_identity *item)
179+ {
180+ return " <" + (item ? item->getFullName () : std::string (" void" )) + " >" ;
181+ }
182+
183+ std::string ptr_container_identity::getFullName (type_identity *item)
184+ {
185+ return " <" + (item ? item->getFullName () : std::string (" void" )) + " *>" ;
186+ }
187+
188+ std::string bit_container_identity::getFullName (type_identity *)
189+ {
190+ return " <bool>" ;
191+ }
192+
193+ std::string df::buffer_container_identity::getFullName (type_identity *item)
194+ {
195+ return (item ? item->getFullName () : std::string (" void" )) +
196+ (size > 0 ? stl_sprintf (" [%d]" , size) : std::string (" []" ));
197+ }
198+
199+ virtual_identity::virtual_identity (size_t size, TAllocateFn alloc,
200+ const char *dfhack_name, const char *original_name,
201+ virtual_identity *parent, const struct_field_info *fields)
202+ : struct_identity(size, alloc, NULL , dfhack_name, parent, fields), original_name(original_name),
203+ vtable_ptr(NULL )
204+ {
205+ }
206+
207+ static std::map<std::string, virtual_identity*> name_lookup;
208+
209+ void virtual_identity::doInit (Core *core)
210+ {
211+ struct_identity::doInit (core);
212+
213+ name_lookup[getOriginalName ()] = this ;
214+ }
215+
216+ /* Vtable to identity lookup. */
59217std::map<void *, virtual_identity*> virtual_identity::known;
60218
61219virtual_identity *virtual_identity::get (virtual_ptr instance_ptr)
@@ -78,8 +236,9 @@ virtual_identity *virtual_identity::get(virtual_ptr instance_ptr)
78236
79237 virtual_identity *actual = NULL ;
80238
81- for (virtual_identity *p = list; p; p = p->next ) {
82- if (strcmp (name.c_str (), p->getOriginalName ()) != 0 ) continue ;
239+ auto name_it = name_lookup.find (name);
240+ if (name_it != name_lookup.end ()) {
241+ virtual_identity *p = name_it->second ;
83242
84243 if (p->vtable_ptr && p->vtable_ptr != vtable) {
85244 std::cerr << " Conflicting vtable ptr for class '" << p->getName ()
@@ -103,14 +262,6 @@ virtual_identity *virtual_identity::get(virtual_ptr instance_ptr)
103262 return NULL ;
104263}
105264
106- bool virtual_identity::is_subclass (virtual_identity *actual)
107- {
108- for (; actual; actual = actual->parent )
109- if (actual == this ) return true ;
110-
111- return false ;
112- }
113-
114265void virtual_identity::adjust_vtable (virtual_ptr obj, virtual_identity *main)
115266{
116267 if (vtable_ptr) {
@@ -135,35 +286,6 @@ virtual_ptr virtual_identity::clone(virtual_ptr obj)
135286 return copy;
136287}
137288
138- void virtual_identity::Init (Core *core)
139- {
140- if (!known_mutex)
141- known_mutex = new tthread::mutex ();
142-
143- // This cannot be done in the constructors, because
144- // they are called in an undefined order.
145- for (virtual_identity *p = list; p; p = p->next ) {
146- p->has_children = false ;
147- p->children .clear ();
148- }
149- for (virtual_identity *p = list; p; p = p->next ) {
150- if (p->parent ) {
151- p->parent ->children .push_back (p);
152- p->parent ->has_children = true ;
153- }
154- }
155- // FIXME: ... nuked. the group was empty...
156- /*
157- // Read pre-filled vtable ptrs
158- OffsetGroup *ptr_table = core->vinfo->getGroup("vtable");
159- for (virtual_identity *p = list; p; p = p->next) {
160- void * tmp;
161- if (ptr_table->getSafeAddress(p->getName(),tmp))
162- p->vtable_ptr = tmp;
163- }
164- */
165- }
166-
167289bool DFHack::findBitfieldField (unsigned *idx, const std::string &name,
168290 unsigned size, const bitfield_item_info *items)
169291{
0 commit comments