1use super::*;
20use crate::abi;
21use crate::mangle::{self, swift_type};
22use crate::resolve;
23use core::ffi::c_void;
24
25#[cfg(target_os = "macos")]
32unsafe fn container_meta(
33 ma: *const c_void,
34 content: &ViewHandle,
35) -> (*const c_void, *const c_void) {
36 unsafe {
37 let meta = abi::generic_metadata2(ma, content.meta, content.wt);
38 assert!(!meta.is_null(), "container metadata instantiation failed");
39 let wt = abi::get_view_wt(meta);
40 assert!(!wt.is_null(), "{} !: View", crate::diag::type_name(meta));
41 (meta, wt)
42 }
43}
44
45#[cfg(target_os = "macos")]
53unsafe fn one_child_container(
54 init: *const c_void,
55 ma: *const c_void,
56 content: &ViewHandle,
57) -> ViewHandle {
58 unsafe {
59 let (meta, wt) = container_meta(ma, content);
60 let child = content.clone();
63 let kid = Child::new(&child, Content::Concrete);
64 let handles = kid.element();
65 let payload = TuplePayload { children: handles.as_ptr(), count: 1 };
66 let mut ctx =
67 abi::ClosureCtx::new(emit_tuple, &payload as *const TuplePayload as *mut c_void);
68
69 let mut result = vec![0u8; abi::type_bytes(meta)];
70 core::arch::asm!("blr {f}", f = in(reg) init,
71 in("x0") abi::swift_closure_thunk as *const c_void,
72 in("x1") &mut ctx as *mut abi::ClosureCtx,
73 in("x2") content.meta,
74 in("x3") content.wt,
75 in("x8") result.as_mut_ptr(),
76 lateout("x4") _, lateout("x5") _, lateout("x6") _, lateout("x7") _,
77 lateout("x9") _, lateout("x10") _, lateout("x11") _, lateout("x12") _,
78 lateout("x13") _, lateout("x14") _, lateout("x15") _, lateout("x16") _,
79 lateout("x17") _, lateout("lr") _, lateout("x20") _, lateout("x21") _,
80 clobber_abi("C"),
81 );
82 wrap_owned(result, meta, wt)
83 }
84}
85
86#[cfg(target_os = "macos")]
91pub fn hsplit_view(content: &ViewHandle) -> ViewHandle {
92 unsafe {
93 one_child_container(resolve::hsplit_view_init(), resolve::hsplit_view_ma(), content)
94 }
95}
96
97#[cfg(target_os = "macos")]
99pub fn vsplit_view(content: &ViewHandle) -> ViewHandle {
100 unsafe {
101 one_child_container(resolve::vsplit_view_init(), resolve::vsplit_view_ma(), content)
102 }
103}
104
105unsafe fn no_argument_view(init: *const c_void, named: &str) -> ViewHandle {
111 unsafe {
112 let meta = abi::resolve_type_by_mangled_name(named.as_bytes());
113 assert!(!meta.is_null(), "{}", mangle::demangle(named));
114 let wt = abi::get_view_wt(meta);
115 assert!(!wt.is_null(), "{} !: View", crate::diag::type_name(meta));
116 let mut result = vec![0u8; abi::type_bytes(meta)];
117 core::arch::asm!("blr {f}", f = in(reg) init,
118 in("x8") result.as_mut_ptr(),
119 lateout("x0") _, lateout("x1") _, lateout("x2") _, lateout("x3") _,
120 lateout("x4") _, lateout("x5") _, lateout("x6") _, lateout("x7") _,
121 lateout("x9") _, lateout("x10") _, lateout("x11") _, lateout("x12") _,
122 lateout("x13") _, lateout("x14") _, lateout("x15") _, lateout("x16") _,
123 lateout("x17") _, lateout("lr") _, lateout("x20") _, lateout("x21") _,
124 clobber_abi("C"),
125 );
126 wrap_owned(result, meta, wt)
127 }
128}
129
130pub fn rename_button() -> ViewHandle {
136 unsafe {
137 let label = mangle::bound(
138 &swift_type!(SwiftUI.Label),
139 &[&swift_type!(SwiftUI.Text), &swift_type!(SwiftUI.Image)],
140 );
141 let named = mangle::bound(&swift_type!(SwiftUI.RenameButton), &[&label]);
142 no_argument_view(resolve::rename_button_init(), &named)
143 }
144}
145
146#[cfg(target_os = "macos")]
151pub fn settings_link() -> ViewHandle {
152 unsafe {
153 let named = mangle::bound(
154 &swift_type!(SwiftUI.SettingsLink),
155 &[&swift_type!(SwiftUI.DefaultSettingsLinkLabel)],
156 );
157 no_argument_view(resolve::settings_link_init(), &named)
158 }
159}
160
161pub fn content_unavailable(title: &str, system_image: &str, description: Option<&str>) -> ViewHandle {
169 unsafe {
170 let label = mangle::bound(
171 &swift_type!(SwiftUI.Label),
172 &[&swift_type!(SwiftUI.Text), &swift_type!(SwiftUI.Image)],
173 );
174 let named = mangle::bound(
175 &swift_type!(SwiftUI.ContentUnavailableView),
176 &[
177 &label,
178 &mangle::optional(&swift_type!(SwiftUI.Text)),
179 &swift_type!(SwiftUI.EmptyView),
180 ],
181 );
182 let meta = abi::resolve_type_by_mangled_name(named.as_bytes());
183 assert!(!meta.is_null(), "{}", mangle::demangle(&named));
184 let wt = abi::get_view_wt(meta);
185 assert!(!wt.is_null(), "{} !: View", crate::diag::type_name(meta));
186
187 let (k0, k1, k2, k3) = lsk_words(title);
188 let img = abi::swift_string(system_image);
189 let i0 = u64::from_le_bytes(img[..8].try_into().expect("image lo"));
190 let i1 = u64::from_le_bytes(img[8..].try_into().expect("image hi"));
191 let text = match description {
195 Some(s) => text_value(s),
196 None => [0u64; 4],
197 };
198
199 let mut result = vec![0u8; abi::type_bytes(meta)];
200 core::arch::asm!(
203 "sub sp, sp, #16",
204 "stp {t2}, {t3}, [sp]",
205 "blr {f}",
206 "add sp, sp, #16",
207 f = in(reg) resolve::content_unavailable_system_init(),
208 t2 = in(reg) text[2],
209 t3 = in(reg) text[3],
210 in("x0") k0, in("x1") k1, in("x2") k2, in("x3") k3,
211 in("x4") i0, in("x5") i1,
212 in("x6") text[0], in("x7") text[1],
213 in("x8") result.as_mut_ptr(),
214 lateout("x9") _, lateout("x10") _, lateout("x11") _, lateout("x12") _,
215 lateout("x13") _, lateout("x14") _, lateout("x15") _, lateout("x16") _,
216 lateout("x17") _, lateout("lr") _, lateout("x20") _, lateout("x21") _,
217 clobber_abi("C"),
218 );
219 wrap_owned(result, meta, wt)
220 }
221}
222
223pub struct ScrollProxy {
246 bytes: Vec<u8>,
247 meta: *const c_void,
248}
249
250impl Clone for ScrollProxy {
251 fn clone(&self) -> Self {
252 unsafe {
253 let vwt = &*swift_runtime_sys::SwiftABI::get_value_witness_table(self.meta);
254 let mut bytes = vec![0u8; self.bytes.len()];
255 (vwt.initialize_with_copy)(
256 bytes.as_mut_ptr() as *mut c_void,
257 self.bytes.as_ptr() as *mut c_void,
258 self.meta,
259 );
260 Self { bytes, meta: self.meta }
261 }
262 }
263}
264
265impl Drop for ScrollProxy {
266 fn drop(&mut self) {
267 unsafe {
268 let vwt = &*swift_runtime_sys::SwiftABI::get_value_witness_table(self.meta);
269 if vwt.size > 0 {
270 (vwt.destroy)(self.bytes.as_mut_ptr() as *mut c_void, self.meta);
271 }
272 }
273 }
274}
275
276impl ScrollProxy {
277 unsafe fn copy_from(raw: *mut c_void) -> Self {
282 unsafe {
283 let meta = abi::metadata0(resolve::scroll_view_proxy_ma());
284 assert!(!meta.is_null(), "ScrollViewProxy metadata");
285 let vwt = &*swift_runtime_sys::SwiftABI::get_value_witness_table(meta);
286 let mut bytes = vec![0u8; abi::type_bytes(meta)];
287 (vwt.initialize_with_copy)(bytes.as_mut_ptr() as *mut c_void, raw, meta);
288 Self { bytes, meta }
289 }
290 }
291
292 pub fn scroll_to(&self, id: i64) {
298 unsafe { self.scroll(id, None) }
299 }
300
301 pub fn scroll_to_anchor(&self, id: i64, anchor: (f64, f64)) {
303 unsafe { self.scroll(id, Some(anchor)) }
304 }
305
306 unsafe fn scroll(&self, id: i64, anchor: Option<(f64, f64)>) {
309 unsafe {
310 let mut value = id;
311 let (x, y, tag) = match anchor {
316 Some((x, y)) => (x.to_bits(), y.to_bits(), 0u64),
317 None => (0, 0, 1),
318 };
319 core::arch::asm!("blr {f}", f = in(reg) resolve::scroll_to_fn(),
320 in("x0") &mut value as *mut i64,
321 in("x1") x, in("x2") y, in("x3") tag,
322 in("x4") resolve::int_meta(),
323 in("x5") resolve::int_hashable_wt(),
324 in("x20") self.bytes.as_ptr(),
325 lateout("x6") _, lateout("x7") _, lateout("x8") _,
326 lateout("x9") _, lateout("x10") _, lateout("x11") _, lateout("x12") _,
327 lateout("x13") _, lateout("x14") _, lateout("x15") _, lateout("x16") _,
328 lateout("x17") _, lateout("lr") _, lateout("x21") _, clobber_abi("C"),
329 );
330 }
331 }
332}
333
334struct ProxyPayload {
336 builder: Box<dyn Fn(ScrollProxy) -> ViewHandle>,
337}
338
339unsafe extern "C" fn emit_with_proxy(out: *mut u8, proxy: i64, payload: *mut c_void) {
345 let p = unsafe { &*(payload as *const ProxyPayload) };
346 let view = (p.builder)(unsafe { ScrollProxy::copy_from(proxy as *mut c_void) });
347 unsafe { *(out as *mut u64) = view.into_anyview_word() };
348}
349
350pub fn scroll_view_reader(
358 content: impl Fn(ScrollProxy) -> ViewHandle + 'static,
359) -> ViewHandle {
360 unsafe {
361 let meta = abi::generic_metadata2(
362 resolve::scroll_view_reader_ma(),
363 resolve::anyview_meta(),
364 resolve::anyview_wt(),
365 );
366 assert!(!meta.is_null(), "ScrollViewReader metadata");
367 let wt = abi::get_view_wt(meta);
368 assert!(!wt.is_null(), "{} !: View", crate::diag::type_name(meta));
369
370 let payload = Box::leak(Box::new(ProxyPayload { builder: Box::new(content) }))
371 as *mut ProxyPayload as *mut c_void;
372 let ctx = Box::leak(Box::new(abi::IndexClosureCtx::new(emit_with_proxy, payload)))
373 as *mut abi::IndexClosureCtx;
374
375 let stride = abi::type_bytes(meta);
380 assert_eq!(stride, 16, "ScrollViewReader is no longer two words");
381 let (w0, w1): (u64, u64);
382 core::arch::asm!("blr {f}", f = in(reg) resolve::scroll_view_reader_init(),
383 in("x0") abi::index_closure_thunk as *const c_void,
384 in("x1") ctx,
385 in("x2") resolve::anyview_meta(),
386 in("x3") resolve::anyview_wt(),
387 lateout("x0") w0, lateout("x1") w1,
388 lateout("x2") _, lateout("x3") _, lateout("x4") _, lateout("x5") _,
389 lateout("x6") _, lateout("x7") _, lateout("x8") _,
390 lateout("x9") _, lateout("x10") _, lateout("x11") _, lateout("x12") _,
391 lateout("x13") _, lateout("x14") _, lateout("x15") _, lateout("x16") _,
392 lateout("x17") _, lateout("lr") _, lateout("x20") _, lateout("x21") _,
393 clobber_abi("C"),
394 );
395 let mut result = vec![0u8; stride];
396 result[..8].copy_from_slice(&w0.to_le_bytes());
397 result[8..16].copy_from_slice(&w1.to_le_bytes());
398 wrap_owned(result, meta, wt)
399 }
400}
401
402pub fn paste_button(
410 kinds: &[ContentType],
411 paste: impl Fn(&[ItemProvider]) + 'static,
412) -> ViewHandle {
413 unsafe {
414 let meta = abi::metadata0(resolve::paste_button_ma());
415 assert!(!meta.is_null(), "PasteButton metadata");
416 let wt = abi::get_view_wt(meta);
417 assert!(!wt.is_null(), "{} !: View", crate::diag::type_name(meta));
418
419 let types = content_types(kinds);
420 let c = wide_words(observe_providers, provider_payload(0, None, Some(Box::new(paste))));
421 let mut result = vec![0u8; abi::type_bytes(meta)];
422 core::arch::asm!("blr {f}", f = in(reg) resolve::paste_button_init(),
423 in("x0") types,
424 in("x1") c[0],
425 in("x2") c[1],
426 in("x8") result.as_mut_ptr(),
427 lateout("x3") _, lateout("x4") _, lateout("x5") _, lateout("x6") _,
428 lateout("x7") _,
429 lateout("x9") _, lateout("x10") _, lateout("x11") _, lateout("x12") _,
430 lateout("x13") _, lateout("x14") _, lateout("x15") _, lateout("x16") _,
431 lateout("x17") _, lateout("lr") _, lateout("x20") _, lateout("x21") _,
432 clobber_abi("C"),
433 );
434 wrap_owned(result, meta, wt)
435 }
436}
437
438pub fn on_insert(
450 content: &ViewHandle,
451 kinds: &[ContentType],
452 action: impl Fn(i64, &[ItemProvider]) + 'static,
453) -> ViewHandle {
454 unsafe {
455 let dvc = abi::get_view_wt_for_proto(content.meta, resolve::dynamic_view_content_proto());
456 assert!(
457 !dvc.is_null(),
458 "{} !: DynamicViewContent — `on_insert` needs a ForEach, not any view",
459 crate::diag::type_name(content.meta),
460 );
461
462 let types = content_types(kinds);
463 let c = pair_words(
464 insert_at_index,
465 Box::leak(Box::new(InsertPayload { action: Box::new(action) })) as *mut InsertPayload
466 as *mut c_void,
467 );
468
469 let (meta, _dvc_out, size) =
470 super::opaque_result_type(resolve::on_insert_oret(), &[content.meta, dvc]);
471 let wt = abi::get_view_wt(meta);
475 assert!(!wt.is_null(), "{} !: View", crate::diag::type_name(meta));
476
477 let mut result = vec![0u8; size];
478 let this = content.value_ptr();
479 core::arch::asm!("blr {f}", f = in(reg) resolve::on_insert_fn(),
482 in("x0") types,
483 in("x1") c[0],
484 in("x2") c[1],
485 in("x3") content.meta,
486 in("x4") dvc,
487 in("x8") result.as_mut_ptr(),
488 in("x20") this,
489 lateout("x5") _, lateout("x6") _, lateout("x7") _,
490 lateout("x9") _, lateout("x10") _, lateout("x11") _, lateout("x12") _,
491 lateout("x13") _, lateout("x14") _, lateout("x15") _, lateout("x16") _,
492 lateout("x17") _, lateout("lr") _, lateout("x21") _, clobber_abi("C"),
493 );
494 wrap_owned(result, meta, wt)
495 }
496}
497
498type InsertAction = Box<dyn Fn(i64, &[ItemProvider])>;
500
501struct InsertPayload {
503 action: InsertAction,
504}
505
506unsafe extern "C" fn insert_at_index(index: *const u8, providers: *const u8, payload: *mut c_void) {
513 let p = unsafe { &*(payload as *const InsertPayload) };
514 let items = unsafe { read_provider_array(providers as u64) };
515 (p.action)(index as i64, &items);
516}
517
518pub fn subscription_view(
534 content: &ViewHandle,
535 complete_immediately: bool,
536 action: impl Fn(i64) + 'static,
537) -> ViewHandle {
538 unsafe {
539 let empty = mangle::bound("7Combine5EmptyV", &[mangle::INT, mangle::NEVER]);
540 let publisher = abi::resolve_type_by_mangled_name(empty.as_bytes());
541 assert!(!publisher.is_null(), "{}", mangle::demangle(&empty));
542 let pub_wt = abi::get_view_wt_for_proto(publisher, resolve::publisher_proto());
543 assert!(!pub_wt.is_null(), "Empty<Int, Never> !: Combine.Publisher");
544
545 let named = mangle::bound(
546 &swift_type!(SwiftUI.SubscriptionView),
547 &[&empty, &swift_type!(SwiftUI.AnyView)],
548 );
549 let meta = abi::resolve_type_by_mangled_name(named.as_bytes());
550 assert!(!meta.is_null(), "{}", mangle::demangle(&named));
551 let wt = abi::get_view_wt(meta);
552 assert!(!wt.is_null(), "{} !: View", crate::diag::type_name(meta));
553
554 let mut value = vec![u8::from(complete_immediately); abi::type_bytes(publisher).max(1)];
555 let mut erased_word = content.to_anyview_word().to_le_bytes();
558
559 let ctx = Box::leak(Box::new(abi::ValueClosureCtx::new(
560 super::saw_published_int,
561 super::boxed_ctx(Box::new(action) as Box<dyn Fn(i64)>),
562 ))) as *mut abi::ValueClosureCtx;
563
564 let mut result = vec![0u8; abi::type_bytes(meta)];
565 core::arch::asm!("blr {f}", f = in(reg) resolve::subscription_view_init(),
569 in("x0") erased_word.as_mut_ptr(),
570 in("x1") value.as_mut_ptr(),
571 in("x2") abi::value_closure_thunk as *const c_void,
572 in("x3") ctx,
573 in("x4") publisher,
574 in("x5") resolve::anyview_meta(),
575 in("x6") pub_wt,
576 in("x7") resolve::anyview_wt(),
577 in("x8") result.as_mut_ptr(),
578 lateout("x9") _, lateout("x10") _, lateout("x11") _, lateout("x12") _,
579 lateout("x13") _, lateout("x14") _, lateout("x15") _, lateout("x16") _,
580 lateout("x17") _, lateout("lr") _, lateout("x20") _, lateout("x21") _,
581 clobber_abi("C"),
582 );
583 wrap_owned(result, meta, wt)
584 }
585}
586
587#[derive(Clone, Copy, Debug, PartialEq, Eq)]
601pub enum AppleButtonLabel {
602 SignIn,
604 SignUp,
606 Continue,
608}
609
610impl AppleButtonLabel {
611 fn getter(self) -> &'static core::ffi::CStr {
612 match self {
613 Self::SignIn => c"$s31_AuthenticationServices_SwiftUI21SignInWithAppleButtonV5LabelV04signF0AEvgZ",
614 Self::SignUp => c"$s31_AuthenticationServices_SwiftUI21SignInWithAppleButtonV5LabelV6signUpAEvgZ",
615 Self::Continue => c"$s31_AuthenticationServices_SwiftUI21SignInWithAppleButtonV5LabelV8continueAEvgZ",
616 }
617 }
618}
619
620#[derive(Clone, Copy, Debug, PartialEq, Eq)]
622pub enum AppleButtonStyle {
623 Black,
625 White,
627 WhiteOutline,
629}
630
631impl AppleButtonStyle {
632 fn getter(self) -> &'static core::ffi::CStr {
633 match self {
634 Self::Black => c"$s31_AuthenticationServices_SwiftUI21SignInWithAppleButtonV5StyleV5blackAEvgZ",
635 Self::White => c"$s31_AuthenticationServices_SwiftUI21SignInWithAppleButtonV5StyleV5whiteAEvgZ",
636 Self::WhiteOutline => c"$s31_AuthenticationServices_SwiftUI21SignInWithAppleButtonV5StyleV12whiteOutlineAEvgZ",
637 }
638 }
639}
640
641pub struct AppleIDRequest<'a> {
647 raw: *mut c_void,
648 marker: core::marker::PhantomData<&'a ()>,
649}
650
651impl AppleIDRequest<'_> {
652 pub fn request_full_name_and_email(&self) {
658 unsafe {
659 let full_name = crate::objc::nsstring("fullName");
660 let email = crate::objc::nsstring("email");
661 let items = [full_name, email];
662 let array_cls = crate::objc::class(c"OBJC_CLASS_$_NSArray");
663 assert!(!array_cls.is_null(), "NSArray class");
664 type WithObjects =
665 unsafe extern "C" fn(*mut c_void, *const c_void, *const *mut c_void, u64) -> *mut c_void;
666 let f: WithObjects =
667 core::mem::transmute(crate::objc::msg_send_addr());
668 let array = f(
669 array_cls,
670 crate::objc::sel(c"arrayWithObjects:count:"),
671 items.as_ptr(),
672 2,
673 );
674 crate::objc::send_id(self.raw, crate::objc::sel(c"setRequestedScopes:"), array);
675 }
676 }
677
678 pub fn raw(&self) -> *mut c_void {
683 self.raw
684 }
685}
686
687struct ApplePayload {
689 on_request: Box<dyn Fn(AppleIDRequest<'_>)>,
690 on_completion: Box<dyn Fn(bool)>,
691 result_meta: *const c_void,
692}
693
694unsafe extern "C" fn apple_on_request(request: *const u8, payload: *mut c_void) {
702 let p = unsafe { &*(payload as *const ApplePayload) };
703 (p.on_request)(AppleIDRequest {
704 raw: request as *mut c_void,
705 marker: core::marker::PhantomData,
706 });
707}
708
709unsafe extern "C" fn apple_on_completion(result: *const u8, payload: *mut c_void) {
719 let p = unsafe { &*(payload as *const ApplePayload) };
720 let tag = unsafe { abi::enum_tag(result as *const c_void, p.result_meta) };
721 (p.on_completion)(tag == 0);
722}
723
724pub fn sign_in_with_apple_button(
729 label: AppleButtonLabel,
730 on_request: impl Fn(AppleIDRequest<'_>) + 'static,
731 on_completion: impl Fn(bool) + 'static,
732) -> ViewHandle {
733 unsafe {
734 let meta = abi::metadata0(resolve::siwa_button_ma());
735 assert!(!meta.is_null(), "SignInWithAppleButton metadata");
736 let wt = abi::get_view_wt(meta);
737 assert!(!wt.is_null(), "{} !: View", crate::diag::type_name(meta));
738
739 let label_meta = abi::metadata0(resolve::siwa_label_ma());
740 assert!(!label_meta.is_null(), "SignInWithAppleButton.Label metadata");
741 let getter = resolve::sym_in(resolve::AUTH_SWIFTUI, label.getter());
742 assert!(!getter.is_null(), "{:?}", label.getter());
743 let mut label_value = static_getter_indirect(getter, label_meta, 0);
744
745 let result_named = mangle::bound(
746 "s6ResultO",
747 &["So15ASAuthorizationC", "s5Error_p"],
748 );
749 let result_meta = abi::resolve_type_by_mangled_name(result_named.as_bytes());
750 assert!(!result_meta.is_null(), "{}", mangle::demangle(&result_named));
751
752 let payload = Box::leak(Box::new(ApplePayload {
755 on_request: Box::new(on_request),
756 on_completion: Box::new(on_completion),
757 result_meta,
758 })) as *mut ApplePayload as *mut c_void;
759 let req_ctx = Box::leak(Box::new(abi::ValueClosureCtx::new(apple_on_request, payload)))
760 as *mut abi::ValueClosureCtx;
761 let done_ctx =
762 Box::leak(Box::new(abi::ValueClosureCtx::new(apple_on_completion, payload)))
763 as *mut abi::ValueClosureCtx;
764
765 let mut result = vec![0u8; abi::type_bytes(meta)];
766 core::arch::asm!("blr {f}", f = in(reg) resolve::siwa_button_init(),
768 in("x0") label_value.as_mut_ptr(),
769 in("x1") abi::value_closure_thunk as *const c_void,
770 in("x2") req_ctx,
771 in("x3") abi::value_closure_thunk as *const c_void,
772 in("x4") done_ctx,
773 in("x8") result.as_mut_ptr(),
774 lateout("x5") _, lateout("x6") _, lateout("x7") _,
775 lateout("x9") _, lateout("x10") _, lateout("x11") _, lateout("x12") _,
776 lateout("x13") _, lateout("x14") _, lateout("x15") _, lateout("x16") _,
777 lateout("x17") _, lateout("lr") _, lateout("x20") _, lateout("x21") _,
778 clobber_abi("C"),
779 );
780 wrap_owned(result, meta, wt)
781 }
782}
783
784pub fn sign_in_with_apple_button_style(
790 view: &ViewHandle,
791 style: AppleButtonStyle,
792) -> ViewHandle {
793 unsafe {
794 let style_meta = abi::metadata0(resolve::siwa_style_ma());
795 assert!(!style_meta.is_null(), "SignInWithAppleButton.Style metadata");
796 let getter = resolve::sym_in(resolve::AUTH_SWIFTUI, style.getter());
797 assert!(!getter.is_null(), "{:?}", style.getter());
798 let mut value = static_getter_indirect(getter, style_meta, 0);
799
800 let (meta, wt, size) =
801 super::opaque_result_type(resolve::siwa_style_oret(), &[view.meta, view.wt]);
802 let mut result = vec![0u8; size];
803 let this = view.value_ptr();
804 core::arch::asm!("blr {f}", f = in(reg) resolve::siwa_style_fn(),
806 in("x0") value.as_mut_ptr(),
807 in("x1") view.meta,
808 in("x2") view.wt,
809 in("x8") result.as_mut_ptr(),
810 in("x20") this,
811 lateout("x3") _, lateout("x4") _, lateout("x5") _, lateout("x6") _,
812 lateout("x7") _,
813 lateout("x9") _, lateout("x10") _, lateout("x11") _, lateout("x12") _,
814 lateout("x13") _, lateout("x14") _, lateout("x15") _, lateout("x16") _,
815 lateout("x17") _, lateout("lr") _, lateout("x21") _, clobber_abi("C"),
816 );
817 wrap_owned(result, meta, wt)
818 }
819}