Skip to content

Commit 943ade7

Browse files
committed
Follow-Up: Adjust the API to match the new C API introduced with bytecodealliance/wasmtime#3153, in order to support 64-bit memory.
This also fixes the definition of native functions wasmtime_memory_size and wasmtime_memory_grow, which previously incorrectly used a UInt32 instead of UInt64, and config functions taking a bool parameter, which were previously missing the MarshalAsAttribute (to marshal a Boolean as 1 byte instead of 4 bytes).
1 parent d7c468b commit 943ade7

12 files changed

Lines changed: 139 additions & 70 deletions

src/Config.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -373,46 +373,46 @@ private static class Native
373373
public static extern void wasm_config_delete(IntPtr config);
374374

375375
[DllImport(Engine.LibraryName)]
376-
public static extern void wasmtime_config_debug_info_set(Handle config, bool enable);
376+
public static extern void wasmtime_config_debug_info_set(Handle config, [MarshalAs(UnmanagedType.I1)] bool enable);
377377

378378
[DllImport(Engine.LibraryName)]
379-
public static extern void wasmtime_config_epoch_interruption_set(Handle config, bool enable);
379+
public static extern void wasmtime_config_epoch_interruption_set(Handle config, [MarshalAs(UnmanagedType.I1)] bool enable);
380380

381381
[DllImport(Engine.LibraryName)]
382-
public static extern void wasmtime_config_consume_fuel_set(Handle config, bool enable);
382+
public static extern void wasmtime_config_consume_fuel_set(Handle config, [MarshalAs(UnmanagedType.I1)] bool enable);
383383

384384
[DllImport(Engine.LibraryName)]
385-
public static extern void wasmtime_config_max_wasm_stack_set(Handle config, UIntPtr size);
385+
public static extern void wasmtime_config_max_wasm_stack_set(Handle config, nuint size);
386386

387387
[DllImport(Engine.LibraryName)]
388-
public static extern void wasmtime_config_wasm_threads_set(Handle config, bool enable);
388+
public static extern void wasmtime_config_wasm_threads_set(Handle config, [MarshalAs(UnmanagedType.I1)] bool enable);
389389

390390
[DllImport(Engine.LibraryName)]
391-
public static extern void wasmtime_config_wasm_reference_types_set(Handle config, bool enable);
391+
public static extern void wasmtime_config_wasm_reference_types_set(Handle config, [MarshalAs(UnmanagedType.I1)] bool enable);
392392

393393
[DllImport(Engine.LibraryName)]
394-
public static extern void wasmtime_config_wasm_simd_set(Handle config, bool enable);
394+
public static extern void wasmtime_config_wasm_simd_set(Handle config, [MarshalAs(UnmanagedType.I1)] bool enable);
395395

396396
[DllImport(Engine.LibraryName)]
397-
public static extern void wasmtime_config_wasm_bulk_memory_set(Handle config, bool enable);
397+
public static extern void wasmtime_config_wasm_bulk_memory_set(Handle config, [MarshalAs(UnmanagedType.I1)] bool enable);
398398

399399
[DllImport(Engine.LibraryName)]
400-
public static extern void wasmtime_config_wasm_multi_value_set(Handle config, bool enable);
400+
public static extern void wasmtime_config_wasm_multi_value_set(Handle config, [MarshalAs(UnmanagedType.I1)] bool enable);
401401

402402
[DllImport(Engine.LibraryName)]
403-
public static extern void wasmtime_config_wasm_multi_memory_set(Handle config, bool enable);
403+
public static extern void wasmtime_config_wasm_multi_memory_set(Handle config, [MarshalAs(UnmanagedType.I1)] bool enable);
404404

405405
[DllImport(Engine.LibraryName)]
406-
public static extern void wasmtime_config_wasm_memory64_set(Handle config, bool enable);
406+
public static extern void wasmtime_config_wasm_memory64_set(Handle config, [MarshalAs(UnmanagedType.I1)] bool enable);
407407

408408
[DllImport(Engine.LibraryName)]
409409
public static extern void wasmtime_config_strategy_set(Handle config, byte strategy);
410410

