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

Fix segfault when passing DartOpaque through ffi boundaries #2259

Merged
merged 7 commits into from
Sep 11, 2024
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,36 @@ use crate::codegen::generator::codec::sse::ty::*;

impl<'a> CodecSseTyTrait for DartOpaqueCodecSseTy<'a> {
fn generate_encode(&self, lang: &Lang) -> Option<String> {
Some(simple_delegate_encode(
lang,
&self.mir.get_delegate(),
match lang {
Lang::DartLang(_) => {
"BigInt.from(PlatformPointerUtil.ptrToInt(encodeDartOpaque(self, portManager.dartHandlerPort, generalizedFrbRustBinding))).toUnsigned(64)"
}
Lang::RustLang(_) => "self.encode()",
},
))
Some(match lang {
Lang::DartLang(_) => {
simple_delegate_encode(
lang,
&self.mir.get_delegate_dart(),
"PlatformPointerUtil.ptrToPlatformInt64(encodeDartOpaque(self, portManager.dartHandlerPort, generalizedFrbRustBinding))",
)
}
Lang::RustLang(_) => {
simple_delegate_encode(
lang,
&self.mir.get_delegate_rust(),
"self.encode()",
)
}
})
}

fn generate_decode(&self, lang: &Lang) -> Option<String> {
Some(simple_delegate_decode(
lang,
&self.mir.get_delegate(),
match lang {
Lang::DartLang(_) => "decodeDartOpaque(inner, generalizedFrbRustBinding)",
Lang::RustLang(_) => {
"unsafe { flutter_rust_bridge::for_generated::sse_decode_dart_opaque(inner) }"
}
},
))
Some(match lang {
Lang::DartLang(_) => simple_delegate_decode(
lang,
&self.mir.get_delegate_dart(),
"decodeDartOpaque(inner, generalizedFrbRustBinding)",
),
Lang::RustLang(_) => simple_delegate_decode(
lang,
&self.mir.get_delegate_rust(),
"unsafe { flutter_rust_bridge::for_generated::sse_decode_dart_opaque(inner) }",
),
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl PathTexts {
pub(crate) fn write_to_disk(&self) -> anyhow::Result<()> {
self.assert_no_duplicate_paths();
for item in self.0.iter() {
create_dir_all_and_write(&item.path, &item.text.all_code())?;
create_dir_all_and_write(&item.path, item.text.all_code())?;
}
Ok(())
}
Expand Down
9 changes: 7 additions & 2 deletions frb_codegen/src/library/codegen/ir/mir/ty/dart_opaque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ impl MirTypeTrait for MirTypeDartOpaque {
f: &mut F,
mir_context: &impl MirContext,
) {
self.get_delegate().visit_types(f, mir_context)
self.get_delegate_rust().visit_types(f, mir_context);
self.get_delegate_dart().visit_types(f, mir_context);
}

fn safe_ident(&self) -> String {
Expand All @@ -28,7 +29,11 @@ impl MirTypeTrait for MirTypeDartOpaque {
}

impl MirTypeDartOpaque {
pub(crate) fn get_delegate(&self) -> MirType {
pub(crate) fn get_delegate_rust(&self) -> MirType {
MirType::Primitive(MirTypePrimitive::Usize)
}

pub(crate) fn get_delegate_dart(&self) -> MirType {
MirType::Primitive(MirTypePrimitive::Isize)
}
}
3 changes: 3 additions & 0 deletions frb_dart/lib/src/platform_types/_io.dart
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ class PlatformPointerUtil {
/// {@macro flutter_rust_bridge.internal}
static int ptrToInt(PlatformPointer ptr) => ptr.address;

/// {@macro flutter_rust_bridge.internal}
static PlatformInt64 ptrToPlatformInt64(PlatformPointer ptr) => ptrToInt(ptr);

/// {@macro flutter_rust_bridge.internal}
static PlatformPointer nullPtr() => ffi.Pointer.fromAddress(0);

Expand Down
4 changes: 4 additions & 0 deletions frb_dart/lib/src/platform_types/_web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ class PlatformPointerUtil {
/// {@macro flutter_rust_bridge.internal}
static int ptrToInt(int ptr) => ptr;

/// {@macro flutter_rust_bridge.internal}
static PlatformInt64 ptrToPlatformInt64(PlatformPointer ptr) =>
BigInt.from(ptrToInt(ptr));

/// {@macro flutter_rust_bridge.internal}
static PlatformPointer nullPtr() => 0;

Expand Down
27 changes: 22 additions & 5 deletions frb_example/integrate_third_party/lib/src/rust/frb_generated.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21119,6 +21119,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return raw as int;
}

@protected
PlatformInt64 dco_decode_isize(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
return dcoDecodeI64(raw);
}

@protected
List<MediaStreamTrack>
dco_decode_list_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMediaStreamTrack(
Expand Down Expand Up @@ -22506,7 +22512,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
@protected
Object sse_decode_DartOpaque(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var inner = sse_decode_usize(deserializer);
var inner = sse_decode_isize(deserializer);
return decodeDartOpaque(inner, generalizedFrbRustBinding);
}

Expand Down Expand Up @@ -23940,6 +23946,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return deserializer.buffer.getInt32();
}

@protected
PlatformInt64 sse_decode_isize(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
return deserializer.buffer.getPlatformInt64();
}

@protected
List<MediaStreamTrack>
sse_decode_list_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMediaStreamTrack(
Expand Down Expand Up @@ -25465,10 +25477,9 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
@protected
void sse_encode_DartOpaque(Object self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_usize(
BigInt.from(PlatformPointerUtil.ptrToInt(encodeDartOpaque(
self, portManager.dartHandlerPort, generalizedFrbRustBinding)))
.toUnsigned(64),
sse_encode_isize(
PlatformPointerUtil.ptrToPlatformInt64(encodeDartOpaque(
self, portManager.dartHandlerPort, generalizedFrbRustBinding)),
serializer);
}

Expand Down Expand Up @@ -27058,6 +27069,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
serializer.buffer.putInt32(self);
}

@protected
void sse_encode_isize(PlatformInt64 self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
serializer.buffer.putPlatformInt64(self);
}

@protected
void
sse_encode_list_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMediaStreamTrack(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1501,6 +1501,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
int dco_decode_i_32(dynamic raw);

@protected
PlatformInt64 dco_decode_isize(dynamic raw);

@protected
List<MediaStreamTrack>
dco_decode_list_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMediaStreamTrack(
Expand Down Expand Up @@ -2760,6 +2763,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
int sse_decode_i_32(SseDeserializer deserializer);

@protected
PlatformInt64 sse_decode_isize(SseDeserializer deserializer);

@protected
List<MediaStreamTrack>
sse_decode_list_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMediaStreamTrack(
Expand Down Expand Up @@ -4056,6 +4062,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_i_32(int self, SseSerializer serializer);

@protected
void sse_encode_isize(PlatformInt64 self, SseSerializer serializer);

@protected
void
sse_encode_list_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMediaStreamTrack(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1503,6 +1503,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
int dco_decode_i_32(dynamic raw);

@protected
PlatformInt64 dco_decode_isize(dynamic raw);

@protected
List<MediaStreamTrack>
dco_decode_list_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMediaStreamTrack(
Expand Down Expand Up @@ -2762,6 +2765,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
int sse_decode_i_32(SseDeserializer deserializer);

@protected
PlatformInt64 sse_decode_isize(SseDeserializer deserializer);

@protected
List<MediaStreamTrack>
sse_decode_list_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMediaStreamTrack(
Expand Down Expand Up @@ -4058,6 +4064,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_i_32(int self, SseSerializer serializer);

@protected
void sse_encode_isize(PlatformInt64 self, SseSerializer serializer);

@protected
void
sse_encode_list_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMediaStreamTrack(
Expand Down
17 changes: 17 additions & 0 deletions frb_example/integrate_third_party/rust/src/frb_generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31014,6 +31014,13 @@ impl SseDecode for i32 {
}
}

impl SseDecode for isize {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
deserializer.cursor.read_i64::<NativeEndian>().unwrap() as _
}
}

impl SseDecode for Vec<MediaStreamTrack> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
Expand Down Expand Up @@ -37759,6 +37766,16 @@ impl SseEncode for i32 {
}
}

impl SseEncode for isize {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
serializer
.cursor
.write_i64::<NativeEndian>(self as _)
.unwrap();
}
}

impl SseEncode for Vec<MediaStreamTrack> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
Expand Down
9 changes: 4 additions & 5 deletions frb_example/pure_dart/lib/src/rust/frb_generated.dart
Original file line number Diff line number Diff line change
Expand Up @@ -121866,7 +121866,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
@protected
Object sse_decode_DartOpaque(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var inner = sse_decode_usize(deserializer);
var inner = sse_decode_isize(deserializer);
return decodeDartOpaque(inner, generalizedFrbRustBinding);
}

Expand Down Expand Up @@ -147921,10 +147921,9 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
@protected
void sse_encode_DartOpaque(Object self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_usize(
BigInt.from(PlatformPointerUtil.ptrToInt(encodeDartOpaque(
self, portManager.dartHandlerPort, generalizedFrbRustBinding)))
.toUnsigned(64),
sse_encode_isize(
PlatformPointerUtil.ptrToPlatformInt64(encodeDartOpaque(
self, portManager.dartHandlerPort, generalizedFrbRustBinding)),
serializer);
}

Expand Down
9 changes: 4 additions & 5 deletions frb_example/pure_dart_pde/lib/src/rust/frb_generated.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54235,7 +54235,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
@protected
Object sse_decode_DartOpaque(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var inner = sse_decode_usize(deserializer);
var inner = sse_decode_isize(deserializer);
return decodeDartOpaque(inner, generalizedFrbRustBinding);
}

Expand Down Expand Up @@ -65971,10 +65971,9 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
@protected
void sse_encode_DartOpaque(Object self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_usize(
BigInt.from(PlatformPointerUtil.ptrToInt(encodeDartOpaque(
self, portManager.dartHandlerPort, generalizedFrbRustBinding)))
.toUnsigned(64),
sse_encode_isize(
PlatformPointerUtil.ptrToPlatformInt64(encodeDartOpaque(
self, portManager.dartHandlerPort, generalizedFrbRustBinding)),
serializer);
}

Expand Down
Loading