mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 19:58:18 +00:00
Merge pull request #5763 from roc-lang/glue-unsized-skeleton
skeleton for unsized glue
This commit is contained in:
commit
738e54ebba
3 changed files with 56 additions and 28 deletions
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue