### Install NetWasm templates Source: https://github.com/zion-sati/netwasm/blob/main/docs/sdk-quickstart.md Installs the NetWasm project templates from NuGet. ```bash dotnet new install NetWasm.Templates ``` -------------------------------- ### Install and run NetWasm WIT bindings tool Source: https://github.com/zion-sati/netwasm/blob/main/docs/sdk-quickstart.md Installs the standalone .NET tool 'NetWasm.Wit.Bindings.Tool' and generates C# bindings from a WIT world. Omit '--world' when the WIT document contains exactly one world. The tool carries the pinned platform-neutral wasm-tools module and does not require a native 'wasm-tools' installation. It still needs Node.js 24+ available on 'PATH', through 'NETWASM_NODE_PATH' or through 'EMSDK_NODE'. ```bash dotnet new tool-manifest dotnet tool install NetWasm.Wit.Bindings.Tool --version dotnet netwasm-wit-bindgen --wit service.wit --world example:service@1.0.0/service --output Bindings.g.cs ``` -------------------------------- ### Create and run a NetWasm application Source: https://github.com/zion-sati/netwasm/blob/main/QUICKSTART.md Install the NetWasm templates, create a new application, restore dependencies, run it, and publish a release build. Requires .NET SDK 10.0.303 or newer; native build tools are restored from NuGet automatically. ```sh dotnet new install NetWasm.Templates mkdir HelloNetWasm cd HelloNetWasm dotnet new netwasm-app dotnet restore dotnet run dotnet publish -c Release -o publish ``` -------------------------------- ### Install and run NetWasm.Wit.Bindings.Tool Source: https://github.com/zion-sati/netwasm/blob/main/docs/cli-build-deployment.md Creates a local tool manifest, installs the WIT bindings tool at the project's NetWasm version, and generates C# bindings from service.wit with the service world. Requires Node.js 24+ on PATH via NETWASM_NODE_PATH or EMSDK_NODE; no native wasm-tools installation needed. ```sh dotnet new tool-manifest dotnet tool install NetWasm.Wit.Bindings.Tool --version dotnet netwasm-wit-bindgen --wit service.wit --world service --output Bindings.g.cs ``` -------------------------------- ### Install and run a NetWasm app Source: https://github.com/zion-sati/netwasm/blob/main/README.md Install the .NET SDK 10.0.303 or newer, then create and run a new NetWasm app. The commands restore, run, and publish the project. ```sh dotnet new install NetWasm.Templates dotnet new netwasm-app -n HelloNetWasm cd HelloNetWasm dotnet restore dotnet run dotnet publish -c Release -o publish/local ``` -------------------------------- ### Create a dual-target library Source: https://github.com/zion-sati/netwasm/blob/main/docs/sdk-quickstart.md Creates a new NetWasm library project targeting 'netwasm0.1' and 'net10.0'. The consuming application selects its host and capabilities. ```bash cd .. mkdir HelloNetWasm.Library cd HelloNetWasm.Library dotnet new netwasm-lib dotnet restore dotnet build dotnet pack -c Release ``` -------------------------------- ### Restore and build after SDK version change Source: https://github.com/zion-sati/netwasm/blob/main/docs/sdk-quickstart.md After changing the SDK version, run these commands to restore and build the project. ```bash dotnet restore dotnet build ``` -------------------------------- ### Publish portable local deployment Source: https://github.com/zion-sati/netwasm/blob/main/docs/sdk-quickstart.md Publishes a portable local deployment to the 'publish/local' directory. The output contains the selected 'netwasm.host.mjs' launcher and its portable deployment closure. ```bash dotnet publish -c Release -o publish/local ``` -------------------------------- ### Update standalone WIT bindings tool Source: https://github.com/zion-sati/netwasm/blob/main/docs/sdk-quickstart.md Update the standalone WIT bindings tool to the same version and regenerate bindings. Bindings from NetWasmWit items regenerate with the build. ```bash dotnet tool update NetWasm.Wit.Bindings.Tool --version ``` -------------------------------- ### dotnet run output for browser project Source: https://github.com/zion-sati/netwasm/blob/main/docs/sdk-quickstart.md Output of `dotnet run` for a browser project, showing the server listening on `http://localhost:5080/`. The server runs on the loopback interface only and serves files without caching. ```text $ dotnet run Now listening on: http://localhost:5080/ ``` -------------------------------- ### Set NetWasm SDK version in project file Source: https://github.com/zion-sati/netwasm/blob/main/docs/sdk-quickstart.md The first line of a NetWasm project file names the SDK version. Change the version to upgrade. ```xml ``` -------------------------------- ### Install NetWasm WIT Bindings tool Source: https://github.com/zion-sati/netwasm/blob/main/docs/wit-bindings.md Creates a local tool manifest and installs the NetWasm WIT bindings generator at the specified version. Use the version matching the NetWasm SDK to ensure bindings match. ```sh dotnet new tool-manifest dotnet tool install NetWasm.Wit.Bindings.Tool --version ``` -------------------------------- ### Set async-command contract Source: https://github.com/zion-sati/netwasm/blob/main/docs/sdk-quickstart.md Selects the async-command entry contract for a suspending Main that returns Task or Task. This is required when Main may suspend. ```xml async-command ``` -------------------------------- ### Create and run a NetWasm application Source: https://github.com/zion-sati/netwasm/blob/main/docs/sdk-quickstart.md Creates a new NetWasm app, restores dependencies, builds, and runs it. The template prints 42. Debug builds include managed stack traces by default; Release omits them unless NetWasmManagedStackTrace=true. Debug builds compile at O0 and keep compiled code under obj/ for incremental builds. ```bash mkdir HelloNetWasm cd HelloNetWasm dotnet new netwasm-app dotnet restore dotnet build dotnet run ``` -------------------------------- ### nwc compiler invocation example Source: https://github.com/zion-sati/netwasm/blob/main/docs/cli-build-deployment.md Compiles App.dll to application.wasm with a reference to NetWasm.CoreLib.dll and a runtime layout file. The command line follows csc conventions: options start with - or /, values follow a colon, switches end in + or -, and @file reads options from a response file. ```sh nwc -out:application.wasm -r:NetWasm.CoreLib.dll -runtimelayout:layout.json App.dll ``` -------------------------------- ### Configure async-command with raw output Source: https://github.com/zion-sati/netwasm/blob/main/docs/sdk-quickstart.md Sets both NetWasmComponentContract=async-command and NetWasmRawWasm=true for a suspending entry point that directly imports an application JavaScript module. The C# code declares a JSImport for the 'report' function from 'app.host'. ```xml async-command true ``` ```csharp using System.Runtime.InteropServices.JavaScript; internal static class Host { [JSImport("report", "app.host")] internal static extern void Report(int value); } ``` -------------------------------- ### TinyGo build and run commands Source: https://github.com/zion-sati/netwasm/blob/main/docs/size-and-methodology.md Builds the TinyGo example with the official TinyGo 0.39.0 toolchain and runs it with wasmtime. The retained run used the official tinygo/tinygo:0.39.0 image. ```sh tinygo build -target=wasi -opt=2 -no-debug -o console42.wasm main.go wasmtime run console42.wasm ``` -------------------------------- ### TinyGo source for console42 Source: https://github.com/zion-sati/netwasm/blob/main/docs/size-and-methodology.md Source code for the TinyGo example that prints 42. Built with TinyGo 0.39.0 using -target=wasi -opt=2 -no-debug. ```go package main import "fmt" func main() { fmt.Println(42) } ``` -------------------------------- ### Set up Emscripten SDK on macOS or Linux Source: https://github.com/zion-sati/netwasm/blob/main/CONTRIBUTING.md Install and activate the pinned Emscripten 6.0.7 SDK and set NETWASM_EMSDK_ROOT. Required for maintainer workflows that build the toolchain or regenerate runtime packs. ```sh git clone https://github.com/emscripten-core/emsdk.git ~/emsdk cd ~/emsdk ./emsdk install 6.0.7 ./emsdk activate 6.0.7 source ~/emsdk/emsdk_env.sh export NETWASM_EMSDK_ROOT="$EMSDK" ``` -------------------------------- ### NetWasmPreopen: Map host directory to guest path Source: https://github.com/zion-sati/netwasm/blob/main/docs/sdk-quickstart.md Declares a preopen mapping a host directory to a guest path in the Wasm sandbox. `Include` is the host directory, `GuestPath` is the absolute sandbox path, and `Access` is either `readOnly` or `readWrite`. Guest paths must use canonical forward-slash syntax and be unique within the project. ```xml ``` -------------------------------- ### Entry.cs: Multi-file entry point with partial class and file-local type Source: https://github.com/zion-sati/netwasm/blob/main/tests/NetWasm.Compiler.Tests/Correctness/Fixtures/multi-file/Entry.cs.txt Defines a static partial class EntryPoint with a Run method that sums results from Left and Right. Uses a file-local sealed class LocalValue to add 23 to the input. This is part of a multi-file fixture for correctness tests. ```csharp namespace NetWasm.Correctness.MultiFile; public static partial class EntryPoint { public static int Run(int input) => Left(input) + Right(input); private static int Left(int input) => new LocalValue().Read(input); } file sealed class LocalValue { public int Read(int input) => input + 23; } ``` -------------------------------- ### Install pinned Rust toolchains for wasm32-wasip2 Source: https://github.com/zion-sati/netwasm/blob/main/docs/size-and-methodology.md Installs Rust 1.90.0 and 1.99.1 with the wasm32-wasip2 target without changing the default toolchain. ```sh rustup toolchain install 1.90.0 --profile minimal --target wasm32-wasip2 rustup toolchain install 1.99.1 --profile minimal --target wasm32-wasip2 ``` -------------------------------- ### Restore and build NetWasm from repository root Source: https://github.com/zion-sati/netwasm/blob/main/CONTRIBUTING.md Restore dependencies, install npm packages, verify the toolchain, and build the solution in Release mode without restoring again. ```sh dotnet restore NetWasm.slnx npm ci eng/verify-toolchain.sh dotnet build NetWasm.slnx -c Release --no-restore ``` -------------------------------- ### Program.cs for Blazor AOT app Source: https://github.com/zion-sati/netwasm/blob/main/docs/size-and-methodology.md Entry point that prints 42 to the console and starts the Blazor WebAssembly host. Requires the Blazor42 namespace and the App component. ```csharp using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using Blazor42; Console.WriteLine(42); var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add("#app"); await builder.Build().RunAsync(); ``` -------------------------------- ### Set NetWasm SDK version in global.json Source: https://github.com/zion-sati/netwasm/blob/main/docs/sdk-quickstart.md Leave the version off each Sdk attribute and set it once in the repository's global.json to keep every project on one version. A version on the Sdk attribute takes precedence over global.json. ```json { "msbuild-sdks": { "NetWasm.Sdk": "" } } ``` -------------------------------- ### Install templates and create a worker Source: https://github.com/zion-sati/netwasm/blob/main/docs/web-workers.md Install the NetWasm templates, then create a worker project with either the WIT or JSExport boundary. `dotnet run` publishes and serves the worker and page at `http://localhost:5080/`; `dotnet publish -c Release` writes the site to `bin/Release/netwasm0.1/publish`. ```bash dotnet new install NetWasm.Templates dotnet new netwasm-app -n ReportWorker --worker wit # or: dotnet new netwasm-app -n ReportWorker --host worker cd ReportWorker dotnet run ``` -------------------------------- ### Publish browser-selected deployment Source: https://github.com/zion-sati/netwasm/blob/main/docs/sdk-quickstart.md Publishes the browser-selected deployment to 'publish/browser', alongside the portable local deployment. Release publishing selects and minifies only the JavaScript host closure needed by that deployment. Set '-p:NetWasmMinifyJavaScript=false' only when readable JavaScript is useful for diagnosis. ```bash dotnet publish -c Release -p:NetWasmPublishTarget=browser -o publish ``` -------------------------------- ### Declare JavaScript module for raw host in project file Source: https://github.com/zion-sati/netwasm/blob/main/docs/sdk-quickstart.md Declares the JavaScript module file for the raw host in the application project. The module name must match the exact module name (e.g., app.host). This item supplies modules to JsModule projects and ordinary raw browser applications. ```xml ``` -------------------------------- ### Example service.wit WIT definition Source: https://github.com/zion-sati/netwasm/blob/main/docs/wit-bindings.md A WIT package defining a host interface with a record, variant, and function, plus a world that imports the host and exports an evaluate function. Used as input for the bindings generator. ```wit package docs:bindings@1.0.0; interface host { record point { x: s32, y: s32, } variant outcome { value(s32), message(string), } transform: func(input: point) -> outcome; } world service { import host; export evaluate: func(value: s32) -> s32; } ``` -------------------------------- ### Create a new NetWasm application Source: https://github.com/zion-sati/netwasm/blob/main/docs/static-native-interop.md Install the NetWasm templates and scaffold a new application named NativeSample. Creates the native/wasm32 directory for the C archive. ```sh dotnet new install NetWasm.Templates dotnet new netwasm-app -n NativeSample cd NativeSample mkdir -p native/wasm32 ``` -------------------------------- ### Run performance collectors with NetWasm and Compact Source: https://github.com/zion-sati/netwasm/blob/main/docs/performance.md Reproduces the runtime performance harness. Requires Python 3, .NET SDKs pinned in eng/csharp15-toolchain.json, Wasmtime 49.0.3 on PATH, Node.js for Brotli sizes, and Rust to build the memory host. For the Mono row, install a .NET 11 RC3 SDK with the wasi-experimental workload and wasi-sdk 33.0. An empty --feed directory restores released NetWasm packages from NuGet.org. Prints the table and writes every run's time to summary.json. ```sh python3 compiler-qualification/runtime-performance/collectors.py \ --feed 0.11.2 --output \ --collectors NetWasm Compact \ --mono-aot \ --desktop jit aot ``` -------------------------------- ### SDK reproduction commands Source: https://github.com/zion-sati/netwasm/blob/main/docs/size-and-methodology.md Commands to reproduce the size measurements with the released NetWasm SDK 0.11.2. The application prints 42; the SDK restores host tools via NuGet, so no maintainer Emscripten installation is needed. ```sh dotnet new install NetWasm.Templates@0.11.2 dotnet new netwasm-app -n NetWasmApp cd NetWasmApp dotnet restore dotnet publish -c Release -p:NetWasmOptimization=Oz -o publish/local dotnet run -c Release -p:NetWasmOptimization=Oz wc -c publish/local/NetWasmApp.wasm wasmtime run publish/local/NetWasmApp.wasm ``` -------------------------------- ### NetWasmSiteFile: Add shell files to published site Source: https://github.com/zion-sati/netwasm/blob/main/docs/sdk-quickstart.md Declares a target that adds shell files to the published site via `NetWasmSiteFile` items. The `NetWasmCollectSiteFilesDependsOn` property ensures the target runs during the build. `SitePath` is relative to the publish directory. ```xml $(NetWasmCollectSiteFilesDependsOn);AddShellFiles <_ShellFile Include="shell/**/*" /> ``` -------------------------------- ### page-host.mjs: export report function for DOM access Source: https://github.com/zion-sati/netwasm/blob/main/docs/sdk-quickstart.md JavaScript module that runs in the page's realm when the bootstrap runs, allowing access to the page's DOM. The report function writes a value to the #result element. ```javascript // page-host.mjs export function report(value) { document.querySelector("#result").textContent = String(value); } ``` -------------------------------- ### Run the worker with dotnet run Source: https://github.com/zion-sati/netwasm/blob/main/src/NetWasm.Templates/content/NetWasm.App/worker-common/README.md Starts the worker and serves the browser page on localhost. The printed address should be opened in a browser. The page calls the worker asynchronously, receives progress via worker messaging, and disposes the worker when the call finishes. ```bash dotnet run ``` -------------------------------- ### Import and call createWorker from the generated worker client Source: https://github.com/zion-sati/netwasm/blob/main/docs/web-workers.md Use this JavaScript to import the generated worker client and call an export. The example uses the JSExport template; WIT export names are qualified as shown in the WIT section. createWorker() resolves after the worker is ready, export calls return Promises and run concurrently, and each call takes a trailing { signal }. ```JavaScript import { createWorker } from "./browser/ReportWorker.worker-client.mjs"; const worker = await createWorker({ onNotification({ operation, arguments: values }) { console.log(operation, ...values); }, }); try { const result = await worker.run(5); console.log(result); } finally { await worker.dispose(); } ``` -------------------------------- ### Counter.CurrentCount Source: https://github.com/zion-sati/netwasm/blob/main/tests/NetWasm.Compiler.Tests/Correctness/HostFixtures/Interlocked/TUnitCounter.cs.txt Gets the current count value using an atomic read operation. ```APIDOC ## Counter.CurrentCount ### Description Gets the current count value using an atomic read operation. ### Property public int CurrentCount ### Returns - **int** - The current count value. ``` -------------------------------- ### Run the application Source: https://github.com/zion-sati/netwasm/blob/main/docs/static-native-interop.md Executes the application in Release configuration. The documented output is '42' and '41'. ```sh dotnet run -c Release ``` -------------------------------- ### Replace application project with worker configuration Source: https://github.com/zion-sati/netwasm/blob/main/docs/wit-bindings.md Configures the project to use the worker SDK, sets the WIT package directory, and includes the host import and content files. ```xml WitWebWorker netwasm0.1 disable enable $(MSBuildProjectDirectory)/wit docs:bindings@1.0.0/worker docs:bindings@1.0.0/service ``` -------------------------------- ### Clone dotnet/performance at pinned commit Source: https://github.com/zion-sati/netwasm/blob/main/compiler-qualification/micro-benchmarks/README.md Check out dotnet/performance at the commit run.py pins before running the harness. ```sh git clone https://github.com/dotnet/performance git -C checkout ceb046992aa203f881d7c8a29d50a105805ecb42 ``` -------------------------------- ### Create and run wasm-tools and Binaryen hosts Source: https://github.com/zion-sati/netwasm/blob/main/src/NetWasm.Toolchain/Browser/Tools/README.md Initializes the wasm-tools and Binaryen hosts with verified loaders, then runs a parse and an optimization pipeline. Requires verified asset loaders and shims; outputs are owned byte maps. ```javascript import { createWasmToolsHost } from './wasm-tools-host.mjs'; import { createBinaryenHost } from './binaryen-host.mjs'; const wasmTools = createWasmToolsHost({ loadAsset: verifiedLoader, wasiShim: verifiedPreview1Shim }); const binaryen = createBinaryenHost({ loadAsset: verifiedLoader }); const parsed = await wasmTools.run({ args: ['parse', 'input.wat', '-o', 'core.wasm'], files: { 'input.wat': watBytes }, outputs: ['core.wasm'] }); const optimized = await binaryen.run('wasm-opt', { args: ['core.wasm', '-Oz', '-o', 'optimized.wasm'], files: parsed.files, outputs: ['optimized.wasm'] }); ``` -------------------------------- ### Run published component with Wasmtime Source: https://github.com/zion-sati/netwasm/blob/main/README.md Run the published WebAssembly component with a compatible WASI Preview 2 host like Wasmtime. ```sh wasmtime run publish/local/HelloNetWasm.wasm ``` -------------------------------- ### Create a NetWasm library with dotnet new Source: https://github.com/zion-sati/netwasm/blob/main/README.md Use the netwasm-lib template to create a library targeting both netwasm0.1 and net10.0, producing NuGet assets for both platforms. ```sh dotnet new netwasm-lib -n MyLibrary ``` -------------------------------- ### Run micro-benchmark harness with run.py Source: https://github.com/zion-sati/netwasm/blob/main/compiler-qualification/micro-benchmarks/README.md Runs the full benchmark suite. Requires Python 3, Git, .NET SDKs, Wasmtime 49.0.3, and for Mono AOT a .NET 11 RC3 SDK with wasi-experimental workload and wasi-sdk 33.0. An empty --feed directory restores released NetWasm packages from NuGet.org. ```sh python3 compiler-qualification/micro-benchmarks/run.py \ --performance \ --feed 0.11.2 --libraries 0.11.0 \ --mono-aot \ --output ``` -------------------------------- ### AsWritableReferenceContainingType: MemoryMarshal.AsRef rejects reference-containing types Source: https://github.com/zion-sati/netwasm/blob/main/tests/NetWasm.Compiler.Tests/Correctness/Fixtures/memory-unsafe-boundaries/Program.cs.txt Attempts to get a reference to a ReferencePair from an empty span, expecting an ArgumentException (returning 42) rather than an ArgumentOutOfRangeException (returning -32) or unexpected success (-31). Verifies that the API rejects reference-containing types before checking length. ```csharp private static int AsWritableReferenceContainingType() { try { _ = MemoryMarshal.AsRef(Span.Empty); return -31; } catch (ArgumentOutOfRangeException) { return -32; } catch (ArgumentException) { return 42; } } ``` -------------------------------- ### AsReadOnlyReferenceContainingType: MemoryMarshal.AsRef rejects reference-containing types Source: https://github.com/zion-sati/netwasm/blob/main/tests/NetWasm.Compiler.Tests/Correctness/Fixtures/memory-unsafe-boundaries/Program.cs.txt Attempts to get a reference to a ReferencePair from an empty read-only span, expecting an ArgumentException (returning 42) rather than an ArgumentOutOfRangeException (returning -32) or unexpected success (-31). Verifies that the API rejects reference-containing types before checking length. ```csharp private static int AsReadOnlyReferenceContainingType() { try { _ = MemoryMarshal.AsRef(ReadOnlySpan.Empty); return -31; } catch (ArgumentOutOfRangeException) { return -32; } catch (ArgumentException) { return 42; } } ``` -------------------------------- ### Create GitHub Release with gh CLI Source: https://github.com/zion-sati/netwasm/blob/main/docs/maintenance.md Use this command to create and publish a GitHub Release targeting the signed PR-head SHA. Add --prerelease for a preview. The CLI creates the tag and Release together; no local tag or version edit is needed. ```sh gh release create vVERSION --repo zion-sati/NetWasm \ --target FULL_SIGNED_PR_HEAD_SHA --notes-file release-notes.md ``` -------------------------------- ### Open and call a NetWasm module from a page Source: https://github.com/zion-sati/netwasm/blob/main/docs/javascript-interop.md Import the generated module and call `open()` to get a frozen object with methods for each export, plus `close()` and `failure`. Synchronous exports run on the page thread; `Task` exports return Promises. `failure` settles on trap or after `close()`, and calls after that throw `NetWasmHostError`. ```js import { open } from "./browser/Calculator.mjs"; const app = await open({ stdout: line => console.log(line) }); app.Add(2, 3); // 5, synchronously on the page await app.FetchTitle(url); // a Task export returns a Promise app.failure.then(error => console.error(error)); await app.close(); ``` -------------------------------- ### Add NetWasmWit item for WIT input Source: https://github.com/zion-sati/netwasm/blob/main/docs/wit-bindings.md Configure a NetWasmWit item in the project file to generate C# bindings during the build. Include points to a WIT file or package directory, World selects a world (optional if only one), Namespace overrides the package namespace, and Accessibility is Public (default) or Internal. Each item requires a distinct file or directory name. ```xml ``` -------------------------------- ### Query custom attributes with DescriptionAttribute Source: https://github.com/zion-sati/netwasm/blob/main/docs/custom-attributes.md Shows how NetWasm resolves custom attribute queries at compile time when the target and filter identify one exact, closed type. The example uses DescriptionAttribute on a sealed class and demonstrates IsDefined, GetCustomAttribute, GetCustomAttributes, and the explicit filter overload. No runtime attribute database is needed. ```csharp using System.ComponentModel; using System.Reflection; [Description("An order")] sealed class Order; static class Example { public static void Query() { bool present = typeof(Order).IsDefined(typeof(DescriptionAttribute), false); DescriptionAttribute? one = typeof(Order).GetCustomAttribute(); IEnumerable many = typeof(Order).GetCustomAttributes(); object[] explicitFilter = typeof(Order).GetCustomAttributes(typeof(DescriptionAttribute), false); } } ``` -------------------------------- ### Create BindingConsumer app and generate bindings Source: https://github.com/zion-sati/netwasm/blob/main/docs/wit-bindings.md Creates a new NetWasm application and generates bindings from the initial contract before adding the worker world. ```sh dotnet new netwasm-app -n BindingConsumer cd BindingConsumer netwasm-wit-bindgen --wit wit/service.wit \ --world docs:bindings@1.0.0/service \ --output Bindings.g.cs --accessibility internal ``` -------------------------------- ### C# test for generic EqualNull with value and reference types Source: https://github.com/zion-sati/netwasm/blob/main/tests/NetWasm.Compiler.Tests/Correctness/RuntimeJit/Upstream/instance_equalnull_class01.upstream.cs.txt Defines generic structs and classes used as type arguments, then tests the Gen.EqualNull method for value types (int, double, Guid), string, and object. Asserts that non-null values return false and null returns true, printing 'Test Passed' and returning 100 on success. ```csharp // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // using System; using Xunit; public struct ValX0 { } public struct ValY0 { } public struct ValX1 { } public struct ValY1 { } public struct ValX2 { } public struct ValY2 { } public struct ValX3 { } public struct ValY3 { } public class RefX0 { } public class RefY0 { } public class RefX1 { } public class RefY1 { } public class RefX2 { } public class RefY2 { } public class RefX3 { } public class RefY3 { } public class Gen { public bool EqualNull(T t) { return ((object)t == null); } } public class Test_instance_equalnull_class01 { public static int counter = 0; public static bool result = true; public static void Eval(bool exp) { counter++; if (!exp) { result = exp; Console.WriteLine("Test Failed at location: " + counter); } } [Fact] public static int TestEntryPoint() { int _int = 0; Eval(false == new Gen().EqualNull(_int)); double _double = 0; Eval(false == new Gen().EqualNull(_double)); Guid _Guid = new Guid(); Eval(false == new Gen().EqualNull(_Guid)); string _string = "string"; Eval(false == new Gen().EqualNull(_string)); Eval(true == new Gen().EqualNull(null)); object _object = new object(); Eval(false == new Gen().EqualNull(_string)); Eval(true == new Gen().EqualNull(null)); if (result) { Console.WriteLine("Test Passed"); return 100; } else { Console.WriteLine("Test Failed"); return 1; } } } ``` -------------------------------- ### Implement WIT host import in host.mjs Source: https://github.com/zion-sati/netwasm/blob/main/docs/wit-bindings.md Provides the JavaScript implementation of the transform host function. ```js export function transform(point) { return { tag: "value", val: point.x * 2 + point.y }; } ``` -------------------------------- ### createWasmToolsHost Source: https://github.com/zion-sati/netwasm/blob/main/src/NetWasm.Toolchain/Browser/Tools/README.md Creates a host for the pinned wasm-tools Preview 1 binary. It accepts owned byte maps and CLI arguments, and runs the tool with verified assets and a WASI shim. ```APIDOC ## createWasmToolsHost ### Description Creates a host for the pinned wasm-tools Preview 1 binary. It accepts owned byte maps and CLI arguments, and runs the tool with verified assets and a WASI shim. ### Method Factory function ### Parameters #### Options - **loadAsset** (function) - Required - Function that returns verified `Uint8Array` bytes for an asset name. - **wasiShim** (object) - Required - Verified Preview 1 WASI shim. - **limits** (object) - Optional - Configuration for bounds and memory limits. ### Returns - **wasmToolsHost** (object) - Host object with a `run` method. ### Example ```js const wasmTools = createWasmToolsHost({ loadAsset: verifiedLoader, wasiShim: verifiedPreview1Shim }); ``` ``` -------------------------------- ### Serve .mjs with correct MIME type using Python http.server Source: https://github.com/zion-sati/netwasm/blob/main/docs/javascript-interop.md Use this command to start a static server from the publish directory with the correct JavaScript MIME type for .mjs files. Required because browsers refuse to run module scripts served as anything else. On Windows, Python's http.server may send text/plain if the registry overrides the mapping. ```sh python -c "import http.server, mimetypes; mimetypes.add_type('text/javascript', '.mjs'); http.server.test(http.server.SimpleHTTPRequestHandler, port=8000)" ``` -------------------------------- ### Declare imports and exports with executeNetWasm Source: https://github.com/zion-sati/netwasm/blob/main/docs/javascript-interop.md Use this snippet to invoke a NetWasm deployment from a browser. It fetches the deployment manifest, computes its SHA-256 digest, and calls executeNetWasm with a request that grants randomness but denies network, clocks, environment variables, and filesystem mounts. The example requires a secure context (HTTPS or localhost) for crypto.subtle. On failure, the result's primaryFailure contains a stable code and message, with an optional detail field for host-caught errors. ```javascript import { executeNetWasm } from "./browser/netwasm.browser.mjs"; const bytes = await (await fetch("./browser/deployment.json")).arrayBuffer(); const manifest = JSON.parse(new TextDecoder().decode(bytes)); const digest = await crypto.subtle.digest("SHA-256", bytes); const sha256 = Array.from(new Uint8Array(digest), byte => byte.toString(16).padStart(2, "0")).join(""); const request = { schemaVersion: 1, buildFingerprint: manifest.buildFingerprint, deploymentManifestSha256: sha256, arguments: [], environment: [], grants: { environment: [], preopens: [], network: "denyAll", clocks: [], randomness: true, }, applicationImports: [], }; const sink = Object.freeze({ write(bytes) { console.log(new TextDecoder().decode(bytes)); }, }); const result = await executeNetWasm({ request, stdout: sink, stderr: sink, signal: null, }); if (result.primaryFailure !== null || result.exitCode !== 0) { throw new Error(JSON.stringify(result)); } ``` -------------------------------- ### Declare prebuilt WebAssembly archives with NativeLibrary items Source: https://github.com/zion-sati/netwasm/blob/main/src/NetWasm.Sdk/README.md Declares prebuilt WebAssembly archives for a project. All three fields are required: Include, NetWasmLibraryName, and WasmTarget. NetWasmLibraryName must match the logical import name exactly and does not need an .a suffix. Only regular .a archives are accepted. ```xml ``` -------------------------------- ### Build the C archive with Emscripten Source: https://github.com/zion-sati/netwasm/blob/main/docs/static-native-interop.md Compile sample.c to an object file and create the static archive libsample.a. Requires Emscripten activated; consumers of the prebuilt archive do not need it. ```sh source ~/emsdk/emsdk_env.sh emcc -Oz -c native/sample.c -o native/wasm32/sample.o emar rcs native/wasm32/libsample.a native/wasm32/sample.o ``` -------------------------------- ### Optimize Rust component with wasm-opt and wasm-tools Source: https://github.com/zion-sati/netwasm/blob/main/docs/size-and-methodology.md Builds the Rust core module with --skip-wit-component, optimizes it with wasm-opt -Oz --converge, re-encodes as a component, and strips custom sections. ```sh RUSTFLAGS="-C link-arg=--skip-wit-component" \ cargo +1.99.1 build --profile small --target wasm32-wasip2 --target-dir target-core wasm-opt -Oz --converge \ --enable-bulk-memory --enable-bulk-memory-opt --enable-call-indirect-overlong \ --enable-nontrapping-float-to-int --enable-sign-ext --enable-mutable-globals \ --enable-multivalue --enable-reference-types \ target-core/wasm32-wasip2/small/console42.wasm -o core.wasm wasm-tools component new core.wasm -o component.wasm wasm-tools strip --all component.wasm -o console42.wasm ``` -------------------------------- ### EntryPoint dispatch and helper methods Source: https://github.com/zion-sati/netwasm/blob/main/tests/NetWasm.Compiler.Tests/Correctness/Fixtures/math-boundary/Program.cs.txt Defines the entry point that dispatches to various math boundary contracts based on input. Includes helper methods for bitwise comparison and finite tolerance checks. ```csharp using System; namespace NetWasm.Correctness.MathBoundary; public static class EntryPoint { public static int Run(int input) => input switch { 1 => DoubleBoundaryContract(), 2 => TranscendentalContract(), 3 => SingleBoundaryContract(), 4 => IntegerExceptionContract(), 5 => Math.BigMul(int.MaxValue, int.MaxValue) == 4611686014132420609L ? 100 : 1, 6 => UnsignedBigMulContract(), 7 => DivRemContract(), 8 => FiniteComparisonContract(), 9 => FusedMultiplyAddContract(), _ => 0, }; public static int Trace() => 0; private static bool SameBits(double left, double right) => BitConverter.DoubleToInt64Bits(left) == BitConverter.DoubleToInt64Bits(right); private static bool SameBits(float left, float right) => BitConverter.SingleToInt32Bits(left) == BitConverter.SingleToInt32Bits(right); private static bool FiniteNear(double actual, double expected, double tolerance) => double.IsFinite(actual) && double.IsFinite(expected) && double.IsFinite(tolerance) && tolerance >= 0 && Math.Abs(actual - expected) <= tolerance; } ``` -------------------------------- ### Run netwasm-wit-bindgen with options Source: https://github.com/zion-sati/netwasm/blob/main/docs/wit-bindings.md Generates C# bindings from a WIT file for a specified world. Omit --world if only one world exists; --output - writes to stdout; --accessibility accepts public (default) or internal. ```sh dotnet netwasm-wit-bindgen \ --wit service.wit \ --world docs:bindings@1.0.0/service \ --output Bindings.g.cs \ --accessibility internal ``` -------------------------------- ### Project configuration for NativeLibrary Source: https://github.com/zion-sati/netwasm/blob/main/docs/static-native-interop.md Enables unsafe blocks and declares the native archive with the required NativeLibrary fields: Include, NetWasmLibraryName, and WasmTarget. The logical name 'sample' matches the LibraryImport name ordinally. ```xml true ``` -------------------------------- ### Regenerate bindings from materialized package Source: https://github.com/zion-sati/netwasm/blob/main/docs/wit-bindings.md Builds the project and regenerates bindings from the SDK's materialized WIT package, then publishes. ```sh dotnet build -c Release netwasm-wit-bindgen \ --wit obj/Release/netwasm0.1/netwasm/wasm32/wit-worker-source \ --world docs:bindings@1.0.0/service \ --output Bindings.g.cs --accessibility internal dotnet publish -c Release ``` -------------------------------- ### Configure AllowUnsafeBlocks and NativeLibrary for static native interop Source: https://github.com/zion-sati/netwasm/blob/main/docs/corelib-runtime.md Required MSBuild properties and item group for static native interop. Set AllowUnsafeBlocks to true for the LibraryImport source generator and declare the native library with all three fields: Include, NetWasmLibraryName, and WasmTarget. ```xml true ``` -------------------------------- ### Build and measure Rust wasm32-wasip2 artifacts Source: https://github.com/zion-sati/netwasm/blob/main/docs/size-and-methodology.md Builds the console42 project with Rust 1.90.0 and 1.99.1 using release and small profiles, then prints the sizes of the resulting .wasm files. ```sh cargo +1.90.0 build --release --target wasm32-wasip2 --target-dir target-190 cargo +1.99.1 build --release --target wasm32-wasip2 --target-dir target-199 cargo +1.99.1 build --profile small --target wasm32-wasip2 --target-dir target-199 wc -c target-190/wasm32-wasip2/release/console42.wasm wc -c target-199/wasm32-wasip2/release/console42.wasm wc -c target-199/wasm32-wasip2/small/console42.wasm ``` -------------------------------- ### Kotlin/Wasm compile and run commands Source: https://github.com/zion-sati/netwasm/blob/main/docs/size-and-methodology.md Compiles the Kotlin/Wasm project and runs the resulting WASI Preview 1 core module with wasmtime. The project uses Kotlin Multiplatform plugin 2.4.0 and Gradle 9.5.1. ```sh gradle --no-daemon compileProductionExecutableKotlinWasmWasi wasmtime run build/compileSync/wasmWasi/main/productionExecutable/kotlin/console42.wasm ``` -------------------------------- ### Run Console42 size canary script Source: https://github.com/zion-sati/netwasm/blob/main/eng/size-canary/README.md Compiles the Console.WriteLine(42) source with Release optimization, uses the current worktree's compiler, CoreLib, native runtime, and command WIT, packages an executable WASI Preview 2 component with -Oz, validates it, and checks that Wasmtime prints 42. The evidence directory must be new, absolute, and outside the source worktree. The final artifact is NetWasmApp.wasm. ```sh NETWASM_EMSDK_ROOT=/absolute/path/to/emsdk \ NETWASM_NODE_MODULES_ROOT=/absolute/path/to/node_modules \ bash eng/measure-console42-size.sh /absolute/new/evidence-directory ``` -------------------------------- ### Run the published browser application Source: https://github.com/zion-sati/netwasm/blob/main/docs/javascript-interop.md Imports the generated run() helper from the browser publish output and invokes it with an options object. The helper pins the deployment's build fingerprint and manifest digest; all options are optional. ```javascript import { run } from "./browser/App.mjs"; const result = await run({ stdout: line => document.querySelector("#output").append(line, "\n"), }); if (result.primaryFailure !== null || result.exitCode !== 0) { throw new Error(result.primaryFailure?.detail ?? result.primaryFailure?.message); } ``` -------------------------------- ### wwwroot/index.html for Blazor AOT app Source: https://github.com/zion-sati/netwasm/blob/main/docs/size-and-methodology.md HTML host page for the Blazor WebAssembly app. Includes the Blazor script reference with a fingerprint placeholder. ```html Blazor AOT 42
Loading
``` -------------------------------- ### Build Netwasm Runtime Source: https://github.com/zion-sati/netwasm/blob/main/docs/cli-build-deployment.md Builds the matching runtime from the compiler's layout using the eng/build-netwasm-runtime.sh script. Specify the runtime layout, target, configuration, and output paths. The output is a WebAssembly runtime file. ```sh eng/build-netwasm-runtime.sh \ --runtime-layout build/netwasm/runtime-layout.json \ --target wasm32 --configuration release \ --output build/netwasm/runtime.wasm ``` -------------------------------- ### Maintainer size measurement script Source: https://github.com/zion-sati/netwasm/blob/main/docs/size-and-methodology.md Runs the maintainer script from a source checkout with pinned tools to validate and execute collector comparison, recording sizes and hashes. Ordinary consumers use the SDK commands instead. ```sh bash eng/measure-console42-size.sh /absolute/new/evidence --compare-collectors ``` -------------------------------- ### Implement partial export method Source: https://github.com/zion-sati/netwasm/blob/main/docs/wit-bindings.md Application code implementing the generated partial method. Must be in the same namespace and class as the generated declaration. ```csharp namespace NetWasm.Wit.Docs.Bindings._1._0._0; internal static partial class ServiceExports { public static partial int Evaluate(int value) => value * 2; } ``` -------------------------------- ### Run method with static initialization cases Source: https://github.com/zion-sati/netwasm/blob/main/tests/NetWasm.Compiler.Tests/Correctness/Fixtures/flow-static-initialization/Program.cs.txt Test fixture for static initialization correctness. Each case exercises a different static initialization scenario, returning 42 on success or a negative error code on failure. Cases include static fields, generic statics, inheritance, recursion, cycles, exception handling, and allocation. ```csharp public static int Run(int input) { Probe.Count = 0; Probe.Order = 0; switch (input) { case 0: var first = Once.Next(); var second = Once.Next(); return first == 42 && second == 43 && Once.Value == 43 && Probe.Count == 1 ? 42 : -1; case 1: Closed.Value++; return Closed.Value == 42 && Closed.Value == 41 && Probe.Count == 2 && !ReferenceEquals(Closed.Identity, Closed.Identity) ? 42 : -2; case 2: Outer.Inner.Value++; return Outer.Inner.Value == 42 && Outer.Inner.Value == 41 && Outer.Inner.Value == 41 && Probe.Count == 3 ? 42 : -3; case 3: return DerivedDependency.Result == 42 && BaseDependency.Value == 40 && Probe.Order == 12 ? 42 : -4; case 4: return Recursive.Instance.Value == 42 && Probe.Count == 1 && ReferenceEquals(Recursive.Instance, Recursive.Instance) ? 42 : -5; case 5: return CycleA.Value == 42 && CycleB.Value == 20 && Probe.Order == 12 ? 42 : -6; case 6: for (var attempt = 0; attempt < 2; attempt++) { try { _ = Failing.Read(); return -7; } catch (Exception failure) { if (!IsOriginalFailure(failure)) return -8; } } return Probe.Count == 1 ? 42 : -9; case 7: return Relaxed.Value; case 8: var instance = new WithStatic { Number = 7 }; return WithStatic.Next() == 42 && WithStatic.Next() == 43 && instance.Number == 7 && Probe.Count == 1 ? 42 : -10; case 9: for (var attempt = 0; attempt < 2; attempt++) { try { _ = Failing.Read(); return -11; } catch (Exception failure) { if (!IsOriginalFailure(failure)) return -12; } try { _ = Failing.Read(); return -13; } catch (Exception failure) { if (!IsOriginalFailure(failure)) return -14; } } return Probe.Count == 2 ? 42 : -15; case 10: return Allocating.First.Value + Allocating.Second.Value == 42 && ReferenceEquals(Allocating.Second.Next, Allocating.First) && Probe.Count == 1 ? 42 : -16; default: throw new ArgumentOutOfRangeException(nameof(input)); } } } ``` -------------------------------- ### Expected output Source: https://github.com/zion-sati/netwasm/blob/main/README.md The output of running the published component is the number 42. ```text 42 ``` -------------------------------- ### Expected output Source: https://github.com/zion-sati/netwasm/blob/main/docs/static-native-interop.md The printed output from running the application: 42 and 41. ```text 42 41 ```