mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 16:44:33 +00:00
generate signature for the entry points
This commit is contained in:
parent
d42e831e47
commit
3ff17aa0ea
11 changed files with 150 additions and 92 deletions
|
@ -1,5 +1,5 @@
|
||||||
interface Types
|
interface Types
|
||||||
exposes [Types, shape, size, alignment, target, walkShapes]
|
exposes [Types, shape, size, alignment, target, walkShapes, entryPoints]
|
||||||
imports [Shape.{ Shape }, TypeId.{ TypeId }, Target.{ Target }, InternalTypeId]
|
imports [Shape.{ Shape }, TypeId.{ TypeId }, Target.{ Target }, InternalTypeId]
|
||||||
|
|
||||||
# TODO: switch AssocList uses to Dict once roc_std is updated.
|
# TODO: switch AssocList uses to Dict once roc_std is updated.
|
||||||
|
@ -19,12 +19,19 @@ Types := {
|
||||||
## This is important for declaration order in C; we need to output a
|
## This is important for declaration order in C; we need to output a
|
||||||
## type declaration earlier in the file than where it gets referenced by another type.
|
## type declaration earlier in the file than where it gets referenced by another type.
|
||||||
deps : List Tuple2,
|
deps : List Tuple2,
|
||||||
|
|
||||||
|
## Names and types of the entry points of the program (e.g. mainForHost)
|
||||||
|
entrypoints : List Tuple1,
|
||||||
|
|
||||||
target : Target,
|
target : Target,
|
||||||
}
|
}
|
||||||
|
|
||||||
target : Types -> Target
|
target : Types -> Target
|
||||||
target = \@Types types -> types.target
|
target = \@Types types -> types.target
|
||||||
|
|
||||||
|
entryPoints : Types -> List Tuple1
|
||||||
|
entryPoints = \@Types { entrypoints} -> entrypoints
|
||||||
|
|
||||||
walkShapes : Types, state, (state, Shape, TypeId -> state) -> state
|
walkShapes : Types, state, (state, Shape, TypeId -> state) -> state
|
||||||
walkShapes = \@Types { types: shapes }, originalState, update ->
|
walkShapes = \@Types { types: shapes }, originalState, update ->
|
||||||
List.walk shapes { index: 0, state: originalState } \{ index, state }, elem ->
|
List.walk shapes { index: 0, state: originalState } \{ index, state }, elem ->
|
||||||
|
|
|
@ -8,7 +8,7 @@ makeGlue = \typesByArch ->
|
||||||
modFileContent =
|
modFileContent =
|
||||||
List.walk typesByArch "" \content, types ->
|
List.walk typesByArch "" \content, types ->
|
||||||
arch = (Types.target types).architecture
|
arch = (Types.target types).architecture
|
||||||
archStr = archName arch
|
archStr = archName arch
|
||||||
|
|
||||||
Str.concat
|
Str.concat
|
||||||
content
|
content
|
||||||
|
@ -17,7 +17,7 @@ makeGlue = \typesByArch ->
|
||||||
mod \(archStr);
|
mod \(archStr);
|
||||||
#[cfg(target_arch = "\(archStr)")]
|
#[cfg(target_arch = "\(archStr)")]
|
||||||
pub use \(archStr)::*;
|
pub use \(archStr)::*;
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
typesByArch
|
typesByArch
|
||||||
|
@ -88,13 +88,90 @@ convertTypesToFile = \types ->
|
||||||
buf
|
buf
|
||||||
|
|
||||||
arch = (Types.target types).architecture
|
arch = (Types.target types).architecture
|
||||||
archStr = archName arch
|
archStr = archName arch
|
||||||
|
|
||||||
{
|
{
|
||||||
name: "\(archStr).rs",
|
name: "\(archStr).rs",
|
||||||
content,
|
content: content |> generateEntryPoints types,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
generateEntryPoints: Str, Types -> Str
|
||||||
|
generateEntryPoints = \buf, types ->
|
||||||
|
List.walk (Types.entryPoints types) buf \accum, T name id -> generateEntryPoint accum types name id
|
||||||
|
|
||||||
|
generateEntryPoint: Str, Types, Str, TypeId -> Str
|
||||||
|
generateEntryPoint = \buf, types, name, id ->
|
||||||
|
# functionName: Str,
|
||||||
|
# externName: Str,
|
||||||
|
# args: List TypeId,
|
||||||
|
# lambdaSet: TypeId,
|
||||||
|
# ret: TypeId,
|
||||||
|
|
||||||
|
|
||||||
|
publicSignature =
|
||||||
|
when Types.shape types id is
|
||||||
|
Function rocFn ->
|
||||||
|
arguments =
|
||||||
|
rocFn.args
|
||||||
|
|> List.mapWithIndex \i, argId ->
|
||||||
|
type = typeName types argId
|
||||||
|
c = Num.toStr i
|
||||||
|
"arg\(c): \(type)"
|
||||||
|
|> Str.joinWith ", "
|
||||||
|
|
||||||
|
ret = typeName types rocFn.ret
|
||||||
|
|
||||||
|
"(\(arguments)) -> \(ret)"
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
ret = typeName types id
|
||||||
|
"() -> \(ret)"
|
||||||
|
|
||||||
|
externSignature =
|
||||||
|
when Types.shape types id is
|
||||||
|
Function rocFn ->
|
||||||
|
arguments =
|
||||||
|
rocFn.args
|
||||||
|
|> List.map \argId ->
|
||||||
|
type = typeName types argId
|
||||||
|
"_: \(type)"
|
||||||
|
|> Str.joinWith ", "
|
||||||
|
|
||||||
|
ret = typeName types rocFn.ret
|
||||||
|
"(_: *mut \(ret), \(arguments))"
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
ret = typeName types id
|
||||||
|
"(_: *mut \(ret))"
|
||||||
|
|
||||||
|
externArguments =
|
||||||
|
when Types.shape types id is
|
||||||
|
Function rocFn ->
|
||||||
|
rocFn.args
|
||||||
|
|> List.mapWithIndex \i, _ ->
|
||||||
|
c = Num.toStr i
|
||||||
|
"arg\(c)"
|
||||||
|
|> Str.joinWith ", "
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
""
|
||||||
|
|
||||||
|
"""
|
||||||
|
\(buf)
|
||||||
|
|
||||||
|
pub fn \(name)\(publicSignature) {
|
||||||
|
extern "C" {
|
||||||
|
fn roc__\(name)_1_exposed_generic\(externSignature);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut ret = std::mem::MaybeUninit::uninit();
|
||||||
|
|
||||||
|
unsafe { roc__\(name)_1_exposed_generic(ret.as_mut_ptr(), \(externArguments)) };
|
||||||
|
|
||||||
|
unsafe { ret.assume_init() }
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
generateStruct : Str, Types, TypeId, _, _, _ -> Str
|
generateStruct : Str, Types, TypeId, _, _, _ -> Str
|
||||||
generateStruct = \buf, types, id, name, structFields, visibility ->
|
generateStruct = \buf, types, id, name, structFields, visibility ->
|
||||||
escapedName = escapeKW name
|
escapedName = escapeKW name
|
||||||
|
@ -169,7 +246,7 @@ generateEnumeration = \buf, types, enumType, name, tags, tagBytes ->
|
||||||
impl core::fmt::Debug for \(escapedName) {
|
impl core::fmt::Debug for \(escapedName) {
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|> \b -> List.walk tags b (generateEnumTagsDebug name)
|
|> \b -> List.walk tags b (generateEnumTagsDebug name)
|
||||||
|> Str.concat "\(indent)\(indent)}\n\(indent)}\n}\n\n"
|
|> Str.concat "\(indent)\(indent)}\n\(indent)}\n}\n\n"
|
||||||
|
@ -222,7 +299,7 @@ generateNonRecursiveTagUnion = \buf, types, id, name, tags, discriminantSize, di
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|> Str.concat "// TODO: NonRecursive TagUnion constructor impls\n\n"
|
|> Str.concat "// TODO: NonRecursive TagUnion constructor impls\n\n"
|
||||||
|> \b ->
|
|> \b ->
|
||||||
|
@ -235,7 +312,7 @@ generateNonRecursiveTagUnion = \buf, types, id, name, tags, discriminantSize, di
|
||||||
impl Drop for \(escapedName) {
|
impl Drop for \(escapedName) {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
// Drop the payloads
|
// Drop the payloads
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|> generateTagUnionDropPayload types selfMut tags discriminantName discriminantSize 2
|
|> generateTagUnionDropPayload types selfMut tags discriminantName discriminantSize 2
|
||||||
|> Str.concat
|
|> Str.concat
|
||||||
|
@ -243,7 +320,7 @@ generateNonRecursiveTagUnion = \buf, types, id, name, tags, discriminantSize, di
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
else
|
else
|
||||||
b
|
b
|
||||||
|
@ -428,7 +505,7 @@ generateMultiElementSingleTagStruct = \buf, types, name, tagName, payloadFields,
|
||||||
|> Str.concat
|
|> Str.concat
|
||||||
"""
|
"""
|
||||||
impl \(name) {
|
impl \(name) {
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|> \b ->
|
|> \b ->
|
||||||
fieldTypes =
|
fieldTypes =
|
||||||
|
@ -475,7 +552,7 @@ generateMultiElementSingleTagStruct = \buf, types, name, tagName, payloadFields,
|
||||||
\(indent) }
|
\(indent) }
|
||||||
\(indent)}
|
\(indent)}
|
||||||
|
|
||||||
|
|
||||||
""",
|
""",
|
||||||
fieldTypes,
|
fieldTypes,
|
||||||
fieldAccesses,
|
fieldAccesses,
|
||||||
|
@ -494,7 +571,7 @@ generateMultiElementSingleTagStruct = \buf, types, name, tagName, payloadFields,
|
||||||
\(indent) \(retExpr)
|
\(indent) \(retExpr)
|
||||||
\(indent)}
|
\(indent)}
|
||||||
|
|
||||||
|
|
||||||
""",
|
""",
|
||||||
fieldTypes,
|
fieldTypes,
|
||||||
fieldAccesses,
|
fieldAccesses,
|
||||||
|
@ -517,7 +594,7 @@ generateMultiElementSingleTagStruct = \buf, types, name, tagName, payloadFields,
|
||||||
\(indent)pub fn as_\(tagName)(&self) -> \(retType) {
|
\(indent)pub fn as_\(tagName)(&self) -> \(retType) {
|
||||||
\(indent) \(retExpr)
|
\(indent) \(retExpr)
|
||||||
\(indent)}
|
\(indent)}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|> Str.concat
|
|> Str.concat
|
||||||
"""
|
"""
|
||||||
|
@ -527,7 +604,7 @@ generateMultiElementSingleTagStruct = \buf, types, name, tagName, payloadFields,
|
||||||
impl core::fmt::Debug for \(name) {
|
impl core::fmt::Debug for \(name) {
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
f.debug_tuple("\(name)::\(tagName)")
|
f.debug_tuple("\(name)::\(tagName)")
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|> \b ->
|
|> \b ->
|
||||||
payloadFields
|
payloadFields
|
||||||
|
@ -542,7 +619,7 @@ generateMultiElementSingleTagStruct = \buf, types, name, tagName, payloadFields,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
asRustTuple = \list ->
|
asRustTuple = \list ->
|
||||||
|
@ -585,7 +662,7 @@ generateZeroElementSingleTagStruct = \buf, name, tagName ->
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
generateDeriveStr = \buf, types, type, includeDebug ->
|
generateDeriveStr = \buf, types, type, includeDebug ->
|
||||||
|
@ -854,7 +931,7 @@ fileHeader =
|
||||||
#![allow(clippy::clone_on_copy)]
|
#![allow(clippy::clone_on_copy)]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
indent = " "
|
indent = " "
|
||||||
|
|
|
@ -453,7 +453,7 @@ pub fn load_types(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let types = Types::new(
|
let types = Types::new_with_entry_points(
|
||||||
arena,
|
arena,
|
||||||
subs,
|
subs,
|
||||||
variables.clone(),
|
variables.clone(),
|
||||||
|
@ -461,6 +461,7 @@ pub fn load_types(
|
||||||
glue_procs_by_layout,
|
glue_procs_by_layout,
|
||||||
layout_cache,
|
layout_cache,
|
||||||
target_info,
|
target_info,
|
||||||
|
exposed_to_host.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
arch_types.push(types);
|
arch_types.push(types);
|
||||||
|
|
|
@ -42,6 +42,7 @@ pub struct File {
|
||||||
pub struct Types {
|
pub struct Types {
|
||||||
pub aligns: roc_std::RocList<u32>,
|
pub aligns: roc_std::RocList<u32>,
|
||||||
pub deps: roc_std::RocList<Tuple2>,
|
pub deps: roc_std::RocList<Tuple2>,
|
||||||
|
pub entrypoints: roc_std::RocList<Tuple1>,
|
||||||
pub sizes: roc_std::RocList<u32>,
|
pub sizes: roc_std::RocList<u32>,
|
||||||
pub types: roc_std::RocList<RocType>,
|
pub types: roc_std::RocList<RocType>,
|
||||||
pub typesByName: roc_std::RocList<Tuple1>,
|
pub typesByName: roc_std::RocList<Tuple1>,
|
||||||
|
|
|
@ -81,7 +81,7 @@ impl Types {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub(crate) fn new<'a, I: Iterator<Item = Variable>>(
|
pub(crate) fn new_with_entry_points<'a, I: Iterator<Item = Variable>>(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
subs: &'a Subs,
|
subs: &'a Subs,
|
||||||
variables: I,
|
variables: I,
|
||||||
|
@ -89,6 +89,7 @@ impl Types {
|
||||||
glue_procs_by_layout: MutMap<Layout<'a>, &'a [String]>,
|
glue_procs_by_layout: MutMap<Layout<'a>, &'a [String]>,
|
||||||
layout_cache: LayoutCache<'a>,
|
layout_cache: LayoutCache<'a>,
|
||||||
target: TargetInfo,
|
target: TargetInfo,
|
||||||
|
mut entry_points: MutMap<Symbol, Variable>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut types = Self::with_capacity(variables.size_hint().0, target);
|
let mut types = Self::with_capacity(variables.size_hint().0, target);
|
||||||
let mut env = Env::new(
|
let mut env = Env::new(
|
||||||
|
@ -102,9 +103,37 @@ impl Types {
|
||||||
|
|
||||||
for var in variables {
|
for var in variables {
|
||||||
env.lambda_set_ids = env.find_lambda_sets(var);
|
env.lambda_set_ids = env.find_lambda_sets(var);
|
||||||
env.add_type(var, &mut types);
|
let id = env.add_type(var, &mut types);
|
||||||
|
|
||||||
|
let key = entry_points
|
||||||
|
.iter()
|
||||||
|
.find_map(|(k, v)| (*v == var).then_some((*k, id)));
|
||||||
|
|
||||||
|
if let Some((k, id)) = key {
|
||||||
|
let name = k.as_str(env.interns).to_string();
|
||||||
|
types.entry_points.push((name, id));
|
||||||
|
entry_points.remove(&k);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let variables: Vec<_> = entry_points.values().copied().collect();
|
||||||
|
for var in variables {
|
||||||
|
env.lambda_set_ids = env.find_lambda_sets(var);
|
||||||
|
let id = env.add_type(var, &mut types);
|
||||||
|
|
||||||
|
let key = entry_points
|
||||||
|
.iter()
|
||||||
|
.find_map(|(k, v)| (*v == var).then_some((*k, id)));
|
||||||
|
|
||||||
|
if let Some((k, id)) = key {
|
||||||
|
let name = k.as_str(env.interns).to_string();
|
||||||
|
types.entry_points.push((name, id));
|
||||||
|
entry_points.remove(&k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_assert!(entry_points.is_empty());
|
||||||
|
|
||||||
env.resolve_pending_recursive_types(&mut types);
|
env.resolve_pending_recursive_types(&mut types);
|
||||||
|
|
||||||
types
|
types
|
||||||
|
@ -626,9 +655,17 @@ impl From<&Types> for roc_type::Types {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(k, v)| roc_type::Tuple1::T(k.as_str().into(), v.0 as _))
|
.map(|(k, v)| roc_type::Tuple1::T(k.as_str().into(), v.0 as _))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
let entrypoints = types
|
||||||
|
.entry_points()
|
||||||
|
.iter()
|
||||||
|
.map(|(k, v)| roc_type::Tuple1::T(k.as_str().into(), v.0 as _))
|
||||||
|
.collect();
|
||||||
|
|
||||||
roc_type::Types {
|
roc_type::Types {
|
||||||
aligns: types.aligns.as_slice().into(),
|
aligns: types.aligns.as_slice().into(),
|
||||||
deps,
|
deps,
|
||||||
|
entrypoints,
|
||||||
sizes: types.sizes.as_slice().into(),
|
sizes: types.sizes.as_slice().into(),
|
||||||
types: types.types.iter().map(|t| t.into()).collect(),
|
types: types.types.iter().map(|t| t.into()).collect(),
|
||||||
typesByName: types_by_name,
|
typesByName: types_by_name,
|
||||||
|
|
|
@ -1,22 +1,11 @@
|
||||||
mod test_glue;
|
mod test_glue;
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#[link_name = "roc__mainForHost_1_exposed_generic"]
|
|
||||||
fn roc_main(_: *mut test_glue::MyRcd);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn rust_main() -> i32 {
|
pub extern "C" fn rust_main() -> i32 {
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::hash_set::HashSet;
|
use std::collections::hash_set::HashSet;
|
||||||
|
|
||||||
let record = unsafe {
|
let record = test_glue::mainForHost();
|
||||||
let mut ret: core::mem::MaybeUninit<test_glue::MyRcd> = core::mem::MaybeUninit::uninit();
|
|
||||||
|
|
||||||
roc_main(ret.as_mut_ptr());
|
|
||||||
|
|
||||||
ret.assume_init()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Verify that the record has all the expected traits.
|
// Verify that the record has all the expected traits.
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,11 @@
|
||||||
mod test_glue;
|
mod test_glue;
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#[link_name = "roc__mainForHost_1_exposed_generic"]
|
|
||||||
fn roc_main(_: *mut test_glue::MyEnum);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn rust_main() -> i32 {
|
pub extern "C" fn rust_main() -> i32 {
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::hash_set::HashSet;
|
use std::collections::hash_set::HashSet;
|
||||||
|
|
||||||
let tag_union = unsafe {
|
let tag_union = test_glue::mainForHost();
|
||||||
let mut ret: core::mem::MaybeUninit<test_glue::MyEnum> = core::mem::MaybeUninit::uninit();
|
|
||||||
|
|
||||||
roc_main(ret.as_mut_ptr());
|
|
||||||
|
|
||||||
ret.assume_init()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Verify that it has all the expected traits.
|
// Verify that it has all the expected traits.
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,13 @@
|
||||||
mod test_glue;
|
mod test_glue;
|
||||||
|
|
||||||
use indoc::indoc;
|
use indoc::indoc;
|
||||||
use test_glue::Combined;
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#[link_name = "roc__mainForHost_1_exposed_generic"]
|
|
||||||
fn roc_main(_: *mut Combined);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn rust_main() -> i32 {
|
pub extern "C" fn rust_main() -> i32 {
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::hash_set::HashSet;
|
use std::collections::hash_set::HashSet;
|
||||||
|
|
||||||
let tag_union = unsafe {
|
let tag_union = test_glue::mainForHost();
|
||||||
let mut ret: core::mem::MaybeUninit<Combined> = core::mem::MaybeUninit::uninit();
|
|
||||||
|
|
||||||
roc_main(ret.as_mut_ptr());
|
|
||||||
|
|
||||||
ret.assume_init()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Verify that it has all the expected traits.
|
// Verify that it has all the expected traits.
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,10 @@
|
||||||
mod test_glue;
|
mod test_glue;
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#[link_name = "roc__mainForHost_1_exposed_generic"]
|
|
||||||
fn roc_main(_: *mut test_glue::Outer);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn rust_main() -> i32 {
|
pub extern "C" fn rust_main() -> i32 {
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
let outer = unsafe {
|
let outer = test_glue::mainForHost();
|
||||||
let mut ret: core::mem::MaybeUninit<test_glue::Outer> = core::mem::MaybeUninit::uninit();
|
|
||||||
|
|
||||||
roc_main(ret.as_mut_ptr());
|
|
||||||
|
|
||||||
ret.assume_init()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Verify that `inner` has all the expected traits.
|
// Verify that `inner` has all the expected traits.
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,23 +3,12 @@ mod test_glue;
|
||||||
use indoc::indoc;
|
use indoc::indoc;
|
||||||
use test_glue::SingleTagUnion;
|
use test_glue::SingleTagUnion;
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#[link_name = "roc__mainForHost_1_exposed_generic"]
|
|
||||||
fn roc_main(_: *mut SingleTagUnion);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn rust_main() -> i32 {
|
pub extern "C" fn rust_main() -> i32 {
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::hash_set::HashSet;
|
use std::collections::hash_set::HashSet;
|
||||||
|
|
||||||
let tag_union = unsafe {
|
let tag_union = test_glue::mainForHost();
|
||||||
let mut ret: core::mem::MaybeUninit<SingleTagUnion> = core::mem::MaybeUninit::uninit();
|
|
||||||
|
|
||||||
roc_main(ret.as_mut_ptr());
|
|
||||||
|
|
||||||
ret.assume_init()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Verify that it has all the expected traits.
|
// Verify that it has all the expected traits.
|
||||||
|
|
||||||
|
|
|
@ -10,10 +10,7 @@ use std::io::Write;
|
||||||
use std::mem::MaybeUninit;
|
use std::mem::MaybeUninit;
|
||||||
use std::os::raw::c_char;
|
use std::os::raw::c_char;
|
||||||
|
|
||||||
extern "C" {
|
use glue::mainForHost as roc_main;
|
||||||
#[link_name = "roc__mainForHost_1_exposed_generic"]
|
|
||||||
fn roc_main(_: *mut Op);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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 {
|
||||||
|
@ -93,13 +90,7 @@ pub extern "C" fn rust_main() -> i32 {
|
||||||
|
|
||||||
println!("Let's do things!");
|
println!("Let's do things!");
|
||||||
|
|
||||||
let mut op: Op = unsafe {
|
let mut op: Op = roc_main();
|
||||||
let mut mem = MaybeUninit::uninit();
|
|
||||||
|
|
||||||
roc_main(mem.as_mut_ptr());
|
|
||||||
|
|
||||||
mem.assume_init()
|
|
||||||
};
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match dbg!(op.discriminant()) {
|
match dbg!(op.discriminant()) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue