diff --git a/eng/pipelines/common/global-build-job.yml b/eng/pipelines/common/global-build-job.yml index 006806496984..a0537c64ce36 100644 --- a/eng/pipelines/common/global-build-job.yml +++ b/eng/pipelines/common/global-build-job.yml @@ -224,11 +224,13 @@ jobs: displayName: Install NodeJS - ${{ if and(eq(parameters.runtimeFlavor, 'coreclr'), eq(parameters.platform, 'wasi_wasm_win')) }}: - # Install Wasi Wasm dependencies: wasi-sdk, wasmer + # Install Wasi Wasm dependencies: wasi-sdk, wasmtime - script: call $(Build.SourcesDirectory)/eng/pipelines/runtimelab/install-wasi-sdk.cmd $(Build.SourcesDirectory)\wasm-tools displayName: Install wasi-sdk - script: pwsh $(Build.SourcesDirectory)/eng/pipelines/runtimelab/install-wasmtime.ps1 -CI -InstallDir $(Build.SourcesDirectory)/wasm-tools displayName: Install wasmtime + - script: pwsh $(Build.SourcesDirectory)/eng/pipelines/runtimelab/install-jco.ps1 $(Build.SourcesDirectory) + displayName: Install Jco - ${{ if or(eq(parameters.platform, 'browser_wasm_win'), and(eq(parameters.platform, 'wasi_wasm_win'), not(eq(parameters.runtimeFlavor, 'coreclr')))) }}: # Update machine certs diff --git a/eng/pipelines/runtimelab/install-jco.ps1 b/eng/pipelines/runtimelab/install-jco.ps1 new file mode 100644 index 000000000000..06d77575c83f --- /dev/null +++ b/eng/pipelines/runtimelab/install-jco.ps1 @@ -0,0 +1,9 @@ +$RootPath = $Args[0] + +$NpmExePath = $Env:NPM_EXECUTABLE + +Set-Location -Path $RootPath + +& $NpmExePath install @bytecodealliance/jco +& $NpmExePath install @bytecodealliance/preview2-shim + diff --git a/eng/pipelines/runtimelab/install-nodejs.ps1 b/eng/pipelines/runtimelab/install-nodejs.ps1 index 5dee2727f2d4..7d3d21d7ad48 100644 --- a/eng/pipelines/runtimelab/install-nodejs.ps1 +++ b/eng/pipelines/runtimelab/install-nodejs.ps1 @@ -51,11 +51,13 @@ if ($IsWindows) { Expand-Archive -LiteralPath "$InstallPath\$NodeJSZipName" -DestinationPath $InstallPath -Force $NodeJSExePath = "$InstallPath\$NodeJSInstallName\node.exe" + $NpmExePath = "$InstallPath\$NodeJSInstallName\npm.cmd" } else { tar xJf $InstallPath/$NodeJSZipName -C $InstallPath $NodeJSExePath = "$InstallPath/$NodeJSInstallName/bin/node" + $NpmExePath = "$InstallPath/$NodeJSInstallName/bin/npm" } if (!(Test-Path $NodeJSExePath)) @@ -64,5 +66,14 @@ if (!(Test-Path $NodeJSExePath)) exit 1 } +if (!(Test-Path $NpmExePath)) +{ + Write-Error "Did not find NPM at: '$NpmExePath'" + exit 1 +} + Write-Host Setting NODEJS_EXECUTABLE to $NodeJSExePath Write-Host "##vso[task.setvariable variable=NODEJS_EXECUTABLE]$NodeJSExePath" + +Write-Host Setting NPM_EXECUTABLE to $NpmExePath +Write-Host "##vso[task.setvariable variable=NPM_EXECUTABLE]$NpmExePath" diff --git a/eng/testing/FindWasmHostExecutable.sh b/eng/testing/FindWasmHostExecutable.sh new file mode 100644 index 000000000000..c831cda77610 --- /dev/null +++ b/eng/testing/FindWasmHostExecutable.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +exename=$(basename "$1" .dll) +dirname=$(dirname "$1") + +node="node --stack_trace_limit=100" +wasmtime="wasmtime run -S http" + +if [ -e "${dirname}/${exename}.js" ]; then + WASM_HOST_EXECUTABLE=$node + WASM_BINARY_TO_EXECUTE="${dirname}/${exename}.js" +elif [ -e "${dirname}/main.js" ]; then + WASM_HOST_EXECUTABLE=$node + WASM_BINARY_TO_EXECUTE="${dirname}/main.js" +elif [ -e "${dirname}/${exename}.mjs" ]; then + WASM_HOST_EXECUTABLE=$node + WASM_BINARY_TO_EXECUTE="${dirname}/${exename}.mjs" +elif [ -e "${dirname}/main.mjs" ]; then + WASM_HOST_EXECUTABLE=$node + WASM_BINARY_TO_EXECUTE="${dirname}/main.mjs" +elif [ -e "${dirname}/${exename}.wasm" ]; then + WASM_HOST_EXECUTABLE=$wasmtime + WASM_BINARY_TO_EXECUTE="${dirname}/${exename}.wasm" +fi diff --git a/eng/testing/FindWasmHostExecutableAndRun.sh b/eng/testing/FindWasmHostExecutableAndRun.sh new file mode 100755 index 000000000000..9b1bf6f90a2b --- /dev/null +++ b/eng/testing/FindWasmHostExecutableAndRun.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd) + +source $SCRIPT_DIR/FindWasmHostExecutable.sh "$1" + +if [ -n "${WASM_HOST_EXECUTABLE}" ]; then + echo $WASM_HOST_EXECUTABLE "$WASM_BINARY_TO_EXECUTE" "${@:2}" + $WASM_HOST_EXECUTABLE "$WASM_BINARY_TO_EXECUTE" "${@:2}" +else + exit 1 +fi diff --git a/src/coreclr/build-runtime.cmd b/src/coreclr/build-runtime.cmd index eac7903e1abf..bb679fe5e176 100644 --- a/src/coreclr/build-runtime.cmd +++ b/src/coreclr/build-runtime.cmd @@ -349,9 +349,11 @@ for /f "delims=" %%a in ("-%__RequestedBuildComponents%-") do ( set __CMakeTarget=!__CMakeTarget! nativeaot if "%__TargetArch%"=="wasm" ( - if not defined EMSDK ( - echo %__ErrMsgPrefix%%__MsgPrefix%Error: The EMSDK environment variable pointing to emsdk root must be set. - goto ExitWithError + if "%__TargetOS%"=="browser" ( + if not defined EMSDK ( + echo %__ErrMsgPrefix%%__MsgPrefix%Error: The EMSDK environment variable pointing to emsdk root must be set. + goto ExitWithError + ) ) ) ) diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index a88bd007482d..ec098003ede5 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -1262,8 +1262,12 @@ void DisplayNowayAssertMap() fout = _wfopen(strJitMeasureNowayAssertFile, W("a")); if (fout == nullptr) { +#if !defined(TARGET_WINDOWS) + // TODO: how do we print a `const char16_t*` portably? +#else fprintf(jitstdout(), "Failed to open JitMeasureNowayAssertFile \"%ws\"\n", strJitMeasureNowayAssertFile); +#endif return; } } @@ -1295,7 +1299,7 @@ void DisplayNowayAssertMap() for (i = 0; i < count; i++) { - fprintf(fout, "%u, %s, %u, \"%s\"\n", nacp[i].count, nacp[i].fl.m_file, nacp[i].fl.m_line, + fprintf(fout, "%u, %s, %u, \"%s\"\n", (unsigned int) nacp[i].count, nacp[i].fl.m_file, nacp[i].fl.m_line, nacp[i].fl.m_condStr); } @@ -3415,7 +3419,7 @@ void Compiler::compInitOptions(JitFlags* jitFlags) if (verbose) { printf("STRESS_NULL_OBJECT_CHECK: compMaxUncheckedOffsetForNullObject=0x%X\n", - compMaxUncheckedOffsetForNullObject); + (unsigned int) compMaxUncheckedOffsetForNullObject); } } @@ -9682,7 +9686,7 @@ void dumpConvertedVarSet(Compiler* comp, VARSET_VALARG_TP vars) { printf(" "); } - printf("V%02u", varNum); + printf("V%02u", (unsigned int) varNum); first = false; } } diff --git a/src/coreclr/jit/llvmlssa.cpp b/src/coreclr/jit/llvmlssa.cpp index 280bf0d2692c..03ccad3de501 100644 --- a/src/coreclr/jit/llvmlssa.cpp +++ b/src/coreclr/jit/llvmlssa.cpp @@ -1639,6 +1639,7 @@ class ShadowStackAllocator #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wformat-security" +#pragma clang diagnostic ignored "-Wdeprecated-declarations" #endif // __clang__ if (pBuffer == nullptr) { diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets index 7400c13fa252..021cdfc0362b 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets @@ -602,6 +602,7 @@ The .NET Foundation licenses this file to you under the MIT license. + diff --git a/src/coreclr/nativeaot/Runtime/Portable/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/Portable/CMakeLists.txt index 4eb224818192..342923738361 100644 --- a/src/coreclr/nativeaot/Runtime/Portable/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/Portable/CMakeLists.txt @@ -41,3 +41,10 @@ if (NOT CLR_CMAKE_TARGET_ARCH_WASM) install_static_library(standalonegc-enabled aotsdk nativeaot) endif() +if (CLR_CMAKE_TARGET_WASI) + install( + FILES ../../../../libraries/System.Net.Http/src/System/Net/Http/WasiHttpHandler/WasiHttpWorld_component_type.wit + DESTINATION aotsdk + COMPONENT nativeaot + ) +endif() diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs index 925df9892752..71fa429b4b55 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs +++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs @@ -163,8 +163,8 @@ internal PhysicalFilesWatcher CreateFileWatcher() FileSystemWatcher? watcher; #if NET - // For browser/iOS/tvOS we will proactively fallback to polling since FileSystemWatcher is not supported. - if (OperatingSystem.IsBrowser() || (OperatingSystem.IsIOS() && !OperatingSystem.IsMacCatalyst()) || OperatingSystem.IsTvOS()) + // For WASI/browser/iOS/tvOS we will proactively fallback to polling since FileSystemWatcher is not supported. + if (OperatingSystem.IsWasi() || OperatingSystem.IsBrowser() || (OperatingSystem.IsIOS() && !OperatingSystem.IsMacCatalyst()) || OperatingSystem.IsTvOS()) { UsePollingFileWatcher = true; UseActivePolling = true; diff --git a/src/libraries/System.Net.Http/src/System.Net.Http.csproj b/src/libraries/System.Net.Http/src/System.Net.Http.csproj index c6af468c2532..7dfbc43fc4a0 100644 --- a/src/libraries/System.Net.Http/src/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/src/System.Net.Http.csproj @@ -526,5 +526,4 @@ - diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/WasiHttpHandler/WasiHttpHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/WasiHttpHandler/WasiHttpHandler.cs index dcccb9899109..4963f18ec897 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/WasiHttpHandler/WasiHttpHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/WasiHttpHandler/WasiHttpHandler.cs @@ -471,7 +471,6 @@ private static Task RegisterWasiPollable(IPoll.Pollable pollable) GC.SuppressFinalize(pollable); return CallRegisterWasiPollableHandle((Thread)null!, handle); - } [UnsafeAccessor(UnsafeAccessorKind.StaticMethod, Name = "RegisterWasiPollableHandle")] diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index f266e5e6155e..f963a03c7743 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -2807,4 +2807,4 @@ - \ No newline at end of file + diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.Unix.cs index 359c889c975b..cd95eff22d9c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.Unix.cs @@ -33,6 +33,10 @@ internal static int PollWasiEventLoopUntilResolved(Task mainTask) return mainTask.Result; } + internal static void DispatchWasiEventLoop() + { + WasiEventLoop.DispatchWasiEventLoop(); + } #endif // the closest analog to Sleep(0) on Unix is sched_yield diff --git a/src/native/libs/CMakeLists.txt b/src/native/libs/CMakeLists.txt index b5578a8cc9b8..ba409bdeb2d3 100644 --- a/src/native/libs/CMakeLists.txt +++ b/src/native/libs/CMakeLists.txt @@ -36,6 +36,9 @@ if (CLR_CMAKE_TARGET_UNIX OR CLR_CMAKE_TARGET_BROWSER OR CLR_CMAKE_TARGET_WASI) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-pre-c11-compat") endif() + # TODO-LLVM: remove once upstream moves to WASI SDK 24 as well (or otherwise fixes these warnings). + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-switch-default") + add_compile_options(-I${CMAKE_CURRENT_SOURCE_DIR}/Common) add_compile_options(-I${CMAKE_CURRENT_BINARY_DIR}/Common) diff --git a/src/tests/Common/CLRTest.Execute.Bash.targets b/src/tests/Common/CLRTest.Execute.Bash.targets index 23205302d972..b15fe8a4edcf 100644 --- a/src/tests/Common/CLRTest.Execute.Bash.targets +++ b/src/tests/Common/CLRTest.Execute.Bash.targets @@ -341,7 +341,7 @@ fi "$CORE_ROOT/watchdog" $_WatcherTimeoutMins - /dev/null && pwd) + +source $SCRIPT_DIR/../../../../eng/testing/FindWasmHostExecutable.sh "$1/native/$2" + +if [ -n "${WASM_HOST_EXECUTABLE}" ]; then + echo $WASM_HOST_EXECUTABLE "$WASM_BINARY_TO_EXECUTE" "${@:3}" + $WASM_HOST_EXECUTABLE "$WASM_BINARY_TO_EXECUTE" "${@:3}" +else + chmod +x $1/native/$exename + $_DebuggerFullPath $1/native/$exename "${@:3}" +fi diff --git a/src/tests/nativeaot/SmokeTests/HelloWasm/HelloWasm.cs b/src/tests/nativeaot/SmokeTests/HelloWasm/HelloWasm.cs index b255b8d8f421..64d0d8898d96 100644 --- a/src/tests/nativeaot/SmokeTests/HelloWasm/HelloWasm.cs +++ b/src/tests/nativeaot/SmokeTests/HelloWasm/HelloWasm.cs @@ -46,7 +46,7 @@ private static unsafe int Main(string[] args) PrintLine("Hello from C#!"); int tempInt = 0; int tempInt2 = 0; - StartTest("Address/derefernce test"); + StartTest("Address/dereference test"); (*(&tempInt)) = 9; EndTest(tempInt == 9); diff --git a/src/tests/nativeaot/SmokeTests/SharedLibrary/.npmrc b/src/tests/nativeaot/SmokeTests/SharedLibrary/.npmrc new file mode 100644 index 000000000000..33312472ae5b --- /dev/null +++ b/src/tests/nativeaot/SmokeTests/SharedLibrary/.npmrc @@ -0,0 +1 @@ +registry=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/ \ No newline at end of file diff --git a/src/tests/nativeaot/SmokeTests/SharedLibrary/Library.cs b/src/tests/nativeaot/SmokeTests/SharedLibrary/Library.cs new file mode 100644 index 000000000000..6f7447039b20 --- /dev/null +++ b/src/tests/nativeaot/SmokeTests/SharedLibrary/Library.cs @@ -0,0 +1,176 @@ +// Generated by `wit-bindgen` 0.29.0. DO NOT EDIT! +// +#nullable enable +using System; +using System.Runtime.CompilerServices; +using System.Collections; +using System.Runtime.InteropServices; +using System.Text; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; + +namespace LibraryWorld { + + public interface ILibraryWorld { + static abstract void TestHttp(ushort port); + + static abstract int ReturnsPrimitiveInt(); + + static abstract bool ReturnsPrimitiveBool(); + + static abstract uint ReturnsPrimitiveChar(); + + static abstract void EnsureManagedClassLoaders(); + + static abstract int CheckSimpleExceptionHandling(); + + static abstract int CheckSimpleGcCollect(); + + } + + public readonly struct None {} + + [StructLayout(LayoutKind.Sequential)] + public readonly struct Result + { + public readonly byte Tag; + private readonly object value; + + private Result(byte tag, object value) + { + Tag = tag; + this.value = value; + } + + public static Result ok(Ok ok) + { + return new Result(OK, ok!); + } + + public static Result err(Err err) + { + return new Result(ERR, err!); + } + + public bool IsOk => Tag == OK; + public bool IsErr => Tag == ERR; + + public Ok AsOk + { + get + { + if (Tag == OK) + return (Ok)value; + else + throw new ArgumentException("expected OK, got " + Tag); + } + } + + public Err AsErr + { + get + { + if (Tag == ERR) + return (Err)value; + else + throw new ArgumentException("expected ERR, got " + Tag); + } + } + + public const byte OK = 0; + public const byte ERR = 1; + } + + namespace exports { + public static class LibraryWorld + { + + [UnmanagedCallersOnly(EntryPoint = "test-http")] + public static unsafe void wasmExportTestHttp(int p0) { + + LibraryWorldImpl.TestHttp((((ushort)p0))); + + } + + [UnmanagedCallersOnly(EntryPoint = "returns-primitive-int")] + public static unsafe int wasmExportReturnsPrimitiveInt() { + + int ret; + ret = LibraryWorldImpl.ReturnsPrimitiveInt(); + return ret; + + } + + [UnmanagedCallersOnly(EntryPoint = "cabi_post_returns-primitive-int")] + public static void cabi_post_wasmExportReturnsPrimitiveInt(int returnValue) { + Console.WriteLine("TODO: cabi_post_returns-primitive-int"); + } + + [UnmanagedCallersOnly(EntryPoint = "returns-primitive-bool")] + public static unsafe int wasmExportReturnsPrimitiveBool() { + + bool ret; + ret = LibraryWorldImpl.ReturnsPrimitiveBool(); + return (ret ? 1 : 0); + + } + + [UnmanagedCallersOnly(EntryPoint = "cabi_post_returns-primitive-bool")] + public static void cabi_post_wasmExportReturnsPrimitiveBool(int returnValue) { + Console.WriteLine("TODO: cabi_post_returns-primitive-bool"); + } + + [UnmanagedCallersOnly(EntryPoint = "returns-primitive-char")] + public static unsafe int wasmExportReturnsPrimitiveChar() { + + uint ret; + ret = LibraryWorldImpl.ReturnsPrimitiveChar(); + return ((int)ret); + + } + + [UnmanagedCallersOnly(EntryPoint = "cabi_post_returns-primitive-char")] + public static void cabi_post_wasmExportReturnsPrimitiveChar(int returnValue) { + Console.WriteLine("TODO: cabi_post_returns-primitive-char"); + } + + [UnmanagedCallersOnly(EntryPoint = "ensure-managed-class-loaders")] + public static unsafe void wasmExportEnsureManagedClassLoaders() { + + LibraryWorldImpl.EnsureManagedClassLoaders(); + + } + + [UnmanagedCallersOnly(EntryPoint = "check-simple-exception-handling")] + public static unsafe int wasmExportCheckSimpleExceptionHandling() { + + int ret; + ret = LibraryWorldImpl.CheckSimpleExceptionHandling(); + return ret; + + } + + [UnmanagedCallersOnly(EntryPoint = "cabi_post_check-simple-exception-handling")] + public static void cabi_post_wasmExportCheckSimpleExceptionHandling(int returnValue) { + Console.WriteLine("TODO: cabi_post_check-simple-exception-handling"); + } + + [UnmanagedCallersOnly(EntryPoint = "check-simple-gc-collect")] + public static unsafe int wasmExportCheckSimpleGcCollect() { + + int ret; + ret = LibraryWorldImpl.CheckSimpleGcCollect(); + return ret; + + } + + [UnmanagedCallersOnly(EntryPoint = "cabi_post_check-simple-gc-collect")] + public static void cabi_post_wasmExportCheckSimpleGcCollect(int returnValue) { + Console.WriteLine("TODO: cabi_post_check-simple-gc-collect"); + } + + } + } + +} diff --git a/src/tests/nativeaot/SmokeTests/SharedLibrary/LibraryWorld_component_type.wit b/src/tests/nativeaot/SmokeTests/SharedLibrary/LibraryWorld_component_type.wit new file mode 100644 index 000000000000..3dd01916452a --- /dev/null +++ b/src/tests/nativeaot/SmokeTests/SharedLibrary/LibraryWorld_component_type.wit @@ -0,0 +1,11 @@ +package local:local; + +world library { + export test-http: func(port: u16); + export returns-primitive-int: func() -> s32; + export returns-primitive-bool: func() -> bool; + export returns-primitive-char: func() -> char; + export ensure-managed-class-loaders: func(); + export check-simple-exception-handling: func() -> s32; + export check-simple-gc-collect: func() -> s32; +} diff --git a/src/tests/nativeaot/SmokeTests/SharedLibrary/SharedLibrary.cs b/src/tests/nativeaot/SmokeTests/SharedLibrary/SharedLibrary.cs index a6c2c7e74ec1..d501963c8c17 100644 --- a/src/tests/nativeaot/SmokeTests/SharedLibrary/SharedLibrary.cs +++ b/src/tests/nativeaot/SmokeTests/SharedLibrary/SharedLibrary.cs @@ -2,8 +2,15 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Net.Http.Headers; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; namespace SharedLibrary { @@ -36,6 +43,11 @@ public static void EnsureManagedClassLoaders() [UnmanagedCallersOnly(EntryPoint = "CheckSimpleExceptionHandling", CallConvs = new Type[] { typeof(CallConvStdcall) })] public static int CheckSimpleExceptionHandling() + { + return DoCheckSimpleExceptionHandling(); + } + + public static int DoCheckSimpleExceptionHandling() { int result = 10; @@ -79,6 +91,11 @@ private static void MakeGarbage() [UnmanagedCallersOnly(EntryPoint = "CheckSimpleGCCollect", CallConvs = new Type[] { typeof(CallConvStdcall) })] public static int CheckSimpleGCCollect() + { + return DoCheckSimpleGCCollect(); + } + + public static int DoCheckSimpleGCCollect() { string myString = string.Format("Hello {0}", "world"); @@ -93,3 +110,119 @@ public static int CheckSimpleGCCollect() } } } + +// Implements the component model interface defined in wit/world.wit +namespace LibraryWorld +{ + public class LibraryWorldImpl : ILibraryWorld + { + public static void TestHttp(ushort port) + { + var task = TestHttpAsync(port); + while (!task.IsCompleted) + { + WasiEventLoop.DispatchWasiEventLoop(); + } + var exception = task.Exception; + if (exception is not null) + { + throw exception; + } + } + + private static async Task TestHttpAsync(ushort port) + { + using var client = new HttpClient(); + + Trace.Assert(client.Timeout.Equals(Timeout.InfiniteTimeSpan)); + + try { + client.Timeout = TimeSpan.FromSeconds(100); + throw new Exception("expected PlatformNotSupportedException when setting HttpClient.Timeout"); + } catch (PlatformNotSupportedException e) { + // This is expected until `System.Threading.Timer` is implemented for WASI. + } + + var urlBase = $"http://127.0.0.1:{port}"; + { + var response = await client.GetAsync($"{urlBase}/hello"); + response.EnsureSuccessStatusCode(); + Trace.Assert( + 4 == response.Content.Headers.ContentLength, + $"unexpected content length: {response.Content.Headers.ContentLength}" + ); + Trace.Assert( + "text/plain".Equals(response.Content.Headers.ContentType.ToString()), + $"unexpected content type: \"{response.Content.Headers.ContentType}\"" + ); + var content = await response.Content.ReadAsStringAsync(); + Trace.Assert("hola".Equals(content), $"unexpected content: \"{content}\""); + } + + { + var length = 10 * 1024 * 1024; + var body = new byte[length]; + new Random().NextBytes(body); + + var content = new StreamContent(new MemoryStream(body)); + var type = "application/octet-stream"; + content.Headers.ContentType = new MediaTypeHeaderValue(type); + + var response = await client.PostAsync($"{urlBase}/echo", content); + response.EnsureSuccessStatusCode(); + Trace.Assert( + length == response.Content.Headers.ContentLength, + $"unexpected content length: {response.Content.Headers.ContentLength}" + ); + Trace.Assert( + type.Equals(response.Content.Headers.ContentType.ToString()), + $"unexpected content type: \"{response.Content.Headers.ContentType}\"" + ); + var received = await response.Content.ReadAsByteArrayAsync(); + Trace.Assert(body.SequenceEqual(received), "unexpected content"); + } + } + + public static int ReturnsPrimitiveInt() + { + return 10; + } + + public static bool ReturnsPrimitiveBool() + { + return true; + } + + public static uint ReturnsPrimitiveChar() + { + return (uint)'a'; + } + + public static void EnsureManagedClassLoaders() + { + Random random = new Random(); + random.Next(); + } + + public static int CheckSimpleExceptionHandling() + { + return SharedLibrary.ClassLibrary.DoCheckSimpleExceptionHandling(); + } + + public static int CheckSimpleGcCollect() + { + return SharedLibrary.ClassLibrary.DoCheckSimpleGCCollect(); + } + } + + internal static class WasiEventLoop + { + internal static void DispatchWasiEventLoop() + { + CallDispatchWasiEventLoop((Thread)null!); + + [UnsafeAccessor(UnsafeAccessorKind.StaticMethod, Name = "DispatchWasiEventLoop")] + static extern void CallDispatchWasiEventLoop(Thread t); + } + } +} diff --git a/src/tests/nativeaot/SmokeTests/SharedLibrary/SharedLibrary.csproj b/src/tests/nativeaot/SmokeTests/SharedLibrary/SharedLibrary.csproj index dd725ef9d8bd..4a92d5809a8b 100644 --- a/src/tests/nativeaot/SmokeTests/SharedLibrary/SharedLibrary.csproj +++ b/src/tests/nativeaot/SmokeTests/SharedLibrary/SharedLibrary.csproj @@ -33,6 +33,7 @@ cp SharedLibraryDriver native/SharedLibrary + @@ -58,5 +59,6 @@ cp SharedLibraryDriver$(NativeExtension) native/SharedLibrary$(NativeExtension) + diff --git a/src/tests/nativeaot/SmokeTests/SharedLibrary/SharedLibraryDriver.mjs b/src/tests/nativeaot/SmokeTests/SharedLibrary/SharedLibraryDriver.mjs index 434aab734efd..8d48c93d8aed 100644 --- a/src/tests/nativeaot/SmokeTests/SharedLibrary/SharedLibraryDriver.mjs +++ b/src/tests/nativeaot/SmokeTests/SharedLibrary/SharedLibraryDriver.mjs @@ -1,37 +1,97 @@ -import { readFile } from 'node:fs/promises'; -import { WASI } from 'wasi'; -import { argv, env } from 'node:process'; +import { Worker, parentPort, isMainThread } from 'node:worker_threads'; +import { readFile, writeFile } from 'node:fs/promises'; +import { transpile } from '@bytecodealliance/jco'; +import { _setPreopens } from '@bytecodealliance/preview2-shim/filesystem'; +import * as http from 'node:http'; -const wasi = new WASI({ - version: 'preview1', - args: argv, - env -}); +// Note that `jco` implements `wasi:io` by synchronously dispatching to worker +// threads. That means that when we run `HttpClient` smoke test below, it will +// block the main thread waiting for I/O. Therefore, the HTTP server we launch +// for that test needs to run in a dedicated thread rather than the main thread. -const wasm = await WebAssembly.compile( - await readFile(new URL("./SharedLibrary.wasm", import.meta.url)), -); +if (isMainThread) { + // Run the tests + const base = import.meta.url; + const component = await readFile(new URL("./SharedLibrary.wasm", base)); + const transpiled = await transpile(component, { + name: "shared-library", + typescript: false, + }); + await writeFile(new URL("./shared-library.core.wasm", base), transpiled.files["shared-library.core.wasm"]); + await writeFile(new URL("./shared-library.core2.wasm", base), transpiled.files["shared-library.core2.wasm"]); + await writeFile(new URL("./shared-library.core3.wasm", base), transpiled.files["shared-library.core3.wasm"]); + await writeFile(new URL("./shared-library.mjs", base), transpiled.files["shared-library.js"]); + _setPreopens([]); + const instance = await import(new URL("./shared-library.mjs", base)); -const instance = await WebAssembly.instantiate(wasm, wasi.getImportObject()); + // Spawn a worker thread to run the HTTP server and feed the port number + // it's listening on back to us when ready: + const port = await new Promise((resolve, reject) => { + const worker = new Worker(new URL("./SharedLibrary.mjs", base)); + worker.on("message", resolve); + worker.on("error", reject); + worker.on("exit", (code) => { + reject(new Error(`worker stopped with exit code ${code}`)); + }); + }); -wasi.initialize(instance); + instance.testHttp(port); -if (instance.exports.ReturnsPrimitiveInt() != 10) - process.exit(1); + if (instance.returnsPrimitiveInt() != 10) + process.exit(1); -if (instance.exports.ReturnsPrimitiveBool() != 1) - process.exit(2); + if (instance.returnsPrimitiveBool() != 1) + process.exit(2); -if (instance.exports.ReturnsPrimitiveChar() != 97) // 'a' - process.exit(3); + if (instance.returnsPrimitiveChar() != 'a') + process.exit(3); -// As long as no unmanaged exception is thrown managed class loaders were initialized successfully. -instance.exports.EnsureManagedClassLoaders(); + // As long as no unmanaged exception is thrown managed class loaders were initialized successfully. + instance.ensureManagedClassLoaders(); -if (instance.exports.CheckSimpleGCCollect() != 100) - process.exit(4); + if (instance.checkSimpleGcCollect() != 100) + process.exit(4); -if (instance.exports.CheckSimpleExceptionHandling() != 100) - process.exit(5); + if (instance.checkSimpleExceptionHandling() != 100) + process.exit(5); -process.exit(100); + process.exit(100); +} else { + // Run the HTTP server + const server = http.createServer((req, res) => { + if (req.method === "POST" && req.url === "/echo") { + // Note that we buffer the request body here rather than pipe it + // directly to the response. That's because, as of this writing, + // `WasiHttpHandler` sends the entire request body before reading + // any of the response body, which can lead to deadlock if the + // server is blocked on backpressure when sending the response body. + let chunks = []; + req.on("data", (chunk) => { + chunks.push(chunk); + }); + req.on("end", () => { + res.writeHead(200, req.headers); + res.end(Buffer.concat(chunks)); + }); + } else { + let status; + let body; + if (req.method === "GET" && req.url === "/hello") { + status = 200; + body = "hola"; + } else { + status = 400; + body = "Bad Request"; + } + res + .writeHead(status, { + "content-length": Buffer.byteLength(body), + "content-type": "text/plain", + }) + .end(body); + } + }); + server.listen(() => { + parentPort.postMessage(server.address().port); + }); +} diff --git a/src/tests/nativeaot/SmokeTests/SharedLibrary/generate-shared-library-bindings.sh b/src/tests/nativeaot/SmokeTests/SharedLibrary/generate-shared-library-bindings.sh new file mode 100644 index 000000000000..4a051a50554a --- /dev/null +++ b/src/tests/nativeaot/SmokeTests/SharedLibrary/generate-shared-library-bindings.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +set -ex + +# This script will regenerate the `wit-bindgen`-generated files in this +# directory. + +# Prerequisites: +# POSIX shell +# tar +# [cargo](https://rustup.rs/) +# [curl](https://curl.se/download.html) + +cargo install --locked --no-default-features --features csharp --version 0.29.0 wit-bindgen-cli +wit-bindgen c-sharp -w library -r native-aot wit +rm LibraryWorld_wasm_import_linkage_attribute.cs LibraryWorld_cabi_realloc.c LibraryWorld_component_type.o diff --git a/src/tests/nativeaot/SmokeTests/SharedLibrary/package-lock.json b/src/tests/nativeaot/SmokeTests/SharedLibrary/package-lock.json new file mode 100644 index 000000000000..0b2ea4e1793b --- /dev/null +++ b/src/tests/nativeaot/SmokeTests/SharedLibrary/package-lock.json @@ -0,0 +1,698 @@ +{ + "name": "sharedlibrarytest", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "sharedlibrarytest", + "version": "1.0.0", + "dependencies": { + "@bytecodealliance/jco": "1.3.1" + } + }, + "node_modules/@bytecodealliance/jco": { + "version": "1.3.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@bytecodealliance/jco/-/jco-1.3.1.tgz", + "integrity": "sha1-k/ZHBglXNPz66y9DL7JIuXLuFeg=", + "license": "(Apache-2.0 WITH LLVM-exception)", + "workspaces": [ + "packages/preview2-shim" + ], + "dependencies": { + "@bytecodealliance/preview2-shim": "^0.16.3", + "binaryen": "^116.0.0", + "chalk-template": "^1", + "commander": "^12", + "mkdirp": "^3", + "ora": "^8", + "terser": "^5" + }, + "bin": { + "jco": "src/jco.js" + } + }, + "node_modules/@bytecodealliance/preview2-shim": { + "version": "0.16.4", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@bytecodealliance/preview2-shim/-/preview2-shim-0.16.4.tgz", + "integrity": "sha1-Y3CfvaiO8u7hxJLiGP3+GWPOIaw=", + "license": "(Apache-2.0 WITH LLVM-exception)" + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha1-3M5q/3S99trRqVgCtpsEovyx+zY=", + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha1-eg7mAfYPmaIMfHxf8MgDiMEYm9Y=", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha1-VY+2Ry7RakyFC4iVMOazZDjEkoA=", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha1-nXHKiG4yUC65NiyadKRnh8Nt+Bo=", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha1-18bmdVx4VnqVHgSrUu8P0m3lnzI=", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha1-FfGQ6YiV8/wjJ27hS8drZ1wuUPA=", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha1-cWFr3MviXielRDngBG6JynbfIkg=", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha1-MYPjj66aZdfLXlOUXNWJfQJgoGo=", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/binaryen": { + "version": "116.0.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/binaryen/-/binaryen-116.0.0.tgz", + "integrity": "sha1-rXn7k5JGE4+xKNlDjVV0FS7OOf4=", + "license": "Apache-2.0", + "bin": { + "wasm-opt": "bin/wasm-opt", + "wasm2js": "bin/wasm2js" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha1-KxRqb9cugLT1XSVfNe1Zo6mkG9U=", + "license": "MIT" + }, + "node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha1-Z8IKfr73Dn85cKAfkPohDLaGA4U=", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk-template": { + "version": "1.1.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/chalk-template/-/chalk-template-1.1.0.tgz", + "integrity": "sha1-/8Vdtt10XpOUuFMnyKyEZu23p7E=", + "license": "MIT", + "dependencies": { + "chalk": "^5.2.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/chalk/chalk-template?sponsor=1" + } + }, + "node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha1-POz+NzS/T+Aqg2HL3A9v4oxqV+o=", + "license": "MIT", + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha1-F3Oo9LnE1qwxVj31Oz/B15Ri/kE=", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/commander": { + "version": "12.1.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/commander/-/commander-12.1.0.tgz", + "integrity": "sha1-AUI7NvUBJZ/arE0OTWDJbJkVhdM=", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha1-dpmLkmhAnrPa496YklTUVucM/iM=", + "license": "MIT" + }, + "node_modules/get-east-asian-width": { + "version": "1.2.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", + "integrity": "sha1-Xm69m67m+4t7a9UFIhBl8M2R9k4=", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha1-QMV2FFk4JtoRAK3mBZd41ZfxbpA=", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "2.0.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/is-unicode-supported/-/is-unicode-supported-2.0.0.tgz", + "integrity": "sha1-/fMt+a6Y/2qyztwVWlpuiVcBxFE=", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols": { + "version": "6.0.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/log-symbols/-/log-symbols-6.0.0.tgz", + "integrity": "sha1-u5Xl8FMiZRysMMD+tkBPnyqKlDk=", + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "is-unicode-supported": "^1.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha1-2CSYS2FsKSouGYIH1KYJmDhC9xQ=", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha1-ftLCzMyvhNP/y3pptXcR/CCDQBs=", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha1-5E5MVgf7J5wWgkFxPMbg/qmty1A=", + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha1-0Oluu1awdHbfHdnEgG5SN5hcpF4=", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "8.0.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/ora/-/ora-8.0.1.tgz", + "integrity": "sha1-bcuSUKYpZCy+DS3zpjMa1veirz4=", + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "cli-cursor": "^4.0.0", + "cli-spinners": "^2.9.2", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.0.0", + "log-symbols": "^6.0.0", + "stdin-discarder": "^0.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha1-UZVgpDGJdQlt725gnUQQDtqkzLk=", + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha1-qaF2f4r4QVURTqq9c/mSc8j1mtk=", + "license": "ISC" + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha1-BP58f54e0tZiIzwoyys1ufY/bk8=", + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/stdin-discarder": { + "version": "0.2.2", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/stdin-discarder/-/stdin-discarder-0.2.2.tgz", + "integrity": "sha1-OQA39ExK4aGuU1xf443Dq6jZl74=", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha1-tbuOIWXOJ11NQ0dt0nAK2Qkdttw=", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha1-1bZWjKaJ2FYTcLBwdoXSJDT6/0U=", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/terser": { + "version": "5.31.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/terser/-/terser-5.31.1.tgz", + "integrity": "sha1-c13jyYfdZx6VGQ5rmM/i8H888NQ=", + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/commander/-/commander-2.20.3.tgz", + "integrity": "sha1-/UhehMA+tIgcIHIrpIA16FMa6zM=", + "license": "MIT" + } + }, + "dependencies": { + "@bytecodealliance/jco": { + "version": "1.3.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@bytecodealliance/jco/-/jco-1.3.1.tgz", + "integrity": "sha1-k/ZHBglXNPz66y9DL7JIuXLuFeg=", + "requires": { + "@bytecodealliance/preview2-shim": "^0.16.3", + "binaryen": "^116.0.0", + "chalk-template": "^1", + "commander": "^12", + "mkdirp": "^3", + "ora": "^8", + "terser": "^5" + } + }, + "@bytecodealliance/preview2-shim": { + "version": "0.16.4", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@bytecodealliance/preview2-shim/-/preview2-shim-0.16.4.tgz", + "integrity": "sha1-Y3CfvaiO8u7hxJLiGP3+GWPOIaw=" + }, + "@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha1-3M5q/3S99trRqVgCtpsEovyx+zY=", + "requires": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha1-eg7mAfYPmaIMfHxf8MgDiMEYm9Y=" + }, + "@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha1-VY+2Ry7RakyFC4iVMOazZDjEkoA=" + }, + "@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha1-nXHKiG4yUC65NiyadKRnh8Nt+Bo=", + "requires": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha1-18bmdVx4VnqVHgSrUu8P0m3lnzI=" + }, + "@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha1-FfGQ6YiV8/wjJ27hS8drZ1wuUPA=", + "requires": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "acorn": { + "version": "8.12.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha1-cWFr3MviXielRDngBG6JynbfIkg=" + }, + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha1-MYPjj66aZdfLXlOUXNWJfQJgoGo=" + }, + "binaryen": { + "version": "116.0.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/binaryen/-/binaryen-116.0.0.tgz", + "integrity": "sha1-rXn7k5JGE4+xKNlDjVV0FS7OOf4=" + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha1-KxRqb9cugLT1XSVfNe1Zo6mkG9U=" + }, + "chalk": { + "version": "5.3.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha1-Z8IKfr73Dn85cKAfkPohDLaGA4U=" + }, + "chalk-template": { + "version": "1.1.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/chalk-template/-/chalk-template-1.1.0.tgz", + "integrity": "sha1-/8Vdtt10XpOUuFMnyKyEZu23p7E=", + "requires": { + "chalk": "^5.2.0" + } + }, + "cli-cursor": { + "version": "4.0.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha1-POz+NzS/T+Aqg2HL3A9v4oxqV+o=", + "requires": { + "restore-cursor": "^4.0.0" + } + }, + "cli-spinners": { + "version": "2.9.2", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha1-F3Oo9LnE1qwxVj31Oz/B15Ri/kE=" + }, + "commander": { + "version": "12.1.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/commander/-/commander-12.1.0.tgz", + "integrity": "sha1-AUI7NvUBJZ/arE0OTWDJbJkVhdM=" + }, + "emoji-regex": { + "version": "10.3.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha1-dpmLkmhAnrPa496YklTUVucM/iM=" + }, + "get-east-asian-width": { + "version": "1.2.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", + "integrity": "sha1-Xm69m67m+4t7a9UFIhBl8M2R9k4=" + }, + "is-interactive": { + "version": "2.0.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha1-QMV2FFk4JtoRAK3mBZd41ZfxbpA=" + }, + "is-unicode-supported": { + "version": "2.0.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/is-unicode-supported/-/is-unicode-supported-2.0.0.tgz", + "integrity": "sha1-/fMt+a6Y/2qyztwVWlpuiVcBxFE=" + }, + "log-symbols": { + "version": "6.0.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/log-symbols/-/log-symbols-6.0.0.tgz", + "integrity": "sha1-u5Xl8FMiZRysMMD+tkBPnyqKlDk=", + "requires": { + "chalk": "^5.3.0", + "is-unicode-supported": "^1.3.0" + }, + "dependencies": { + "is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha1-2CSYS2FsKSouGYIH1KYJmDhC9xQ=" + } + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha1-ftLCzMyvhNP/y3pptXcR/CCDQBs=" + }, + "mkdirp": { + "version": "3.0.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha1-5E5MVgf7J5wWgkFxPMbg/qmty1A=" + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha1-0Oluu1awdHbfHdnEgG5SN5hcpF4=", + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "ora": { + "version": "8.0.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/ora/-/ora-8.0.1.tgz", + "integrity": "sha1-bcuSUKYpZCy+DS3zpjMa1veirz4=", + "requires": { + "chalk": "^5.3.0", + "cli-cursor": "^4.0.0", + "cli-spinners": "^2.9.2", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.0.0", + "log-symbols": "^6.0.0", + "stdin-discarder": "^0.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + } + }, + "restore-cursor": { + "version": "4.0.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha1-UZVgpDGJdQlt725gnUQQDtqkzLk=", + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha1-qaF2f4r4QVURTqq9c/mSc8j1mtk=" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=" + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha1-BP58f54e0tZiIzwoyys1ufY/bk8=", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "stdin-discarder": { + "version": "0.2.2", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/stdin-discarder/-/stdin-discarder-0.2.2.tgz", + "integrity": "sha1-OQA39ExK4aGuU1xf443Dq6jZl74=" + }, + "string-width": { + "version": "7.2.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha1-tbuOIWXOJ11NQ0dt0nAK2Qkdttw=", + "requires": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + } + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha1-1bZWjKaJ2FYTcLBwdoXSJDT6/0U=", + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "terser": { + "version": "5.31.1", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/terser/-/terser-5.31.1.tgz", + "integrity": "sha1-c13jyYfdZx6VGQ5rmM/i8H888NQ=", + "requires": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/commander/-/commander-2.20.3.tgz", + "integrity": "sha1-/UhehMA+tIgcIHIrpIA16FMa6zM=" + } + } + } + } +} diff --git a/src/tests/nativeaot/SmokeTests/SharedLibrary/package.json b/src/tests/nativeaot/SmokeTests/SharedLibrary/package.json new file mode 100644 index 000000000000..3d278ba3cb3e --- /dev/null +++ b/src/tests/nativeaot/SmokeTests/SharedLibrary/package.json @@ -0,0 +1,11 @@ +{ + "name": "sharedlibrarytest", + "type": "module", + "version": "1.0.0", + "scripts": { + "test": "node SharedLibraryDriver.mjs" + }, + "dependencies": { + "@bytecodealliance/jco": "1.3.1" + } +} \ No newline at end of file diff --git a/src/tests/nativeaot/SmokeTests/SharedLibrary/wit/world.wit b/src/tests/nativeaot/SmokeTests/SharedLibrary/wit/world.wit new file mode 100644 index 000000000000..3dd01916452a --- /dev/null +++ b/src/tests/nativeaot/SmokeTests/SharedLibrary/wit/world.wit @@ -0,0 +1,11 @@ +package local:local; + +world library { + export test-http: func(port: u16); + export returns-primitive-int: func() -> s32; + export returns-primitive-bool: func() -> bool; + export returns-primitive-char: func() -> char; + export ensure-managed-class-loaders: func(); + export check-simple-exception-handling: func() -> s32; + export check-simple-gc-collect: func() -> s32; +}