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