Skip to content

Commit c3fce61

Browse files
committed
C#
Move export and import types to respective classes. Capitilase import and export Add initial future support
1 parent b6537dc commit c3fce61

File tree

47 files changed

+1231
-486
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1231
-486
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/**
2+
* Helpers for future support.
3+
*/
4+
5+
public readonly struct WaitableStatus (int status)
6+
{
7+
public int State => status & 0xf;
8+
public int Count => (int)(status >> 4);
9+
public bool IsBlocked => status == -1;
10+
public bool IsCompleted => State == 0;
11+
public bool IsDropped => State == 1;
12+
}
13+
14+
public enum EventCode
15+
{
16+
None,
17+
Subtask,
18+
StreamRead,
19+
StreamWrite,
20+
FutureRead,
21+
FutureWrite,
22+
Cancel,
23+
}
24+
25+
public readonly struct EventWaitable
26+
{
27+
public EventWaitable(EventCode eventCode, int waitable, int code)
28+
{
29+
Event = eventCode;
30+
Waitable = waitable;
31+
Status = new WaitableStatus(code);
32+
}
33+
public readonly EventCode Event;
34+
public readonly int Waitable;
35+
public readonly int Code;
36+
37+
public readonly WaitableStatus Status;
38+
}
39+
40+
public partial class WaitableSet(int handle) : IDisposable
41+
{
42+
public int Handle { get; } = handle;
43+
44+
void Dispose(bool _disposing)
45+
{
46+
{{interop_name}}.WaitableSetDrop(Handle);
47+
}
48+
49+
public void Dispose()
50+
{
51+
Dispose(true);
52+
GC.SuppressFinalize(this);
53+
}
54+
55+
~WaitableSet()
56+
{
57+
Dispose(false);
58+
}
59+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* Helpers for future reader support.
3+
*/
4+
5+
public abstract class FutureReader(int handle) : IDisposable // : TODO Waitable
6+
{
7+
public int Handle { get; } = handle;
8+
9+
// TODO: Generate per type for this instrinsic.
10+
public Task Read()
11+
{
12+
// TODO: Generate for the interop name and the namespace.
13+
14+
var status = new WaitableStatus(ReadInternal());
15+
if (status.IsBlocked)
16+
{
17+
//TODO: store somewhere so we can complete it later.
18+
var tcs = new TaskCompletionSource();
19+
20+
return tcs.Task;
21+
}
22+
if (status.IsCompleted)
23+
{
24+
return Task.CompletedTask;
25+
}
26+
27+
throw new NotImplementedException();
28+
}
29+
30+
void Dispose(bool _disposing)
31+
{
32+
// Free unmanaged resources if any.
33+
Drop();
34+
}
35+
36+
public void Dispose()
37+
{
38+
Dispose(true);
39+
GC.SuppressFinalize(this);
40+
}
41+
42+
~FutureReader()
43+
{
44+
Dispose(false);
45+
}
46+
47+
protected abstract int ReadInternal();
48+
protected abstract void Drop();
49+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* Helpers for future writer support.
3+
*/
4+
5+
public abstract class FutureWriter(int handle) // : TODO Waitable
6+
{
7+
public int Handle { get; } = handle;
8+
9+
// TODO: Generate per type for this instrinsic.
10+
public Task Write()
11+
{
12+
// TODO: Generate for the interop name.
13+
var status = new WaitableStatus(Write(Handle, IntPtr.Zero));
14+
if (status.IsBlocked)
15+
{
16+
//TODO: store somewhere so we can complete it later.
17+
var tcs = new TaskCompletionSource();
18+
return tcs.Task;
19+
}
20+
21+
throw new NotImplementedException();
22+
}
23+
24+
protected abstract void Drop();
25+
26+
void Dispose(bool _disposing)
27+
{
28+
// Free unmanaged resources if any.
29+
Drop();
30+
}
31+
32+
public void Dispose()
33+
{
34+
Dispose(true);
35+
GC.SuppressFinalize(this);
36+
}
37+
38+
~FutureWriter()
39+
{
40+
Dispose(false);
41+
}
42+
43+
protected abstract int Write(int handle, IntPtr buffer);
44+
}

crates/csharp/src/csproj.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,10 @@ impl CSProjectLLVMBuilder {
109109
csproj.push_str(
110110
&format!(
111111
r#"
112-
<ItemGroup>
113-
<PackageReference Include="Microsoft.DotNet.ILCompiler.LLVM" Version="10.0.0-*" />
114-
<PackageReference Include="runtime.{os}-x64.Microsoft.DotNet.ILCompiler.LLVM" Version="10.0.0-*" />
115-
</ItemGroup>
116-
"#),
112+
<ItemGroup>
113+
<PackageReference Include="Microsoft.DotNet.ILCompiler.LLVM" Version="10.0.0-*" />
114+
<PackageReference Include="runtime.{os}-x64.Microsoft.DotNet.ILCompiler.LLVM" Version="10.0.0-*" />
115+
</ItemGroup>"#),
117116
);
118117

119118
fs::write(
@@ -153,8 +152,9 @@ impl CSProjectLLVMBuilder {
153152
}
154153

155154
csproj.push_str(
156-
r#"</Project>
157-
"#,
155+
r#"
156+
</Project>
157+
"#,
158158
);
159159

160160
fs::write(self.dir.join(format!("{camel}.csproj")), csproj)?;

crates/csharp/src/function.rs

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pub(crate) struct FunctionBindgen<'a, 'b> {
3333
fixed_statments: Vec<Fixed>,
3434
parameter_type: ParameterType,
3535
result_type: Option<Type>,
36+
pub(crate) resource_type_name: Option<String>,
3637
}
3738

3839
impl<'a, 'b> FunctionBindgen<'a, 'b> {
@@ -70,6 +71,7 @@ impl<'a, 'b> FunctionBindgen<'a, 'b> {
7071
fixed_statments: Vec::new(),
7172
parameter_type: parameter_type,
7273
result_type: result_type,
74+
resource_type_name: None,
7375
}
7476
}
7577

@@ -1062,9 +1064,32 @@ impl Bindgen for FunctionBindgen<'_, '_> {
10621064
None => operands.join(", "),
10631065
};
10641066

1067+
let (_namespace, interface_name) =
1068+
&CSharp::get_class_name_from_qualified_name(self.interface_gen.name);
1069+
let mut interop_name = format!("{}ImportsInterop", interface_name.strip_prefix("I").unwrap()
1070+
.strip_suffix(if self.interface_gen.direction == Direction::Import { "Imports" } else { "Exports" }).unwrap().to_upper_camel_case());
1071+
1072+
if self.interface_gen.is_world && self.interface_gen.direction == Direction::Import {
1073+
interop_name = format!("Imports.{interop_name}");
1074+
}
1075+
1076+
let resource_type_name = match self.kind {
1077+
FunctionKind::Method(resource_type_id) |
1078+
FunctionKind::Static(resource_type_id) |
1079+
FunctionKind::Constructor(resource_type_id) => {
1080+
format!(
1081+
".{}",
1082+
self.interface_gen.csharp_gen.all_resources[resource_type_id]
1083+
.name
1084+
.to_upper_camel_case()
1085+
)
1086+
}
1087+
_ => String::new(),
1088+
};
1089+
10651090
uwriteln!(
10661091
self.src,
1067-
"{assignment} {func_name}WasmInterop.wasmImport{func_name}({operands});"
1092+
"{assignment} {interop_name}{resource_type_name}.{func_name}WasmInterop.wasmImport{func_name}({operands});"
10681093
);
10691094

10701095
if let Some(buffer) = async_return_buffer {
@@ -1364,6 +1389,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
13641389
} else {
13651390
uwriteln!(self.src, "var {resource} = ({export_name}) {export_name}.repTable.Get({op});");
13661391
}
1392+
self.resource_type_name = Some(export_name);
13671393
}
13681394
}
13691395
results.push(resource);
@@ -1375,15 +1401,27 @@ impl Bindgen for FunctionBindgen<'_, '_> {
13751401

13761402
Instruction::FutureLower { .. } => {
13771403
let op = &operands[0];
1404+
self.interface_gen.add_future(self.func_name);
1405+
13781406
results.push(format!("{op}.Handle"));
13791407
}
13801408

13811409
Instruction::AsyncTaskReturn { name: _, params: _ } => {
13821410
uwriteln!(self.src, "// TODO_task_cancel.forget();");
13831411
}
13841412

1385-
Instruction::FutureLift { .. }
1386-
| Instruction::StreamLower { .. }
1413+
Instruction::FutureLift { payload: _, ty: _ } => {
1414+
// TODO get the prefix for the type
1415+
let sig_type_name = "Void";
1416+
uwriteln!(self.src, "var reader = new {}.FutureReader{}({});", self.interface_gen.name, sig_type_name, operands[0]);
1417+
self.interface_gen.csharp_gen.needs_future_reader_support = true;
1418+
results.push("reader".to_string());
1419+
1420+
self.interface_gen.add_future(self.func_name);
1421+
self.interface_gen.csharp_gen.needs_future_reader_support = true;
1422+
}
1423+
1424+
Instruction::StreamLower { .. }
13871425
| Instruction::StreamLift { .. }
13881426
| Instruction::ErrorContextLower { .. }
13891427
| Instruction::ErrorContextLift { .. }
@@ -1418,7 +1456,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
14181456
uwrite!(
14191457
self.src,
14201458
"
1421-
var {ret_area} = stackalloc {element_type}[{array_size}+1];
1459+
var {ret_area} = stackalloc {element_type}[{array_size} + 1];
14221460
var {ptr} = ((int){ret_area}) + ({align} - 1) & -{align};
14231461
",
14241462
align = align.align_wasm32()
@@ -1487,7 +1525,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
14871525
}
14881526

14891527
/// Dereference any number `TypeDefKind::Type` aliases to retrieve the target type.
1490-
fn dealias(resolve: &Resolve, mut id: TypeId) -> TypeId {
1528+
pub fn dealias(resolve: &Resolve, mut id: TypeId) -> TypeId {
14911529
loop {
14921530
match &resolve.types[id].kind {
14931531
TypeDefKind::Type(Type::Id(that_id)) => id = *that_id,

0 commit comments

Comments
 (0)