Merge pull request #5763 from roc-lang/glue-unsized-skeleton

skeleton for unsized glue
This commit is contained in:
Richard Feldman 2023-08-21 12:47:56 -04:00 committed by GitHub
commit 738e54ebba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 56 additions and 28 deletions

View file

@ -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<union_\(escapedName)> {
fn unmasked_pointer(&self) -> *mut union_\(escapedName) {
debug_assert!(!self.0.is_null());
let mask = match std::mem::size_of::<usize>() {
@ -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_\(escapedName)
}
unsafe fn ptr_read_union(&self) -> core::mem::ManuallyDrop<union_\(escapedName)> {
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)
@ -2081,7 +2111,6 @@ nextMultipleOf = \lhs, rhs ->
0 -> lhs
r -> lhs + (rhs - r)
isUnit : Shape -> Bool
isUnit = \shape ->
when shape is

View file

@ -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]

View file

@ -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);