bare_rust/
lib.rs

1use std::ffi::{c_void, CString};
2use std::ptr;
3use std::slice;
4use std::string;
5
6pub use bare_rust_ffi as ffi;
7
8use ffi::*;
9
10macro_rules! check_status {
11    ($env:expr, $status:expr) => {
12        if $status == JS_PENDING_EXCEPTION {
13            return Err($env.pending_exception());
14        } else if $status != 0 {
15            panic!("Uncaught JavaScript exception");
16        }
17    };
18}
19
20pub type Result<T> = std::result::Result<T, Value>;
21
22#[derive(Debug)]
23pub struct Env {
24    ptr: *mut js_env_t,
25}
26
27impl Env {
28    pub fn is_exception_pending(&self) -> bool {
29        let mut result = false;
30
31        unsafe {
32            js_is_exception_pending(self.ptr, &mut result);
33        }
34
35        result
36    }
37
38    pub fn pending_exception(&self) -> Value {
39        let mut ptr: *mut js_value_t = ptr::null_mut();
40
41        unsafe {
42            js_get_and_clear_last_exception(self.ptr, &mut ptr);
43        }
44
45        Value { env: self.ptr, ptr }
46    }
47}
48
49impl From<*mut js_env_t> for Env {
50    fn from(ptr: *mut js_env_t) -> Self {
51        return Self { ptr };
52    }
53}
54
55#[derive(Debug)]
56pub struct Value {
57    env: *mut js_env_t,
58    ptr: *mut js_value_t,
59}
60
61impl From<Value> for *mut js_value_t {
62    fn from(value: Value) -> Self {
63        value.ptr
64    }
65}
66
67#[derive(Debug)]
68pub struct Undefined(Value);
69
70impl Undefined {
71    pub fn new(env: &Env) -> Self {
72        let mut ptr: *mut js_value_t = ptr::null_mut();
73
74        unsafe {
75            js_get_undefined(env.ptr, &mut ptr);
76        }
77
78        Self(Value { env: env.ptr, ptr })
79    }
80}
81
82impl From<Undefined> for *mut js_value_t {
83    fn from(undefined: Undefined) -> Self {
84        undefined.0.ptr
85    }
86}
87
88impl From<Value> for Undefined {
89    fn from(value: Value) -> Self {
90        Self(value)
91    }
92}
93
94#[derive(Debug)]
95pub struct Null(Value);
96
97impl Null {
98    pub fn new(env: &Env) -> Self {
99        let mut ptr: *mut js_value_t = ptr::null_mut();
100
101        unsafe {
102            js_get_null(env.ptr, &mut ptr);
103        }
104
105        Self(Value { env: env.ptr, ptr })
106    }
107}
108
109impl From<Null> for *mut js_value_t {
110    fn from(null: Null) -> Self {
111        null.0.ptr
112    }
113}
114
115impl From<Value> for Null {
116    fn from(value: Value) -> Self {
117        Self(value)
118    }
119}
120
121#[derive(Debug)]
122pub struct Boolean(Value);
123
124impl Boolean {
125    pub fn new(env: &Env, value: bool) -> Self {
126        let mut ptr: *mut js_value_t = ptr::null_mut();
127
128        unsafe {
129            js_get_boolean(env.ptr, value, &mut ptr);
130        }
131
132        Self(Value { env: env.ptr, ptr })
133    }
134}
135
136impl From<Boolean> for bool {
137    fn from(boolean: Boolean) -> Self {
138        let mut value = false;
139
140        unsafe {
141            js_get_value_bool(boolean.0.env, boolean.0.ptr, &mut value);
142        }
143
144        value
145    }
146}
147
148impl From<Boolean> for *mut js_value_t {
149    fn from(boolean: Boolean) -> Self {
150        boolean.0.ptr
151    }
152}
153
154impl From<Value> for Boolean {
155    fn from(value: Value) -> Self {
156        Self(value)
157    }
158}
159
160#[derive(Debug)]
161pub struct Number(Value);
162
163impl Number {
164    pub fn with_i32(env: &Env, value: i32) -> Self {
165        let mut ptr: *mut js_value_t = ptr::null_mut();
166
167        unsafe {
168            js_create_int32(env.ptr, value, &mut ptr);
169        }
170
171        Self(Value { env: env.ptr, ptr })
172    }
173
174    pub fn with_u32(env: &Env, value: u32) -> Self {
175        let mut ptr: *mut js_value_t = ptr::null_mut();
176
177        unsafe {
178            js_create_uint32(env.ptr, value, &mut ptr);
179        }
180
181        Self(Value { env: env.ptr, ptr })
182    }
183
184    pub fn with_i64(env: &Env, value: i64) -> Self {
185        let mut ptr: *mut js_value_t = ptr::null_mut();
186
187        unsafe {
188            js_create_int64(env.ptr, value, &mut ptr);
189        }
190
191        Self(Value { env: env.ptr, ptr })
192    }
193
194    pub fn with_f64(env: &Env, value: f64) -> Self {
195        let mut ptr: *mut js_value_t = ptr::null_mut();
196
197        unsafe {
198            js_create_double(env.ptr, value, &mut ptr);
199        }
200
201        Self(Value { env: env.ptr, ptr })
202    }
203}
204
205impl From<Number> for i32 {
206    fn from(number: Number) -> Self {
207        let mut value = 0;
208
209        unsafe {
210            js_get_value_int32(number.0.env, number.0.ptr, &mut value);
211        }
212
213        value
214    }
215}
216
217impl From<Number> for u32 {
218    fn from(number: Number) -> Self {
219        let mut value = 0;
220
221        unsafe {
222            js_get_value_uint32(number.0.env, number.0.ptr, &mut value);
223        }
224
225        value
226    }
227}
228
229impl From<Number> for i64 {
230    fn from(number: Number) -> Self {
231        let mut value = 0;
232
233        unsafe {
234            js_get_value_int64(number.0.env, number.0.ptr, &mut value);
235        }
236
237        value
238    }
239}
240
241impl From<Number> for f64 {
242    fn from(number: Number) -> Self {
243        let mut value = 0.0;
244
245        unsafe {
246            js_get_value_double(number.0.env, number.0.ptr, &mut value);
247        }
248
249        value
250    }
251}
252
253impl From<Number> for *mut js_value_t {
254    fn from(number: Number) -> Self {
255        number.0.ptr
256    }
257}
258
259impl From<Value> for Number {
260    fn from(value: Value) -> Self {
261        Self(value)
262    }
263}
264
265#[derive(Debug)]
266pub struct BigInt(Value);
267
268impl BigInt {
269    pub fn with_i64(env: &Env, value: i64) -> Self {
270        let mut ptr: *mut js_value_t = ptr::null_mut();
271
272        unsafe {
273            js_create_bigint_int64(env.ptr, value, &mut ptr);
274        }
275
276        Self(Value { env: env.ptr, ptr })
277    }
278
279    pub fn with_u64(env: &Env, value: u64) -> Self {
280        let mut ptr: *mut js_value_t = ptr::null_mut();
281
282        unsafe {
283            js_create_bigint_uint64(env.ptr, value, &mut ptr);
284        }
285
286        Self(Value { env: env.ptr, ptr })
287    }
288}
289
290impl From<BigInt> for i64 {
291    fn from(bigint: BigInt) -> Self {
292        let mut value = 0;
293
294        unsafe {
295            js_get_value_bigint_int64(bigint.0.env, bigint.0.ptr, &mut value, ptr::null_mut());
296        }
297
298        value
299    }
300}
301
302impl From<BigInt> for u64 {
303    fn from(bigint: BigInt) -> Self {
304        let mut value = 0;
305
306        unsafe {
307            js_get_value_bigint_uint64(bigint.0.env, bigint.0.ptr, &mut value, ptr::null_mut());
308        }
309
310        value
311    }
312}
313
314impl From<BigInt> for *mut js_value_t {
315    fn from(bigint: BigInt) -> Self {
316        bigint.0.ptr
317    }
318}
319
320impl From<Value> for BigInt {
321    fn from(value: Value) -> Self {
322        Self(value)
323    }
324}
325
326#[derive(Debug)]
327pub struct Name(Value);
328
329impl From<Name> for *mut js_value_t {
330    fn from(name: Name) -> Self {
331        name.0.ptr
332    }
333}
334
335impl From<String> for Name {
336    fn from(string: String) -> Self {
337        Name(string.0)
338    }
339}
340
341impl From<Symbol> for Name {
342    fn from(symbol: Symbol) -> Self {
343        Name(symbol.0)
344    }
345}
346
347#[derive(Debug)]
348pub struct Symbol(Value);
349
350impl Symbol {
351    pub fn new(env: &Env, description: &str) -> Result<Self> {
352        let description = String::new(env, description)?;
353
354        let mut ptr: *mut js_value_t = ptr::null_mut();
355
356        let status = unsafe { js_create_symbol(env.ptr, description.0.ptr, &mut ptr) };
357
358        check_status!(env, status);
359
360        Ok(Self(Value { env: env.ptr, ptr }))
361    }
362}
363
364impl From<Symbol> for *mut js_value_t {
365    fn from(symbol: Symbol) -> Self {
366        symbol.0.ptr
367    }
368}
369
370impl From<Value> for Symbol {
371    fn from(value: Value) -> Self {
372        Self(value)
373    }
374}
375
376#[derive(Debug)]
377pub struct String(Value);
378
379impl String {
380    pub fn new(env: &Env, value: &str) -> Result<Self> {
381        let mut ptr: *mut js_value_t = ptr::null_mut();
382
383        let status = unsafe {
384            js_create_string_utf8(
385                env.ptr,
386                value.as_ptr().cast(),
387                value.len() as usize,
388                &mut ptr,
389            )
390        };
391
392        check_status!(env, status);
393
394        Ok(Self(Value { env: env.ptr, ptr }))
395    }
396
397    pub fn to_bytes(&self) -> Vec<u8> {
398        let mut len = 0;
399
400        unsafe {
401            js_get_value_string_utf8(self.0.env, self.0.ptr, ptr::null_mut(), 0, &mut len);
402        }
403
404        let mut result = Vec::new();
405
406        result.resize(len, 0);
407
408        unsafe {
409            js_get_value_string_utf8(self.0.env, self.0.ptr, result.as_mut_ptr(), len, &mut len);
410        }
411
412        result
413    }
414}
415
416impl From<String> for string::String {
417    fn from(string: String) -> Self {
418        return string::String::from_utf8(string.to_bytes()).unwrap();
419    }
420}
421
422impl From<String> for *mut js_value_t {
423    fn from(string: String) -> Self {
424        string.0.ptr
425    }
426}
427
428impl From<Value> for String {
429    fn from(value: Value) -> Self {
430        Self(value)
431    }
432}
433
434#[derive(Debug)]
435pub struct Object(Value);
436
437impl Object {
438    pub fn new(env: &Env) -> Result<Self> {
439        let mut ptr: *mut js_value_t = ptr::null_mut();
440
441        let status = unsafe { js_create_object(env.ptr, &mut ptr) };
442
443        check_status!(env, status);
444
445        Ok(Self(Value { env: env.ptr, ptr }))
446    }
447
448    pub fn get_property<N, T>(&self, name: N) -> Result<T>
449    where
450        N: Into<Name>,
451        T: From<Value>,
452    {
453        let env = Env::from(self.0.env);
454
455        let name = N::into(name);
456
457        let mut ptr: *mut js_value_t = ptr::null_mut();
458
459        let status = unsafe { js_get_property(self.0.env, self.0.ptr, name.0.ptr, &mut ptr) };
460
461        check_status!(env, status);
462
463        Ok(T::from(Value { env: env.ptr, ptr }))
464    }
465
466    pub fn get_named_property<T>(&self, name: &str) -> Result<T>
467    where
468        T: From<Value>,
469    {
470        let env = Env::from(self.0.env);
471
472        let key = CString::new(name).unwrap();
473
474        let mut ptr: *mut js_value_t = ptr::null_mut();
475
476        let status =
477            unsafe { js_get_named_property(self.0.env, self.0.ptr, key.as_ptr(), &mut ptr) };
478
479        check_status!(env, status);
480
481        Ok(T::from(Value { env: env.ptr, ptr }))
482    }
483
484    pub fn get_element<T>(&self, index: u32) -> Result<T>
485    where
486        T: From<Value>,
487    {
488        let env = Env::from(self.0.env);
489
490        let mut ptr: *mut js_value_t = ptr::null_mut();
491
492        let status = unsafe { js_get_element(self.0.env, self.0.ptr, index, &mut ptr) };
493
494        check_status!(env, status);
495
496        Ok(T::from(Value { env: env.ptr, ptr }))
497    }
498
499    pub fn has_property<N>(&self, name: N) -> Result<bool>
500    where
501        N: Into<Name>,
502    {
503        let env = Env::from(self.0.env);
504
505        let name = N::into(name);
506
507        let mut result = false;
508
509        let status = unsafe { js_has_property(self.0.env, self.0.ptr, name.0.ptr, &mut result) };
510
511        check_status!(env, status);
512
513        Ok(result)
514    }
515
516    pub fn has_own_property<N>(&self, name: N) -> Result<bool>
517    where
518        N: Into<Name>,
519    {
520        let env = Env::from(self.0.env);
521
522        let name = N::into(name);
523
524        let mut result = false;
525
526        let status =
527            unsafe { js_has_own_property(self.0.env, self.0.ptr, name.0.ptr, &mut result) };
528
529        check_status!(env, status);
530
531        Ok(result)
532    }
533
534    pub fn has_named_property(&self, name: &str) -> Result<bool> {
535        let env = Env::from(self.0.env);
536
537        let key = CString::new(name).unwrap();
538
539        let mut result = false;
540
541        let status =
542            unsafe { js_has_named_property(self.0.env, self.0.ptr, key.as_ptr(), &mut result) };
543
544        check_status!(env, status);
545
546        Ok(result)
547    }
548
549    pub fn has_element(&self, index: u32) -> Result<bool> {
550        let env = Env::from(self.0.env);
551
552        let mut result = false;
553
554        let status = unsafe { js_has_element(self.0.env, self.0.ptr, index, &mut result) };
555
556        check_status!(env, status);
557
558        Ok(result)
559    }
560
561    pub fn set_property<N, T>(&mut self, name: N, value: T) -> Result<()>
562    where
563        N: Into<Name>,
564        T: Into<*mut js_value_t>,
565    {
566        let env = Env::from(self.0.env);
567
568        let name = N::into(name);
569
570        let status = unsafe { js_set_property(self.0.env, self.0.ptr, name.0.ptr, T::into(value)) };
571
572        check_status!(env, status);
573
574        Ok(())
575    }
576
577    pub fn set_named_property<T>(&mut self, name: &str, value: T) -> Result<()>
578    where
579        T: Into<*mut js_value_t>,
580    {
581        let env = Env::from(self.0.env);
582
583        let key = CString::new(name).unwrap();
584
585        let status =
586            unsafe { js_set_named_property(self.0.env, self.0.ptr, key.as_ptr(), T::into(value)) };
587
588        check_status!(env, status);
589
590        Ok(())
591    }
592
593    pub fn set_element<T>(&mut self, index: u32, value: T) -> Result<()>
594    where
595        T: Into<*mut js_value_t>,
596    {
597        let env = Env::from(self.0.env);
598
599        let status = unsafe { js_set_element(self.0.env, self.0.ptr, index, T::into(value)) };
600
601        check_status!(env, status);
602
603        Ok(())
604    }
605
606    pub fn delete_property<N>(&self, name: N) -> Result<bool>
607    where
608        N: Into<Name>,
609    {
610        let env = Env::from(self.0.env);
611
612        let name = N::into(name);
613
614        let mut result = false;
615
616        let status = unsafe { js_delete_property(self.0.env, self.0.ptr, name.0.ptr, &mut result) };
617
618        check_status!(env, status);
619
620        Ok(result)
621    }
622
623    pub fn delete_named_property(&self, name: &str) -> Result<bool> {
624        let env = Env::from(self.0.env);
625
626        let key = CString::new(name).unwrap();
627
628        let mut result = false;
629
630        let status =
631            unsafe { js_delete_named_property(self.0.env, self.0.ptr, key.as_ptr(), &mut result) };
632
633        check_status!(env, status);
634
635        Ok(result)
636    }
637
638    pub fn delete_element(&self, index: u32) -> Result<bool> {
639        let env = Env::from(self.0.env);
640
641        let mut result = false;
642
643        let status = unsafe { js_delete_element(self.0.env, self.0.ptr, index, &mut result) };
644
645        check_status!(env, status);
646
647        Ok(result)
648    }
649}
650
651impl From<Object> for *mut js_value_t {
652    fn from(object: Object) -> Self {
653        object.0.ptr
654    }
655}
656
657impl From<Value> for Object {
658    fn from(value: Value) -> Self {
659        Self(value)
660    }
661}
662
663#[derive(Debug)]
664pub struct Callback {
665    env: *mut js_env_t,
666    args: Vec<*mut js_value_t>,
667    receiver: *mut js_value_t,
668}
669
670impl Callback {
671    pub fn arg<T>(&self, i: usize) -> Option<T>
672    where
673        T: From<Value>,
674    {
675        if i < self.args.len() {
676            Some(T::from(Value {
677                env: self.env,
678                ptr: self.args[i],
679            }))
680        } else {
681            None
682        }
683    }
684
685    pub fn receiver<T>(&self) -> T
686    where
687        T: From<Value>,
688    {
689        T::from(Value {
690            env: self.env,
691            ptr: self.receiver,
692        })
693    }
694}
695
696#[derive(Debug)]
697pub struct Function(Value);
698
699impl Function {
700    pub fn new<F, R>(env: &Env, function: F) -> Result<Self>
701    where
702        F: FnMut(&Env, &Callback) -> Result<R>,
703        R: Into<*mut js_value_t>,
704    {
705        let mut function = function;
706
707        let closure: Box<dyn FnMut(&Env, &Callback) -> *mut js_value_t> =
708            Box::new(move |env, info| match function(env, info) {
709                Ok(result) => result.into(),
710                Err(error) => {
711                    unsafe {
712                        js_throw(env.ptr, error.ptr);
713                    }
714
715                    ptr::null_mut()
716                }
717            });
718
719        let data = Box::into_raw(Box::new(closure)) as *mut _;
720
721        let mut ptr: *mut js_value_t = ptr::null_mut();
722
723        let status = unsafe {
724            js_create_function(
725                env.ptr,
726                ptr::null_mut(),
727                0,
728                Some(Function::call),
729                data,
730                &mut ptr,
731            )
732        };
733
734        check_status!(env, status);
735
736        unsafe {
737            js_add_finalizer(
738                env.ptr,
739                ptr,
740                data,
741                Some(Function::drop),
742                ptr::null_mut(),
743                ptr::null_mut(),
744            );
745        }
746
747        Ok(Self(Value { env: env.ptr, ptr }))
748    }
749
750    extern "C" fn call(env: *mut js_env_t, info: *mut js_callback_info_t) -> *mut js_value_t {
751        let mut len: usize = 0;
752        let mut receiver: *mut js_value_t = ptr::null_mut();
753        let mut data: *mut c_void = ptr::null_mut();
754
755        unsafe {
756            js_get_callback_info(
757                env,
758                info,
759                &mut len,
760                ptr::null_mut(),
761                &mut receiver,
762                &mut data,
763            );
764        }
765
766        let mut args = Vec::new();
767
768        args.resize(len, ptr::null_mut());
769
770        if len > 0 {
771            unsafe {
772                js_get_callback_info(
773                    env,
774                    info,
775                    &mut len,
776                    args.as_mut_ptr(),
777                    ptr::null_mut(),
778                    ptr::null_mut(),
779                );
780            }
781        }
782
783        let closure =
784            unsafe { &mut *(data as *mut Box<dyn FnMut(&Env, &Callback) -> *mut js_value_t>) };
785
786        return closure(
787            &Env::from(env),
788            &Callback {
789                env,
790                args,
791                receiver,
792            },
793        );
794    }
795
796    extern "C" fn drop(_: *mut js_env_t, data: *mut c_void, _: *mut c_void) -> () {
797        unsafe {
798            drop(Box::from_raw(data));
799        }
800    }
801}
802
803impl From<Function> for *mut js_value_t {
804    fn from(function: Function) -> Self {
805        function.0.ptr
806    }
807}
808
809impl From<Value> for Function {
810    fn from(value: Value) -> Self {
811        Self(value)
812    }
813}
814
815#[derive(Debug)]
816pub struct ArrayBuffer(Value);
817
818impl ArrayBuffer {
819    pub fn new(env: &Env, len: usize) -> Result<Self> {
820        let mut ptr: *mut js_value_t = ptr::null_mut();
821
822        let status = unsafe { js_create_arraybuffer(env.ptr, len, ptr::null_mut(), &mut ptr) };
823
824        check_status!(env, status);
825
826        Ok(Self(Value { env: env.ptr, ptr }))
827    }
828
829    pub fn as_slice(&self) -> &[u8] {
830        self.as_mut_slice()
831    }
832
833    pub fn as_mut_slice(&self) -> &mut [u8] {
834        let mut len: usize = 0;
835        let mut data: *mut c_void = ptr::null_mut();
836
837        unsafe {
838            js_get_arraybuffer_info(self.0.env, self.0.ptr, &mut data, &mut len);
839        }
840
841        unsafe { slice::from_raw_parts_mut(data as *mut u8, len) }
842    }
843}
844
845impl From<ArrayBuffer> for *mut js_value_t {
846    fn from(arraybuffer: ArrayBuffer) -> Self {
847        arraybuffer.0.ptr
848    }
849}
850
851impl From<Value> for ArrayBuffer {
852    fn from(value: Value) -> Self {
853        Self(value)
854    }
855}
856
857pub trait TypedArray<T> {
858    fn as_slice(&self) -> &[T];
859    fn as_mut_slice(&self) -> &mut [T];
860}
861
862macro_rules! define_typedarray {
863    ($name:ident, $type:ident, $kind:ident) => {
864        #[derive(Debug)]
865        pub struct $name(Value);
866
867        impl $name {
868            pub fn new(env: &Env, len: usize) -> Result<Self> {
869                let arraybuffer = ArrayBuffer::new(env, len * size_of::<$type>())?;
870
871                let mut ptr: *mut js_value_t = ptr::null_mut();
872
873                let status = unsafe {
874                    js_create_typedarray(
875                        env.ptr,
876                        js_typedarray_type_t::$kind,
877                        len,
878                        arraybuffer.0.ptr,
879                        0,
880                        &mut ptr,
881                    )
882                };
883
884                check_status!(env, status);
885
886                Ok(Self(Value { env: env.ptr, ptr }))
887            }
888        }
889
890        impl TypedArray<$type> for $name {
891            fn as_slice(&self) -> &[$type] {
892                self.as_mut_slice()
893            }
894
895            fn as_mut_slice(&self) -> &mut [$type] {
896                let mut len: usize = 0;
897                let mut data: *mut c_void = ptr::null_mut();
898
899                unsafe {
900                    js_get_typedarray_info(
901                        self.0.env,
902                        self.0.ptr,
903                        ptr::null_mut(),
904                        &mut data,
905                        &mut len,
906                        ptr::null_mut(),
907                        ptr::null_mut(),
908                    );
909                }
910
911                unsafe { slice::from_raw_parts_mut(data as *mut $type, len) }
912            }
913        }
914
915        impl From<$name> for *mut js_value_t {
916            fn from(typedarray: $name) -> Self {
917                typedarray.0.ptr
918            }
919        }
920
921        impl From<Value> for $name {
922            fn from(value: Value) -> Self {
923                Self(value)
924            }
925        }
926    };
927}
928
929define_typedarray!(Int8Array, i8, js_int8array);
930define_typedarray!(Uint8Array, u8, js_uint8array);
931define_typedarray!(Uint8ClampedArray, u8, js_uint8clampedarray);
932define_typedarray!(Int16Array, i16, js_int16array);
933define_typedarray!(Uint16Array, u16, js_uint16array);
934define_typedarray!(Int32Array, i32, js_int32array);
935define_typedarray!(Uint32Array, u32, js_uint32array);
936define_typedarray!(Float32Array, f32, js_float32array);
937define_typedarray!(Float64Array, f64, js_float64array);
938define_typedarray!(BigInt64Array, i32, js_bigint64array);
939define_typedarray!(BigUint64Array, u32, js_biguint64array);
940
941macro_rules! define_error {
942    ($name:ident, $create:ident) => {
943        #[derive(Debug)]
944        pub struct $name(Value);
945
946        impl $name {
947            pub fn new(env: &Env, message: &str) -> Self {
948                let message = String::new(env, message).unwrap();
949
950                let mut ptr: *mut js_value_t = std::ptr::null_mut();
951
952                unsafe {
953                    $create(env.ptr, std::ptr::null_mut(), message.0.ptr, &mut ptr);
954                }
955
956                Self(Value { env: env.ptr, ptr })
957            }
958        }
959
960        impl From<$name> for *mut js_value_t {
961            fn from(error: $name) -> Self {
962                error.0.ptr
963            }
964        }
965
966        impl From<Value> for $name {
967            fn from(value: Value) -> Self {
968                Self(value)
969            }
970        }
971    };
972}
973
974define_error!(Error, js_create_error);
975define_error!(TypeError, js_create_type_error);
976define_error!(RangeError, js_create_range_error);
977define_error!(SyntaxError, js_create_syntax_error);
978define_error!(ReferenceError, js_create_reference_error);