-
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixed issues with methods which return via buffer.
* Fixed return by buffer for record types on instance methods on Windows x64. * Fixed incorrect void return type on functions with return by buffer semantics. (It should've been the return buffer pointer type again.) * Changed return buffer type on virtual function pointers from out byref to pointer to make it easier to properly implement virtual methods. Fixes #142
- Loading branch information
1 parent
0cd096f
commit e498d90
Showing
9 changed files
with
96 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
using Biohazrd.Tests.Common; | ||
using Xunit; | ||
|
||
namespace Biohazrd.Tests | ||
{ | ||
public sealed class ReturnBufferTests : BiohazrdTestBase | ||
{ | ||
[Fact] | ||
[RelatedIssue("https://github.com/InfectedLibraries/Biohazrd/issues/142")] | ||
public void EnregisterableRecord_Windows() | ||
{ | ||
TranslatedLibrary library = CreateLibrary | ||
(@" | ||
struct MyInt | ||
{ | ||
int X; | ||
}; | ||
MyInt GlobalFunction(); | ||
class MyClass | ||
{ | ||
public: | ||
static MyInt StaticMethod(); | ||
MyInt InstanceMethod(); | ||
virtual MyInt VirtualMethod(); | ||
}; | ||
" | ||
); | ||
|
||
TranslatedFunction globalFunction = library.FindDeclaration<TranslatedFunction>("GlobalFunction"); | ||
TranslatedRecord myClass = library.FindDeclaration<TranslatedRecord>("MyClass"); | ||
TranslatedFunction staticMethod = myClass.FindDeclaration<TranslatedFunction>("StaticMethod"); | ||
TranslatedFunction instanceMethod = myClass.FindDeclaration<TranslatedFunction>("InstanceMethod"); | ||
TranslatedFunction virtualMethod = myClass.FindDeclaration<TranslatedFunction>("VirtualMethod"); | ||
TranslatedVTable vTable = Assert.NotNull(myClass.VTable); | ||
TranslatedVTableEntry vTableFunction = Assert.Single(vTable.Entries, e => e.IsFunctionPointer); | ||
FunctionPointerTypeReference vTableFunctionPointerType = Assert.IsType<FunctionPointerTypeReference>(vTableFunction.Type); | ||
|
||
// https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-160#return-values | ||
// "User-defined types can be returned by value from global functions and static member functions." | ||
// Note the lack of instance methods in this list. | ||
// See https://github.com/InfectedLibraries/Biohazrd/issues/142 for details. | ||
Assert.False(globalFunction.ReturnByReference); | ||
Assert.False(staticMethod.ReturnByReference); | ||
Assert.True(instanceMethod.ReturnByReference); | ||
Assert.True(virtualMethod.ReturnByReference); | ||
|
||
// VTable entries don't directly expose that they're return by reference. | ||
// However, you can observe that they are as a side effect of the return type becoming a pointer and being added as a second parameter. | ||
Assert.IsType<PointerTypeReference>(vTableFunctionPointerType.ReturnType); | ||
Assert.Equal(2, vTableFunctionPointerType.ParameterTypes.Length); // (this, retbuf) | ||
Assert.Equal(vTableFunctionPointerType.ReturnType, vTableFunctionPointerType.ParameterTypes[1]); | ||
} | ||
} | ||
} |