Skip to content

Commit

Permalink
Add csharp feature
Browse files Browse the repository at this point in the history
  • Loading branch information
yowl committed Oct 23, 2023
1 parent 987cbab commit 51e29f5
Show file tree
Hide file tree
Showing 8 changed files with 1,939 additions and 0 deletions.
15 changes: 15 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ wit-bindgen-c = { path = 'crates/c', version = '0.13.0' }
wit-bindgen-rust = { path = "crates/rust", version = "0.13.0" }
wit-bindgen-teavm-java = { path = 'crates/teavm-java', version = '0.13.0' }
wit-bindgen-go = { path = 'crates/go', version = '0.13.0' }
wit-bindgen-csharp = { path = 'crates/csharp', version = '0.13.0' }
wit-bindgen-markdown = { path = 'crates/markdown', version = '0.13.0' }
wit-bindgen = { path = 'crates/guest-rust', version = '0.13.0', default-features = false }
wit-bindgen-rust-macro-shared = { path = 'crates/rust-macro-shared', version = '0.3.0' }
Expand All @@ -55,6 +56,7 @@ wit-bindgen-c = { workspace = true, features = ['clap'], optional = true }
wit-bindgen-markdown = { workspace = true, features = ['clap'], optional = true }
wit-bindgen-teavm-java = { workspace = true, features = ['clap'], optional = true }
wit-bindgen-go = { workspace = true, features = ['clap'], optional = true }
wit-bindgen-csharp = { workspace = true, features = ['clap'], optional = true }
wit-component = { workspace = true }
wasm-encoder = { workspace = true }
wasmtime-wasi = { workspace = true }
Expand All @@ -66,12 +68,14 @@ default = [
'markdown',
'teavm-java',
'go',
'csharp',
]
c = ['dep:wit-bindgen-c']
rust = ['dep:wit-bindgen-rust']
markdown = ['dep:wit-bindgen-markdown']
teavm-java = ['dep:wit-bindgen-teavm-java']
go = ['dep:wit-bindgen-go']
csharp = ['dep:wit-bindgen-csharp']

[dev-dependencies]
heck = { workspace = true }
Expand Down
28 changes: 28 additions & 0 deletions crates/csharp/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[package]
name = "wit-bindgen-csharp"
authors = ["Timmy Silesmo <[email protected]>"]
version = "0.13.0"
edition.workspace = true
repository = 'https://github.com/bytecodealliance/wit-bindgen'
license = "Apache-2.0 WITH LLVM-exception"
homepage = 'https://github.com/bytecodealliance/wit-bindgen'
description = """
C# bindings generator for WIT and the component model, typically used
through the `wit-bindgen-cli` crate.
"""

[lib]
doctest = false
test = false

[dependencies]
wasm-encoder = { workspace = true }
wit-bindgen-core = { workspace = true }
wit-component = { workspace = true }
wasm-metadata = { workspace = true }
heck = { workspace = true }
clap = { workspace = true, optional = true }
anyhow = { workspace = true }

[dev-dependencies]
test-helpers = { path = '../test-helpers' }
3 changes: 3 additions & 0 deletions crates/csharp/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// generate the c# and the component meta module

cargo run c-sharp --string-encoding utf8 --out-dir testing-csharp tests/codegen/floats.wit
58 changes: 58 additions & 0 deletions crates/csharp/src/component_type_object.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use anyhow::Result;
use heck::ToSnakeCase;
use wasm_encoder::{
CodeSection, CustomSection, Function, FunctionSection, LinkingSection, Module, SymbolTable,
TypeSection,
};
use wit_bindgen_core::wit_parser::{Resolve, WorldId};
use wit_component::StringEncoding;

pub fn linking_symbol(name: &str) -> String {
let snake = name.to_snake_case();
format!("__component_type_object_force_link_{snake}")
}

pub fn object(resolve: &Resolve, world: WorldId, encoding: StringEncoding) -> Result<Vec<u8>> {
let mut module = Module::new();

// Build a module with one function that's a "dummy function"
let mut types = TypeSection::new();
types.function([], []);
module.section(&types);
let mut funcs = FunctionSection::new();
funcs.function(0);
module.section(&funcs);
let mut code = CodeSection::new();
code.function(&Function::new([]));
module.section(&code);

let mut producers = wasm_metadata::Producers::empty();
producers.add(
"processed-by",
env!("CARGO_PKG_NAME"),
env!("CARGO_PKG_VERSION"),
);
let data = wit_component::metadata::encode(resolve, world, encoding, Some(&producers)).unwrap();

// The custom section name here must start with "component-type" but
// otherwise is attempted to be unique here to ensure that this doesn't get
// concatenated to other custom sections by LLD by accident since LLD will
// concatenate custom sections of the same name.
let world_name = &resolve.worlds[world].name;
let section_name = format!("component-type:{world_name}");

// Add our custom section
module.section(&CustomSection {
name: std::borrow::Cow::Borrowed(&section_name),
data: std::borrow::Cow::Borrowed(data.as_slice()),
});

// Append the linking section, so that lld knows the custom section's symbol name
let mut linking = LinkingSection::new();
let mut symbols = SymbolTable::new();
symbols.function(0, 0, Some(&linking_symbol(&world_name)));
linking.symbol_table(&symbols);
module.section(&linking);

Ok(module.finish())
}
Loading

0 comments on commit 51e29f5

Please sign in to comment.