Skip to content

Commit dc185a6

Browse files
committed
Add initial QuickJS generator.
1 parent 6c0c461 commit dc185a6

File tree

15 files changed

+1229
-1
lines changed

15 files changed

+1229
-1
lines changed

examples/QuickJS/build.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
set -ex
2+
mono ../../build/vs2015/lib/Debug_x64/CppSharp.CLI.exe -gen=qjs -module=test -prefix=js_ test-native.h
3+
../../build/premake5-osx --file=premake5.lua gmake
4+
make clean
5+
make
6+
7+
cp gen/bin/release/libtest.dylib .
8+
../../deps/QuickJS/qjs test.js

examples/QuickJS/premake5.lua

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
qjs_inc_dir = path.getabsolute("../../deps/QuickJS")
2+
qjs_lib_dir = path.getabsolute("../../deps/QuickJS")
3+
4+
workspace "qjs"
5+
configurations { "release" }
6+
7+
project "test-native"
8+
kind "StaticLib"
9+
files { "*-native.cpp" }
10+
11+
include "gen/js_premake5.lua"
12+
13+
project "test"
14+
includedirs { "." }
15+
links { "test-native" }

examples/QuickJS/test-native.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#include "test-native.h"
2+
3+
extern "C" int plus(int a, int b)
4+
{
5+
return a + b;
6+
}

examples/QuickJS/test-native.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
extern "C" int plus(int a, int b);

examples/QuickJS/test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import { plus } from './libtest.dylib'
2+
console.log(plus(1, 2))

src/CLI/CLI.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,9 @@ static void GetGeneratorKind(string generator, List<string> errorMessages)
219219
case "cpp":
220220
options.Kind = CppSharp.Generators.GeneratorKind.CPlusPlus;
221221
return;
222+
case "qjs":
223+
options.Kind = CppSharp.Generators.GeneratorKind.QuickJS;
224+
return;
222225
}
223226

224227
errorMessages.Add($"Unknown generator kind: {generator}. Defaulting to {options.Kind}");

src/Generator/Driver.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ Generator CreateGeneratorFromKind(GeneratorKind kind)
4545
return new CLIGenerator(Context);
4646
case GeneratorKind.CSharp:
4747
return new CSharpGenerator(Context);
48+
case GeneratorKind.QuickJS:
49+
return new QuickJSGenerator(Context);
4850
}
4951

5052
throw new NotImplementedException();

src/Generator/Generator.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ public enum GeneratorKind
1616
CPlusPlus,
1717
ObjectiveC,
1818
Java,
19-
Swift
19+
Swift,
20+
QuickJS
2021
}
2122

