Skip to content

Commit e234871

Browse files
committed
fix(csharp): componentize map runtime with harness metadata
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
1 parent c0d980f commit e234871

7 files changed

Lines changed: 42 additions & 123 deletions

File tree

Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/csharp/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ test = false
2323
wit-bindgen-core = { workspace = true }
2424
wit-component = { workspace = true }
2525
wit-parser = { workspace = true }
26-
wasm-encoder = { workspace = true }
2726
wasm-metadata = { workspace = true }
2827
heck = { workspace = true }
2928
clap = { workspace = true, optional = true }

crates/csharp/src/csproj.rs

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use anyhow::Result;
22
use std::{fs, path::PathBuf};
33

4-
use heck::{ToSnakeCase, ToUpperCamelCase};
4+
use heck::ToUpperCamelCase;
55

66
pub struct CSProject;
77

@@ -12,7 +12,7 @@ pub struct CSProjectLLVMBuilder {
1212
clean_targets: bool,
1313
world_name: String,
1414
binary: bool,
15-
component_type_object: bool,
15+
skip_wit_component: bool,
1616
}
1717

1818
pub struct CSProjectMonoBuilder {
@@ -32,7 +32,7 @@ impl CSProject {
3232
clean_targets: false,
3333
world_name: world_name.to_string(),
3434
binary: false,
35-
component_type_object: false,
35+
skip_wit_component: false,
3636
}
3737
}
3838

@@ -71,21 +71,8 @@ impl CSProjectLLVMBuilder {
7171
"<OutputType>Library</OutputType>"
7272
};
7373

74-
let component_type_define = if self.component_type_object {
75-
"<DefineConstants>$(DefineConstants);WIT_BINDGEN_COMPONENT_TYPE_OBJECT</DefineConstants>"
76-
} else {
77-
""
78-
};
79-
80-
let component_type_linker_arg = if self.component_type_object {
81-
let linking_symbol = format!(
82-
"__component_type_object_force_link_{}",
83-
self.world_name.to_snake_case()
84-
);
85-
format!(
86-
"<NativeFileReference Include=\"{camel}_component_type.o\" />\n\
87-
<CustomLinkerArg Include=\"-Wl,--undefined={linking_symbol}\" />"
88-
)
74+
let component_type_linker_arg = if self.skip_wit_component {
75+
"<CustomLinkerArg Include=\"-Wl,--skip-wit-component\" />".to_string()
8976
} else {
9077
format!(
9178
"<CustomLinkerArg Include=\"-Wl,--component-type,{camel}_component_type.wit\" />"
@@ -105,7 +92,6 @@ impl CSProjectLLVMBuilder {
10592
<!-- treat these are errors so they are caught during code generation tests -->
10693
<WarningsAsErrors>CS0105</WarningsAsErrors>
10794
{output_type}
108-
{component_type_define}
10995
</PropertyGroup>
11096
11197
<PropertyGroup>
@@ -202,8 +188,8 @@ impl CSProjectLLVMBuilder {
202188
self.binary = true;
203189
}
204190

205-
pub fn component_type_object(&mut self) {
206-
self.component_type_object = true;
191+
pub fn skip_wit_component(&mut self) {
192+
self.skip_wit_component = true;
207193
}
208194

209195
pub fn clean(&mut self) -> &mut Self {

crates/csharp/src/world_generator.rs

Lines changed: 1 addition & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,12 @@ use crate::csharp_ident::ToCSharpIdent;
22
use crate::function::ResourceInfo;
33
use crate::interface::{InterfaceFragment, InterfaceGenerator, InterfaceTypeAndFragments};
44
use crate::{CSharpRuntime, Opts};
5-
use heck::{ToSnakeCase, ToUpperCamelCase};
5+
use heck::ToUpperCamelCase;
66
use indexmap::IndexMap;
77
use std::collections::{HashMap, HashSet};
88
use std::fmt::Write;
99
use std::ops::Deref;
1010
use std::{iter, mem};
11-
use wasm_encoder::{
12-
CodeSection, CustomSection, Function as WasmFunction, FunctionSection, LinkingSection, Module,
13-
SymbolTable, TypeSection,
14-
};
1511
use wit_bindgen_core::{Direction, Files, InterfaceGenerator as _, Types, WorldGenerator, uwrite};
1612
use wit_component::WitPrinter;
1713
use wit_parser::abi::WasmType;
@@ -861,43 +857,6 @@ impl WorldGenerator for CSharp {
861857
&format!("{world_namespace}_component_type.wit"),
862858
String::from(printer.output).as_bytes(),
863859
);
864-
files.push(
865-
&format!("{world_namespace}_component_type.o"),
866-
component_type_object(
867-
&resolve,
868-
world,
869-
&resolve.worlds[world].name,
870-
self.opts.string_encoding,
871-
)?
872-
.as_slice(),
873-
);
874-
let linking_symbol = format!(
875-
"__component_type_object_force_link_{}",
876-
resolve.worlds[world].name.to_snake_case()
877-
);
878-
files.push(
879-
&format!("{world_namespace}_component_type_force_link.cs"),
880-
indent(&format!(
881-
r#"
882-
#if WIT_BINDGEN_COMPONENT_TYPE_OBJECT
883-
namespace {world_namespace};
884-
885-
internal static partial class ComponentTypeObjectForceLink
886-
{{
887-
[global::System.Runtime.InteropServices.DllImport("__Internal", EntryPoint = "{linking_symbol}")]
888-
private static extern void ForceLink();
889-
890-
[global::System.Runtime.CompilerServices.ModuleInitializer]
891-
internal static void Initialize()
892-
{{
893-
ForceLink();
894-
}}
895-
}}
896-
#endif
897-
"#
898-
))
899-
.as_bytes(),
900-
);
901860
}
902861

903862
// TODO: remove when we switch to dotnet 9
@@ -1158,58 +1117,6 @@ fn by_resource<'a>(
11581117
by_resource
11591118
}
11601119

1161-
fn component_type_object(
1162-
resolve: &Resolve,
1163-
world: WorldId,
1164-
world_name: &str,
1165-
encoding: wit_component::StringEncoding,
1166-
) -> anyhow::Result<Vec<u8>> {
1167-
let mut module = Module::new();
1168-
1169-
let mut types = TypeSection::new();
1170-
types.ty().function([], []);
1171-
module.section(&types);
1172-
1173-
let mut funcs = FunctionSection::new();
1174-
funcs.function(0);
1175-
module.section(&funcs);
1176-
1177-
let mut code = CodeSection::new();
1178-
let mut func = WasmFunction::new([]);
1179-
func.instruction(&wasm_encoder::Instruction::End);
1180-
code.function(&func);
1181-
module.section(&code);
1182-
1183-
let mut producers = wasm_metadata::Producers::empty();
1184-
producers.add(
1185-
"processed-by",
1186-
env!("CARGO_PKG_NAME"),
1187-
env!("CARGO_PKG_VERSION"),
1188-
);
1189-
let data = wit_component::metadata::encode(resolve, world, encoding, Some(&producers))?;
1190-
let section_name = format!("component-type:{world_name}");
1191-
1192-
module.section(&CustomSection {
1193-
name: std::borrow::Cow::Borrowed(&section_name),
1194-
data: std::borrow::Cow::Borrowed(data.as_slice()),
1195-
});
1196-
1197-
let mut linking = LinkingSection::new();
1198-
let mut symbols = SymbolTable::new();
1199-
symbols.function(
1200-
0,
1201-
0,
1202-
Some(&format!(
1203-
"__component_type_object_force_link_{}",
1204-
world_name.to_snake_case()
1205-
)),
1206-
);
1207-
linking.symbol_table(&symbols);
1208-
module.section(&linking);
1209-
1210-
Ok(module.finish())
1211-
}
1212-
12131120
#[cfg(test)]
12141121
mod tests {
12151122
use super::*;

crates/test/src/csharp.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub struct Csharp;
1212
#[derive(Default, Deserialize)]
1313
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
1414
struct LangConfig {
15-
component_type_object: bool,
15+
skip_wit_component: bool,
1616
}
1717

1818
fn dotnet() -> Command {
@@ -83,8 +83,8 @@ impl LanguageMethods for Csharp {
8383
let mut csproj =
8484
wit_bindgen_csharp::CSProject::new(test_dir.to_path_buf(), &assembly_name, world_name);
8585
csproj.aot();
86-
if config.component_type_object {
87-
csproj.component_type_object();
86+
if config.skip_wit_component {
87+
csproj.skip_wit_component();
8888
}
8989
csproj.generate()?;
9090

@@ -120,7 +120,11 @@ impl LanguageMethods for Csharp {
120120

121121
runner.run_command(&mut cmd)?;
122122

123-
fs::copy(&wasm_filename, &compile.output)?;
123+
if config.skip_wit_component {
124+
runner.convert_p1_to_component_appending_type_metadata(&wasm_filename, compile)?;
125+
} else {
126+
fs::copy(&wasm_filename, &compile.output)?;
127+
}
124128

125129
Ok(())
126130
}

crates/test/src/lib.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1081,14 +1081,38 @@ status: {}",
10811081
///
10821082
/// Stores the output at `compile.output`.
10831083
fn convert_p1_to_component(&self, p1: &Path, compile: &Compile<'_>) -> Result<()> {
1084+
self.convert_p1_to_component_impl(p1, compile, false)
1085+
}
1086+
1087+
/// Converts the WASIp1 module at `p1` to a component, appending component
1088+
/// type metadata from the test WIT even if existing metadata is present.
1089+
///
1090+
/// Some toolchains emit incomplete or stale component type metadata even
1091+
/// when asked to skip componentization, while still needing their own
1092+
/// metadata for WASI imports. Use this when the test harness must add
1093+
/// guest-world metadata without discarding toolchain metadata.
1094+
fn convert_p1_to_component_appending_type_metadata(
1095+
&self,
1096+
p1: &Path,
1097+
compile: &Compile<'_>,
1098+
) -> Result<()> {
1099+
self.convert_p1_to_component_impl(p1, compile, true)
1100+
}
1101+
1102+
fn convert_p1_to_component_impl(
1103+
&self,
1104+
p1: &Path,
1105+
compile: &Compile<'_>,
1106+
append_component_type: bool,
1107+
) -> Result<()> {
10841108
let mut resolve = wit_parser::Resolve::default();
10851109
let (pkg, _) = resolve
10861110
.push_path(&compile.component.bindgen.wit_path)
10871111
.context("failed to load WIT")?;
10881112
let world = resolve.select_world(&[pkg], Some(&compile.component.bindgen.world))?;
10891113
let mut module = fs::read(&p1).context("failed to read wasm file")?;
10901114

1091-
if !has_component_type_sections(&module) {
1115+
if append_component_type || !has_component_type_sections(&module) {
10921116
let encoded =
10931117
wit_component::metadata::encode(&resolve, world, StringEncoding::UTF8, None)?;
10941118
let section = wasm_encoder::CustomSection {

tests/runtime/map/test.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//@ wasmtime-flags = '-Wcomponent-model-map'
22
//@ [lang]
3-
//@ component-type-object = true
3+
//@ skip-wit-component = true
44

55
using System.Diagnostics;
66
using System.Text;

0 commit comments

Comments
 (0)