mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 00:24:34 +00:00
skeleton for unsized glue
This commit is contained in:
parent
2bd998a215
commit
609d76529a
3 changed files with 56 additions and 28 deletions
|
@ -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 },
|
||||||
|
@ -50,7 +52,7 @@ staticFiles =
|
||||||
{ name: "roc_std/src/roc_set.rs", content: rocStdSet },
|
{ name: "roc_std/src/roc_set.rs", content: rocStdSet },
|
||||||
{ name: "roc_std/src/roc_str.rs", content: rocStdStr },
|
{ name: "roc_std/src/roc_str.rs", content: rocStdStr },
|
||||||
{ name: "roc_std/src/storage.rs", content: rocStdStorage },
|
{ name: "roc_std/src/storage.rs", content: rocStdStorage },
|
||||||
]
|
]
|
||||||
|
|
||||||
convertTypesToFile : Types -> File
|
convertTypesToFile : Types -> File
|
||||||
convertTypesToFile = \types ->
|
convertTypesToFile = \types ->
|
||||||
|
@ -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
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue