diff --git a/Cargo.toml b/Cargo.toml index 83ecc282..9dc126cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,12 +39,12 @@ termcolor = "1.4" itertools = "0.14" assert_cmd = "2.0.17" paste = "1.0" -cranelift = "0.93" -cranelift-codegen = "0.93" -cranelift-frontend = "0.93" -cranelift-module = "0.93" -cranelift-native = "0.93" -cranelift-jit = "0.93" +cranelift = "0.123.2" +cranelift-codegen = "0.123.2" +cranelift-frontend = "0.123.2" +cranelift-module = "0.123.2" +cranelift-native = "0.123.2" +cranelift-jit = "0.123.2" fast-float = "0.2" bumpalo = { version = "3.19.0", features = ["collections"] } target-lexicon = "0.12.2" diff --git a/src/codegen/clif.rs b/src/codegen/clif.rs index 560bcb7b..1294f767 100644 --- a/src/codegen/clif.rs +++ b/src/codegen/clif.rs @@ -122,7 +122,6 @@ struct Frame { // somewhat differently). header_block: Block, n_params: usize, - n_vars: usize, } /// Function-independent data used in compilation @@ -205,18 +204,15 @@ impl Jit for Generator { fn jit_builder() -> Result { // Adapted from the cranelift source. let mut flag_builder = settings::builder(); - cfg_if::cfg_if! { - if #[cfg(target_arch = "aarch64")] { - // See https://github.com/bytecodealliance/wasmtime/issues/2735 - flag_builder.set("is_pic", "false").unwrap(); - // Notes from cranelift source: "On at least AArch64, 'colocated' calls use - // shorter-range relocations, which might not reach all definitions; we - // can't handle that here, so we require long-range relocation types." - flag_builder.set("use_colocated_libcalls", "false").unwrap(); - } else { - flag_builder.set("is_pic", "true").unwrap(); - } - } + flag_builder.set("is_pic", "false").unwrap(); + + // See https://github.com/bytecodealliance/wasmtime/issues/2735 + // Notes from cranelift source: "On at least AArch64, 'colocated' calls use + // shorter-range relocations, which might not reach all definitions; we + // can't handle that here, so we require long-range relocation types." + #[cfg(target_arch = "aarch64")] + flag_builder.set("use_colocated_libcalls", "false").unwrap(); + let isa_builder = cranelift_native::builder() .map_err(|msg| err_raw!("host machine is not supported by cranelift: {}", msg))?; flag_builder.enable("enable_llvm_abi_extensions").unwrap(); @@ -309,12 +305,10 @@ impl Generator { // Now, build each global variable "by hand". Allocate a variable for it, assign it to the // address of a default value of the type in question on the stack. for (reg, ty) in globals { - let var = Variable::new(view.f.n_vars); - vars.push((var, ty)); - view.f.n_vars += 1; + let var = view.builder.declare_var(ptr_ty); let cl_ty = view.get_ty(ty); let ptr_ty = view.ptr_to(cl_ty); - view.builder.declare_var(var, ptr_ty); + view.builder.declare_var(ptr_ty); let slot = view.stack_slot_bytes(cl_ty.lane_bits() / 8); let default = view.default_value(ty)?; @@ -393,7 +387,6 @@ impl Generator { header_block, // this will get overwritten in process_args runtime: Variable::new(0), - n_vars: 0, vars: Default::default(), iters: Default::default(), header_actions: Default::default(), @@ -480,16 +473,10 @@ impl Generator { } } -macro_rules! external { - ($name:ident) => { - crate::codegen::intrinsics::$name as *const u8 - }; -} - impl<'a> View<'a> { fn stack_slot_bytes(&mut self, bytes: u32) -> StackSlot { debug_assert!(bytes > 0); // This signals a bug; all frawk types have positive size. - let data = StackSlotData::new(StackSlotKind::ExplicitSlot, bytes); + let data = StackSlotData::new(StackSlotKind::ExplicitSlot, bytes, 0); self.builder.create_sized_stack_slot(data) } @@ -609,9 +596,7 @@ impl<'a> View<'a> { .cloned() .collect(); for (i, (val, (rf, ty))) in params.into_iter().zip(param_tys).enumerate() { - let var = Variable::new(self.f.n_vars); - self.f.n_vars += 1; - self.builder.declare_var(var, ty); + let var = self.builder.declare_var(ty); self.builder.def_var(var, val); if i == self.f.n_params - 1 { // runtime @@ -830,26 +815,24 @@ impl<'a> View<'a> { /// Initialize the `Variable` associated with a non-iterator local variable of type `ty`. fn declare_local(&mut self, ty: compile::Ty) -> Result { use compile::Ty::*; - let next_var = Variable::new(self.f.n_vars); - self.f.n_vars += 1; let cl_ty = self.get_ty(ty); - // Remember to allocate/initialize this variable in the header - self.f - .header_actions - .push(EntryDeclaration { ty, var: next_var }); - match ty { + let next_var = match ty { Null | Int | Float => { - self.builder.declare_var(next_var, cl_ty); - } + self.builder.declare_var(cl_ty) + }, Str => { let ptr_ty = self.ptr_to(cl_ty); - self.builder.declare_var(next_var, ptr_ty); - } + self.builder.declare_var(ptr_ty) + }, MapIntInt | MapIntFloat | MapIntStr | MapStrInt | MapStrFloat | MapStrStr => { - self.builder.declare_var(next_var, cl_ty); - } + self.builder.declare_var(cl_ty) + }, IterInt | IterStr => return err!("iterators cannot be declared"), - } + }; + // Remember to allocate/initialize this variable in the header + self.f + .header_actions + .push(EntryDeclaration { ty, var: next_var }); Ok(next_var) } @@ -858,13 +841,9 @@ impl<'a> View<'a> { use compile::Ty::*; match ty { IterStr | IterInt => { - let bytes = Variable::new(self.f.n_vars); - let cur = Variable::new(self.f.n_vars + 1); - let base = Variable::new(self.f.n_vars + 2); - self.f.n_vars += 3; - self.builder.declare_var(bytes, types::I64); - self.builder.declare_var(cur, types::I64); - self.builder.declare_var(base, self.void_ptr_ty()); + let bytes = self.builder.declare_var(types::I64); + let cur = self.builder.declare_var(types::I64); + let base = self.builder.declare_var(self.void_ptr_ty()); Ok(IterState { bytes, cur, base }) } Null | Int | Float | Str | MapIntInt | MapIntFloat | MapIntStr | MapStrInt diff --git a/src/codegen/intrinsics.rs b/src/codegen/intrinsics.rs index 126fb48c..74d92c37 100644 --- a/src/codegen/intrinsics.rs +++ b/src/codegen/intrinsics.rs @@ -439,30 +439,36 @@ impl<'a> Drop for Runtime<'a> { } } +#[inline(never)] pub(crate) unsafe extern "C" fn exit(runtime: *mut c_void, code: Int) { exit!(runtime, code as i32); } +#[inline(never)] pub(crate) unsafe extern "C" fn run_system(cmd: *mut U128) -> Int { let s: &Str = &*(cmd as *mut Str); s.with_bytes(runtime::run_command) } +#[inline(never)] pub(crate) unsafe extern "C" fn rand_float(runtime: *mut c_void) -> f64 { let runtime = &mut *(runtime as *mut Runtime); runtime.core.rng.random_range(0.0..=1.0) } +#[inline(never)] pub(crate) unsafe extern "C" fn seed_rng(runtime: *mut c_void, seed: Int) -> Int { let runtime = &mut *(runtime as *mut Runtime); runtime.core.reseed(seed as u64) as Int } +#[inline(never)] pub(crate) unsafe extern "C" fn reseed_rng(runtime: *mut c_void) -> Int { let runtime = &mut *(runtime as *mut Runtime); runtime.core.reseed_random() as Int } +#[inline(never)] pub(crate) unsafe extern "C" fn read_err( runtime: *mut c_void, file: *mut c_void, @@ -483,12 +489,14 @@ pub(crate) unsafe extern "C" fn read_err( ) } +#[inline(never)] pub(crate) unsafe extern "C" fn read_err_stdin(runtime: *mut c_void) -> Int { let runtime = &mut *(runtime as *mut Runtime); with_input!(&mut runtime.input_data, |(_, read_files)| read_files .read_err_stdin()) } +#[inline(never)] pub(crate) unsafe extern "C" fn next_line_stdin_fused(runtime: *mut c_void) { let runtime = &mut *(runtime as *mut Runtime); let changed = try_abort!( @@ -506,6 +514,7 @@ pub(crate) unsafe extern "C" fn next_line_stdin_fused(runtime: *mut c_void) { } } +#[inline(never)] pub(crate) unsafe extern "C" fn next_file(runtime: *mut c_void) { let runtime = &mut *(runtime as *mut Runtime); try_abort!( @@ -516,6 +525,7 @@ pub(crate) unsafe extern "C" fn next_file(runtime: *mut c_void) { ); } +#[inline(never)] pub(crate) unsafe extern "C" fn next_line_stdin(runtime: *mut c_void) -> U128 { let runtime = &mut *(runtime as *mut Runtime); let (changed, res) = try_abort!( @@ -534,6 +544,7 @@ pub(crate) unsafe extern "C" fn next_line_stdin(runtime: *mut c_void) -> U128 { mem::transmute::(res) } +#[inline(never)] pub(crate) unsafe extern "C" fn next_line( runtime: *mut c_void, file: *mut c_void, @@ -553,6 +564,7 @@ pub(crate) unsafe extern "C" fn next_line( } } +#[inline(never)] pub(crate) unsafe extern "C" fn update_used_fields(runtime: *mut c_void) { let runtime = &mut *(runtime as *mut Runtime); let fi = &runtime.core.vars.fi; @@ -561,6 +573,7 @@ pub(crate) unsafe extern "C" fn update_used_fields(runtime: *mut c_void) { }); } +#[inline(never)] pub(crate) unsafe extern "C" fn set_fi_entry(runtime: *mut c_void, key: Int, val: Int) { let rt = &mut *(runtime as *mut Runtime); let fi = &rt.core.vars.fi; @@ -568,6 +581,7 @@ pub(crate) unsafe extern "C" fn set_fi_entry(runtime: *mut c_void, key: Int, val fi.insert(k, val); } +#[inline(never)] pub(crate) unsafe extern "C" fn split_str( runtime: *mut c_void, to_split: *mut c_void, @@ -590,6 +604,7 @@ pub(crate) unsafe extern "C" fn split_str( res } +#[inline(never)] pub(crate) unsafe extern "C" fn split_int( runtime: *mut c_void, to_split: *mut c_void, @@ -612,6 +627,7 @@ pub(crate) unsafe extern "C" fn split_int( res } +#[inline(never)] pub(crate) unsafe extern "C" fn get_col(runtime: *mut c_void, col: Int) -> U128 { let runtime = &mut *(runtime as *mut Runtime); let col_str = with_input!(&mut runtime.input_data, |(line, _)| { @@ -629,6 +645,7 @@ pub(crate) unsafe extern "C" fn get_col(runtime: *mut c_void, col: Int) -> U128 mem::transmute::(res) } +#[inline(never)] pub(crate) unsafe extern "C" fn join_csv(runtime: *mut c_void, start: Int, end: Int) -> U128 { let sep: Str<'static> = ",".into(); let runtime = &mut *(runtime as *mut Runtime); @@ -647,6 +664,7 @@ pub(crate) unsafe extern "C" fn join_csv(runtime: *mut c_void, start: Int, end: mem::transmute::(res) } +#[inline(never)] pub(crate) unsafe extern "C" fn join_tsv(runtime: *mut c_void, start: Int, end: Int) -> U128 { let sep: Str<'static> = "\t".into(); let runtime = &mut *(runtime as *mut Runtime); @@ -665,6 +683,7 @@ pub(crate) unsafe extern "C" fn join_tsv(runtime: *mut c_void, start: Int, end: mem::transmute::(res) } +#[inline(never)] pub(crate) unsafe extern "C" fn join_cols( runtime: *mut c_void, start: Int, @@ -687,16 +706,19 @@ pub(crate) unsafe extern "C" fn join_cols( mem::transmute::(res) } +#[inline(never)] pub(crate) unsafe extern "C" fn to_upper_ascii(s: *mut U128) -> U128 { let res = (*(s as *mut Str as *const Str)).to_upper_ascii(); mem::transmute::(res) } +#[inline(never)] pub(crate) unsafe extern "C" fn to_lower_ascii(s: *mut U128) -> U128 { let res = (*(s as *mut Str as *const Str)).to_lower_ascii(); mem::transmute::(res) } +#[inline(never)] pub(crate) unsafe extern "C" fn set_col(runtime: *mut c_void, col: Int, s: *mut c_void) { let runtime = &mut *(runtime as *mut Runtime); let s = &*(s as *mut Str); @@ -710,11 +732,13 @@ pub(crate) unsafe extern "C" fn set_col(runtime: *mut c_void, col: Int, s: *mut } } +#[inline(never)] pub(crate) unsafe extern "C" fn str_len(s: *mut c_void) -> usize { let s = &*(s as *mut Str); s.len() } +#[inline(never)] pub(crate) unsafe extern "C" fn starts_with_const( s1: *mut c_void, base: *const u8, @@ -727,6 +751,7 @@ pub(crate) unsafe extern "C" fn starts_with_const( ((s1_bytes.len() >= other.len()) && &s1_bytes[..other.len()] == other) as Int } +#[inline(never)] pub(crate) unsafe extern "C" fn concat(s1: *mut c_void, s2: *mut c_void) -> U128 { let s1 = &*(s1 as *mut Str); let s2 = &*(s2 as *mut Str); @@ -734,6 +759,7 @@ pub(crate) unsafe extern "C" fn concat(s1: *mut c_void, s2: *mut c_void) -> U128 mem::transmute::(res) } +#[inline(never)] pub(crate) unsafe extern "C" fn match_pat( runtime: *mut c_void, s: *mut c_void, @@ -750,12 +776,14 @@ pub(crate) unsafe extern "C" fn match_pat( res as Int } +#[inline(never)] pub(crate) unsafe extern "C" fn match_const_pat(s: *mut c_void, pat: *mut c_void) -> Int { let s = &*(s as *mut Str); let pat = &*(pat as *const Regex); RegexCache::regex_const_match(pat, s) as Int } +#[inline(never)] pub(crate) unsafe extern "C" fn match_pat_loc( runtime: *mut c_void, s: *mut c_void, @@ -772,6 +800,7 @@ pub(crate) unsafe extern "C" fn match_pat_loc( res as Int } +#[inline(never)] pub(crate) unsafe extern "C" fn match_const_pat_loc( runtime: *mut c_void, s: *mut c_void, @@ -787,12 +816,14 @@ pub(crate) unsafe extern "C" fn match_const_pat_loc( ) } +#[inline(never)] pub(crate) unsafe extern "C" fn substr_index(s: *mut U128, t: *mut U128) -> Int { let s = &*(s as *mut Str); let t = &*(t as *mut Str); runtime::string_search::index_substr(/*needle*/ t, /*haystack*/ s) } +#[inline(never)] pub(crate) unsafe extern "C" fn subst_first( runtime: *mut c_void, pat: *mut U128, @@ -814,6 +845,7 @@ pub(crate) unsafe extern "C" fn subst_first( new as Int } +#[inline(never)] pub(crate) unsafe extern "C" fn subst_all( runtime: *mut c_void, pat: *mut U128, @@ -835,6 +867,7 @@ pub(crate) unsafe extern "C" fn subst_all( nsubs } +#[inline(never)] pub(crate) unsafe extern "C" fn gen_subst( runtime: *mut c_void, pat: *mut U128, @@ -857,14 +890,17 @@ pub(crate) unsafe extern "C" fn gen_subst( mem::transmute::(subbed) } +#[inline(never)] pub(crate) unsafe extern "C" fn escape_csv(s: *mut U128) -> U128 { mem::transmute::(runtime::escape_csv(&*(s as *mut Str))) } +#[inline(never)] pub(crate) unsafe extern "C" fn escape_tsv(s: *mut U128) -> U128 { mem::transmute::(runtime::escape_tsv(&*(s as *mut Str))) } +#[inline(never)] pub(crate) unsafe extern "C" fn substr(base: *mut U128, l: Int, r: Int) -> U128 { use std::cmp::{max, min}; let base = &*(base as *mut Str); @@ -878,15 +914,18 @@ pub(crate) unsafe extern "C" fn substr(base: *mut U128, l: Int, r: Int) -> U128 } } +#[inline(never)] pub(crate) unsafe extern "C" fn ref_str(s: *mut c_void) { mem::forget((*(s as *mut Str)).clone()) } // This is a "slow path" drop, used by cranelift only for the time being. +#[inline(never)] pub(crate) unsafe extern "C" fn drop_str(s: *mut U128) { std::ptr::drop_in_place(s as *mut Str) } +#[inline(never)] pub(crate) unsafe extern "C" fn drop_str_slow(s: *mut U128, tag: u64) { (*(s as *mut Str)).drop_with_tag(tag) } @@ -904,33 +943,40 @@ unsafe fn drop_map_generic(m: *mut c_void) { // XXX: relying on this doing the same thing regardless of type. We probably want a custom Rc to // guarantee this. +#[inline(never)] pub(crate) unsafe extern "C" fn ref_map(m: *mut c_void) { ref_map_generic::(m) } +#[inline(never)] pub(crate) unsafe extern "C" fn int_to_str(i: Int) -> U128 { mem::transmute::(runtime::convert::(i)) } +#[inline(never)] pub(crate) unsafe extern "C" fn float_to_str(f: Float) -> U128 { mem::transmute::(runtime::convert::(f)) } +#[inline(never)] pub(crate) unsafe extern "C" fn str_to_int(s: *mut c_void) -> Int { let s = &*(s as *mut Str); runtime::convert::<&Str, Int>(s) } +#[inline(never)] pub(crate) unsafe extern "C" fn hex_str_to_int(s: *mut c_void) -> Int { let s = &*(s as *mut Str); s.with_bytes(runtime::hextoi) } +#[inline(never)] pub(crate) unsafe extern "C" fn str_to_float(s: *mut c_void) -> Float { let s = &*(s as *mut Str); runtime::convert::<&Str, Float>(s) } +#[inline(never)] pub(crate) unsafe extern "C" fn load_var_str(rt: *mut c_void, var: usize) -> U128 { let runtime = &mut *(rt as *mut Runtime); if let Ok(var) = Variable::try_from(var) { @@ -941,6 +987,7 @@ pub(crate) unsafe extern "C" fn load_var_str(rt: *mut c_void, var: usize) -> U12 } } +#[inline(never)] pub(crate) unsafe extern "C" fn store_var_str(rt: *mut c_void, var: usize, s: *mut c_void) { let runtime = &mut *(rt as *mut Runtime); if let Ok(var) = Variable::try_from(var) { @@ -951,6 +998,7 @@ pub(crate) unsafe extern "C" fn store_var_str(rt: *mut c_void, var: usize, s: *m } } +#[inline(never)] pub(crate) unsafe extern "C" fn load_var_int(rt: *mut c_void, var: usize) -> Int { let runtime = &mut *(rt as *mut Runtime); if let Ok(var) = Variable::try_from(var) { @@ -968,6 +1016,7 @@ pub(crate) unsafe extern "C" fn load_var_int(rt: *mut c_void, var: usize) -> Int } } +#[inline(never)] pub(crate) unsafe extern "C" fn store_var_int(rt: *mut c_void, var: usize, i: Int) { let runtime = &mut *(rt as *mut Runtime); if let Ok(var) = Variable::try_from(var) { @@ -977,6 +1026,7 @@ pub(crate) unsafe extern "C" fn store_var_int(rt: *mut c_void, var: usize, i: In } } +#[inline(never)] pub(crate) unsafe extern "C" fn load_var_intstrmap(rt: *mut c_void, var: usize) -> *mut c_void { let runtime = &mut *(rt as *mut Runtime); if let Ok(var) = Variable::try_from(var) { @@ -987,6 +1037,7 @@ pub(crate) unsafe extern "C" fn load_var_intstrmap(rt: *mut c_void, var: usize) } } +#[inline(never)] pub(crate) unsafe extern "C" fn store_var_intstrmap(rt: *mut c_void, var: usize, map: *mut c_void) { let runtime = &mut *(rt as *mut Runtime); if let Ok(var) = Variable::try_from(var) { @@ -998,6 +1049,7 @@ pub(crate) unsafe extern "C" fn store_var_intstrmap(rt: *mut c_void, var: usize, } } +#[inline(never)] pub(crate) unsafe extern "C" fn load_var_strintmap(rt: *mut c_void, var: usize) -> *mut c_void { let runtime = &mut *(rt as *mut Runtime); if let Ok(var) = Variable::try_from(var) { @@ -1008,6 +1060,7 @@ pub(crate) unsafe extern "C" fn load_var_strintmap(rt: *mut c_void, var: usize) } } +#[inline(never)] pub(crate) unsafe extern "C" fn store_var_strintmap(rt: *mut c_void, var: usize, map: *mut c_void) { let runtime = &mut *(rt as *mut Runtime); if let Ok(var) = Variable::try_from(var) { @@ -1044,6 +1097,7 @@ pub(crate) unsafe extern "C" fn store_var_strstrmap(rt: *mut c_void, var: usize, macro_rules! str_compare_inner { ($name:ident, $op:tt) => { + #[inline(never)] pub(crate) unsafe extern "C" fn $name(s1: *mut c_void, s2: *mut c_void) -> Int { let s1 = &*(s1 as *mut Str); let s2 = &*(s2 as *mut Str); @@ -1060,10 +1114,12 @@ str_compare! { str_lt(<); str_gt(>); str_lte(<=); str_gte(>=); str_eq(==); } +#[inline(never)] pub(crate) unsafe extern "C" fn drop_iter_int(iter: *mut Int, len: usize) { mem::drop(Box::from_raw(slice::from_raw_parts_mut(iter, len))) } +#[inline(never)] pub(crate) unsafe extern "C" fn drop_iter_str(iter: *mut U128, len: usize) { let p = iter as *mut Str; mem::drop(Box::from_raw(slice::from_raw_parts_mut(p, len))) @@ -1088,10 +1144,16 @@ unsafe fn wrap_args<'a>( ty_code ) }; + let typed_arg: FormatArg = match ty { - Ty::Int => mem::transmute::(arg).into(), + Ty::Int => (arg.cast_signed() as i64).into(), Ty::Float => Float::from_bits(arg as u64).into(), - Ty::Str => mem::transmute::(arg).clone().into(), + Ty::Str => { + unsafe { + let str_ref = std::ptr::with_exposed_provenance::(arg).as_ref().unwrap(); + str_ref.clone().into() + } + }, Ty::Null => FormatArg::Null, _ => fail!( _rt, @@ -1104,6 +1166,7 @@ unsafe fn wrap_args<'a>( format_args } +#[inline(never)] pub(crate) unsafe extern "C" fn print_all_stdout(rt: *mut c_void, args: *mut usize, num_args: Int) { let args_wrapped: &[&Str] = slice::from_raw_parts(args as *const usize as *const &Str, num_args as usize); @@ -1111,6 +1174,7 @@ pub(crate) unsafe extern "C" fn print_all_stdout(rt: *mut c_void, args: *mut usi try_silent_abort!(rt, (*rt).core.write_files.write_all(args_wrapped, None)) } +#[inline(never)] pub(crate) unsafe extern "C" fn print_all_file( rt: *mut c_void, args: *mut usize, @@ -1135,6 +1199,7 @@ pub(crate) unsafe extern "C" fn print_all_file( ) } +#[inline(never)] pub(crate) unsafe extern "C" fn printf_impl_file( rt: *mut c_void, spec: *mut U128, @@ -1159,6 +1224,7 @@ pub(crate) unsafe extern "C" fn printf_impl_file( ) } +#[inline(never)] pub(crate) unsafe extern "C" fn sprintf_impl( rt: *mut c_void, spec: *mut U128, @@ -1177,6 +1243,7 @@ pub(crate) unsafe extern "C" fn sprintf_impl( mem::transmute::(buf.into_str()) } +#[inline(never)] pub(crate) unsafe extern "C" fn printf_impl_stdout( rt: *mut c_void, spec: *mut U128, @@ -1195,6 +1262,7 @@ pub(crate) unsafe extern "C" fn printf_impl_stdout( } } +#[inline(never)] pub(crate) unsafe extern "C" fn close_file(rt: *mut c_void, file: *mut U128) { let rt = &mut *(rt as *mut Runtime); let file = &*(file as *mut Str); @@ -1202,42 +1270,52 @@ pub(crate) unsafe extern "C" fn close_file(rt: *mut c_void, file: *mut U128) { try_abort!(rt, rt.core.write_files.close(file)); } +#[inline(never)] pub(crate) unsafe extern "C" fn _frawk_cos(f: Float) -> Float { f.cos() } +#[inline(never)] pub(crate) unsafe extern "C" fn _frawk_sin(f: Float) -> Float { f.sin() } +#[inline(never)] pub(crate) unsafe extern "C" fn _frawk_log(f: Float) -> Float { f.ln() } +#[inline(never)] pub(crate) unsafe extern "C" fn _frawk_log2(f: Float) -> Float { f.log2() } +#[inline(never)] pub(crate) unsafe extern "C" fn _frawk_log10(f: Float) -> Float { f.log10() } +#[inline(never)] pub(crate) unsafe extern "C" fn _frawk_exp(f: Float) -> Float { f.exp() } +#[inline(never)] pub(crate) unsafe extern "C" fn _frawk_atan(f: Float) -> Float { f.atan() } +#[inline(never)] pub(crate) unsafe extern "C" fn _frawk_atan2(x: Float, y: Float) -> Float { x.atan2(y) } +#[inline(never)] pub(crate) unsafe extern "C" fn _frawk_pow(x: Float, y: Float) -> Float { Float::powf(x, y) } +#[inline(never)] pub(crate) unsafe extern "C" fn _frawk_fprem(x: Float, y: Float) -> Float { x % y } @@ -1327,11 +1405,13 @@ macro_rules! convert_out { macro_rules! map_impl { ($ty:ident, $k:tt, $v:tt) => { paste! { + #[inline(never)] pub(crate) unsafe extern "C" fn [< alloc_ $ty >]() -> *mut c_void { let res: runtime::SharedMap<$k, $v> = Default::default(); mem::transmute::, *mut c_void>(res) } + #[inline(never)] pub(crate) unsafe extern "C" fn [< iter_ $ty >](map: *mut c_void) -> iter_ty!($k) { debug_assert!(!map.is_null()); let map = mem::transmute::<*mut c_void, runtime::SharedMap<$k, $v>>(map); @@ -1341,6 +1421,7 @@ macro_rules! map_impl { Box::into_raw(b) as _ } + #[inline(never)] pub(crate) unsafe extern "C" fn [](map: *mut c_void) -> Int { debug_assert!(!map.is_null()); let map = mem::transmute::<*mut c_void, runtime::SharedMap<$k, $v>>(map); @@ -1349,6 +1430,7 @@ macro_rules! map_impl { res as Int } + #[inline(never)] pub(crate) unsafe extern "C" fn [](map: *mut c_void, k: in_ty!($k)) -> out_ty!($v) { // TODO: this should probably insert the value as well! debug_assert!(!map.is_null()); @@ -1359,6 +1441,7 @@ macro_rules! map_impl { convert_out!($v, res) } + #[inline(never)] pub(crate) unsafe extern "C" fn [](map: *mut c_void, k: in_ty!($k)) -> Int { debug_assert!(!map.is_null()); let map = mem::transmute::<*mut c_void, runtime::SharedMap<$k, $v>>(map); @@ -1368,6 +1451,7 @@ macro_rules! map_impl { res } + #[inline(never)] pub(crate) unsafe extern "C" fn [](map: *mut c_void, k: in_ty!($k), v: in_ty!($v)) { debug_assert!(!map.is_null()); let map = mem::transmute::<*mut c_void, runtime::SharedMap<$k, $v>>(map); @@ -1377,6 +1461,7 @@ macro_rules! map_impl { mem::forget(map); } + #[inline(never)] pub(crate) unsafe extern "C" fn [](map: *mut c_void, k: in_ty!($k)) { debug_assert!(!map.is_null()); let map = mem::transmute::<*mut c_void, runtime::SharedMap<$k, $v>>(map); @@ -1385,6 +1470,7 @@ macro_rules! map_impl { mem::forget(map); } + #[inline(never)] pub(crate) unsafe extern "C" fn [](map: *mut c_void) { debug_assert!(!map.is_null()); let map = mem::transmute::<*mut c_void, runtime::SharedMap<$k, $v>>(map); @@ -1392,11 +1478,13 @@ macro_rules! map_impl { mem::forget(map); } + #[inline(never)] pub(crate) unsafe extern "C" fn [](map: *mut c_void) { debug_assert!(!map.is_null()); drop_map_generic::<$k, $v>(map) } + #[inline(never)] pub(crate) unsafe extern "C" fn [](map: *mut c_void, k: in_ty!($k), by: Int) -> out_ty!($v) { debug_assert!(!map.is_null()); let map = mem::transmute::<*mut c_void, runtime::SharedMap<$k, $v>>(map); @@ -1406,6 +1494,7 @@ macro_rules! map_impl { convert_out!($v, res) } + #[inline(never)] pub(crate) unsafe extern "C" fn [](map: *mut c_void, k: in_ty!($k), by: Float) -> out_ty!($v) { debug_assert!(!map.is_null()); let map = mem::transmute::<*mut c_void, runtime::SharedMap<$k, $v>>(map); @@ -1428,11 +1517,13 @@ map_impl!(strstr, Str, Str); macro_rules! slot_impl { ($name:ident, $ty:tt) => { paste! { + #[inline(never)] pub(crate) unsafe extern "C" fn [](runtime: *mut c_void, slot: Int) -> out_ty!($ty) { let runtime = &mut *(runtime as *mut Runtime); convert_out!($ty, runtime.core.[](slot as usize)) } + #[inline(never)] pub(crate) unsafe extern "C" fn [](runtime: *mut c_void, slot: Int, v: in_ty!($ty)) { let runtime = &mut *(runtime as *mut Runtime); runtime diff --git a/src/compile.rs b/src/compile.rs index 527bd7e5..3fd3afd6 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -25,6 +25,7 @@ use std::sync::Arc; pub(crate) const UNUSED: u32 = u32::max_value(); pub(crate) const NULL_REG: u32 = UNUSED - 1; +#[repr(u8)] #[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, Default)] pub(crate) enum Ty { Int = 0,