Browse Source

Add C++ WebAssembly ABI (#1711)

* Minor code refactorings.

* Fix debug assert issue with vtable methods.

* Add support for WebAssembly C++ ABI to parser and AST converter.
quickjs
João Matos 2 years ago committed by GitHub
parent
commit
9b06e7bc01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      src/AST/ASTContext.cs
  2. 9
      src/AST/ClassLayout.cs
  3. 2
      src/CLI/CLI.cs
  4. 26
      src/CLI/Generator.cs
  5. 3
      src/CppParser/Bindings/CLI/Decl.h
  6. 3
      src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/CppSharp.CppParser.cs
  7. 3
      src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/CppSharp.CppParser.cs
  8. 3
      src/CppParser/Bindings/CSharp/x86_64-apple-darwin12.4.0/CppSharp.CppParser.cs
  9. 3
      src/CppParser/Bindings/CSharp/x86_64-linux-gnu-cxx11abi/CppSharp.CppParser.cs
  10. 3
      src/CppParser/Bindings/CSharp/x86_64-linux-gnu/CppSharp.CppParser.cs
  11. 3
      src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/CppSharp.CppParser.cs
  12. 1650
      src/CppParser/Decl.h
  13. 2
      src/CppParser/Parser.cpp
  14. 9
      src/Generator.Tests/GeneratorTest.cs
  15. 1
      src/Generator/AST/VTables.cs
  16. 2
      src/Parser/ASTConverter.cs
  17. 2
      src/Parser/Parser.cs
  18. 25
      src/Parser/ParserOptions.cs

3
src/AST/ASTContext.cs

@ -11,7 +11,8 @@ namespace CppSharp.AST
Microsoft, Microsoft,
ARM, ARM,
iOS, iOS,
iOS64 iOS64,
WebAssembly
} }
/// <summary> /// <summary>

9
src/AST/ClassLayout.cs

@ -31,14 +31,7 @@ namespace CppSharp.AST
public Declaration Declaration; public Declaration Declaration;
/// Method declaration (if Kind == FunctionPointer). /// Method declaration (if Kind == FunctionPointer).
public Method Method public Method Method => Declaration as Method;
{
get
{
Debug.Assert(Kind == VTableComponentKind.FunctionPointer);
return Declaration as Method;
}
}
} }
/// <summary> /// <summary>

2
src/CLI/CLI.cs

@ -288,7 +288,7 @@ namespace CppSharp
Generator gen = new Generator(options); Generator gen = new Generator(options);
bool validOptions = gen.ValidateOptions(errorMessages); var validOptions = gen.ValidateOptions(errorMessages);
PrintErrorMessages(errorMessages); PrintErrorMessages(errorMessages);
if (errorMessages.Any() || !validOptions) if (errorMessages.Any() || !validOptions)

26
src/CLI/Generator.cs

@ -13,30 +13,13 @@ namespace CppSharp
{ {
class Generator : ILibrary class Generator : ILibrary
{ {
private Options options = null; private readonly Options options;
private string triple = ""; private string triple = "";
private CppAbi abi = CppAbi.Microsoft; private CppAbi abi = CppAbi.Microsoft;
public Generator(Options options) public Generator(Options options)
{ {
if (options == null) this.options = options ?? throw new ArgumentNullException(nameof(options));
throw new ArgumentNullException(nameof(options));
this.options = options;
}
static TargetPlatform GetCurrentPlatform()
{
if (Platform.IsWindows)
return TargetPlatform.Windows;
if (Platform.IsMacOS)
return TargetPlatform.MacOS;
if (Platform.IsLinux)
return TargetPlatform.Linux;
throw new System.NotImplementedException("Unknown host platform");
} }
void SetupTargetTriple() void SetupTargetTriple()
@ -78,8 +61,7 @@ namespace CppSharp
return false; return false;
} }
if (!options.Platform.HasValue) options.Platform ??= Platform.Host;
options.Platform = GetCurrentPlatform();
if (string.IsNullOrEmpty(options.OutputDir)) if (string.IsNullOrEmpty(options.OutputDir))
{ {
@ -189,7 +171,7 @@ namespace CppSharp
public void Run() public void Run()
{ {
StringBuilder messageBuilder = new StringBuilder(); var messageBuilder = new StringBuilder();
messageBuilder.Append($"Generating {GetGeneratorKindName(options.Kind)}"); messageBuilder.Append($"Generating {GetGeneratorKindName(options.Kind)}");
messageBuilder.Append($" bindings for {GetPlatformName(options.Platform)} {options.Architecture}"); messageBuilder.Append($" bindings for {GetPlatformName(options.Platform)} {options.Architecture}");

3
src/CppParser/Bindings/CLI/Decl.h

@ -256,7 +256,8 @@ namespace CppSharp
Microsoft = 1, Microsoft = 1,
ARM = 2, ARM = 2,
iOS = 3, iOS = 3,
iOS64 = 4 iOS64 = 4,
WebAssembly = 5
}; };
public enum class RecordArgABI public enum class RecordArgABI

3
src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/CppSharp.CppParser.cs

@ -6301,7 +6301,8 @@ namespace CppSharp
Microsoft = 1, Microsoft = 1,
ARM = 2, ARM = 2,
iOS = 3, iOS = 3,
iOS64 = 4 iOS64 = 4,
WebAssembly = 5
} }
public enum RecordArgABI public enum RecordArgABI

3
src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/CppSharp.CppParser.cs

@ -6301,7 +6301,8 @@ namespace CppSharp
Microsoft = 1, Microsoft = 1,
ARM = 2, ARM = 2,
iOS = 3, iOS = 3,
iOS64 = 4 iOS64 = 4,
WebAssembly = 5
} }
public enum RecordArgABI public enum RecordArgABI

