Skip to content

Commit 77cf8ac

Browse files
authored
Merge branch 'praydog:master' into master
2 parents 3a4e8aa + 888da74 commit 77cf8ac

5 files changed

Lines changed: 339 additions & 93 deletions

File tree

shared/sdk/RETypeDB.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,25 @@ void* REField::get_data_raw(void* object, bool is_value_type) const {
359359
return Address{object}.get(this->get_offset_from_fieldptr());
360360
}
361361

362+
#if TDB_VER >= 81
363+
// Read fieldptr_offset from the object's own vtable, not from the
364+
// declaring type's managed_vt. For abstract declaring types,
365+
// get_managed_vt() walks up the parent chain and can return an
366+
// ancestor's vtable with a WRONG fieldptr_offset. The object's
367+
// vtable always has the correct value — this matches what the
368+
// .NET runtime does in RuntimeFieldInfo.GetValue.
369+
if (object != nullptr) try {
370+
const auto vtable_ptr = *(uintptr_t*)object;
371+
if (vtable_ptr != 0) {
372+
const auto fieldptr_offset = *(int32_t*)(vtable_ptr - sizeof(void*));
373+
return Address{object}.get(fieldptr_offset + this->get_offset_from_fieldptr());
374+
}
375+
} catch (...) {
376+
// Occurs if consumer passes some bad object in. Need to look into this more.
377+
return nullptr;
378+
}
379+
#endif
380+
362381
return Address{object}.get(this->get_offset_from_base());
363382
}
364383

shared/sdk/RETypeDefinition.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -717,15 +717,15 @@ bool RETypeDefinition::is_by_ref() const {
717717
auto runtime_type = this->get_runtime_type();
718718

719719
if (runtime_type == nullptr) {
720-
g_by_ref_map[this] = true;
721-
return true;
720+
g_by_ref_map[this] = false;
721+
return false;
722722
}
723723

724724
auto runtime_typedef = utility::re_managed_object::get_type_definition(runtime_type);
725725

726726
if (runtime_typedef == nullptr) {
727-
g_by_ref_map[this] = true;
728-
return true;
727+
g_by_ref_map[this] = false;
728+
return false;
729729
}
730730

731731
static auto by_ref_method = runtime_typedef->get_method("get_IsByRef") != nullptr ?

0 commit comments

Comments
 (0)