2223
/// <summary>
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
using System.Collections.Generic;
2+
using CppSharp.AST;
3+
using CppSharp.Generators.Cpp;
4+
5+
namespace CppSharp.Generators.C
6+
{
7+
/// <summary>
8+
/// QuickJS generator responsible for driving the generation of binding files.
9+
/// QuickJS documentation: https://bellard.org/quickjs/
10+
/// </summary>
11+
public class QuickJSGenerator : CppGenerator
12+
{
13+
public QuickJSGenerator(BindingContext context) : base(context)
14+
{
15+
}
16+
17+
public override List<GeneratorOutput> Generate()
18+
{
19+
var outputs = base.Generate();
20+
21+
foreach (var module in Context.Options.Modules)
22+
{
23+
if (module == Context.Options.SystemModule)
24+
continue;
25+
26+
var output = GenerateModule(module);
27+
if (output != null)
28+
{
29+
OnUnitGenerated(output);
30+
outputs.Add(output);
31+
}
32+
33+
var premake = GeneratePremake(module);
34+
if (premake != null)
35+
{
36+
OnUnitGenerated(premake);
37+
outputs.Add(premake);
38+
}
39+
}
40+
41+
return outputs;
42+
}
43+
44+
public override List<CodeGenerator> Generate(IEnumerable<TranslationUnit> units)
45+
{
46+
var outputs = new List<CodeGenerator>();
47+
48+
var header = new QuickJSHeaders(Context, units);
49+
outputs.Add(header);
50+
51+
var source = new QuickJSSources(Context, units);
52+
outputs.Add(source);
53+
54+
return outputs;
55+
}
56+
57+
public override GeneratorOutput GenerateModule(Module module)
58+
{
59+
if (module == Context.Options.SystemModule)
60+
return null;
61+
62+
var moduleGen = new QuickJSModule(Context, module);
63+
64+
var output = new GeneratorOutput
65+
{
66+
TranslationUnit = new TranslationUnit
67+
{
68+
FilePath = $"{module.LibraryName}_qjs_module.cpp",
69+
Module = module
70+
},
71+
Outputs = new List<CodeGenerator> { moduleGen }
72+
};
73+
74+
output.Outputs[0].Process();
75+
76+
return output;
77+
}
78+
79+
public GeneratorOutput GeneratePremake(Module module)
80+
{
81+
if (module == Context.Options.SystemModule)
82+
return null;
83+
84+
var premakeGen = new QuickJSPremakeBuildGenerator(Context, module);
85+
86+
var output = new GeneratorOutput
87+
{
88+
TranslationUnit = new TranslationUnit
89+
{
90+
FilePath = "premake5.lua",
91+
Module = module
92+
},
93+
Outputs = new List<CodeGenerator> { premakeGen }
94+
};
95+
96+
output.Outputs[0].Process();
97+
98+
return output;
99+
}
100+
}
101+
102+
class QuickJSPremakeBuildGenerator : CodeGenerator
103+
{
104+
readonly Module module;
105+
106+
public QuickJSPremakeBuildGenerator(BindingContext context, Module module)
107+
: base(context, (TranslationUnit)null)
108+
{
109+
this.module = module;
110+
}
111+
112+
public override string FileExtension => "lua";
113+
114+
public override void Process()
115+
{
116+
/*
117+
var qjsPath = @"/Users/joao/Dev/CppSharp/examples/wxSharp/QuickJS";
118+
WriteLine($"qjs_inc_dir = \"{qjsPath}\"");
119+
WriteLine($"qjs_lib_dir = \"{qjsPath}\"");
120+
121+
WriteLine("workspace \"qjs\"");
122+
WriteLineIndent("configurations { \"release\" }");
123+
*/
124+
125+
WriteLine($"project \"{module.LibraryName}\"");
126+
Indent();
127+
128+
WriteLine("kind \"SharedLib\"");
129+
WriteLine("language \"C++\"");
130+
WriteLine("files { \"*.cpp\" }");
131+
WriteLine("includedirs { qjs_inc_dir }");
132+
WriteLine("libdirs { qjs_lib_dir }");
133+
WriteLine("filter { \"kind:StaticLib\" }");
134+
WriteLineIndent("links { \"quickjs\" }");
135+
WriteLine("filter { \"kind:SharedLib\" }");
136+
WriteLineIndent("defines { \"JS_SHARED_LIBRARY\" }");
137+
WriteLine("filter { \"kind:SharedLib\", \"system:macosx\" }");
138+
WriteLineIndent("linkoptions { \"-undefined dynamic_lookup\" }");
139+
140+
Unindent();
141+
}
142+
}
143+
144+
/* TODO: Write a build.sh aswell.
145+
* set -ex
146+
../../../../../build/premake5-osx gmake
147+
make clean
148+
make
149+
*/
150+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using System.Collections.Generic;
2+
using CppSharp.AST;
3+
using CppSharp.Generators.C;
4+
5+
namespace CppSharp.Generators.Cpp
6+
{
7+
/// <summary>
8+
/// Generates QuickJS C/C++ header files.
9+
/// QuickJS documentation: https://bellard.org/quickjs/
10+
/// </summary>
11+
public class QuickJSHeaders : CppHeaders
12+
{
13+
public QuickJSHeaders(BindingContext context, IEnumerable<TranslationUnit> units)
14+
: base(context, units)
15+
{
16+
CTypePrinter.PushContext(TypePrinterContextKind.Managed);
17+
}
18+
19+
public override bool ShouldGenerateNamespaces => false;
20+
21+
public override void Process()
22+
{
23+
GenerateFilePreamble(CommentKind.BCPL);
24+
25+
PushBlock(BlockKind.Includes);
26+
WriteLine("#pragma once");
27+
NewLine();
28+
29+
var include = new CInclude()
30+
{
31+
File = "quickjs.h",
32+
Kind = CInclude.IncludeKind.Angled
33+
};
34+
35+
WriteInclude(include);
36+
NewLine();
37+
PopBlock();
38+
39+
VisitNamespace(TranslationUnit);
40+
}
41+
42+
public override bool VisitFunctionDecl(Function function)
43+
{
44+
Write("extern \"C\" ");
45+
WriteLine($"JSValue js_{function.Name}(JSContext* ctx, JSValueConst this_val,");
46+
WriteLineIndent("int argc, JSValueConst* argv);");
47+
48+
return true;
49+
}
50+
}
51+
}

0 commit comments

Comments
 (0)