diff --git a/crates/glue/src/RustGlue.roc b/crates/glue/src/RustGlue.roc index 8c5d6a4718..d94c205fc2 100644 --- a/crates/glue/src/RustGlue.roc +++ b/crates/glue/src/RustGlue.roc @@ -1,7 +1,10 @@ app "rust-glue" packages { pf: "../platform/main.roc" } imports [ - pf.Types.{ Types }, pf.Shape.{ Shape, RocFn }, pf.File.{ File }, pf.TypeId.{ TypeId }, + pf.Types.{ Types }, + pf.Shape.{ Shape, RocFn }, + pf.File.{ File }, + pf.TypeId.{ TypeId }, "../static/Cargo.toml" as rocAppCargoToml : Str, "../../roc_std/Cargo.toml" as rocStdCargoToml : Str, "../../roc_std/src/lib.rs" as rocStdLib : Str, @@ -39,18 +42,17 @@ makeGlue = \typesByArch -> ## These are always included, and don't depend on the specifics of the app. staticFiles : List File -staticFiles = - [ - { name: "roc_app/Cargo.toml", content: rocAppCargoToml }, - { name: "roc_std/Cargo.toml", content: rocStdCargoToml }, - { name: "roc_std/src/lib.rs", content: rocStdLib }, - { name: "roc_std/src/roc_box.rs", content: rocStdBox }, - { name: "roc_std/src/roc_list.rs", content: rocStdList }, - { name: "roc_std/src/roc_dict.rs", content: rocStdDict }, - { name: "roc_std/src/roc_set.rs", content: rocStdSet }, - { name: "roc_std/src/roc_str.rs", content: rocStdStr }, - { name: "roc_std/src/storage.rs", content: rocStdStorage }, - ] +staticFiles = [ + { name: "roc_app/Cargo.toml", content: rocAppCargoToml }, + { name: "roc_std/Cargo.toml", content: rocStdCargoToml }, + { name: "roc_std/src/lib.rs", content: rocStdLib }, + { name: "roc_std/src/roc_box.rs", content: rocStdBox }, + { name: "roc_std/src/roc_list.rs", content: rocStdList }, + { name: "roc_std/src/roc_dict.rs", content: rocStdDict }, + { name: "roc_std/src/roc_set.rs", content: rocStdSet }, + { name: "roc_std/src/roc_str.rs", content: rocStdStr }, + { name: "roc_std/src/storage.rs", content: rocStdStorage }, +] convertTypesToFile : Types -> File convertTypesToFile = \types -> @@ -845,6 +847,32 @@ generateRecursiveTagUnion = \buf, types, id, tagUnionName, tags, discriminantSiz None -> [] + fieldGetters = + List.walk payloadFields { i: 0, accum: "" } \{ i, accum }, fieldTypeId -> + fieldTypeName = typeName types fieldTypeId + fieldIndex = Num.toStr i + + { + i: i + 1, + accum: + """ + \(accum) + pub fn get_\(tagName)_f\(fieldIndex)(&self) -> &\(fieldTypeName) { + debug_assert!(self.is_\(tagName)()); + + // extern "C" { + // fn foobar(tag_id: u16, field_index: usize) -> usize; + // } + + // let offset = unsafe { foobar(\(fieldIndex)) }; + let offset = 0; + unsafe { &*self.unmasked_pointer().add(offset).cast() } + } + + """, + } + |> .accum + payloadFieldNames = commaSeparated "" payloadFields \_, i -> n = Num.toStr i @@ -896,6 +924,7 @@ generateRecursiveTagUnion = \buf, types, id, tagUnionName, tags, discriminantSiz Self((ptr as usize | tag_id as usize) as *mut _) } + \(fieldGetters) pub fn get_\(tagName)(mut self) -> \(escapedName)_\(tagName) { debug_assert!(self.is_\(tagName)()); @@ -1040,8 +1069,6 @@ generateRecursiveTagUnion = \buf, types, id, tagUnionName, tags, discriminantSiz |> List.mapWithIndex hashCase |> Str.joinWith "\n" - - hashImpl = if canSupportPartialEqOrd types (Types.shape types id) then """ @@ -1144,7 +1171,7 @@ generateRecursiveTagUnion = \buf, types, id, tagUnionName, tags, discriminantSiz } } - unsafe fn ptr_read_union(&self) -> core::mem::ManuallyDrop { + fn unmasked_pointer(&self) -> *mut union_Op { debug_assert!(!self.0.is_null()); let mask = match std::mem::size_of::() { @@ -1153,7 +1180,11 @@ generateRecursiveTagUnion = \buf, types, id, tagUnionName, tags, discriminantSiz _ => unreachable!(), }; - let ptr = ((self.0 as usize) & mask) as *mut union_\(escapedName); + ((self.0 as usize) & mask) as *mut union_Op + } + + unsafe fn ptr_read_union(&self) -> core::mem::ManuallyDrop { + let ptr = self.unmasked_pointer(); core::mem::ManuallyDrop::new(unsafe { std::ptr::read(ptr) }) } @@ -1803,12 +1834,11 @@ canDeriveCopy = \types, type -> cannotSupportDefault = \types, type -> when type is Unit | Unsized | EmptyTagUnion | TagUnion _ | RocResult _ _ | RecursivePointer _ | Function _ -> Bool.true - RocStr | Bool | Num _ -> Bool.false + RocStr | Bool | Num _ -> Bool.false RocList id | RocSet id | RocBox id -> cannotSupportDefault types (Types.shape types id) TagUnionPayload { fields: HasClosure _ } -> Bool.true - RocDict keyId valId -> cannotSupportCopy types (Types.shape types keyId) || cannotSupportCopy types (Types.shape types valId) @@ -2090,7 +2120,6 @@ nextMultipleOf = \lhs, rhs -> 0 -> lhs r -> lhs + (rhs - r) - isUnit : Shape -> Bool isUnit = \shape -> when shape is diff --git a/examples/glue/rust-platform/Cargo.toml b/examples/glue/rust-platform/Cargo.toml index 8d10ce6eea..3cfadfba58 100644 --- a/examples/glue/rust-platform/Cargo.toml +++ b/examples/glue/rust-platform/Cargo.toml @@ -16,7 +16,8 @@ name = "host" path = "src/main.rs" [dependencies] -roc_std = { path = "../../../crates/roc_std" } +roc_app = { path = "roc_app" } +roc_std = { path = "roc_std" } libc = "0.2" [workspace] diff --git a/examples/glue/rust-platform/src/lib.rs b/examples/glue/rust-platform/src/lib.rs index fe5398b647..e821634b41 100644 --- a/examples/glue/rust-platform/src/lib.rs +++ b/examples/glue/rust-platform/src/lib.rs @@ -1,15 +1,13 @@ #![allow(non_snake_case)] -mod test_glue; - use core::ffi::c_void; +use roc_app::Op; use roc_std::RocStr; use std::ffi::CStr; use std::io::Write; use std::os::raw::c_char; -use test_glue::Op; -use test_glue::mainForHost as roc_main; +use roc_app::mainForHost as roc_main; #[no_mangle] pub unsafe extern "C" fn roc_alloc(size: usize, _alignment: u32) -> *mut c_void { @@ -80,7 +78,7 @@ pub unsafe extern "C" fn roc_shm_open( #[no_mangle] pub extern "C" fn rust_main() -> i32 { - use test_glue::discriminant_Op::*; + use roc_app::discriminant_Op::*; println!("Let's do things!"); @@ -91,7 +89,7 @@ pub extern "C" fn rust_main() -> i32 { StdoutWrite => { let stdout_write = op.get_StdoutWrite(); let output: RocStr = stdout_write.f0; - op = unsafe { stdout_write.f1.force_thunk(()) }; + op = unsafe { stdout_write.f1.force_thunk() }; if let Err(e) = std::io::stdout().write_all(output.as_bytes()) { panic!("Writing to stdout failed! {:?}", e); @@ -100,7 +98,7 @@ pub extern "C" fn rust_main() -> i32 { StderrWrite => { let stderr_write = op.get_StderrWrite(); let output: RocStr = stderr_write.f0; - op = unsafe { stderr_write.f1.force_thunk(()) }; + op = unsafe { stderr_write.f1.force_thunk() }; if let Err(e) = std::io::stderr().write_all(output.as_bytes()) { panic!("Writing to stdout failed! {:?}", e);