Skip to content

Commit 060e2f5

Browse files
authored
Add support for Interop generation (#57)
1 parent 9ab251b commit 060e2f5

File tree

11 files changed

+644
-121
lines changed

11 files changed

+644
-121
lines changed

source/MetadataProcessor.Console/Program.cs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -127,25 +127,20 @@ public void GenerateSkeleton(
127127
string file,
128128
string name,
129129
string project,
130-
bool withoutInteropCode)
130+
bool withoutInteropCode,
131+
bool isCoreLibrary)
131132
{
132133
try
133134
{
134-
if (!withoutInteropCode)
135-
{
136-
System.Console.Error.WriteLine("Generator for Interop stubs is not supported yet.");
137-
138-
Environment.Exit(1);
139-
}
140-
141135
if (Verbose) System.Console.WriteLine("Generating skeleton files...");
142136

143137
var skeletonGenerator = new nanoSkeletonGenerator(
144138
_assemblyBuilder.TablesContext,
145139
file,
146140
name,
147141
project,
148-
withoutInteropCode);
142+
withoutInteropCode,
143+
isCoreLibrary);
149144

150145
skeletonGenerator.GenerateSkeleton();
151146
}
@@ -185,6 +180,8 @@ public static void Main(string[] args)
185180
{
186181
FileVersionInfo fileVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location);
187182

183+
bool isCoreLibrary = false;
184+
188185
// output header to console
189186
System.Console.WriteLine($"nanoFramework MetadataProcessor Utility v{fileVersion.ToString()}");
190187
System.Console.WriteLine("Copyright (c) 2019 nanoFramework project contributors");
@@ -222,8 +219,6 @@ public static void Main(string[] args)
222219
}
223220
else if (arg == "-compile" && i + 2 < args.Length)
224221
{
225-
bool isCoreLibrary = false;
226-
227222
if (!bool.TryParse(args[i + 2], out isCoreLibrary))
228223
{
229224
System.Console.Error.WriteLine("Bad parameter for compile. IsCoreLib options has to be 'true' or 'false'.");
@@ -273,7 +268,8 @@ public static void Main(string[] args)
273268
file,
274269
name,
275270
project,
276-
withoutInteropCode);
271+
withoutInteropCode,
272+
isCoreLibrary);
277273

278274
i += 4;
279275
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//
2+
// Copyright (c) 2019 The nanoFramework project contributors
3+
// See LICENSE file in the project root for full license information.
4+
//
5+
6+
using Mono.Cecil;
7+
using System.Text;
8+
using System.Linq;
9+
10+
namespace nanoFramework.Tools.MetadataProcessor.Core.Extensions
11+
{
12+
internal static class ParameterDefintionExtensions
13+
{
14+
public static string TypeToString(this ParameterDefinition parameter)
15+
{
16+
if(parameter.ParameterType is ByReferenceType byReference)
17+
{
18+
// pointer to native type
19+
return " *" + byReference.TypeSignatureAsString();
20+
}
21+
else if (parameter.ParameterType is ArrayType arrayType)
22+
{
23+
return "CLR_RT_TypedArray_" + arrayType.ElementType.TypeSignatureAsString();
24+
}
25+
else if (parameter.ParameterType.IsValueType)
26+
{
27+
return parameter.ParameterType.Resolve().TypeSignatureAsString();
28+
}
29+
else
30+
{
31+
return parameter.ParameterType.TypeSignatureAsString();
32+
}
33+
}
34+
}
35+
}

source/MetadataProcessor.Core/Extensions/TypeReferenceExtensions.cs

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//
55

66
using Mono.Cecil;
7+
using System.Text;
78

89
namespace nanoFramework.Tools.MetadataProcessor.Core.Extensions
910
{
@@ -13,5 +14,218 @@ public static bool IsToInclude(this TypeReference value)
1314
{
1415
return !nanoTablesContext.IgnoringAttributes.Contains(value.FullName);
1516
}
17+
18+
public static string TypeSignatureAsString(this TypeReference type)
19+
{
20+
if (type.MetadataType == MetadataType.IntPtr)
21+
{
22+
return "I";
23+
}
24+
25+
if (type.MetadataType == MetadataType.UIntPtr)
26+
{
27+
return "U";
28+
}
29+
30+
nanoCLR_DataType dataType;
31+
if (nanoSignaturesTable.PrimitiveTypes.TryGetValue(type.FullName, out dataType))
32+
{
33+
switch (dataType)
34+
{
35+
case nanoCLR_DataType.DATATYPE_VOID:
36+
case nanoCLR_DataType.DATATYPE_BOOLEAN:
37+
case nanoCLR_DataType.DATATYPE_CHAR:
38+
case nanoCLR_DataType.DATATYPE_I1:
39+
case nanoCLR_DataType.DATATYPE_U1:
40+
case nanoCLR_DataType.DATATYPE_I2:
41+
case nanoCLR_DataType.DATATYPE_U2:
42+
case nanoCLR_DataType.DATATYPE_I4:
43+
case nanoCLR_DataType.DATATYPE_U4:
44+
case nanoCLR_DataType.DATATYPE_I8:
45+
case nanoCLR_DataType.DATATYPE_U8:
46+
case nanoCLR_DataType.DATATYPE_R4:
47+
case nanoCLR_DataType.DATATYPE_BYREF:
48+
case nanoCLR_DataType.DATATYPE_OBJECT:
49+
return dataType.ToString().Replace("DATATYPE_", "");
50+
51+
case nanoCLR_DataType.DATATYPE_LAST_PRIMITIVE:
52+
return "STRING";
53+
54+
case nanoCLR_DataType.DATATYPE_LAST_PRIMITIVE_TO_PRESERVE:
55+
return "R8";
56+
57+
case nanoCLR_DataType.DATATYPE_LAST_PRIMITIVE_TO_MARSHAL:
58+
return "TIMESPAN";
59+
60+
case nanoCLR_DataType.DATATYPE_REFLECTION:
61+
return type.FullName.Replace(".", "");
62+
}
63+
}
64+
65+
if (type.MetadataType == MetadataType.Class)
66+
{
67+
StringBuilder classSig = new StringBuilder("CLASS [");
68+
classSig.Append(type.MetadataToken.ToInt32().ToString("x8"));
69+
classSig.Append("]");
70+
71+
return classSig.ToString();
72+
}
73+
74+
if (type.MetadataType == MetadataType.ValueType)
75+
{
76+
StringBuilder valueTypeSig = new StringBuilder("VALUETYPE [");
77+
valueTypeSig.Append(type.MetadataToken.ToInt32().ToString("x8"));
78+
valueTypeSig.Append("]");
79+
80+
return valueTypeSig.ToString();
81+
}
82+
83+
if (type.IsArray)
84+
{
85+
StringBuilder arraySig = new StringBuilder("SZARRAY ");
86+
arraySig.Append(type.GetElementType().TypeSignatureAsString());
87+
88+
return arraySig.ToString();
89+
}
90+
91+
return "";
92+
}
93+
94+
public static string ToNativeTypeAsString(this TypeReference type)
95+
{
96+
nanoCLR_DataType dataType;
97+
if (nanoSignaturesTable.PrimitiveTypes.TryGetValue(type.FullName, out dataType))
98+
{
99+
switch (dataType)
100+
{
101+
case nanoCLR_DataType.DATATYPE_VOID:
102+
return "void";
103+
case nanoCLR_DataType.DATATYPE_BOOLEAN:
104+
return "bool";
105+
case nanoCLR_DataType.DATATYPE_CHAR:
106+
return "char";
107+
case nanoCLR_DataType.DATATYPE_I1:
108+
return "int8_t";
109+
case nanoCLR_DataType.DATATYPE_U1:
110+
return "uint8_t";
111+
case nanoCLR_DataType.DATATYPE_I2:
112+
return "int16_t";
113+
case nanoCLR_DataType.DATATYPE_U2:
114+
return "uint16_t";
115+
case nanoCLR_DataType.DATATYPE_I4:
116+
return "int32_t";
117+
case nanoCLR_DataType.DATATYPE_U4:
118+
return "uint32_t";
119+
case nanoCLR_DataType.DATATYPE_I8:
120+
return "int64_t";
121+
case nanoCLR_DataType.DATATYPE_U8:
122+
return "uint64_t";
123+
case nanoCLR_DataType.DATATYPE_R4:
124+
return "float";
125+
case nanoCLR_DataType.DATATYPE_BYREF:
126+
return "";
127+
128+
// system.String
129+
case nanoCLR_DataType.DATATYPE_LAST_PRIMITIVE:
130+
return "const char*";
131+
132+
// System.Double
133+
case nanoCLR_DataType.DATATYPE_LAST_PRIMITIVE_TO_PRESERVE:
134+
return "double";
135+
136+
default:
137+
return "UNSUPPORTED";
138+
}
139+
}
140+
141+
if (type.MetadataType == MetadataType.Class)
142+
{
143+
return "UNSUPPORTED";
144+
}
145+
146+
if (type.MetadataType == MetadataType.ValueType)
147+
{
148+
return "UNSUPPORTED";
149+
}
150+
151+
if (type.IsArray)
152+
{
153+
StringBuilder arraySig = new StringBuilder("CLR_RT_TypedArray_");
154+
arraySig.Append(type.GetElementType().ToCLRTypeAsString());
155+
156+
return arraySig.ToString();
157+
}
158+
159+
return "";
160+
}
161+
162+
public static string ToCLRTypeAsString(this TypeReference type)
163+
{
164+
nanoCLR_DataType dataType;
165+
if (nanoSignaturesTable.PrimitiveTypes.TryGetValue(type.FullName, out dataType))
166+
{
167+
switch (dataType)
168+
{
169+
case nanoCLR_DataType.DATATYPE_VOID:
170+
return "void";
171+
case nanoCLR_DataType.DATATYPE_BOOLEAN:
172+
return "bool";
173+
case nanoCLR_DataType.DATATYPE_CHAR:
174+
return "CHAR";
175+
case nanoCLR_DataType.DATATYPE_I1:
176+
return "INT8";
177+
case nanoCLR_DataType.DATATYPE_U1:
178+
return "UINT8";
179+
case nanoCLR_DataType.DATATYPE_I2:
180+
return "INT16";
181+
case nanoCLR_DataType.DATATYPE_U2:
182+
return "UINT16";
183+
case nanoCLR_DataType.DATATYPE_I4:
184+
return "INT32";
185+
case nanoCLR_DataType.DATATYPE_U4:
186+
return "UINT32";
187+
case nanoCLR_DataType.DATATYPE_I8:
188+
return "INT64";
189+
case nanoCLR_DataType.DATATYPE_U8:
190+
return "UINT64";
191+
case nanoCLR_DataType.DATATYPE_R4:
192+
return "float";
193+
case nanoCLR_DataType.DATATYPE_BYREF:
194+
return "NONE";
195+
196+
// system.String
197+
case nanoCLR_DataType.DATATYPE_LAST_PRIMITIVE:
198+
return "LPCSTR";
199+
200+
// System.Double
201+
case nanoCLR_DataType.DATATYPE_LAST_PRIMITIVE_TO_PRESERVE:
202+
return "double";
203+
204+
default:
205+
return "UNSUPPORTED";
206+
}
207+
}
208+
209+
if (type.MetadataType == MetadataType.Class)
210+
{
211+
return "UNSUPPORTED";
212+
}
213+
214+
if (type.MetadataType == MetadataType.ValueType)
215+
{
216+
return "UNSUPPORTED";
217+
}
218+
219+
if (type.IsArray)
220+
{
221+
StringBuilder arraySig = new StringBuilder();
222+
arraySig.Append(type.GetElementType().ToCLRTypeAsString());
223+
arraySig.Append("_ARRAY");
224+
225+
return arraySig.ToString();
226+
}
227+
228+
return "";
229+
}
16230
}
17231
}

source/MetadataProcessor.Core/MetadataProcessor.Core.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
<Compile Include="DumpGenerator\DumpAllTable.cs" />
7878
<Compile Include="DumpGenerator\DumpTemplates.cs" />
7979
<Compile Include="Endianness\nanoBinaryWriter.cs" />
80+
<Compile Include="Extensions\ParameterDefintionExtensions.cs" />
8081
<Compile Include="Extensions\ByteArrayExtensions.cs" />
8182
<Compile Include="Extensions\TypeReferenceExtensions.cs" />
8283
<Compile Include="Extensions\TypeDefinitionExtensions.cs" />

source/MetadataProcessor.Core/SkeletonGenerator/AssemblyClass.cs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,20 @@ public class AssemblyDeclaration
1313
public string ShortName;
1414
public string ShortNameUpper;
1515

16+
public bool IsCoreLib = false;
17+
1618
public List<Class> Classes = new List<Class>();
1719
}
1820

1921
public class Class
2022
{
2123
public string Name;
2224
public string AssemblyName;
25+
public string ShortNameUpper;
2326

2427
public List<StaticField> StaticFields = new List<StaticField>();
2528
public List<InstanceField> InstanceFields = new List<InstanceField>();
26-
public List<Method> Methods = new List<Method>();
29+
public List<MethodStub> Methods = new List<MethodStub>();
2730
}
2831

2932
public class StaticField
@@ -40,8 +43,25 @@ public class InstanceField
4043
public string FieldWarning;
4144
}
4245

43-
public class Method
46+
public class MethodStub
47+
{
48+
public string Declaration;
49+
public string DeclarationForUserCode;
50+
public string CallFromMarshalling;
51+
public string ReturnType;
52+
public string MarshallingReturnType;
53+
public bool HasReturnType;
54+
public bool IsStatic = false;
55+
56+
public List<ParameterDeclaration> ParameterDeclaration = new List<ParameterDeclaration>();
57+
}
58+
59+
public class ParameterDeclaration
4460
{
61+
public string Index;
62+
public string Type;
63+
public string Name;
64+
public string MarshallingDeclaration;
4565
public string Declaration;
4666
}
4767
}

source/MetadataProcessor.Core/SkeletonGenerator/AssemblyClassStubs.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@ public class AssemblyClassStubs
1111
{
1212
public string HeaderFileName;
1313

14-
public List<Method> Functions = new List<Method>();
14+
public string ClassHeaderFileName;
15+
16+
public string ClassName;
17+
18+
public string ShortNameUpper;
19+
20+
public string RootNamespace;
21+
22+
public string ProjectName;
23+
24+
public List<MethodStub> Functions = new List<MethodStub>();
1525
}
1626
}

0 commit comments

Comments
 (0)