skeleton for unsized glue

This commit is contained in:
Folkert 2023-08-14 22:24:47 +02:00
parent 2bd998a215
commit 609d76529a
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
3 changed files with 56 additions and 28 deletions

View file

@ -1,7 +1,10 @@
app "rust-glue" app "rust-glue"
packages { pf: "../platform/main.roc" } packages { pf: "../platform/main.roc" }
imports [ 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, "../static/Cargo.toml" as rocAppCargoToml : Str,
"../../roc_std/Cargo.toml" as rocStdCargoToml : Str, "../../roc_std/Cargo.toml" as rocStdCargoToml : Str,
"../../roc_std/src/lib.rs" as rocStdLib : Str, "../../roc_std/src/lib.rs" as rocStdLib : Str,
@ -39,8 +42,7 @@ makeGlue = \typesByArch ->
## These are always included, and don't depend on the specifics of the app. ## These are always included, and don't depend on the specifics of the app.
staticFiles : List File staticFiles : List File
staticFiles = staticFiles = [
[
{ name: "roc_app/Cargo.toml", content: rocAppCargoToml }, { name: "roc_app/Cargo.toml", content: rocAppCargoToml },
{ name: "roc_std/Cargo.toml", content: rocStdCargoToml }, { name: "roc_std/Cargo.toml", content: rocStdCargoToml },
{ name: "roc_std/src/lib.rs", content: rocStdLib }, { name: "roc_std/src/lib.rs", content: rocStdLib },
@ -845,6 +847,32 @@ generateRecursiveTagUnion = \buf, types, id, tagUnionName, tags, discriminantSiz
None -> 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 = payloadFieldNames =
commaSeparated "" payloadFields \_, i -> commaSeparated "" payloadFields \_, i ->
n = Num.toStr 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 _) Self((ptr as usize | tag_id as usize) as *mut _)
} }
\(fieldGetters)
pub fn get_\(tagName)(mut self) -> \(escapedName)_\(tagName) { pub fn get_\(tagName)(mut self) -> \(escapedName)_\(tagName) {
debug_assert!(self.is_\(tagName)()); debug_assert!(self.is_\(tagName)());
@ -1040,8 +1069,6 @@ generateRecursiveTagUnion = \buf, types, id, tagUnionName, tags, discriminantSiz
|> List.mapWithIndex hashCase |> List.mapWithIndex hashCase
|> Str.joinWith "\n" |> Str.joinWith "\n"
hashImpl = hashImpl =
if canSupportPartialEqOrd types (Types.shape types id) then 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<union_\(escapedName)> { fn unmasked_pointer(&self) -> *mut union_Op {
debug_assert!(!self.0.is_null()); debug_assert!(!self.0.is_null());
let mask = match std::mem::size_of::<usize>() { let mask = match std::mem::size_of::<usize>() {
@ -1153,7 +1180,11 @@ generateRecursiveTagUnion = \buf, types, id, tagUnionName, tags, discriminantSiz
_ => unreachable!(), _ => 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<union_Op> {
let ptr = self.unmasked_pointer();
core::mem::ManuallyDrop::new(unsafe { std::ptr::read(ptr) }) core::mem::ManuallyDrop::new(unsafe { std::ptr::read(ptr) })
} }
@ -1808,7 +1839,6 @@ cannotSupportDefault = \types, type ->
cannotSupportDefault types (Types.shape types id) cannotSupportDefault types (Types.shape types id)
TagUnionPayload { fields: HasClosure _ } -> Bool.true TagUnionPayload { fields: HasClosure _ } -> Bool.true
RocDict keyId valId -> RocDict keyId valId ->
cannotSupportCopy types (Types.shape types keyId) cannotSupportCopy types (Types.shape types keyId)
|| cannotSupportCopy types (Types.shape types valId) || cannotSupportCopy types (Types.shape types valId)
@ -2090,7 +2120,6 @@ nextMultipleOf = \lhs, rhs ->
0 -> lhs 0 -> lhs
r -> lhs + (rhs - r) r -> lhs + (rhs - r)
isUnit : Shape -> Bool isUnit : Shape -> Bool
isUnit = \shape -> isUnit = \shape ->
when shape is when shape is

View file

@ -16,7 +16,8 @@ name = "host"
path = "src/main.rs" path = "src/main.rs"
[dependencies] [dependencies]
roc_std = { path = "../../../crates/roc_std" } roc_app = { path = "roc_app" }
roc_std = { path = "roc_std" }
libc = "0.2" libc = "0.2"
[workspace] [workspace]

View file

@ -1,15 +1,13 @@
#![allow(non_snake_case)] #![allow(non_snake_case)]
mod test_glue;
use core::ffi::c_void; use core::ffi::c_void;
use roc_app::Op;
use roc_std::RocStr; use roc_std::RocStr;
use std::ffi::CStr; use std::ffi::CStr;
use std::io::Write; use std::io::Write;
use std::os::raw::c_char; 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] #[no_mangle]
pub unsafe extern "C" fn roc_alloc(size: usize, _alignment: u32) -> *mut c_void { 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] #[no_mangle]
pub extern "C" fn rust_main() -> i32 { pub extern "C" fn rust_main() -> i32 {
use test_glue::discriminant_Op::*; use roc_app::discriminant_Op::*;
println!("Let's do things!"); println!("Let's do things!");
@ -91,7 +89,7 @@ pub extern "C" fn rust_main() -> i32 {
StdoutWrite => { StdoutWrite => {
let stdout_write = op.get_StdoutWrite(); let stdout_write = op.get_StdoutWrite();
let output: RocStr = stdout_write.f0; 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()) { if let Err(e) = std::io::stdout().write_all(output.as_bytes()) {
panic!("Writing to stdout failed! {:?}", e); panic!("Writing to stdout failed! {:?}", e);
@ -100,7 +98,7 @@ pub extern "C" fn rust_main() -> i32 {
StderrWrite => { StderrWrite => {
let stderr_write = op.get_StderrWrite(); let stderr_write = op.get_StderrWrite();
let output: RocStr = stderr_write.f0; 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()) { if let Err(e) = std::io::stderr().write_all(output.as_bytes()) {
panic!("Writing to stdout failed! {:?}", e); panic!("Writing to stdout failed! {:?}", e);