mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 06:44:46 +00:00
clip clip clip
This commit is contained in:
parent
f07e69ad87
commit
3fe0140c7e
4 changed files with 39 additions and 55 deletions
|
@ -15,7 +15,6 @@ use crate::llvm::refcounting::{
|
||||||
};
|
};
|
||||||
use bumpalo::collections::Vec;
|
use bumpalo::collections::Vec;
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
use either;
|
|
||||||
use inkwell::basic_block::BasicBlock;
|
use inkwell::basic_block::BasicBlock;
|
||||||
use inkwell::builder::Builder;
|
use inkwell::builder::Builder;
|
||||||
use inkwell::context::Context;
|
use inkwell::context::Context;
|
||||||
|
@ -1941,7 +1940,7 @@ where
|
||||||
let catch_block = context.append_basic_block(parent, "catch_block");
|
let catch_block = context.append_basic_block(parent, "catch_block");
|
||||||
let cont_block = context.append_basic_block(parent, "cont_block");
|
let cont_block = context.append_basic_block(parent, "cont_block");
|
||||||
|
|
||||||
let result_alloca = builder.build_alloca(call_result_type.clone(), "result");
|
let result_alloca = builder.build_alloca(call_result_type, "result");
|
||||||
|
|
||||||
// invoke instead of call, so that we can catch any exeptions thrown in Roc code
|
// invoke instead of call, so that we can catch any exeptions thrown in Roc code
|
||||||
let call_result = {
|
let call_result = {
|
||||||
|
@ -2147,6 +2146,11 @@ pub fn build_proc_header<'a, 'ctx, 'env>(
|
||||||
Layout::Closure(arguments, closure, result) => {
|
Layout::Closure(arguments, closure, result) => {
|
||||||
build_closure_caller(env, &fn_name, *name, arguments, closure, result)
|
build_closure_caller(env, &fn_name, *name, arguments, closure, result)
|
||||||
}
|
}
|
||||||
|
Layout::FunctionPointer(_arguments, _result) => {
|
||||||
|
// TODO should this be considered a closure of size 0?
|
||||||
|
// or do we let the host call it directly?
|
||||||
|
// then we have no RocCallResult wrapping though
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
@ -2215,12 +2219,11 @@ pub fn build_closure_caller<'a, 'ctx, 'env>(
|
||||||
let function_pointer_type = {
|
let function_pointer_type = {
|
||||||
let function_layout =
|
let function_layout =
|
||||||
ClosureLayout::extend_function_layout(arena, arguments, closure.clone(), result);
|
ClosureLayout::extend_function_layout(arena, arguments, closure.clone(), result);
|
||||||
let basic_type = basic_type_from_layout(arena, context, &function_layout, env.ptr_bytes);
|
|
||||||
|
|
||||||
// this is already a (function) pointer type
|
// this is already a (function) pointer type
|
||||||
basic_type
|
basic_type_from_layout(arena, context, &function_layout, env.ptr_bytes)
|
||||||
};
|
};
|
||||||
argument_types.push(function_pointer_type.into());
|
argument_types.push(function_pointer_type);
|
||||||
|
|
||||||
let closure_argument_type = {
|
let closure_argument_type = {
|
||||||
let basic_type = basic_type_from_layout(
|
let basic_type = basic_type_from_layout(
|
||||||
|
|
|
@ -1793,9 +1793,7 @@ fn introduce_solved_type_to_subs<'a>(env: &mut Env<'a, '_>, solved_type: &Solved
|
||||||
|
|
||||||
env.subs.extend_by(variables_introduced as usize);
|
env.subs.extend_by(variables_introduced as usize);
|
||||||
|
|
||||||
let result = insert_type_into_subs(env.subs, &normal_type);
|
insert_type_into_subs(env.subs, &normal_type)
|
||||||
|
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn specialize_solved_type<'a>(
|
fn specialize_solved_type<'a>(
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
use roc_std::alloca;
|
use roc_std::alloca;
|
||||||
|
use roc_std::RocCallResult;
|
||||||
use std::alloc::Layout;
|
use std::alloc::Layout;
|
||||||
use std::ffi::CString;
|
|
||||||
use std::os::raw::c_char;
|
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
use RocCallResult::*;
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#[link_name = "makeClosure_1_exposed"]
|
#[link_name = "makeClosure_1_exposed"]
|
||||||
|
@ -53,10 +51,10 @@ pub fn rust_main() -> isize {
|
||||||
|
|
||||||
make_closure(buffer);
|
make_closure(buffer);
|
||||||
|
|
||||||
let output = &*(buffer as *mut RocCallResult<((), ())>);
|
let output = &*(buffer as *mut RocCallResult<()>);
|
||||||
|
|
||||||
match output.into() {
|
match output.into() {
|
||||||
Ok((_, _)) => {
|
Ok(()) => {
|
||||||
let function_pointer = {
|
let function_pointer = {
|
||||||
// this is a pointer to the location where the function pointer is stored
|
// this is a pointer to the location where the function pointer is stored
|
||||||
// we pass just the function pointer
|
// we pass just the function pointer
|
||||||
|
@ -89,45 +87,3 @@ pub fn rust_main() -> isize {
|
||||||
// Exit code
|
// Exit code
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(u64)]
|
|
||||||
pub enum RocCallResult<T> {
|
|
||||||
Success(T),
|
|
||||||
Failure(*mut c_char),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Sized> Into<Result<T, String>> for RocCallResult<T> {
|
|
||||||
fn into(self) -> Result<T, String> {
|
|
||||||
match self {
|
|
||||||
Success(value) => Ok(value),
|
|
||||||
Failure(failure) => Err({
|
|
||||||
let raw = unsafe { CString::from_raw(failure) };
|
|
||||||
|
|
||||||
let result = format!("{:?}", raw);
|
|
||||||
|
|
||||||
// make sure rust does not try to free the Roc string
|
|
||||||
std::mem::forget(raw);
|
|
||||||
|
|
||||||
result
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Sized + Copy> Into<Result<T, String>> for &RocCallResult<T> {
|
|
||||||
fn into(self) -> Result<T, String> {
|
|
||||||
match self {
|
|
||||||
Success(value) => Ok(*value),
|
|
||||||
Failure(failure) => Err({
|
|
||||||
let raw = unsafe { CString::from_raw(*failure) };
|
|
||||||
|
|
||||||
let result = format!("{:?}", raw);
|
|
||||||
|
|
||||||
// make sure rust does not try to free the Roc string
|
|
||||||
std::mem::forget(raw);
|
|
||||||
|
|
||||||
result
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -464,3 +464,30 @@ impl<T: Sized> Into<Result<T, &'static str>> for RocCallResult<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, T: Sized + Copy> Into<Result<T, &'a str>> for &'a RocCallResult<T> {
|
||||||
|
fn into(self) -> Result<T, &'a str> {
|
||||||
|
use RocCallResult::*;
|
||||||
|
|
||||||
|
match self {
|
||||||
|
Success(value) => Ok(*value),
|
||||||
|
Failure(failure) => Err({
|
||||||
|
let msg = unsafe {
|
||||||
|
let mut null_byte_index = 0;
|
||||||
|
loop {
|
||||||
|
if *failure.offset(null_byte_index) == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
null_byte_index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let bytes = core::slice::from_raw_parts(*failure, null_byte_index as usize);
|
||||||
|
|
||||||
|
core::str::from_utf8_unchecked(bytes)
|
||||||
|
};
|
||||||
|
|
||||||
|
msg
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue