1use super::atom::{Atom, AtomTable};
2use super::event_loop::EventLoop;
3use super::extension::MacroTaskExtension;
4use super::runtime::JSRuntime;
5use crate::builtins;
6use crate::builtins::promise::{Microtask, MicrotaskQueue};
7use crate::compiler::codegen::OptLevel;
8use crate::host::HostFunction;
9use crate::object::JSObject;
10use crate::object::ShapeCache;
11use crate::util::FxHashMap;
12use crate::value::JSValue;
13
14#[allow(non_snake_case)]
15pub struct CommonAtoms {
16 pub length: Atom,
17 pub prototype: Atom,
18 pub constructor: Atom,
19 pub call: Atom,
20 pub apply: Atom,
21 pub bind: Atom,
22 pub to_string: Atom,
23 pub value_of: Atom,
24 pub push: Atom,
25 pub pop: Atom,
26 pub shift: Atom,
27 pub unshift: Atom,
28 pub slice: Atom,
29 pub splice: Atom,
30 pub join: Atom,
31 pub map: Atom,
32 pub for_each: Atom,
33 pub filter: Atom,
34 pub reduce: Atom,
35 pub index_of: Atom,
36 pub last_index_of: Atom,
37 pub includes: Atom,
38 pub concat: Atom,
39 pub reverse: Atom,
40 pub sort: Atom,
41 pub flat: Atom,
42 pub flat_map: Atom,
43 pub find: Atom,
44 pub find_index: Atom,
45 pub every: Atom,
46 pub some: Atom,
47 pub fill: Atom,
48 pub keys: Atom,
49 pub values: Atom,
50 pub entries: Atom,
51 pub has_own_property: Atom,
52 pub is_prototype_of: Atom,
53 pub property_is_enumerable: Atom,
54 pub to_locale_string: Atom,
55 pub split: Atom,
56 pub replace: Atom,
57 pub match_atom: Atom,
58 pub search: Atom,
59 pub test: Atom,
60 pub exec: Atom,
61 pub then: Atom,
62 pub catch: Atom,
63 pub finally: Atom,
64 pub message: Atom,
65 pub name: Atom,
66 pub stack: Atom,
67 pub __proto__: Atom,
68 pub __super__: Atom,
69 pub __boundFn: Atom,
70 pub __boundArgs: Atom,
71 pub __boundThis: Atom,
72 pub __value__: Atom,
73 pub __dateValue__: Atom,
74 pub __pattern__: Atom,
75 pub __flags__: Atom,
76 pub source: Atom,
77 pub global: Atom,
78 pub ignore_case: Atom,
79 pub multiline: Atom,
80 pub sticky: Atom,
81 pub unicode: Atom,
82 pub undefined: Atom,
83 pub null: Atom,
84 pub object: Atom,
85 pub function: Atom,
86 pub number: Atom,
87 pub string: Atom,
88 pub boolean: Atom,
89 pub symbol: Atom,
90 pub bigint: Atom,
91 pub math: Atom,
92 pub json: Atom,
93 pub array: Atom,
94 pub regexp: Atom,
95 pub error: Atom,
96 pub date: Atom,
97 pub promise: Atom,
98 pub map_ctor: Atom,
99 pub set_ctor: Atom,
100 pub weak_map_ctor: Atom,
101 pub weak_set_ctor: Atom,
102 pub proxy: Atom,
103 pub reflect: Atom,
104 pub console: Atom,
105 pub index: Atom,
106 pub input: Atom,
107 pub empty: Atom,
108 pub n0: Atom,
109 pub n1: Atom,
110
111 pub typeof_undefined: Atom,
112 pub typeof_object: Atom,
113 pub typeof_boolean: Atom,
114 pub typeof_number: Atom,
115 pub typeof_bigint: Atom,
116 pub typeof_symbol: Atom,
117 pub typeof_string: Atom,
118 pub typeof_function: Atom,
119
120 pub dot_all: Atom,
121 pub last_index: Atom,
122 pub callee: Atom,
123 pub default_: Atom,
124 pub url: Atom,
125 pub __promise_state__: Atom,
126 pub __promise_result__: Atom,
127 pub __done__: Atom,
128 pub __iter_arr__: Atom,
129 pub __iter_idx__: Atom,
130 pub to_string_tag: Atom,
131}
132
133impl CommonAtoms {
134 pub fn new(tbl: &mut AtomTable) -> Self {
135 CommonAtoms {
136 length: tbl.intern("length"),
137 prototype: tbl.intern("prototype"),
138 constructor: tbl.intern("constructor"),
139 call: tbl.intern("call"),
140 apply: tbl.intern("apply"),
141 bind: tbl.intern("bind"),
142 to_string: tbl.intern("toString"),
143 value_of: tbl.intern("valueOf"),
144 push: tbl.intern("push"),
145 pop: tbl.intern("pop"),
146 shift: tbl.intern("shift"),
147 unshift: tbl.intern("unshift"),
148 slice: tbl.intern("slice"),
149 splice: tbl.intern("splice"),
150 join: tbl.intern("join"),
151 map: tbl.intern("map"),
152 for_each: tbl.intern("forEach"),
153 filter: tbl.intern("filter"),
154 reduce: tbl.intern("reduce"),
155 index_of: tbl.intern("indexOf"),
156 last_index_of: tbl.intern("lastIndexOf"),
157 includes: tbl.intern("includes"),
158 concat: tbl.intern("concat"),
159 reverse: tbl.intern("reverse"),
160 sort: tbl.intern("sort"),
161 flat: tbl.intern("flat"),
162 flat_map: tbl.intern("flatMap"),
163 find: tbl.intern("find"),
164 find_index: tbl.intern("findIndex"),
165 every: tbl.intern("every"),
166 some: tbl.intern("some"),
167 fill: tbl.intern("fill"),
168 keys: tbl.intern("keys"),
169 values: tbl.intern("values"),
170 entries: tbl.intern("entries"),
171 has_own_property: tbl.intern("hasOwnProperty"),
172 is_prototype_of: tbl.intern("isPrototypeOf"),
173 property_is_enumerable: tbl.intern("propertyIsEnumerable"),
174 to_locale_string: tbl.intern("toLocaleString"),
175 split: tbl.intern("split"),
176 replace: tbl.intern("replace"),
177 match_atom: tbl.intern("match"),
178 search: tbl.intern("search"),
179 test: tbl.intern("test"),
180 exec: tbl.intern("exec"),
181 then: tbl.intern("then"),
182 catch: tbl.intern("catch"),
183 finally: tbl.intern("finally"),
184 message: tbl.intern("message"),
185 name: tbl.intern("name"),
186 stack: tbl.intern("stack"),
187 __proto__: tbl.intern("__proto__"),
188 __super__: tbl.intern("__super__"),
189 __boundFn: tbl.intern("__boundFn"),
190 __boundArgs: tbl.intern("__boundArgs"),
191 __boundThis: tbl.intern("__boundThis"),
192 __value__: tbl.intern("__value__"),
193 __dateValue__: tbl.intern("__dateValue__"),
194 __pattern__: tbl.intern("__pattern__"),
195 __flags__: tbl.intern("__flags__"),
196 source: tbl.intern("source"),
197 global: tbl.intern("global"),
198 ignore_case: tbl.intern("ignoreCase"),
199 multiline: tbl.intern("multiline"),
200 sticky: tbl.intern("sticky"),
201 unicode: tbl.intern("unicode"),
202 undefined: tbl.intern("undefined"),
203 null: tbl.intern("null"),
204 object: tbl.intern("Object"),
205 function: tbl.intern("Function"),
206 number: tbl.intern("Number"),
207 string: tbl.intern("String"),
208 boolean: tbl.intern("Boolean"),
209 symbol: tbl.intern("Symbol"),
210 bigint: tbl.intern("BigInt"),
211 math: tbl.intern("Math"),
212 json: tbl.intern("JSON"),
213 array: tbl.intern("Array"),
214 regexp: tbl.intern("RegExp"),
215 error: tbl.intern("Error"),
216 date: tbl.intern("Date"),
217 promise: tbl.intern("Promise"),
218 map_ctor: tbl.intern("Map"),
219 set_ctor: tbl.intern("Set"),
220 weak_map_ctor: tbl.intern("WeakMap"),
221 weak_set_ctor: tbl.intern("WeakSet"),
222 proxy: tbl.intern("Proxy"),
223 reflect: tbl.intern("Reflect"),
224 console: tbl.intern("console"),
225 index: tbl.intern("index"),
226 input: tbl.intern("input"),
227 empty: tbl.intern(""),
228 n0: tbl.intern("0"),
229 n1: tbl.intern("1"),
230 typeof_undefined: tbl.intern("undefined"),
231 typeof_object: tbl.intern("object"),
232 typeof_boolean: tbl.intern("boolean"),
233 typeof_number: tbl.intern("number"),
234 typeof_bigint: tbl.intern("bigint"),
235 typeof_symbol: tbl.intern("symbol"),
236 typeof_string: tbl.intern("string"),
237 typeof_function: tbl.intern("function"),
238 dot_all: tbl.intern("dotAll"),
239 last_index: tbl.intern("lastIndex"),
240 callee: tbl.intern("callee"),
241 default_: tbl.intern("default"),
242 url: tbl.intern("url"),
243 __promise_state__: tbl.intern("__promise_state__"),
244 __promise_result__: tbl.intern("__promise_result__"),
245 __done__: tbl.intern("__done__"),
246 __iter_arr__: tbl.intern("__iter_arr__"),
247 __iter_idx__: tbl.intern("__iter_idx__"),
248 to_string_tag: tbl.intern("Symbol.toStringTag"),
249 }
250 }
251}
252
253pub struct JSContext {
254 runtime: *mut JSRuntime,
255 global_object: JSValue,
256 interrupt_counter: i32,
257 builtin_functions: FxHashMap<String, HostFunction>,
258
259 string_prototype: Option<usize>,
260 number_prototype: Option<usize>,
261 array_prototype: Option<usize>,
262 array_iterator_prototype: Option<usize>,
263 map_iterator_prototype: Option<usize>,
264 set_iterator_prototype: Option<usize>,
265 regexp_prototype: Option<usize>,
266 date_prototype: Option<usize>,
267 object_prototype: Option<usize>,
268 function_prototype: Option<usize>,
269 map_prototype: Option<usize>,
270 set_prototype: Option<usize>,
271 weakmap_prototype: Option<usize>,
272 weakset_prototype: Option<usize>,
273 dataview_prototype: Option<usize>,
274 typed_array_prototype: Option<usize>,
275 error_prototype: Option<usize>,
276 type_error_prototype: Option<usize>,
277 reference_error_prototype: Option<usize>,
278 syntax_error_prototype: Option<usize>,
279 range_error_prototype: Option<usize>,
280 uri_error_prototype: Option<usize>,
281 eval_error_prototype: Option<usize>,
282 symbol_prototype: Option<usize>,
283 bool_prototype: Option<usize>,
284 bigint_prototype: Option<usize>,
285 weakref_prototype: Option<usize>,
286 finalization_registry_prototype: Option<usize>,
287 pub finalization_registries: std::cell::RefCell<Vec<usize>>,
288 generator_prototype: Option<usize>,
289 async_generator_prototype: Option<usize>,
290 promise_prototype: Option<usize>,
291
292 register_vm_ptr: Option<usize>,
293 compiler_opt_level: OptLevel,
294
295 pub pending_exception: Option<JSValue>,
296
297 pending_callback: Option<PendingCallback>,
298
299 microtask_queue: MicrotaskQueue,
300
301 current_module_specifier: Option<String>,
302 import_meta_object: Option<usize>,
303
304 event_loop: EventLoop,
305
306 running_event_loop: Option<*mut EventLoop>,
307
308 shape_cache: ShapeCache,
309
310 pub common_atoms: CommonAtoms,
311
312 cached_int_atoms: [Atom; 100],
313
314 args_length_shape: Option<std::ptr::NonNull<crate::object::shape::Shape>>,
315}
316
317#[derive(Clone)]
318pub struct PendingCallback {
319 pub func: JSValue,
320
321 pub args: Vec<JSValue>,
322
323 pub is_method_call: bool,
324}
325
326impl JSContext {
327 const INTERRUPT_THRESHOLD: i32 = 1000;
328
329 pub fn new(runtime: &mut JSRuntime) -> Self {
330 let global = JSObject::new_global();
331 let global_ptr = Box::into_raw(Box::new(global)) as usize;
332 runtime.gc_heap_mut().track(global_ptr);
333 let global_value = JSValue::new_object(global_ptr);
334
335 let mut ctx = JSContext {
336 runtime: runtime as *mut JSRuntime,
337 global_object: global_value,
338 interrupt_counter: Self::INTERRUPT_THRESHOLD,
339 builtin_functions: FxHashMap::default(),
340 string_prototype: None,
341 number_prototype: None,
342 array_prototype: None,
343 array_iterator_prototype: None,
344 map_iterator_prototype: None,
345 set_iterator_prototype: None,
346 regexp_prototype: None,
347 date_prototype: None,
348 object_prototype: None,
349 function_prototype: None,
350 map_prototype: None,
351 set_prototype: None,
352 weakmap_prototype: None,
353 weakset_prototype: None,
354 dataview_prototype: None,
355 typed_array_prototype: None,
356 error_prototype: None,
357 type_error_prototype: None,
358 reference_error_prototype: None,
359 syntax_error_prototype: None,
360 range_error_prototype: None,
361 uri_error_prototype: None,
362 eval_error_prototype: None,
363 symbol_prototype: None,
364 bool_prototype: None,
365 bigint_prototype: None,
366 weakref_prototype: None,
367 finalization_registry_prototype: None,
368 finalization_registries: std::cell::RefCell::new(Vec::new()),
369 generator_prototype: None,
370 async_generator_prototype: None,
371 promise_prototype: None,
372 register_vm_ptr: None,
373 compiler_opt_level: OptLevel::default(),
374 pending_exception: None,
375 pending_callback: None,
376 microtask_queue: MicrotaskQueue::new(),
377 current_module_specifier: None,
378 import_meta_object: None,
379 event_loop: EventLoop::new(),
380 running_event_loop: None,
381 shape_cache: ShapeCache::new(),
382 common_atoms: CommonAtoms::new(runtime.atom_table_mut()),
383 cached_int_atoms: {
384 let mut arr = [Atom::empty(); 100];
385 for i in 0..100 {
386 arr[i] = runtime.atom_table_mut().intern(&i.to_string());
387 }
388 arr
389 },
390 args_length_shape: None,
391 };
392
393 builtins::init_globals(&mut ctx);
394
395 ctx
396 }
397
398 #[inline(always)]
399 pub fn check_interrupt(&mut self) -> Result<(), String> {
400 self.interrupt_counter -= 1;
401 if self.interrupt_counter <= 0 {
402 self.interrupt_counter = Self::INTERRUPT_THRESHOLD;
403 if self.runtime_mut().is_interrupted() {
404 return Err("interrupted".to_string());
405 }
406 }
407 Ok(())
408 }
409
410 #[inline(always)]
411 pub fn reset_interrupt_counter(&mut self) {
412 self.interrupt_counter = 0;
413 }
414
415 pub fn runtime(&self) -> &JSRuntime {
416 unsafe { &*self.runtime }
417 }
418
419 pub fn runtime_mut(&mut self) -> &mut JSRuntime {
420 unsafe { &mut *self.runtime }
421 }
422
423 pub fn atom_table(&self) -> &AtomTable {
424 self.runtime().atom_table()
425 }
426
427 pub fn atom_table_mut(&mut self) -> &mut AtomTable {
428 self.runtime_mut().atom_table_mut()
429 }
430
431 pub fn shape_cache(&self) -> &ShapeCache {
432 &self.shape_cache
433 }
434
435 pub fn shape_cache_mut(&mut self) -> &mut ShapeCache {
436 &mut self.shape_cache
437 }
438
439 #[inline]
440 pub fn get_or_create_args_length_shape(
441 &mut self,
442 ) -> std::ptr::NonNull<crate::object::shape::Shape> {
443 if let Some(s) = self.args_length_shape {
444 return s;
445 }
446 let root = self.shape_cache.root_shape();
447 let s = self.shape_cache.transition(root, self.common_atoms.length);
448 self.args_length_shape = Some(s);
449 s
450 }
451
452 pub fn global(&self) -> JSValue {
453 self.global_object
454 }
455
456 pub fn set_global(&mut self, value: JSValue) {
457 self.global_object = value;
458 }
459
460 pub fn intern(&mut self, s: &str) -> Atom {
461 self.atom_table_mut().intern(s)
462 }
463
464 #[inline]
465 pub fn intern_concat(&mut self, a: &str, b: &str) -> Atom {
466 self.atom_table_mut().intern_concat(a, b)
467 }
468
469 #[inline]
470 pub fn intern_concat_atoms(&mut self, a: Atom, b: Atom) -> Atom {
471 self.atom_table_mut().intern_concat_atoms(a, b)
472 }
473
474 #[inline]
475 pub fn int_atom(&self, n: usize) -> Atom {
476 if n < 100 {
477 unsafe { *self.cached_int_atoms.get_unchecked(n) }
478 } else {
479 self.common_atoms.empty
480 }
481 }
482
483 #[inline]
484 pub fn int_atom_mut(&mut self, n: usize) -> Atom {
485 if n < 100 {
486 unsafe { *self.cached_int_atoms.get_unchecked(n) }
487 } else {
488 self.atom_table_mut().intern(&n.to_string())
489 }
490 }
491
492 pub fn intern_fast(&mut self, s: &str) -> Atom {
493 self.atom_table_mut().intern_fast(s)
494 }
495
496 pub fn lookup_atom(&self, s: &str) -> Option<Atom> {
497 self.atom_table().lookup(s)
498 }
499
500 pub fn get_atom_str(&self, atom: Atom) -> &str {
501 self.atom_table().get(atom)
502 }
503
504 #[inline]
505 pub fn string_char_count(&self, atom: Atom) -> usize {
506 self.atom_table().char_count(atom)
507 }
508
509 #[inline]
510 pub fn string_char_code_at(&self, atom: Atom, index: usize) -> Option<u32> {
511 self.atom_table().char_code_at(atom, index)
512 }
513
514 pub fn mark_symbol_atom(&mut self, atom: Atom) {
515 self.atom_table_mut().mark_symbol_atom(atom.index());
516 }
517
518 pub fn is_symbol_atom(&self, atom: Atom) -> bool {
519 self.atom_table().is_symbol_atom(atom.index())
520 }
521
522 pub fn register_builtin(&mut self, name: &str, func: HostFunction) {
523 self.builtin_functions.insert(name.to_string(), func);
524 }
525
526 pub fn register_global_builtin(
527 &mut self,
528 name: &'static str,
529 arity: u32,
530 func: crate::host::HostFunc,
531 ) {
532 self.register_builtin(name, HostFunction::new(name, arity, func));
533 let mut f = crate::object::function::JSFunction::new_builtin(self.intern(name), arity);
534 f.set_builtin_marker(self, name);
535 let ptr = Box::into_raw(Box::new(f)) as usize;
536 self.runtime_mut().gc_heap_mut().track_function(ptr);
537 self.global()
538 .as_object_mut()
539 .set(self.intern(name), crate::value::JSValue::new_function(ptr));
540 }
541
542 pub fn call_builtin(&mut self, name: &str, args: &[JSValue]) -> JSValue {
543 let func = self.builtin_functions.get(name).cloned();
544 if let Some(f) = func {
545 f.call(self, args)
546 } else {
547 JSValue::undefined()
548 }
549 }
550
551 pub fn get_builtin_func(&self, name: &str) -> Option<crate::host::func::HostFunc> {
552 self.builtin_functions.get(name).map(|f| f.func)
553 }
554
555 pub fn get_builtin_name(&self, name: &str) -> Option<&'static str> {
556 self.builtin_functions.get(name).map(|f| f.name)
557 }
558
559 pub fn builtin_needs_this(&self, name: &str) -> bool {
560 self.builtin_functions
561 .get(name)
562 .map(|f| f.needs_this)
563 .unwrap_or(false)
564 }
565
566 pub fn builtin_is_constructor(&self, name: &str) -> bool {
567 self.builtin_functions
568 .get(name)
569 .map(|f| f.is_constructor)
570 .unwrap_or(false)
571 }
572
573 pub fn get_builtin_arity(&self, name: &str) -> Option<u32> {
574 self.builtin_functions.get(name).map(|f| f.arity)
575 }
576
577 pub fn call_builtin_direct(
578 &mut self,
579 func: crate::host::func::HostFunc,
580 args: &[JSValue],
581 ) -> JSValue {
582 func(self, args)
583 }
584
585 pub fn set_string_prototype(&mut self, ptr: usize) {
586 self.string_prototype = Some(ptr);
587 }
588
589 pub fn set_number_prototype(&mut self, ptr: usize) {
590 self.number_prototype = Some(ptr);
591 }
592
593 pub fn set_array_prototype(&mut self, ptr: usize) {
594 self.array_prototype = Some(ptr);
595 }
596
597 pub fn set_array_iterator_prototype(&mut self, ptr: usize) {
598 self.array_iterator_prototype = Some(ptr);
599 }
600
601 pub fn get_array_iterator_prototype(&self) -> Option<usize> {
602 self.array_iterator_prototype
603 }
604
605 pub fn set_map_iterator_prototype(&mut self, ptr: usize) {
606 self.map_iterator_prototype = Some(ptr);
607 }
608
609 pub fn get_map_iterator_prototype(&self) -> Option<usize> {
610 self.map_iterator_prototype
611 }
612
613 pub fn set_set_iterator_prototype(&mut self, ptr: usize) {
614 self.set_iterator_prototype = Some(ptr);
615 }
616
617 pub fn get_set_iterator_prototype(&self) -> Option<usize> {
618 self.set_iterator_prototype
619 }
620
621 pub fn set_regexp_prototype(&mut self, ptr: usize) {
622 self.regexp_prototype = Some(ptr);
623 }
624
625 pub fn set_object_prototype(&mut self, ptr: usize) {
626 self.object_prototype = Some(ptr);
627 }
628
629 pub fn set_function_prototype(&mut self, ptr: usize) {
630 self.function_prototype = Some(ptr);
631 }
632
633 pub fn set_map_prototype(&mut self, ptr: usize) {
634 self.map_prototype = Some(ptr);
635 }
636
637 pub fn set_set_prototype(&mut self, ptr: usize) {
638 self.set_prototype = Some(ptr);
639 }
640
641 pub fn get_string_prototype(&self) -> Option<*mut JSObject> {
642 self.string_prototype.map(|p| p as *mut JSObject)
643 }
644
645 pub fn get_number_prototype(&self) -> Option<*mut JSObject> {
646 self.number_prototype.map(|p| p as *mut JSObject)
647 }
648
649 pub fn get_bool_prototype(&self) -> Option<*mut JSObject> {
650 self.bool_prototype.map(|p| p as *mut JSObject)
651 }
652
653 pub fn set_bool_prototype(&mut self, ptr: usize) {
654 self.bool_prototype = Some(ptr);
655 }
656
657 pub fn get_bigint_prototype(&self) -> Option<*mut JSObject> {
658 self.bigint_prototype.map(|p| p as *mut JSObject)
659 }
660
661 pub fn set_bigint_prototype(&mut self, ptr: usize) {
662 self.bigint_prototype = Some(ptr);
663 }
664
665 pub fn get_array_prototype(&self) -> Option<*mut JSObject> {
666 self.array_prototype.map(|p| p as *mut JSObject)
667 }
668
669 pub fn get_regexp_prototype(&self) -> Option<*mut JSObject> {
670 self.regexp_prototype.map(|p| p as *mut JSObject)
671 }
672
673 pub fn get_object_prototype(&self) -> Option<*mut JSObject> {
674 self.object_prototype.map(|p| p as *mut JSObject)
675 }
676
677 pub fn set_date_prototype(&mut self, ptr: usize) {
678 self.date_prototype = Some(ptr);
679 }
680
681 pub fn get_date_prototype(&self) -> Option<*mut JSObject> {
682 self.date_prototype.map(|p| p as *mut JSObject)
683 }
684
685 pub fn get_function_prototype(&self) -> Option<*mut JSObject> {
686 self.function_prototype.map(|p| p as *mut JSObject)
687 }
688
689 pub fn get_map_prototype(&self) -> Option<*mut JSObject> {
690 self.map_prototype.map(|p| p as *mut JSObject)
691 }
692
693 pub fn get_set_prototype(&self) -> Option<*mut JSObject> {
694 self.set_prototype.map(|p| p as *mut JSObject)
695 }
696
697 pub fn set_weakmap_prototype(&mut self, ptr: usize) {
698 self.weakmap_prototype = Some(ptr);
699 }
700
701 pub fn get_weakmap_prototype(&self) -> Option<*mut JSObject> {
702 self.weakmap_prototype.map(|p| p as *mut JSObject)
703 }
704
705 pub fn set_weakset_prototype(&mut self, ptr: usize) {
706 self.weakset_prototype = Some(ptr);
707 }
708
709 pub fn set_dataview_prototype(&mut self, ptr: usize) {
710 self.dataview_prototype = Some(ptr);
711 }
712
713 pub fn set_typed_array_prototype(&mut self, ptr: usize) {
714 self.typed_array_prototype = Some(ptr);
715 }
716
717 pub fn get_weakset_prototype(&self) -> Option<*mut JSObject> {
718 self.weakset_prototype.map(|p| p as *mut JSObject)
719 }
720
721 pub fn get_dataview_prototype(&self) -> Option<*mut JSObject> {
722 self.dataview_prototype.map(|p| p as *mut JSObject)
723 }
724
725 pub fn get_typed_array_prototype(&self) -> Option<*mut JSObject> {
726 self.typed_array_prototype.map(|p| p as *mut JSObject)
727 }
728
729 pub fn set_error_prototype(&mut self, ptr: usize) {
730 self.error_prototype = Some(ptr);
731 }
732
733 pub fn get_error_prototype(&self) -> Option<*mut JSObject> {
734 self.error_prototype.map(|p| p as *mut JSObject)
735 }
736
737 pub fn set_type_error_prototype(&mut self, ptr: usize) {
738 self.type_error_prototype = Some(ptr);
739 }
740
741 pub fn get_type_error_prototype(&self) -> Option<*mut JSObject> {
742 self.type_error_prototype.map(|p| p as *mut JSObject)
743 }
744
745 pub fn set_reference_error_prototype(&mut self, ptr: usize) {
746 self.reference_error_prototype = Some(ptr);
747 }
748
749 pub fn get_reference_error_prototype(&self) -> Option<*mut JSObject> {
750 self.reference_error_prototype.map(|p| p as *mut JSObject)
751 }
752
753 pub fn set_range_error_prototype(&mut self, ptr: usize) {
754 self.range_error_prototype = Some(ptr);
755 }
756
757 pub fn get_range_error_prototype(&self) -> Option<*mut JSObject> {
758 self.range_error_prototype.map(|p| p as *mut JSObject)
759 }
760
761 pub fn set_uri_error_prototype(&mut self, ptr: usize) {
762 self.uri_error_prototype = Some(ptr);
763 }
764
765 pub fn get_uri_error_prototype(&self) -> Option<*mut JSObject> {
766 self.uri_error_prototype.map(|p| p as *mut JSObject)
767 }
768
769 pub fn set_syntax_error_prototype(&mut self, ptr: usize) {
770 self.syntax_error_prototype = Some(ptr);
771 }
772
773 pub fn get_syntax_error_prototype(&self) -> Option<*mut JSObject> {
774 self.syntax_error_prototype.map(|p| p as *mut JSObject)
775 }
776
777 pub fn set_eval_error_prototype(&mut self, ptr: usize) {
778 self.eval_error_prototype = Some(ptr);
779 }
780
781 pub fn get_eval_error_prototype(&self) -> Option<*mut JSObject> {
782 self.eval_error_prototype.map(|p| p as *mut JSObject)
783 }
784
785 pub fn set_symbol_prototype(&mut self, ptr: usize) {
786 self.symbol_prototype = Some(ptr);
787 }
788
789 pub fn get_symbol_prototype(&self) -> Option<*mut JSObject> {
790 self.symbol_prototype.map(|p| p as *mut JSObject)
791 }
792
793 pub fn set_weakref_prototype(&mut self, ptr: usize) {
794 self.weakref_prototype = Some(ptr);
795 }
796
797 pub fn get_weakref_prototype(&self) -> Option<*mut JSObject> {
798 self.weakref_prototype.map(|p| p as *mut JSObject)
799 }
800
801 pub fn set_finalization_registry_prototype(&mut self, ptr: usize) {
802 self.finalization_registry_prototype = Some(ptr);
803 }
804
805 pub fn get_finalization_registry_prototype(&self) -> Option<*mut JSObject> {
806 self.finalization_registry_prototype
807 .map(|p| p as *mut JSObject)
808 }
809
810 pub fn set_generator_prototype(&mut self, ptr: usize) {
811 self.generator_prototype = Some(ptr);
812 }
813
814 pub fn get_generator_prototype(&self) -> Option<*mut JSObject> {
815 self.generator_prototype.map(|p| p as *mut JSObject)
816 }
817
818 pub fn set_async_generator_prototype(&mut self, ptr: usize) {
819 self.async_generator_prototype = Some(ptr);
820 }
821
822 pub fn get_async_generator_prototype(&self) -> Option<*mut JSObject> {
823 self.async_generator_prototype.map(|p| p as *mut JSObject)
824 }
825
826 pub fn set_promise_prototype(&mut self, ptr: usize) {
827 self.promise_prototype = Some(ptr);
828 }
829
830 pub fn get_promise_prototype(&self) -> Option<*mut JSObject> {
831 self.promise_prototype.map(|p| p as *mut JSObject)
832 }
833
834 pub fn set_register_vm_ptr(&mut self, ptr: Option<usize>) {
835 self.register_vm_ptr = ptr;
836 }
837
838 pub fn get_register_vm_ptr(&self) -> Option<usize> {
839 self.register_vm_ptr
840 }
841
842 pub fn add_extension(&mut self, ext: Box<dyn MacroTaskExtension>) {
843 self.event_loop_mut().extensions.push(ext);
844 }
845
846 pub fn set_compiler_opt_level(&mut self, opt_level: OptLevel) {
847 self.compiler_opt_level = opt_level;
848 }
849
850 pub fn get_compiler_opt_level(&self) -> OptLevel {
851 self.compiler_opt_level
852 }
853
854 pub fn set_pending_callback(&mut self, callback: PendingCallback) {
855 self.pending_callback = Some(callback);
856 }
857
858 pub fn take_pending_callback(&mut self) -> Option<PendingCallback> {
859 self.pending_callback.take()
860 }
861
862 pub fn has_pending_callback(&self) -> bool {
863 self.pending_callback.is_some()
864 }
865
866 pub fn microtask_enqueue(&mut self, task: Microtask) {
867 self.microtask_queue.enqueue(task);
868 }
869
870 pub fn microtask_is_empty(&self) -> bool {
871 self.microtask_queue.is_empty()
872 }
873
874 pub fn microtask_dequeue(&mut self) -> Option<Microtask> {
875 self.microtask_queue.dequeue()
876 }
877
878 pub fn set_current_module(&mut self, specifier: Option<String>) {
879 self.current_module_specifier = specifier;
880 }
881
882 pub fn get_current_module(&self) -> Option<&str> {
883 self.current_module_specifier.as_deref()
884 }
885
886 pub fn get_symbol_registry_ptr(&self) -> Option<usize> {
887 self.runtime().symbol_registry()
888 }
889
890 pub fn set_symbol_registry_ptr(&mut self, ptr: Option<usize>) {
891 self.runtime_mut().set_symbol_registry(ptr);
892 }
893
894 pub fn set_import_meta(&mut self, ptr: Option<usize>) {
895 self.import_meta_object = ptr;
896 }
897
898 pub fn get_import_meta(&self) -> Option<usize> {
899 self.import_meta_object
900 }
901
902 pub fn event_loop(&self) -> &EventLoop {
903 &self.event_loop
904 }
905
906 pub fn event_loop_mut(&mut self) -> &mut EventLoop {
907 if let Some(ptr) = self.running_event_loop {
908 unsafe { &mut *ptr }
909 } else {
910 &mut self.event_loop
911 }
912 }
913
914 pub fn run_event_loop(&mut self) -> Result<super::event_loop::EventLoopResult, String> {
915 let mut event_loop = std::mem::take(&mut self.event_loop);
916
917 self.running_event_loop = Some(&mut event_loop as *mut EventLoop);
918 let result = event_loop.run_until_complete(self, None);
919 self.running_event_loop = None;
920 self.event_loop = event_loop;
921 result
922 }
923
924 pub fn run_event_loop_with_timeout(
925 &mut self,
926 timeout_ms: u64,
927 ) -> Result<super::event_loop::EventLoopResult, String> {
928 let mut event_loop = std::mem::take(&mut self.event_loop);
929
930 self.running_event_loop = Some(&mut event_loop as *mut EventLoop);
931 let result = event_loop.run_until_complete(self, Some(timeout_ms));
932 self.running_event_loop = None;
933 self.event_loop = event_loop;
934 result
935 }
936}