1use crate::convert::{FromWasmAbi, IntoWasmAbi, WasmAbi, WasmRet};
2use crate::describe::inform;
3use crate::JsValue;
4#[cfg(all(
5 all(target_family = "wasm", not(target_os = "wasi")),
6 feature = "std",
7 panic = "unwind"
8))]
9use core::any::Any;
10use core::borrow::{Borrow, BorrowMut};
11#[cfg(target_feature = "atomics")]
12use core::cell::UnsafeCell;
13use core::cell::{Cell, RefCell};
14use core::convert::Infallible;
15use core::marker::PhantomData;
16use core::ops::{Deref, DerefMut};
17use core::panic::{RefUnwindSafe, UnwindSafe};
18#[cfg(target_feature = "atomics")]
19use core::sync::atomic::{AtomicU8, Ordering};
20use wasm_bindgen_shared::tys::FUNCTION;
21
22use alloc::alloc::{alloc, dealloc, realloc, Layout};
23use alloc::rc::Rc;
24use once_cell::unsync::Lazy;
25
26pub extern crate alloc;
27pub extern crate core;
28#[cfg(feature = "std")]
29pub extern crate std;
30
31pub mod marker;
32
33pub use wasm_bindgen_macro::BindgenedStruct;
34
35pub fn js_panic(err: JsValue) {
37 #[cfg(all(feature = "std", not(target_feature = "atomics")))]
38 ::std::panic::panic_any(err);
39 #[cfg(not(all(feature = "std", not(target_feature = "atomics"))))]
40 ::core::panic!("{err:?}");
41}
42
43pub fn wbg_cast<From: IntoWasmAbi, To: FromWasmAbi>(value: From) -> To {
49 #[inline(never)]
88 #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
89 unsafe extern "C" fn breaks_if_inlined<From: IntoWasmAbi, To: FromWasmAbi>(
90 prim1: <From::Abi as WasmAbi>::Prim1,
91 prim2: <From::Abi as WasmAbi>::Prim2,
92 prim3: <From::Abi as WasmAbi>::Prim3,
93 prim4: <From::Abi as WasmAbi>::Prim4,
94 ) -> WasmRet<To::Abi> {
95 inform(FUNCTION);
96 inform(0);
97 inform(1);
98 From::describe();
99 To::describe();
100 To::describe();
101 core::ptr::read(super::__wbindgen_describe_cast(
104 breaks_if_inlined::<From, To> as _,
105 &(prim1, prim2, prim3, prim4) as *const _ as _,
106 ) as _)
107 }
108
109 let (prim1, prim2, prim3, prim4) = value.into_abi().split();
110
111 unsafe { To::from_abi(breaks_if_inlined::<From, To>(prim1, prim2, prim3, prim4).join()) }
112}
113
114pub(crate) const JSIDX_OFFSET: u32 = 1024; pub(crate) const JSIDX_UNDEFINED: u32 = JSIDX_OFFSET;
116pub(crate) const JSIDX_NULL: u32 = JSIDX_OFFSET + 1;
117pub(crate) const JSIDX_TRUE: u32 = JSIDX_OFFSET + 2;
118pub(crate) const JSIDX_FALSE: u32 = JSIDX_OFFSET + 3;
119pub(crate) const JSIDX_RESERVED: u32 = JSIDX_OFFSET + 4;
120
121pub(crate) struct ThreadLocalWrapper<T>(pub(crate) T);
122
123#[cfg(not(target_feature = "atomics"))]
124unsafe impl<T> Sync for ThreadLocalWrapper<T> {}
125
126#[cfg(not(target_feature = "atomics"))]
127unsafe impl<T> Send for ThreadLocalWrapper<T> {}
128
129pub struct LazyCell<T, F = fn() -> T>(ThreadLocalWrapper<Lazy<T, F>>);
131
132impl<T, F> LazyCell<T, F> {
133 pub const fn new(init: F) -> LazyCell<T, F> {
134 Self(ThreadLocalWrapper(Lazy::new(init)))
135 }
136}
137
138impl<T, F: FnOnce() -> T> LazyCell<T, F> {
139 pub fn force(this: &Self) -> &T {
140 &this.0 .0
141 }
142}
143
144impl<T> Deref for LazyCell<T> {
145 type Target = T;
146
147 fn deref(&self) -> &T {
148 ::once_cell::unsync::Lazy::force(&self.0 .0)
149 }
150}
151
152#[cfg(not(target_feature = "atomics"))]
153pub use LazyCell as LazyLock;
154
155#[cfg(target_feature = "atomics")]
156pub struct LazyLock<T, F = fn() -> T> {
157 state: AtomicU8,
158 data: UnsafeCell<Data<T, F>>,
159}
160
161#[cfg(target_feature = "atomics")]
162enum Data<T, F> {
163 Value(T),
164 Init(F),
165}
166
167#[cfg(target_feature = "atomics")]
168impl<T, F> LazyLock<T, F> {
169 const STATE_UNINIT: u8 = 0;
170 const STATE_INITIALIZING: u8 = 1;
171 const STATE_INIT: u8 = 2;
172
173 pub const fn new(init: F) -> LazyLock<T, F> {
174 Self {
175 state: AtomicU8::new(Self::STATE_UNINIT),
176 data: UnsafeCell::new(Data::Init(init)),
177 }
178 }
179}
180
181#[cfg(target_feature = "atomics")]
182impl<T> Deref for LazyLock<T> {
183 type Target = T;
184
185 fn deref(&self) -> &T {
186 let mut state = self.state.load(Ordering::Acquire);
187
188 loop {
189 match state {
190 Self::STATE_INIT => {
191 let Data::Value(value) = (unsafe { &*self.data.get() }) else {
192 unreachable!()
193 };
194 return value;
195 }
196 Self::STATE_UNINIT => {
197 if let Err(new_state) = self.state.compare_exchange_weak(
198 Self::STATE_UNINIT,
199 Self::STATE_INITIALIZING,
200 Ordering::Acquire,
201 Ordering::Relaxed,
202 ) {
203 state = new_state;
204 continue;
205 }
206
207 let data = unsafe { &mut *self.data.get() };
208 let Data::Init(init) = data else {
209 unreachable!()
210 };
211 *data = Data::Value(init());
212 self.state.store(Self::STATE_INIT, Ordering::Release);
213 state = Self::STATE_INIT;
214 }
215 Self::STATE_INITIALIZING => {
216 state = self.state.load(Ordering::Acquire);
219 }
220 _ => unreachable!(),
221 }
222 }
223 }
224}
225
226#[cfg(target_feature = "atomics")]
227unsafe impl<T, F: Sync> Sync for LazyLock<T, F> {}
228
229#[cfg(target_feature = "atomics")]
230unsafe impl<T, F: Send> Send for LazyLock<T, F> {}
231
232#[macro_export]
233#[doc(hidden)]
234#[cfg(not(target_feature = "atomics"))]
235macro_rules! __wbindgen_thread_local {
236 ($wasm_bindgen:tt, $actual_ty:ty) => {{
237 static _VAL: $wasm_bindgen::__rt::LazyCell<$actual_ty> =
238 $wasm_bindgen::__rt::LazyCell::new(init);
239 $wasm_bindgen::JsThreadLocal { __inner: &_VAL }
240 }};
241}
242
243#[macro_export]
244#[doc(hidden)]
245#[cfg(target_feature = "atomics")]
246#[allow_internal_unstable(thread_local)]
247macro_rules! __wbindgen_thread_local {
248 ($wasm_bindgen:tt, $actual_ty:ty) => {{
249 #[thread_local]
250 static _VAL: $wasm_bindgen::__rt::LazyCell<$actual_ty> =
251 $wasm_bindgen::__rt::LazyCell::new(init);
252 $wasm_bindgen::JsThreadLocal {
253 __inner: || unsafe { $wasm_bindgen::__rt::LazyCell::force(&_VAL) as *const $actual_ty },
254 }
255 }};
256}
257
258#[macro_export]
259#[doc(hidden)]
260#[cfg(not(wasm_bindgen_unstable_test_coverage))]
261macro_rules! __wbindgen_coverage {
262 ($item:item) => {
263 $item
264 };
265}
266
267#[macro_export]
268#[doc(hidden)]
269#[cfg(wasm_bindgen_unstable_test_coverage)]
270#[allow_internal_unstable(coverage_attribute)]
271macro_rules! __wbindgen_coverage {
272 ($item:item) => {
273 #[coverage(off)]
274 $item
275 };
276}
277
278#[inline]
279pub fn assert_not_null<T>(s: *mut T) {
280 if s.is_null() {
281 throw_null();
282 }
283}
284
285#[cfg(target_arch = "wasm64")]
286pub type WasmWordRepr = f64;
287#[cfg(not(target_arch = "wasm64"))]
288pub type WasmWordRepr = u32;
289
290#[cfg(target_arch = "wasm64")]
293pub type WasmSignedWordRepr = f64;
294#[cfg(not(target_arch = "wasm64"))]
295pub type WasmSignedWordRepr = i32;
296
297#[repr(transparent)]
299#[derive(Copy, Clone, Default)]
300pub struct WasmWord(WasmWordRepr);
301
302impl WasmWord {
303 #[inline]
304 pub fn from_usize(value: usize) -> Self {
305 #[cfg(target_arch = "wasm64")]
306 {
307 Self(value as f64)
308 }
309 #[cfg(not(target_arch = "wasm64"))]
310 {
311 Self(value as u32)
312 }
313 }
314
315 #[inline]
316 pub fn into_usize(self) -> usize {
317 self.0 as usize
318 }
319
320 #[inline]
321 pub fn from_isize(value: isize) -> Self {
322 #[cfg(target_arch = "wasm64")]
323 {
324 Self(value as f64)
325 }
326 #[cfg(not(target_arch = "wasm64"))]
327 {
328 Self(value as u32)
329 }
330 }
331
332 #[inline]
333 pub fn into_isize(self) -> isize {
334 self.0 as isize
335 }
336
337 #[inline]
338 pub fn is_zero(&self) -> bool {
339 #[cfg(target_arch = "wasm64")]
340 {
341 self.0 == 0.0
342 }
343 #[cfg(not(target_arch = "wasm64"))]
344 {
345 self.0 == 0
346 }
347 }
348}
349
350impl WasmAbi for WasmWord {
351 type Prim1 = WasmWordRepr;
352 type Prim2 = ();
353 type Prim3 = ();
354 type Prim4 = ();
355
356 #[inline]
357 fn split(self) -> (Self::Prim1, (), (), ()) {
358 (self.0, (), (), ())
359 }
360
361 #[inline]
362 fn join(prim1: Self::Prim1, _: (), _: (), _: ()) -> Self {
363 Self(prim1)
364 }
365}
366
367#[repr(transparent)]
369#[derive(Copy, Clone)]
370pub struct WasmPtr<T> {
371 word: WasmWord,
372 _marker: PhantomData<*mut T>,
373}
374
375impl<T> Default for WasmPtr<T> {
376 #[inline]
377 fn default() -> Self {
378 Self::null()
379 }
380}
381
382impl<T> WasmPtr<T> {
383 #[inline]
384 pub fn from_ptr(ptr: *mut T) -> Self {
385 Self::from_usize(ptr as usize)
386 }
387
388 #[inline]
389 pub fn into_ptr(self) -> *mut T {
390 self.into_usize() as *mut T
391 }
392
393 #[inline]
394 pub fn from_usize(value: usize) -> Self {
395 Self {
396 word: WasmWord::from_usize(value),
397 _marker: PhantomData,
398 }
399 }
400
401 #[inline]
402 pub fn into_usize(self) -> usize {
403 self.word.into_usize()
404 }
405
406 #[inline]
407 pub fn null() -> Self {
408 Self::from_usize(0)
409 }
410
411 #[inline]
412 pub fn is_null(&self) -> bool {
413 self.word.is_zero()
414 }
415}
416
417impl<T> WasmAbi for WasmPtr<T> {
418 type Prim1 = <WasmWord as WasmAbi>::Prim1;
419 type Prim2 = ();
420 type Prim3 = ();
421 type Prim4 = ();
422
423 #[inline]
424 fn split(self) -> (Self::Prim1, (), (), ()) {
425 self.word.split()
426 }
427
428 #[inline]
429 fn join(prim1: Self::Prim1, _: (), _: (), _: ()) -> Self {
430 Self {
431 word: WasmWord::join(prim1, (), (), ()),
432 _marker: PhantomData,
433 }
434 }
435}
436
437#[cfg(all(test, target_arch = "wasm64"))]
441mod tests {
442 use super::WasmWord;
443
444 #[test]
445 fn wasm_word_roundtrips_large_pointer_values() {
446 let value = 1usize << 60;
447 assert_eq!(WasmWord::from_usize(value).into_usize(), value);
448
449 let signed = -(1isize << 40);
450 assert_eq!(WasmWord::from_isize(signed).into_isize(), signed);
451 }
452}
453
454#[cold]
455#[inline(never)]
456fn throw_null() -> ! {
457 super::throw_str("null pointer passed to rust");
458}
459
460pub struct WasmRefCell<T: ?Sized> {
478 inner: RefCell<T>,
479}
480
481impl<T: ?Sized> UnwindSafe for WasmRefCell<T> {}
482impl<T: ?Sized> RefUnwindSafe for WasmRefCell<T> {}
483
484impl<T: ?Sized> WasmRefCell<T> {
485 pub fn new(value: T) -> WasmRefCell<T>
486 where
487 T: Sized,
488 {
489 WasmRefCell {
490 inner: RefCell::new(value),
491 }
492 }
493
494 pub fn get_mut(&mut self) -> &mut T {
495 self.inner.get_mut()
496 }
497
498 pub fn borrow(&self) -> Ref<'_, T> {
499 match self.inner.try_borrow() {
500 Ok(inner) => Ref { inner },
501 Err(_) => borrow_fail(),
502 }
503 }
504
505 pub fn borrow_mut(&self) -> RefMut<'_, T> {
506 match self.inner.try_borrow_mut() {
507 Ok(inner) => RefMut { inner },
508 Err(_) => borrow_fail(),
509 }
510 }
511
512 pub fn into_inner(self) -> T
513 where
514 T: Sized,
515 {
516 self.inner.into_inner()
517 }
518}
519
520pub struct Ref<'b, T: ?Sized + 'b> {
521 inner: core::cell::Ref<'b, T>,
522}
523
524impl<T: ?Sized> Deref for Ref<'_, T> {
525 type Target = T;
526
527 #[inline]
528 fn deref(&self) -> &T {
529 &self.inner
530 }
531}
532
533impl<T: ?Sized> Borrow<T> for Ref<'_, T> {
534 #[inline]
535 fn borrow(&self) -> &T {
536 self
537 }
538}
539
540pub struct RefMut<'b, T: ?Sized + 'b> {
541 inner: core::cell::RefMut<'b, T>,
542}
543
544impl<T: ?Sized> Deref for RefMut<'_, T> {
545 type Target = T;
546
547 #[inline]
548 fn deref(&self) -> &T {
549 &self.inner
550 }
551}
552
553impl<T: ?Sized> DerefMut for RefMut<'_, T> {
554 #[inline]
555 fn deref_mut(&mut self) -> &mut T {
556 &mut self.inner
557 }
558}
559
560impl<T: ?Sized> Borrow<T> for RefMut<'_, T> {
561 #[inline]
562 fn borrow(&self) -> &T {
563 self
564 }
565}
566
567impl<T: ?Sized> BorrowMut<T> for RefMut<'_, T> {
568 #[inline]
569 fn borrow_mut(&mut self) -> &mut T {
570 self
571 }
572}
573
574#[cfg(panic = "unwind")]
575fn borrow_fail() -> ! {
576 panic!(
577 "recursive use of an object detected which would lead to \
578 unsafe aliasing in rust",
579 )
580}
581
582#[cfg(not(panic = "unwind"))]
583fn borrow_fail() -> ! {
584 super::throw_str(
585 "recursive use of an object detected which would lead to \
586 unsafe aliasing in rust",
587 );
588}
589
590pub struct RcRef<T: ?Sized + 'static> {
596 ref_: Ref<'static, T>,
605 _rc: Rc<WasmRefCell<T>>,
606}
607
608impl<T: ?Sized> UnwindSafe for RcRef<T> {}
609
610impl<T: ?Sized> RcRef<T> {
611 pub fn new(rc: Rc<WasmRefCell<T>>) -> Self {
612 let ref_ = unsafe { (*Rc::as_ptr(&rc)).borrow() };
613 Self { _rc: rc, ref_ }
614 }
615}
616
617impl<T: ?Sized> Deref for RcRef<T> {
618 type Target = T;
619
620 #[inline]
621 fn deref(&self) -> &T {
622 &self.ref_
623 }
624}
625
626impl<T: ?Sized> Borrow<T> for RcRef<T> {
627 #[inline]
628 fn borrow(&self) -> &T {
629 &self.ref_
630 }
631}
632
633pub struct RcRefMut<T: ?Sized + 'static> {
639 ref_: RefMut<'static, T>,
640 _rc: Rc<WasmRefCell<T>>,
641}
642
643impl<T: ?Sized> RcRefMut<T> {
644 pub fn new(rc: Rc<WasmRefCell<T>>) -> Self {
645 let ref_ = unsafe { (*Rc::as_ptr(&rc)).borrow_mut() };
646 Self { _rc: rc, ref_ }
647 }
648}
649
650impl<T: ?Sized> Deref for RcRefMut<T> {
651 type Target = T;
652
653 #[inline]
654 fn deref(&self) -> &T {
655 &self.ref_
656 }
657}
658
659impl<T: ?Sized> DerefMut for RcRefMut<T> {
660 #[inline]
661 fn deref_mut(&mut self) -> &mut T {
662 &mut self.ref_
663 }
664}
665
666impl<T: ?Sized> Borrow<T> for RcRefMut<T> {
667 #[inline]
668 fn borrow(&self) -> &T {
669 &self.ref_
670 }
671}
672
673impl<T: ?Sized> BorrowMut<T> for RcRefMut<T> {
674 #[inline]
675 fn borrow_mut(&mut self) -> &mut T {
676 &mut self.ref_
677 }
678}
679
680#[no_mangle]
681pub extern "C" fn __wbindgen_malloc(size: WasmWord, align: WasmWord) -> WasmPtr<u8> {
682 let size = size.into_usize();
683 let align = align.into_usize();
684 if let Ok(layout) = Layout::from_size_align(size, align) {
685 unsafe {
686 if layout.size() > 0 {
687 let ptr = alloc(layout);
688 if !ptr.is_null() {
689 return WasmPtr::from_ptr(ptr);
690 }
691 } else {
692 return WasmPtr::from_usize(align);
693 }
694 }
695 }
696
697 malloc_failure();
698}
699
700#[no_mangle]
701pub unsafe extern "C" fn __wbindgen_realloc(
702 ptr: WasmPtr<u8>,
703 old_size: WasmWord,
704 new_size: WasmWord,
705 align: WasmWord,
706) -> WasmPtr<u8> {
707 let ptr = ptr.into_ptr();
708 let old_size = old_size.into_usize();
709 let new_size = new_size.into_usize();
710 let align = align.into_usize();
711 debug_assert!(old_size > 0);
712 debug_assert!(new_size > 0);
713 if let Ok(layout) = Layout::from_size_align(old_size, align) {
714 let ptr = realloc(ptr, layout, new_size);
715 if !ptr.is_null() {
716 return WasmPtr::from_ptr(ptr);
717 }
718 }
719 malloc_failure();
720}
721
722#[cold]
723fn malloc_failure() -> ! {
724 cfg_if::cfg_if! {
725 if #[cfg(debug_assertions)] {
726 super::throw_str("invalid malloc request")
727 } else if #[cfg(feature = "std")] {
728 std::process::abort();
729 } else if #[cfg(target_arch = "wasm32")] {
730 core::arch::wasm32::unreachable();
732 } else if #[cfg(target_arch = "wasm64")] {
733 core::arch::wasm64::unreachable();
735 } else {
736 unreachable!()
737 }
738 }
739}
740
741#[no_mangle]
742pub unsafe extern "C" fn __wbindgen_free(ptr: WasmPtr<u8>, size: WasmWord, align: WasmWord) {
743 let size = size.into_usize();
744 if size == 0 {
747 return;
748 }
749 let ptr = ptr.into_ptr();
750 let align = align.into_usize();
751 let layout = Layout::from_size_align_unchecked(size, align);
752 dealloc(ptr, layout);
753}
754
755#[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
789pub fn link_mem_intrinsics() {
790 crate::link::link_intrinsics();
791}
792
793#[cfg_attr(target_feature = "atomics", thread_local)]
794static GLOBAL_EXNDATA: ThreadLocalWrapper<Cell<[u32; 2]>> = ThreadLocalWrapper(Cell::new([0; 2]));
795
796#[no_mangle]
797pub static mut __instance_terminated: u32 = 0;
798
799fn no_op() {}
800
801pub static NO_OP_PTR: fn() = no_op;
802
803#[no_mangle]
806pub static mut __abort_handler: fn() = NO_OP_PTR;
807
808pub fn set_on_abort(f: fn()) -> Option<fn()> {
823 let prev = unsafe { __abort_handler };
824 unsafe {
825 __abort_handler = f;
826 }
827
828 if (prev as usize) != (NO_OP_PTR as usize) {
830 Some(prev)
831 } else {
832 None
833 }
834}
835
836pub fn schedule_reinit() {
841 crate::__wbindgen_reinit();
842}
843
844#[no_mangle]
845pub unsafe extern "C" fn __wbindgen_exn_store(idx: u32) {
846 debug_assert_eq!(GLOBAL_EXNDATA.0.get()[0], 0);
847 GLOBAL_EXNDATA.0.set([1, idx]);
848}
849
850pub fn take_last_exception() -> Result<(), super::JsValue> {
851 let ret = if GLOBAL_EXNDATA.0.get()[0] == 1 {
852 Err(super::JsValue::_new(GLOBAL_EXNDATA.0.get()[1]))
853 } else {
854 Ok(())
855 };
856 GLOBAL_EXNDATA.0.set([0, 0]);
857 ret
858}
859
860pub trait IntoJsResult {
865 fn into_js_result(self) -> Result<JsValue, JsValue>;
866}
867
868impl IntoJsResult for () {
869 fn into_js_result(self) -> Result<JsValue, JsValue> {
870 Ok(JsValue::undefined())
871 }
872}
873
874impl<T: Into<JsValue>> IntoJsResult for T {
875 fn into_js_result(self) -> Result<JsValue, JsValue> {
876 Ok(self.into())
877 }
878}
879
880impl<T: Into<JsValue>, E: Into<JsValue>> IntoJsResult for Result<T, E> {
881 fn into_js_result(self) -> Result<JsValue, JsValue> {
882 match self {
883 Ok(e) => Ok(e.into()),
884 Err(e) => Err(e.into()),
885 }
886 }
887}
888
889impl<E: Into<JsValue>> IntoJsResult for Result<(), E> {
890 fn into_js_result(self) -> Result<JsValue, JsValue> {
891 match self {
892 Ok(()) => Ok(JsValue::undefined()),
893 Err(e) => Err(e.into()),
894 }
895 }
896}
897
898pub trait Start {
901 fn start(self);
902}
903
904impl Start for () {
905 #[inline]
906 fn start(self) {}
907}
908
909impl<E: Into<JsValue>> Start for Result<(), E> {
910 #[inline]
911 fn start(self) {
912 if let Err(e) = self {
913 crate::throw_val(e.into());
914 }
915 }
916}
917
918pub struct MainWrapper<T>(pub Option<T>);
921
922pub trait Main {
923 fn __wasm_bindgen_main(&mut self);
924}
925
926impl Main for &mut &mut MainWrapper<()> {
927 #[inline]
928 fn __wasm_bindgen_main(&mut self) {}
929}
930
931impl Main for &mut &mut MainWrapper<Infallible> {
932 #[inline]
933 fn __wasm_bindgen_main(&mut self) {}
934}
935
936impl<E: Into<JsValue>> Main for &mut &mut MainWrapper<Result<(), E>> {
937 #[inline]
938 fn __wasm_bindgen_main(&mut self) {
939 if let Err(e) = self.0.take().unwrap() {
940 crate::throw_val(e.into());
941 }
942 }
943}
944
945impl<E: core::fmt::Debug> Main for &mut MainWrapper<Result<(), E>> {
946 #[inline]
947 fn __wasm_bindgen_main(&mut self) {
948 if let Err(e) = self.0.take().unwrap() {
949 crate::throw_str(&alloc::format!("{e:?}"));
950 }
951 }
952}
953
954pub const fn flat_len<T, const SIZE: usize>(slices: [&[T]; SIZE]) -> usize {
955 let mut len = 0;
956 let mut i = 0;
957 while i < slices.len() {
958 len += slices[i].len();
959 i += 1;
960 }
961 len
962}
963
964pub const fn flat_byte_slices<const RESULT_LEN: usize, const SIZE: usize>(
965 slices: [&[u8]; SIZE],
966) -> [u8; RESULT_LEN] {
967 let mut result = [0; RESULT_LEN];
968
969 let mut slice_index = 0;
970 let mut result_offset = 0;
971
972 while slice_index < slices.len() {
973 let mut i = 0;
974 let slice = slices[slice_index];
975 while i < slice.len() {
976 result[result_offset] = slice[i];
977 i += 1;
978 result_offset += 1;
979 }
980 slice_index += 1;
981 }
982
983 result
984}
985
986pub const fn encode_u32_to_fixed_len_bytes(value: u32) -> [u8; 5] {
990 let mut result: [u8; 5] = [0; 5];
991 let mut i = 0;
992 while i < 4 {
993 result[i] = ((value >> (7 * i)) | 0x80) as u8;
994 i += 1;
995 }
996 result[4] = (value >> (7 * 4)) as u8;
997 result
998}
999
1000#[cfg(all(
1001 all(target_family = "wasm", not(target_os = "wasi")),
1002 feature = "std",
1003 panic = "unwind"
1004))]
1005#[wasm_bindgen_macro::wasm_bindgen(wasm_bindgen = crate, raw_module = "__wbindgen_placeholder__")]
1006extern "C" {
1007 fn __wbindgen_panic_error(msg: &JsValue) -> JsValue;
1008}
1009
1010#[cfg(all(
1011 all(target_family = "wasm", not(target_os = "wasi")),
1012 feature = "std",
1013 panic = "unwind"
1014))]
1015pub fn panic_to_panic_error(val: std::boxed::Box<dyn Any + Send>) -> JsValue {
1016 #[cfg(not(target_feature = "atomics"))]
1017 {
1018 if let Some(s) = val.downcast_ref::<JsValue>() {
1019 return __wbindgen_panic_error(&s);
1020 }
1021 }
1022 let maybe_panic_msg: Option<&str> = if let Some(s) = val.downcast_ref::<&str>() {
1023 Some(s)
1024 } else if let Some(s) = val.downcast_ref::<std::string::String>() {
1025 Some(s)
1026 } else {
1027 None
1028 };
1029 let err: JsValue = __wbindgen_panic_error(&JsValue::from_str(
1030 maybe_panic_msg.unwrap_or("No panic message available"),
1031 ));
1032 err
1033}
1034
1035#[cfg(all(
1036 all(target_family = "wasm", not(target_os = "wasi")),
1037 feature = "std",
1038 panic = "unwind"
1039))]
1040pub fn maybe_catch_unwind<F: FnOnce() -> R + std::panic::UnwindSafe, R>(f: F) -> R {
1041 let result = std::panic::catch_unwind(f);
1042 match result {
1043 Ok(val) => val,
1044 Err(e) => {
1045 crate::throw_val(panic_to_panic_error(e));
1046 }
1047 }
1048}
1049
1050#[cfg(not(all(
1051 all(target_family = "wasm", not(target_os = "wasi")),
1052 feature = "std",
1053 panic = "unwind"
1054)))]
1055pub fn maybe_catch_unwind<F: FnOnce() -> R, R>(f: F) -> R {
1056 f()
1057}
1058
1059#[cfg(all(
1079 all(target_family = "wasm", not(target_os = "wasi")),
1080 feature = "std",
1081 panic = "unwind"
1082))]
1083#[inline(always)]
1084pub fn ensure_ref_unwind_safe<T: ?Sized + std::panic::RefUnwindSafe>() {}
1085
1086#[cfg(not(all(
1087 all(target_family = "wasm", not(target_os = "wasi")),
1088 feature = "std",
1089 panic = "unwind"
1090)))]
1091#[inline(always)]
1092pub fn ensure_ref_unwind_safe<T: ?Sized>() {}
1093
1094#[cfg(all(
1103 all(target_family = "wasm", not(target_os = "wasi")),
1104 feature = "std",
1105 panic = "unwind"
1106))]
1107#[inline(always)]
1108pub fn ensure_unwind_safe<T: ?Sized + std::panic::UnwindSafe>() {}
1109
1110#[cfg(not(all(
1111 all(target_family = "wasm", not(target_os = "wasi")),
1112 feature = "std",
1113 panic = "unwind"
1114)))]
1115#[inline(always)]
1116pub fn ensure_unwind_safe<T: ?Sized>() {}