3
src/CppParser/Bindings/CSharp/x86_64-apple-darwin12.4.0/CppSharp.CppParser.cs

@ -6301,7 +6301,8 @@ namespace CppSharp
Microsoft = 1, Microsoft = 1,
ARM = 2, ARM = 2,
iOS = 3, iOS = 3,
iOS64 = 4 iOS64 = 4,
WebAssembly = 5
} }
public enum RecordArgABI public enum RecordArgABI

3
src/CppParser/Bindings/CSharp/x86_64-linux-gnu-cxx11abi/CppSharp.CppParser.cs

@ -6301,7 +6301,8 @@ namespace CppSharp
Microsoft = 1, Microsoft = 1,
ARM = 2, ARM = 2,
iOS = 3, iOS = 3,
iOS64 = 4 iOS64 = 4,
WebAssembly = 5
} }
public enum RecordArgABI public enum RecordArgABI

3
src/CppParser/Bindings/CSharp/x86_64-linux-gnu/CppSharp.CppParser.cs

@ -6301,7 +6301,8 @@ namespace CppSharp
Microsoft = 1, Microsoft = 1,
ARM = 2, ARM = 2,
iOS = 3, iOS = 3,
iOS64 = 4 iOS64 = 4,
WebAssembly = 5
} }
public enum RecordArgABI public enum RecordArgABI

3
src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/CppSharp.CppParser.cs

@ -6301,7 +6301,8 @@ namespace CppSharp
Microsoft = 1, Microsoft = 1,
ARM = 2, ARM = 2,
iOS = 3, iOS = 3,
iOS64 = 4 iOS64 = 4,
WebAssembly = 5
} }
public enum RecordArgABI public enum RecordArgABI

1650
src/CppParser/Decl.h

File diff suppressed because it is too large Load Diff

2
src/CppParser/Parser.cpp

@ -104,6 +104,8 @@ static CppAbi GetClassLayoutAbi(clang::TargetCXXABI::Kind abi)
return CppAbi::iOS; return CppAbi::iOS;
case clang::TargetCXXABI::AppleARM64: case clang::TargetCXXABI::AppleARM64:
return CppAbi::iOS64; return CppAbi::iOS64;
case clang::TargetCXXABI::WebAssembly:
return CppAbi::WebAssembly;
default: default:
llvm_unreachable("Unsupported C++ ABI kind"); llvm_unreachable("Unsupported C++ ABI kind");
} }

9
src/Generator.Tests/GeneratorTest.cs

@ -72,7 +72,7 @@ namespace CppSharp.Utils
public static string GetTestsDirectory(string name) public static string GetTestsDirectory(string name)
{ {
var directory = new DirectoryInfo( var directory = new DirectoryInfo(
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? string.Empty);
while (directory != null) while (directory != null)
{ {
@ -89,15 +89,12 @@ namespace CppSharp.Utils
directory = directory.Parent; directory = directory.Parent;
} }
throw new Exception(string.Format( throw new Exception($"Tests directory for project '{name}' was not found");
"Tests directory for project '{0}' was not found", name));
} }
static string GetOutputDirectory() static string GetOutputDirectory()
{ {
string exePath = new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath; var directory = Directory.GetParent(Assembly.GetExecutingAssembly().Location);
var directory = Directory.GetParent(exePath);
while (directory != null) while (directory != null)
{ {
var path = Path.Combine(directory.FullName, "build"); var path = Path.Combine(directory.FullName, "build");

1
src/Generator/AST/VTables.cs

@ -34,6 +34,7 @@ namespace CppSharp.AST
where component.Kind != VTableComponentKind.CompleteDtorPointer && where component.Kind != VTableComponentKind.CompleteDtorPointer &&
component.Kind != VTableComponentKind.RTTI && component.Kind != VTableComponentKind.RTTI &&
component.Kind != VTableComponentKind.UnusedFunctionPointer && component.Kind != VTableComponentKind.UnusedFunctionPointer &&
component.Kind != VTableComponentKind.OffsetToTop &&
component.Method != null component.Method != null
select component); select component);

2
src/Parser/ASTConverter.cs

@ -1719,6 +1719,8 @@ namespace CppSharp
return AST.CppAbi.iOS; return AST.CppAbi.iOS;
case CppAbi.iOS64: case CppAbi.iOS64:
return AST.CppAbi.iOS64; return AST.CppAbi.iOS64;
case CppAbi.WebAssembly:
return AST.CppAbi.WebAssembly;
default: default:
throw new ArgumentOutOfRangeException("abi"); throw new ArgumentOutOfRangeException("abi");
} }

2
src/Parser/Parser.cs

@ -59,7 +59,7 @@ namespace CppSharp
/// <summary> /// <summary>
/// Converts a native parser AST to a managed AST. /// Converts a native parser AST to a managed AST.
/// </summary> /// </summary>
static public AST.ASTContext ConvertASTContext(ASTContext context) public static AST.ASTContext ConvertASTContext(ASTContext context)
{ {
var converter = new ASTConverter(context); var converter = new ASTConverter(context);
return converter.Convert(); return converter.Convert();

25
src/Parser/ParserOptions.cs

@ -5,9 +5,7 @@ using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using LanguageVersion = CppSharp.Parser.LanguageVersion;
namespace CppSharp.Parser namespace CppSharp.Parser
{ {
@ -200,20 +198,22 @@ namespace CppSharp.Parser
var versions = Directory.EnumerateDirectories(Path.Combine(headersPath, var versions = Directory.EnumerateDirectories(Path.Combine(headersPath,
"usr", "include", "c++")); "usr", "include", "c++"));
if (versions.Count() == 0) if (!versions.Any())
throw new Exception("No valid GCC version found on system include paths"); throw new Exception("No valid GCC version found on system include paths");
string gccVersionPath = versions.First(); var gccVersionPath = versions.First();
longVersion = shortVersion = gccVersionPath.Substring( longVersion = shortVersion = gccVersionPath.Substring(
gccVersionPath.LastIndexOf(Path.DirectorySeparatorChar) + 1); gccVersionPath.LastIndexOf(Path.DirectorySeparatorChar) + 1);
return; return;
} }
var info = new ProcessStartInfo(Environment.GetEnvironmentVariable("CXX") ?? "gcc", "-v"); var info = new ProcessStartInfo(Environment.GetEnvironmentVariable("CXX") ?? "gcc", "-v")
info.RedirectStandardError = true; {
info.CreateNoWindow = true; RedirectStandardError = true,
info.UseShellExecute = false; CreateNoWindow = true,
UseShellExecute = false
};
var process = Process.Start(info); var process = Process.Start(info);
if (process == null) if (process == null)
@ -237,13 +237,12 @@ namespace CppSharp.Parser
NoBuiltinIncludes = true; NoBuiltinIncludes = true;
NoStandardIncludes = true; NoStandardIncludes = true;
string compiler, longVersion, shortVersion; GetUnixCompilerInfo(headersPath, out var compiler, out var longVersion, out var shortVersion);
GetUnixCompilerInfo(headersPath, out compiler, out longVersion, out shortVersion);
AddSystemIncludeDirs(BuiltinsDir); AddSystemIncludeDirs(BuiltinsDir);
AddArguments($"-fgnuc-version={longVersion}"); AddArguments($"-fgnuc-version={longVersion}");
string majorVersion = shortVersion.Split('.')[0]; var majorVersion = shortVersion.Split('.')[0];
string[] versions = { longVersion, shortVersion, majorVersion }; string[] versions = { longVersion, shortVersion, majorVersion };
string[] triples = { "x86_64-linux-gnu", "x86_64-pc-linux-gnu" }; string[] triples = { "x86_64-linux-gnu", "x86_64-pc-linux-gnu" };
if (compiler == "gcc") if (compiler == "gcc")
@ -287,9 +286,7 @@ namespace CppSharp.Parser
private void SetupArguments() private void SetupArguments()
{ {
// do not remove the CppSharp prefix becase the Mono C# compiler breaks LanguageVersion ??= CppSharp.Parser.LanguageVersion.CPP14_GNU;
if (!LanguageVersion.HasValue)
LanguageVersion = CppSharp.Parser.LanguageVersion.CPP14_GNU;
// As of Clang revision 5e866e411caa we are required to pass "-fgnuc-version=" // As of Clang revision 5e866e411caa we are required to pass "-fgnuc-version="
// to get the __GNUC__ symbol defined. macOS and Linux system headers require // to get the __GNUC__ symbol defined. macOS and Linux system headers require

Loading…
Cancel
Save