Use a better ID for identifying classes.

Upon testing (and reading), getting the address of a static
is safe even across .so boundaries. Moreover it doesn't incur
into the risk of collisions, unlike hashes, and also works
with different classes with the same name (for example from
two different unnamed namespaces). At this point the crc32
stuff is pretty much redundant, I'll try to remove it next.
This commit is contained in:
King_DuckZ 2022-06-03 09:39:43 +02:00
commit 09530e15c9
10 changed files with 164 additions and 70 deletions

View file

@ -80,6 +80,15 @@ namespace wren {
std::size_t ClassNameHash::operator()(TempClassName value) const {
return value.module_hash() ^ (value.class_hash() << 1);
}
std::size_t TypeIDHash::operator()(TypeID tid) const {
if constexpr (sizeof(tid.id()) > sizeof(std::size_t)) {
return std::hash<decltype(tid.id())>{}(tid.id());
}
else {
return static_cast<std::size_t>(tid.id());
}
}
} //namespace detail
ClassManager::ClassManager() = default;
@ -119,15 +128,15 @@ namespace wren {
return retval;
}
void ClassManager::add_type (ClassManagerNameHashType hash, const detail::ClassNameOwning* name) {
void ClassManager::add_type (TypeID hash, const detail::ClassNameOwning* name) {
using detail::TempClassName;
assert(m_types.count(hash) == 0 or m_types.at(hash) == name);
assert(m_types.count(hash) == 0 or *m_types.at(hash) == *name);
//insert if not present, leave old value if hash is already there
m_types.insert(std::make_pair(hash, name));
}
ModuleAndName ClassManager::wren_class_name_from_hash(ClassManagerNameHashType hash) const {
ModuleAndName ClassManager::wren_class_name_from_hash(TypeID hash) const {
const auto it_found = m_types.find(hash);
if (m_types.cend() != it_found) {
const detail::ClassNameOwning* const name = it_found->second;

View file

@ -162,7 +162,8 @@ namespace wren {
struct VM::LocalData {
explicit LocalData (const detail::Callbacks& cb) :
callbacks(cb),
wvm(nullptr)
wvm(nullptr),
user_data_type(type_id<std::nullptr_t>())
{
callbacks.dynafunc = &dynafunc;
}
@ -180,10 +181,10 @@ namespace wren {
DynafuncMaker dynafunc;
WrenVM* wvm;
void* user_data;
std::uint32_t user_data_type;
TypeID user_data_type;
};
VM::VM (Configuration* conf, const detail::Callbacks& cb, void* user_data, std::uint32_t user_data_type) :
VM::VM (Configuration* conf, const detail::Callbacks& cb, void* user_data, TypeID user_data_type) :
m_local(std::make_unique<LocalData>(cb))
{
this->reset(conf);
@ -197,7 +198,7 @@ namespace wren {
return &m_local->dynafunc;
}
std::uint32_t VM::user_data_type() const {
TypeID VM::user_data_type() const {
return m_local->user_data_type;
}
@ -205,7 +206,7 @@ namespace wren {
return m_local->user_data;
}
void VM::set_user_data (void* user_data, std::uint32_t user_data_type) {
void VM::set_user_data (void* user_data, TypeID user_data_type) {
m_local->user_data = user_data;
m_local->user_data_type = user_data_type;
}
@ -281,7 +282,7 @@ namespace wren {
void VM::set_user_data (std::nullptr_t) {
m_local->user_data = nullptr;
m_local->user_data_type = detail::type_id<std::nullptr_t>();
m_local->user_data_type = type_id<std::nullptr_t>();
}
bool VM::has_user_data() const noexcept {

View file

@ -6,7 +6,7 @@ namespace wren {
namespace detail {
ModuleAndName fetch_class_name_from_manager (
const VM& vm,
ClassManagerNameHashType hash
TypeID hash
) {
return vm.class_manager().wren_class_name_from_hash(hash);
}