1use std::cell::Cell;
8use std::char;
9use std::default::Default;
10use std::ffi::{CStr, CString};
11use std::marker::PhantomData;
12use std::mem::MaybeUninit;
13use std::ops::{Deref, DerefMut};
14use std::ptr::{self, NonNull};
15use std::slice;
16use std::str;
17use std::sync::atomic::{AtomicU32, Ordering};
18use std::sync::{Arc, Mutex, RwLock};
19
20use self::wrappers::{
21 StackGCVectorStringAtIndex, StackGCVectorStringLength, StackGCVectorValueAtIndex,
22 StackGCVectorValueLength,
23};
24use crate::consts::{JSCLASS_GLOBAL_SLOT_COUNT, JSCLASS_RESERVED_SLOTS_MASK};
25use crate::consts::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL};
26use crate::conversions::jsstr_to_string;
27use crate::default_heapsize;
28pub use crate::gc::*;
29use crate::glue::AppendToRootedObjectVector;
30use crate::glue::{CreateRootedIdVector, CreateRootedObjectVector};
31use crate::glue::{
32 DeleteCompileOptions, DeleteRootedObjectVector, DescribeScriptedCaller, DestroyRootedIdVector,
33};
34use crate::glue::{DeleteJSAutoStructuredCloneBuffer, NewJSAutoStructuredCloneBuffer};
35use crate::glue::{
36 GetIdVectorAddress, GetObjectVectorAddress, NewCompileOptions, SliceRootedIdVector,
37};
38use crate::jsapi;
39use crate::jsapi::glue::{DeleteRealmOptions, JS_Init, JS_NewRealmOptions};
40use crate::jsapi::js;
41use crate::jsapi::js::frontend::InitialStencilAndDelazifications;
42use crate::jsapi::mozilla::Utf8Unit;
43use crate::jsapi::shadow::BaseShape;
44use crate::jsapi::HandleObjectVector as RawHandleObjectVector;
45use crate::jsapi::HandleValue as RawHandleValue;
46use crate::jsapi::JS_AddExtraGCRootsTracer;
47use crate::jsapi::MutableHandleIdVector as RawMutableHandleIdVector;
48use crate::jsapi::{already_AddRefed, jsid};
49use crate::jsapi::{BuildStackString, CaptureCurrentStack, StackFormat};
50use crate::jsapi::{HandleValueArray, StencilRelease};
51use crate::jsapi::{InitSelfHostedCode, IsWindowSlow};
52use crate::jsapi::{JSAutoStructuredCloneBuffer, JSStructuredCloneCallbacks, StructuredCloneScope};
53use crate::jsapi::{JSClass, JSClassOps, JSContext, Realm, JSCLASS_RESERVED_SLOTS_SHIFT};
54use crate::jsapi::{JSErrorReport, JSFunctionSpec, JSGCParamKey};
55use crate::jsapi::{JSObject, JSPropertySpec, JSRuntime};
56use crate::jsapi::{JSString, Object, PersistentRootedIdVector};
57use crate::jsapi::{JS_DefineFunctions, JS_DefineProperties, JS_DestroyContext, JS_ShutDown};
58use crate::jsapi::{JS_EnumerateStandardClasses, JS_GlobalObjectTraceHook};
59use crate::jsapi::{JS_MayResolveStandardClass, JS_NewContext, JS_ResolveStandardClass};
60use crate::jsapi::{JS_RequestInterruptCallback, JS_RequestInterruptCallbackCanWait};
61use crate::jsapi::{JS_SetGCParameter, JS_SetNativeStackQuota, JS_WrapObject, JS_WrapValue};
62use crate::jsapi::{JS_StackCapture_AllFrames, JS_StackCapture_MaxFrames};
63use crate::jsapi::{PersistentRootedObjectVector, ReadOnlyCompileOptions, RootingContext};
64use crate::jsapi::{SetWarningReporter, SourceText, ToBooleanSlow};
65use crate::jsapi::{ToInt32Slow, ToInt64Slow, ToNumberSlow, ToStringSlow, ToUint16Slow};
66use crate::jsapi::{ToUint32Slow, ToUint64Slow, ToWindowProxyIfWindowSlow};
67use crate::jsval::{JSVal, ObjectValue};
68use crate::panic::maybe_resume_unwind;
69use crate::realm::AutoRealm;
70use log::{debug, warn};
71use mozjs_sys::jsapi::JS::SavedFrameResult;
72pub use mozjs_sys::jsgc::{GCMethods, IntoHandle, IntoMutableHandle};
73pub use mozjs_sys::trace::Traceable as Trace;
74
75use crate::rooted;
76
77const STACK_QUOTA: usize = 128 * 8 * 1024;
81
82const SYSTEM_CODE_BUFFER: usize = 10 * 1024;
108
109const TRUSTED_SCRIPT_BUFFER: usize = 8 * 12800;
111
112trait ToResult {
113 fn to_result(self) -> Result<(), ()>;
114}
115
116impl ToResult for bool {
117 fn to_result(self) -> Result<(), ()> {
118 if self {
119 Ok(())
120 } else {
121 Err(())
122 }
123 }
124}
125
126pub struct RealmOptions(*mut jsapi::RealmOptions);
130
131impl Deref for RealmOptions {
132 type Target = jsapi::RealmOptions;
133 fn deref(&self) -> &Self::Target {
134 unsafe { &*self.0 }
135 }
136}
137
138impl DerefMut for RealmOptions {
139 fn deref_mut(&mut self) -> &mut Self::Target {
140 unsafe { &mut *self.0 }
141 }
142}
143
144impl Default for RealmOptions {
145 fn default() -> RealmOptions {
146 RealmOptions(unsafe { JS_NewRealmOptions() })
147 }
148}
149
150impl Drop for RealmOptions {
151 fn drop(&mut self) {
152 unsafe { DeleteRealmOptions(self.0) }
153 }
154}
155
156thread_local!(static CONTEXT: Cell<Option<NonNull<JSContext>>> = Cell::new(None));
157
158#[derive(PartialEq)]
159enum EngineState {
160 Uninitialized,
161 InitFailed,
162 Initialized,
163 ShutDown,
164}
165
166static ENGINE_STATE: Mutex<EngineState> = Mutex::new(EngineState::Uninitialized);
167
168#[derive(Debug)]
169pub enum JSEngineError {
170 AlreadyInitialized,
171 AlreadyShutDown,
172 InitFailed,
173}
174
175pub struct JSEngine {
179 outstanding_handles: Arc<AtomicU32>,
181 marker: PhantomData<*mut ()>,
183}
184
185pub struct JSEngineHandle(Arc<AtomicU32>);
186
187impl Clone for JSEngineHandle {
188 fn clone(&self) -> JSEngineHandle {
189 self.0.fetch_add(1, Ordering::SeqCst);
190 JSEngineHandle(self.0.clone())
191 }
192}
193
194impl Drop for JSEngineHandle {
195 fn drop(&mut self) {
196 self.0.fetch_sub(1, Ordering::SeqCst);
197 }
198}
199
200impl JSEngine {
201 pub fn init() -> Result<JSEngine, JSEngineError> {
203 let mut state = ENGINE_STATE.lock().unwrap();
204 match *state {
205 EngineState::Initialized => return Err(JSEngineError::AlreadyInitialized),
206 EngineState::InitFailed => return Err(JSEngineError::InitFailed),
207 EngineState::ShutDown => return Err(JSEngineError::AlreadyShutDown),
208 EngineState::Uninitialized => (),
209 }
210 if unsafe { !JS_Init() } {
211 *state = EngineState::InitFailed;
212 Err(JSEngineError::InitFailed)
213 } else {
214 *state = EngineState::Initialized;
215 Ok(JSEngine {
216 outstanding_handles: Arc::new(AtomicU32::new(0)),
217 marker: PhantomData,
218 })
219 }
220 }
221
222 pub fn can_shutdown(&self) -> bool {
223 self.outstanding_handles.load(Ordering::SeqCst) == 0
224 }
225
226 pub fn handle(&self) -> JSEngineHandle {
228 self.outstanding_handles.fetch_add(1, Ordering::SeqCst);
229 JSEngineHandle(self.outstanding_handles.clone())
230 }
231}
232
233impl Drop for JSEngine {
236 fn drop(&mut self) {
237 let mut state = ENGINE_STATE.lock().unwrap();
238 if *state == EngineState::Initialized {
239 assert_eq!(
240 self.outstanding_handles.load(Ordering::SeqCst),
241 0,
242 "There are outstanding JS engine handles"
243 );
244 *state = EngineState::ShutDown;
245 unsafe {
246 JS_ShutDown();
247 }
248 }
249 }
250}
251
252pub fn transform_str_to_source_text(source: &str) -> SourceText<Utf8Unit> {
253 SourceText {
254 units_: source.as_ptr() as *const _,
255 length_: source.len() as u32,
256 ownsUnits_: false,
257 _phantom_0: PhantomData,
258 }
259}
260
261pub fn transform_u16_to_source_text(source: &[u16]) -> SourceText<u16> {
262 SourceText {
263 units_: source.as_ptr() as *const _,
264 length_: source.len() as u32,
265 ownsUnits_: false,
266 _phantom_0: PhantomData,
267 }
268}
269
270pub struct ParentRuntime {
274 parent: *mut JSRuntime,
276 engine: JSEngineHandle,
278 children_of_parent: Arc<()>,
280}
281unsafe impl Send for ParentRuntime {}
282
283pub struct Runtime {
285 cx: crate::context::JSContext,
287 engine: JSEngineHandle,
289 _parent_child_count: Option<Arc<()>>,
294 outstanding_children: Arc<()>,
300 thread_safe_handle: Arc<RwLock<Option<NonNull<JSContext>>>>,
304}
305
306impl Runtime {
307 pub fn get() -> Option<NonNull<JSContext>> {
311 CONTEXT.with(|context| context.get())
312 }
313
314 pub fn thread_safe_js_context(&self) -> ThreadSafeJSContext {
316 ThreadSafeJSContext(self.thread_safe_handle.clone())
319 }
320
321 pub fn new(engine: JSEngineHandle) -> Runtime {
323 unsafe { Self::create(engine, None) }
324 }
325
326 pub fn prepare_for_new_child(&self) -> ParentRuntime {
332 ParentRuntime {
333 parent: self.rt(),
334 engine: self.engine.clone(),
335 children_of_parent: self.outstanding_children.clone(),
336 }
337 }
338
339 pub unsafe fn create_with_parent(parent: ParentRuntime) -> Runtime {
347 Self::create(parent.engine.clone(), Some(parent))
348 }
349
350 unsafe fn create(engine: JSEngineHandle, parent: Option<ParentRuntime>) -> Runtime {
351 let parent_runtime = parent.as_ref().map_or(ptr::null_mut(), |r| r.parent);
352 let js_context = NonNull::new(JS_NewContext(
353 default_heapsize + (ChunkSize as u32),
354 parent_runtime,
355 ))
356 .unwrap();
357
358 JS_SetGCParameter(js_context.as_ptr(), JSGCParamKey::JSGC_MAX_BYTES, u32::MAX);
364
365 JS_AddExtraGCRootsTracer(js_context.as_ptr(), Some(trace_traceables), ptr::null_mut());
366
367 JS_SetNativeStackQuota(
368 js_context.as_ptr(),
369 STACK_QUOTA,
370 STACK_QUOTA - SYSTEM_CODE_BUFFER,
371 STACK_QUOTA - SYSTEM_CODE_BUFFER - TRUSTED_SCRIPT_BUFFER,
372 );
373
374 CONTEXT.with(|context| {
375 assert!(context.get().is_none());
376 context.set(Some(js_context));
377 });
378
379 #[cfg(target_pointer_width = "64")]
380 let cache = crate::jsapi::__BindgenOpaqueArray::<u64, 2>::default();
381 #[cfg(target_pointer_width = "32")]
382 let cache = crate::jsapi::__BindgenOpaqueArray::<u32, 2>::default();
383
384 InitSelfHostedCode(js_context.as_ptr(), cache, None);
385
386 SetWarningReporter(js_context.as_ptr(), Some(report_warning));
387
388 Runtime {
389 engine,
390 _parent_child_count: parent.map(|p| p.children_of_parent),
391 cx: crate::context::JSContext::from_ptr(js_context),
392 outstanding_children: Arc::new(()),
393 thread_safe_handle: Arc::new(RwLock::new(Some(js_context))),
394 }
395 }
396
397 pub fn rt(&self) -> *mut JSRuntime {
399 unsafe { wrappers2::JS_GetRuntime(self.cx_no_gc()) }
400 }
401
402 pub fn cx<'rt>(&'rt mut self) -> &'rt mut crate::context::JSContext {
404 &mut self.cx
405 }
406
407 pub fn cx_no_gc<'rt>(&'rt self) -> &'rt crate::context::JSContext {
409 &self.cx
410 }
411}
412
413pub fn evaluate_script(
414 cx: &mut crate::context::JSContext,
415 glob: HandleObject,
416 script: &str,
417 rval: MutableHandleValue,
418 options: CompileOptionsWrapper,
419) -> Result<(), ()> {
420 debug!(
421 "Evaluating script from {} with content {}",
422 options.filename(),
423 script
424 );
425
426 let mut realm = AutoRealm::new_from_handle(cx, glob);
427
428 unsafe {
429 let mut source = transform_str_to_source_text(&script);
430 if !wrappers2::Evaluate2(&mut realm, options.ptr, &mut source, rval.into()) {
431 debug!("...err!");
432 maybe_resume_unwind();
433 Err(())
434 } else {
435 debug!("...ok!");
438 Ok(())
439 }
440 }
441}
442
443impl Drop for Runtime {
444 fn drop(&mut self) {
445 self.thread_safe_handle.write().unwrap().take();
446 assert!(
447 Arc::get_mut(&mut self.outstanding_children).is_some(),
448 "This runtime still has live children."
449 );
450 unsafe {
451 JS_DestroyContext(self.cx.raw_cx());
452
453 CONTEXT.with(|context| {
454 assert!(context.take().is_some());
455 });
456 }
457 }
458}
459
460#[derive(Clone)]
464pub struct ThreadSafeJSContext(Arc<RwLock<Option<NonNull<JSContext>>>>);
465
466unsafe impl Send for ThreadSafeJSContext {}
467unsafe impl Sync for ThreadSafeJSContext {}
468
469impl ThreadSafeJSContext {
470 pub fn request_interrupt_callback(&self) {
474 if let Some(cx) = self.0.read().unwrap().as_ref() {
475 unsafe {
476 JS_RequestInterruptCallback(cx.as_ptr());
477 }
478 }
479 }
480
481 pub fn request_interrupt_callback_can_wait(&self) {
485 if let Some(cx) = self.0.read().unwrap().as_ref() {
486 unsafe {
487 JS_RequestInterruptCallbackCanWait(cx.as_ptr());
488 }
489 }
490 }
491}
492
493const ChunkShift: usize = 20;
494const ChunkSize: usize = 1 << ChunkShift;
495
496#[cfg(target_pointer_width = "32")]
497const ChunkLocationOffset: usize = ChunkSize - 2 * 4 - 8;
498
499pub struct RootedObjectVectorWrapper {
503 pub ptr: *mut PersistentRootedObjectVector,
504}
505
506impl RootedObjectVectorWrapper {
507 pub fn new(cx: *mut JSContext) -> RootedObjectVectorWrapper {
508 RootedObjectVectorWrapper {
509 ptr: unsafe { CreateRootedObjectVector(cx) },
510 }
511 }
512
513 pub fn append(&self, obj: *mut JSObject) -> bool {
514 unsafe { AppendToRootedObjectVector(self.ptr, obj) }
515 }
516
517 pub fn handle(&self) -> RawHandleObjectVector {
518 RawHandleObjectVector {
519 ptr: unsafe { GetObjectVectorAddress(self.ptr) },
520 }
521 }
522}
523
524impl Drop for RootedObjectVectorWrapper {
525 fn drop(&mut self) {
526 unsafe { DeleteRootedObjectVector(self.ptr) }
527 }
528}
529
530pub struct CompileOptionsWrapper {
531 pub ptr: *mut ReadOnlyCompileOptions,
532 filename: CString,
533}
534
535impl CompileOptionsWrapper {
536 pub fn new(cx: &crate::context::JSContext, filename: &str, line: u32) -> Self {
537 let filename = CString::new(filename.as_bytes()).unwrap();
538 let ptr = unsafe { wrappers2::NewCompileOptions(cx, filename.as_ptr(), line) };
539 assert!(!ptr.is_null());
540 Self { ptr, filename }
541 }
542 pub unsafe fn new_raw(cx: *mut JSContext, filename: &str, line: u32) -> Self {
546 let filename = CString::new(filename.as_bytes()).unwrap();
547 let ptr = NewCompileOptions(cx, filename.as_ptr(), line);
548 assert!(!ptr.is_null());
549 Self { ptr, filename }
550 }
551
552 pub fn filename(&self) -> &str {
553 self.filename.to_str().expect("Guaranteed by new")
554 }
555
556 pub fn set_introduction_type(&mut self, introduction_type: &'static CStr) {
557 unsafe {
558 (*self.ptr)._base.introductionType = introduction_type.as_ptr();
559 }
560 }
561}
562
563impl Drop for CompileOptionsWrapper {
564 fn drop(&mut self) {
565 unsafe { DeleteCompileOptions(self.ptr) }
566 }
567}
568
569pub struct JSAutoStructuredCloneBufferWrapper {
570 ptr: NonNull<JSAutoStructuredCloneBuffer>,
571}
572
573impl JSAutoStructuredCloneBufferWrapper {
574 pub unsafe fn new(
575 scope: StructuredCloneScope,
576 callbacks: *const JSStructuredCloneCallbacks,
577 ) -> Self {
578 let raw_ptr = NewJSAutoStructuredCloneBuffer(scope, callbacks);
579 Self {
580 ptr: NonNull::new(raw_ptr).unwrap(),
581 }
582 }
583
584 pub fn as_raw_ptr(&self) -> *mut JSAutoStructuredCloneBuffer {
585 self.ptr.as_ptr()
586 }
587}
588
589impl Drop for JSAutoStructuredCloneBufferWrapper {
590 fn drop(&mut self) {
591 unsafe {
592 DeleteJSAutoStructuredCloneBuffer(self.ptr.as_ptr());
593 }
594 }
595}
596
597pub struct Stencil {
598 inner: already_AddRefed<InitialStencilAndDelazifications>,
599}
600
601impl Drop for Stencil {
605 fn drop(&mut self) {
606 if self.is_null() {
607 return;
608 }
609 unsafe {
610 StencilRelease(self.inner.mRawPtr);
611 }
612 }
613}
614
615impl Deref for Stencil {
616 type Target = *mut InitialStencilAndDelazifications;
617
618 fn deref(&self) -> &Self::Target {
619 &self.inner.mRawPtr
620 }
621}
622
623impl Stencil {
624 pub fn is_null(&self) -> bool {
625 self.inner.mRawPtr.is_null()
626 }
627}
628
629#[inline]
633pub unsafe fn ToBoolean(v: HandleValue) -> bool {
634 let val = *v.ptr;
635
636 if val.is_boolean() {
637 return val.to_boolean();
638 }
639
640 if val.is_int32() {
641 return val.to_int32() != 0;
642 }
643
644 if val.is_null_or_undefined() {
645 return false;
646 }
647
648 if val.is_double() {
649 let d = val.to_double();
650 return !d.is_nan() && d != 0f64;
651 }
652
653 if val.is_symbol() {
654 return true;
655 }
656
657 ToBooleanSlow(v.into())
658}
659
660#[inline]
661pub unsafe fn ToNumber(cx: *mut JSContext, v: HandleValue) -> Result<f64, ()> {
662 let val = *v.ptr;
663 if val.is_number() {
664 return Ok(val.to_number());
665 }
666
667 let mut out = Default::default();
668 if ToNumberSlow(cx, v.into_handle(), &mut out) {
669 Ok(out)
670 } else {
671 Err(())
672 }
673}
674
675#[inline]
676unsafe fn convert_from_int32<T: Default + Copy>(
677 cx: *mut JSContext,
678 v: HandleValue,
679 conv_fn: unsafe extern "C" fn(*mut JSContext, RawHandleValue, *mut T) -> bool,
680) -> Result<T, ()> {
681 let val = *v.ptr;
682 if val.is_int32() {
683 let intval: i64 = val.to_int32() as i64;
684 let intval = *(&intval as *const i64 as *const T);
686 return Ok(intval);
687 }
688
689 let mut out = Default::default();
690 if conv_fn(cx, v.into(), &mut out) {
691 Ok(out)
692 } else {
693 Err(())
694 }
695}
696
697#[inline]
698pub unsafe fn ToInt32(cx: *mut JSContext, v: HandleValue) -> Result<i32, ()> {
699 convert_from_int32::<i32>(cx, v, ToInt32Slow)
700}
701
702#[inline]
703pub unsafe fn ToUint32(cx: *mut JSContext, v: HandleValue) -> Result<u32, ()> {
704 convert_from_int32::<u32>(cx, v, ToUint32Slow)
705}
706
707#[inline]
708pub unsafe fn ToUint16(cx: *mut JSContext, v: HandleValue) -> Result<u16, ()> {
709 convert_from_int32::<u16>(cx, v, ToUint16Slow)
710}
711
712#[inline]
713pub unsafe fn ToInt64(cx: *mut JSContext, v: HandleValue) -> Result<i64, ()> {
714 convert_from_int32::<i64>(cx, v, ToInt64Slow)
715}
716
717#[inline]
718pub unsafe fn ToUint64(cx: *mut JSContext, v: HandleValue) -> Result<u64, ()> {
719 convert_from_int32::<u64>(cx, v, ToUint64Slow)
720}
721
722#[inline]
723pub unsafe fn ToString(cx: *mut JSContext, v: HandleValue) -> *mut JSString {
724 let val = *v.ptr;
725 if val.is_string() {
726 return val.to_string();
727 }
728
729 ToStringSlow(cx, v.into())
730}
731
732pub unsafe fn ToWindowProxyIfWindow(obj: *mut JSObject) -> *mut JSObject {
733 if is_window(obj) {
734 ToWindowProxyIfWindowSlow(obj)
735 } else {
736 obj
737 }
738}
739
740pub unsafe extern "C" fn report_warning(_cx: *mut JSContext, report: *mut JSErrorReport) {
741 fn latin1_to_string(bytes: &[u8]) -> String {
742 bytes
743 .iter()
744 .map(|c| char::from_u32(*c as u32).unwrap())
745 .collect()
746 }
747
748 let fnptr = (*report)._base.filename.data_;
749 let fname = if !fnptr.is_null() {
750 let c_str = CStr::from_ptr(fnptr);
751 latin1_to_string(c_str.to_bytes())
752 } else {
753 "none".to_string()
754 };
755
756 let lineno = (*report)._base.lineno;
757 let column = (*report)._base.column._base;
758
759 let msg_ptr = (*report)._base.message_.data_ as *const u8;
760 let msg_len = (0usize..)
761 .find(|&i| *msg_ptr.offset(i as isize) == 0)
762 .unwrap();
763 let msg_slice = slice::from_raw_parts(msg_ptr, msg_len);
764 let msg = str::from_utf8_unchecked(msg_slice);
765
766 warn!("Warning at {}:{}:{}: {}\n", fname, lineno, column, msg);
767}
768
769pub struct IdVector(*mut PersistentRootedIdVector);
770
771impl IdVector {
772 pub unsafe fn new(cx: *mut JSContext) -> IdVector {
773 let vector = CreateRootedIdVector(cx);
774 assert!(!vector.is_null());
775 IdVector(vector)
776 }
777
778 pub fn handle_mut(&mut self) -> RawMutableHandleIdVector {
779 RawMutableHandleIdVector {
780 ptr: unsafe { GetIdVectorAddress(self.0) },
781 }
782 }
783}
784
785impl Drop for IdVector {
786 fn drop(&mut self) {
787 unsafe { DestroyRootedIdVector(self.0) }
788 }
789}
790
791impl Deref for IdVector {
792 type Target = [jsid];
793
794 fn deref(&self) -> &[jsid] {
795 unsafe {
796 let mut length = 0;
797 let pointer = SliceRootedIdVector(self.0, &mut length);
798 slice::from_raw_parts(pointer, length)
799 }
800 }
801}
802
803pub unsafe fn define_methods(
819 cx: *mut JSContext,
820 obj: HandleObject,
821 methods: &'static [JSFunctionSpec],
822) -> Result<(), ()> {
823 assert!({
824 match methods.last() {
825 Some(&JSFunctionSpec {
826 name,
827 call,
828 nargs,
829 flags,
830 selfHostedName,
831 }) => {
832 name.string_.is_null()
833 && call.is_zeroed()
834 && nargs == 0
835 && flags == 0
836 && selfHostedName.is_null()
837 }
838 None => false,
839 }
840 });
841
842 JS_DefineFunctions(cx, obj.into(), methods.as_ptr()).to_result()
843}
844
845pub unsafe fn define_properties(
861 cx: *mut JSContext,
862 obj: HandleObject,
863 properties: &'static [JSPropertySpec],
864) -> Result<(), ()> {
865 assert!({
866 match properties.last() {
867 Some(spec) => spec.is_zeroed(),
868 None => false,
869 }
870 });
871
872 JS_DefineProperties(cx, obj.into(), properties.as_ptr()).to_result()
873}
874
875static SIMPLE_GLOBAL_CLASS_OPS: JSClassOps = JSClassOps {
876 addProperty: None,
877 delProperty: None,
878 enumerate: Some(JS_EnumerateStandardClasses),
879 newEnumerate: None,
880 resolve: Some(JS_ResolveStandardClass),
881 mayResolve: Some(JS_MayResolveStandardClass),
882 finalize: None,
883 call: None,
884 construct: None,
885 trace: Some(JS_GlobalObjectTraceHook),
886};
887
888pub static SIMPLE_GLOBAL_CLASS: JSClass = JSClass {
890 name: c"Global".as_ptr(),
891 flags: JSCLASS_IS_GLOBAL
892 | ((JSCLASS_GLOBAL_SLOT_COUNT & JSCLASS_RESERVED_SLOTS_MASK)
893 << JSCLASS_RESERVED_SLOTS_SHIFT),
894 cOps: &SIMPLE_GLOBAL_CLASS_OPS as *const JSClassOps,
895 spec: ptr::null(),
896 ext: ptr::null(),
897 oOps: ptr::null(),
898};
899
900#[inline]
901unsafe fn get_object_group(obj: *mut JSObject) -> *mut BaseShape {
902 assert!(!obj.is_null());
903 let obj = obj as *mut Object;
904 (*(*obj).shape).base
905}
906
907#[inline]
908pub unsafe fn get_object_class(obj: *mut JSObject) -> *const JSClass {
909 (*get_object_group(obj)).clasp as *const _
910}
911
912#[inline]
913pub unsafe fn get_object_realm(obj: *mut JSObject) -> *mut Realm {
914 (*get_object_group(obj)).realm
915}
916
917#[inline]
918pub unsafe fn get_context_realm(cx: *mut JSContext) -> *mut Realm {
919 let cx = cx as *mut RootingContext;
920 (*cx).realm_
921}
922
923#[inline]
924pub fn is_dom_class(class: &JSClass) -> bool {
925 class.flags & JSCLASS_IS_DOMJSCLASS != 0
926}
927
928#[inline]
929pub unsafe fn is_dom_object(obj: *mut JSObject) -> bool {
930 is_dom_class(&*get_object_class(obj))
931}
932
933#[inline]
934pub unsafe fn is_window(obj: *mut JSObject) -> bool {
935 (*get_object_class(obj)).flags & JSCLASS_IS_GLOBAL != 0 && IsWindowSlow(obj)
936}
937
938#[inline]
939pub unsafe fn try_to_outerize(mut rval: MutableHandleValue) {
940 let obj = rval.to_object();
941 if is_window(obj) {
942 let obj = ToWindowProxyIfWindowSlow(obj);
943 assert!(!obj.is_null());
944 rval.set(ObjectValue(&mut *obj));
945 }
946}
947
948#[inline]
949pub unsafe fn try_to_outerize_object(mut rval: MutableHandleObject) {
950 if is_window(*rval) {
951 let obj = ToWindowProxyIfWindowSlow(*rval);
952 assert!(!obj.is_null());
953 rval.set(obj);
954 }
955}
956
957#[inline]
958pub unsafe fn maybe_wrap_object(cx: *mut JSContext, mut obj: MutableHandleObject) {
959 if get_object_realm(*obj) != get_context_realm(cx) {
960 assert!(JS_WrapObject(cx, obj.reborrow().into()));
961 }
962 try_to_outerize_object(obj);
963}
964
965#[inline]
966pub unsafe fn maybe_wrap_object_value(cx: *mut JSContext, rval: MutableHandleValue) {
967 assert!(rval.is_object());
968 let obj = rval.to_object();
969 if get_object_realm(obj) != get_context_realm(cx) {
970 assert!(JS_WrapValue(cx, rval.into()));
971 } else if is_dom_object(obj) {
972 try_to_outerize(rval);
973 }
974}
975
976#[inline]
977pub unsafe fn maybe_wrap_object_or_null_value(cx: *mut JSContext, rval: MutableHandleValue) {
978 assert!(rval.is_object_or_null());
979 if !rval.is_null() {
980 maybe_wrap_object_value(cx, rval);
981 }
982}
983
984#[inline]
985pub unsafe fn maybe_wrap_value(cx: *mut JSContext, rval: MutableHandleValue) {
986 if rval.is_string() {
987 assert!(JS_WrapValue(cx, rval.into()));
988 } else if rval.is_object() {
989 maybe_wrap_object_value(cx, rval);
990 }
991}
992
993#[macro_export]
995macro_rules! new_jsjitinfo_bitfield_1 {
996 (
997 $type_: expr,
998 $aliasSet_: expr,
999 $returnType_: expr,
1000 $isInfallible: expr,
1001 $isMovable: expr,
1002 $isEliminatable: expr,
1003 $isAlwaysInSlot: expr,
1004 $isLazilyCachedInSlot: expr,
1005 $isTypedMethod: expr,
1006 $slotIndex: expr,
1007 ) => {
1008 0 | (($type_ as u32) << 0u32)
1009 | (($aliasSet_ as u32) << 4u32)
1010 | (($returnType_ as u32) << 8u32)
1011 | (($isInfallible as u32) << 16u32)
1012 | (($isMovable as u32) << 17u32)
1013 | (($isEliminatable as u32) << 18u32)
1014 | (($isAlwaysInSlot as u32) << 19u32)
1015 | (($isLazilyCachedInSlot as u32) << 20u32)
1016 | (($isTypedMethod as u32) << 21u32)
1017 | (($slotIndex as u32) << 22u32)
1018 };
1019}
1020
1021#[derive(Debug, Default)]
1022pub struct ScriptedCaller {
1023 pub filename: String,
1024 pub line: u32,
1025 pub col: u32,
1026}
1027
1028pub unsafe fn describe_scripted_caller(cx: *mut JSContext) -> Result<ScriptedCaller, ()> {
1029 let mut buf = [0; 1024];
1030 let mut line = 0;
1031 let mut col = 0;
1032 if !DescribeScriptedCaller(cx, buf.as_mut_ptr(), buf.len(), &mut line, &mut col) {
1033 return Err(());
1034 }
1035 let filename = CStr::from_ptr((&buf) as *const _ as *const _);
1036 Ok(ScriptedCaller {
1037 filename: String::from_utf8_lossy(filename.to_bytes()).into_owned(),
1038 line,
1039 col,
1040 })
1041}
1042
1043pub struct CapturedJSStack<'a> {
1044 cx: *mut JSContext,
1045 stack: RootedGuard<'a, *mut JSObject>,
1046}
1047
1048impl<'a> CapturedJSStack<'a> {
1049 pub unsafe fn new(
1050 cx: *mut JSContext,
1051 mut guard: RootedGuard<'a, *mut JSObject>,
1052 max_frame_count: Option<u32>,
1053 ) -> Option<Self> {
1054 let ref mut stack_capture = MaybeUninit::uninit();
1055 match max_frame_count {
1056 None => JS_StackCapture_AllFrames(stack_capture.as_mut_ptr()),
1057 Some(count) => JS_StackCapture_MaxFrames(count, stack_capture.as_mut_ptr()),
1058 };
1059 let ref mut stack_capture = stack_capture.assume_init();
1060
1061 if !CaptureCurrentStack(
1062 cx,
1063 guard.handle_mut().raw(),
1064 stack_capture,
1065 HandleObject::null().into(),
1066 ) {
1067 None
1068 } else {
1069 Some(CapturedJSStack { cx, stack: guard })
1070 }
1071 }
1072
1073 pub fn as_string(&self, indent: Option<usize>, format: StackFormat) -> Option<String> {
1074 unsafe {
1075 let stack_handle = self.stack.handle();
1076 rooted!(in(self.cx) let mut js_string = ptr::null_mut::<JSString>());
1077 let mut string_handle = js_string.handle_mut();
1078
1079 if !BuildStackString(
1080 self.cx,
1081 ptr::null_mut(),
1082 stack_handle.into(),
1083 string_handle.raw(),
1084 indent.unwrap_or(0),
1085 format,
1086 ) {
1087 return None;
1088 }
1089
1090 Some(jsstr_to_string(self.cx, NonNull::new(string_handle.get())?))
1091 }
1092 }
1093
1094 pub fn for_each_stack_frame<F>(&self, mut f: F)
1096 where
1097 F: FnMut(Handle<*mut JSObject>),
1098 {
1099 rooted!(in(self.cx) let mut current_element = self.stack.clone());
1100 rooted!(in(self.cx) let mut next_element = ptr::null_mut::<JSObject>());
1101
1102 loop {
1103 f(current_element.handle());
1104
1105 unsafe {
1106 let result = jsapi::GetSavedFrameParent(
1107 self.cx,
1108 ptr::null_mut(),
1109 current_element.handle().into_handle(),
1110 next_element.handle_mut().into_handle_mut(),
1111 jsapi::SavedFrameSelfHosted::Include,
1112 );
1113
1114 if result != SavedFrameResult::Ok || next_element.is_null() {
1115 return;
1116 }
1117 }
1118 current_element.set(next_element.get());
1119 }
1120 }
1121}
1122
1123#[macro_export]
1124macro_rules! capture_stack {
1125 (&in($cx:expr) $($t:tt)*) => {
1126 capture_stack!(in(unsafe {$cx.raw_cx_no_gc()}) $($t)*);
1127 };
1128 (in($cx:expr) let $name:ident = with max depth($max_frame_count:expr)) => {
1129 rooted!(in($cx) let mut __obj = ::std::ptr::null_mut());
1130 let $name = $crate::rust::CapturedJSStack::new($cx, __obj, Some($max_frame_count));
1131 };
1132 (in($cx:expr) let $name:ident ) => {
1133 rooted!(in($cx) let mut __obj = ::std::ptr::null_mut());
1134 let $name = $crate::rust::CapturedJSStack::new($cx, __obj, None);
1135 }
1136}
1137
1138pub struct EnvironmentChain {
1139 chain: *mut crate::jsapi::JS::EnvironmentChain,
1140}
1141
1142impl EnvironmentChain {
1143 pub fn new(
1144 cx: *mut JSContext,
1145 support_unscopeables: crate::jsapi::JS::SupportUnscopables,
1146 ) -> Self {
1147 unsafe {
1148 Self {
1149 chain: crate::jsapi::glue::NewEnvironmentChain(cx, support_unscopeables),
1150 }
1151 }
1152 }
1153
1154 pub fn append(&self, obj: *mut JSObject) {
1155 unsafe {
1156 assert!(crate::jsapi::glue::AppendToEnvironmentChain(
1157 self.chain, obj
1158 ));
1159 }
1160 }
1161
1162 pub fn get(&self) -> *mut crate::jsapi::JS::EnvironmentChain {
1163 self.chain
1164 }
1165}
1166
1167impl Drop for EnvironmentChain {
1168 fn drop(&mut self) {
1169 unsafe {
1170 crate::jsapi::glue::DeleteEnvironmentChain(self.chain);
1171 }
1172 }
1173}
1174
1175impl<'a> Handle<'a, StackGCVector<JSVal, js::TempAllocPolicy>> {
1176 pub fn at(&'a self, index: u32) -> Option<Handle<'a, JSVal>> {
1177 if index >= self.len() {
1178 return None;
1179 }
1180 let handle =
1181 unsafe { Handle::from_marked_location(StackGCVectorValueAtIndex(*self, index)) };
1182 Some(handle)
1183 }
1184
1185 pub fn len(&self) -> u32 {
1186 unsafe { StackGCVectorValueLength(*self) }
1187 }
1188}
1189
1190impl<'a> Handle<'a, StackGCVector<*mut JSString, js::TempAllocPolicy>> {
1191 pub fn at(&'a self, index: u32) -> Option<Handle<'a, *mut JSString>> {
1192 if index >= self.len() {
1193 return None;
1194 }
1195 let handle =
1196 unsafe { Handle::from_marked_location(StackGCVectorStringAtIndex(*self, index)) };
1197 Some(handle)
1198 }
1199
1200 pub fn len(&self) -> u32 {
1201 unsafe { StackGCVectorStringLength(*self) }
1202 }
1203}
1204
1205pub mod wrappers {
1207 macro_rules! wrap {
1208 (@inner $saved:tt <> ($($acc:expr,)*) <> $arg:ident: *const Handle<$gentype:ty>, $($rest:tt)*) => {
1213 wrap!(@inner $saved <> ($($acc,)* if $arg.is_null() { std::ptr::null() } else { &(*$arg).into() },) <> $($rest)*);
1214 };
1215 (@inner $saved:tt <> ($($acc:expr,)*) <> $arg:ident: Handle<$gentype:ty>, $($rest:tt)*) => {
1216 wrap!(@inner $saved <> ($($acc,)* $arg.into(),) <> $($rest)*);
1217 };
1218 (@inner $saved:tt <> ($($acc:expr,)*) <> $arg:ident: MutableHandle<$gentype:ty>, $($rest:tt)*) => {
1219 wrap!(@inner $saved <> ($($acc,)* $arg.into(),) <> $($rest)*);
1220 };
1221 (@inner $saved:tt <> ($($acc:expr,)*) <> $arg:ident: Handle, $($rest:tt)*) => {
1222 wrap!(@inner $saved <> ($($acc,)* $arg.into(),) <> $($rest)*);
1223 };
1224 (@inner $saved:tt <> ($($acc:expr,)*) <> $arg:ident: MutableHandle, $($rest:tt)*) => {
1225 wrap!(@inner $saved <> ($($acc,)* $arg.into(),) <> $($rest)*);
1226 };
1227 (@inner $saved:tt <> ($($acc:expr,)*) <> $arg:ident: HandleFunction , $($rest:tt)*) => {
1228 wrap!(@inner $saved <> ($($acc,)* $arg.into(),) <> $($rest)*);
1229 };
1230 (@inner $saved:tt <> ($($acc:expr,)*) <> $arg:ident: HandleId , $($rest:tt)*) => {
1231 wrap!(@inner $saved <> ($($acc,)* $arg.into(),) <> $($rest)*);
1232 };
1233 (@inner $saved:tt <> ($($acc:expr,)*) <> $arg:ident: HandleObject , $($rest:tt)*) => {
1234 wrap!(@inner $saved <> ($($acc,)* $arg.into(),) <> $($rest)*);
1235 };
1236 (@inner $saved:tt <> ($($acc:expr,)*) <> $arg:ident: HandleScript , $($rest:tt)*) => {
1237 wrap!(@inner $saved <> ($($acc,)* $arg.into(),) <> $($rest)*);
1238 };
1239 (@inner $saved:tt <> ($($acc:expr,)*) <> $arg:ident: HandleString , $($rest:tt)*) => {
1240 wrap!(@inner $saved <> ($($acc,)* $arg.into(),) <> $($rest)*);
1241 };
1242 (@inner $saved:tt <> ($($acc:expr,)*) <> $arg:ident: HandleSymbol , $($rest:tt)*) => {
1243 wrap!(@inner $saved <> ($($acc,)* $arg.into(),) <> $($rest)*);
1244 };
1245 (@inner $saved:tt <> ($($acc:expr,)*) <> $arg:ident: HandleValue , $($rest:tt)*) => {
1246 wrap!(@inner $saved <> ($($acc,)* $arg.into(),) <> $($rest)*);
1247 };
1248 (@inner $saved:tt <> ($($acc:expr,)*) <> $arg:ident: MutableHandleFunction , $($rest:tt)*) => {
1249 wrap!(@inner $saved <> ($($acc,)* $arg.into(),) <> $($rest)*);
1250 };
1251 (@inner $saved:tt <> ($($acc:expr,)*) <> $arg:ident: MutableHandleId , $($rest:tt)*) => {
1252 wrap!(@inner $saved <> ($($acc,)* $arg.into(),) <> $($rest)*);
1253 };
1254 (@inner $saved:tt <> ($($acc:expr,)*) <> $arg:ident: MutableHandleObject , $($rest:tt)*) => {
1255 wrap!(@inner $saved <> ($($acc,)* $arg.into(),) <> $($rest)*);
1256 };
1257 (@inner $saved:tt <> ($($acc:expr,)*) <> $arg:ident: MutableHandleScript , $($rest:tt)*) => {
1258 wrap!(@inner $saved <> ($($acc,)* $arg.into(),) <> $($rest)*);
1259 };
1260 (@inner $saved:tt <> ($($acc:expr,)*) <> $arg:ident: MutableHandleString , $($rest:tt)*) => {
1261 wrap!(@inner $saved <> ($($acc,)* $arg.into(),) <> $($rest)*);
1262 };
1263 (@inner $saved:tt <> ($($acc:expr,)*) <> $arg:ident: MutableHandleSymbol , $($rest:tt)*) => {
1264 wrap!(@inner $saved <> ($($acc,)* $arg.into(),) <> $($rest)*);
1265 };
1266 (@inner $saved:tt <> ($($acc:expr,)*) <> $arg:ident: MutableHandleValue , $($rest:tt)*) => {
1267 wrap!(@inner $saved <> ($($acc,)* $arg.into(),) <> $($rest)*);
1268 };
1269 (@inner $saved:tt <> ($($acc:expr,)*) <> $arg:ident: $type:ty, $($rest:tt)*) => {
1270 wrap!(@inner $saved <> ($($acc,)* $arg,) <> $($rest)*);
1271 };
1272 (@inner ($module:tt: $func_name:ident ($($args:tt)*) -> $outtype:ty) <> ($($argexprs:expr,)*) <> ) => {
1273 #[inline]
1274 pub unsafe fn $func_name($($args)*) -> $outtype {
1275 $module::$func_name($($argexprs),*)
1276 }
1277 };
1278 ($module:tt: pub fn $func_name:ident($($args:tt)*) -> $outtype:ty) => {
1279 wrap!(@inner ($module: $func_name ($($args)*) -> $outtype) <> () <> $($args)* ,);
1280 };
1281 ($module:tt: pub fn $func_name:ident($($args:tt)*)) => {
1282 wrap!($module: pub fn $func_name($($args)*) -> ());
1283 }
1284 }
1285
1286 use super::*;
1287 use crate::glue;
1288 use crate::glue::EncodedStringCallback;
1289 use crate::jsapi;
1290 use crate::jsapi::js::TempAllocPolicy;
1291 use crate::jsapi::jsid;
1292 use crate::jsapi::mozilla::Utf8Unit;
1293 use crate::jsapi::BigInt;
1294 use crate::jsapi::CallArgs;
1295 use crate::jsapi::CloneDataPolicy;
1296 use crate::jsapi::ColumnNumberOneOrigin;
1297 use crate::jsapi::CompartmentTransplantCallback;
1298 use crate::jsapi::EnvironmentChain;
1299 use crate::jsapi::JSONParseHandler;
1300 use crate::jsapi::Latin1Char;
1301 use crate::jsapi::PropertyKey;
1302 use crate::jsapi::TaggedColumnNumberOneOrigin;
1303 use crate::jsapi::ESClass;
1305 use crate::jsapi::ExceptionStackBehavior;
1306 use crate::jsapi::ForOfIterator;
1307 use crate::jsapi::ForOfIterator_NonIterableBehavior;
1308 use crate::jsapi::HandleObjectVector;
1309 use crate::jsapi::InstantiateOptions;
1310 use crate::jsapi::JSClass;
1311 use crate::jsapi::JSErrorReport;
1312 use crate::jsapi::JSExnType;
1313 use crate::jsapi::JSFunctionSpecWithHelp;
1314 use crate::jsapi::JSJitInfo;
1315 use crate::jsapi::JSONWriteCallback;
1316 use crate::jsapi::JSPrincipals;
1317 use crate::jsapi::JSPropertySpec;
1318 use crate::jsapi::JSPropertySpec_Name;
1319 use crate::jsapi::JSProtoKey;
1320 use crate::jsapi::JSScript;
1321 use crate::jsapi::JSStructuredCloneData;
1322 use crate::jsapi::JSType;
1323 use crate::jsapi::ModuleErrorBehaviour;
1324 use crate::jsapi::ModuleType;
1325 use crate::jsapi::MutableHandleIdVector;
1326 use crate::jsapi::PromiseState;
1327 use crate::jsapi::PromiseUserInputEventHandlingState;
1328 use crate::jsapi::ReadOnlyCompileOptions;
1329 use crate::jsapi::Realm;
1330 use crate::jsapi::RefPtr;
1331 use crate::jsapi::RegExpFlags;
1332 use crate::jsapi::ScriptEnvironmentPreparer_Closure;
1333 use crate::jsapi::SourceText;
1334 use crate::jsapi::StackCapture;
1335 use crate::jsapi::Stencil;
1336 use crate::jsapi::StructuredCloneScope;
1337 use crate::jsapi::Symbol;
1338 use crate::jsapi::SymbolCode;
1339 use crate::jsapi::TranscodeBuffer;
1340 use crate::jsapi::TwoByteChars;
1341 use crate::jsapi::UniqueChars;
1342 use crate::jsapi::Value;
1343 use crate::jsapi::WasmModule;
1344 use crate::jsapi::{ElementAdder, IsArrayAnswer, PropertyDescriptor};
1345 use crate::jsapi::{JSContext, JSFunction, JSNative, JSObject, JSString};
1346 use crate::jsapi::{
1347 JSStructuredCloneCallbacks, JSStructuredCloneReader, JSStructuredCloneWriter,
1348 };
1349 use crate::jsapi::{MallocSizeOf, ObjectOpResult, ObjectPrivateVisitor, TabSizes};
1350 use crate::jsapi::{SavedFrameResult, SavedFrameSelfHosted};
1351 include!("jsapi_wrappers.in.rs");
1352 include!("glue_wrappers.in.rs");
1353}
1354
1355pub mod wrappers2 {
1357 macro_rules! wrap {
1358 (@inner $saved:tt <> ($($arg_sig_acc:tt)*) <> ($($arg_expr_acc:expr,)*) <> $arg:ident: *const Handle<$gentype:ty>, $($rest:tt)*) => {
1363 wrap!(@inner $saved <> ($($arg_sig_acc)* , $arg: *const Handle<$gentype>) <> ($($arg_expr_acc,)* if $arg.is_null() { ::std::ptr::null() } else { &(*$arg).into() },) <> $($rest)*);
1364 };
1365 (@inner $saved:tt <> ($($arg_sig_acc:tt)*) <> ($($arg_expr_acc:expr,)*) <> $arg:ident: Handle<$gentype:ty>, $($rest:tt)*) => {
1366 wrap!(@inner $saved <> ($($arg_sig_acc)* , $arg: Handle<$gentype>) <> ($($arg_expr_acc,)* $arg.into(),) <> $($rest)*);
1367 };
1368 (@inner $saved:tt <> ($($arg_sig_acc:tt)*) <> ($($arg_expr_acc:expr,)*) <> $arg:ident: MutableHandle<$gentype:ty>, $($rest:tt)*) => {
1369 wrap!(@inner $saved <> ($($arg_sig_acc)* , $arg: MutableHandle<$gentype>) <> ($($arg_expr_acc,)* $arg.into(),) <> $($rest)*);
1370 };
1371 (@inner $saved:tt <> ($($arg_sig_acc:tt)*) <> ($($arg_expr_acc:expr,)*) <> $arg:ident: Handle, $($rest:tt)*) => {
1372 wrap!(@inner $saved <> ($($arg_sig_acc)* , $arg: Handle) <> ($($arg_expr_acc,)* $arg.into(),) <> $($rest)*);
1373 };
1374 (@inner $saved:tt <> ($($arg_sig_acc:tt)*) <> ($($arg_expr_acc:expr,)*) <> $arg:ident: MutableHandle, $($rest:tt)*) => {
1375 wrap!(@inner $saved <> ($($arg_sig_acc)* , $arg: MutableHandle) <> ($($arg_expr_acc,)* $arg.into(),) <> $($rest)*);
1376 };
1377 (@inner $saved:tt <> ($($arg_sig_acc:tt)*) <> ($($arg_expr_acc:expr,)*) <> $arg:ident: HandleFunction , $($rest:tt)*) => {
1378 wrap!(@inner $saved <> ($($arg_sig_acc)* , $arg: HandleFunction) <> ($($arg_expr_acc,)* $arg.into(),) <> $($rest)*);
1379 };
1380 (@inner $saved:tt <> ($($arg_sig_acc:tt)*) <> ($($arg_expr_acc:expr,)*) <> $arg:ident: HandleId , $($rest:tt)*) => {
1381 wrap!(@inner $saved <> ($($arg_sig_acc)* , $arg: HandleId) <> ($($arg_expr_acc,)* $arg.into(),) <> $($rest)*);
1382 };
1383 (@inner $saved:tt <> ($($arg_sig_acc:tt)*) <> ($($arg_expr_acc:expr,)*) <> $arg:ident: HandleObject , $($rest:tt)*) => {
1384 wrap!(@inner $saved <> ($($arg_sig_acc)* , $arg: HandleObject) <> ($($arg_expr_acc,)* $arg.into(),) <> $($rest)*);
1385 };
1386 (@inner $saved:tt <> ($($arg_sig_acc:tt)*) <> ($($arg_expr_acc:expr,)*) <> $arg:ident: HandleScript , $($rest:tt)*) => {
1387 wrap!(@inner $saved <> ($($arg_sig_acc)* , $arg: HandleScript) <> ($($arg_expr_acc,)* $arg.into(),) <> $($rest)*);
1388 };
1389 (@inner $saved:tt <> ($($arg_sig_acc:tt)*) <> ($($arg_expr_acc:expr,)*) <> $arg:ident: HandleString , $($rest:tt)*) => {
1390 wrap!(@inner $saved <> ($($arg_sig_acc)* , $arg: HandleString) <> ($($arg_expr_acc,)* $arg.into(),) <> $($rest)*);
1391 };
1392 (@inner $saved:tt <> ($($arg_sig_acc:tt)*) <> ($($arg_expr_acc:expr,)*) <> $arg:ident: HandleSymbol , $($rest:tt)*) => {
1393 wrap!(@inner $saved <> ($($arg_sig_acc)* , $arg: HandleSymbol) <> ($($arg_expr_acc,)* $arg.into(),) <> $($rest)*);
1394 };
1395 (@inner $saved:tt <> ($($arg_sig_acc:tt)*) <> ($($arg_expr_acc:expr,)*) <> $arg:ident: HandleValue , $($rest:tt)*) => {
1396 wrap!(@inner $saved <> ($($arg_sig_acc)* , $arg: HandleValue) <> ($($arg_expr_acc,)* $arg.into(),) <> $($rest)*);
1397 };
1398 (@inner $saved:tt <> ($($arg_sig_acc:tt)*) <> ($($arg_expr_acc:expr,)*) <> $arg:ident: MutableHandleFunction , $($rest:tt)*) => {
1399 wrap!(@inner $saved <> ($($arg_sig_acc)* , $arg: MutableHandleFunction) <> ($($arg_expr_acc,)* $arg.into(),) <> $($rest)*);
1400 };
1401 (@inner $saved:tt <> ($($arg_sig_acc:tt)*) <> ($($arg_expr_acc:expr,)*) <> $arg:ident: MutableHandleId , $($rest:tt)*) => {
1402 wrap!(@inner $saved <> ($($arg_sig_acc)* , $arg: MutableHandleId) <> ($($arg_expr_acc,)* $arg.into(),) <> $($rest)*);
1403 };
1404 (@inner $saved:tt <> ($($arg_sig_acc:tt)*) <> ($($arg_expr_acc:expr,)*) <> $arg:ident: MutableHandleObject , $($rest:tt)*) => {
1405 wrap!(@inner $saved <> ($($arg_sig_acc)* , $arg: MutableHandleObject) <> ($($arg_expr_acc,)* $arg.into(),) <> $($rest)*);
1406 };
1407 (@inner $saved:tt <> ($($arg_sig_acc:tt)*) <> ($($arg_expr_acc:expr,)*) <> $arg:ident: MutableHandleScript , $($rest:tt)*) => {
1408 wrap!(@inner $saved <> ($($arg_sig_acc)* , $arg: MutableHandleScript) <> ($($arg_expr_acc,)* $arg.into(),) <> $($rest)*);
1409 };
1410 (@inner $saved:tt <> ($($arg_sig_acc:tt)*) <> ($($arg_expr_acc:expr,)*) <> $arg:ident: MutableHandleString , $($rest:tt)*) => {
1411 wrap!(@inner $saved <> ($($arg_sig_acc)* , $arg: MutableHandleString) <> ($($arg_expr_acc,)* $arg.into(),) <> $($rest)*);
1412 };
1413 (@inner $saved:tt <> ($($arg_sig_acc:tt)*) <> ($($arg_expr_acc:expr,)*) <> $arg:ident: MutableHandleSymbol , $($rest:tt)*) => {
1414 wrap!(@inner $saved <> ($($arg_sig_acc)* , $arg: MutableHandleSymbol) <> ($($arg_expr_acc,)* $arg.into(),) <> $($rest)*);
1415 };
1416 (@inner $saved:tt <> ($($arg_sig_acc:tt)*) <> ($($arg_expr_acc:expr,)*) <> $arg:ident: MutableHandleValue , $($rest:tt)*) => {
1417 wrap!(@inner $saved <> ($($arg_sig_acc)* , $arg: MutableHandleValue) <> ($($arg_expr_acc,)* $arg.into(),) <> $($rest)*);
1418 };
1419 (@inner $saved:tt <> ($($arg_sig_acc:tt)*) <> ($($arg_expr_acc:expr,)*) <> $arg:ident: &mut JSContext , $($rest:tt)*) => {
1420 wrap!(@inner $saved <> ($($arg_sig_acc)* , $arg: &mut JSContext) <> ($($arg_expr_acc,)* $arg.raw_cx(),) <> $($rest)*);
1421 };
1422 (@inner $saved:tt <> ($($arg_sig_acc:tt)*) <> ($($arg_expr_acc:expr,)*) <> $arg:ident: &JSContext , $($rest:tt)*) => {
1423 wrap!(@inner $saved <> ($($arg_sig_acc)* , $arg: &JSContext) <> ($($arg_expr_acc,)* $arg.raw_cx_no_gc(),) <> $($rest)*);
1424 };
1425 (@inner $saved:tt <> ($($arg_sig_acc:tt)*) <> ($($arg_expr_acc:expr,)*) <> $arg:ident: *const AutoRequireNoGC , $($rest:tt)*) => {
1427 wrap!(@inner $saved <> ($($arg_sig_acc)*) <> ($($arg_expr_acc,)* ::std::ptr::null(),) <> $($rest)*);
1428 };
1429 (@inner $saved:tt <> ($($arg_sig_acc:tt)*) <> ($($arg_expr_acc:expr,)*) <> $arg:ident: $type:ty, $($rest:tt)*) => {
1430 wrap!(@inner $saved <> ($($arg_sig_acc)* , $arg: $type) <> ($($arg_expr_acc,)* $arg,) <> $($rest)*);
1431 };
1432 (@inner ($module:tt: $func_name:ident -> $outtype:ty) <> (, $($args:tt)*) <> ($($argexprs:expr,)*) <> ) => {
1433 #[inline]
1434 pub unsafe fn $func_name($($args)*) -> $outtype {
1435 $module::$func_name($($argexprs),*)
1436 }
1437 };
1438 ($module:tt: pub fn $func_name:ident($($args:tt)*) -> $outtype:ty) => {
1439 wrap!(@inner ($module: $func_name -> $outtype) <> () <> () <> $($args)* ,);
1440 };
1441 ($module:tt: pub fn $func_name:ident($($args:tt)*)) => {
1442 wrap!($module: pub fn $func_name($($args)*) -> ());
1443 }
1444 }
1445
1446 use super::*;
1447 use super::{
1448 Handle, HandleFunction, HandleId, HandleObject, HandleScript, HandleString, HandleValue,
1449 HandleValueArray, MutableHandle, MutableHandleId, MutableHandleObject, MutableHandleString,
1450 MutableHandleValue, StackGCVector,
1451 };
1452 use crate::context::JSContext;
1453 use crate::glue;
1454 use crate::glue::*;
1455 use crate::jsapi;
1456 use crate::jsapi::js::TempAllocPolicy;
1457 use crate::jsapi::mozilla::Utf8Unit;
1458 use crate::jsapi::mozilla::*;
1459 use crate::jsapi::BigInt;
1460 use crate::jsapi::CallArgs;
1461 use crate::jsapi::CloneDataPolicy;
1462 use crate::jsapi::ColumnNumberOneOrigin;
1463 use crate::jsapi::CompartmentTransplantCallback;
1464 use crate::jsapi::ESClass;
1465 use crate::jsapi::EnvironmentChain;
1466 use crate::jsapi::ExceptionStackBehavior;
1467 use crate::jsapi::ForOfIterator;
1468 use crate::jsapi::ForOfIterator_NonIterableBehavior;
1469 use crate::jsapi::HandleObjectVector;
1470 use crate::jsapi::InstantiateOptions;
1471 use crate::jsapi::JSClass;
1472 use crate::jsapi::JSErrorReport;
1473 use crate::jsapi::JSExnType;
1474 use crate::jsapi::JSFunctionSpecWithHelp;
1475 use crate::jsapi::JSJitInfo;
1476 use crate::jsapi::JSONParseHandler;
1477 use crate::jsapi::JSONWriteCallback;
1478 use crate::jsapi::JSPrincipals;
1479 use crate::jsapi::JSPropertySpec;
1480 use crate::jsapi::JSPropertySpec_Name;
1481 use crate::jsapi::JSProtoKey;
1482 use crate::jsapi::JSScript;
1483 use crate::jsapi::JSStructuredCloneData;
1484 use crate::jsapi::JSType;
1485 use crate::jsapi::Latin1Char;
1486 use crate::jsapi::ModuleErrorBehaviour;
1487 use crate::jsapi::ModuleType;
1488 use crate::jsapi::MutableHandleIdVector;
1489 use crate::jsapi::PromiseState;
1490 use crate::jsapi::PromiseUserInputEventHandlingState;
1491 use crate::jsapi::PropertyKey;
1492 use crate::jsapi::ReadOnlyCompileOptions;
1493 use crate::jsapi::Realm;
1494 use crate::jsapi::RealmOptions;
1495 use crate::jsapi::RefPtr;
1496 use crate::jsapi::RegExpFlags;
1497 use crate::jsapi::ScriptEnvironmentPreparer_Closure;
1498 use crate::jsapi::SourceText;
1499 use crate::jsapi::StackCapture;
1500 use crate::jsapi::Stencil;
1501 use crate::jsapi::StructuredCloneScope;
1502 use crate::jsapi::Symbol;
1503 use crate::jsapi::SymbolCode;
1504 use crate::jsapi::TaggedColumnNumberOneOrigin;
1505 use crate::jsapi::TranscodeBuffer;
1506 use crate::jsapi::TwoByteChars;
1507 use crate::jsapi::UniqueChars;
1508 use crate::jsapi::Value;
1509 use crate::jsapi::WasmModule;
1510 use crate::jsapi::*;
1511 use crate::jsapi::{ElementAdder, IsArrayAnswer, PropertyDescriptor};
1512 use crate::jsapi::{JSFunction, JSNative, JSObject, JSString};
1513 use crate::jsapi::{
1514 JSStructuredCloneCallbacks, JSStructuredCloneReader, JSStructuredCloneWriter,
1515 };
1516 use crate::jsapi::{MallocSizeOf, ObjectOpResult, ObjectPrivateVisitor, TabSizes};
1517 use crate::jsapi::{SavedFrameResult, SavedFrameSelfHosted};
1518 include!("jsapi2_wrappers.in.rs");
1519 include!("glue2_wrappers.in.rs");
1520}