mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 06:44:46 +00:00
correct codegen for calling the extern
This commit is contained in:
parent
1ac2c2bb80
commit
c622cebea6
4 changed files with 204 additions and 165 deletions
|
@ -637,7 +637,6 @@ fn add_tag_union(
|
||||||
types: &Types,
|
types: &Types,
|
||||||
impls: &mut Impls,
|
impls: &mut Impls,
|
||||||
) {
|
) {
|
||||||
dbg!("adding", name);
|
|
||||||
let name = escape_kw(name.to_string());
|
let name = escape_kw(name.to_string());
|
||||||
|
|
||||||
// We should never be attempting to generate glue for empty tag unions;
|
// We should never be attempting to generate glue for empty tag unions;
|
||||||
|
@ -1844,26 +1843,35 @@ fn add_function(
|
||||||
buf.push('\n');
|
buf.push('\n');
|
||||||
buf.push('\n');
|
buf.push('\n');
|
||||||
|
|
||||||
let arguments = "";
|
|
||||||
let argument_types = "";
|
|
||||||
let argument_names = "";
|
|
||||||
let extern_name = &roc_fn.extern_name;
|
let extern_name = &roc_fn.extern_name;
|
||||||
|
|
||||||
let return_type_str = type_name(roc_fn.ret, types);
|
let return_type_str = type_name(roc_fn.ret, types);
|
||||||
|
|
||||||
writeln!(buf, "impl {name} {{").unwrap();
|
writeln!(buf, "impl {name} {{").unwrap();
|
||||||
writeln!(
|
|
||||||
|
write!(buf, "{INDENT}pub fn force_thunk(self").unwrap();
|
||||||
|
for (i, argument_type) in roc_fn.args.iter().enumerate() {
|
||||||
|
write!(buf, ", arg_{i}: {}", type_name(*argument_type, types)).unwrap();
|
||||||
|
}
|
||||||
|
writeln!(buf, ") -> {return_type_str} {{").unwrap();
|
||||||
|
|
||||||
|
writeln!(buf, "{INDENT}{INDENT}extern \"C\" {{").unwrap();
|
||||||
|
|
||||||
|
// fn extern_name(output: *mut return_type, arg1: arg1_type, ..., closure_data: *mut u8);
|
||||||
|
write!(
|
||||||
buf,
|
buf,
|
||||||
"{INDENT}pub fn force_thunk(self, {arguments}) -> {return_type_str} {{"
|
"{INDENT}{INDENT}{INDENT} fn {extern_name}(output: *mut {return_type_str}, "
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
writeln!(buf, "{INDENT}{INDENT}extern \"C\" {{").unwrap();
|
for (i, argument_type) in roc_fn.args.iter().enumerate() {
|
||||||
writeln!(
|
write!(buf, "arg_{i}: {}, ", type_name(*argument_type, types)).unwrap();
|
||||||
buf,
|
}
|
||||||
"{INDENT}{INDENT}{INDENT} fn {extern_name}(output: *mut {return_type_str}, {argument_types}, closure_data: *mut u8);"
|
|
||||||
)
|
writeln!(buf, "closure_data: *mut u8);").unwrap();
|
||||||
.unwrap();
|
|
||||||
|
// {argument_types} "
|
||||||
|
|
||||||
writeln!(buf, "{INDENT}{INDENT}}}").unwrap();
|
writeln!(buf, "{INDENT}{INDENT}}}").unwrap();
|
||||||
|
|
||||||
writeln!(buf).unwrap();
|
writeln!(buf).unwrap();
|
||||||
|
@ -1874,12 +1882,18 @@ fn add_function(
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
writeln!(
|
write!(
|
||||||
buf,
|
buf,
|
||||||
"{INDENT}{INDENT}unsafe {{ {extern_name}(output.as_mut_ptr(), {argument_names}, self.closure_data) }};"
|
"{INDENT}{INDENT}unsafe {{ {extern_name}(output.as_mut_ptr(), "
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
for (i, _) in roc_fn.args.iter().enumerate() {
|
||||||
|
write!(buf, "arg_{i}, ").unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
writeln!(buf, "self.closure_data) }};").unwrap();
|
||||||
|
|
||||||
writeln!(buf, "{INDENT}{INDENT}unsafe {{ output.assume_init() }}").unwrap();
|
writeln!(buf, "{INDENT}{INDENT}unsafe {{ output.assume_init() }}").unwrap();
|
||||||
|
|
||||||
writeln!(buf, "{INDENT}}}").unwrap();
|
writeln!(buf, "{INDENT}}}").unwrap();
|
||||||
|
|
|
@ -1005,16 +1005,12 @@ fn add_type_help<'a>(
|
||||||
let extern_name = String::from("roc__mainForHost_1__Fx2_caller");
|
let extern_name = String::from("roc__mainForHost_1__Fx2_caller");
|
||||||
// let extern_name = env.extern_names.get(&lambda_set).cloned().unwrap();
|
// let extern_name = env.extern_names.get(&lambda_set).cloned().unwrap();
|
||||||
|
|
||||||
dbg!(&extern_name, &name);
|
|
||||||
|
|
||||||
for arg_var in args {
|
for arg_var in args {
|
||||||
let arg_layout = env
|
let arg_layout = env
|
||||||
.layout_cache
|
.layout_cache
|
||||||
.from_var(env.arena, *arg_var, env.subs)
|
.from_var(env.arena, *arg_var, env.subs)
|
||||||
.expect("Something weird ended up in the content");
|
.expect("Something weird ended up in the content");
|
||||||
|
|
||||||
dbg!(&arg_layout);
|
|
||||||
|
|
||||||
arg_type_ids.push(add_type_help(env, arg_layout, *arg_var, None, types));
|
arg_type_ids.push(add_type_help(env, arg_layout, *arg_var, None, types));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1027,8 +1023,6 @@ fn add_type_help<'a>(
|
||||||
.from_var(env.arena, *ret_var, env.subs)
|
.from_var(env.arena, *ret_var, env.subs)
|
||||||
.expect("Something weird ended up in the content");
|
.expect("Something weird ended up in the content");
|
||||||
|
|
||||||
dbg!(ret_layout);
|
|
||||||
|
|
||||||
add_type_help(env, ret_layout, *ret_var, None, types)
|
add_type_help(env, ret_layout, *ret_var, None, types)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1202,7 +1196,7 @@ fn add_type_help<'a>(
|
||||||
|
|
||||||
if tags.is_empty() {
|
if tags.is_empty() {
|
||||||
// this function does not capture anything. Represent that at runtime as a unit value
|
// this function does not capture anything. Represent that at runtime as a unit value
|
||||||
types.add_anonymous(&env.layout_cache.interner, RocType::Unit, layout)
|
types.add_anonymous(&env.layout_cache.interner, RocType::Unsized, layout)
|
||||||
} else {
|
} else {
|
||||||
add_tag_union(env, opt_name, &tags, var, types, layout, None)
|
add_tag_union(env, opt_name, &tags, var, types, layout, None)
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,7 @@ pub struct Op {
|
||||||
pointer: *mut union_Op,
|
pointer: *mut union_Op,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
target_arch = "arm",
|
target_arch = "arm",
|
||||||
target_arch = "aarch64",
|
target_arch = "aarch64",
|
||||||
|
@ -86,6 +87,7 @@ union union_Op {
|
||||||
target_arch = "x86_64"
|
target_arch = "x86_64"
|
||||||
))]
|
))]
|
||||||
//TODO HAS CLOSURE 2
|
//TODO HAS CLOSURE 2
|
||||||
|
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
target_arch = "arm",
|
target_arch = "arm",
|
||||||
target_arch = "aarch64",
|
target_arch = "aarch64",
|
||||||
|
@ -93,20 +95,20 @@ union union_Op {
|
||||||
target_arch = "x86",
|
target_arch = "x86",
|
||||||
target_arch = "x86_64"
|
target_arch = "x86_64"
|
||||||
))]
|
))]
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct RocFunction_65<'a> {
|
pub struct RocFunction_65 {
|
||||||
closure_data: *const u8,
|
pub closure_data: *mut u8,
|
||||||
_marker: std::marker::PhantomData<&'a ()>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> RocFunction_65<'a> {
|
impl RocFunction_65 {
|
||||||
pub fn force_thunk(self) -> Op {
|
pub fn force_thunk(self, arg_0: ()) -> Op {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn roc__mainForHost_1__Fx2_caller(output: *mut Op, input: *const u8);
|
fn roc__mainForHost_1__Fx2_caller(output: *mut Op, arg_0: (), closure_data: *mut u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut output = std::mem::MaybeUninit::uninit();
|
let mut output = std::mem::MaybeUninit::uninit();
|
||||||
unsafe { roc__mainForHost_1__Fx2_caller(output.as_mut_ptr(), self.closure_data) };
|
unsafe { roc__mainForHost_1__Fx2_caller(output.as_mut_ptr(), arg_0, self.closure_data) };
|
||||||
unsafe { output.assume_init() }
|
unsafe { output.assume_init() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,19 +120,20 @@ impl<'a> RocFunction_65<'a> {
|
||||||
target_arch = "x86",
|
target_arch = "x86",
|
||||||
target_arch = "x86_64"
|
target_arch = "x86_64"
|
||||||
))]
|
))]
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct RocFunction_67 {
|
pub struct RocFunction_67 {
|
||||||
pub closure_data: (),
|
pub closure_data: *mut u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RocFunction_67 {
|
impl RocFunction_67 {
|
||||||
pub fn force_thunk(self) -> Op {
|
pub fn force_thunk(self, arg_0: ()) -> Op {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn roc__mainForHost_1__Fx2_caller(output: *mut Op);
|
fn roc__mainForHost_1__Fx2_caller(output: *mut Op, arg_0: (), closure_data: *mut u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut output = std::mem::MaybeUninit::uninit();
|
let mut output = std::mem::MaybeUninit::uninit();
|
||||||
unsafe { roc__mainForHost_1__Fx2_caller(output.as_mut_ptr()) };
|
unsafe { roc__mainForHost_1__Fx2_caller(output.as_mut_ptr(), arg_0, self.closure_data) };
|
||||||
unsafe { output.assume_init() }
|
unsafe { output.assume_init() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,18 +161,28 @@ impl Op {
|
||||||
if untagged.is_null() {
|
if untagged.is_null() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
unsafe { Some(&*untagged.sub(1)) }
|
unsafe {
|
||||||
|
Some(&*untagged.sub(1))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))]
|
#[cfg(any(
|
||||||
|
target_arch = "arm",
|
||||||
|
target_arch = "wasm32",
|
||||||
|
target_arch = "x86"
|
||||||
|
))]
|
||||||
/// Returns which variant this tag union holds. Note that this never includes a payload!
|
/// Returns which variant this tag union holds. Note that this never includes a payload!
|
||||||
pub fn discriminant(&self) -> discriminant_Op {
|
pub fn discriminant(&self) -> discriminant_Op {
|
||||||
// The discriminant is stored in the unused bytes at the end of the recursive pointer
|
// The discriminant is stored in the unused bytes at the end of the recursive pointer
|
||||||
unsafe { core::mem::transmute::<u8, discriminant_Op>((self.pointer as u8) & 0b11) }
|
unsafe { core::mem::transmute::<u8, discriminant_Op>((self.pointer as u8) & 0b11) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))]
|
#[cfg(any(
|
||||||
|
target_arch = "arm",
|
||||||
|
target_arch = "wasm32",
|
||||||
|
target_arch = "x86"
|
||||||
|
))]
|
||||||
/// Internal helper
|
/// Internal helper
|
||||||
fn tag_discriminant(pointer: *mut union_Op, discriminant: discriminant_Op) -> *mut union_Op {
|
fn tag_discriminant(pointer: *mut union_Op, discriminant: discriminant_Op) -> *mut union_Op {
|
||||||
// The discriminant is stored in the unused bytes at the end of the union pointer
|
// The discriminant is stored in the unused bytes at the end of the union pointer
|
||||||
|
@ -179,7 +192,11 @@ impl Op {
|
||||||
tagged as *mut union_Op
|
tagged as *mut union_Op
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))]
|
#[cfg(any(
|
||||||
|
target_arch = "arm",
|
||||||
|
target_arch = "wasm32",
|
||||||
|
target_arch = "x86"
|
||||||
|
))]
|
||||||
/// Internal helper
|
/// Internal helper
|
||||||
fn union_pointer(&self) -> *mut union_Op {
|
fn union_pointer(&self) -> *mut union_Op {
|
||||||
// The discriminant is stored in the unused bytes at the end of the union pointer
|
// The discriminant is stored in the unused bytes at the end of the union pointer
|
||||||
|
@ -264,7 +281,7 @@ impl Op {
|
||||||
let ptr = roc_std::roc_alloc_refcounted::<union_Op>();
|
let ptr = roc_std::roc_alloc_refcounted::<union_Op>();
|
||||||
|
|
||||||
*ptr = union_Op {
|
*ptr = union_Op {
|
||||||
StderrWrite: core::mem::ManuallyDrop::new(arg),
|
StderrWrite: core::mem::ManuallyDrop::new(arg)
|
||||||
};
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
@ -273,7 +290,11 @@ impl Op {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))]
|
#[cfg(any(
|
||||||
|
target_arch = "arm",
|
||||||
|
target_arch = "wasm32",
|
||||||
|
target_arch = "x86"
|
||||||
|
))]
|
||||||
/// Unsafely assume this `Op` has a `.discriminant()` of `StderrWrite` and convert it to `StderrWrite`'s payload.
|
/// Unsafely assume this `Op` has a `.discriminant()` of `StderrWrite` and convert it to `StderrWrite`'s payload.
|
||||||
/// (Always examine `.discriminant()` first to make sure this is the correct variant!)
|
/// (Always examine `.discriminant()` first to make sure this is the correct variant!)
|
||||||
/// Panics in debug builds if the `.discriminant()` doesn't return `StderrWrite`.
|
/// Panics in debug builds if the `.discriminant()` doesn't return `StderrWrite`.
|
||||||
|
@ -297,7 +318,11 @@ impl Op {
|
||||||
payload
|
payload
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))]
|
#[cfg(any(
|
||||||
|
target_arch = "arm",
|
||||||
|
target_arch = "wasm32",
|
||||||
|
target_arch = "x86"
|
||||||
|
))]
|
||||||
/// Unsafely assume this `Op` has a `.discriminant()` of `StderrWrite` and return its payload.
|
/// Unsafely assume this `Op` has a `.discriminant()` of `StderrWrite` and return its payload.
|
||||||
/// (Always examine `.discriminant()` first to make sure this is the correct variant!)
|
/// (Always examine `.discriminant()` first to make sure this is the correct variant!)
|
||||||
/// Panics in debug builds if the `.discriminant()` doesn't return `StderrWrite`.
|
/// Panics in debug builds if the `.discriminant()` doesn't return `StderrWrite`.
|
||||||
|
@ -352,16 +377,14 @@ impl Op {
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#[link_name = "roc__getter__3"]
|
#[link_name = "roc__getter__3"]
|
||||||
fn getter(_: *const Op) -> *const u8;
|
fn getter(_: *mut RocFunction_65, _: *const Op);
|
||||||
// fn getter(_: *mut RocFunction_65, _: *const Op);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let ptr = getter(self);
|
let mut ret = core::mem::MaybeUninit::uninit();
|
||||||
|
|
||||||
RocFunction_65 {
|
getter(ret.as_mut_ptr(), self);
|
||||||
closure_data: ptr,
|
|
||||||
_marker: Default::default(),
|
ret.assume_init()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
|
@ -380,7 +403,7 @@ impl Op {
|
||||||
let ptr = roc_std::roc_alloc_refcounted::<union_Op>();
|
let ptr = roc_std::roc_alloc_refcounted::<union_Op>();
|
||||||
|
|
||||||
*ptr = union_Op {
|
*ptr = union_Op {
|
||||||
StdoutWrite: core::mem::ManuallyDrop::new(arg),
|
StdoutWrite: core::mem::ManuallyDrop::new(arg)
|
||||||
};
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
@ -389,7 +412,11 @@ impl Op {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))]
|
#[cfg(any(
|
||||||
|
target_arch = "arm",
|
||||||
|
target_arch = "wasm32",
|
||||||
|
target_arch = "x86"
|
||||||
|
))]
|
||||||
/// Unsafely assume this `Op` has a `.discriminant()` of `StdoutWrite` and convert it to `StdoutWrite`'s payload.
|
/// Unsafely assume this `Op` has a `.discriminant()` of `StdoutWrite` and convert it to `StdoutWrite`'s payload.
|
||||||
/// (Always examine `.discriminant()` first to make sure this is the correct variant!)
|
/// (Always examine `.discriminant()` first to make sure this is the correct variant!)
|
||||||
/// Panics in debug builds if the `.discriminant()` doesn't return `StdoutWrite`.
|
/// Panics in debug builds if the `.discriminant()` doesn't return `StdoutWrite`.
|
||||||
|
@ -413,7 +440,11 @@ impl Op {
|
||||||
payload
|
payload
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_arch = "arm", target_arch = "wasm32", target_arch = "x86"))]
|
#[cfg(any(
|
||||||
|
target_arch = "arm",
|
||||||
|
target_arch = "wasm32",
|
||||||
|
target_arch = "x86"
|
||||||
|
))]
|
||||||
/// Unsafely assume this `Op` has a `.discriminant()` of `StdoutWrite` and return its payload.
|
/// Unsafely assume this `Op` has a `.discriminant()` of `StdoutWrite` and return its payload.
|
||||||
/// (Always examine `.discriminant()` first to make sure this is the correct variant!)
|
/// (Always examine `.discriminant()` first to make sure this is the correct variant!)
|
||||||
/// Panics in debug builds if the `.discriminant()` doesn't return `StdoutWrite`.
|
/// Panics in debug builds if the `.discriminant()` doesn't return `StdoutWrite`.
|
||||||
|
@ -428,14 +459,20 @@ impl Op {
|
||||||
&payload
|
&payload
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
|
#[cfg(any(
|
||||||
|
target_arch = "aarch64",
|
||||||
|
target_arch = "x86_64"
|
||||||
|
))]
|
||||||
/// Returns which variant this tag union holds. Note that this never includes a payload!
|
/// Returns which variant this tag union holds. Note that this never includes a payload!
|
||||||
pub fn discriminant(&self) -> discriminant_Op {
|
pub fn discriminant(&self) -> discriminant_Op {
|
||||||
// The discriminant is stored in the unused bytes at the end of the recursive pointer
|
// The discriminant is stored in the unused bytes at the end of the recursive pointer
|
||||||
unsafe { core::mem::transmute::<u8, discriminant_Op>((self.pointer as u8) & 0b111) }
|
unsafe { core::mem::transmute::<u8, discriminant_Op>((self.pointer as u8) & 0b111) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
|
#[cfg(any(
|
||||||
|
target_arch = "aarch64",
|
||||||
|
target_arch = "x86_64"
|
||||||
|
))]
|
||||||
/// Internal helper
|
/// Internal helper
|
||||||
fn tag_discriminant(pointer: *mut union_Op, discriminant: discriminant_Op) -> *mut union_Op {
|
fn tag_discriminant(pointer: *mut union_Op, discriminant: discriminant_Op) -> *mut union_Op {
|
||||||
// The discriminant is stored in the unused bytes at the end of the union pointer
|
// The discriminant is stored in the unused bytes at the end of the union pointer
|
||||||
|
@ -445,14 +482,20 @@ impl Op {
|
||||||
tagged as *mut union_Op
|
tagged as *mut union_Op
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
|
#[cfg(any(
|
||||||
|
target_arch = "aarch64",
|
||||||
|
target_arch = "x86_64"
|
||||||
|
))]
|
||||||
/// Internal helper
|
/// Internal helper
|
||||||
fn union_pointer(&self) -> *mut union_Op {
|
fn union_pointer(&self) -> *mut union_Op {
|
||||||
// The discriminant is stored in the unused bytes at the end of the union pointer
|
// The discriminant is stored in the unused bytes at the end of the union pointer
|
||||||
((self.pointer as usize) & (!0b111 as usize)) as *mut union_Op
|
((self.pointer as usize) & (!0b111 as usize)) as *mut union_Op
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
|
#[cfg(any(
|
||||||
|
target_arch = "aarch64",
|
||||||
|
target_arch = "x86_64"
|
||||||
|
))]
|
||||||
/// Unsafely assume this `Op` has a `.discriminant()` of `StderrWrite` and convert it to `StderrWrite`'s payload.
|
/// Unsafely assume this `Op` has a `.discriminant()` of `StderrWrite` and convert it to `StderrWrite`'s payload.
|
||||||
/// (Always examine `.discriminant()` first to make sure this is the correct variant!)
|
/// (Always examine `.discriminant()` first to make sure this is the correct variant!)
|
||||||
/// Panics in debug builds if the `.discriminant()` doesn't return `StderrWrite`.
|
/// Panics in debug builds if the `.discriminant()` doesn't return `StderrWrite`.
|
||||||
|
@ -476,7 +519,10 @@ impl Op {
|
||||||
payload
|
payload
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
|
#[cfg(any(
|
||||||
|
target_arch = "aarch64",
|
||||||
|
target_arch = "x86_64"
|
||||||
|
))]
|
||||||
/// Unsafely assume this `Op` has a `.discriminant()` of `StderrWrite` and return its payload.
|
/// Unsafely assume this `Op` has a `.discriminant()` of `StderrWrite` and return its payload.
|
||||||
/// (Always examine `.discriminant()` first to make sure this is the correct variant!)
|
/// (Always examine `.discriminant()` first to make sure this is the correct variant!)
|
||||||
/// Panics in debug builds if the `.discriminant()` doesn't return `StderrWrite`.
|
/// Panics in debug builds if the `.discriminant()` doesn't return `StderrWrite`.
|
||||||
|
@ -491,7 +537,10 @@ impl Op {
|
||||||
&payload
|
&payload
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
|
#[cfg(any(
|
||||||
|
target_arch = "aarch64",
|
||||||
|
target_arch = "x86_64"
|
||||||
|
))]
|
||||||
/// Unsafely assume this `Op` has a `.discriminant()` of `StdoutWrite` and convert it to `StdoutWrite`'s payload.
|
/// Unsafely assume this `Op` has a `.discriminant()` of `StdoutWrite` and convert it to `StdoutWrite`'s payload.
|
||||||
/// (Always examine `.discriminant()` first to make sure this is the correct variant!)
|
/// (Always examine `.discriminant()` first to make sure this is the correct variant!)
|
||||||
/// Panics in debug builds if the `.discriminant()` doesn't return `StdoutWrite`.
|
/// Panics in debug builds if the `.discriminant()` doesn't return `StdoutWrite`.
|
||||||
|
@ -515,7 +564,10 @@ impl Op {
|
||||||
payload
|
payload
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
|
#[cfg(any(
|
||||||
|
target_arch = "aarch64",
|
||||||
|
target_arch = "x86_64"
|
||||||
|
))]
|
||||||
/// Unsafely assume this `Op` has a `.discriminant()` of `StdoutWrite` and return its payload.
|
/// Unsafely assume this `Op` has a `.discriminant()` of `StdoutWrite` and return its payload.
|
||||||
/// (Always examine `.discriminant()` first to make sure this is the correct variant!)
|
/// (Always examine `.discriminant()` first to make sure this is the correct variant!)
|
||||||
/// Panics in debug builds if the `.discriminant()` doesn't return `StdoutWrite`.
|
/// Panics in debug builds if the `.discriminant()` doesn't return `StdoutWrite`.
|
||||||
|
@ -551,21 +603,15 @@ impl Drop for Op {
|
||||||
// Drop the payload first.
|
// Drop the payload first.
|
||||||
match self.discriminant() {
|
match self.discriminant() {
|
||||||
discriminant_Op::Done => {}
|
discriminant_Op::Done => {}
|
||||||
discriminant_Op::StderrWrite => unsafe {
|
discriminant_Op::StderrWrite => unsafe { core::mem::ManuallyDrop::drop(&mut (&mut *self.union_pointer()).StderrWrite) },
|
||||||
core::mem::ManuallyDrop::drop(&mut (&mut *self.union_pointer()).StderrWrite)
|
discriminant_Op::StdoutWrite => unsafe { core::mem::ManuallyDrop::drop(&mut (&mut *self.union_pointer()).StdoutWrite) },
|
||||||
},
|
|
||||||
discriminant_Op::StdoutWrite => unsafe {
|
|
||||||
core::mem::ManuallyDrop::drop(&mut (&mut *self.union_pointer()).StdoutWrite)
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Dealloc the pointer
|
// Dealloc the pointer
|
||||||
let alignment =
|
let alignment = core::mem::align_of::<Self>().max(core::mem::align_of::<roc_std::Storage>());
|
||||||
core::mem::align_of::<Self>().max(core::mem::align_of::<roc_std::Storage>());
|
|
||||||
|
|
||||||
unsafe {
|
unsafe { crate::roc_dealloc(storage.as_ptr().cast(), alignment as u32); }
|
||||||
crate::roc_dealloc(storage.as_ptr().cast(), alignment as u32);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Write the storage back.
|
// Write the storage back.
|
||||||
storage.set(new_storage);
|
storage.set(new_storage);
|
||||||
|
@ -592,12 +638,8 @@ impl PartialEq for Op {
|
||||||
unsafe {
|
unsafe {
|
||||||
match self.discriminant() {
|
match self.discriminant() {
|
||||||
discriminant_Op::Done => true,
|
discriminant_Op::Done => true,
|
||||||
discriminant_Op::StderrWrite => {
|
discriminant_Op::StderrWrite => (&*self.union_pointer()).StderrWrite == (&*other.union_pointer()).StderrWrite,
|
||||||
(&*self.union_pointer()).StderrWrite == (&*other.union_pointer()).StderrWrite
|
discriminant_Op::StdoutWrite => (&*self.union_pointer()).StdoutWrite == (&*other.union_pointer()).StdoutWrite,
|
||||||
}
|
|
||||||
discriminant_Op::StdoutWrite => {
|
|
||||||
(&*self.union_pointer()).StdoutWrite == (&*other.union_pointer()).StdoutWrite
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -620,12 +662,8 @@ impl PartialOrd for Op {
|
||||||
unsafe {
|
unsafe {
|
||||||
match self.discriminant() {
|
match self.discriminant() {
|
||||||
discriminant_Op::Done => Some(core::cmp::Ordering::Equal),
|
discriminant_Op::Done => Some(core::cmp::Ordering::Equal),
|
||||||
discriminant_Op::StderrWrite => (&*self.union_pointer())
|
discriminant_Op::StderrWrite => (&*self.union_pointer()).StderrWrite.partial_cmp(&(&*other.union_pointer()).StderrWrite),
|
||||||
.StderrWrite
|
discriminant_Op::StdoutWrite => (&*self.union_pointer()).StdoutWrite.partial_cmp(&(&*other.union_pointer()).StdoutWrite),
|
||||||
.partial_cmp(&(&*other.union_pointer()).StderrWrite),
|
|
||||||
discriminant_Op::StdoutWrite => (&*self.union_pointer())
|
|
||||||
.StdoutWrite
|
|
||||||
.partial_cmp(&(&*other.union_pointer()).StdoutWrite),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -648,12 +686,8 @@ impl Ord for Op {
|
||||||
unsafe {
|
unsafe {
|
||||||
match self.discriminant() {
|
match self.discriminant() {
|
||||||
discriminant_Op::Done => core::cmp::Ordering::Equal,
|
discriminant_Op::Done => core::cmp::Ordering::Equal,
|
||||||
discriminant_Op::StderrWrite => (&*self.union_pointer())
|
discriminant_Op::StderrWrite => (&*self.union_pointer()).StderrWrite.cmp(&(&*other.union_pointer()).StderrWrite),
|
||||||
.StderrWrite
|
discriminant_Op::StdoutWrite => (&*self.union_pointer()).StdoutWrite.cmp(&(&*other.union_pointer()).StdoutWrite),
|
||||||
.cmp(&(&*other.union_pointer()).StderrWrite),
|
|
||||||
discriminant_Op::StdoutWrite => (&*self.union_pointer())
|
|
||||||
.StdoutWrite
|
|
||||||
.cmp(&(&*other.union_pointer()).StdoutWrite),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -677,7 +711,7 @@ impl Clone for Op {
|
||||||
}
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
pointer: self.pointer,
|
pointer: self.pointer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -690,8 +724,7 @@ impl core::hash::Hash for Op {
|
||||||
target_arch = "x86",
|
target_arch = "x86",
|
||||||
target_arch = "x86_64"
|
target_arch = "x86_64"
|
||||||
))]
|
))]
|
||||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
fn hash<H: core::hash::Hasher>(&self, state: &mut H) { match self.discriminant() {
|
||||||
match self.discriminant() {
|
|
||||||
discriminant_Op::Done => discriminant_Op::Done.hash(state),
|
discriminant_Op::Done => discriminant_Op::Done.hash(state),
|
||||||
discriminant_Op::StderrWrite => unsafe {
|
discriminant_Op::StderrWrite => unsafe {
|
||||||
discriminant_Op::StderrWrite.hash(state);
|
discriminant_Op::StderrWrite.hash(state);
|
||||||
|
@ -719,12 +752,10 @@ impl core::fmt::Debug for Op {
|
||||||
unsafe {
|
unsafe {
|
||||||
match self.discriminant() {
|
match self.discriminant() {
|
||||||
discriminant_Op::Done => f.write_str("Done"),
|
discriminant_Op::Done => f.write_str("Done"),
|
||||||
discriminant_Op::StderrWrite => f
|
discriminant_Op::StderrWrite => f.debug_tuple("StderrWrite")
|
||||||
.debug_tuple("StderrWrite")
|
|
||||||
// TODO HAS CLOSURE
|
// TODO HAS CLOSURE
|
||||||
.finish(),
|
.finish(),
|
||||||
discriminant_Op::StdoutWrite => f
|
discriminant_Op::StdoutWrite => f.debug_tuple("StdoutWrite")
|
||||||
.debug_tuple("StdoutWrite")
|
|
||||||
// TODO HAS CLOSURE
|
// TODO HAS CLOSURE
|
||||||
.finish(),
|
.finish(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,7 +105,7 @@ pub extern "C" fn rust_main() -> i32 {
|
||||||
match dbg!(op.discriminant()) {
|
match dbg!(op.discriminant()) {
|
||||||
StdoutWrite => {
|
StdoutWrite => {
|
||||||
let output: RocStr = unsafe { op.get_StdoutWrite_0() };
|
let output: RocStr = unsafe { op.get_StdoutWrite_0() };
|
||||||
op = unsafe { op.get_StdoutWrite_1().force_thunk() };
|
op = unsafe { op.get_StdoutWrite_1().force_thunk(()) };
|
||||||
|
|
||||||
dbg!(&output);
|
dbg!(&output);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue