Fix ScriptingObject::FromInterface to return object if the pointer is already valid object

This commit is contained in:
Wojtek Figat
2023-01-09 18:03:14 +01:00
parent 17f9219cd0
commit a74b847e65

View File

@@ -108,21 +108,33 @@ ScriptingObject* ScriptingObject::FromInterface(void* interfaceObj, const Script
if (type.Type != ScriptingTypes::Script)
continue;
auto interfaceImpl = type.GetInterface(interfaceType);
if (interfaceImpl && interfaceImpl->IsNative)
if (!interfaceImpl || !interfaceImpl->IsNative)
continue;
// Get vtable for this type
void* vtable = type.Script.VTable;
if (!vtable && type.GetDefaultInstance())
{
ScriptingObject* predictedObj = (ScriptingObject*)((byte*)interfaceObj - interfaceImpl->VTableOffset);
void* predictedVTable = *(void***)predictedObj;
void* vtable = type.Script.VTable;
if (!vtable && type.GetDefaultInstance())
{
// Use vtable from default instance of this type
vtable = *(void***)type.GetDefaultInstance();
}
if (vtable == predictedVTable)
{
ASSERT(predictedObj->GetType().GetInterface(interfaceType));
return predictedObj;
}
// Use vtable from default instance of this type
vtable = *(void***)type.GetDefaultInstance();
}
// Check if object interface vtable matches the type interface vtable value
ScriptingObject* predictedObj = (ScriptingObject*)((byte*)interfaceObj - interfaceImpl->VTableOffset);
void* predictedVTable = *(void***)predictedObj;
if (vtable == predictedVTable)
{
ASSERT(predictedObj->GetType().GetInterface(interfaceType));
return predictedObj;
}
// Check for case of passing object directly
predictedObj = (ScriptingObject*)interfaceObj;
predictedVTable = *(void***)predictedObj;
if (vtable == predictedVTable)
{
ASSERT(predictedObj->GetType().GetInterface(interfaceType));
return predictedObj;
}
}
}