Merge branch 'trunk' of github.com:rtfeldman/roc into wasm-recursive-tags

This commit is contained in:
Brian Carroll 2021-12-11 23:26:29 +00:00
commit b1a2a3ba07
7 changed files with 92 additions and 43 deletions

1
Cargo.lock generated
View file

@ -3411,6 +3411,7 @@ dependencies = [
"roc_collections", "roc_collections",
"roc_module", "roc_module",
"roc_mono", "roc_mono",
"roc_reporting",
"roc_std", "roc_std",
"target-lexicon", "target-lexicon",
] ]

View file

@ -10,6 +10,7 @@ edition = "2018"
roc_collections = { path = "../collections" } roc_collections = { path = "../collections" }
roc_module = { path = "../module" } roc_module = { path = "../module" }
roc_builtins = { path = "../builtins" } roc_builtins = { path = "../builtins" }
roc_reporting = { path = "../../reporting" }
roc_mono = { path = "../mono" } roc_mono = { path = "../mono" }
roc_std = { path = "../../roc_std" } roc_std = { path = "../../roc_std" }
morphic_lib = { path = "../../vendor/morphic_lib" } morphic_lib = { path = "../../vendor/morphic_lib" }

View file

@ -62,6 +62,7 @@ use roc_mono::ir::{
ModifyRc, OptLevel, ProcLayout, ModifyRc, OptLevel, ProcLayout,
}; };
use roc_mono::layout::{Builtin, LambdaSet, Layout, LayoutIds, TagIdIntType, UnionLayout}; use roc_mono::layout::{Builtin, LambdaSet, Layout, LayoutIds, TagIdIntType, UnionLayout};
use roc_reporting::internal_error;
use target_lexicon::{Architecture, OperatingSystem, Triple}; use target_lexicon::{Architecture, OperatingSystem, Triple};
/// This is for Inkwell's FunctionValue::verify - we want to know the verification /// This is for Inkwell's FunctionValue::verify - we want to know the verification
@ -5604,9 +5605,13 @@ fn run_low_level<'a, 'ctx, 'env>(
let int_type = convert::int_type_from_int_width(env, *int_width); let int_type = convert::int_type_from_int_width(env, *int_width);
build_int_unary_op(env, arg.into_int_value(), int_type, op) build_int_unary_op(env, arg.into_int_value(), int_type, op)
} }
Float(float_width) => { Float(float_width) => build_float_unary_op(
build_float_unary_op(env, arg.into_float_value(), op, *float_width) env,
} layout,
arg.into_float_value(),
op,
*float_width,
),
_ => { _ => {
unreachable!("Compiler bug: tried to run numeric operation {:?} on invalid builtin layout: ({:?})", op, arg_layout); unreachable!("Compiler bug: tried to run numeric operation {:?} on invalid builtin layout: ({:?})", op, arg_layout);
} }
@ -6983,9 +6988,10 @@ fn int_abs_with_overflow<'a, 'ctx, 'env>(
fn build_float_unary_op<'a, 'ctx, 'env>( fn build_float_unary_op<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>, env: &Env<'a, 'ctx, 'env>,
layout: &Layout<'a>,
arg: FloatValue<'ctx>, arg: FloatValue<'ctx>,
op: LowLevel, op: LowLevel,
float_width: FloatWidth, float_width: FloatWidth, // arg width
) -> BasicValueEnum<'ctx> { ) -> BasicValueEnum<'ctx> {
use roc_module::low_level::LowLevel::*; use roc_module::low_level::LowLevel::*;
@ -6997,7 +7003,35 @@ fn build_float_unary_op<'a, 'ctx, 'env>(
NumAbs => env.call_intrinsic(&LLVM_FABS[float_width], &[arg.into()]), NumAbs => env.call_intrinsic(&LLVM_FABS[float_width], &[arg.into()]),
NumSqrtUnchecked => env.call_intrinsic(&LLVM_SQRT[float_width], &[arg.into()]), NumSqrtUnchecked => env.call_intrinsic(&LLVM_SQRT[float_width], &[arg.into()]),
NumLogUnchecked => env.call_intrinsic(&LLVM_LOG[float_width], &[arg.into()]), NumLogUnchecked => env.call_intrinsic(&LLVM_LOG[float_width], &[arg.into()]),
NumToFloat => arg.into(), /* Converting from Float to Float is a no-op */ NumToFloat => {
let return_width = match layout {
Layout::Builtin(Builtin::Float(return_width)) => *return_width,
_ => internal_error!("Layout for returning is not Float : {:?}", layout),
};
match (float_width, return_width) {
(FloatWidth::F32, FloatWidth::F32) => arg.into(),
(FloatWidth::F32, FloatWidth::F64) => bd.build_cast(
InstructionOpcode::FPExt,
arg,
env.context.f64_type(),
"f32_to_f64",
),
(FloatWidth::F64, FloatWidth::F32) => bd.build_cast(
InstructionOpcode::FPTrunc,
arg,
env.context.f32_type(),
"f64_to_f32",
),
(FloatWidth::F64, FloatWidth::F64) => arg.into(),
(FloatWidth::F128, FloatWidth::F128) => arg.into(),
(FloatWidth::F128, _) => {
unimplemented!("I cannot handle F128 with Num.toFloat yet")
}
(_, FloatWidth::F128) => {
unimplemented!("I cannot handle F128 with Num.toFloat yet")
}
}
}
NumCeiling => env.builder.build_cast( NumCeiling => env.builder.build_cast(
InstructionOpcode::FPToSI, InstructionOpcode::FPToSI,
env.call_intrinsic(&LLVM_CEILING[float_width], &[arg.into()]), env.call_intrinsic(&LLVM_CEILING[float_width], &[arg.into()]),

View file

@ -1309,7 +1309,7 @@ fn num_to_float() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-dev"))] #[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn num_to_float_f64_to_f32() { fn num_to_float_f64_to_f32() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -1328,7 +1328,47 @@ fn num_to_float_f64_to_f32() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-wasm", feature = "gen-dev"))] #[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn num_to_float_f32_to_f32() {
assert_evals_to!(
indoc!(
r#"
arg : F32
arg = 9.0
ret : F32
ret = Num.toFloat arg
ret
"#
),
9.0,
f32
);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn num_to_float_f64_to_f64() {
assert_evals_to!(
indoc!(
r#"
arg : F64
arg = 9.0
ret : F64
ret = Num.toFloat arg
ret
"#
),
9.0,
f64
);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn num_to_float_f32_to_f64() { fn num_to_float_f32_to_f64() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(

View file

@ -1,4 +1,3 @@
use std::cell::Cell;
use std::collections::hash_map::DefaultHasher; use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::marker::PhantomData; use std::marker::PhantomData;
@ -23,10 +22,6 @@ use roc_mono::ir::PRETTY_PRINT_IR_SYMBOLS;
const TEST_WRAPPER_NAME: &str = "test_wrapper"; const TEST_WRAPPER_NAME: &str = "test_wrapper";
std::thread_local! {
static TEST_COUNTER: Cell<u32> = Cell::new(0);
}
fn promote_expr_to_module(src: &str) -> String { fn promote_expr_to_module(src: &str) -> String {
let mut buffer = String::from("app \"test\" provides [ main ] to \"./platform\"\n\nmain =\n"); let mut buffer = String::from("app \"test\" provides [ main ] to \"./platform\"\n\nmain =\n");

View file

@ -2,7 +2,7 @@
use core::alloc::Layout; use core::alloc::Layout;
use core::ffi::c_void; use core::ffi::c_void;
use core::mem::MaybeUninit; use core::mem::{ManuallyDrop, MaybeUninit};
use libc; use libc;
use roc_std::RocStr; use roc_std::RocStr;
use std::ffi::CStr; use std::ffi::CStr;
@ -119,13 +119,8 @@ pub extern "C" fn roc_fx_getLine() -> RocStr {
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn roc_fx_putLine(line: RocStr) -> () { pub extern "C" fn roc_fx_putLine(line: ManuallyDrop<RocStr>) {
let bytes = line.as_slice(); let bytes = line.as_slice();
let string = unsafe { std::str::from_utf8_unchecked(bytes) }; let string = unsafe { std::str::from_utf8_unchecked(bytes) };
println!("{}", string); println!("{}", string);
// don't mess with the refcount!
core::mem::forget(line);
()
} }

View file

@ -2,7 +2,7 @@
use core::alloc::Layout; use core::alloc::Layout;
use core::ffi::c_void; use core::ffi::c_void;
use core::mem::MaybeUninit; use core::mem::{ManuallyDrop, MaybeUninit};
use libc; use libc;
use roc_std::{RocList, RocStr}; use roc_std::{RocList, RocStr};
use std::env; use std::env;
@ -141,29 +141,19 @@ pub extern "C" fn roc_fx_getChar() -> u8 {
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn roc_fx_putLine(line: RocStr) -> () { pub extern "C" fn roc_fx_putLine(line: ManuallyDrop<RocStr>) {
let bytes = line.as_slice(); let bytes = line.as_slice();
let string = unsafe { std::str::from_utf8_unchecked(bytes) }; let string = unsafe { std::str::from_utf8_unchecked(bytes) };
println!("{}", string); println!("{}", string);
std::io::stdout().lock().flush(); std::io::stdout().lock().flush();
// don't mess with the refcount!
core::mem::forget(line);
()
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn roc_fx_putRaw(line: RocStr) -> () { pub extern "C" fn roc_fx_putRaw(line: ManuallyDrop<RocStr>) {
let bytes = line.as_slice(); let bytes = line.as_slice();
let string = unsafe { std::str::from_utf8_unchecked(bytes) }; let string = unsafe { std::str::from_utf8_unchecked(bytes) };
print!("{}", string); print!("{}", string);
std::io::stdout().lock().flush(); std::io::stdout().lock().flush();
// don't mess with the refcount!
core::mem::forget(line);
()
} }
#[no_mangle] #[no_mangle]
@ -190,25 +180,23 @@ pub extern "C" fn roc_fx_getFileBytes(br_ptr: *mut BufReader<File>) -> RocList<u
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn roc_fx_closeFile(br_ptr: *mut BufReader<File>) -> () { pub extern "C" fn roc_fx_closeFile(br_ptr: *mut BufReader<File>) {
unsafe { unsafe {
Box::from_raw(br_ptr); Box::from_raw(br_ptr);
} }
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn roc_fx_openFile(name: RocStr) -> *mut BufReader<File> { pub extern "C" fn roc_fx_openFile(name: ManuallyDrop<RocStr>) -> *mut BufReader<File> {
let f = File::open(name.as_str()).expect("Unable to open file"); let f = File::open(name.as_str()).expect("Unable to open file");
let br = BufReader::new(f); let br = BufReader::new(f);
// don't mess with the refcount!
core::mem::forget(name);
Box::into_raw(Box::new(br)) Box::into_raw(Box::new(br))
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn roc_fx_withFileOpen(name: RocStr, buffer: *const u8) -> () { pub extern "C" fn roc_fx_withFileOpen(name: ManuallyDrop<RocStr>, buffer: *const u8) {
// TODO: figure out accepting a closure in an fx and passing data to it.
// let f = File::open(name.as_str()).expect("Unable to open file"); // let f = File::open(name.as_str()).expect("Unable to open file");
// let mut br = BufReader::new(f); // let mut br = BufReader::new(f);
@ -216,9 +204,4 @@ pub extern "C" fn roc_fx_withFileOpen(name: RocStr, buffer: *const u8) -> () {
// let closure_data_ptr = buffer.offset(8); // let closure_data_ptr = buffer.offset(8);
// call_the_closure(closure_data_ptr); // call_the_closure(closure_data_ptr);
// } // }
// // don't mess with the refcount!
// core::mem::forget(name);
()
} }