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);