Minor refactoring of container indexing and object allocation.

develop
Alexander Gavrilov 2012-03-22 10:56:32 +04:00
parent ad10303cec
commit 27824642d9
5 changed files with 95 additions and 56 deletions

@ -40,6 +40,37 @@ distribution.
using namespace DFHack;
void *type_identity::do_allocate_pod() {
void *p = malloc(size);
memset(p, 0, size);
return p;
}
void type_identity::do_copy_pod(void *tgt, const void *src) {
memmove(tgt, src, size);
};
void *type_identity::allocate() {
if (can_allocate())
return do_allocate();
else
return NULL;
}
bool type_identity::copy(void *tgt, const void *src) {
if (can_allocate() && tgt && src)
do_copy(tgt, src);
else
return false;
}
void *enum_identity::do_allocate() {
void *p = malloc(byte_size());
memcpy(p, &first_item_value, std::min(byte_size(), sizeof(int64_t)));
return p;
}
/* The order of global object constructor calls is
* undefined between compilation units. Therefore,
* this list has to be plain data, so that it gets
@ -95,19 +126,19 @@ void compound_identity::Init(Core *core)
*/
}
bitfield_identity::bitfield_identity(size_t size, TAllocateFn alloc,
bitfield_identity::bitfield_identity(size_t size,
compound_identity *scope_parent, const char *dfhack_name,
int num_bits, const bitfield_item_info *bits)
: compound_identity(size, alloc, scope_parent, dfhack_name), bits(bits), num_bits(num_bits)
: compound_identity(size, NULL, scope_parent, dfhack_name), bits(bits), num_bits(num_bits)
{
}
enum_identity::enum_identity(size_t size, TAllocateFn alloc,
enum_identity::enum_identity(size_t size,
compound_identity *scope_parent, const char *dfhack_name,
type_identity *base_type,
int64_t first_item_value, int64_t last_item_value,
const char *const *keys)
: compound_identity(size, alloc, scope_parent, dfhack_name),
: compound_identity(size, NULL, scope_parent, dfhack_name),
first_item_value(first_item_value), last_item_value(last_item_value),
keys(keys), base_type(base_type)
{

@ -265,29 +265,29 @@ int container_identity::lua_item_count(lua_State *state, void *ptr)
int container_identity::lua_item_read(lua_State *state, int fname_idx, void *ptr, int idx)
{
void *pitem = item_pointer(ptr, idx);
auto id = (type_identity*)lua_touserdata(state, UPVAL_ITEM_ID);
void *pitem = item_pointer(id, ptr, idx);
return id->lua_read(state, fname_idx, pitem);
}
void container_identity::lua_item_write(lua_State *state, int fname_idx, void *ptr, int idx, int val_index)
{
void *pitem = item_pointer(ptr, idx);
auto id = (type_identity*)lua_touserdata(state, UPVAL_ITEM_ID);
void *pitem = item_pointer(id, ptr, idx);
id->lua_write(state, fname_idx, pitem, val_index);
}
int ptr_container_identity::lua_item_read(lua_State *state, int fname_idx, void *ptr, int idx)
{
void *pitem = item_pointer(ptr, idx);
auto id = (type_identity*)lua_touserdata(state, UPVAL_ITEM_ID);
void *pitem = item_pointer(&df::identity_traits<void*>::identity, ptr, idx);
return df::pointer_identity::lua_read(state, fname_idx, pitem, id);
}
void ptr_container_identity::lua_item_write(lua_State *state, int fname_idx, void *ptr, int idx, int val_index)
{
void *pitem = item_pointer(ptr, idx);
auto id = (type_identity*)lua_touserdata(state, UPVAL_ITEM_ID);
void *pitem = item_pointer(&df::identity_traits<void*>::identity, ptr, idx);
df::pointer_identity::lua_write(state, fname_idx, pitem, id, val_index);
}
@ -307,25 +307,12 @@ void bit_container_identity::lua_item_write(lua_State *state, int fname_idx, voi
field_error(state, fname_idx, "boolean or number expected", "write");
}
int df::buffer_container_identity::lua_item_read(lua_State *state, int fname_idx, void *ptr, int idx)
{
auto id = (type_identity*)lua_touserdata(state, UPVAL_ITEM_ID);
void *pitem = ((uint8_t*)ptr) + idx * id->byte_size();
return id->lua_read(state, fname_idx, pitem);
}
void df::buffer_container_identity::lua_item_write(lua_State *state, int fname_idx, void *ptr, int idx, int val_index)
{
auto id = (type_identity*)lua_touserdata(state, UPVAL_ITEM_ID);
void *pitem = ((uint8_t*)ptr) + idx * id->byte_size();
id->lua_write(state, fname_idx, pitem, val_index);
}
/* */
static int change_error(lua_State *state)
{
luaL_error(state, "Attempt to change a read-only table.\n");
return 0;
}
/**
@ -618,6 +605,8 @@ static int read_field(lua_State *state, const struct_field_info *field, void *pt
case struct_field_info::END:
return 0;
}
return 0;
}
static void write_field(lua_State *state, const struct_field_info *field, void *ptr, int value_idx)

@ -69,14 +69,12 @@ namespace DFHack
protected:
type_identity(size_t size) : size(size) {};
virtual void *do_instantiate() {
void *p = malloc(size);
memset(p, 0, size);
return p;
}
virtual void do_copy(void *tgt, const void *src) {
memmove(tgt, src, size);
};
void *do_allocate_pod();
void do_copy_pod(void *tgt, const void *src);
virtual bool can_allocate() { return true; }
virtual void *do_allocate() { return do_allocate_pod(); }
virtual void do_copy(void *tgt, const void *src) { do_copy_pod(tgt, src); }
public:
virtual ~type_identity() {}
@ -93,6 +91,9 @@ namespace DFHack
virtual void build_metatable(lua_State *state);
virtual bool isContainer() { return false; }
void *allocate();
bool copy(void *tgt, const void *src);
};
class DFHACK_EXPORT constructed_identity : public type_identity {
@ -102,13 +103,9 @@ namespace DFHack
constructed_identity(size_t size, TAllocateFn alloc)
: type_identity(size), allocator(alloc) {};
virtual void *do_instantiate() {
return allocator ? allocator(NULL,NULL) : type_identity::do_instantiate();
}
virtual void do_copy(void *tgt, const void *src) {
if (allocator) allocator(tgt,src);
else type_identity::do_copy(tgt, src);
};
virtual bool can_allocate() { return (allocator != NULL); }
virtual void *do_allocate() { return allocator(NULL,NULL); }
virtual void do_copy(void *tgt, const void *src) { allocator(tgt,src); }
virtual int lua_read(lua_State *state, int fname_idx, void *ptr);
virtual void lua_write(lua_State *state, int fname_idx, void *ptr, int val_index);
@ -151,8 +148,13 @@ namespace DFHack
const bitfield_item_info *bits;
int num_bits;
protected:
virtual bool can_allocate() { return true; }
virtual void *do_allocate() { return do_allocate_pod(); }
virtual void do_copy(void *tgt, const void *src) { do_copy_pod(tgt, src); }
public:
bitfield_identity(size_t size, TAllocateFn alloc,
bitfield_identity(size_t size,
compound_identity *scope_parent, const char *dfhack_name,
int num_bits, const bitfield_item_info *bits);
@ -171,8 +173,13 @@ namespace DFHack
type_identity *base_type;
protected:
virtual bool can_allocate() { return true; }
virtual void *do_allocate();
virtual void do_copy(void *tgt, const void *src) { do_copy_pod(tgt, src); }
public:
enum_identity(size_t size, TAllocateFn alloc,
enum_identity(size_t size,
compound_identity *scope_parent, const char *dfhack_name,
type_identity *base_type,
int64_t first_item_value, int64_t last_item_value,
@ -266,6 +273,8 @@ namespace DFHack
static void *get_vtable(virtual_ptr instance_ptr) { return *(void**)instance_ptr; }
bool can_allocate() { return struct_identity::can_allocate() && (vtable_ptr != NULL); }
public:
virtual_identity(size_t size, TAllocateFn alloc,
const char *dfhack_name, const char *original_name,
@ -295,8 +304,8 @@ namespace DFHack
}
public:
bool can_instantiate() { return (vtable_ptr != NULL); }
virtual_ptr instantiate() { return can_instantiate() ? (virtual_ptr)do_instantiate() : NULL; }
bool can_instantiate() { return can_allocate(); }
virtual_ptr instantiate() { return can_instantiate() ? (virtual_ptr)do_allocate() : NULL; }
static virtual_ptr clone(virtual_ptr obj);
public:

@ -92,7 +92,7 @@ namespace DFHack
protected:
virtual int item_count(void *ptr) = 0;
virtual void *item_pointer(void *ptr, int idx) = 0;
virtual void *item_pointer(type_identity *item, void *ptr, int idx) = 0;
};
class DFHACK_EXPORT ptr_container_identity : public container_identity {
@ -122,7 +122,7 @@ namespace DFHack
virtual void lua_item_write(lua_State *state, int fname_idx, void *ptr, int idx, int val_index);
protected:
virtual void *item_pointer(void *, int) { return NULL; }
virtual void *item_pointer(type_identity *, void *, int) { return NULL; }
virtual bool get_item(void *ptr, int idx) = 0;
virtual void set_item(void *ptr, int idx, bool val) = 0;
@ -185,6 +185,11 @@ namespace df
class stl_ptr_vector_identity : public ptr_container_identity {
public:
/*
* This class assumes that std::vector<T*> is equivalent
* in layout and behavior to std::vector<void*> for any T.
*/
stl_ptr_vector_identity(type_identity *item = NULL, enum_identity *ienum = NULL)
: ptr_container_identity(sizeof(std::vector<void*>),allocator_fn<std::vector<void*> >,item, ienum)
{};
@ -199,7 +204,7 @@ namespace df
virtual int item_count(void *ptr) {
return ((std::vector<void*>*)ptr)->size();
};
virtual void *item_pointer(void *ptr, int idx) {
virtual void *item_pointer(type_identity *, void *ptr, int idx) {
return &(*(std::vector<void*>*)ptr)[idx];
}
};
@ -220,12 +225,11 @@ namespace df
static buffer_container_identity base_instance;
virtual int lua_item_read(lua_State *state, int fname_idx, void *ptr, int idx);
virtual void lua_item_write(lua_State *state, int fname_idx, void *ptr, int idx, int val_index);
protected:
virtual int item_count(void *ptr) { return size; }
virtual void *item_pointer(void *ptr, int idx) { return NULL; }
virtual void *item_pointer(type_identity *item, void *ptr, int idx) {
return ((uint8_t*)ptr) + idx * item->byte_size();
}
};
template<class T>
@ -243,29 +247,35 @@ namespace df
protected:
virtual int item_count(void *ptr) { return ((T*)ptr)->size(); }
virtual void *item_pointer(void *ptr, int idx) { return &(*(T*)ptr)[idx]; }
virtual void *item_pointer(type_identity *item, void *ptr, int idx) {
return &(*(T*)ptr)[idx];
}
};
template<class T>
class bit_array_identity : public bit_container_identity {
public:
typedef BitArray<T> container;
/*
* This class assumes that BitArray<T> is equivalent
* in layout and behavior to BitArray<int> for any T.
*/
typedef BitArray<int> container;
bit_array_identity(enum_identity *ienum = NULL)
: bit_container_identity(sizeof(container), &allocator_fn<container>, ienum)
{}
std::string getFullName(type_identity *item) {
return "BitArray" + bit_container_identity::getFullName(item);
return "BitArray<>";
}
protected:
virtual int item_count(void *ptr) { return ((container*)ptr)->size * 8; }
virtual bool get_item(void *ptr, int idx) {
return ((container*)ptr)->is_set(T(idx));
return ((container*)ptr)->is_set(idx);
}
virtual void set_item(void *ptr, int idx, bool val) {
((container*)ptr)->set(T(idx), val);
((container*)ptr)->set(idx, val);
}
};
@ -412,7 +422,7 @@ namespace df
bit_container_identity *identity_traits<BitArray<T> >::get() {
static type_identity *eid = identity_traits<T>::get();
static enum_identity *reid = eid->type() == DFHack::IDTYPE_ENUM ? (enum_identity*)eid : NULL;
static bit_array_identity<T> identity(reid);
static bit_array_identity identity(reid);
return &identity;
}

@ -1 +1 @@
Subproject commit c90a2d499024319ea9aa4f98b3b61df7bba2fc62
Subproject commit b28296a8c0c2e5aaa522840598738109018f0146