use core::ffi::c_void;
#[derive(Clone, Copy)]
pub struct Property<'a> {
pub getter: *const c_void,
pub setter: *const c_void,
pub descriptor: *const c_void,
pub root: &'a [u8],
pub value: &'a [u8],
}
#[repr(C, align(8))]
pub struct Slot {
cache: u64,
pattern: [u32; 12],
descriptor: u64,
id: u64,
root: [u8; 64],
value: [u8; 64],
}
impl Slot {
pub const fn new() -> Self {
Slot {
cache: 0,
pattern: [0; 12],
descriptor: 0,
id: 0,
root: [0; 64],
value: [0; 64],
}
}
}
impl Default for Slot {
fn default() -> Self {
Self::new()
}
}
const BUFFER_HEADER: u32 = 0x8000_0018;
const EXTERNAL_COMPONENT: u32 = 0;
const COMPUTED_COMPONENT: u32 = 0x02c0_0002;
unsafe fn offset(to: *const u8, at: *const u8) -> i32 {
let delta = to as isize - at as isize;
i32::try_from(delta).expect("key path relative pointer out of range")
}
pub unsafe fn build(
slot: &'static mut Slot,
property: Property<'_>,
thunks: (*const c_void, *const c_void, *mut *const c_void, *mut *const c_void),
) -> u64 {
unsafe {
let (get_thunk, set_thunk, get_target, set_target) = thunks;
*get_target = property.getter;
*set_target = property.setter;
slot.descriptor = property.descriptor as u64;
slot.id = property.getter as u64;
slot.root[..property.root.len()].copy_from_slice(property.root);
slot.value[..property.value.len()].copy_from_slice(property.value);
let base = slot.pattern.as_ptr() as *const u8;
let at = |i: usize| base.add(i * 4);
slot.pattern[0] = offset(&slot.cache as *const u64 as *const u8, at(0)) as u32;
slot.pattern[1] = 0;
slot.pattern[2] = (offset(slot.root.as_ptr(), at(2)) | 1) as u32;
slot.pattern[3] = (offset(slot.value.as_ptr(), at(3)) | 1) as u32;
slot.pattern[4] = 0;
slot.pattern[5] = BUFFER_HEADER;
slot.pattern[6] = EXTERNAL_COMPONENT;
slot.pattern[7] = (offset(&slot.descriptor as *const u64 as *const u8, at(7)) | 1) as u32;
slot.pattern[8] = COMPUTED_COMPONENT;
slot.pattern[9] = offset(&slot.id as *const u64 as *const u8, at(9)) as u32;
slot.pattern[10] = offset(get_thunk as *const u8, at(10)) as u32;
slot.pattern[11] = offset(set_thunk as *const u8, at(11)) as u32;
type GetKeyPath = unsafe extern "C" fn(*const c_void, *const c_void) -> u64;
let f: GetKeyPath = core::mem::transmute(crate::resolve::get_key_path());
f(base as *const c_void, core::ptr::null())
}
}
macro_rules! key_path_thunks {
($($get:ident, $set:ident, $get_sym:literal, $set_sym:literal,
$get_tgt:ident, $set_tgt:ident;)*) => {$(
crate::thunk::runtime_thunk! {
fn $get = $get_sym via $get_tgt {
prologue: ["mov x20, x0"], branch: "br", epilogue: [],
}
fn $set = $set_sym via $set_tgt {
prologue: ["mov x20, x1"], branch: "br", epilogue: [],
}
}
)*};
}
key_path_thunks! {
kp0_get, kp0_set, "rswift_kp0_get", "rswift_kp0_set", RSWIFT_KP0_GET, RSWIFT_KP0_SET;
kp1_get, kp1_set, "rswift_kp1_get", "rswift_kp1_set", RSWIFT_KP1_GET, RSWIFT_KP1_SET;
kp2_get, kp2_set, "rswift_kp2_get", "rswift_kp2_set", RSWIFT_KP2_GET, RSWIFT_KP2_SET;
kp3_get, kp3_set, "rswift_kp3_get", "rswift_kp3_set", RSWIFT_KP3_GET, RSWIFT_KP3_SET;
kp4_get, kp4_set, "rswift_kp4_get", "rswift_kp4_set", RSWIFT_KP4_GET, RSWIFT_KP4_SET;
kp5_get, kp5_set, "rswift_kp5_get", "rswift_kp5_set", RSWIFT_KP5_GET, RSWIFT_KP5_SET;
kp6_get, kp6_set, "rswift_kp6_get", "rswift_kp6_set", RSWIFT_KP6_GET, RSWIFT_KP6_SET;
kp7_get, kp7_set, "rswift_kp7_get", "rswift_kp7_set", RSWIFT_KP7_GET, RSWIFT_KP7_SET;
kp8_get, kp8_set, "rswift_kp8_get", "rswift_kp8_set", RSWIFT_KP8_GET, RSWIFT_KP8_SET;
kp9_get, kp9_set, "rswift_kp9_get", "rswift_kp9_set", RSWIFT_KP9_GET, RSWIFT_KP9_SET;
kp10_get, kp10_set, "rswift_kp10_get", "rswift_kp10_set", RSWIFT_KP10_GET, RSWIFT_KP10_SET;
kp11_get, kp11_set, "rswift_kp11_get", "rswift_kp11_set", RSWIFT_KP11_GET, RSWIFT_KP11_SET;
kp12_get, kp12_set, "rswift_kp12_get", "rswift_kp12_set", RSWIFT_KP12_GET, RSWIFT_KP12_SET;
kp13_get, kp13_set, "rswift_kp13_get", "rswift_kp13_set", RSWIFT_KP13_GET, RSWIFT_KP13_SET;
kp14_get, kp14_set, "rswift_kp14_get", "rswift_kp14_set", RSWIFT_KP14_GET, RSWIFT_KP14_SET;
kp15_get, kp15_set, "rswift_kp15_get", "rswift_kp15_set", RSWIFT_KP15_GET, RSWIFT_KP15_SET;
kp16_get, kp16_set, "rswift_kp16_get", "rswift_kp16_set", RSWIFT_KP16_GET, RSWIFT_KP16_SET;
kp17_get, kp17_set, "rswift_kp17_get", "rswift_kp17_set", RSWIFT_KP17_GET, RSWIFT_KP17_SET;
kp18_get, kp18_set, "rswift_kp18_get", "rswift_kp18_set", RSWIFT_KP18_GET, RSWIFT_KP18_SET;
kp19_get, kp19_set, "rswift_kp19_get", "rswift_kp19_set", RSWIFT_KP19_GET, RSWIFT_KP19_SET;
kp20_get, kp20_set, "rswift_kp20_get", "rswift_kp20_set", RSWIFT_KP20_GET, RSWIFT_KP20_SET;
kp21_get, kp21_set, "rswift_kp21_get", "rswift_kp21_set", RSWIFT_KP21_GET, RSWIFT_KP21_SET;
kp22_get, kp22_set, "rswift_kp22_get", "rswift_kp22_set", RSWIFT_KP22_GET, RSWIFT_KP22_SET;
kp23_get, kp23_set, "rswift_kp23_get", "rswift_kp23_set", RSWIFT_KP23_GET, RSWIFT_KP23_SET;
kp24_get, kp24_set, "rswift_kp24_get", "rswift_kp24_set", RSWIFT_KP24_GET, RSWIFT_KP24_SET;
kp25_get, kp25_set, "rswift_kp25_get", "rswift_kp25_set", RSWIFT_KP25_GET, RSWIFT_KP25_SET;
kp26_get, kp26_set, "rswift_kp26_get", "rswift_kp26_set", RSWIFT_KP26_GET, RSWIFT_KP26_SET;
kp27_get, kp27_set, "rswift_kp27_get", "rswift_kp27_set", RSWIFT_KP27_GET, RSWIFT_KP27_SET;
kp28_get, kp28_set, "rswift_kp28_get", "rswift_kp28_set", RSWIFT_KP28_GET, RSWIFT_KP28_SET;
kp29_get, kp29_set, "rswift_kp29_get", "rswift_kp29_set", RSWIFT_KP29_GET, RSWIFT_KP29_SET;
kp30_get, kp30_set, "rswift_kp30_get", "rswift_kp30_set", RSWIFT_KP30_GET, RSWIFT_KP30_SET;
kp31_get, kp31_set, "rswift_kp31_get", "rswift_kp31_set", RSWIFT_KP31_GET, RSWIFT_KP31_SET;
}
pub const THUNK_COUNT: usize = 32;
pub fn thunks(index: usize) -> (*const c_void, *const c_void, *mut *const c_void, *mut *const c_void) {
match index {
0 => (kp0_get as *const c_void, kp0_set as *const c_void,
&raw mut RSWIFT_KP0_GET, &raw mut RSWIFT_KP0_SET),
1 => (kp1_get as *const c_void, kp1_set as *const c_void,
&raw mut RSWIFT_KP1_GET, &raw mut RSWIFT_KP1_SET),
2 => (kp2_get as *const c_void, kp2_set as *const c_void,
&raw mut RSWIFT_KP2_GET, &raw mut RSWIFT_KP2_SET),
3 => (kp3_get as *const c_void, kp3_set as *const c_void,
&raw mut RSWIFT_KP3_GET, &raw mut RSWIFT_KP3_SET),
4 => (kp4_get as *const c_void, kp4_set as *const c_void,
&raw mut RSWIFT_KP4_GET, &raw mut RSWIFT_KP4_SET),
5 => (kp5_get as *const c_void, kp5_set as *const c_void,
&raw mut RSWIFT_KP5_GET, &raw mut RSWIFT_KP5_SET),
6 => (kp6_get as *const c_void, kp6_set as *const c_void,
&raw mut RSWIFT_KP6_GET, &raw mut RSWIFT_KP6_SET),
7 => (kp7_get as *const c_void, kp7_set as *const c_void,
&raw mut RSWIFT_KP7_GET, &raw mut RSWIFT_KP7_SET),
8 => (kp8_get as *const c_void, kp8_set as *const c_void,
&raw mut RSWIFT_KP8_GET, &raw mut RSWIFT_KP8_SET),
9 => (kp9_get as *const c_void, kp9_set as *const c_void,
&raw mut RSWIFT_KP9_GET, &raw mut RSWIFT_KP9_SET),
10 => (kp10_get as *const c_void, kp10_set as *const c_void,
&raw mut RSWIFT_KP10_GET, &raw mut RSWIFT_KP10_SET),
11 => (kp11_get as *const c_void, kp11_set as *const c_void,
&raw mut RSWIFT_KP11_GET, &raw mut RSWIFT_KP11_SET),
12 => (kp12_get as *const c_void, kp12_set as *const c_void,
&raw mut RSWIFT_KP12_GET, &raw mut RSWIFT_KP12_SET),
13 => (kp13_get as *const c_void, kp13_set as *const c_void,
&raw mut RSWIFT_KP13_GET, &raw mut RSWIFT_KP13_SET),
14 => (kp14_get as *const c_void, kp14_set as *const c_void,
&raw mut RSWIFT_KP14_GET, &raw mut RSWIFT_KP14_SET),
15 => (kp15_get as *const c_void, kp15_set as *const c_void,
&raw mut RSWIFT_KP15_GET, &raw mut RSWIFT_KP15_SET),
16 => (kp16_get as *const c_void, kp16_set as *const c_void,
&raw mut RSWIFT_KP16_GET, &raw mut RSWIFT_KP16_SET),
17 => (kp17_get as *const c_void, kp17_set as *const c_void,
&raw mut RSWIFT_KP17_GET, &raw mut RSWIFT_KP17_SET),
18 => (kp18_get as *const c_void, kp18_set as *const c_void,
&raw mut RSWIFT_KP18_GET, &raw mut RSWIFT_KP18_SET),
19 => (kp19_get as *const c_void, kp19_set as *const c_void,
&raw mut RSWIFT_KP19_GET, &raw mut RSWIFT_KP19_SET),
20 => (kp20_get as *const c_void, kp20_set as *const c_void,
&raw mut RSWIFT_KP20_GET, &raw mut RSWIFT_KP20_SET),
21 => (kp21_get as *const c_void, kp21_set as *const c_void,
&raw mut RSWIFT_KP21_GET, &raw mut RSWIFT_KP21_SET),
22 => (kp22_get as *const c_void, kp22_set as *const c_void,
&raw mut RSWIFT_KP22_GET, &raw mut RSWIFT_KP22_SET),
23 => (kp23_get as *const c_void, kp23_set as *const c_void,
&raw mut RSWIFT_KP23_GET, &raw mut RSWIFT_KP23_SET),
24 => (kp24_get as *const c_void, kp24_set as *const c_void,
&raw mut RSWIFT_KP24_GET, &raw mut RSWIFT_KP24_SET),
25 => (kp25_get as *const c_void, kp25_set as *const c_void,
&raw mut RSWIFT_KP25_GET, &raw mut RSWIFT_KP25_SET),
26 => (kp26_get as *const c_void, kp26_set as *const c_void,
&raw mut RSWIFT_KP26_GET, &raw mut RSWIFT_KP26_SET),
27 => (kp27_get as *const c_void, kp27_set as *const c_void,
&raw mut RSWIFT_KP27_GET, &raw mut RSWIFT_KP27_SET),
28 => (kp28_get as *const c_void, kp28_set as *const c_void,
&raw mut RSWIFT_KP28_GET, &raw mut RSWIFT_KP28_SET),
29 => (kp29_get as *const c_void, kp29_set as *const c_void,
&raw mut RSWIFT_KP29_GET, &raw mut RSWIFT_KP29_SET),
30 => (kp30_get as *const c_void, kp30_set as *const c_void,
&raw mut RSWIFT_KP30_GET, &raw mut RSWIFT_KP30_SET),
31 => (kp31_get as *const c_void, kp31_set as *const c_void,
&raw mut RSWIFT_KP31_GET, &raw mut RSWIFT_KP31_SET),
_ => panic!(
"key path {index} is past the {THUNK_COUNT} thunk pairs; \
add more to key_path_thunks!"
),
}
}
pub fn next_thunks() -> (*const c_void, *const c_void, *mut *const c_void, *mut *const c_void) {
static NEXT: std::sync::atomic::AtomicUsize = std::sync::atomic::AtomicUsize::new(0);
let i = NEXT.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
assert!(
i < THUNK_COUNT,
"more than {THUNK_COUNT} key paths; add more pairs to key_path_thunks!"
);
thunks(i)
}
const COMPUTED_BUFFER_HEADER: u32 = 0x8000_000C;
const COMPUTED_GET_ONLY: u32 = 0x0200_0000;
#[repr(C, align(8))]
pub struct ComputedSlot {
cache: u64,
pattern: [u32; 9],
_pad: u32,
root: [u8; 48],
value: [u8; 48],
}
impl ComputedSlot {
pub const fn new() -> Self {
ComputedSlot { cache: 0, pattern: [0; 9], _pad: 0, root: [0; 48], value: [0; 48] }
}
}
impl Default for ComputedSlot {
fn default() -> Self {
Self::new()
}
}
pub unsafe fn build_computed(
slot: &'static mut ComputedSlot,
root: &[u8],
value: &[u8],
getter: *const c_void,
) -> u64 {
unsafe {
slot.root[..root.len()].copy_from_slice(root);
slot.value[..value.len()].copy_from_slice(value);
let base = slot.pattern.as_ptr() as *const u8;
let at = |i: usize| base.add(i * 4);
slot.pattern[0] = offset(&slot.cache as *const u64 as *const u8, at(0)) as u32;
slot.pattern[1] = 0;
slot.pattern[2] = (offset(slot.root.as_ptr(), at(2)) | 1) as u32;
slot.pattern[3] = (offset(slot.value.as_ptr(), at(3)) | 1) as u32;
slot.pattern[4] = 0;
slot.pattern[5] = COMPUTED_BUFFER_HEADER;
slot.pattern[6] = COMPUTED_GET_ONLY;
slot.pattern[7] = offset(getter as *const u8, at(7)) as u32;
slot.pattern[8] = offset(getter as *const u8, at(8)) as u32;
type GetKeyPath = unsafe extern "C" fn(*const c_void, *const c_void) -> u64;
let f: GetKeyPath = core::mem::transmute(crate::resolve::get_key_path());
f(base as *const c_void, core::ptr::null())
}
}
core::arch::global_asm!(
".p2align 2",
".globl _rswift_kp_nil_children_get",
"_rswift_kp_nil_children_get:",
"mov x1, x0",
"mov x0, x8",
"b _rswift_kp_nil_children_body",
);
unsafe extern "C" {
#[link_name = "rswift_kp_nil_children_get"]
pub fn kp_nil_children_get();
}
#[unsafe(no_mangle)]
unsafe extern "C" fn rswift_kp_nil_children_body(out: *mut u8, _root: *const u8) {
unsafe { core::ptr::write_bytes(out, 0, 8) };
}
const IDENTITY_BUFFER_HEADER: u32 = 0x8000_0000;
#[repr(C, align(8))]
pub struct IdentitySlot {
cache: u64,
pattern: [u32; 6],
_pad: [u32; 2],
root: [u8; 48],
value: [u8; 48],
}
impl IdentitySlot {
pub const fn new() -> Self {
IdentitySlot { cache: 0, pattern: [0; 6], _pad: [0; 2], root: [0; 48], value: [0; 48] }
}
}
impl Default for IdentitySlot {
fn default() -> Self {
Self::new()
}
}
pub unsafe fn build_identity(slot: &'static mut IdentitySlot, root: &[u8], value: &[u8]) -> u64 {
unsafe {
slot.root[..root.len()].copy_from_slice(root);
slot.value[..value.len()].copy_from_slice(value);
let base = slot.pattern.as_ptr() as *const u8;
let at = |i: usize| base.add(i * 4);
slot.pattern[0] = offset(&slot.cache as *const u64 as *const u8, at(0)) as u32;
slot.pattern[1] = 0;
slot.pattern[2] = (offset(slot.root.as_ptr(), at(2)) | 1) as u32;
slot.pattern[3] = (offset(slot.value.as_ptr(), at(3)) | 1) as u32;
slot.pattern[4] = 0;
slot.pattern[5] = IDENTITY_BUFFER_HEADER;
type GetKeyPath = unsafe extern "C" fn(*const c_void, *const c_void) -> u64;
let f: GetKeyPath = core::mem::transmute(crate::resolve::get_key_path());
f(base as *const c_void, core::ptr::null())
}
}
const WRITABLE_BUFFER_HEADER: u32 = 0x8000_0010;
const WRITABLE_COMPUTED_COMPONENT: u32 = 0x02c0_0000;
#[repr(C, align(8))]
pub struct WritableComputedSlot {
cache: u64,
pattern: [u32; 10],
_pad: [u32; 2],
root: [u8; 64],
value: [u8; 64],
}
impl WritableComputedSlot {
pub const fn new() -> Self {
WritableComputedSlot {
cache: 0,
pattern: [0; 10],
_pad: [0; 2],
root: [0; 64],
value: [0; 64],
}
}
}
impl Default for WritableComputedSlot {
fn default() -> Self {
Self::new()
}
}
pub unsafe fn build_writable_computed(
slot: &'static mut WritableComputedSlot,
root: &[u8],
value: &[u8],
getter: *const c_void,
setter: *const c_void,
) -> u64 {
unsafe {
slot.root[..root.len()].copy_from_slice(root);
slot.value[..value.len()].copy_from_slice(value);
let base = slot.pattern.as_ptr() as *const u8;
let at = |i: usize| base.add(i * 4);
slot.pattern[0] = offset(&slot.cache as *const u64 as *const u8, at(0)) as u32;
slot.pattern[1] = 0;
slot.pattern[2] = (offset(slot.root.as_ptr(), at(2)) | 1) as u32;
slot.pattern[3] = (offset(slot.value.as_ptr(), at(3)) | 1) as u32;
slot.pattern[4] = 0;
slot.pattern[5] = WRITABLE_BUFFER_HEADER;
slot.pattern[6] = WRITABLE_COMPUTED_COMPONENT;
slot.pattern[7] = offset(getter as *const u8, at(7)) as u32;
slot.pattern[8] = offset(getter as *const u8, at(8)) as u32;
slot.pattern[9] = offset(setter as *const u8, at(9)) as u32;
type GetKeyPath = unsafe extern "C" fn(*const c_void, *const c_void) -> u64;
let f: GetKeyPath = core::mem::transmute(crate::resolve::get_key_path());
f(base as *const c_void, core::ptr::null())
}
}
macro_rules! value_thunks {
($($i:literal, $get:ident, $set:ident, $gsym:literal, $ssym:literal,
$gtgt:ident, $stgt:ident;)*) => {
$(
crate::thunk::runtime_thunk! {
fn $get = $gsym via $gtgt {
prologue: ["mov x1, x0", "mov x0, x8", concat!("mov x2, #", $i)],
branch: "br", epilogue: [],
}
fn $set = $ssym via $stgt {
prologue: [concat!("mov x2, #", $i)],
branch: "br", epilogue: [],
}
}
)*
pub const VALUE_SLOTS: usize = [$($i),*].len();
pub fn value_thunks(
index: usize,
) -> (*const c_void, *const c_void, *mut *const c_void, *mut *const c_void) {
match index {
$($i => (
$get as *const c_void,
$set as *const c_void,
&raw mut $gtgt,
&raw mut $stgt,
),)*
_ => panic!(
"key path slot {index} is past the {} this crate has",
VALUE_SLOTS,
),
}
}
};
}
value_thunks! {
0, fk0_get, fk0_set, "rswift_fk0_get", "rswift_fk0_set", RSWIFT_FK0_GET, RSWIFT_FK0_SET;
1, fk1_get, fk1_set, "rswift_fk1_get", "rswift_fk1_set", RSWIFT_FK1_GET, RSWIFT_FK1_SET;
2, fk2_get, fk2_set, "rswift_fk2_get", "rswift_fk2_set", RSWIFT_FK2_GET, RSWIFT_FK2_SET;
3, fk3_get, fk3_set, "rswift_fk3_get", "rswift_fk3_set", RSWIFT_FK3_GET, RSWIFT_FK3_SET;
4, fk4_get, fk4_set, "rswift_fk4_get", "rswift_fk4_set", RSWIFT_FK4_GET, RSWIFT_FK4_SET;
5, fk5_get, fk5_set, "rswift_fk5_get", "rswift_fk5_set", RSWIFT_FK5_GET, RSWIFT_FK5_SET;
6, fk6_get, fk6_set, "rswift_fk6_get", "rswift_fk6_set", RSWIFT_FK6_GET, RSWIFT_FK6_SET;
7, fk7_get, fk7_set, "rswift_fk7_get", "rswift_fk7_set", RSWIFT_FK7_GET, RSWIFT_FK7_SET;
8, fk8_get, fk8_set, "rswift_fk8_get", "rswift_fk8_set", RSWIFT_FK8_GET, RSWIFT_FK8_SET;
9, fk9_get, fk9_set, "rswift_fk9_get", "rswift_fk9_set", RSWIFT_FK9_GET, RSWIFT_FK9_SET;
10, fk10_get, fk10_set, "rswift_fk10_get", "rswift_fk10_set", RSWIFT_FK10_GET, RSWIFT_FK10_SET;
11, fk11_get, fk11_set, "rswift_fk11_get", "rswift_fk11_set", RSWIFT_FK11_GET, RSWIFT_FK11_SET;
12, fk12_get, fk12_set, "rswift_fk12_get", "rswift_fk12_set", RSWIFT_FK12_GET, RSWIFT_FK12_SET;
13, fk13_get, fk13_set, "rswift_fk13_get", "rswift_fk13_set", RSWIFT_FK13_GET, RSWIFT_FK13_SET;
14, fk14_get, fk14_set, "rswift_fk14_get", "rswift_fk14_set", RSWIFT_FK14_GET, RSWIFT_FK14_SET;
15, fk15_get, fk15_set, "rswift_fk15_get", "rswift_fk15_set", RSWIFT_FK15_GET, RSWIFT_FK15_SET;
16, fk16_get, fk16_set, "rswift_fk16_get", "rswift_fk16_set", RSWIFT_FK16_GET, RSWIFT_FK16_SET;
17, fk17_get, fk17_set, "rswift_fk17_get", "rswift_fk17_set", RSWIFT_FK17_GET, RSWIFT_FK17_SET;
18, fk18_get, fk18_set, "rswift_fk18_get", "rswift_fk18_set", RSWIFT_FK18_GET, RSWIFT_FK18_SET;
19, fk19_get, fk19_set, "rswift_fk19_get", "rswift_fk19_set", RSWIFT_FK19_GET, RSWIFT_FK19_SET;
20, fk20_get, fk20_set, "rswift_fk20_get", "rswift_fk20_set", RSWIFT_FK20_GET, RSWIFT_FK20_SET;
21, fk21_get, fk21_set, "rswift_fk21_get", "rswift_fk21_set", RSWIFT_FK21_GET, RSWIFT_FK21_SET;
22, fk22_get, fk22_set, "rswift_fk22_get", "rswift_fk22_set", RSWIFT_FK22_GET, RSWIFT_FK22_SET;
23, fk23_get, fk23_set, "rswift_fk23_get", "rswift_fk23_set", RSWIFT_FK23_GET, RSWIFT_FK23_SET;
24, fk24_get, fk24_set, "rswift_fk24_get", "rswift_fk24_set", RSWIFT_FK24_GET, RSWIFT_FK24_SET;
25, fk25_get, fk25_set, "rswift_fk25_get", "rswift_fk25_set", RSWIFT_FK25_GET, RSWIFT_FK25_SET;
26, fk26_get, fk26_set, "rswift_fk26_get", "rswift_fk26_set", RSWIFT_FK26_GET, RSWIFT_FK26_SET;
27, fk27_get, fk27_set, "rswift_fk27_get", "rswift_fk27_set", RSWIFT_FK27_GET, RSWIFT_FK27_SET;
28, fk28_get, fk28_set, "rswift_fk28_get", "rswift_fk28_set", RSWIFT_FK28_GET, RSWIFT_FK28_SET;
29, fk29_get, fk29_set, "rswift_fk29_get", "rswift_fk29_set", RSWIFT_FK29_GET, RSWIFT_FK29_SET;
30, fk30_get, fk30_set, "rswift_fk30_get", "rswift_fk30_set", RSWIFT_FK30_GET, RSWIFT_FK30_SET;
31, fk31_get, fk31_set, "rswift_fk31_get", "rswift_fk31_set", RSWIFT_FK31_GET, RSWIFT_FK31_SET;
}
static mut SLOTS: [WritableComputedSlot; VALUE_SLOTS] =
[const { WritableComputedSlot::new() }; VALUE_SLOTS];
pub fn next_value_slot() -> usize {
use std::sync::atomic::{AtomicUsize, Ordering};
static NEXT: AtomicUsize = AtomicUsize::new(0);
let i = NEXT.fetch_add(1, Ordering::Relaxed);
assert!(
i < VALUE_SLOTS,
"this crate can synthesise {VALUE_SLOTS} key paths; the {}th was asked for",
i + 1,
);
i
}
pub unsafe fn value_slot(index: usize) -> &'static mut WritableComputedSlot {
unsafe { &mut SLOTS[index] }
}