{"id":24165976,"url":"https://github.com/jonathanvdc/cs-wasm","last_synced_at":"2025-10-14T20:13:22.786Z","repository":{"id":88519309,"uuid":"85337974","full_name":"jonathanvdc/cs-wasm","owner":"jonathanvdc","description":"A C# library that can read, write, interpret and assemble WebAssembly files.","archived":false,"fork":false,"pushed_at":"2020-01-05T21:52:57.000Z","size":519,"stargazers_count":46,"open_issues_count":3,"forks_count":6,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-10-14T20:13:19.584Z","etag":null,"topics":["csharp","dotnet","wasm","webassembly"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jonathanvdc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-03-17T17:30:04.000Z","updated_at":"2025-09-30T15:25:52.000Z","dependencies_parsed_at":null,"dependency_job_id":"cccf6ddb-1661-4a0a-8a45-48459d87c7b6","html_url":"https://github.com/jonathanvdc/cs-wasm","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/jonathanvdc/cs-wasm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonathanvdc%2Fcs-wasm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonathanvdc%2Fcs-wasm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonathanvdc%2Fcs-wasm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonathanvdc%2Fcs-wasm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jonathanvdc","download_url":"https://codeload.github.com/jonathanvdc/cs-wasm/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonathanvdc%2Fcs-wasm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279021005,"owners_count":26086946,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-14T02:00:06.444Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","dotnet","wasm","webassembly"],"created_at":"2025-01-12T20:13:27.825Z","updated_at":"2025-10-14T20:13:22.764Z","avatar_url":"https://github.com/jonathanvdc.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `cs-wasm`\n\n[![Build status](https://travis-ci.org/jonathanvdc/cs-wasm.svg?branch=master)](https://travis-ci.org/jonathanvdc/cs-wasm)\n[![Build status](https://ci.appveyor.com/api/projects/status/4lfpgydcssxvr56o?svg=true)](https://ci.appveyor.com/project/jonathanvdc/cs-wasm)\n[![NuGet](https://img.shields.io/nuget/v/Wasm.svg)](https://www.nuget.org/packages/Wasm)\n\n`cs-wasm` is a C# library that can read, write, interpret and optimize binary WebAssembly files.\n\nIt tries to represent WebAssembly files as faithfully as possible; reading a file into memory and writing it back to disk is byte-for-byte equivalent to a simple copy.\n\n## Setting up `cs-wasm`\n\nInstalling `cs-wasm` is easy. Just add a dependency on the [**Wasm** NuGet package](https://www.nuget.org/packages/Wasm) and you'll be all set.\n\n## Using `cs-wasm`\n\nHere are some sample code fragments to give you a feel of what it's like to use `cs-wasm`.\n\n### Reading a WebAssembly file\n\nReading binary WebAssembly files is pretty easy. All we have to do is call a `WasmFile.ReadBinaryFrom` overload, like so:\n\n```cs\nusing Wasm;\n// ...\nWasmFile file = WasmFile.ReadBinaryFrom(path);\n// - or -\nfile = WasmFile.ReadBinaryFrom(stream);\n```\n\n### Writing a `WasmFile` to disk\n\nGiven a `WasmFile` stored in a variable `file`, we can just:\n\n```cs\nusing Wasm;\n// ...\nWasmFile file;\n// file = ...;\nfile.WriteBinaryTo(path);\n// - or -\nfile.WriteBinaryTo(stream);\n```\n\n### Inspecting a `WasmFile`\n\n`WasmFile` is modeled after the binary encoding for WebAssembly files. It contains a `Sections` property that returns a `List\u003cSection\u003e` which can be iterated through.\n\nIf you're interested in a specific type of section, then you can use the `GetSections`/`GetFirstSectionOrNull` methods defined by `WasmFile`. (Or you can just throw LINQ at the `Sections` list \u0026ndash; it's up to you.)\n\nFor example, the following example prints the size of a WebAssembly file's linear memory, assuming that `file` defines a memory section which contains exactly one linear memory definition.\n\n```cs\nusing System.Linq;\nusing Wasm;\n// ...\nWasmFile file;\n// file = ...;\nConsole.WriteLine(\n    \"Memory size: {0}\",\n    file.GetFirstSectionOrNull\u003cMemorySection\u003e()\n        .Memories\n        .Single\u003cMemoryType\u003e()\n        .Limits);\n```\n\n### Modifying a `WasmFile`\n\nMost reference types (aka `class` types) in `cs-wasm` are mutable. So, to change the size of a `WasmFile`'s linear memory to exactly one page, i.e., 64KiB, we can do the following.\n\n```cs\nusing System.Linq;\nusing Wasm;\n// ...\nWasmFile file;\n// file = ...;\nvar memSection = file.GetFirstSectionOrNull\u003cMemorySection\u003e();\nif (memSection == null)\n{\n    // The file doesn't specify a memory section, so we'll\n    // have to create one and add it to the file.\n    memSection = new MemorySection();\n    file.Sections.Add(memSection);\n}\nmemSection.Memories.Clear();\n// Memory sizes are specified in WebAssembly pages,\n// which are regions of storage with size 64KiB.\n// `new ResizableLimits(1, 1)` creates a memory description\n// that is initially one page (first argument) in size and\n// is capped at one page of memory (second argument), so\n// there will always be exactly one page of linear memory.\nmemSection.Memories.Add(\n    new MemoryType(new ResizableLimits(1, 1))); \n```\n\n### Creating a `WasmFile` from scratch\n\nThis one's easy. `WasmFile`'s parameterless constructor creates the bare-minimum WebAssembly module: it has an eight-byte header and nothing more.\n\n```cs\nusing Wasm;\n// ...\n// Create a WebAssembly file.\nvar file = new WasmFile();\n```\n\nWe may want to add some sections to our newly-created file now. The example from the previous section adds a memory section to a file if it doesn't exist already. Other kinds of sections can be added similarly. For instance, the following code adds a type section to `file`.\n\n```cs\n// Define a type section.\nvar typeSection = new TypeSection();\nfile.Sections.Add(typeSection);\n```\n\n### Interpreting a `WasmFile`\n\nTo interpret a WebAssembly file, you first need to instantiate it.\n\n```cs\nusing Wasm.Interpret;\n// ...\nModuleInstance module = ModuleInstance.Instantiate(wasmFile, importer);\n```\n\nNotice the `importer` argument there? That's the object from which a `ModuleInstance` can import functions, memories, global variables and tables. An `importer` must implement `IImporter`. You don't have to implement `IImporter` yourself if you don't feel like it, though: `PredefinedImporter` is perfectly adequate for most purposes:\n\n```cs\nusing System;\nusing Wasm.Interpret;\n// ...\nIReadOnlyList\u003cobject\u003e Print(IReadOnlyList\u003cobject\u003e Values)\n{\n    Console.WriteLine(Values[0]);\n    return new object[0];\n}\n// ...\n// Create an importer.\nvar importer = new PredefinedImporter();\n// Define a function called 'print_i32' that takes an i32 and\n// returns nothing.\nimporter.DefineFunction(\n    \"print_i32\",\n    new DelegateFunctionDefinition(\n        new WasmValueType[] { WasmValueType.Int32 },\n        new WasmValueType[] { },\n        Print));\n// Instantiate the module.\nModuleInstance module = ModuleInstance.Instantiate(wasmFile, importer);\n```\n\nOnce instantiated, you can access the module's functions, memories, global variables and tables, exported or otherwise. To run an exported function named `factorial` and print the result:\n\n```cs\nFunctionDefinition funcDef = module.ExportedFunctions[\"factorial\"];\nIReadOnlyList\u003cobject\u003e results = funcDef.Invoke(new object[] { 10L });\nConsole.WriteLine(\"Return value: {0}\", results[0]);\n```\n\nAlternatively, you might want to run the WebAssembly file's entry point. `ModuleInstance` does not expose an entry point directly, but it's easy enough to find it by examining the 'start' section of the `WasmFile` on which the `ModuleInstance` is based.\n\n```cs\nvar startSec = wasmFile.GetFirstSectionOrNull\u003cStartSection\u003e();\nFunctionDefinition mainFunc = module.Functions[(int)startSec.StartFunctionIndex];\nmainFunc.Invoke(new object[] { });\n```\n\n### Optimizing a `WasmFile`\n\n`cs-wasm` offers some basic optimizations for WebAssembly files. These optimizations include:\n\n  * removing duplicate type table entries,\n  * merging function body local entries, and\n  * peephole optimizations for function body instructions.\n\nThese optimizations are mainly intended for people who want to manipulate/generate decent-looking WebAssembly files without jumping through too many hoops.\n\nApplying all optimizations that ship with `cs-wasm` is a one-liner (not counting the lines that were added for context):\n\n```cs\nusing Wasm.Optimize;\n// ...\nWasmFile file;\n// file = ...;\nfile.Optimize();\n```\n\n### Assembling a text format file\n\nThe `cs-wasm` project includes an additional library\u0026mdash;`Wasm.Text`, available as [a separate NuGet package](https://www.nuget.org/packages/Wasm.Text)\u0026mdash;that can assemble WebAssembly text format files and scripts. To assemble a string of textual WebAssembly, add a dependency on that library and do the following:\n```cs\nusing Wasm.Text;\nusing Pixie.Terminal;\n// ...\nvar log = TerminalLog.Acquire();\nWasmFile file = new Assembler(log).AssembleModule(\"(module)\");\n```\n\nThe resulting `WasmFile` can be manipulated in all the same ways that a regular `WasmFile` parsed from a binary module can.\n\n### Other fun stuff\n\nThere are lots of things you can do with `cs-wasm`. Drop me a GitHub issue if you'd like a chat.\n\n## Contributing\n\nWant to help out? Thanks! That's awesome! You're very welcome to open an issue or send a pull request.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonathanvdc%2Fcs-wasm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjonathanvdc%2Fcs-wasm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonathanvdc%2Fcs-wasm/lists"}