Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
Signed-off-by: James Sturtevant <[email protected]>
  • Loading branch information
jsturtevant committed Nov 20, 2023
1 parent 902e0e1 commit 6c0648f
Showing 1 changed file with 95 additions and 89 deletions.
184 changes: 95 additions & 89 deletions crates/csharp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,42 +145,7 @@ impl WorldGenerator for CSharp {
gen.import(&resolve.name_world_key(key), func);
}

let mut ret_struct_type = String::new();
if gen.gen.return_area_size > 0 {
uwrite!(
ret_struct_type,
r#"
private unsafe struct ReturnArea
{{
private int GetS32(IntPtr ptr, int offset)
{{
var span = new Span<byte>((void*)ptr, {});
return BitConverter.ToInt32(span.Slice(offset, 4));
}}
public string GetUTF8String(IntPtr ptr)
{{
return Encoding.UTF8.GetString((byte*)GetS32(ptr, 0), GetS32(ptr, 4));
}}
}}
[ThreadStatic]
[FixedAddressValueType]
private static ReturnArea returnArea;
"#,
gen.gen.return_area_size
);
}

uwrite!(
gen.csharp_interop_src,
r#"
{ret_struct_type}
"#
);

gen.add_import_return_area();
gen.add_interface_fragment(false);
}

Expand Down Expand Up @@ -217,59 +182,7 @@ impl WorldGenerator for CSharp {
gen.export(func, Some(key));
}

// Declare a statically-allocated return area, if needed. We only do
// this for export bindings, because import bindings allocate their
// return-area on the stack.
if gen.gen.return_area_size > 0 {
let mut ret_area_str = String::new();

uwrite!(
ret_area_str,
"
[InlineArray({})]
[StructLayout(LayoutKind.Sequential, Pack = {})]
private struct ReturnArea
{{
private byte buffer;
private int GetS32(int offset)
{{
ReadOnlySpan<byte> span = this;
return BitConverter.ToInt32(span.Slice(offset, 4));
}}
public void SetS32(int offset, int value)
{{
Span<byte> span = this;
BitConverter.TryWriteBytes(span.Slice(offset), value);
}}
internal unsafe int AddrOfBuffer()
{{
fixed(byte* ptr = &buffer)
{{
return (int)ptr;
}}
}}
public unsafe string GetUTF8String(int p0, int p1)
{{
return Encoding.UTF8.GetString((byte*)p0, p1);
}}
}}
[ThreadStatic]
private static ReturnArea returnArea = default;
",
gen.gen.return_area_size,
gen.gen.return_area_align,
);

gen.csharp_interop_src.push_str(&ret_area_str);
}

gen.add_export_return_area();
gen.add_interface_fragment(true);
Ok(())
}
Expand Down Expand Up @@ -678,6 +591,99 @@ impl InterfaceGenerator<'_> {
});
}

fn add_import_return_area(&mut self) {
let mut ret_struct_type = String::new();
if self.gen.return_area_size > 0 {
uwrite!(
ret_struct_type,
r#"
private unsafe struct ReturnArea
{{
private int GetS32(IntPtr ptr, int offset)
{{
var span = new Span<byte>((void*)ptr, {});
return BitConverter.ToInt32(span.Slice(offset, 4));
}}
public string GetUTF8String(IntPtr ptr)
{{
return Encoding.UTF8.GetString((byte*)GetS32(ptr, 0), GetS32(ptr, 4));
}}
}}
[ThreadStatic]
[FixedAddressValueType]
private static ReturnArea returnArea;
"#,
self.gen.return_area_size
);
}

uwrite!(
self.csharp_interop_src,
r#"
{ret_struct_type}
"#
);
}

fn add_export_return_area(&mut self) {
// Declare a statically-allocated return area, if needed. We only do
// this for export bindings, because import bindings allocate their
// return-area on the stack.
if self.gen.return_area_size > 0 {
let mut ret_area_str = String::new();

uwrite!(
ret_area_str,
"
[InlineArray({})]
[StructLayout(LayoutKind.Sequential, Pack = {})]
private struct ReturnArea
{{
private byte buffer;
private int GetS32(int offset)
{{
ReadOnlySpan<byte> span = this;
return BitConverter.ToInt32(span.Slice(offset, 4));
}}
public void SetS32(int offset, int value)
{{
Span<byte> span = this;
BitConverter.TryWriteBytes(span.Slice(offset), value);
}}
internal unsafe int AddrOfBuffer()
{{
fixed(byte* ptr = &buffer)
{{
return (int)ptr;
}}
}}
public unsafe string GetUTF8String(int p0, int p1)
{{
return Encoding.UTF8.GetString((byte*)p0, p1);
}}
}}
[ThreadStatic]
private static ReturnArea returnArea = default;
",
self.gen.return_area_size,
self.gen.return_area_align,
);

self.csharp_interop_src.push_str(&ret_area_str);
}
}

fn add_world_fragment(self) {
self.gen.world_fragments.push(InterfaceFragment {
csharp_src: self.src,
Expand Down

0 comments on commit 6c0648f

Please sign in to comment.