Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Coverall2 and Rondpoint working with WASM! #191

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions crates/ubrn_bindgen/src/bindings/extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,11 @@ pub(crate) impl FfiFunction {
let name = self.name();
name.contains("ffi__") && name.contains("_internal_")
}

fn is_unsafe(&self) -> bool {
let name = self.name();
name.contains("_fn_clone_") || name.contains("_fn_free_") || name.contains("_rustbuffer_")
}
}

#[ext]
Expand Down
100 changes: 57 additions & 43 deletions crates/ubrn_bindgen/src/bindings/gen_rust/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ use uniffi_bindgen::{
};

use crate::{
bindings::{extensions::ComponentInterfaceExt, metadata::ModuleMetadata},
bindings::{
extensions::{ComponentInterfaceExt, FfiFunctionExt},
metadata::ModuleMetadata,
},
switches::SwitchArgs,
AbiFlavor,
};
Expand Down Expand Up @@ -157,20 +160,25 @@ impl<'a> ComponentTemplate<'a> {
}

fn runtime_ident(&self) -> Ident {
ident("__runtime")
ident("f")
}

fn module_ident(&self) -> Ident {
ident("__module")
ident("r")
}

fn uniffi_ident(&self) -> Ident {
ident("u")
}

fn prelude(&self, ci: &ComponentInterface) -> TokenStream {
let runtime_alias_ident = self.runtime_ident();
let runtime_ident = self.flavor.runtime_module();
let namespace_ident = ident(ci.namespace());
let module_ident = self.module_ident();
let uniffi_alias_ident = self.uniffi_ident();
quote! {
use #runtime_ident::{self as #runtime_alias_ident, IntoRust};
use #runtime_ident::{self as #runtime_alias_ident, uniffi as #uniffi_alias_ident, IntoRust};
use #namespace_ident as #module_ident;
}
}
Expand All @@ -187,6 +195,8 @@ impl<'a> ComponentTemplate<'a> {
fn ffi_function(&mut self, func: &FfiFunction) -> TokenStream {
let module = self.module_ident();
let runtime = self.runtime_ident();
let uniffi = self.uniffi_ident();

let annotation = quote! { #[#runtime::export] };
let func_ident = ident(func.name());
let foreign_func_ident = self.flavor.foreign_ident(func.name());
Expand All @@ -206,9 +216,9 @@ impl<'a> ComponentTemplate<'a> {

let needs_call_status = func.has_rust_call_status_arg();
if needs_call_status {
let rust_status_ident = ident("__rust_call_status");
let foreign_status_ident = ident("__call_status");
let return_ident = ident("__return");
let rust_status_ident = ident("u_status_");
let foreign_status_ident = ident("f_status_");
let return_ident = ident("value_");
let let_value = if has_return {
quote! { let #return_ident = }
} else {
Expand All @@ -224,11 +234,16 @@ impl<'a> ComponentTemplate<'a> {
} else {
quote! {}
};
let unsafe_ = if func.is_unsafe() {
quote! { unsafe }
} else {
quote! {}
};

quote! {
#annotation
pub fn #foreign_func_ident(#args_decl #foreign_status_ident: &mut #runtime::CallStatus) #decl_suffix {
let mut #rust_status_ident = #runtime::RustCallStatus::default();
pub #unsafe_ fn #foreign_func_ident(#args_decl #foreign_status_ident: &mut #runtime::RustCallStatus) #decl_suffix {
let mut #rust_status_ident = #uniffi::RustCallStatus::default();
#let_value #module::#func_ident(#args_call &mut #rust_status_ident) #call_suffix;
#foreign_status_ident.copy_into(#rust_status_ident);
#return_value
Expand Down Expand Up @@ -290,18 +305,19 @@ impl<'a> ComponentTemplate<'a> {
FfiType::Float32 => quote! { #runtime::Float32 },
FfiType::Float64 => quote! { #runtime::Float64 },
FfiType::RustArcPtr(_) => quote! { #runtime::VoidPointer },
FfiType::RustBuffer(_external_ffi_metadata) => quote! { #runtime::ForeignBytes },
FfiType::ForeignBytes => quote! { #module::ForeignBytes },
FfiType::RustBuffer(_) => quote! { #runtime::ForeignBytes },
FfiType::ForeignBytes => quote! { #runtime::ForeignBytes },
FfiType::Callback(_) => quote! { #module::Callback },
FfiType::Struct(_) => quote! { #module::Struct },
FfiType::Handle => quote! { #module::Handle },
FfiType::RustCallStatus => quote! { #module::RustCallStatus },
FfiType::RustCallStatus => quote! { #runtime::RustCallStatus },
FfiType::Reference(_ffi_type) => todo!(),
FfiType::VoidPointer => quote! { #runtime::VoidPointer },
}
}

fn ffi_type_rust(&self, t: &FfiType) -> TokenStream {
let uniffi = self.uniffi_ident();
match t {
FfiType::UInt8 => quote! { u8 },
FfiType::Int8 => quote! { i8 },
Expand All @@ -313,6 +329,8 @@ impl<'a> ComponentTemplate<'a> {
FfiType::Int64 => quote! { i64 },
FfiType::Float32 => quote! { f32 },
FfiType::Float64 => quote! { f64 },
FfiType::RustBuffer(_) => quote! { #uniffi::RustBuffer },
FfiType::RustArcPtr(_) => quote! { #uniffi::VoidPointer },
_ => todo!(),
}
}
Expand Down Expand Up @@ -407,12 +425,12 @@ mod unit_tests {
string.trim(),
trim_indent(
"
#[__runtime::export]
pub fn ubrn_my_function(__call_status: &mut __runtime::CallStatus) -> __runtime::Int8 {
let mut __rust_call_status = __runtime::RustCallStatus::default();
let __return = __module::my_function(&mut __rust_call_status).into_js();
__call_status.copy_into(__rust_call_status);
__return
#[f::export]
pub fn ubrn_my_function(f_status_: &mut f::RustCallStatus) -> f::Int8 {
let mut u_status_ = u::RustCallStatus::default();
let value_ = r::my_function(&mut u_status_).into_js();
f_status_.copy_into(u_status_);
value_
}
"
)
Expand All @@ -435,16 +453,12 @@ mod unit_tests {
string.trim(),
trim_indent(
"
#[__runtime::export]
pub fn ubrn_my_function(
num: __runtime::Int32,
__call_status: &mut __runtime::CallStatus,
) -> __runtime::Int8 {
let mut __rust_call_status = __runtime::RustCallStatus::default();
let __return = __module::my_function(i32::into_rust(num), &mut __rust_call_status)
.into_js();
__call_status.copy_into(__rust_call_status);
__return
#[f::export]
pub fn ubrn_my_function(num: f::Int32, f_status_: &mut f::RustCallStatus) -> f::Int8 {
let mut u_status_ = u::RustCallStatus::default();
let value_ = r::my_function(i32::into_rust(num), &mut u_status_).into_js();
f_status_.copy_into(u_status_);
value_
}
"
)
Expand All @@ -467,21 +481,21 @@ mod unit_tests {
string.trim(),
trim_indent(
"
#[__runtime::export]
#[f::export]
pub fn ubrn_my_function(
left: __runtime::Int32,
right: __runtime::Float32,
__call_status: &mut __runtime::CallStatus,
) -> __runtime::Int8 {
let mut __rust_call_status = __runtime::RustCallStatus::default();
let __return = __module::my_function(
left: f::Int32,
right: f::Float32,
f_status_: &mut f::RustCallStatus,
) -> f::Int8 {
let mut u_status_ = u::RustCallStatus::default();
let value_ = r::my_function(
i32::into_rust(left),
f32::into_rust(right),
&mut __rust_call_status,
&mut u_status_,
)
.into_js();
__call_status.copy_into(__rust_call_status);
__return
f_status_.copy_into(u_status_);
value_
}"
)
);
Expand All @@ -499,11 +513,11 @@ mod unit_tests {
string.trim(),
trim_indent(
"
#[__runtime::export]
pub fn ubrn_my_function(__call_status: &mut __runtime::CallStatus) {
let mut __rust_call_status = __runtime::RustCallStatus::default();
__module::my_function(&mut __rust_call_status);
__call_status.copy_into(__rust_call_status);
#[f::export]
pub fn ubrn_my_function(f_status_: &mut f::RustCallStatus) {
let mut u_status_ = u::RustCallStatus::default();
r::my_function(&mut u_status_);
f_status_.copy_into(u_status_);
}
"
)
Expand Down
8 changes: 8 additions & 0 deletions crates/ubrn_bindgen/src/bindings/gen_typescript/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ impl TsFlavorParams<'_> {
pub(crate) fn is_jsi(&self) -> bool {
matches!(self.inner, &AbiFlavor::Jsi)
}

pub(crate) fn supports_text_encoder(&self) -> bool {
!matches!(self.inner, &AbiFlavor::Jsi)
}

pub(crate) fn supports_finalization_registry(&self) -> bool {
!matches!(self.inner, &AbiFlavor::Jsi)
}
}

#[derive(Template)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
{{- self.import_infra_type("UniffiByteArray", "ffi-types")}}
{{- self.import_infra("UniffiRustCaller", "rust-call")}}
{{- self.import_infra_type("UniffiRustCallStatus", "rust-call")}}
{{- self.import_infra("RustBuffer", "ffi-types")}}

{%- let vtable_methods = cbi.vtable_methods() %}
{%- let trait_impl = format!("uniffiCallbackInterface{}", name) %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,11 @@ export class {{ impl_class_name }} extends UniffiAbstractObject implements {{ pr
* {@inheritDoc uniffi-bindgen-react-native#UniffiAbstractObject.uniffiDestroy}
*/
uniffiDestroy(): void {
if ((this as any)[destructorGuardSymbol]) {
const ptr = (this as any)[destructorGuardSymbol];
if (ptr !== undefined) {
const pointer = {{ obj_factory }}.pointer(this);
{{ obj_factory }}.freePointer(pointer);
this[destructorGuardSymbol].markDestroyed();
{{ obj_factory }}.unbless(ptr);
delete (this as any)[destructorGuardSymbol];
}
}
Expand Down Expand Up @@ -148,6 +149,24 @@ const {{ obj_factory }}: UniffiObjectFactory<{{ type_name }}> = {
return instance;
},

{% if flavor.supports_finalization_registry() %}
registry: new FinalizationRegistry<UnsafeMutableRawPointer>((heldValue) => {
{{ obj_factory }}.freePointer(heldValue);
}),

bless(p: UnsafeMutableRawPointer): UniffiRustArcPtr {
const ptr = {
p, // make sure this object doesn't get optimized away.
markDestroyed: () => undefined,
};
{{ obj_factory }}.registry.register(ptr, p, ptr);
return ptr;
},

unbless(ptr: UniffiRustArcPtr) {
{{ obj_factory }}.registry.unregister(ptr);
},
{%- else %}
bless(p: UnsafeMutableRawPointer): UniffiRustArcPtr {
return uniffiCaller.rustCall(
/*caller:*/ (status) =>
Expand All @@ -156,6 +175,11 @@ const {{ obj_factory }}: UniffiObjectFactory<{{ type_name }}> = {
);
},

unbless(ptr: UniffiRustArcPtr) {
ptr.markDestroyed();
},
{%- endif %}

pointer(obj: {{ type_name }}): UnsafeMutableRawPointer {
if ((obj as any)[destructorGuardSymbol] === undefined) {
throw new UniffiInternalError.UnexpectedNullPointer();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
{{- self.import_infra("RustBuffer", "ffi-types") }}
{{- self.import_infra("uniffiCreateRecord", "records") }}

{%- let rec = ci|get_record_definition(name) %}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,42 +1,24 @@
{{- self.import_infra("RustBuffer", "ffi-types") }}
{{- self.import_infra_type("UniffiByteArray", "ffi-types") }}
{{- self.import_infra("FfiConverterInt32", "ffi-converters") }}
{{- self.import_infra_type("FfiConverter", "ffi-converters") }}
{{- self.import_infra("uniffiCreateFfiConverterString", "ffi-converters") }}

const stringToArrayBuffer = (s: string): UniffiByteArray =>
uniffiCaller.rustCall((status) => {% call ts::fn_handle(ci.ffi_function_string_to_arraybuffer()) %}(s, status));

const arrayBufferToString = (ab: UniffiByteArray): string =>
uniffiCaller.rustCall((status) => {% call ts::fn_handle(ci.ffi_function_arraybuffer_to_string()) %}(ab, status));

const stringByteLength = (s: string): number =>
uniffiCaller.rustCall((status) => {% call ts::fn_handle(ci.ffi_function_string_to_bytelength()) %}(s, status));

const FfiConverterString = (() => {
const lengthConverter = FfiConverterInt32;
type TypeName = string;
class FFIConverter implements FfiConverter<UniffiByteArray, TypeName> {
lift(value: UniffiByteArray): TypeName {
return arrayBufferToString(value);
}
lower(value: TypeName): UniffiByteArray {
return stringToArrayBuffer(value);
}
read(from: RustBuffer): TypeName {
const length = lengthConverter.read(from);
const bytes = from.readBytes(length);
return arrayBufferToString(new Uint8Array(bytes));
}
write(value: TypeName, into: RustBuffer): void {
const buffer = stringToArrayBuffer(value).buffer;
const numBytes = buffer.byteLength;
lengthConverter.write(numBytes, into);
into.writeBytes(buffer);
}
allocationSize(value: TypeName): number {
return lengthConverter.allocationSize(0) + stringByteLength(value);
}
}

return new FFIConverter();
{%- if flavor.supports_text_encoder() %}
const stringConverter = (() => {
const encoder = new TextEncoder();
const decoder = new TextDecoder();
return {
stringToBytes: (s: string) => encoder.encode(s),
bytesToString: (ab: UniffiByteArray) => decoder.decode(ab),
stringByteLength: (s: string) => encoder.encode(s).byteLength,
};
})();
{%- else %}
const stringConverter = {
stringToBytes: (s: string) =>
uniffiCaller.rustCall((status) => {% call ts::fn_handle(ci.ffi_function_string_to_arraybuffer()) %}(s, status)),
bytesToString: (ab: UniffiByteArray) =>
uniffiCaller.rustCall((status) => {% call ts::fn_handle(ci.ffi_function_arraybuffer_to_string()) %}(ab, status)),
stringByteLength: (s: string) =>
uniffiCaller.rustCall((status) => {% call ts::fn_handle(ci.ffi_function_string_to_bytelength()) %}(s, status)),
};
{%- endif %}
const FfiConverterString = uniffiCreateFfiConverterString(stringConverter);
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{%- import "macros.ts" as ts %}
{{- self.import_infra("RustBuffer", "ffi-types") }}
{{- self.import_infra("UniffiInternalError", "errors") -}}
{{- self.import_infra("UniffiRustCaller", "rust-call") }}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const {
const uniffiCaller = new UniffiRustCaller();
{%- else %}
const nativeModule = () => wasmBundle;
const uniffiCaller = new UniffiRustCaller(() => new wasmBundle.CallStatus());
const uniffiCaller = new UniffiRustCaller(() => new wasmBundle.RustCallStatus());
{%- endif %}

const uniffiIsDebug =
Expand Down
Loading
Loading