411411
[DllImport(Engine.LibraryName)]
412-
public static extern void wasmtime_config_cranelift_debug_verifier_set(Handle config, bool enable);
412+
public static extern void wasmtime_config_cranelift_debug_verifier_set(Handle config, [MarshalAs(UnmanagedType.I1)] bool enable);
413413

414414
[DllImport(Engine.LibraryName)]
415-
public static extern void wasmtime_config_cranelift_nan_canonicalization_set(Handle config, bool enable);
415+
public static extern void wasmtime_config_cranelift_nan_canonicalization_set(Handle config, [MarshalAs(UnmanagedType.I1)] bool enable);
416416

417417
[DllImport(Engine.LibraryName)]
418418
public static extern void wasmtime_config_cranelift_opt_level_set(Handle config, byte level);

src/Export.cs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -192,21 +192,35 @@ internal MemoryExport(IntPtr exportType, IntPtr externType) : base(exportType)
192192

193193
unsafe
194194
{
195-
var limits = Memory.Native.wasm_memorytype_limits(type);
196-
Minimum = limits->min;
197-
Maximum = limits->max;
195+
Minimum = (long)Memory.Native.wasmtime_memorytype_minimum(type);
196+
197+
bool hasMax = Memory.Native.wasmtime_memorytype_maximum(type, out ulong max);
198+
if (hasMax)
199+
{
200+
Maximum = (long)max;
201+
}
202+
203+
Is64Bit = Memory.Native.wasmtime_memorytype_is64(type);
198204
}
199205
}
200206

201207
/// <summary>
202-
/// The minimum memory size (in WebAssembly page units).
208+
/// Gets the minimum memory size (in WebAssembly page units).
203209
/// </summary>
204-
public uint Minimum { get; private set; }
210+
/// <value>The minimum memory size (in WebAssembly page units).</value>
211+
public long Minimum { get; }
205212

206213
/// <summary>
207-
/// The maximum memory size (in WebAssembly page units).
214+
/// Gets the maximum memory size (in WebAssembly page units).
208215
/// </summary>
209-
public uint Maximum { get; private set; }
216+
/// <value>The maximum memory size (in WebAssembly page units), or <c>null</c> if no maximum is specified.</value>
217+
public long? Maximum { get; }
218+
219+
/// <summary>
220+
/// Gets a value that indicates whether this type of memory represents a 64-bit memory.
221+
/// </summary>
222+
/// <value><c>true</c> if this type of memory represents a 64-bit memory, <c>false</c> if it represents a 32-bit memory.</value>
223+
public bool Is64Bit { get; }
210224

211225
private static class Native
212226
{

src/Import.cs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -205,21 +205,35 @@ internal MemoryImport(IntPtr importType, IntPtr externType) : base(importType)
205205

206206
unsafe
207207
{
208-
var limits = Memory.Native.wasm_memorytype_limits(type);
209-
Minimum = limits->min;
210-
Maximum = limits->max;
208+
Minimum = (long)Memory.Native.wasmtime_memorytype_minimum(type);
209+
210+
bool hasMax = Memory.Native.wasmtime_memorytype_maximum(type, out ulong max);
211+
if (hasMax)
212+
{
213+
Maximum = (long)max;
214+
}
215+
216+
Is64Bit = Memory.Native.wasmtime_memorytype_is64(type);
211217
}
212218
}
213219

214220
/// <summary>
215-
/// The minimum memory size (in WebAssembly page units).
221+
/// Gets the minimum memory size (in WebAssembly page units).
216222
/// </summary>
217-
public uint Minimum { get; private set; }
223+
/// <value>The minimum memory size (in WebAssembly page units).</value>
224+
public long Minimum { get; }
218225

219226
/// <summary>
220-
/// The maximum memory size (in WebAssembly page units).
227+
/// Gets the maximum memory size (in WebAssembly page units).
221228
/// </summary>
222-
public uint Maximum { get; private set; }
229+
/// <value>The maximum memory size (in WebAssembly page units), or <c>null</c> if no maximum is specified.</value>
230+
public long? Maximum { get; }
231+
232+
/// <summary>
233+
/// Gets a value that indicates whether this type of memory represents a 64-bit memory.
234+
/// </summary>
235+
/// <value><c>true</c> if this type of memory represents a 64-bit memory, <c>false</c> if it represents a 32-bit memory.</value>
236+
public bool Is64Bit { get; }
223237

224238
private static class Native
225239
{

src/Memory.cs

Lines changed: 50 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ public class Memory : IExternal
1616
/// </summary>
1717
/// <param name="store">The store to create the memory in.</param>
1818
/// <param name="minimum">The minimum number of WebAssembly pages.</param>
19-
/// <param name="maximum">The maximum number of WebAssembly pages.</param>
20-
public Memory(IStore store, uint minimum = 0, uint maximum = uint.MaxValue)
19+
/// <param name="maximum">The maximum number of WebAssembly pages, or <c>null</c> to not specify a maximum.</param>
20+
/// <param name="is64Bit"><c>true</c> when memory type represents a 64-bit memory, <c>false</c> when it represents a 32-bit memory.</param>
21+
public Memory(IStore store, long minimum = 0, long? maximum = null, bool is64Bit = false)
2122
{
2223
if (store is null)
2324
{
@@ -32,14 +33,12 @@ public Memory(IStore store, uint minimum = 0, uint maximum = uint.MaxValue)
3233
this.store = store;
3334
Minimum = minimum;
3435
Maximum = maximum;
36+
Is64Bit = is64Bit;
3537

3638
unsafe
3739
{
38-
var limits = new Native.Limits();
39-
limits.min = minimum;
40-
limits.max = maximum;
40+
using var type = new TypeHandle(Native.wasmtime_memorytype_new((ulong)minimum, maximum is not null, (ulong)(maximum ?? 0), is64Bit));
4141

42-
using var type = new TypeHandle(Native.wasm_memorytype_new(limits));
4342
var error = Native.wasmtime_memory_new(store.Context.handle, type, out this.memory);
4443
if (error != IntPtr.Zero)
4544
{
@@ -54,22 +53,30 @@ public Memory(IStore store, uint minimum = 0, uint maximum = uint.MaxValue)
5453
public const int PageSize = 65536;
5554

5655
/// <summary>
57-
/// The minimum memory size (in WebAssembly page units).
56+
/// Gets the minimum memory size (in WebAssembly page units).
5857
/// </summary>
59-
public uint Minimum { get; private set; }
58+
/// <value>The minimum memory size (in WebAssembly page units).</value>
59+
public long Minimum { get; }
6060

6161
/// <summary>
62-
/// The maximum memory size (in WebAssembly page units).
62+
/// Gets the maximum memory size (in WebAssembly page units).
6363
/// </summary>
64-
public uint Maximum { get; private set; }
64+
/// <value>The maximum memory size (in WebAssembly page units), or <c>null</c> if no maximum is specified.</value>
65+
public long? Maximum { get; }
66+
67+
/// <summary>
68+
/// Gets a value that indicates whether this type of memory represents a 64-bit memory.
69+
/// </summary>
70+
/// <value><c>true</c> if this type of memory represents a 64-bit memory, <c>false</c> otherwise.</value>
71+
public bool Is64Bit { get; }
6572

6673
/// <summary>
6774
/// Gets the current size of the memory, in WebAssembly page units.
6875
/// </summary>
6976
/// <returns>Returns the current size of the memory, in WebAssembly page units.</returns>
70-
public uint GetSize()
77+
public long GetSize()
7178
{
72-
return Native.wasmtime_memory_size(store.Context.handle, this.memory);
79+
return (long)Native.wasmtime_memory_size(store.Context.handle, this.memory);
7380
}
7481

7582
/// <summary>
@@ -78,7 +85,7 @@ public uint GetSize()
7885
/// <returns>Returns the current length of the memory, in bytes.</returns>
7986
public long GetLength()
8087
{
81-
return checked((long)(nuint)Native.wasmtime_memory_data_size(store.Context.handle, this.memory));
88+
return checked((long)Native.wasmtime_memory_data_size(store.Context.handle, this.memory));
8289
}
8390

8491
/// <summary>
@@ -485,20 +492,25 @@ public void WriteDouble(long address, double value)
485492
/// <param name="delta">The number of WebAssembly pages to grow the memory by.</param>
486493
/// <returns>Returns the previous size of the Webassembly memory, in pages.</returns>
487494
/// <remarks>This method will invalidate previously returned values from `GetSpan`.</remarks>
488-
public uint Grow(uint delta)
495+
public long Grow(long delta)
489496
{
490497
if (store is null)
491498
{
492499
throw new ArgumentNullException(nameof(store));
493500
}
494501

495-
var error = Native.wasmtime_memory_grow(store.Context.handle, this.memory, delta, out var prev);
502+
if (delta < 0)
503+
{
504+
throw new ArgumentOutOfRangeException(nameof(delta));
505+
}
506+
507+
var error = Native.wasmtime_memory_grow(store.Context.handle, this.memory, (ulong)delta, out var prev);
496508
if (error != IntPtr.Zero)
497509
{
498510
throw WasmtimeException.FromOwnedError(error);
499511
}
500512

501-
return prev;
513+
return (long)prev;
502514
}
503515

504516
Extern IExternal.AsExtern()
@@ -518,9 +530,15 @@ internal Memory(IStore store, ExternMemory memory)
518530

519531
unsafe
520532
{
521-
var limits = Native.wasm_memorytype_limits(type.DangerousGetHandle());
522-
Minimum = limits->min;
523-
Maximum = limits->max;
533+
Minimum = (long)Native.wasmtime_memorytype_minimum(type.DangerousGetHandle());
534+
535+
bool hasMax = Native.wasmtime_memorytype_maximum(type.DangerousGetHandle(), out ulong max);
536+
if (hasMax)
537+
{
538+
Maximum = (long)max;
539+
}
540+
541+
Is64Bit = Native.wasmtime_memorytype_is64(type.DangerousGetHandle());
524542
}
525543
}
526544

@@ -541,37 +559,37 @@ protected override bool ReleaseHandle()
541559

542560
internal static class Native
543561
{
544-
[StructLayout(LayoutKind.Sequential)]
545-
internal struct Limits
546-
{
547-
public uint min;
548-
549-
public uint max;
550-
}
551-
552562
[DllImport(Engine.LibraryName)]
553563
public static extern IntPtr wasmtime_memory_new(IntPtr context, TypeHandle type, out ExternMemory memory);
554564

555565
[DllImport(Engine.LibraryName)]
556566
public static unsafe extern byte* wasmtime_memory_data(IntPtr context, in ExternMemory memory);
557567

558568
[DllImport(Engine.LibraryName)]
559-
public static extern UIntPtr wasmtime_memory_data_size(IntPtr context, in ExternMemory memory);
569+
public static extern nuint wasmtime_memory_data_size(IntPtr context, in ExternMemory memory);
560570

561571
[DllImport(Engine.LibraryName)]
562-
public static extern uint wasmtime_memory_size(IntPtr context, in ExternMemory memory);
572+
public static extern ulong wasmtime_memory_size(IntPtr context, in ExternMemory memory);
563573

564574
[DllImport(Engine.LibraryName)]
565-
public static extern IntPtr wasmtime_memory_grow(IntPtr context, in ExternMemory memory, uint delta, out uint prev);
575+
public static extern IntPtr wasmtime_memory_grow(IntPtr context, in ExternMemory memory, ulong delta, out ulong prev);
566576

567577
[DllImport(Engine.LibraryName)]
568578
public static extern IntPtr wasmtime_memory_type(IntPtr context, in ExternMemory memory);
569579

570580
[DllImport(Engine.LibraryName)]
571-
public static extern IntPtr wasm_memorytype_new(in Limits limits);
581+
public static extern IntPtr wasmtime_memorytype_new(ulong min, [MarshalAs(UnmanagedType.I1)] bool max_present, ulong max, [MarshalAs(UnmanagedType.I1)] bool is_64);
582+
583+
[DllImport(Engine.LibraryName)]
584+
public static unsafe extern ulong wasmtime_memorytype_minimum(IntPtr type);
585+
586+
[DllImport(Engine.LibraryName)]
587+
[return: MarshalAs(UnmanagedType.I1)]
588+
public static unsafe extern bool wasmtime_memorytype_maximum(IntPtr type, out ulong max);
572589

573590
[DllImport(Engine.LibraryName)]
574-
public static unsafe extern Limits* wasm_memorytype_limits(IntPtr type);
591+
[return: MarshalAs(UnmanagedType.I1)]
592+
public static unsafe extern bool wasmtime_memorytype_is64(IntPtr type);
575593

576594
[DllImport(Engine.LibraryName)]
577595
public static extern void wasm_memorytype_delete(IntPtr handle);

tests/Memory64AccessTests.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,18 @@ public Memory64AccessTests(Memory64AccessFixture fixture)
2828
[Fact]
2929
public unsafe void ItCanAccessMemoryWith65537Pages()
3030
{
31+
var memoryExport = Fixture.Module.Exports.OfType<MemoryExport>().Single();
32+
memoryExport.Minimum.Should().Be(0x10001);
33+
memoryExport.Maximum.Should().Be(0x1000000000000);
34+
memoryExport.Is64Bit.Should().Be(true);
35+
3136
var instance = Linker.Instantiate(Store, Fixture.Module);
3237
var memory = instance.GetMemory("mem");
3338

39+
memory.Minimum.Should().Be(0x10001);
40+
memory.Maximum.Should().Be(0x1000000000000);
41+
memory.Is64Bit.Should().Be(true);
42+
memory.GetSize().Should().Be(0x10001);
3443
memory.GetLength().Should().Be(0x100010000);
3544

3645
memory.ReadInt32(0).Should().Be(0);

tests/MemoryAccessTests.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,18 @@ public MemoryAccessTests(MemoryAccessFixture fixture)
2828
[Fact]
2929
public unsafe void ItCanAccessMemoryWith65536Pages()
3030
{
31+
var memoryExport = Fixture.Module.Exports.OfType<MemoryExport>().Single();
32+
memoryExport.Minimum.Should().Be(0x10000);
33+
memoryExport.Maximum.Should().Be(null);
34+
memoryExport.Is64Bit.Should().Be(false);
35+
3136
var instance = Linker.Instantiate(Store, Fixture.Module);
3237
var memory = instance.GetMemory("mem");
3338

39+
memory.Minimum.Should().Be(0x10000);
40+
memory.Maximum.Should().Be(null);
41+
memory.Is64Bit.Should().Be(false);
42+
memory.GetSize().Should().Be(0x10000);
3443
memory.GetLength().Should().Be(0x100000000);
3544

3645
memory.ReadInt32(0).Should().Be(0);

tests/MemoryExportsTests.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,13 @@ public MemoryExportsTests(MemoryExportsFixture fixture)
2929

3030
[Theory]
3131
[MemberData(nameof(GetMemoryExports))]
32-
public void ItHasTheExpectedMemoryExports(string exportName, uint expectedMinimum, uint expectedMaximum)
32+
public void ItHasTheExpectedMemoryExports(string exportName, long expectedMinimum, long? expectedMaximum, bool is64Bit)
3333
{
3434
var export = Fixture.Module.Exports.Where(m => m.Name == exportName).FirstOrDefault() as MemoryExport;
3535
export.Should().NotBeNull();
3636
export.Minimum.Should().Be(expectedMinimum);
3737
export.Maximum.Should().Be(expectedMaximum);
38+
export.Is64Bit.Should().Be(is64Bit);
3839
}
3940

4041
[Fact]
@@ -109,8 +110,9 @@ public static IEnumerable<object[]> GetMemoryExports()
109110
{
110111
yield return new object[] {
111112
"mem",
112-
1,
113-
2
113+
1L,
114+
2L,
115+
false
114116
};
115117
}
116118

tests/MemoryImportFromModuleTests.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ public void ItHasTheExpectedImport()
2828
memory.Should().NotBeNull();
2929
memory.ModuleName.Should().Be("js");
3030
memory.Name.Should().Be("mem");
31-
memory.Minimum.Should().Be(1);
32-
memory.Maximum.Should().Be(2);
31+
memory.Minimum.Should().Be(1L);
32+
memory.Maximum.Should().Be(2L);
33+
memory.Is64Bit.Should().BeFalse();
3334
}
3435
}
3536
}

0 commit comments

Comments
 (0)