Skip to content

Commit b910eea

Browse files
authored
Merge pull request #780 from Marwes/clone_userdata
fix: Add tests and fix the regression with clone_userdata
2 parents ba66854 + df07872 commit b910eea

File tree

4 files changed

+34
-6
lines changed

4 files changed

+34
-6
lines changed

codegen/src/userdata.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ fn gen_impl(container: &Container, ident: Ident, generics: Generics) -> TokenStr
5555

5656
let deep_clone = if container.clone {
5757
quote! {
58-
fn deep_clone(
58+
fn deep_clone<'gc>(
5959
&self,
60-
deep_cloner: &mut _gluon_api::Cloner
61-
) -> _gluon_Result<_gluon_gc::GcPtr<Box<dyn _gluon_api::Userdata>>> {
60+
deep_cloner: &'gc mut _gluon_api::Cloner
61+
) -> _gluon_Result<_gluon_gc::GcRef<'gc, Box<dyn _gluon_api::Userdata>>> {
6262
let data: Box<dyn _gluon_api::Userdata> = Box::new(self.clone());
6363
deep_cloner.gc().alloc(_gluon_gc::Move(data))
6464
}

examples/marshalling.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,9 @@ fn marshal_wrapper() -> Result<()> {
334334
Ok(())
335335
}
336336

337-
#[derive(Userdata, Trace, Debug, Clone, VmType)]
337+
#[derive(Userdata, Trace, Clone, Debug, VmType)]
338+
#[gluon_userdata(clone)]
339+
// Lets gluon know that the value can be cloned which can be needed when transferring the value between threads
338340
#[gluon(vm_type = "WindowHandle")]
339341
struct WindowHandle {
340342
id: Arc<u64>,
@@ -348,6 +350,7 @@ fn load_mod(vm: &gluon::Thread) -> vm::Result<ExternModule> {
348350
create_hwnd => primitive!(2, create_hwnd),
349351
id => primitive!(1, id),
350352
metadata => primitive!(1, metadata),
353+
default_hwnd => create_hwnd(0, "default".into()),
351354
};
352355

353356
ExternModule::new(vm, module)

parser/src/grammar.lalrpop

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -806,15 +806,15 @@ Expr: Expr<Id> = {
806806
},
807807

808808
<metadata: Metadata?> "rec" <bindings: RecursiveValueBinding+> <body: InExpr> => {
809-
let mut bindings = bindings.into_iter().map(|x| *x).collect::<Vec<_>>();;
809+
let mut bindings = bindings.into_iter().map(|x| *x).collect::<Vec<_>>();
810810
if let Some(metadata) = metadata {
811811
bindings[0].metadata = metadata;
812812
}
813813
Expr::LetBindings(ValueBindings::Recursive(bindings), Box::new(body))
814814
},
815815

816816
<metadata: Metadata?> "rec" <bindings: TypeBinding+> <body: InExpr> => {
817-
let mut bindings = bindings.into_iter().map(|x| *x).collect::<Vec<_>>();;
817+
let mut bindings = bindings.into_iter().map(|x| *x).collect::<Vec<_>>();
818818
if let Some(metadata) = metadata {
819819
bindings[0].metadata = metadata;
820820
}

tests/api.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -705,3 +705,28 @@ fn child_vm_do_not_cause_undroppable_cycle_reverse_drop_order() {
705705
"The virtual machine and its values were not dropped"
706706
);
707707
}
708+
709+
#[test]
710+
fn clone_userdata() {
711+
let _ = ::env_logger::try_init();
712+
713+
let expr = r#"
714+
import! test
715+
"#;
716+
717+
#[derive(Debug, Userdata, Trace, VmType, Clone, PartialEq)]
718+
#[gluon(vm_type = "Test")]
719+
#[gluon_userdata(clone)]
720+
struct Test(VmInt);
721+
722+
let vm = make_vm();
723+
vm.register_type::<Test>("Test", &[])
724+
.unwrap_or_else(|_| panic!("Could not add type"));
725+
add_extern_module(&vm, "test", |thread| ExternModule::new(thread, Test(123)));
726+
727+
let (result, _) = Compiler::new()
728+
.run_expr::<OpaqueValue<RootedThread, Test>>(&vm, "<top>", expr)
729+
.unwrap_or_else(|err| panic!("{}", err));
730+
731+
assert_eq!(*result, Test(123));
732+
}

0 commit comments

Comments
 (0)