1#![no_std]
2#![allow(unused_unsafe)]
3#![allow(unused_imports)]
4extern crate alloc;
5
6pub mod common;
7
8#[cfg(not(all(target_os = "wasi", target_env = "p2")))]
9pub mod env;
10#[cfg(not(all(target_os = "wasi", target_env = "p2")))]
11use crate::env::*;
12
13#[cfg(all(target_os = "wasi", target_env = "p2"))]
14pub mod wasip2env;
15#[cfg(all(target_os = "wasi", target_env = "p2"))]
16use crate::wasip2env::*;
17
18use crate::common::Handle;
19use core::ffi::CStr;
20use alloc::string::String;
21use alloc::string::ToString;
22use alloc::boxed::Box;
23use alloc::vec::Vec;
24use alloc::format;
25
26#[repr(u32)]
27pub enum EmlitePredefHandles {
28 Null = 0,
29 Undefined,
30 False,
31 True,
32 GlobalThis,
33 Console,
34 Reserved,
35}
36
37#[macro_export]
39macro_rules! eval {
40 ($src: literal) => {{
41 $crate::Val::global("eval").invoke(&[$crate::Val::from($src)])
42 }};
43 ($src: literal $(, $arg:expr)* $(,)?) => {{
44 $crate::Val::global("eval").invoke(
45 &[$crate::Val::from(&format!($src, $( $arg ),*)) ]
46 )
47 }};
48}
49
50#[macro_export]
52macro_rules! argv {
53 ($($rest:expr),*) => {{
54 [$($crate::Val::from($rest)),*]
55 }};
56}
57
58pub fn init() {
59 unsafe {
60 emlite_init_handle_table();
61 }
62}
63
64#[derive(Debug)]
66pub struct Val {
67 inner: Handle,
68}
69
70impl Val {
71 pub const fn global_this() -> Val {
73 Val { inner: EmlitePredefHandles::GlobalThis as _ }
74 }
75
76 pub fn get<T: Into<Val>>(&self, prop: T) -> Val {
78 let h = unsafe { emlite_val_get(self.as_handle(), prop.into().as_handle()) };
79 Val::take_ownership(h)
80 }
81
82 pub fn global(name: &str) -> Val {
84 Val::global_this().get(name)
85 }
86
87 pub const fn null() -> Val {
89 Val { inner: EmlitePredefHandles::Null as _ }
90 }
91
92 pub const fn undefined() -> Val {
94 Val { inner: EmlitePredefHandles::Undefined as _ }
95 }
96
97 pub fn object() -> Val {
99 Val::take_ownership(unsafe { emlite_val_new_object() })
100 }
101
102 pub fn array() -> Val {
104 Val::take_ownership(unsafe { emlite_val_new_array() })
105 }
106
107 pub fn set<K: Into<Val>, V: Into<Val>>(&self, prop: K, val: V) {
109 unsafe {
110 emlite_val_set(
111 self.as_handle(),
112 prop.into().as_handle(),
113 val.into().as_handle(),
114 )
115 };
116 }
117
118 pub fn has<T: Into<Val>>(&self, prop: T) -> bool {
120 unsafe { emlite_val_has(self.as_handle(), prop.into().as_handle()) }
121 }
122
123 pub fn has_own_property(&self, prop: &str) -> bool {
125 #[cfg(all(target_os = "wasi", target_env = "p2"))]
126 unsafe { emlite_val_obj_has_own_prop(self.as_handle(), prop) }
127 #[cfg(not(all(target_os = "wasi", target_env = "p2")))]
128 unsafe { emlite_val_obj_has_own_prop(self.as_handle(), prop.as_ptr() as _, prop.len()) }
129 }
130
131 pub fn type_of(&self) -> String {
133 unsafe {
134 #[cfg(all(target_os = "wasi", target_env = "p2"))]
135 {
136 emlite_val_typeof(self.as_handle())
137 }
138 #[cfg(not(all(target_os = "wasi", target_env = "p2")))]
139 {
140 let ptr = emlite_val_typeof(self.as_handle());
141 if ptr.is_null() {
142 String::from("undefined")
143 } else {
144 String::from_utf8_lossy(CStr::from_ptr(ptr).to_bytes()).to_string()
145 }
146 }
147 }
148 }
149
150 pub fn at<T: Into<Val>>(&self, idx: T) -> Val {
152 Val::take_ownership(unsafe { emlite_val_get(self.as_handle(), idx.into().as_handle()) })
153 }
154
155 pub fn to_vec<V: FromVal>(&self) -> Vec<V> {
157 let len = self.get("length").as_::<usize>();
158 let mut v: Vec<V> = Vec::with_capacity(len);
159 for i in 0..len {
160 v.push(self.at::<i32>(i as _).as_::<V>());
161 }
162 v
163 }
164
165 pub fn call(&self, f: &str, args: &[Val]) -> Val {
167 unsafe {
168 let arr = Val::take_ownership(emlite_val_new_array());
169 for arg in args {
170 emlite_val_push(arr.as_handle(), arg.as_handle());
171 }
172 #[cfg(all(target_os = "wasi", target_env = "p2"))]
173 {
174 Val::take_ownership(emlite_val_obj_call(
175 self.as_handle(),
176 f,
177 arr.as_handle(),
178 ))
179 }
180 #[cfg(not(all(target_os = "wasi", target_env = "p2")))]
181 {
182 Val::take_ownership(emlite_val_obj_call(
183 self.as_handle(),
184 f.as_ptr() as _,
185 f.len(),
186 arr.as_handle(),
187 ))
188 }
189 }
190 }
191
192 pub fn new(&self, args: &[Val]) -> Val {
194 unsafe {
195 let arr = Val::take_ownership(emlite_val_new_array());
196 for arg in args {
197 emlite_val_push(arr.as_handle(), arg.as_handle());
198 }
199 Val::take_ownership(emlite_val_construct_new(self.as_handle(), arr.as_handle()))
200 }
201 }
202
203 pub fn invoke(&self, args: &[Val]) -> Val {
205 unsafe {
206 let arr = Val::take_ownership(emlite_val_new_array());
207 for arg in args {
208 emlite_val_push(arr.as_handle(), arg.as_handle());
209 }
210 Val::take_ownership(emlite_val_func_call(self.as_handle(), arr.as_handle()))
211 }
212 }
213
214 pub fn make_fn_raw(f: fn(Handle, Handle) -> Handle, data: Handle) -> Val {
216 let idx: u32 = f as usize as u32;
217 unsafe { Val::take_ownership(emlite_val_make_callback(idx, data)) }
218 }
219
220 pub fn make_fn<F: FnMut(&[Val]) -> Val>(cb: F) -> Val {
222 fn shim(args: Handle, data: Handle) -> Handle {
223 let v = Val::take_ownership(args);
224 let vals: Vec<Val> = v.to_vec();
225 let func0 = Val::take_ownership(data);
226 let a = func0.as_::<i32>() as usize as *mut Box<dyn FnMut(&[Val]) -> Val>;
227 let f: &mut (dyn FnMut(&[Val]) -> Val) = unsafe { &mut **a };
228 core::mem::forget(func0);
229 f(&vals).as_handle()
230 }
231 #[allow(clippy::type_complexity)]
232 let a: *mut Box<dyn FnMut(&[Val]) -> Val> = Box::into_raw(Box::new(Box::new(cb)));
233 let data = Val::from(a as Handle);
234 unsafe {
235 emlite_val_inc_ref(data.as_handle());
236 }
237 Self::make_fn_raw(shim, data.as_handle())
238 }
239
240 pub fn await_(&self) -> Val {
242 eval!(
243 r#"
244 (async () => {{
245 let obj = EMLITE_VALMAP.toValue({});
246 let ret = await obj;
247 return EMLITE_VALMAP.toHandle(ret);
248 }})()
249 "#,
250 self.as_handle()
251 )
252 }
253
254 pub fn delete(v: Val) {
256 unsafe {
257 emlite_val_dec_ref(v.as_handle());
258 }
259 }
260
261 pub fn throw(v: Val) -> ! {
263 unsafe {
264 emlite_val_throw(v.as_handle());
265 }
266 }
267
268 pub fn instanceof(&self, v: Val) -> bool {
270 unsafe { emlite_val_instanceof(self.as_handle(), v.as_handle()) }
271 }
272
273 pub fn is_number(&self) -> bool {
274 unsafe { emlite_val_is_number(self.as_handle()) }
275 }
276
277 pub fn is_bool(&self) -> bool {
278 unsafe { emlite_val_is_bool(self.as_handle()) }
279 }
280
281 pub fn is_string(&self) -> bool {
282 unsafe { emlite_val_is_string(self.as_handle()) }
283 }
284
285 pub fn is_null(&self) -> bool {
286 self.as_handle() == EmlitePredefHandles::Null as u32
287 }
288
289 pub fn is_undefined(&self) -> bool {
290 self.as_handle() == EmlitePredefHandles::Undefined as u32
291 }
292
293 pub fn is_error(&self) -> bool {
294 self.instanceof(Val::global("Error"))
295 }
296
297 pub fn is_function(&self) -> bool {
298 self.instanceof(Val::global("Function"))
299 }
300
301 #[inline(always)]
302 pub fn as_<T>(&self) -> T
303 where
304 T: FromVal,
305 {
306 T::from_val(self)
307 }
308
309 pub fn from_utf16(utf16: &[u16]) -> Val {
311 Val::from(utf16)
312 }
313
314 pub fn to_utf16(&self) -> Option<Vec<u16>> {
316 self.as_::<Option<Vec<u16>>>()
317 }
318
319 pub fn to_utf16_result(&self) -> Result<Vec<u16>, Val> {
321 self.as_::<Result<Vec<u16>, Val>>()
322 }
323
324 pub fn utf16_to_string(utf16: &[u16]) -> Result<String, ()> {
326 match String::from_utf16(utf16) {
329 Ok(s) => Ok(s),
330 Err(_) => Err(()),
331 }
332 }
333
334 pub fn from_string_via_utf16(s: &str) -> Val {
336 let utf16: Vec<u16> = s.encode_utf16().collect();
337 Val::from_utf16(&utf16)
338 }
339}
340
341impl From<bool> for Val {
342 fn from(v: bool) -> Self {
343 Val::take_ownership(unsafe { emlite_val_make_bool(v as _) })
344 }
345}
346
347impl From<i8> for Val {
348 fn from(v: i8) -> Self {
349 Val::take_ownership(unsafe { emlite_val_make_int(v as _) })
350 }
351}
352
353impl From<u8> for Val {
354 fn from(v: u8) -> Self {
355 Val::take_ownership(unsafe { emlite_val_make_int(v as _) })
356 }
357}
358
359impl From<i16> for Val {
360 fn from(v: i16) -> Self {
361 Val::take_ownership(unsafe { emlite_val_make_int(v as _) })
362 }
363}
364
365impl From<u16> for Val {
366 fn from(v: u16) -> Self {
367 Val::take_ownership(unsafe { emlite_val_make_int(v as _) })
368 }
369}
370
371impl From<i32> for Val {
372 fn from(v: i32) -> Self {
373 Val::take_ownership(unsafe { emlite_val_make_int(v) })
374 }
375}
376
377impl From<u32> for Val {
378 fn from(v: u32) -> Self {
379 Val::take_ownership(unsafe { emlite_val_make_uint(v as _) })
380 }
381}
382
383impl From<i64> for Val {
384 fn from(v: i64) -> Self {
385 Val::take_ownership(unsafe { emlite_val_make_bigint(v as _) })
386 }
387}
388
389impl From<u64> for Val {
390 fn from(v: u64) -> Self {
391 Val::take_ownership(unsafe { emlite_val_make_biguint(v as _) })
392 }
393}
394
395impl From<usize> for Val {
396 fn from(v: usize) -> Self {
397 Val::take_ownership(unsafe { emlite_val_make_biguint(v as _) })
398 }
399}
400
401impl From<isize> for Val {
402 fn from(v: isize) -> Self {
403 Val::take_ownership(unsafe { emlite_val_make_bigint(v as _) })
404 }
405}
406
407impl From<f32> for Val {
408 fn from(v: f32) -> Self {
409 Val::take_ownership(unsafe { emlite_val_make_double(v as _) })
410 }
411}
412
413impl From<f64> for Val {
414 fn from(v: f64) -> Self {
415 Val::take_ownership(unsafe { emlite_val_make_double(v) })
416 }
417}
418
419impl From<()> for Val {
420 fn from(_: ()) -> Self {
421 Val::undefined()
422 }
423}
424
425impl From<&str> for Val {
426 fn from(s: &str) -> Self {
427 #[cfg(all(target_os = "wasi", target_env = "p2"))]
428 {
429 Val::take_ownership(unsafe { emlite_val_make_str(s) })
430 }
431 #[cfg(not(all(target_os = "wasi", target_env = "p2")))]
432 {
433 Val::take_ownership(unsafe { emlite_val_make_str(s.as_ptr() as _, s.len()) })
434 }
435 }
436}
437
438impl From<String> for Val {
439 fn from(s: String) -> Self {
440 #[cfg(all(target_os = "wasi", target_env = "p2"))]
441 {
442 Val::take_ownership(unsafe { emlite_val_make_str(&s) })
443 }
444 #[cfg(not(all(target_os = "wasi", target_env = "p2")))]
445 {
446 Val::take_ownership(unsafe { emlite_val_make_str(s.as_ptr() as _, s.len()) })
447 }
448 }
449}
450
451impl From<&String> for Val {
452 fn from(s: &String) -> Self {
453 #[cfg(all(target_os = "wasi", target_env = "p2"))]
454 {
455 Val::take_ownership(unsafe { emlite_val_make_str(s) })
456 }
457 #[cfg(not(all(target_os = "wasi", target_env = "p2")))]
458 {
459 Val::take_ownership(unsafe { emlite_val_make_str(s.as_ptr() as _, s.len()) })
460 }
461 }
462}
463
464impl From<&[u16]> for Val {
465 fn from(s: &[u16]) -> Self {
466 #[cfg(all(target_os = "wasi", target_env = "p2"))]
467 {
468 Val::take_ownership(unsafe { emlite_val_make_str_utf16(s) })
469 }
470 #[cfg(not(all(target_os = "wasi", target_env = "p2")))]
471 {
472 Val::take_ownership(unsafe { emlite_val_make_str_utf16(s.as_ptr(), s.len()) })
473 }
474 }
475}
476
477impl From<Vec<u16>> for Val {
478 fn from(s: Vec<u16>) -> Self {
479 #[cfg(all(target_os = "wasi", target_env = "p2"))]
480 {
481 Val::take_ownership(unsafe { emlite_val_make_str_utf16(&s) })
482 }
483 #[cfg(not(all(target_os = "wasi", target_env = "p2")))]
484 {
485 Val::take_ownership(unsafe { emlite_val_make_str_utf16(s.as_ptr(), s.len()) })
486 }
487 }
488}
489
490impl From<&Vec<u16>> for Val {
491 fn from(s: &Vec<u16>) -> Self {
492 #[cfg(all(target_os = "wasi", target_env = "p2"))]
493 {
494 Val::take_ownership(unsafe { emlite_val_make_str_utf16(s) })
495 }
496 #[cfg(not(all(target_os = "wasi", target_env = "p2")))]
497 {
498 Val::take_ownership(unsafe { emlite_val_make_str_utf16(s.as_ptr(), s.len()) })
499 }
500 }
501}
502
503impl From<&Val> for Val {
504 fn from(v: &Val) -> Self {
505 v.clone()
506 }
507}
508
509impl Drop for Val {
510 fn drop(&mut self) {
511 unsafe { emlite_val_dec_ref(self.as_handle()) }
512 }
513}
514
515impl Clone for Val {
516 fn clone(&self) -> Val {
517 unsafe {
518 emlite_val_inc_ref(self.as_handle());
519 }
520 Val::take_ownership(self.as_handle())
521 }
522}
523
524use core::ops::{Deref, DerefMut};
525
526#[derive(Clone, Debug)]
528pub struct Console {
529 val: Val,
530}
531
532impl Console {
533 pub const fn get() -> Console {
535 Console {
536 val: Val {
537 inner: EmlitePredefHandles::Console as _,
538 },
539 }
540 }
541
542 pub fn log(&self, args: &[Val]) {
544 self.val.call("log", args);
545 }
546
547 pub fn warn(&self, args: &[Val]) {
549 self.val.call("warn", args);
550 }
551
552 pub fn info(&self, args: &[Val]) {
554 self.val.call("info", args);
555 }
556
557 pub fn as_handle(&self) -> Handle {
559 self.val.as_handle()
560 }
561}
562
563impl Deref for Console {
564 type Target = Val;
565
566 fn deref(&self) -> &Self::Target {
567 &self.val
568 }
569}
570
571impl DerefMut for Console {
572 fn deref_mut(&mut self) -> &mut Self::Target {
573 &mut self.val
574 }
575}
576
577impl From<Console> for Val {
578 fn from(val: Console) -> Self {
579 Val::take_ownership(val.as_handle())
580 }
581}
582
583use core::cmp::Ordering;
584use core::ops::Not;
585
586impl PartialEq for Val {
587 fn eq(&self, other: &Val) -> bool {
588 unsafe { emlite_val_strictly_equals(self.as_handle(), other.as_handle()) }
589 }
590}
591
592impl PartialOrd for Val {
593 fn partial_cmp(&self, other: &Val) -> Option<Ordering> {
594 unsafe {
595 if emlite_val_strictly_equals(self.as_handle(), other.as_handle()) {
596 Some(Ordering::Equal)
597 } else if emlite_val_gt(self.as_handle(), other.as_handle()) {
598 Some(Ordering::Greater)
599 } else if emlite_val_lt(self.as_handle(), other.as_handle()) {
600 Some(Ordering::Less)
601 } else {
602 None
603 }
604 }
605 }
606}
607
608impl Not for Val {
609 type Output = bool;
610
611 fn not(self) -> Self::Output {
612 unsafe { emlite_val_not(self.as_handle()) }
613 }
614}
615
616impl AsRef<Val> for Val {
617 #[inline]
618 fn as_ref(&self) -> &Val { self }
619}
620
621impl AsMut<Val> for Val {
622 #[inline]
623 fn as_mut(&mut self) -> &mut Val { self }
624}
625
626pub trait FromVal: Sized {
627 fn from_val(v: &Val) -> Self;
629 fn take_ownership(v: Handle) -> Self;
631 fn as_handle(&self) -> Handle;
633}
634
635impl FromVal for Val {
636 fn from_val(v: &Val) -> Self {
637 unsafe {
638 emlite_val_inc_ref(v.inner);
639 }
640 Val {
641 inner: v.as_handle(),
642 }
643 }
644 fn take_ownership(v: Handle) -> Self {
645 Val { inner: v }
646 }
647 #[inline(always)]
648 fn as_handle(&self) -> Handle {
649 self.inner
650 }
651}
652
653impl FromVal for Result<Val, Val> {
654 fn from_val(v: &Val) -> Self {
655 unsafe {
656 emlite_val_inc_ref(v.inner);
657 }
658 if v.is_error() {
659 Err(v.clone())
660 } else {
661 Ok(v.clone())
662 }
663 }
664 fn take_ownership(v: Handle) -> Self {
665 let temp = Val::take_ownership(v);
666 if temp.is_error() {
667 Err(temp)
668 } else {
669 Ok(temp)
670 }
671 }
672 #[inline(always)]
673 fn as_handle(&self) -> Handle {
674 match self {
675 Ok(ok) => ok.as_handle(),
676 Err(e) => e.as_handle(),
677 }
678 }
679}
680
681impl FromVal for bool {
682 fn from_val(v: &Val) -> Self {
683 unsafe {
684 #[cfg(all(target_os = "wasi", target_env = "p2"))]
685 {
686 !crate::wasip2env::emlite_val_not(v.as_handle())
687 }
688 #[cfg(not(all(target_os = "wasi", target_env = "p2")))]
689 {
690 !crate::env::emlite_val_not(v.as_handle())
691 }
692 }
693 }
694 fn take_ownership(v: Handle) -> Self {
695 Self::from_val(&Val::take_ownership(v))
696 }
697 fn as_handle(&self) -> Handle {
698 if *self { EmlitePredefHandles::True as u32 } else { EmlitePredefHandles::False as u32 }
699 }
700}
701
702
703impl FromVal for Option<bool> {
704 fn from_val(v: &Val) -> Self {
705 unsafe {
706 if v.is_error() || v.is_null() || v.is_undefined() {
707 None
708 } else {
709 #[cfg(all(target_os = "wasi", target_env = "p2"))]
710 {
711 Some(!crate::wasip2env::emlite_val_not(v.as_handle()))
712 }
713 #[cfg(not(all(target_os = "wasi", target_env = "p2")))]
714 {
715 Some(!crate::env::emlite_val_not(v.as_handle()))
716 }
717 }
718 }
719 }
720 fn take_ownership(v: Handle) -> Self {
721 let temp = Val::take_ownership(v);
722 if temp.is_error() || temp.is_null() || temp.is_undefined() {
723 None
724 } else {
725 #[cfg(all(target_os = "wasi", target_env = "p2"))]
726 unsafe { Some(!crate::wasip2env::emlite_val_not(v)) }
727 #[cfg(not(all(target_os = "wasi", target_env = "p2")))]
728 unsafe { Some(!crate::env::emlite_val_not(v)) }
729 }
730 }
731 fn as_handle(&self) -> Handle {
732 match self {
733 Some(ok) => if *ok { EmlitePredefHandles::True as u32 } else { EmlitePredefHandles::False as u32 },
734 None => EmlitePredefHandles::Undefined as u32,
735 }
736 }
737}
738
739impl FromVal for Result<bool, Val> {
740 fn from_val(v: &Val) -> Self {
741 unsafe {
742 if v.is_error() {
743 Err(v.clone())
744 } else {
745 #[cfg(all(target_os = "wasi", target_env = "p2"))]
746 {
747 Ok(!crate::wasip2env::emlite_val_not(v.as_handle()))
748 }
749 #[cfg(not(all(target_os = "wasi", target_env = "p2")))]
750 {
751 Ok(!crate::env::emlite_val_not(v.as_handle()))
752 }
753 }
754 }
755 }
756 fn take_ownership(v: Handle) -> Self {
757 let temp = Val::take_ownership(v);
758 if temp.is_error() {
759 Err(temp)
760 } else {
761 #[cfg(all(target_os = "wasi", target_env = "p2"))]
762 unsafe { Ok(!crate::wasip2env::emlite_val_not(v)) }
763 #[cfg(not(all(target_os = "wasi", target_env = "p2")))]
764 unsafe { Ok(!crate::env::emlite_val_not(v)) }
765 }
766 }
767 fn as_handle(&self) -> Handle {
768 match self {
769 Ok(ok) => if *ok { EmlitePredefHandles::True as u32 } else { EmlitePredefHandles::False as u32 },
770 Err(e) => e.as_handle(),
771 }
772 }
773}
774
775macro_rules! impl_int {
776 ($($t:ty),*) => {$(
777 impl FromVal for $t {
778 fn from_val(v: &Val) -> Self {
779 unsafe {
780 emlite_val_get_value_int(v.as_handle()) as Self
781 }
782 }
783 fn take_ownership(v: Handle) -> Self {
784 unsafe { emlite_val_get_value_int(v) as Self }
785 }
786 fn as_handle(&self) -> Handle {
787 0
788 }
789 }
790 impl FromVal for Option<$t> {
791 fn from_val(v: &Val) -> Self {
792 unsafe {
793 if !v.is_number() {
794 None
795 } else {
796 Some(emlite_val_get_value_int(v.as_handle()) as $t)
797 }
798 }
799 }
800 fn take_ownership(v: Handle) -> Self {
801 let temp = Val::take_ownership(v);
802 if !temp.is_number() {
803 None
804 } else {
805 unsafe { Some(emlite_val_get_value_int(v) as $t) }
806 }
807 }
808 fn as_handle(&self) -> Handle {
809 0
810 }
811 }
812 impl FromVal for Result<$t, Val> {
813 fn from_val(v: &Val) -> Self {
814 unsafe {
815 if v.is_error() {
816 Err(v.clone())
817 } else {
818 Ok(emlite_val_get_value_int(v.as_handle()) as $t)
819 }
820 }
821 }
822 fn take_ownership(v: Handle) -> Self {
823 let temp = Val::take_ownership(v);
824 if temp.is_error() {
825 Err(temp)
826 } else {
827 unsafe { Ok(emlite_val_get_value_int(v) as $t) }
828 }
829 }
830 fn as_handle(&self) -> Handle {
831 0
832 }
833 }
834 )*}
835}
836
837macro_rules! impl_uint {
838 ($($t:ty),*) => {$(
839 impl FromVal for $t {
840 fn from_val(v: &Val) -> Self {
841 unsafe {
842 emlite_val_get_value_uint(v.as_handle()) as Self
843 }
844 }
845 fn take_ownership(v: Handle) -> Self {
846 unsafe { emlite_val_get_value_uint(v) as Self }
847 }
848 fn as_handle(&self) -> Handle {
849 0
850 }
851 }
852 impl FromVal for Option<$t> {
853 fn from_val(v: &Val) -> Self {
854 unsafe {
855 if !v.is_number() {
856 None
857 } else {
858 Some(emlite_val_get_value_uint(v.as_handle()) as $t)
859 }
860 }
861 }
862 fn take_ownership(v: Handle) -> Self {
863 let temp = Val::take_ownership(v);
864 if !temp.is_number() {
865 None
866 } else {
867 unsafe { Some(emlite_val_get_value_uint(v) as $t) }
868 }
869 }
870 fn as_handle(&self) -> Handle {
871 0
872 }
873 }
874 impl FromVal for Result<$t, Val> {
875 fn from_val(v: &Val) -> Self {
876 unsafe {
877 if v.is_error() {
878 Err(v.clone())
879 } else {
880 Ok(emlite_val_get_value_uint(v.as_handle()) as $t)
881 }
882 }
883 }
884 fn take_ownership(v: Handle) -> Self {
885 let temp = Val::take_ownership(v);
886 if temp.is_error() {
887 Err(temp)
888 } else {
889 unsafe { Ok(emlite_val_get_value_uint(v) as $t) }
890 }
891 }
892 fn as_handle(&self) -> Handle {
893 0
894 }
895 }
896 )*}
897}
898
899macro_rules! impl_bigint {
900 ($($t:ty),*) => {$(
901 impl FromVal for $t {
902 fn from_val(v: &Val) -> Self {
903 unsafe {
904 emlite_val_get_value_bigint(v.as_handle()) as Self
905 }
906 }
907 fn take_ownership(v: Handle) -> Self {
908 unsafe { emlite_val_get_value_bigint(v) as Self }
909 }
910 fn as_handle(&self) -> Handle {
911 0
912 }
913 }
914 impl FromVal for Option<$t> {
915 fn from_val(v: &Val) -> Self {
916 unsafe {
917 if !v.is_number() {
918 None
919 } else {
920 Some(emlite_val_get_value_bigint(v.as_handle()) as $t)
921 }
922 }
923 }
924 fn take_ownership(v: Handle) -> Self {
925 let temp = Val::take_ownership(v);
926 if !temp.is_number() {
927 None
928 } else {
929 unsafe { Some(emlite_val_get_value_bigint(v) as $t) }
930 }
931 }
932 fn as_handle(&self) -> Handle {
933 0
934 }
935 }
936 impl FromVal for Result<$t, Val> {
937 fn from_val(v: &Val) -> Self {
938 unsafe {
939 if v.is_error() {
940 Err(v.clone())
941 } else {
942 Ok(emlite_val_get_value_bigint(v.as_handle()) as $t)
943 }
944 }
945 }
946 fn take_ownership(v: Handle) -> Self {
947 let temp = Val::take_ownership(v);
948 if temp.is_error() {
949 Err(temp)
950 } else {
951 unsafe { Ok(emlite_val_get_value_bigint(v) as $t) }
952 }
953 }
954 fn as_handle(&self) -> Handle {
955 0
956 }
957 }
958 )*}
959}
960
961macro_rules! impl_biguint {
962 ($($t:ty),*) => {$(
963 impl FromVal for $t {
964 fn from_val(v: &Val) -> Self {
965 unsafe {
966 emlite_val_get_value_biguint(v.as_handle()) as Self
967 }
968 }
969 fn take_ownership(v: Handle) -> Self {
970 unsafe { emlite_val_get_value_biguint(v) as Self }
971 }
972 fn as_handle(&self) -> Handle {
973 0
974 }
975 }
976 impl FromVal for Option<$t> {
977 fn from_val(v: &Val) -> Self {
978 unsafe {
979 if !v.is_number() {
980 None
981 } else {
982 Some(emlite_val_get_value_biguint(v.as_handle()) as $t)
983 }
984 }
985 }
986 fn take_ownership(v: Handle) -> Self {
987 let temp = Val::take_ownership(v);
988 if !temp.is_number() {
989 None
990 } else {
991 unsafe { Some(emlite_val_get_value_biguint(v) as $t) }
992 }
993 }
994 fn as_handle(&self) -> Handle {
995 0
996 }
997 }
998 impl FromVal for Result<$t, Val> {
999 fn from_val(v: &Val) -> Self {
1000 unsafe {
1001 if v.is_error() {
1002 Err(v.clone())
1003 } else {
1004 Ok(emlite_val_get_value_biguint(v.as_handle()) as $t)
1005 }
1006 }
1007 }
1008 fn take_ownership(v: Handle) -> Self {
1009 let temp = Val::take_ownership(v);
1010 if temp.is_error() {
1011 Err(temp)
1012 } else {
1013 unsafe { Ok(emlite_val_get_value_biguint(v) as $t) }
1014 }
1015 }
1016 fn as_handle(&self) -> Handle {
1017 0
1018 }
1019 }
1020 )*}
1021}
1022
1023impl_int!(i8, i16, i32);
1024impl_uint!(u8, u16, u32);
1025impl_bigint!(i64, isize);
1026impl_biguint!(u64, usize);
1027
1028macro_rules! impl_float {
1029 ($($t:ty),*) => {$(
1030 impl FromVal for $t {
1031 fn from_val(v: &Val) -> Self {
1032 unsafe { emlite_val_get_value_double(v.as_handle()) as Self }
1033 }
1034 fn take_ownership(v: Handle) -> Self {
1035 unsafe { emlite_val_get_value_double(v) as Self }
1036 }
1037 fn as_handle(&self) -> Handle {
1038 0
1039 }
1040 }
1041 impl FromVal for Option<$t> {
1042 fn from_val(v: &Val) -> Self {
1043 unsafe {
1044 if !v.is_number() {
1045 None
1046 } else {
1047 Some(emlite_val_get_value_double(v.as_handle()) as $t)
1048 }
1049 }
1050 }
1051 fn take_ownership(v: Handle) -> Self {
1052 let temp = Val::take_ownership(v);
1053 if !temp.is_number() {
1054 None
1055 } else {
1056 unsafe { Some(emlite_val_get_value_double(v) as $t) }
1057 }
1058 }
1059 fn as_handle(&self) -> Handle {
1060 0
1061 }
1062 }
1063 impl FromVal for Result<$t, Val> {
1064 fn from_val(v: &Val) -> Self {
1065 unsafe {
1066 if v.is_error() {
1067 Err(v.clone())
1068 } else {
1069 Ok(emlite_val_get_value_double(v.as_handle()) as $t)
1070 }
1071 }
1072 }
1073 fn take_ownership(v: Handle) -> Self {
1074 let temp = Val::take_ownership(v);
1075 if temp.is_error() {
1076 Err(temp)
1077 } else {
1078 unsafe { Ok(emlite_val_get_value_double(v) as $t) }
1079 }
1080 }
1081 fn as_handle(&self) -> Handle {
1082 0
1083 }
1084 }
1085 )*}
1086}
1087
1088impl_float!(f32, f64);
1089
1090impl FromVal for () {
1091 fn from_val(_v: &Val) -> Self {
1092 ()
1094 }
1095 fn take_ownership(_v: Handle) -> Self {
1096 ()
1097 }
1098 fn as_handle(&self) -> Handle {
1099 EmlitePredefHandles::Undefined as u32
1100 }
1101}
1102
1103impl FromVal for Option<String> {
1104 fn from_val(v: &Val) -> Self {
1105 unsafe {
1106 if !v.is_string() {
1107 return None;
1108 }
1109 #[cfg(all(target_os = "wasi", target_env = "p2"))]
1110 {
1111 Some(emlite_val_get_value_string(v.as_handle()))
1112 }
1113 #[cfg(not(all(target_os = "wasi", target_env = "p2")))]
1114 {
1115 let ptr = emlite_val_get_value_string(v.as_handle());
1116 if ptr.is_null() {
1117 None
1118 } else {
1119 Some(CStr::from_ptr(ptr).to_string_lossy().into_owned())
1120 }
1121 }
1122 }
1123 }
1124 fn take_ownership(v: Handle) -> Self {
1125 unsafe {
1126 if !emlite_val_is_string(v) {
1127 return None;
1128 }
1129 #[cfg(all(target_os = "wasi", target_env = "p2"))]
1130 {
1131 Some(emlite_val_get_value_string(v))
1132 }
1133 #[cfg(not(all(target_os = "wasi", target_env = "p2")))]
1134 {
1135 let ptr = emlite_val_get_value_string(v);
1136 if ptr.is_null() {
1137 None
1138 } else {
1139 Some(CStr::from_ptr(ptr).to_string_lossy().into_owned())
1140 }
1141 }
1142 }
1143 }
1144 fn as_handle(&self) -> Handle {
1145 0
1146 }
1147}
1148
1149impl FromVal for Result<String, Val> {
1150 fn from_val(v: &Val) -> Self {
1151 unsafe {
1152 if v.is_error() {
1153 Err(v.clone())
1154 } else if !v.is_string() {
1155 Err(Val::global("Error").new(&["Expected string".into()]))
1156 } else {
1157 #[cfg(all(target_os = "wasi", target_env = "p2"))]
1158 {
1159 Ok(emlite_val_get_value_string(v.as_handle()))
1160 }
1161 #[cfg(not(all(target_os = "wasi", target_env = "p2")))]
1162 {
1163 let ptr = emlite_val_get_value_string(v.as_handle());
1164 if ptr.is_null() {
1165 Err(Val::global("Error").new(&["Null string".into()]))
1166 } else {
1167 Ok(CStr::from_ptr(ptr).to_string_lossy().into_owned())
1168 }
1169 }
1170 }
1171 }
1172 }
1173 fn take_ownership(v: Handle) -> Self {
1174 unsafe {
1175 let temp = Val::take_ownership(v);
1176 if temp.is_error() {
1177 Err(temp)
1178 } else if !temp.is_string() {
1179 Err(Val::global("Error").new(&["Expected string".into()]))
1180 } else {
1181 #[cfg(all(target_os = "wasi", target_env = "p2"))]
1182 {
1183 Ok(emlite_val_get_value_string(v))
1184 }
1185 #[cfg(not(all(target_os = "wasi", target_env = "p2")))]
1186 {
1187 let ptr = emlite_val_get_value_string(v);
1188 if ptr.is_null() {
1189 Err(Val::global("Error").new(&["Null string".into()]))
1190 } else {
1191 Ok(CStr::from_ptr(ptr).to_string_lossy().into_owned())
1192 }
1193 }
1194 }
1195 }
1196 }
1197 fn as_handle(&self) -> Handle {
1198 0
1199 }
1200}
1201
1202impl FromVal for Option<Vec<u16>> {
1203 fn from_val(v: &Val) -> Self {
1204 unsafe {
1205 #[cfg(all(target_os = "wasi", target_env = "p2"))]
1206 {
1207 Some(emlite_val_get_value_string_utf16(v.as_handle()))
1208 }
1209 #[cfg(not(all(target_os = "wasi", target_env = "p2")))]
1210 {
1211 let ptr = emlite_val_get_value_string_utf16(v.as_handle());
1212 if ptr.is_null() {
1213 None
1214 } else {
1215 let mut len = 0;
1217 let mut current = ptr;
1218 while *current != 0 {
1219 len += 1;
1220 current = current.add(1);
1221 }
1222 let slice = core::slice::from_raw_parts(ptr, len);
1224 Some(slice.to_vec())
1225 }
1226 }
1227 }
1228 }
1229 fn take_ownership(v: Handle) -> Self {
1230 unsafe {
1231 #[cfg(all(target_os = "wasi", target_env = "p2"))]
1232 {
1233 Some(emlite_val_get_value_string_utf16(v))
1234 }
1235 #[cfg(not(all(target_os = "wasi", target_env = "p2")))]
1236 {
1237 let ptr = emlite_val_get_value_string_utf16(v);
1238 if ptr.is_null() {
1239 None
1240 } else {
1241 let mut len = 0;
1243 let mut current = ptr;
1244 while *current != 0 {
1245 len += 1;
1246 current = current.add(1);
1247 }
1248 let slice = core::slice::from_raw_parts(ptr, len);
1250 Some(slice.to_vec())
1251 }
1252 }
1253 }
1254 }
1255 fn as_handle(&self) -> Handle {
1256 0
1257 }
1258}
1259
1260impl FromVal for Result<Vec<u16>, Val> {
1261 fn from_val(v: &Val) -> Self {
1262 unsafe {
1263 if v.is_error() {
1264 Err(v.clone())
1265 } else {
1266 #[cfg(all(target_os = "wasi", target_env = "p2"))]
1267 {
1268 Ok(emlite_val_get_value_string_utf16(v.as_handle()))
1269 }
1270 #[cfg(not(all(target_os = "wasi", target_env = "p2")))]
1271 {
1272 let ptr = emlite_val_get_value_string_utf16(v.as_handle());
1273 if ptr.is_null() {
1274 Err(Val::global("Error").new(&["Null UTF-16 string".into()]))
1275 } else {
1276 let mut len = 0;
1278 let mut current = ptr;
1279 while *current != 0 {
1280 len += 1;
1281 current = current.add(1);
1282 }
1283 let slice = core::slice::from_raw_parts(ptr, len);
1285 Ok(slice.to_vec())
1286 }
1287 }
1288 }
1289 }
1290 }
1291 fn take_ownership(v: Handle) -> Self {
1292 unsafe {
1293 let temp = Val::take_ownership(v);
1294 if temp.is_error() {
1295 Err(temp)
1296 } else {
1297 #[cfg(all(target_os = "wasi", target_env = "p2"))]
1298 {
1299 Ok(emlite_val_get_value_string_utf16(v))
1300 }
1301 #[cfg(not(all(target_os = "wasi", target_env = "p2")))]
1302 {
1303 let ptr = emlite_val_get_value_string_utf16(v);
1304 if ptr.is_null() {
1305 Err(Val::global("Error").new(&["Null UTF-16 string".into()]))
1306 } else {
1307 let mut len = 0;
1309 let mut current = ptr;
1310 while *current != 0 {
1311 len += 1;
1312 current = current.add(1);
1313 }
1314 let slice = core::slice::from_raw_parts(ptr, len);
1316 Ok(slice.to_vec())
1317 }
1318 }
1319 }
1320 }
1321 }
1322 fn as_handle(&self) -> Handle {
1323 0
1324 }
1325}
1326
1327pub trait FromJsError {
1330 fn from_js_error(val: &Val) -> Self;
1331}
1332
1333impl<T, E> FromVal for Result<T, E>
1336where
1337 T: FromVal,
1338 E: FromJsError,
1339{
1340 fn from_val(v: &Val) -> Self {
1341 if v.is_error() {
1342 Err(E::from_js_error(v))
1343 } else {
1344 Ok(T::from_val(v))
1345 }
1346 }
1347 fn take_ownership(handle: Handle) -> Self {
1348 let temp = Val::take_ownership(handle);
1349 if temp.is_error() {
1350 Err(E::from_js_error(&temp))
1351 } else {
1352 Ok(T::take_ownership(handle))
1353 }
1354 }
1355 fn as_handle(&self) -> Handle {
1356 match self {
1357 Ok(ok) => ok.as_handle(),
1358 Err(_) => 0, }
1360 }
1361}
1362