Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regenerate LLVMSharp from the 6.0.0 sources, based on the ClangSharp rewrite #93

Merged
merged 3 commits into from
Apr 29, 2019

Conversation

tannergooding
Copy link
Member

It looks like LLVMSharp is still on 5.0.0, so I've regenerated the sources using the ClangSharp rewrite (dotnet/ClangSharp#34) to help validate things.

As per the original PR, the notable changes are:

  • The visitation logic now considers Location.IsInMainFile, this ultimately means the order is slightly different and that we don't visit #includes. This changes the output order slightly but also means we don't need to keep track of already visited nodes.
  • We return uint for uint rather than int
  • We no longer prefix @ to everything, and instead only prefix it to reserved C# keywords
  • We better follow typedefs and resolve the correct type to output. For example, we will now write out public CXCompletionString CompletionString rather than public IntPtr @CompletionString. The latter (IntPtr) will still be done if there is a double indirection.
  • We no longer explicitly declarate an enum as : int, since that is the default
  • We output IntPtr rather than ulong for size_t, to make the code produced more portable

This should also help minimize diffs when moving to 8.0.0

@tannergooding
Copy link
Member Author

(still reviewing the changes myself to make sure nothing surprising changed since the ordering makes diffing difficult)

src/Generated.cs Outdated Show resolved Hide resolved
src/Generated.cs Outdated Show resolved Hide resolved
src/Generated.cs Outdated
}

public enum lto_symbol_attributes : int
public enum (anonymous enum at E:\Users\tagoo\Repos\llvm\include/llvm-c/Core.h:342:1)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to handle anonymous top level declarations...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the original binding generator code has some logic to try (ForwardDeclarationVisitor) and find the typedef in this scenario. In the rewrite, that logic was dropped in favor of just getting the associated typedef directly from clang...

However, this enum in particular is setup like:

enum {
  LLVMAttributeReturnIndex = 0U,
  LLVMAttributeFunctionIndex = -1,
};

typedef unsigned LLVMAttributeIndex;

So the ForwardDeclarationVisitor would find it, but not the rewrite. However, I also don't think the original code was doing the write thing for more general usage, since there is no guarantee it isn't a truly anonymous enum and that the next typedef is actually related...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's correct. This is better, although when I did this it was for LLVMSharp. In any case, this is better but how do you resolve it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the general use case, I wouldn't expect this is that common (truly anonymous top level declarations) so it is possibly one of those things worth manually handling..

I dont think there will ever be a way to do this reliably and if it isnt common, it might not be worth the having a switch to support it (but having a switch would be a good option if it was common).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've done a manual fixup as part of the PR for now.

src/Generated.cs Outdated Show resolved Hide resolved
src/Generated.cs Outdated Show resolved Hide resolved
@mjsabby
Copy link
Contributor

mjsabby commented Apr 26, 2019

I think llvm 6 but it may be mostly identical.

@tannergooding
Copy link
Member Author

Fixed a few issues and updated to use LLVM 6

@tannergooding tannergooding changed the title Regenerate LLVMSharp from the 5.0.0 sources, based on the ClangSharp rewrite Regenerate LLVMSharp from the 6.0.0 sources, based on the ClangSharp rewrite Apr 28, 2019
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFramework>netstandard2.0</TargetFramework>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is required to support the custom UTF8 string marshaler and puts it at the same target as ClangSharp currently has.

@mjsabby
Copy link
Contributor

mjsabby commented Apr 28, 2019

@tannergooding did you see the build failures?

@tannergooding
Copy link
Member Author

Yes. There are some fixups still required in the wrappers. Those will take a bit longer...

@tannergooding
Copy link
Member Author

I think it should be all resolved now. All tests are passing locally.

@tannergooding
Copy link
Member Author

dotnet/ClangSharp#40 contains the last of the changes that were made when generating this locally.


public sealed class DisasmContext : IDisposableWrapper<LLVMDisasmContextRef>, IDisposable
{
LLVMDisasmContextRef IWrapper<LLVMDisasmContextRef>.ToHandleType => this._instance;
void IDisposableWrapper<LLVMDisasmContextRef>.MakeHandleOwner() => this._owner = true;

private class SymbolLookupClosure
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delegates are generated such that these wrappers are no longer needed.

@@ -111,16 +85,10 @@ private void Dispose(bool disposing)

public unsafe Tuple<string, int> DisasmInstruction(byte[] instructionBytes, ulong programCounter)
{
fixed(byte* iptr = &instructionBytes[0])
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method signatures are largely generated so explicit fixing isn't needed.


public unsafe static ExecutionEngine CreateMCJITCompiler(Module module, int optionsSize)
{
LLVMMCJITCompilerOptions options;
var size = new size_t(new IntPtr(optionsSize));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No more size_t, since the new generator knows to handle it directly as IntPtr

public int RunAsMain(Function f, uint argC, string[] argV, string[] envP) => LLVM.RunFunctionAsMain(this.Unwrap(), f.Unwrap(), argC, argV, envP);
public int RunAsMain(Function f, uint argC, string[] argV, string[] envP)
{
var marshaledArgv = StringMarshaler.MarshalArray(argV);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These weren't being marshaled as LPStr before, so it's possible they were only handling one character...

They are now each marshaled and through the custom marshaler that handles UTF8 data.

public static extern IntPtr DisasmInstruction(LLVMDisasmContextRef DC, out byte Bytes, ulong BytesSize, ulong PC, out byte OutString, IntPtr OutStringSize);

[DllImport(libraryPath, EntryPoint = "LLVMGetBufferStart", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr GetBufferStart(LLVMMemoryBufferRef MemBuf);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A "downside" to the new generator is a few more methods need to be custom handled. This is because LLVM works with "string handles" for most of the inputs and marshaling looks to break that in a few places.

Relying on purely unsafe code would "resolve" that, but would require more explicit work in the wrapper types. That might be beneficial if the wrappers dealt in terms of ROSpan<byte>, but that would place a higher minimum TFM for the library.

@tannergooding
Copy link
Member Author

I don't have permissions to merge on this repo.

@mjsabby
Copy link
Contributor

mjsabby commented Apr 29, 2019

You should now.

@tannergooding tannergooding merged commit d9fd646 into dotnet:master Apr 29, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants