Skip to content

Commit e6053d3

Browse files
committed
Update API.
1 parent 2bd3704 commit e6053d3

File tree

4 files changed

+89
-161
lines changed

4 files changed

+89
-161
lines changed

Binaryen.NET.Tests/ModuleTests.cs

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,7 @@ public void AddFunction_ShouldAppearInWAT()
2828
using var module = new BinaryenModule();
2929

3030
var body = BinaryenExpression.Nop(module);
31-
module.AddFunction(
32-
name: "myFunc",
33-
paramTypes: new[] { BinaryenType.Int32 },
34-
resultType: BinaryenType.Int32,
35-
localTypes: Array.Empty<BinaryenType>(),
36-
body: body);
31+
module.AddFunction("myFunc", body);
3732

3833
string wat = module.ToText();
3934
Assert.Contains("(func $myFunc", wat);
@@ -46,12 +41,7 @@ public void AddFunctionExport_ShouldAppearInWAT()
4641

4742
// Add a dummy function first so it can be exported
4843
var body = BinaryenExpression.Nop(module);
49-
module.AddFunction(
50-
name: "internalFunc",
51-
paramTypes: new[] { BinaryenType.None },
52-
resultType: BinaryenType.None,
53-
localTypes: Array.Empty<BinaryenType>(),
54-
body: body);
44+
module.AddFunction("internalFunc", body);
5545

5646
module.AddFunctionExport("internalFunc", "externalFunc");
5747
string wat = module.ToText();
@@ -61,26 +51,6 @@ public void AddFunctionExport_ShouldAppearInWAT()
6151
Assert.Contains("(func $internalFunc", wat);
6252
}
6353

64-
[Fact]
65-
public void AddFunctionImport_ShouldAppearInWAT()
66-
{
67-
using var module = new BinaryenModule();
68-
var paramTypes = new[] { BinaryenType.None };
69-
var resultType = BinaryenType.Int32;
70-
71-
module.AddFunctionImport(
72-
internalName: "myFunc",
73-
externalModuleName: "env",
74-
externalBaseName: "myFunc",
75-
paramTypes: paramTypes,
76-
resultType: resultType);
77-
78-
string wat = module.ToText();
79-
Assert.False(string.IsNullOrEmpty(wat));
80-
Assert.Contains("(import \"env\" \"myFunc\"", wat);
81-
Assert.Contains("(func $myFunc", wat);
82-
}
83-
8454
[Fact]
8555
public void ToText_ShouldReturnNonEmptyString()
8656
{

Binaryen.NET/BinaryenExpression.cs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public static BinaryenExpression Drop(BinaryenModule module, BinaryenExpression
3838

3939
public static BinaryenExpression LocalGet(BinaryenModule module, uint index, BinaryenType type)
4040
{
41-
var handle = BinaryenLocalGet(module.Handle, index, type.Handle);
41+
var handle = BinaryenLocalGet(module.Handle, index, (nint)type.Handle);
4242
return new BinaryenExpression(handle);
4343
}
4444

@@ -53,16 +53,4 @@ public static BinaryenExpression Nop(BinaryenModule module)
5353
var handle = BinaryenNop(module.Handle);
5454
return new BinaryenExpression(handle);
5555
}
56-
57-
public static BinaryenExpression Combine(params BinaryenExpression[] values)
58-
{
59-
if (values == null || values.Length == 0)
60-
return null;
61-
62-
IntPtr combined = values[0].Handle;
63-
for (int i = 1; i < values.Length; i++)
64-
combined |= values[i].Handle; // Combine bitmask
65-
66-
return new BinaryenExpression(combined);
67-
}
6856
}

Binaryen.NET/BinaryenModule.cs

Lines changed: 43 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
using System.Runtime.InteropServices;
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Runtime.InteropServices;
25

36
namespace Binaryen.NET;
47

@@ -28,102 +31,78 @@ public class BinaryenModule : IDisposable
2831

2932
[DllImport(Interop.CPPDLL, CallingConvention = CallingConvention.Cdecl)]
3033
private extern static void BinaryenAddFunctionImport(
31-
IntPtr module,
32-
string internalName,
33-
string externalModuleName,
34-
string externalBaseName,
35-
IntPtr paramTypes,
36-
IntPtr resultTypes);
34+
IntPtr module,
35+
string internalName,
36+
string externalModuleName,
37+
string externalBaseName,
38+
UIntPtr paramTypes,
39+
UIntPtr resultTypes);
3740

3841
[DllImport(Interop.CPPDLL, CallingConvention = CallingConvention.Cdecl)]
3942
private extern static IntPtr BinaryenAddFunction(
40-
IntPtr module,
41-
string name,
42-
IntPtr paramTypes,
43-
IntPtr resultTypes,
44-
IntPtr[] varTypes,
45-
uint numVarTypes,
46-
IntPtr body);
43+
IntPtr module,
44+
string name,
45+
UIntPtr paramTypes,
46+
UIntPtr resultTypes,
47+
UIntPtr[] varTypes,
48+
uint numVarTypes,
49+
IntPtr body);
4750
#endregion
4851

49-
/// <summary> Pointer to the native class. </summary>
50-
internal IntPtr Handle { get; set; }
52+
internal IntPtr Handle { get; private set; }
5153
private bool _disposed;
5254

53-
/// <summary> Creates a new instance of <see cref="BinaryenModule"/>. </summary>
5455
public BinaryenModule() => Handle = BinaryenModuleCreate();
55-
56-
/// <summary> Creates a new instance of <see cref="BinaryenModule"/> from the given pointer. </summary>
5756
internal BinaryenModule(IntPtr handle) => Handle = handle;
58-
59-
/// <summary> Finalizer. </summary>
6057
~BinaryenModule() => Dispose();
6158

62-
/// <summary>
63-
/// Creates a new instance of <see cref="BinaryenModule"/> from the given WAT string.
64-
/// </summary>
65-
/// <param name="wat"> The WAT string. </param>
6659
public static BinaryenModule Parse(string wat) => new BinaryenModule(BinaryenModuleParse(wat));
6760

68-
/// <summary> Adds a function export to the module. </summary>
69-
public void AddFunctionExport(string internalName, string externalName) => BinaryenAddFunctionExport(Handle, internalName, externalName);
61+
public void AddFunctionExport(string internalName, string externalName) =>
62+
BinaryenAddFunctionExport(Handle, internalName, externalName);
7063

71-
/// <summary> Adds a function import to the module. </summary>
7264
public void AddFunctionImport(
7365
string internalName,
7466
string externalModuleName,
7567
string externalBaseName,
76-
IEnumerable<BinaryenType> paramTypes,
77-
BinaryenType resultType)
68+
IEnumerable<BinaryenType>? paramTypes = null,
69+
BinaryenType? resultType = null)
7870
{
79-
// No types specified, use default types
80-
if (paramTypes.Count() == 0)
81-
paramTypes = new BinaryenType[] { BinaryenType.None };
71+
paramTypes ??= new[] { BinaryenType.None };
72+
resultType ??= BinaryenType.None;
8273

83-
IntPtr paramTypesHandle = BinaryenType.Combine(paramTypes.ToArray()).Handle;
74+
// Use BinaryenType.Create to combine multiple param types
75+
UIntPtr combinedParams = BinaryenType.Create(paramTypes.ToArray()).Handle;
76+
UIntPtr combinedResult = resultType.Handle;
8477

8578
BinaryenAddFunctionImport(
8679
Handle,
8780
internalName,
8881
externalModuleName,
8982
externalBaseName,
90-
paramTypesHandle,
91-
resultType.Handle);
83+
combinedParams,
84+
combinedResult);
9285
}
9386

94-
/// <summary> Adds a function to the module. </summary>
9587
public IntPtr AddFunction(
9688
string name,
97-
IEnumerable<BinaryenType> paramTypes,
98-
BinaryenType resultType,
99-
IEnumerable<BinaryenType> localTypes,
100-
BinaryenExpression body)
89+
BinaryenExpression body,
90+
IEnumerable<BinaryenType>? paramTypes = null,
91+
BinaryenType? resultType = null,
92+
IEnumerable<BinaryenType>? localTypes = null)
10193
{
102-
if (paramTypes.Count() == 0)
103-
paramTypes = new[] { BinaryenType.None };
104-
if (resultType == null)
105-
resultType = BinaryenType.None;
106-
107-
IntPtr paramHandle = BinaryenType.Combine(paramTypes.ToArray()).Handle;
108-
IntPtr resultHandle = resultType.Handle;
94+
paramTypes ??= Array.Empty<BinaryenType>();
95+
resultType ??= BinaryenType.None;
96+
localTypes ??= Array.Empty<BinaryenType>();
10997

110-
// locals must be passed as raw array of IntPtr
111-
IntPtr[] localHandles = localTypes.Select(t => t.Handle).ToArray();
112-
uint numLocals = (uint)localHandles.Length;
98+
UIntPtr combinedParams = BinaryenType.Create(paramTypes.ToArray()).Handle;
99+
UIntPtr combinedResult = resultType.Handle;
100+
UIntPtr[] locals = localTypes.Select(t => t.Handle).ToArray();
101+
uint numLocals = (uint)locals.Length;
113102

114-
return BinaryenAddFunction(
115-
Handle,
116-
name,
117-
paramHandle,
118-
resultHandle,
119-
localHandles,
120-
numLocals,
121-
body.Handle);
103+
return BinaryenAddFunction(Handle, name, combinedParams, combinedResult, locals, numLocals, body.Handle);
122104
}
123105

124-
125-
126-
/// <summary> Converts the module to a Web Assembly Text (WAT) string. </summary>
127106
public string ToText()
128107
{
129108
if (Handle == IntPtr.Zero)
@@ -135,21 +114,15 @@ public string ToText()
135114
byte[] buffer = new byte[bufferSize];
136115
UIntPtr written = BinaryenModuleWriteText(Handle, buffer, (UIntPtr)buffer.Length);
137116

138-
// If the module fits in the buffer, return the string
139117
if ((int)written < bufferSize)
140118
return System.Text.Encoding.UTF8.GetString(buffer, 0, (int)written);
141119

142-
// Otherwise, double the buffer size and try again
143120
bufferSize *= 2;
144-
145-
// Prevent excessively large allocations
146-
if (bufferSize > 16 * 1024 * 1024) // 16 MB
121+
if (bufferSize > 16 * 1024 * 1024)
147122
throw new InvalidOperationException("Module is too large to serialize to WAT.");
148123
}
149124
}
150125

151-
152-
/// <summary> Converts the module to a Web Assembly (WASM) byte array. </summary>
153126
public byte[] ToBinary()
154127
{
155128
if (Handle == IntPtr.Zero)
@@ -161,19 +134,15 @@ public byte[] ToBinary()
161134
byte[] buffer = new byte[bufferSize];
162135
UIntPtr written = BinaryenModuleWrite(Handle, buffer, (UIntPtr)buffer.Length);
163136

164-
// If the module fits in the buffer, return the bytes
165137
if ((int)written < bufferSize)
166138
{
167139
byte[] result = new byte[(int)written];
168140
Array.Copy(buffer, result, (int)written);
169141
return result;
170142
}
171143

172-
// Otherwise, double the buffer size and try again
173144
bufferSize *= 2;
174-
175-
// Prevent excessively large allocations
176-
if (bufferSize > 16 * 1024 * 1024) // 16 MB
145+
if (bufferSize > 16 * 1024 * 1024)
177146
throw new InvalidOperationException("Module is too large to serialize to binary.");
178147
}
179148
}

Binaryen.NET/BinaryenType.cs

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,59 @@
1-

1+
using System;
2+
using System.Linq;
23
using System.Runtime.InteropServices;
34

4-
namespace Binaryen.NET;
5-
6-
/// <summary>
7-
/// A Binaryen type.
8-
/// </summary>
9-
public class BinaryenType
5+
namespace Binaryen.NET
106
{
11-
#region Native
12-
[DllImport(Interop.CPPDLL, CallingConvention = CallingConvention.Cdecl)]
13-
private extern static IntPtr BinaryenTypeNone();
7+
/// <summary>
8+
/// A Binaryen type.
9+
/// </summary>
10+
public class BinaryenType
11+
{
12+
#region Native
13+
[DllImport(Interop.CPPDLL, CallingConvention = CallingConvention.Cdecl)]
14+
private static extern UIntPtr BinaryenTypeCreate([In] UIntPtr[] valueTypes, uint numTypes);
1415

15-
[DllImport(Interop.CPPDLL, CallingConvention = CallingConvention.Cdecl)]
16-
private extern static IntPtr BinaryenTypeInt32();
16+
[DllImport(Interop.CPPDLL, CallingConvention = CallingConvention.Cdecl)]
17+
private static extern UIntPtr BinaryenTypeNone();
1718

18-
[DllImport(Interop.CPPDLL, CallingConvention = CallingConvention.Cdecl)]
19-
private extern static IntPtr BinaryenTypeInt64();
19+
[DllImport(Interop.CPPDLL, CallingConvention = CallingConvention.Cdecl)]
20+
private static extern UIntPtr BinaryenTypeInt32();
2021

21-
[DllImport(Interop.CPPDLL, CallingConvention = CallingConvention.Cdecl)]
22-
private extern static IntPtr BinaryenTypeFloat32();
22+
[DllImport(Interop.CPPDLL, CallingConvention = CallingConvention.Cdecl)]
23+
private static extern UIntPtr BinaryenTypeInt64();
2324

24-
[DllImport(Interop.CPPDLL, CallingConvention = CallingConvention.Cdecl)]
25-
private extern static IntPtr BinaryenTypeFloat64();
25+
[DllImport(Interop.CPPDLL, CallingConvention = CallingConvention.Cdecl)]
26+
private static extern UIntPtr BinaryenTypeFloat32();
2627

27-
[DllImport(Interop.CPPDLL, CallingConvention = CallingConvention.Cdecl)]
28-
private extern static IntPtr BinaryenTypeVec128();
29-
#endregion
28+
[DllImport(Interop.CPPDLL, CallingConvention = CallingConvention.Cdecl)]
29+
private static extern UIntPtr BinaryenTypeFloat64();
3030

31-
/// <summary> Pointer to the native class. </summary>
32-
internal IntPtr Handle { get; }
31+
[DllImport(Interop.CPPDLL, CallingConvention = CallingConvention.Cdecl)]
32+
private static extern UIntPtr BinaryenTypeVec128();
33+
#endregion
3334

34-
/// <summary> Creates a new instance of <see cref="BinaryenType"/>. </summary>
35-
internal BinaryenType(IntPtr handle) => Handle = handle;
35+
/// <summary> The underlying numeric representation of the type. </summary>
36+
internal UIntPtr Handle { get; }
3637

37-
public static BinaryenType None { get; } = new BinaryenType(BinaryenTypeNone());
38-
public static BinaryenType Int32 { get; } = new BinaryenType(BinaryenTypeInt32());
39-
public static BinaryenType Int64 { get; } = new BinaryenType(BinaryenTypeInt64());
40-
public static BinaryenType Float32 { get; } = new BinaryenType(BinaryenTypeFloat32());
41-
public static BinaryenType Float64 { get; } = new BinaryenType(BinaryenTypeFloat64());
42-
public static BinaryenType Vec128 { get; } = new BinaryenType(BinaryenTypeVec128());
38+
/// <summary> Creates a new instance of <see cref="BinaryenType"/> from a native handle. </summary>
39+
internal BinaryenType(UIntPtr handle) => Handle = handle;
4340

44-
/// <summary>
45-
/// Combines multiple <see cref="BinaryenType"/> into one.
46-
/// </summary>
47-
public static BinaryenType Combine(params BinaryenType[] types)
48-
{
49-
if (types == null || types.Length == 0)
50-
return None;
41+
/// <summary> Creates a BinaryenType representing multiple types. </summary>
42+
internal static BinaryenType Create(params BinaryenType[] types)
43+
{
44+
if (types == null || types.Length == 0)
45+
return None;
5146

52-
IntPtr combined = types[0].Handle;
53-
for (int i = 1; i < types.Length; i++)
54-
combined |= types[i].Handle; // Combine bitmask
47+
UIntPtr[] nativeTypes = types.Select(t => t.Handle).ToArray();
48+
UIntPtr combined = BinaryenTypeCreate(nativeTypes, (uint)nativeTypes.Length);
49+
return new BinaryenType(combined);
50+
}
5551

56-
return new BinaryenType(combined);
52+
public static BinaryenType None { get; } = new BinaryenType(BinaryenTypeNone());
53+
public static BinaryenType Int32 { get; } = new BinaryenType(BinaryenTypeInt32());
54+
public static BinaryenType Int64 { get; } = new BinaryenType(BinaryenTypeInt64());
55+
public static BinaryenType Float32 { get; } = new BinaryenType(BinaryenTypeFloat32());
56+
public static BinaryenType Float64 { get; } = new BinaryenType(BinaryenTypeFloat64());
57+
public static BinaryenType Vec128 { get; } = new BinaryenType(BinaryenTypeVec128());
5758
}
5859
}

0 commit comments

Comments
 (0)