1use core::ffi::c_void;
44
45#[derive(Clone, Copy)]
47pub struct Property<'a> {
48 pub getter: *const c_void,
50 pub setter: *const c_void,
52 pub descriptor: *const c_void,
54 pub root: &'a [u8],
59 pub value: &'a [u8],
61}
62
63#[repr(C, align(8))]
65pub struct Slot {
66 cache: u64,
67 pattern: [u32; 12],
68 descriptor: u64,
69 id: u64,
70 root: [u8; 64],
71 value: [u8; 64],
72}
73
74impl Slot {
75 pub const fn new() -> Self {
77 Slot {
78 cache: 0,
79 pattern: [0; 12],
80 descriptor: 0,
81 id: 0,
82 root: [0; 64],
83 value: [0; 64],
84 }
85 }
86}
87
88impl Default for Slot {
89 fn default() -> Self {
90 Self::new()
91 }
92}
93
94const BUFFER_HEADER: u32 = 0x8000_0018;
96const EXTERNAL_COMPONENT: u32 = 0;
98const COMPUTED_COMPONENT: u32 = 0x02c0_0002;
100
101unsafe fn offset(to: *const u8, at: *const u8) -> i32 {
103 let delta = to as isize - at as isize;
104 i32::try_from(delta).expect("key path relative pointer out of range")
105}
106
107pub unsafe fn build(
116 slot: &'static mut Slot,
117 property: Property<'_>,
118 thunks: (*const c_void, *const c_void, *mut *const c_void, *mut *const c_void),
119) -> u64 {
120 unsafe {
121 let (get_thunk, set_thunk, get_target, set_target) = thunks;
122 *get_target = property.getter;
123 *set_target = property.setter;
124 slot.descriptor = property.descriptor as u64;
125 slot.id = property.getter as u64;
126 slot.root[..property.root.len()].copy_from_slice(property.root);
127 slot.value[..property.value.len()].copy_from_slice(property.value);
128
129 let base = slot.pattern.as_ptr() as *const u8;
130 let at = |i: usize| base.add(i * 4);
131 slot.pattern[0] = offset(&slot.cache as *const u64 as *const u8, at(0)) as u32;
132 slot.pattern[1] = 0;
133 slot.pattern[2] = (offset(slot.root.as_ptr(), at(2)) | 1) as u32;
137 slot.pattern[3] = (offset(slot.value.as_ptr(), at(3)) | 1) as u32;
138 slot.pattern[4] = 0;
139 slot.pattern[5] = BUFFER_HEADER;
140 slot.pattern[6] = EXTERNAL_COMPONENT;
141 slot.pattern[7] = (offset(&slot.descriptor as *const u64 as *const u8, at(7)) | 1) as u32;
145 slot.pattern[8] = COMPUTED_COMPONENT;
146 slot.pattern[9] = offset(&slot.id as *const u64 as *const u8, at(9)) as u32;
147 slot.pattern[10] = offset(get_thunk as *const u8, at(10)) as u32;
148 slot.pattern[11] = offset(set_thunk as *const u8, at(11)) as u32;
149
150 type GetKeyPath = unsafe extern "C" fn(*const c_void, *const c_void) -> u64;
151 let f: GetKeyPath = core::mem::transmute(crate::resolve::get_key_path());
152 f(base as *const c_void, core::ptr::null())
153 }
154}
155
156macro_rules! key_path_thunks {
167 ($($get:ident, $set:ident, $get_sym:literal, $set_sym:literal,
168 $get_tgt:ident, $set_tgt:ident;)*) => {$(
169 crate::thunk::runtime_thunk! {
170 fn $get = $get_sym via $get_tgt {
172 prologue: ["mov x20, x0"], branch: "br", epilogue: [],
173 }
174 fn $set = $set_sym via $set_tgt {
176 prologue: ["mov x20, x1"], branch: "br", epilogue: [],
177 }
178 }
179 )*};
180}
181
182key_path_thunks! {
183 kp0_get, kp0_set, "rswift_kp0_get", "rswift_kp0_set", RSWIFT_KP0_GET, RSWIFT_KP0_SET;
184 kp1_get, kp1_set, "rswift_kp1_get", "rswift_kp1_set", RSWIFT_KP1_GET, RSWIFT_KP1_SET;
185 kp2_get, kp2_set, "rswift_kp2_get", "rswift_kp2_set", RSWIFT_KP2_GET, RSWIFT_KP2_SET;
186 kp3_get, kp3_set, "rswift_kp3_get", "rswift_kp3_set", RSWIFT_KP3_GET, RSWIFT_KP3_SET;
187 kp4_get, kp4_set, "rswift_kp4_get", "rswift_kp4_set", RSWIFT_KP4_GET, RSWIFT_KP4_SET;
188 kp5_get, kp5_set, "rswift_kp5_get", "rswift_kp5_set", RSWIFT_KP5_GET, RSWIFT_KP5_SET;
189 kp6_get, kp6_set, "rswift_kp6_get", "rswift_kp6_set", RSWIFT_KP6_GET, RSWIFT_KP6_SET;
190 kp7_get, kp7_set, "rswift_kp7_get", "rswift_kp7_set", RSWIFT_KP7_GET, RSWIFT_KP7_SET;
191 kp8_get, kp8_set, "rswift_kp8_get", "rswift_kp8_set", RSWIFT_KP8_GET, RSWIFT_KP8_SET;
192 kp9_get, kp9_set, "rswift_kp9_get", "rswift_kp9_set", RSWIFT_KP9_GET, RSWIFT_KP9_SET;
193 kp10_get, kp10_set, "rswift_kp10_get", "rswift_kp10_set", RSWIFT_KP10_GET, RSWIFT_KP10_SET;
194 kp11_get, kp11_set, "rswift_kp11_get", "rswift_kp11_set", RSWIFT_KP11_GET, RSWIFT_KP11_SET;
195 kp12_get, kp12_set, "rswift_kp12_get", "rswift_kp12_set", RSWIFT_KP12_GET, RSWIFT_KP12_SET;
196 kp13_get, kp13_set, "rswift_kp13_get", "rswift_kp13_set", RSWIFT_KP13_GET, RSWIFT_KP13_SET;
197 kp14_get, kp14_set, "rswift_kp14_get", "rswift_kp14_set", RSWIFT_KP14_GET, RSWIFT_KP14_SET;
198 kp15_get, kp15_set, "rswift_kp15_get", "rswift_kp15_set", RSWIFT_KP15_GET, RSWIFT_KP15_SET;
199 kp16_get, kp16_set, "rswift_kp16_get", "rswift_kp16_set", RSWIFT_KP16_GET, RSWIFT_KP16_SET;
200 kp17_get, kp17_set, "rswift_kp17_get", "rswift_kp17_set", RSWIFT_KP17_GET, RSWIFT_KP17_SET;
201 kp18_get, kp18_set, "rswift_kp18_get", "rswift_kp18_set", RSWIFT_KP18_GET, RSWIFT_KP18_SET;
202 kp19_get, kp19_set, "rswift_kp19_get", "rswift_kp19_set", RSWIFT_KP19_GET, RSWIFT_KP19_SET;
203 kp20_get, kp20_set, "rswift_kp20_get", "rswift_kp20_set", RSWIFT_KP20_GET, RSWIFT_KP20_SET;
204 kp21_get, kp21_set, "rswift_kp21_get", "rswift_kp21_set", RSWIFT_KP21_GET, RSWIFT_KP21_SET;
205 kp22_get, kp22_set, "rswift_kp22_get", "rswift_kp22_set", RSWIFT_KP22_GET, RSWIFT_KP22_SET;
206 kp23_get, kp23_set, "rswift_kp23_get", "rswift_kp23_set", RSWIFT_KP23_GET, RSWIFT_KP23_SET;
207 kp24_get, kp24_set, "rswift_kp24_get", "rswift_kp24_set", RSWIFT_KP24_GET, RSWIFT_KP24_SET;
208 kp25_get, kp25_set, "rswift_kp25_get", "rswift_kp25_set", RSWIFT_KP25_GET, RSWIFT_KP25_SET;
209 kp26_get, kp26_set, "rswift_kp26_get", "rswift_kp26_set", RSWIFT_KP26_GET, RSWIFT_KP26_SET;
210 kp27_get, kp27_set, "rswift_kp27_get", "rswift_kp27_set", RSWIFT_KP27_GET, RSWIFT_KP27_SET;
211 kp28_get, kp28_set, "rswift_kp28_get", "rswift_kp28_set", RSWIFT_KP28_GET, RSWIFT_KP28_SET;
212 kp29_get, kp29_set, "rswift_kp29_get", "rswift_kp29_set", RSWIFT_KP29_GET, RSWIFT_KP29_SET;
213 kp30_get, kp30_set, "rswift_kp30_get", "rswift_kp30_set", RSWIFT_KP30_GET, RSWIFT_KP30_SET;
214 kp31_get, kp31_set, "rswift_kp31_get", "rswift_kp31_set", RSWIFT_KP31_GET, RSWIFT_KP31_SET;
215}
216
217pub const THUNK_COUNT: usize = 32;
219
220pub fn thunks(index: usize) -> (*const c_void, *const c_void, *mut *const c_void, *mut *const c_void) {
228 match index {
229 0 => (kp0_get as *const c_void, kp0_set as *const c_void,
230 &raw mut RSWIFT_KP0_GET, &raw mut RSWIFT_KP0_SET),
231 1 => (kp1_get as *const c_void, kp1_set as *const c_void,
232 &raw mut RSWIFT_KP1_GET, &raw mut RSWIFT_KP1_SET),
233 2 => (kp2_get as *const c_void, kp2_set as *const c_void,
234 &raw mut RSWIFT_KP2_GET, &raw mut RSWIFT_KP2_SET),
235 3 => (kp3_get as *const c_void, kp3_set as *const c_void,
236 &raw mut RSWIFT_KP3_GET, &raw mut RSWIFT_KP3_SET),
237 4 => (kp4_get as *const c_void, kp4_set as *const c_void,
238 &raw mut RSWIFT_KP4_GET, &raw mut RSWIFT_KP4_SET),
239 5 => (kp5_get as *const c_void, kp5_set as *const c_void,
240 &raw mut RSWIFT_KP5_GET, &raw mut RSWIFT_KP5_SET),
241 6 => (kp6_get as *const c_void, kp6_set as *const c_void,
242 &raw mut RSWIFT_KP6_GET, &raw mut RSWIFT_KP6_SET),
243 7 => (kp7_get as *const c_void, kp7_set as *const c_void,
244 &raw mut RSWIFT_KP7_GET, &raw mut RSWIFT_KP7_SET),
245 8 => (kp8_get as *const c_void, kp8_set as *const c_void,
246 &raw mut RSWIFT_KP8_GET, &raw mut RSWIFT_KP8_SET),
247 9 => (kp9_get as *const c_void, kp9_set as *const c_void,
248 &raw mut RSWIFT_KP9_GET, &raw mut RSWIFT_KP9_SET),
249 10 => (kp10_get as *const c_void, kp10_set as *const c_void,
250 &raw mut RSWIFT_KP10_GET, &raw mut RSWIFT_KP10_SET),
251 11 => (kp11_get as *const c_void, kp11_set as *const c_void,
252 &raw mut RSWIFT_KP11_GET, &raw mut RSWIFT_KP11_SET),
253 12 => (kp12_get as *const c_void, kp12_set as *const c_void,
254 &raw mut RSWIFT_KP12_GET, &raw mut RSWIFT_KP12_SET),
255 13 => (kp13_get as *const c_void, kp13_set as *const c_void,
256 &raw mut RSWIFT_KP13_GET, &raw mut RSWIFT_KP13_SET),
257 14 => (kp14_get as *const c_void, kp14_set as *const c_void,
258 &raw mut RSWIFT_KP14_GET, &raw mut RSWIFT_KP14_SET),
259 15 => (kp15_get as *const c_void, kp15_set as *const c_void,
260 &raw mut RSWIFT_KP15_GET, &raw mut RSWIFT_KP15_SET),
261 16 => (kp16_get as *const c_void, kp16_set as *const c_void,
262 &raw mut RSWIFT_KP16_GET, &raw mut RSWIFT_KP16_SET),
263 17 => (kp17_get as *const c_void, kp17_set as *const c_void,
264 &raw mut RSWIFT_KP17_GET, &raw mut RSWIFT_KP17_SET),
265 18 => (kp18_get as *const c_void, kp18_set as *const c_void,
266 &raw mut RSWIFT_KP18_GET, &raw mut RSWIFT_KP18_SET),
267 19 => (kp19_get as *const c_void, kp19_set as *const c_void,
268 &raw mut RSWIFT_KP19_GET, &raw mut RSWIFT_KP19_SET),
269 20 => (kp20_get as *const c_void, kp20_set as *const c_void,
270 &raw mut RSWIFT_KP20_GET, &raw mut RSWIFT_KP20_SET),
271 21 => (kp21_get as *const c_void, kp21_set as *const c_void,
272 &raw mut RSWIFT_KP21_GET, &raw mut RSWIFT_KP21_SET),
273 22 => (kp22_get as *const c_void, kp22_set as *const c_void,
274 &raw mut RSWIFT_KP22_GET, &raw mut RSWIFT_KP22_SET),
275 23 => (kp23_get as *const c_void, kp23_set as *const c_void,
276 &raw mut RSWIFT_KP23_GET, &raw mut RSWIFT_KP23_SET),
277 24 => (kp24_get as *const c_void, kp24_set as *const c_void,
278 &raw mut RSWIFT_KP24_GET, &raw mut RSWIFT_KP24_SET),
279 25 => (kp25_get as *const c_void, kp25_set as *const c_void,
280 &raw mut RSWIFT_KP25_GET, &raw mut RSWIFT_KP25_SET),
281 26 => (kp26_get as *const c_void, kp26_set as *const c_void,
282 &raw mut RSWIFT_KP26_GET, &raw mut RSWIFT_KP26_SET),
283 27 => (kp27_get as *const c_void, kp27_set as *const c_void,
284 &raw mut RSWIFT_KP27_GET, &raw mut RSWIFT_KP27_SET),
285 28 => (kp28_get as *const c_void, kp28_set as *const c_void,
286 &raw mut RSWIFT_KP28_GET, &raw mut RSWIFT_KP28_SET),
287 29 => (kp29_get as *const c_void, kp29_set as *const c_void,
288 &raw mut RSWIFT_KP29_GET, &raw mut RSWIFT_KP29_SET),
289 30 => (kp30_get as *const c_void, kp30_set as *const c_void,
290 &raw mut RSWIFT_KP30_GET, &raw mut RSWIFT_KP30_SET),
291 31 => (kp31_get as *const c_void, kp31_set as *const c_void,
292 &raw mut RSWIFT_KP31_GET, &raw mut RSWIFT_KP31_SET),
293 _ => panic!(
294 "key path {index} is past the {THUNK_COUNT} thunk pairs; \
295 add more to key_path_thunks!"
296 ),
297 }
298}
299
300pub fn next_thunks() -> (*const c_void, *const c_void, *mut *const c_void, *mut *const c_void) {
308 static NEXT: std::sync::atomic::AtomicUsize = std::sync::atomic::AtomicUsize::new(0);
309 let i = NEXT.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
310 assert!(
311 i < THUNK_COUNT,
312 "more than {THUNK_COUNT} key paths; add more pairs to key_path_thunks!"
313 );
314 thunks(i)
315}
316
317const COMPUTED_BUFFER_HEADER: u32 = 0x8000_000C;
321const COMPUTED_GET_ONLY: u32 = 0x0200_0000;
323
324#[repr(C, align(8))]
330pub struct ComputedSlot {
331 cache: u64,
332 pattern: [u32; 9],
333 _pad: u32,
334 root: [u8; 48],
335 value: [u8; 48],
336}
337
338impl ComputedSlot {
339 pub const fn new() -> Self {
341 ComputedSlot { cache: 0, pattern: [0; 9], _pad: 0, root: [0; 48], value: [0; 48] }
342 }
343}
344
345impl Default for ComputedSlot {
346 fn default() -> Self {
347 Self::new()
348 }
349}
350
351pub unsafe fn build_computed(
369 slot: &'static mut ComputedSlot,
370 root: &[u8],
371 value: &[u8],
372 getter: *const c_void,
373) -> u64 {
374 unsafe {
375 slot.root[..root.len()].copy_from_slice(root);
376 slot.value[..value.len()].copy_from_slice(value);
377
378 let base = slot.pattern.as_ptr() as *const u8;
379 let at = |i: usize| base.add(i * 4);
380 slot.pattern[0] = offset(&slot.cache as *const u64 as *const u8, at(0)) as u32;
381 slot.pattern[1] = 0;
382 slot.pattern[2] = (offset(slot.root.as_ptr(), at(2)) | 1) as u32;
383 slot.pattern[3] = (offset(slot.value.as_ptr(), at(3)) | 1) as u32;
384 slot.pattern[4] = 0;
385 slot.pattern[5] = COMPUTED_BUFFER_HEADER;
386 slot.pattern[6] = COMPUTED_GET_ONLY;
387 slot.pattern[7] = offset(getter as *const u8, at(7)) as u32;
391 slot.pattern[8] = offset(getter as *const u8, at(8)) as u32;
392
393 type GetKeyPath = unsafe extern "C" fn(*const c_void, *const c_void) -> u64;
394 let f: GetKeyPath = core::mem::transmute(crate::resolve::get_key_path());
395 f(base as *const c_void, core::ptr::null())
396 }
397}
398
399core::arch::global_asm!(
405 ".p2align 2",
406 ".globl _rswift_kp_nil_children_get",
407 "_rswift_kp_nil_children_get:",
408 "mov x1, x0",
409 "mov x0, x8",
410 "b _rswift_kp_nil_children_body",
411);
412
413unsafe extern "C" {
414 #[link_name = "rswift_kp_nil_children_get"]
416 pub fn kp_nil_children_get();
417}
418
419#[unsafe(no_mangle)]
420unsafe extern "C" fn rswift_kp_nil_children_body(out: *mut u8, _root: *const u8) {
421 unsafe { core::ptr::write_bytes(out, 0, 8) };
424}
425
426const IDENTITY_BUFFER_HEADER: u32 = 0x8000_0000;
430
431#[repr(C, align(8))]
436pub struct IdentitySlot {
437 cache: u64,
438 pattern: [u32; 6],
439 _pad: [u32; 2],
440 root: [u8; 48],
441 value: [u8; 48],
442}
443
444impl IdentitySlot {
445 pub const fn new() -> Self {
447 IdentitySlot { cache: 0, pattern: [0; 6], _pad: [0; 2], root: [0; 48], value: [0; 48] }
448 }
449}
450
451impl Default for IdentitySlot {
452 fn default() -> Self {
453 Self::new()
454 }
455}
456
457pub unsafe fn build_identity(slot: &'static mut IdentitySlot, root: &[u8], value: &[u8]) -> u64 {
473 unsafe {
474 slot.root[..root.len()].copy_from_slice(root);
475 slot.value[..value.len()].copy_from_slice(value);
476
477 let base = slot.pattern.as_ptr() as *const u8;
478 let at = |i: usize| base.add(i * 4);
479 slot.pattern[0] = offset(&slot.cache as *const u64 as *const u8, at(0)) as u32;
480 slot.pattern[1] = 0;
481 slot.pattern[2] = (offset(slot.root.as_ptr(), at(2)) | 1) as u32;
482 slot.pattern[3] = (offset(slot.value.as_ptr(), at(3)) | 1) as u32;
483 slot.pattern[4] = 0;
484 slot.pattern[5] = IDENTITY_BUFFER_HEADER;
485
486 type GetKeyPath = unsafe extern "C" fn(*const c_void, *const c_void) -> u64;
487 let f: GetKeyPath = core::mem::transmute(crate::resolve::get_key_path());
488 f(base as *const c_void, core::ptr::null())
489 }
490}
491
492
493const WRITABLE_BUFFER_HEADER: u32 = 0x8000_0010;
498const WRITABLE_COMPUTED_COMPONENT: u32 = 0x02c0_0000;
507
508#[repr(C, align(8))]
515pub struct WritableComputedSlot {
516 cache: u64,
517 pattern: [u32; 10],
518 _pad: [u32; 2],
519 root: [u8; 64],
520 value: [u8; 64],
521}
522
523impl WritableComputedSlot {
524 pub const fn new() -> Self {
526 WritableComputedSlot {
527 cache: 0,
528 pattern: [0; 10],
529 _pad: [0; 2],
530 root: [0; 64],
531 value: [0; 64],
532 }
533 }
534}
535
536impl Default for WritableComputedSlot {
537 fn default() -> Self {
538 Self::new()
539 }
540}
541
542pub unsafe fn build_writable_computed(
557 slot: &'static mut WritableComputedSlot,
558 root: &[u8],
559 value: &[u8],
560 getter: *const c_void,
561 setter: *const c_void,
562) -> u64 {
563 unsafe {
564 slot.root[..root.len()].copy_from_slice(root);
565 slot.value[..value.len()].copy_from_slice(value);
566
567 let base = slot.pattern.as_ptr() as *const u8;
568 let at = |i: usize| base.add(i * 4);
569 slot.pattern[0] = offset(&slot.cache as *const u64 as *const u8, at(0)) as u32;
570 slot.pattern[1] = 0;
571 slot.pattern[2] = (offset(slot.root.as_ptr(), at(2)) | 1) as u32;
572 slot.pattern[3] = (offset(slot.value.as_ptr(), at(3)) | 1) as u32;
573 slot.pattern[4] = 0;
574 slot.pattern[5] = WRITABLE_BUFFER_HEADER;
575 slot.pattern[6] = WRITABLE_COMPUTED_COMPONENT;
576 slot.pattern[7] = offset(getter as *const u8, at(7)) as u32;
580 slot.pattern[8] = offset(getter as *const u8, at(8)) as u32;
581 slot.pattern[9] = offset(setter as *const u8, at(9)) as u32;
582
583 type GetKeyPath = unsafe extern "C" fn(*const c_void, *const c_void) -> u64;
584 let f: GetKeyPath = core::mem::transmute(crate::resolve::get_key_path());
585 f(base as *const c_void, core::ptr::null())
586 }
587}
588
589macro_rules! value_thunks {
598 ($($i:literal, $get:ident, $set:ident, $gsym:literal, $ssym:literal,
599 $gtgt:ident, $stgt:ident;)*) => {
600 $(
601 crate::thunk::runtime_thunk! {
602 fn $get = $gsym via $gtgt {
604 prologue: ["mov x1, x0", "mov x0, x8", concat!("mov x2, #", $i)],
605 branch: "br", epilogue: [],
606 }
607 fn $set = $ssym via $stgt {
609 prologue: [concat!("mov x2, #", $i)],
610 branch: "br", epilogue: [],
611 }
612 }
613 )*
614
615 pub const VALUE_SLOTS: usize = [$($i),*].len();
629
630 pub fn value_thunks(
632 index: usize,
633 ) -> (*const c_void, *const c_void, *mut *const c_void, *mut *const c_void) {
634 match index {
635 $($i => (
636 $get as *const c_void,
637 $set as *const c_void,
638 &raw mut $gtgt,
639 &raw mut $stgt,
640 ),)*
641 _ => panic!(
642 "key path slot {index} is past the {} this crate has",
643 VALUE_SLOTS,
644 ),
645 }
646 }
647 };
648}
649
650value_thunks! {
651 0, fk0_get, fk0_set, "rswift_fk0_get", "rswift_fk0_set", RSWIFT_FK0_GET, RSWIFT_FK0_SET;
652 1, fk1_get, fk1_set, "rswift_fk1_get", "rswift_fk1_set", RSWIFT_FK1_GET, RSWIFT_FK1_SET;
653 2, fk2_get, fk2_set, "rswift_fk2_get", "rswift_fk2_set", RSWIFT_FK2_GET, RSWIFT_FK2_SET;
654 3, fk3_get, fk3_set, "rswift_fk3_get", "rswift_fk3_set", RSWIFT_FK3_GET, RSWIFT_FK3_SET;
655 4, fk4_get, fk4_set, "rswift_fk4_get", "rswift_fk4_set", RSWIFT_FK4_GET, RSWIFT_FK4_SET;
656 5, fk5_get, fk5_set, "rswift_fk5_get", "rswift_fk5_set", RSWIFT_FK5_GET, RSWIFT_FK5_SET;
657 6, fk6_get, fk6_set, "rswift_fk6_get", "rswift_fk6_set", RSWIFT_FK6_GET, RSWIFT_FK6_SET;
658 7, fk7_get, fk7_set, "rswift_fk7_get", "rswift_fk7_set", RSWIFT_FK7_GET, RSWIFT_FK7_SET;
659 8, fk8_get, fk8_set, "rswift_fk8_get", "rswift_fk8_set", RSWIFT_FK8_GET, RSWIFT_FK8_SET;
660 9, fk9_get, fk9_set, "rswift_fk9_get", "rswift_fk9_set", RSWIFT_FK9_GET, RSWIFT_FK9_SET;
661 10, fk10_get, fk10_set, "rswift_fk10_get", "rswift_fk10_set", RSWIFT_FK10_GET, RSWIFT_FK10_SET;
662 11, fk11_get, fk11_set, "rswift_fk11_get", "rswift_fk11_set", RSWIFT_FK11_GET, RSWIFT_FK11_SET;
663 12, fk12_get, fk12_set, "rswift_fk12_get", "rswift_fk12_set", RSWIFT_FK12_GET, RSWIFT_FK12_SET;
664 13, fk13_get, fk13_set, "rswift_fk13_get", "rswift_fk13_set", RSWIFT_FK13_GET, RSWIFT_FK13_SET;
665 14, fk14_get, fk14_set, "rswift_fk14_get", "rswift_fk14_set", RSWIFT_FK14_GET, RSWIFT_FK14_SET;
666 15, fk15_get, fk15_set, "rswift_fk15_get", "rswift_fk15_set", RSWIFT_FK15_GET, RSWIFT_FK15_SET;
667 16, fk16_get, fk16_set, "rswift_fk16_get", "rswift_fk16_set", RSWIFT_FK16_GET, RSWIFT_FK16_SET;
668 17, fk17_get, fk17_set, "rswift_fk17_get", "rswift_fk17_set", RSWIFT_FK17_GET, RSWIFT_FK17_SET;
669 18, fk18_get, fk18_set, "rswift_fk18_get", "rswift_fk18_set", RSWIFT_FK18_GET, RSWIFT_FK18_SET;
670 19, fk19_get, fk19_set, "rswift_fk19_get", "rswift_fk19_set", RSWIFT_FK19_GET, RSWIFT_FK19_SET;
671 20, fk20_get, fk20_set, "rswift_fk20_get", "rswift_fk20_set", RSWIFT_FK20_GET, RSWIFT_FK20_SET;
672 21, fk21_get, fk21_set, "rswift_fk21_get", "rswift_fk21_set", RSWIFT_FK21_GET, RSWIFT_FK21_SET;
673 22, fk22_get, fk22_set, "rswift_fk22_get", "rswift_fk22_set", RSWIFT_FK22_GET, RSWIFT_FK22_SET;
674 23, fk23_get, fk23_set, "rswift_fk23_get", "rswift_fk23_set", RSWIFT_FK23_GET, RSWIFT_FK23_SET;
675 24, fk24_get, fk24_set, "rswift_fk24_get", "rswift_fk24_set", RSWIFT_FK24_GET, RSWIFT_FK24_SET;
676 25, fk25_get, fk25_set, "rswift_fk25_get", "rswift_fk25_set", RSWIFT_FK25_GET, RSWIFT_FK25_SET;
677 26, fk26_get, fk26_set, "rswift_fk26_get", "rswift_fk26_set", RSWIFT_FK26_GET, RSWIFT_FK26_SET;
678 27, fk27_get, fk27_set, "rswift_fk27_get", "rswift_fk27_set", RSWIFT_FK27_GET, RSWIFT_FK27_SET;
679 28, fk28_get, fk28_set, "rswift_fk28_get", "rswift_fk28_set", RSWIFT_FK28_GET, RSWIFT_FK28_SET;
680 29, fk29_get, fk29_set, "rswift_fk29_get", "rswift_fk29_set", RSWIFT_FK29_GET, RSWIFT_FK29_SET;
681 30, fk30_get, fk30_set, "rswift_fk30_get", "rswift_fk30_set", RSWIFT_FK30_GET, RSWIFT_FK30_SET;
682 31, fk31_get, fk31_set, "rswift_fk31_get", "rswift_fk31_set", RSWIFT_FK31_GET, RSWIFT_FK31_SET;
683}
684
685static mut SLOTS: [WritableComputedSlot; VALUE_SLOTS] =
692 [const { WritableComputedSlot::new() }; VALUE_SLOTS];
693
694pub fn next_value_slot() -> usize {
696 use std::sync::atomic::{AtomicUsize, Ordering};
697 static NEXT: AtomicUsize = AtomicUsize::new(0);
698 let i = NEXT.fetch_add(1, Ordering::Relaxed);
699 assert!(
700 i < VALUE_SLOTS,
701 "this crate can synthesise {VALUE_SLOTS} key paths; the {}th was asked for",
702 i + 1,
703 );
704 i
705}
706
707pub unsafe fn value_slot(index: usize) -> &'static mut WritableComputedSlot {
712 unsafe { &mut SLOTS[index] }
713}