Skip to content

Commit 3f5fc99

Browse files
authored
QuickJS generator improvements. (mono#1865)
* Fixes to QuickJS marshaling. * Handle more primitive types in `GetInfo`. * Fix generator kind CLI option matching. * Alias QuickJS generator kind to `quickjs`. * General CLI code cleanups. * Default to x64 platform over x86 for the CLI. * Implement new Lua bindings file and commands for CLI tool. * Fix QuickJS primitive type marshaling to take target sizes into account. * Minor code cleanup. * Avoid generating includes to units when generating the QuickJS module. * Update file generation naming pattern for QuickJS files. * Update QuickJS JS_GetOpaque and JS_GetAnyOpaque references to work with latest upstream. * Update QuickJS runtime and support code to work with latest upstream. * Avoid generating properties when generating QuickJS register code. * Update QuickJS test suite to bootstrap its own QuickJS runtime. * Update QuickJS test suite to use a Lua bindings definition file. * Minor fixes to test header files. * Fix C++ warning about return values for event invokes. * Disable some non working tests for QuickJS. * Enable QuickJS testing on CI. * Fix shell color attributes for test scripts when under CI. * WIP CI fixes. * Fix warnings in QuickJS support runtime code. * Use C99 designated initializers for all QuickJS class def members. * Disable QuickJS CI steps on Windows. * Clean up error handling for `JS_ToBool`. * More QuickJS support code fixes. * Rename Signal.cpp to QuickJS nomenclature. * Fix QuickJS JS_ToBigUint call. * Remove QuickJS test script verbosity. * More CI fixes. * Verbose build. * Extension fix.
1 parent d82f78d commit 3f5fc99

32 files changed

+415
-200
lines changed

.github/workflows/main.yml

+11-1
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,20 @@ jobs:
5555
shell: bash
5656
run: build/build.sh -platform $PLATFORM -build_only
5757

58-
- name: Test
58+
- name: Test (.NET)
5959
shell: bash
6060
run: build/test.sh -platform $PLATFORM
6161

62+
- name: Build (QuickJS runtime)
63+
shell: bash
64+
run: tests/quickjs/bootstrap.sh
65+
if: runner.os != 'Windows'
66+
67+
- name: Test (QuickJS)
68+
shell: bash
69+
run: tests/quickjs/test.sh
70+
if: runner.os != 'Windows'
71+
6272
- name: Pack
6373
shell: bash
6474
run: build/build.sh prepack -platform $PLATFORM

Directory.Packages.props

+1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
55
<PackageVersion Include="NUnit" Version="3.13.2" />
66
<PackageVersion Include="NUnit3TestAdapter" Version="4.0.0" />
7+
<PackageVersion Include="MoonSharp" Version="2.0.0" />
78
</ItemGroup>
89
</Project>

src/CLI/CLI.cs

+24-7
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,16 @@ static void HandleAdditionalArgument(string args, List<string> errorMessages)
152152
{
153153
bool searchQuery = args.IndexOf('*') >= 0 || args.IndexOf('?') >= 0;
154154
if (searchQuery || Directory.Exists(args))
155+
{
155156
GetFilesFromPath(args, errorMessages);
157+
}
156158
else if (File.Exists(args))
157-
options.HeaderFiles.Add(args);
159+
{
160+
if (Path.GetExtension(args) == ".lua")
161+
options.LuaBindingsFiles.Add(args);
162+
else
163+
options.HeaderFiles.Add(args);
164+
}
158165
else
159166
{
160167
errorMessages.Add($"File '{args}' could not be found.");
@@ -175,7 +182,8 @@ static void GetFilesFromPath(string path, List<string> errorMessages)
175182

176183
if (lastSeparatorPosition >= 0)
177184
{
178-
if (path.IndexOf('*', lastSeparatorPosition) >= lastSeparatorPosition || path.IndexOf('?', lastSeparatorPosition) >= lastSeparatorPosition)
185+
if (path.IndexOf('*', lastSeparatorPosition) >= lastSeparatorPosition ||
186+
path.IndexOf('?', lastSeparatorPosition) >= lastSeparatorPosition)
179187
{
180188
searchPattern = path.Substring(lastSeparatorPosition + 1);
181189
path = path.Substring(0, lastSeparatorPosition);
@@ -204,7 +212,7 @@ static void GetFilesFromPath(string path, List<string> errorMessages)
204212
}
205213
}
206214

207-
static void GetGeneratorKind(string generator, List<string> errorMessages)
215+
public static void GetGeneratorKind(string generator, List<string> errorMessages)
208216
{
209217
foreach (GeneratorKind generatorKind in GeneratorKind.Registered)
210218
{
@@ -218,7 +226,7 @@ static void GetGeneratorKind(string generator, List<string> errorMessages)
218226
errorMessages.Add($"Unknown generator kind: {generator}.");
219227
}
220228

221-
static void GetDestinationPlatform(string platform, List<string> errorMessages)
229+
public static void GetDestinationPlatform(string platform, List<string> errorMessages)
222230
{
223231
switch (platform.ToLower())
224232
{
@@ -239,7 +247,7 @@ static void GetDestinationPlatform(string platform, List<string> errorMessages)
239247
errorMessages.Add($"Unknown target platform: {platform}. Defaulting to {options.Platform}");
240248
}
241249

242-
static void GetDestinationArchitecture(string architecture, List<string> errorMessages)
250+
public static void GetDestinationArchitecture(string architecture, List<string> errorMessages)
243251
{
244252
switch (architecture.ToLower())
245253
{
@@ -257,7 +265,8 @@ static void GetDestinationArchitecture(string architecture, List<string> errorMe
257265
return;
258266
}
259267

260-
errorMessages.Add($"Unknown target architecture: {architecture}. Defaulting to {options.Architecture}");
268+
errorMessages.Add($@"Unknown target architecture: {architecture}. \
269+
Defaulting to {options.Architecture}");
261270
}
262271

263272
static void PrintErrorMessages(List<string> errorMessages)
@@ -275,10 +284,18 @@ static void Main(string[] args)
275284
{
276285
PrintErrorMessages(errorMessages);
277286

278-
// Don't need to show the help since if ParseCommandLineArgs returns false the help has already been shown
287+
// Don't need to show the help since if ParseCommandLineArgs returns false
288+
// since the help has already been shown
279289
return;
280290
}
281291

292+
var luaContext = new LuaContext(options, errorMessages);
293+
foreach (var luaFile in options.LuaBindingsFiles)
294+
{
295+
Directory.SetCurrentDirectory(Path.GetDirectoryName(luaFile));
296+
luaContext.LoadFile(luaFile);
297+
}
298+
282299
var gen = new Generator(options);
283300

284301
var validOptions = gen.ValidateOptions(errorMessages);

src/CLI/CppSharp.CLI.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55

66
<ItemGroup>
77
<ProjectReference Include="..\Generator\CppSharp.Generator.csproj" />
8+
<PackageReference Include="MoonSharp" />
89
</ItemGroup>
910
</Project>

src/CLI/Generator.cs

+18-13
Original file line numberDiff line numberDiff line change
@@ -91,29 +91,34 @@ public bool ValidateOptions(List<string> messages)
9191
options.OutputDir = Path.Combine(Directory.GetCurrentDirectory(), "gen");
9292
}
9393

94-
string moduleName;
95-
if (options.HeaderFiles.Count == 1)
96-
{
97-
moduleName = Path.GetFileNameWithoutExtension(options.HeaderFiles.First());
98-
}
99-
else
100-
{
101-
var dir = Path.GetDirectoryName(options.HeaderFiles.First());
102-
moduleName = new DirectoryInfo(dir).Name;
103-
}
104-
10594
if (string.IsNullOrEmpty(options.OutputFileName))
106-
options.OutputFileName = moduleName;
95+
options.OutputFileName = GetModuleNameFromHeaderFiles();
10796

10897
if (string.IsNullOrEmpty(options.OutputNamespace))
109-
options.OutputNamespace = moduleName;
98+
options.OutputNamespace = GetModuleNameFromHeaderFiles();
11099

111100
if (options.IncludeDirs.Count == 0)
112101
options.IncludeDirs.Add(Path.GetDirectoryName(options.HeaderFiles.First()));
113102

114103
SetupTargetTriple();
115104

116105
return true;
106+
107+
string GetModuleNameFromHeaderFiles()
108+
{
109+
string moduleName;
110+
if (options.HeaderFiles.Count == 1)
111+
{
112+
moduleName = Path.GetFileNameWithoutExtension(options.HeaderFiles.First());
113+
}
114+
else
115+
{
116+
var dir = Path.GetDirectoryName(options.HeaderFiles.First());
117+
moduleName = new DirectoryInfo(dir).Name;
118+
}
119+
120+
return moduleName;
121+
}
117122
}
118123

119124
public void Setup(Driver driver)

src/CLI/LuaContext.cs

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using CppSharp;
5+
using MoonSharp.Interpreter;
6+
7+
class LuaContext
8+
{
9+
public Script script;
10+
public Options options;
11+
public List<string> errorMessages;
12+
13+
public string CurrentModule;
14+
15+
public LuaContext(Options options, List<string> errorMessages)
16+
{
17+
this.options = options;
18+
this.errorMessages = errorMessages;
19+
20+
script = new Script(CoreModules.Basic | CoreModules.String |
21+
CoreModules.Table | CoreModules.TableIterators);
22+
23+
script.Globals["generator"] = (string kind) =>
24+
{
25+
CLI.GetGeneratorKind(kind, errorMessages);
26+
};
27+
28+
script.Globals["platform"] = (string platform) =>
29+
{
30+
CLI.GetDestinationPlatform(platform, errorMessages);
31+
};
32+
33+
script.Globals["architecture"] = (string arch) =>
34+
{
35+
CLI.GetDestinationArchitecture(arch, errorMessages);
36+
};
37+
38+
script.Globals["output"] = script.Globals["location"] = (string dir) =>
39+
{
40+
options.OutputDir = dir;
41+
};
42+
43+
script.Globals["includedirs"] = (List<string> dirs) =>
44+
{
45+
foreach (var dir in dirs)
46+
{
47+
options.IncludeDirs.Add(dir);
48+
}
49+
};
50+
51+
script.Globals["module"] = (string name) =>
52+
{
53+
CurrentModule = name;
54+
options.OutputFileName = name;
55+
};
56+
57+
script.Globals["namespace"] = (string name) =>
58+
{
59+
options.OutputNamespace = name;
60+
};
61+
62+
script.Globals["headers"] = (List<string> files) =>
63+
{
64+
foreach (var file in files)
65+
{
66+
options.HeaderFiles.Add(file);
67+
}
68+
};
69+
}
70+
71+
public DynValue LoadFile(string luaFile)
72+
{
73+
var code = script.LoadFile(luaFile);
74+
75+
try
76+
{
77+
return code.Function.Call();
78+
}
79+
catch (Exception ex)
80+
{
81+
Console.Error.WriteLine($"Error running {Path.GetFileName(luaFile)}:\n{ex.Message}");
82+
return null;
83+
}
84+
}
85+
}

src/CLI/Options.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ enum TargetArchitecture
1313

1414
class Options
1515
{
16+
public List<string> LuaBindingsFiles { get; } = new List<string>();
17+
1618
public List<string> HeaderFiles { get; } = new List<string>();
1719

1820
public List<string> IncludeDirs { get; } = new List<string>();
@@ -37,7 +39,7 @@ class Options
3739

3840
public TargetPlatform? Platform { get; set; }
3941

40-
public TargetArchitecture Architecture { get; set; } = TargetArchitecture.x86;
42+
public TargetArchitecture Architecture { get; set; } = TargetArchitecture.x64;
4143

4244
public GeneratorKind Kind { get; set; } = GeneratorKind.CSharp;
4345

src/Generator/Extensions/PrimitiveTypeExtensions.cs

+6-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ public static (uint Width, uint Alignment) GetInfo(this PrimitiveType primitive,
3434

3535
switch (primitive)
3636
{
37+
case PrimitiveType.Void:
38+
case PrimitiveType.Null:
39+
case PrimitiveType.String:
40+
return (0, 0);
41+
3742
case PrimitiveType.Bool:
3843
return (targetInfo.BoolWidth, targetInfo.BoolAlign);
3944

@@ -97,7 +102,7 @@ public static (uint Width, uint Alignment) GetInfo(this PrimitiveType primitive,
97102
return (targetInfo.PointerWidth, targetInfo.PointerAlign);
98103

99104
default:
100-
throw new NotImplementedException();
105+
throw new Exception($"Not implemented for {primitive}");
101106
}
102107
}
103108
}

src/Generator/GeneratorKind.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public bool IsCLIOptionMatch(string cliOption)
5959
{
6060
return false;
6161
}
62-
return CLIOptions.Any(cliOption.Contains);
62+
return CLIOptions.Any(option => option == cliOption);
6363
}
6464

6565
public static bool operator ==(GeneratorKind obj1, GeneratorKind obj2)
@@ -134,7 +134,7 @@ public override string ToString()
134134
public static readonly GeneratorKind Swift = new(Swift_ID, "Swift", typeof(NotImplementedGenerator), typeof(NotImplementedTypePrinter));
135135

136136
public const string QuickJS_ID = "QuickJS";
137-
public static readonly GeneratorKind QuickJS = new(QuickJS_ID, "QuickJS", typeof(QuickJSGenerator), typeof(QuickJSTypePrinter), new[] { "qjs" });
137+
public static readonly GeneratorKind QuickJS = new(QuickJS_ID, "QuickJS", typeof(QuickJSGenerator), typeof(QuickJSTypePrinter), new[] { "quickjs", "qjs" });
138138

139139
public const string NAPI_ID = "NAPI";
140140
public static readonly GeneratorKind NAPI = new(NAPI_ID, "N-API", typeof(NAPIGenerator), typeof(NAPITypePrinter), new[] { "napi" });

src/Generator/Generators/QuickJS/QuickJSGenerator.cs

+13-3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@ public class QuickJSGenerator : CppGenerator
1212
{
1313
public QuickJSGenerator(BindingContext context) : base(context)
1414
{
15+
if (context.Options.GenerateName == null)
16+
{
17+
context.Options.GenerateName = (unit) =>
18+
{
19+
if (unit.FileName == "premake5.lua")
20+
return unit.FileNameWithoutExtension;
21+
else
22+
return $"{unit.Module.LibraryName}_JS_{unit.FileNameWithoutExtension}";
23+
};
24+
}
1525
}
1626

1727
public override List<GeneratorOutput> Generate()
@@ -45,8 +55,8 @@ public override List<CodeGenerator> Generate(IEnumerable<TranslationUnit> units)
4555
{
4656
var outputs = new List<CodeGenerator>();
4757

48-
var header = new QuickJSHeaders(Context, units);
49-
outputs.Add(header);
58+
// var header = new QuickJSHeaders(Context, units);
59+
// outputs.Add(header);
5060

5161
var source = new QuickJSSources(Context, units);
5262
outputs.Add(source);
@@ -65,7 +75,7 @@ public override GeneratorOutput GenerateModule(Module module)
6575
{
6676
TranslationUnit = new TranslationUnit
6777
{
68-
FilePath = $"{module.LibraryName}_qjs_module.cpp",
78+
FilePath = $"QJSModule.cpp",
6979
Module = module
7080
},
7181
Outputs = new List<CodeGenerator> { moduleGen }

0 commit comments

Comments
 (0)