Skip to main content

boa_engine/context/
intrinsics.rs

1//! Data structures that contain intrinsic objects and constructors.
2
3use boa_gc::{Finalize, Trace};
4
5use crate::{
6    JsSymbol,
7    builtins::{Array, OrdinaryObject, iterable::IteratorPrototypes, uri::UriFunctions},
8    js_string,
9    object::{
10        CONSTRUCTOR, JsFunction, JsObject, Object, PROTOTYPE,
11        internal_methods::immutable_prototype::IMMUTABLE_PROTOTYPE_EXOTIC_INTERNAL_METHODS,
12        shape::{RootShape, shared_shape::template::ObjectTemplate},
13    },
14    property::{Attribute, PropertyKey},
15};
16
17#[cfg(feature = "intl")]
18use crate::builtins::intl::Intl;
19
20/// The intrinsic objects and constructors.
21///
22/// `Intrinsics` is internally stored using a `Gc`, which makes it cheapily cloneable
23/// for multiple references to the same set of intrinsic objects.
24#[derive(Debug, Trace, Finalize)]
25pub struct Intrinsics {
26    /// Cached standard constructors
27    pub(super) constructors: StandardConstructors,
28    /// Cached intrinsic objects
29    pub(super) objects: IntrinsicObjects,
30    /// Cached object templates.
31    pub(super) templates: ObjectTemplates,
32}
33
34impl Intrinsics {
35    /// Creates a new set of uninitialized intrinsics.
36    ///
37    /// Creates all the required empty objects for every intrinsic in this realm.
38    ///
39    /// To initialize all the intrinsics with their spec properties, see [`Realm::initialize`].
40    ///
41    /// [`Realm::initialize`]: crate::realm::Realm::initialize
42    pub(crate) fn uninit(root_shape: &RootShape) -> Option<Self> {
43        let constructors = StandardConstructors::default();
44        let templates = ObjectTemplates::new(root_shape, &constructors);
45
46        Some(Self {
47            constructors,
48            objects: IntrinsicObjects::uninit()?,
49            templates,
50        })
51    }
52
53    /// Return the cached intrinsic objects.
54    #[inline]
55    #[must_use]
56    pub const fn objects(&self) -> &IntrinsicObjects {
57        &self.objects
58    }
59
60    /// Return the cached standard constructors.
61    #[inline]
62    #[must_use]
63    pub const fn constructors(&self) -> &StandardConstructors {
64        &self.constructors
65    }
66
67    pub(crate) const fn templates(&self) -> &ObjectTemplates {
68        &self.templates
69    }
70}
71
72/// Stores a constructor (such as `Object`) and its corresponding prototype.
73#[derive(Debug, Trace, Finalize, Clone)]
74pub struct StandardConstructor {
75    constructor: JsFunction,
76    prototype: JsObject,
77}
78
79impl Default for StandardConstructor {
80    fn default() -> Self {
81        Self {
82            constructor: JsFunction::empty_intrinsic_function(true),
83            prototype: JsObject::with_null_proto(),
84        }
85    }
86}
87
88impl StandardConstructor {
89    /// Creates a new `StandardConstructor` from the constructor and the prototype.
90    pub(crate) fn new(constructor: JsFunction, prototype: JsObject) -> Self {
91        Self {
92            constructor,
93            prototype,
94        }
95    }
96
97    /// Build a constructor with a defined prototype.
98    fn with_prototype(prototype: JsObject) -> Self {
99        Self {
100            constructor: JsFunction::empty_intrinsic_function(true),
101            prototype,
102        }
103    }
104
105    /// Return the prototype of the constructor object.
106    ///
107    /// This is the same as `Object.prototype`, `Array.prototype`, etc.
108    #[inline]
109    #[must_use]
110    pub fn prototype(&self) -> JsObject {
111        self.prototype.clone()
112    }
113
114    /// Return the constructor object.
115    ///
116    /// This is the same as `Object`, `Array`, etc.
117    #[inline]
118    #[must_use]
119    pub fn constructor(&self) -> JsObject {
120        self.constructor.clone().into()
121    }
122}
123
124/// Cached core standard constructors.
125#[derive(Debug, Trace, Finalize)]
126pub struct StandardConstructors {
127    object: StandardConstructor,
128    proxy: StandardConstructor,
129    date: StandardConstructor,
130    function: StandardConstructor,
131    async_function: StandardConstructor,
132    generator_function: StandardConstructor,
133    async_generator_function: StandardConstructor,
134    array: StandardConstructor,
135    bigint: StandardConstructor,
136    number: StandardConstructor,
137    boolean: StandardConstructor,
138    string: StandardConstructor,
139    regexp: StandardConstructor,
140    symbol: StandardConstructor,
141    error: StandardConstructor,
142    type_error: StandardConstructor,
143    reference_error: StandardConstructor,
144    range_error: StandardConstructor,
145    syntax_error: StandardConstructor,
146    eval_error: StandardConstructor,
147    uri_error: StandardConstructor,
148    aggregate_error: StandardConstructor,
149    map: StandardConstructor,
150    set: StandardConstructor,
151    typed_array: StandardConstructor,
152    typed_int8_array: StandardConstructor,
153    typed_uint8_array: StandardConstructor,
154    typed_uint8clamped_array: StandardConstructor,
155    typed_int16_array: StandardConstructor,
156    typed_uint16_array: StandardConstructor,
157    typed_int32_array: StandardConstructor,
158    typed_uint32_array: StandardConstructor,
159    typed_bigint64_array: StandardConstructor,
160    typed_biguint64_array: StandardConstructor,
161    #[cfg(feature = "float16")]
162    typed_float16_array: StandardConstructor,
163    typed_float32_array: StandardConstructor,
164    typed_float64_array: StandardConstructor,
165    array_buffer: StandardConstructor,
166    shared_array_buffer: StandardConstructor,
167    data_view: StandardConstructor,
168    date_time_format: StandardConstructor,
169    promise: StandardConstructor,
170    weak_ref: StandardConstructor,
171    weak_map: StandardConstructor,
172    weak_set: StandardConstructor,
173    iterator: StandardConstructor,
174    finalization_registry: StandardConstructor,
175    #[cfg(feature = "intl")]
176    collator: StandardConstructor,
177    #[cfg(feature = "intl")]
178    list_format: StandardConstructor,
179    #[cfg(feature = "intl")]
180    locale: StandardConstructor,
181    #[cfg(feature = "intl")]
182    segmenter: StandardConstructor,
183    #[cfg(feature = "intl")]
184    plural_rules: StandardConstructor,
185    #[cfg(feature = "intl")]
186    number_format: StandardConstructor,
187    #[cfg(feature = "temporal")]
188    instant: StandardConstructor,
189    #[cfg(feature = "temporal")]
190    plain_date_time: StandardConstructor,
191    #[cfg(feature = "temporal")]
192    plain_date: StandardConstructor,
193    #[cfg(feature = "temporal")]
194    plain_time: StandardConstructor,
195    #[cfg(feature = "temporal")]
196    plain_year_month: StandardConstructor,
197    #[cfg(feature = "temporal")]
198    plain_month_day: StandardConstructor,
199    #[cfg(feature = "temporal")]
200    time_zone: StandardConstructor,
201    #[cfg(feature = "temporal")]
202    duration: StandardConstructor,
203    #[cfg(feature = "temporal")]
204    zoned_date_time: StandardConstructor,
205    #[cfg(feature = "temporal")]
206    calendar: StandardConstructor,
207}
208
209impl Default for StandardConstructors {
210    fn default() -> Self {
211        Self {
212            object: StandardConstructor::with_prototype(JsObject::from_object_and_vtable(
213                Object::<OrdinaryObject>::default(),
214                &IMMUTABLE_PROTOTYPE_EXOTIC_INTERNAL_METHODS,
215            )),
216            async_generator_function: StandardConstructor::default(),
217            proxy: StandardConstructor::default(),
218            date: StandardConstructor::default(),
219            function: StandardConstructor {
220                constructor: JsFunction::empty_intrinsic_function(true),
221                prototype: JsFunction::empty_intrinsic_function(false).into(),
222            },
223            async_function: StandardConstructor::default(),
224            generator_function: StandardConstructor::default(),
225            array: StandardConstructor::with_prototype(JsObject::from_proto_and_data(None, Array)),
226            bigint: StandardConstructor::default(),
227            number: StandardConstructor::with_prototype(JsObject::from_proto_and_data(None, 0.0)),
228            boolean: StandardConstructor::with_prototype(JsObject::from_proto_and_data(
229                None, false,
230            )),
231            string: StandardConstructor::with_prototype(JsObject::from_proto_and_data(
232                None,
233                js_string!(),
234            )),
235            regexp: StandardConstructor::default(),
236            symbol: StandardConstructor::default(),
237            error: StandardConstructor::default(),
238            type_error: StandardConstructor::default(),
239            reference_error: StandardConstructor::default(),
240            range_error: StandardConstructor::default(),
241            syntax_error: StandardConstructor::default(),
242            eval_error: StandardConstructor::default(),
243            uri_error: StandardConstructor::default(),
244            aggregate_error: StandardConstructor::default(),
245            map: StandardConstructor::default(),
246            set: StandardConstructor::default(),
247            typed_array: StandardConstructor::default(),
248            typed_int8_array: StandardConstructor::default(),
249            typed_uint8_array: StandardConstructor::default(),
250            typed_uint8clamped_array: StandardConstructor::default(),
251            typed_int16_array: StandardConstructor::default(),
252            typed_uint16_array: StandardConstructor::default(),
253            typed_int32_array: StandardConstructor::default(),
254            typed_uint32_array: StandardConstructor::default(),
255            typed_bigint64_array: StandardConstructor::default(),
256            typed_biguint64_array: StandardConstructor::default(),
257            #[cfg(feature = "float16")]
258            typed_float16_array: StandardConstructor::default(),
259            typed_float32_array: StandardConstructor::default(),
260            typed_float64_array: StandardConstructor::default(),
261            array_buffer: StandardConstructor::default(),
262            shared_array_buffer: StandardConstructor::default(),
263            data_view: StandardConstructor::default(),
264            date_time_format: StandardConstructor::default(),
265            promise: StandardConstructor::default(),
266            weak_ref: StandardConstructor::default(),
267            weak_map: StandardConstructor::default(),
268            weak_set: StandardConstructor::default(),
269            iterator: StandardConstructor::default(),
270            finalization_registry: StandardConstructor::default(),
271            #[cfg(feature = "intl")]
272            collator: StandardConstructor::default(),
273            #[cfg(feature = "intl")]
274            list_format: StandardConstructor::default(),
275            #[cfg(feature = "intl")]
276            locale: StandardConstructor::default(),
277            #[cfg(feature = "intl")]
278            segmenter: StandardConstructor::default(),
279            #[cfg(feature = "intl")]
280            plural_rules: StandardConstructor::default(),
281            #[cfg(feature = "intl")]
282            number_format: StandardConstructor::default(),
283            #[cfg(feature = "temporal")]
284            instant: StandardConstructor::default(),
285            #[cfg(feature = "temporal")]
286            plain_date_time: StandardConstructor::default(),
287            #[cfg(feature = "temporal")]
288            plain_date: StandardConstructor::default(),
289            #[cfg(feature = "temporal")]
290            plain_time: StandardConstructor::default(),
291            #[cfg(feature = "temporal")]
292            plain_year_month: StandardConstructor::default(),
293            #[cfg(feature = "temporal")]
294            plain_month_day: StandardConstructor::default(),
295            #[cfg(feature = "temporal")]
296            time_zone: StandardConstructor::default(),
297            #[cfg(feature = "temporal")]
298            duration: StandardConstructor::default(),
299            #[cfg(feature = "temporal")]
300            zoned_date_time: StandardConstructor::default(),
301            #[cfg(feature = "temporal")]
302            calendar: StandardConstructor::default(),
303        }
304    }
305}
306
307impl StandardConstructors {
308    /// Returns the `AsyncGeneratorFunction` constructor.
309    ///
310    /// More information:
311    ///  - [ECMAScript reference][spec]
312    ///
313    /// [spec]: https://tc39.es/ecma262/#sec-asyncgeneratorfunction-constructor
314    #[inline]
315    #[must_use]
316    pub const fn async_generator_function(&self) -> &StandardConstructor {
317        &self.async_generator_function
318    }
319
320    /// Returns the `Object` constructor.
321    ///
322    /// More information:
323    ///  - [ECMAScript reference][spec]
324    ///
325    /// [spec]: https://tc39.es/ecma262/#sec-object-constructor
326    #[inline]
327    #[must_use]
328    pub const fn object(&self) -> &StandardConstructor {
329        &self.object
330    }
331
332    /// Returns the `Proxy` constructor.
333    ///
334    /// More information:
335    ///  - [ECMAScript reference][spec]
336    ///
337    /// [spec]: https://tc39.es/ecma262/#sec-proxy-constructor
338    #[inline]
339    #[must_use]
340    pub const fn proxy(&self) -> &StandardConstructor {
341        &self.proxy
342    }
343
344    /// Returns the `Date` constructor.
345    ///
346    /// More information:
347    ///  - [ECMAScript reference][spec]
348    ///
349    /// [spec]: https://tc39.es/ecma262/#sec-date-constructor
350    #[inline]
351    #[must_use]
352    pub const fn date(&self) -> &StandardConstructor {
353        &self.date
354    }
355
356    /// Returns the `Function` constructor.
357    ///
358    /// More information:
359    ///  - [ECMAScript reference][spec]
360    ///
361    /// [spec]: https://tc39.es/ecma262/#sec-function-constructor
362    #[inline]
363    #[must_use]
364    pub const fn function(&self) -> &StandardConstructor {
365        &self.function
366    }
367
368    /// Returns the `AsyncFunction` constructor.
369    ///
370    /// More information:
371    ///  - [ECMAScript reference][spec]
372    ///
373    /// [spec]: https://tc39.es/ecma262/#sec-async-function-constructor
374    #[inline]
375    #[must_use]
376    pub const fn async_function(&self) -> &StandardConstructor {
377        &self.async_function
378    }
379
380    /// Returns the `GeneratorFunction` constructor.
381    ///
382    /// More information:
383    ///  - [ECMAScript reference][spec]
384    ///
385    /// [spec]: https://tc39.es/ecma262/#sec-generatorfunction-constructor
386    #[inline]
387    #[must_use]
388    pub const fn generator_function(&self) -> &StandardConstructor {
389        &self.generator_function
390    }
391
392    /// Returns the `Array` constructor.
393    ///
394    /// More information:
395    ///  - [ECMAScript reference][spec]
396    ///
397    /// [spec]: https://tc39.es/ecma262/#sec-array-constructor
398    #[inline]
399    #[must_use]
400    pub const fn array(&self) -> &StandardConstructor {
401        &self.array
402    }
403
404    /// Returns the `BigInt` constructor.
405    ///
406    /// More information:
407    ///  - [ECMAScript reference][spec]
408    ///
409    /// [spec]: https://tc39.es/ecma262/#sec-bigint-constructor
410    #[inline]
411    #[must_use]
412    pub const fn bigint(&self) -> &StandardConstructor {
413        &self.bigint
414    }
415
416    /// Returns the `Number` constructor.
417    ///
418    /// More information:
419    ///  - [ECMAScript reference][spec]
420    ///
421    /// [spec]: https://tc39.es/ecma262/#sec-number-constructor
422    #[inline]
423    #[must_use]
424    pub const fn number(&self) -> &StandardConstructor {
425        &self.number
426    }
427
428    /// Returns the `Boolean` constructor.
429    ///
430    /// More information:
431    ///  - [ECMAScript reference][spec]
432    ///
433    /// [spec]: https://tc39.es/ecma262/#sec-boolean-constructor
434    #[inline]
435    #[must_use]
436    pub const fn boolean(&self) -> &StandardConstructor {
437        &self.boolean
438    }
439
440    /// Returns the `String` constructor.
441    ///
442    /// More information:
443    ///  - [ECMAScript reference][spec]
444    ///
445    /// [spec]: https://tc39.es/ecma262/#sec-string-constructor
446    #[inline]
447    #[must_use]
448    pub const fn string(&self) -> &StandardConstructor {
449        &self.string
450    }
451
452    /// Returns the `RegExp` constructor.
453    ///
454    /// More information:
455    ///  - [ECMAScript reference][spec]
456    ///
457    /// [spec]: https://tc39.es/ecma262/#sec-regexp-constructor
458    #[inline]
459    #[must_use]
460    pub const fn regexp(&self) -> &StandardConstructor {
461        &self.regexp
462    }
463
464    /// Returns the `Symbol` constructor.
465    ///
466    /// More information:
467    ///  - [ECMAScript reference][spec]
468    ///
469    /// [spec]: https://tc39.es/ecma262/#sec-symbol-constructor
470    #[inline]
471    #[must_use]
472    pub const fn symbol(&self) -> &StandardConstructor {
473        &self.symbol
474    }
475
476    /// Returns the `Error` constructor.
477    ///
478    /// More information:
479    ///  - [ECMAScript reference][spec]
480    ///
481    /// [spec]: https://tc39.es/ecma262/#sec-error-constructor
482    #[inline]
483    #[must_use]
484    pub const fn error(&self) -> &StandardConstructor {
485        &self.error
486    }
487
488    /// Returns the `ReferenceError` constructor.
489    ///
490    /// More information:
491    ///  - [ECMAScript reference][spec]
492    ///
493    /// [spec]: https://tc39.es/ecma262/#sec-native-error-types-used-in-this-standard-referenceerror
494    #[inline]
495    #[must_use]
496    pub const fn reference_error(&self) -> &StandardConstructor {
497        &self.reference_error
498    }
499
500    /// Returns the `TypeError` constructor.
501    ///
502    /// More information:
503    ///  - [ECMAScript reference][spec]
504    ///
505    /// [spec]: https://tc39.es/ecma262/#sec-native-error-types-used-in-this-standard-typeerror
506    #[inline]
507    #[must_use]
508    pub const fn type_error(&self) -> &StandardConstructor {
509        &self.type_error
510    }
511
512    /// Returns the `RangeError` constructor.
513    ///
514    /// More information:
515    ///  - [ECMAScript reference][spec]
516    ///
517    /// [spec]: https://tc39.es/ecma262/#sec-native-error-types-used-in-this-standard-rangeerror
518    #[inline]
519    #[must_use]
520    pub const fn range_error(&self) -> &StandardConstructor {
521        &self.range_error
522    }
523
524    /// Returns the `SyntaxError` constructor.
525    ///
526    /// More information:
527    ///  - [ECMAScript reference][spec]
528    ///
529    /// [spec]: https://tc39.es/ecma262/#sec-native-error-types-used-in-this-standard-syntaxerror
530    #[inline]
531    #[must_use]
532    pub const fn syntax_error(&self) -> &StandardConstructor {
533        &self.syntax_error
534    }
535
536    /// Returns the `EvalError` constructor.
537    ///
538    /// More information:
539    ///  - [ECMAScript reference][spec]
540    ///
541    /// [spec]: https://tc39.es/ecma262/#sec-native-error-types-used-in-this-standard-evalerror
542    #[inline]
543    #[must_use]
544    pub const fn eval_error(&self) -> &StandardConstructor {
545        &self.eval_error
546    }
547
548    /// Returns the `URIError` constructor.
549    ///
550    /// More information:
551    ///  - [ECMAScript reference][spec]
552    ///
553    /// [spec]: https://tc39.es/ecma262/#sec-native-error-types-used-in-this-standard-urierror
554    #[inline]
555    #[must_use]
556    pub const fn uri_error(&self) -> &StandardConstructor {
557        &self.uri_error
558    }
559
560    /// Returns the `AggregateError` constructor.
561    ///
562    /// More information:
563    ///  - [ECMAScript reference][spec]
564    ///
565    /// [spec]: https://tc39.es/ecma262/#sec-aggregate-error-constructor
566    #[inline]
567    #[must_use]
568    pub const fn aggregate_error(&self) -> &StandardConstructor {
569        &self.aggregate_error
570    }
571
572    /// Returns the `Map` constructor.
573    ///
574    /// More information:
575    ///  - [ECMAScript reference][spec]
576    ///
577    /// [spec]: https://tc39.es/ecma262/#sec-map-constructor
578    #[inline]
579    #[must_use]
580    pub const fn map(&self) -> &StandardConstructor {
581        &self.map
582    }
583
584    /// Returns the `Set` constructor.
585    ///
586    /// More information:
587    ///  - [ECMAScript reference][spec]
588    ///
589    /// [spec]: https://tc39.es/ecma262/#sec-set-constructor
590    #[inline]
591    #[must_use]
592    pub const fn set(&self) -> &StandardConstructor {
593        &self.set
594    }
595
596    /// Returns the `TypedArray` constructor.
597    ///
598    /// More information:
599    ///  - [ECMAScript reference][spec]
600    ///
601    /// [spec]: https://tc39.es/ecma262/#sec-typedarray-constructors
602    #[inline]
603    #[must_use]
604    pub const fn typed_array(&self) -> &StandardConstructor {
605        &self.typed_array
606    }
607
608    /// Returns the `Int8Array` constructor.
609    ///
610    /// More information:
611    ///  - [ECMAScript reference][spec]
612    ///
613    /// [spec]: https://tc39.es/ecma262/#sec-typedarray-constructors
614    #[inline]
615    #[must_use]
616    pub const fn typed_int8_array(&self) -> &StandardConstructor {
617        &self.typed_int8_array
618    }
619
620    /// Returns the `Uint8Array` constructor.
621    ///
622    /// More information:
623    ///  - [ECMAScript reference][spec]
624    ///
625    /// [spec]: https://tc39.es/ecma262/#sec-typedarray-constructors
626    #[inline]
627    #[must_use]
628    pub const fn typed_uint8_array(&self) -> &StandardConstructor {
629        &self.typed_uint8_array
630    }
631
632    /// Returns the `Uint8ClampedArray` constructor.
633    ///
634    /// More information:
635    ///  - [ECMAScript reference][spec]
636    ///
637    /// [spec]: https://tc39.es/ecma262/#sec-typedarray-constructors
638    #[inline]
639    #[must_use]
640    pub const fn typed_uint8clamped_array(&self) -> &StandardConstructor {
641        &self.typed_uint8clamped_array
642    }
643
644    /// Returns the `Int16Array` constructor.
645    ///
646    /// More information:
647    ///  - [ECMAScript reference][spec]
648    ///
649    /// [spec]: https://tc39.es/ecma262/#sec-typedarray-constructors
650    #[inline]
651    #[must_use]
652    pub const fn typed_int16_array(&self) -> &StandardConstructor {
653        &self.typed_int16_array
654    }
655
656    /// Returns the `Uint16Array` constructor.
657    ///
658    /// More information:
659    ///  - [ECMAScript reference][spec]
660    ///
661    /// [spec]: https://tc39.es/ecma262/#sec-typedarray-constructors
662    #[inline]
663    #[must_use]
664    pub const fn typed_uint16_array(&self) -> &StandardConstructor {
665        &self.typed_uint16_array
666    }
667
668    /// Returns the `Uint32Array` constructor.
669    ///
670    /// More information:
671    ///  - [ECMAScript reference][spec]
672    ///
673    /// [spec]: https://tc39.es/ecma262/#sec-typedarray-constructors
674    #[inline]
675    #[must_use]
676    pub const fn typed_uint32_array(&self) -> &StandardConstructor {
677        &self.typed_uint32_array
678    }
679
680    /// Returns the `Int32Array` constructor.
681    ///
682    /// More information:
683    ///  - [ECMAScript reference][spec]
684    ///
685    /// [spec]: https://tc39.es/ecma262/#sec-typedarray-constructors
686    #[inline]
687    #[must_use]
688    pub const fn typed_int32_array(&self) -> &StandardConstructor {
689        &self.typed_int32_array
690    }
691
692    /// Returns the `BigInt64Array` constructor.
693    ///
694    /// More information:
695    ///  - [ECMAScript reference][spec]
696    ///
697    /// [spec]: https://tc39.es/ecma262/#sec-typedarray-constructors
698    #[inline]
699    #[must_use]
700    pub const fn typed_bigint64_array(&self) -> &StandardConstructor {
701        &self.typed_bigint64_array
702    }
703
704    /// Returns the `BigUint64Array` constructor.
705    ///
706    /// More information:
707    ///  - [ECMAScript reference][spec]
708    ///
709    /// [spec]: https://tc39.es/ecma262/#sec-typedarray-constructors
710    #[inline]
711    #[must_use]
712    pub const fn typed_biguint64_array(&self) -> &StandardConstructor {
713        &self.typed_biguint64_array
714    }
715
716    /// Returns the `Float16Array` constructor.
717    ///
718    /// More information:
719    ///  - [ECMAScript reference][spec]
720    ///
721    /// [spec]: https://tc39.es/ecma262/#sec-typedarray-constructors
722    #[cfg(feature = "float16")]
723    #[inline]
724    #[must_use]
725    pub const fn typed_float16_array(&self) -> &StandardConstructor {
726        &self.typed_float16_array
727    }
728
729    /// Returns the `Float32Array` constructor.
730    ///
731    /// More information:
732    ///  - [ECMAScript reference][spec]
733    ///
734    /// [spec]: https://tc39.es/ecma262/#sec-typedarray-constructors
735    #[inline]
736    #[must_use]
737    pub const fn typed_float32_array(&self) -> &StandardConstructor {
738        &self.typed_float32_array
739    }
740
741    /// Returns the `Float64Array` constructor.
742    ///
743    /// More information:
744    ///  - [ECMAScript reference][spec]
745    ///
746    /// [spec]: https://tc39.es/ecma262/#sec-typedarray-constructors
747    #[inline]
748    #[must_use]
749    pub const fn typed_float64_array(&self) -> &StandardConstructor {
750        &self.typed_float64_array
751    }
752
753    /// Returns the `ArrayBuffer` constructor.
754    ///
755    /// More information:
756    ///  - [ECMAScript reference][spec]
757    ///
758    /// [spec]: https://tc39.es/ecma262/#sec-arraybuffer-constructor
759    #[inline]
760    #[must_use]
761    pub const fn array_buffer(&self) -> &StandardConstructor {
762        &self.array_buffer
763    }
764
765    /// Returns the `SharedArrayBuffer` constructor.
766    ///
767    /// More information:
768    ///  - [ECMAScript reference][spec]
769    ///
770    /// [spec]: https://tc39.es/ecma262/#sec-sharedarraybuffer-constructor
771    #[inline]
772    #[must_use]
773    pub const fn shared_array_buffer(&self) -> &StandardConstructor {
774        &self.shared_array_buffer
775    }
776
777    /// Returns the `DataView` constructor.
778    ///
779    /// More information:
780    ///  - [ECMAScript reference][spec]
781    ///
782    /// [spec]: https://tc39.es/ecma262/#sec-dataview-constructor
783    #[inline]
784    #[must_use]
785    pub const fn data_view(&self) -> &StandardConstructor {
786        &self.data_view
787    }
788
789    /// Returns the `Intl.DateTimeFormat` constructor.
790    ///
791    /// More information:
792    ///  - [ECMAScript reference][spec]
793    ///
794    /// [spec]: https://tc39.es/ecma402/#sec-intl-datetimeformat-constructor
795    #[inline]
796    #[must_use]
797    pub const fn date_time_format(&self) -> &StandardConstructor {
798        &self.date_time_format
799    }
800
801    /// Returns the `Promise` constructor.
802    ///
803    /// More information:
804    ///  - [ECMAScript reference][spec]
805    ///
806    /// [spec]: https://tc39.es/ecma262/#sec-promise-constructor
807    #[inline]
808    #[must_use]
809    pub const fn promise(&self) -> &StandardConstructor {
810        &self.promise
811    }
812
813    /// Returns the `WeakRef` constructor.
814    ///
815    /// More information:
816    ///  - [ECMAScript reference][spec]
817    ///
818    /// [spec]: https://tc39.es/ecma262/#sec-weak-ref-constructor
819    #[inline]
820    #[must_use]
821    pub const fn weak_ref(&self) -> &StandardConstructor {
822        &self.weak_ref
823    }
824
825    /// Returns the `WeakMap` constructor.
826    ///
827    /// More information:
828    ///  - [ECMAScript reference][spec]
829    ///
830    /// [spec]: https://tc39.es/ecma262/#sec-weakmap-constructor
831    #[inline]
832    #[must_use]
833    pub const fn weak_map(&self) -> &StandardConstructor {
834        &self.weak_map
835    }
836
837    /// Returns the `WeakSet` constructor.
838    ///
839    /// More information:
840    ///  - [ECMAScript reference][spec]
841    ///
842    /// [spec]: https://tc39.es/ecma262/#sec-weakset-constructor
843    #[inline]
844    #[must_use]
845    pub const fn weak_set(&self) -> &StandardConstructor {
846        &self.weak_set
847    }
848
849    /// Returns the `Iterator` constructor.
850    ///
851    /// More information:
852    ///  - [ECMAScript reference][spec]
853    ///
854    /// [spec]: https://tc39.es/proposal-iterator-helpers/#sec-iterator-constructor
855    #[inline]
856    #[must_use]
857    pub const fn iterator(&self) -> &StandardConstructor {
858        &self.iterator
859    }
860
861    /// Returns the `FinalizationRegistry` constructor.
862    ///
863    /// More information:
864    ///  - [ECMAScript reference][spec]
865    ///
866    /// [spec]: https://tc39.es/ecma262/#sec-finalization-registry-constructor
867    #[inline]
868    #[must_use]
869    pub const fn finalization_registry(&self) -> &StandardConstructor {
870        &self.finalization_registry
871    }
872
873    /// Returns the `Intl.Collator` constructor.
874    ///
875    /// More information:
876    ///  - [ECMAScript reference][spec]
877    ///
878    /// [spec]: https://tc39.es/ecma402/#sec-intl.collator
879    #[inline]
880    #[must_use]
881    #[cfg(feature = "intl")]
882    pub const fn collator(&self) -> &StandardConstructor {
883        &self.collator
884    }
885
886    /// Returns the `Intl.ListFormat` constructor.
887    ///
888    /// More information:
889    ///  - [ECMAScript reference][spec]
890    ///
891    /// [spec]: https://tc39.es/ecma402/#sec-Intl.ListFormat
892    #[inline]
893    #[must_use]
894    #[cfg(feature = "intl")]
895    pub const fn list_format(&self) -> &StandardConstructor {
896        &self.list_format
897    }
898
899    /// Returns the `Intl.Locale` constructor.
900    ///
901    /// More information:
902    ///  - [ECMAScript reference][spec]
903    ///
904    /// [spec]: https://tc39.es/ecma402/#sec-Intl.Locale
905    #[inline]
906    #[must_use]
907    #[cfg(feature = "intl")]
908    pub const fn locale(&self) -> &StandardConstructor {
909        &self.locale
910    }
911
912    /// Returns the `Intl.Segmenter` constructor.
913    ///
914    /// More information:
915    ///  - [ECMAScript reference][spec]
916    ///
917    /// [spec]: https://tc39.es/ecma402/#sec-intl.segmenter
918    #[inline]
919    #[must_use]
920    #[cfg(feature = "intl")]
921    pub const fn segmenter(&self) -> &StandardConstructor {
922        &self.segmenter
923    }
924
925    /// Returns the `Intl.PluralRules` constructor.
926    ///
927    /// More information:
928    ///  - [ECMAScript reference][spec]
929    ///
930    /// [spec]: https://tc39.es/ecma402/#sec-intl.pluralrules
931    #[inline]
932    #[must_use]
933    #[cfg(feature = "intl")]
934    pub const fn plural_rules(&self) -> &StandardConstructor {
935        &self.plural_rules
936    }
937
938    /// Returns the `Intl.NumberFormat` constructor.
939    ///
940    /// More information:
941    ///  - [ECMAScript reference][spec]
942    ///
943    /// [spec]: https://tc39.es/ecma402/#sec-intl.numberformat
944    #[inline]
945    #[must_use]
946    #[cfg(feature = "intl")]
947    pub const fn number_format(&self) -> &StandardConstructor {
948        &self.number_format
949    }
950
951    /// Returns the `Temporal.Instant` constructor.
952    ///
953    /// More information:
954    ///  - [ECMAScript reference][spec]
955    ///
956    /// [spec]: https://tc39.es/proposal-temporal/#sec-temporal-instant-constructor
957    #[inline]
958    #[must_use]
959    #[cfg(feature = "temporal")]
960    pub const fn instant(&self) -> &StandardConstructor {
961        &self.instant
962    }
963
964    /// Returns the `Temporal.PlainDateTime` constructor.
965    ///
966    /// More information:
967    ///  - [ECMAScript reference][spec]
968    ///
969    /// [spec]: https://tc39.es/proposal-temporal/#sec-temporal-plaindatetime-constructor
970    #[inline]
971    #[must_use]
972    #[cfg(feature = "temporal")]
973    pub const fn plain_date_time(&self) -> &StandardConstructor {
974        &self.plain_date_time
975    }
976
977    /// Returns the `Temporal.PlainDate` constructor.
978    ///
979    /// More information:
980    ///  - [ECMAScript reference][spec]
981    ///
982    /// [spec]: https://tc39.es/proposal-temporal/#sec-temporal-plaindate-constructor
983    #[inline]
984    #[must_use]
985    #[cfg(feature = "temporal")]
986    pub const fn plain_date(&self) -> &StandardConstructor {
987        &self.plain_date
988    }
989
990    /// Returns the `Temporal.PlainTime` constructor.
991    ///
992    /// More information:
993    ///  - [ECMAScript reference][spec]
994    ///
995    /// [spec]: https://tc39.es/proposal-temporal/#sec-temporal-plaintime-constructor
996    #[inline]
997    #[must_use]
998    #[cfg(feature = "temporal")]
999    pub const fn plain_time(&self) -> &StandardConstructor {
1000        &self.plain_time
1001    }
1002
1003    /// Returns the `Temporal.PlainYearMonth` constructor.
1004    ///
1005    /// More information:
1006    ///  - [ECMAScript reference][spec]
1007    ///
1008    /// [spec]: https://tc39.es/proposal-temporal/#sec-temporal-plainyearmonth-constructor
1009    #[inline]
1010    #[must_use]
1011    #[cfg(feature = "temporal")]
1012    pub const fn plain_year_month(&self) -> &StandardConstructor {
1013        &self.plain_year_month
1014    }
1015
1016    /// Returns the `Temporal.PlainMonthDay` constructor.
1017    ///
1018    /// More information:
1019    ///  - [ECMAScript reference][spec]
1020    ///
1021    /// [spec]: https://tc39.es/proposal-temporal/#sec-temporal-plainmonthday-constructor
1022    #[inline]
1023    #[must_use]
1024    #[cfg(feature = "temporal")]
1025    pub const fn plain_month_day(&self) -> &StandardConstructor {
1026        &self.plain_month_day
1027    }
1028
1029    /// Returns the `Temporal.TimeZone` constructor.
1030    ///
1031    /// More information:
1032    ///  - [ECMAScript reference][spec]
1033    ///
1034    /// [spec]: https://tc39.es/proposal-temporal/#sec-temporal-timezone-constructor
1035    #[inline]
1036    #[must_use]
1037    #[cfg(feature = "temporal")]
1038    pub const fn time_zone(&self) -> &StandardConstructor {
1039        &self.time_zone
1040    }
1041
1042    /// Returns the `Temporal.Duration` constructor.
1043    ///
1044    /// More information:
1045    ///  - [ECMAScript reference][spec]
1046    ///
1047    /// [spec]: https://tc39.es/proposal-temporal/#sec-temporal-duration-constructor
1048    #[inline]
1049    #[must_use]
1050    #[cfg(feature = "temporal")]
1051    pub const fn duration(&self) -> &StandardConstructor {
1052        &self.duration
1053    }
1054
1055    /// Returns the `Temporal.ZonedDateTime` constructor.
1056    ///
1057    /// More information:
1058    ///  - [ECMAScript reference][spec]
1059    ///
1060    /// [spec]: https://tc39.es/proposal-temporal/#sec-temporal-zoneddatetime-constructor
1061    #[inline]
1062    #[must_use]
1063    #[cfg(feature = "temporal")]
1064    pub const fn zoned_date_time(&self) -> &StandardConstructor {
1065        &self.zoned_date_time
1066    }
1067
1068    /// Returns the `Temporal.Calendar` constructor.
1069    ///
1070    /// More information:
1071    ///  - [ECMAScript reference][spec]
1072    ///
1073    /// [spec]: https://tc39.es/proposal-temporal/#sec-temporal-calendar-constructor
1074    #[inline]
1075    #[must_use]
1076    #[cfg(feature = "temporal")]
1077    pub const fn calendar(&self) -> &StandardConstructor {
1078        &self.calendar
1079    }
1080}
1081
1082/// Cached intrinsic objects
1083#[derive(Debug, Trace, Finalize)]
1084pub struct IntrinsicObjects {
1085    /// [`%Reflect%`](https://tc39.es/ecma262/#sec-reflect)
1086    reflect: JsObject,
1087
1088    /// [`%Math%`](https://tc39.es/ecma262/#sec-math)
1089    math: JsObject,
1090
1091    /// [`%JSON%`](https://tc39.es/ecma262/#sec-json)
1092    json: JsObject,
1093
1094    /// [`%ThrowTypeError%`](https://tc39.es/ecma262/#sec-%throwtypeerror%)
1095    throw_type_error: JsFunction,
1096
1097    /// [`%Array.prototype.values%`](https://tc39.es/ecma262/#sec-array.prototype.values)
1098    array_prototype_values: JsFunction,
1099
1100    /// [`%Array.prototype.toString%`](https://tc39.es/ecma262/#sec-array.prototype.tostring)
1101    array_prototype_to_string: JsFunction,
1102
1103    /// Cached iterator prototypes.
1104    iterator_prototypes: IteratorPrototypes,
1105
1106    /// [`%GeneratorFunction.prototype.prototype%`](https://tc39.es/ecma262/#sec-properties-of-generator-prototype)
1107    generator: JsObject,
1108
1109    /// [`%AsyncGeneratorFunction.prototype.prototype%`](https://tc39.es/ecma262/#sec-properties-of-asyncgenerator-prototype)
1110    async_generator: JsObject,
1111
1112    /// [`%Atomics%`](https://tc39.es/ecma262/#sec-atomics)
1113    atomics: JsObject,
1114
1115    /// [`%eval%`](https://tc39.es/ecma262/#sec-eval-x)
1116    eval: JsFunction,
1117
1118    /// URI related functions
1119    uri_functions: UriFunctions,
1120
1121    /// [`%isFinite%`](https://tc39.es/ecma262/#sec-isfinite-number)
1122    is_finite: JsFunction,
1123
1124    /// [`%isNaN%`](https://tc39.es/ecma262/#sec-isnan-number)
1125    is_nan: JsFunction,
1126
1127    /// [`%parseFloat%`](https://tc39.es/ecma262/#sec-parsefloat-string)
1128    parse_float: JsFunction,
1129
1130    /// [`%parseInt%`](https://tc39.es/ecma262/#sec-parseint-string-radix)
1131    parse_int: JsFunction,
1132
1133    /// [`%escape%`](https://tc39.es/ecma262/#sec-escape-string)
1134    #[cfg(feature = "annex-b")]
1135    escape: JsFunction,
1136
1137    /// [`%unescape%`](https://tc39.es/ecma262/#sec-unescape-string)
1138    #[cfg(feature = "annex-b")]
1139    unescape: JsFunction,
1140
1141    /// [`%Intl%`](https://tc39.es/ecma402/#intl-object)
1142    #[cfg(feature = "intl")]
1143    intl: JsObject<Intl>,
1144
1145    /// [`%SegmentsPrototype%`](https://tc39.es/ecma402/#sec-%segmentsprototype%-object)
1146    #[cfg(feature = "intl")]
1147    segments_prototype: JsObject,
1148
1149    /// [`%Temporal%`](https://tc39.es/proposal-temporal/#sec-temporal-objects)
1150    #[cfg(feature = "temporal")]
1151    temporal: JsObject,
1152
1153    /// [`%Temporal.Now%`](https://tc39.es/proposal-temporal/#sec-temporal-now-object)
1154    #[cfg(feature = "temporal")]
1155    now: JsObject,
1156}
1157
1158impl IntrinsicObjects {
1159    /// Creates a new set of uninitialized intrinsic objects.
1160    ///
1161    /// Creates all the required empty objects for every intrinsic object in this realm.
1162    ///
1163    /// To initialize all the intrinsic objects with their spec properties, see [`Realm::initialize`].
1164    ///
1165    /// [`Realm::initialize`]: crate::realm::Realm::initialize
1166    #[allow(clippy::unnecessary_wraps)]
1167    pub(crate) fn uninit() -> Option<Self> {
1168        Some(Self {
1169            reflect: JsObject::with_null_proto(),
1170            math: JsObject::with_null_proto(),
1171            json: JsObject::with_null_proto(),
1172            throw_type_error: JsFunction::empty_intrinsic_function(false),
1173            array_prototype_values: JsFunction::empty_intrinsic_function(false),
1174            array_prototype_to_string: JsFunction::empty_intrinsic_function(false),
1175            iterator_prototypes: IteratorPrototypes::default(),
1176            generator: JsObject::with_null_proto(),
1177            async_generator: JsObject::with_null_proto(),
1178            atomics: JsObject::with_null_proto(),
1179            eval: JsFunction::empty_intrinsic_function(false),
1180            uri_functions: UriFunctions::default(),
1181            is_finite: JsFunction::empty_intrinsic_function(false),
1182            is_nan: JsFunction::empty_intrinsic_function(false),
1183            parse_float: JsFunction::empty_intrinsic_function(false),
1184            parse_int: JsFunction::empty_intrinsic_function(false),
1185            #[cfg(feature = "annex-b")]
1186            escape: JsFunction::empty_intrinsic_function(false),
1187            #[cfg(feature = "annex-b")]
1188            unescape: JsFunction::empty_intrinsic_function(false),
1189            #[cfg(feature = "intl")]
1190            intl: JsObject::new_unique(None, Intl::new()?),
1191            #[cfg(feature = "intl")]
1192            segments_prototype: JsObject::with_null_proto(),
1193            #[cfg(feature = "temporal")]
1194            temporal: JsObject::with_null_proto(),
1195            #[cfg(feature = "temporal")]
1196            now: JsObject::with_null_proto(),
1197        })
1198    }
1199
1200    /// Gets the [`%ThrowTypeError%`][spec] intrinsic function.
1201    ///
1202    /// [spec]: https://tc39.es/ecma262/#sec-%throwtypeerror%
1203    #[inline]
1204    #[must_use]
1205    pub fn throw_type_error(&self) -> JsFunction {
1206        self.throw_type_error.clone()
1207    }
1208
1209    /// Gets the [`%Array.prototype.values%`][spec] intrinsic function.
1210    ///
1211    /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.values
1212    #[inline]
1213    #[must_use]
1214    pub fn array_prototype_values(&self) -> JsFunction {
1215        self.array_prototype_values.clone()
1216    }
1217
1218    /// Gets the [`%Array.prototype.toString%`][spec] intrinsic function.
1219    ///
1220    /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.tostring
1221    #[inline]
1222    #[must_use]
1223    pub fn array_prototype_to_string(&self) -> JsFunction {
1224        self.array_prototype_to_string.clone()
1225    }
1226
1227    /// Gets the cached iterator prototypes.
1228    #[inline]
1229    #[must_use]
1230    pub const fn iterator_prototypes(&self) -> &IteratorPrototypes {
1231        &self.iterator_prototypes
1232    }
1233
1234    /// Gets the [`%GeneratorFunction.prototype.prototype%`][spec] intrinsic object.
1235    ///
1236    /// [spec]: https://tc39.es/ecma262/#sec-generator-objects
1237    #[inline]
1238    #[must_use]
1239    pub fn generator(&self) -> JsObject {
1240        self.generator.clone()
1241    }
1242
1243    /// Gets the [`%AsyncGeneratorFunction.prototype.prototype%`][spec] intrinsic object.
1244    ///
1245    /// [spec]: https://tc39.es/ecma262/#sec-asyncgenerator-objects
1246    #[inline]
1247    #[must_use]
1248    pub fn async_generator(&self) -> JsObject {
1249        self.async_generator.clone()
1250    }
1251
1252    /// Gets the [`%Atomics%`][spec] intrinsic object.
1253    ///
1254    /// [spec]: https://tc39.es/ecma262/#sec-atomics
1255    #[inline]
1256    #[must_use]
1257    pub fn atomics(&self) -> JsObject {
1258        self.atomics.clone()
1259    }
1260
1261    /// Gets the [`%eval%`][spec] intrinsic function.
1262    ///
1263    /// [spec]: https://tc39.es/ecma262/#sec-eval-x
1264    #[inline]
1265    #[must_use]
1266    pub fn eval(&self) -> JsFunction {
1267        self.eval.clone()
1268    }
1269
1270    /// Gets the URI intrinsic functions.
1271    #[inline]
1272    #[must_use]
1273    pub const fn uri_functions(&self) -> &UriFunctions {
1274        &self.uri_functions
1275    }
1276
1277    /// Gets the [`%Reflect%`][spec] intrinsic object.
1278    ///
1279    /// [spec]: https://tc39.es/ecma262/#sec-reflect
1280    #[inline]
1281    #[must_use]
1282    pub fn reflect(&self) -> JsObject {
1283        self.reflect.clone()
1284    }
1285
1286    /// Gets the [`%Math%`][spec] intrinsic object.
1287    ///
1288    /// [spec]: https://tc39.es/ecma262/#sec-math
1289    #[inline]
1290    #[must_use]
1291    pub fn math(&self) -> JsObject {
1292        self.math.clone()
1293    }
1294
1295    /// `true` when `object` is this realm's `%Math%` intrinsic.
1296    #[inline]
1297    #[must_use]
1298    pub(crate) fn is_math(&self, object: &JsObject) -> bool {
1299        JsObject::equals(&self.math, object)
1300    }
1301
1302    /// Gets the [`%JSON%`][spec] intrinsic object.
1303    ///
1304    /// [spec]: https://tc39.es/ecma262/#sec-json
1305    #[inline]
1306    #[must_use]
1307    pub fn json(&self) -> JsObject {
1308        self.json.clone()
1309    }
1310
1311    /// Gets the [`%isFinite%`][spec] intrinsic function.
1312    ///
1313    /// [spec]: https://tc39.es/ecma262/#sec-isfinite-number
1314    #[inline]
1315    #[must_use]
1316    pub fn is_finite(&self) -> JsFunction {
1317        self.is_finite.clone()
1318    }
1319
1320    /// Gets the [`%isNaN%`][spec] intrinsic function.
1321    ///
1322    /// [spec]: https://tc39.es/ecma262/#sec-isnan-number
1323    #[inline]
1324    #[must_use]
1325    pub fn is_nan(&self) -> JsFunction {
1326        self.is_nan.clone()
1327    }
1328
1329    /// Gets the [`%parseFloat%`][spec] intrinsic function.
1330    ///
1331    /// [spec]: https://tc39.es/ecma262/#sec-parsefloat-string
1332    #[inline]
1333    #[must_use]
1334    pub fn parse_float(&self) -> JsFunction {
1335        self.parse_float.clone()
1336    }
1337
1338    /// Gets the [`%parseInt%`][spec] intrinsic function.
1339    ///
1340    /// [spec]: https://tc39.es/ecma262/#sec-parseint-string-radix
1341    #[inline]
1342    #[must_use]
1343    pub fn parse_int(&self) -> JsFunction {
1344        self.parse_int.clone()
1345    }
1346
1347    /// Gets the [`%escape%`][spec] intrinsic function.
1348    ///
1349    /// [spec]: https://tc39.es/ecma262/#sec-escape-string
1350    #[must_use]
1351    #[cfg(feature = "annex-b")]
1352    #[inline]
1353    pub fn escape(&self) -> JsFunction {
1354        self.escape.clone()
1355    }
1356
1357    /// Gets the [`%unescape%`][spec] intrinsic function.
1358    ///
1359    /// [spec]: https://tc39.es/ecma262/#sec-unescape-string
1360    #[must_use]
1361    #[cfg(feature = "annex-b")]
1362    #[inline]
1363    pub fn unescape(&self) -> JsFunction {
1364        self.unescape.clone()
1365    }
1366
1367    /// Gets the [`%Intl%`][spec] intrinsic object.
1368    ///
1369    /// [spec]: https://tc39.es/ecma402/#intl-object
1370    #[must_use]
1371    #[cfg(feature = "intl")]
1372    #[inline]
1373    pub fn intl(&self) -> JsObject<Intl> {
1374        self.intl.clone()
1375    }
1376
1377    /// Gets the [`%SegmentsPrototype%`][spec] intrinsic object.
1378    ///
1379    /// [spec]: https://tc39.es/ecma402/#sec-%segmentsprototype%-object
1380    #[must_use]
1381    #[cfg(feature = "intl")]
1382    pub fn segments_prototype(&self) -> JsObject {
1383        self.segments_prototype.clone()
1384    }
1385
1386    /// Gets the [`%Temporal%`][spec] intrinsic object.
1387    ///
1388    /// [spec]: https://tc39.es/proposal-temporal/#sec-temporal-objects
1389    #[cfg(feature = "temporal")]
1390    #[must_use]
1391    #[inline]
1392    pub fn temporal(&self) -> JsObject {
1393        self.temporal.clone()
1394    }
1395
1396    /// Gets the [`%Temporal.Now%`][spec] intrinsic object.
1397    ///
1398    /// [spec]: https://tc39.es/proposal-temporal/#sec-temporal-now-object
1399    #[cfg(feature = "temporal")]
1400    #[must_use]
1401    #[inline]
1402    pub fn now(&self) -> JsObject {
1403        self.now.clone()
1404    }
1405}
1406
1407/// Contains commonly used [`ObjectTemplate`]s.
1408#[derive(Debug, Trace, Finalize)]
1409pub(crate) struct ObjectTemplates {
1410    iterator_result: ObjectTemplate,
1411    ordinary_object: ObjectTemplate,
1412    array: ObjectTemplate,
1413    number: ObjectTemplate,
1414    string: ObjectTemplate,
1415    symbol: ObjectTemplate,
1416    bigint: ObjectTemplate,
1417    boolean: ObjectTemplate,
1418
1419    regexp: ObjectTemplate,
1420    regexp_without_proto: ObjectTemplate,
1421
1422    unmapped_arguments: ObjectTemplate,
1423    mapped_arguments: ObjectTemplate,
1424
1425    function_with_prototype: ObjectTemplate,
1426    function_prototype: ObjectTemplate,
1427
1428    function: ObjectTemplate,
1429    async_function: ObjectTemplate,
1430    generator_function: ObjectTemplate,
1431    async_generator_function: ObjectTemplate,
1432
1433    function_without_proto: ObjectTemplate,
1434    function_with_prototype_without_proto: ObjectTemplate,
1435
1436    namespace: ObjectTemplate,
1437
1438    with_resolvers: ObjectTemplate,
1439
1440    wait_async: ObjectTemplate,
1441}
1442
1443impl ObjectTemplates {
1444    pub(crate) fn new(root_shape: &RootShape, constructors: &StandardConstructors) -> Self {
1445        let root_shape = root_shape.shape();
1446
1447        // pre-initialize used shapes.
1448        let ordinary_object =
1449            ObjectTemplate::with_prototype(root_shape, constructors.object().prototype());
1450        let mut array = ObjectTemplate::new(root_shape);
1451        let length_property_key: PropertyKey = js_string!("length").into();
1452        array.property(
1453            length_property_key.clone(),
1454            Attribute::WRITABLE | Attribute::PERMANENT | Attribute::NON_ENUMERABLE,
1455        );
1456        array.set_prototype(constructors.array().prototype());
1457
1458        let number = ObjectTemplate::with_prototype(root_shape, constructors.number().prototype());
1459        let symbol = ObjectTemplate::with_prototype(root_shape, constructors.symbol().prototype());
1460        let bigint = ObjectTemplate::with_prototype(root_shape, constructors.bigint().prototype());
1461        let boolean =
1462            ObjectTemplate::with_prototype(root_shape, constructors.boolean().prototype());
1463        let mut string = ObjectTemplate::new(root_shape);
1464        string.property(
1465            length_property_key.clone(),
1466            Attribute::READONLY | Attribute::PERMANENT | Attribute::NON_ENUMERABLE,
1467        );
1468        string.set_prototype(constructors.string().prototype());
1469
1470        let mut regexp_without_proto = ObjectTemplate::new(root_shape);
1471        regexp_without_proto.property(js_string!("lastIndex").into(), Attribute::WRITABLE);
1472
1473        let mut regexp = regexp_without_proto.clone();
1474        regexp.set_prototype(constructors.regexp().prototype());
1475
1476        let name_property_key: PropertyKey = js_string!("name").into();
1477        let mut function = ObjectTemplate::new(root_shape);
1478        function.property(
1479            length_property_key.clone(),
1480            Attribute::READONLY | Attribute::CONFIGURABLE | Attribute::NON_ENUMERABLE,
1481        );
1482        function.property(
1483            name_property_key,
1484            Attribute::READONLY | Attribute::CONFIGURABLE | Attribute::NON_ENUMERABLE,
1485        );
1486
1487        let function_without_proto = function.clone();
1488        let mut async_function = function.clone();
1489        let mut function_with_prototype = function.clone();
1490
1491        function_with_prototype.property(
1492            PROTOTYPE.into(),
1493            Attribute::WRITABLE | Attribute::PERMANENT | Attribute::NON_ENUMERABLE,
1494        );
1495        let mut generator_function = function_with_prototype.clone();
1496        let mut async_generator_function = function_with_prototype.clone();
1497
1498        let function_with_prototype_without_proto = function_with_prototype.clone();
1499
1500        function.set_prototype(constructors.function().prototype());
1501        function_with_prototype.set_prototype(constructors.function().prototype());
1502        async_function.set_prototype(constructors.async_function().prototype());
1503        generator_function.set_prototype(constructors.generator_function().prototype());
1504        async_generator_function.set_prototype(constructors.async_generator_function().prototype());
1505
1506        let mut function_prototype = ordinary_object.clone();
1507        function_prototype.property(
1508            CONSTRUCTOR.into(),
1509            Attribute::WRITABLE | Attribute::CONFIGURABLE | Attribute::NON_ENUMERABLE,
1510        );
1511
1512        let mut unmapped_arguments = ordinary_object.clone();
1513
1514        // 4. Perform DefinePropertyOrThrow(obj, "length", PropertyDescriptor { [[Value]]: 𝔽(len),
1515        // [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
1516        unmapped_arguments.property(
1517            length_property_key,
1518            Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE,
1519        );
1520
1521        // 7. Perform ! DefinePropertyOrThrow(obj, @@iterator, PropertyDescriptor {
1522        // [[Value]]: %Array.prototype.values%, [[Writable]]: true, [[Enumerable]]: false,
1523        // [[Configurable]]: true }).
1524        unmapped_arguments.property(
1525            JsSymbol::iterator().into(),
1526            Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE,
1527        );
1528
1529        let mut mapped_arguments = unmapped_arguments.clone();
1530
1531        // 8. Perform ! DefinePropertyOrThrow(obj, "callee", PropertyDescriptor {
1532        // [[Get]]: %ThrowTypeError%, [[Set]]: %ThrowTypeError%, [[Enumerable]]: false,
1533        // [[Configurable]]: false }).
1534        unmapped_arguments.accessor(
1535            js_string!("callee").into(),
1536            true,
1537            true,
1538            Attribute::NON_ENUMERABLE | Attribute::PERMANENT,
1539        );
1540
1541        // 21. Perform ! DefinePropertyOrThrow(obj, "callee", PropertyDescriptor {
1542        // [[Value]]: func, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
1543        mapped_arguments.property(
1544            js_string!("callee").into(),
1545            Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE,
1546        );
1547
1548        let mut iterator_result = ordinary_object.clone();
1549        iterator_result.property(
1550            js_string!("value").into(),
1551            Attribute::WRITABLE | Attribute::CONFIGURABLE | Attribute::ENUMERABLE,
1552        );
1553        iterator_result.property(
1554            js_string!("done").into(),
1555            Attribute::WRITABLE | Attribute::CONFIGURABLE | Attribute::ENUMERABLE,
1556        );
1557
1558        let mut namespace = ObjectTemplate::new(root_shape);
1559        namespace.property(JsSymbol::to_string_tag().into(), Attribute::empty());
1560
1561        let with_resolvers = {
1562            let mut with_resolvers = ordinary_object.clone();
1563
1564            with_resolvers
1565                // 4. Perform ! CreateDataPropertyOrThrow(obj, "promise", promiseCapability.[[Promise]]).
1566                .property(js_string!("promise").into(), Attribute::all())
1567                // 5. Perform ! CreateDataPropertyOrThrow(obj, "resolve", promiseCapability.[[Resolve]]).
1568                .property(js_string!("resolve").into(), Attribute::all())
1569                // 6. Perform ! CreateDataPropertyOrThrow(obj, "reject", promiseCapability.[[Reject]]).
1570                .property(js_string!("reject").into(), Attribute::all());
1571
1572            with_resolvers
1573        };
1574
1575        let wait_async = {
1576            let mut obj = ordinary_object.clone();
1577
1578            obj.property(js_string!("async").into(), Attribute::all())
1579                .property(js_string!("value").into(), Attribute::all());
1580
1581            obj
1582        };
1583
1584        Self {
1585            iterator_result,
1586            ordinary_object,
1587            array,
1588            number,
1589            string,
1590            symbol,
1591            bigint,
1592            boolean,
1593            regexp,
1594            regexp_without_proto,
1595            unmapped_arguments,
1596            mapped_arguments,
1597            function_with_prototype,
1598            function_prototype,
1599            function,
1600            async_function,
1601            generator_function,
1602            async_generator_function,
1603            function_without_proto,
1604            function_with_prototype_without_proto,
1605            namespace,
1606            with_resolvers,
1607            wait_async,
1608        }
1609    }
1610
1611    /// Cached iterator result template.
1612    ///
1613    /// Transitions:
1614    ///
1615    /// 1. `__proto__`: `Object.prototype`
1616    /// 2. `"done"`: (`WRITABLE`, `CONFIGURABLE`, `ENUMERABLE`)
1617    /// 3. `"value"`: (`WRITABLE`, `CONFIGURABLE`, `ENUMERABLE`)
1618    pub(crate) const fn iterator_result(&self) -> &ObjectTemplate {
1619        &self.iterator_result
1620    }
1621
1622    /// Cached ordinary object template.
1623    ///
1624    /// Transitions:
1625    ///
1626    /// 1. `__proto__`: `Object.prototype`
1627    pub(crate) const fn ordinary_object(&self) -> &ObjectTemplate {
1628        &self.ordinary_object
1629    }
1630
1631    /// Cached array object template.
1632    ///
1633    /// Transitions:
1634    ///
1635    /// 1. `"length"`: (`WRITABLE`, `PERMANENT`,`NON_ENUMERABLE`)
1636    /// 2. `__proto__`: `Array.prototype`
1637    pub(crate) const fn array(&self) -> &ObjectTemplate {
1638        &self.array
1639    }
1640
1641    /// Cached number object template.
1642    ///
1643    /// Transitions:
1644    ///
1645    /// 1. `__proto__`: `Number.prototype`
1646    pub(crate) const fn number(&self) -> &ObjectTemplate {
1647        &self.number
1648    }
1649
1650    /// Cached string object template.
1651    ///
1652    /// Transitions:
1653    ///
1654    /// 1. `"length"`: (`READONLY`, `PERMANENT`,`NON_ENUMERABLE`)
1655    /// 2. `__proto__`: `String.prototype`
1656    pub(crate) const fn string(&self) -> &ObjectTemplate {
1657        &self.string
1658    }
1659
1660    /// Cached symbol object template.
1661    ///
1662    /// Transitions:
1663    ///
1664    /// 1. `__proto__`: `Symbol.prototype`
1665    pub(crate) const fn symbol(&self) -> &ObjectTemplate {
1666        &self.symbol
1667    }
1668
1669    /// Cached bigint object template.
1670    ///
1671    /// Transitions:
1672    ///
1673    /// 1. `__proto__`: `BigInt.prototype`
1674    pub(crate) const fn bigint(&self) -> &ObjectTemplate {
1675        &self.bigint
1676    }
1677
1678    /// Cached boolean object template.
1679    ///
1680    /// Transitions:
1681    ///
1682    /// 1. `__proto__`: `Boolean.prototype`
1683    pub(crate) const fn boolean(&self) -> &ObjectTemplate {
1684        &self.boolean
1685    }
1686
1687    /// Cached regexp object template.
1688    ///
1689    /// Transitions:
1690    ///
1691    /// 1. `"lastIndex"`: (`WRITABLE` , `PERMANENT`,`NON_ENUMERABLE`)
1692    pub(crate) const fn regexp(&self) -> &ObjectTemplate {
1693        &self.regexp
1694    }
1695
1696    /// Cached regexp object template without `__proto__` template.
1697    ///
1698    /// Transitions:
1699    ///
1700    /// 1. `"lastIndex"`: (`WRITABLE` , `PERMANENT`,`NON_ENUMERABLE`)
1701    /// 2. `__proto__`: `RegExp.prototype`
1702    pub(crate) const fn regexp_without_proto(&self) -> &ObjectTemplate {
1703        &self.regexp_without_proto
1704    }
1705
1706    /// Cached unmapped arguments object template.
1707    ///
1708    /// Transitions:
1709    ///
1710    /// 1. `__proto__`: `Object.prototype`
1711    /// 2. `"length"`: (`WRITABLE`, `NON_ENUMERABLE`, `CONFIGURABLE`)
1712    /// 3. `@@iterator`: (`WRITABLE`, `NON_ENUMERABLE`, `CONFIGURABLE`)
1713    /// 4. `get/set` `"callee"`: (`NON_ENUMERABLE`, `PERMANENT`)
1714    pub(crate) const fn unmapped_arguments(&self) -> &ObjectTemplate {
1715        &self.unmapped_arguments
1716    }
1717
1718    /// Cached mapped arguments object template.
1719    ///
1720    /// Transitions:
1721    ///
1722    /// 1. `__proto__`: `Object.prototype`
1723    /// 2. `"length"`: (`WRITABLE`, `NON_ENUMERABLE`, `CONFIGURABLE`)
1724    /// 3. `@@iterator`: (`WRITABLE`, `NON_ENUMERABLE`, `CONFIGURABLE`)
1725    /// 4. `"callee"`: (`WRITABLE`, `NON_ENUMERABLE`, `CONFIGURABLE`)
1726    pub(crate) const fn mapped_arguments(&self) -> &ObjectTemplate {
1727        &self.mapped_arguments
1728    }
1729
1730    /// Cached function object with `"prototype"` property template.
1731    ///
1732    /// Transitions:
1733    ///
1734    /// 1. `"length"`: (`READONLY`, `NON_ENUMERABLE`, `CONFIGURABLE`)
1735    /// 2. `"name"`: (`READONLY`, `NON_ENUMERABLE`, `CONFIGURABLE`)
1736    /// 3. `"prototype"`: (`WRITABLE`, `PERMANENT`, `NON_ENUMERABLE`)
1737    /// 4. `__proto__`: `Function.prototype`
1738    pub(crate) const fn function_with_prototype(&self) -> &ObjectTemplate {
1739        &self.function_with_prototype
1740    }
1741
1742    /// Cached constructor function object template.
1743    ///
1744    /// Transitions:
1745    ///
1746    /// 1. `__proto__`: `Object.prototype`
1747    /// 2. `"constructor"`: (`WRITABLE`, `CONFIGURABLE`, `NON_ENUMERABLE`)
1748    pub(crate) const fn function_prototype(&self) -> &ObjectTemplate {
1749        &self.function_prototype
1750    }
1751
1752    /// Cached function object property template.
1753    ///
1754    /// Transitions:
1755    ///
1756    /// 1. `"length"`: (`READONLY`, `NON_ENUMERABLE`, `CONFIGURABLE`)
1757    /// 2. `"name"`: (`READONLY`, `NON_ENUMERABLE`, `CONFIGURABLE`)
1758    /// 3. `__proto__`: `Function.prototype`
1759    pub(crate) const fn function(&self) -> &ObjectTemplate {
1760        &self.function
1761    }
1762
1763    /// Cached function object property template.
1764    ///
1765    /// Transitions:
1766    ///
1767    /// 1. `"length"`: (`READONLY`, `NON_ENUMERABLE`, `CONFIGURABLE`)
1768    /// 2. `"name"`: (`READONLY`, `NON_ENUMERABLE`, `CONFIGURABLE`)
1769    /// 3. `__proto__`: `AsyncFunction.prototype`
1770    pub(crate) const fn async_function(&self) -> &ObjectTemplate {
1771        &self.async_function
1772    }
1773
1774    /// Cached function object property template.
1775    ///
1776    /// Transitions:
1777    ///
1778    /// 1. `"length"`: (`READONLY`, `NON_ENUMERABLE`, `CONFIGURABLE`)
1779    /// 2. `"name"`: (`READONLY`, `NON_ENUMERABLE`, `CONFIGURABLE`)
1780    /// 3. `"prototype"`: (`WRITABLE`, `PERMANENT`, `NON_ENUMERABLE`)
1781    /// 4. `__proto__`: `GeneratorFunction.prototype`
1782    pub(crate) const fn generator_function(&self) -> &ObjectTemplate {
1783        &self.generator_function
1784    }
1785
1786    /// Cached function object property template.
1787    ///
1788    /// Transitions:
1789    ///
1790    /// 1. `"length"`: (`READONLY`, `NON_ENUMERABLE`, `CONFIGURABLE`)
1791    /// 2. `"name"`: (`READONLY`, `NON_ENUMERABLE`, `CONFIGURABLE`)
1792    /// 3. `"prototype"`: (`WRITABLE`, `PERMANENT`, `NON_ENUMERABLE`)
1793    /// 4. `__proto__`: `AsyncGeneratorFunction.prototype`
1794    pub(crate) const fn async_generator_function(&self) -> &ObjectTemplate {
1795        &self.async_generator_function
1796    }
1797
1798    /// Cached function object without `__proto__` template.
1799    ///
1800    /// Transitions:
1801    ///
1802    /// 1. `"length"`: (`READONLY`, `NON_ENUMERABLE`, `CONFIGURABLE`)
1803    /// 2. `"name"`: (`READONLY`, `NON_ENUMERABLE`, `CONFIGURABLE`)
1804    pub(crate) const fn function_without_proto(&self) -> &ObjectTemplate {
1805        &self.function_without_proto
1806    }
1807
1808    /// Cached function object with `"prototype"` and without `__proto__` template.
1809    ///
1810    /// Transitions:
1811    ///
1812    /// 1. `"length"`: (`READONLY`, `NON_ENUMERABLE`, `CONFIGURABLE`)
1813    /// 2. `"name"`: (`READONLY`, `NON_ENUMERABLE`, `CONFIGURABLE`)
1814    /// 3. `"prototype"`: (`WRITABLE`, `PERMANENT`, `NON_ENUMERABLE`)
1815    pub(crate) const fn function_with_prototype_without_proto(&self) -> &ObjectTemplate {
1816        &self.function_with_prototype_without_proto
1817    }
1818
1819    /// Cached namespace object template.
1820    ///
1821    /// Transitions:
1822    ///
1823    /// 1. `@@toStringTag`: (`READONLY`, `NON_ENUMERABLE`, `PERMANENT`)
1824    pub(crate) const fn namespace(&self) -> &ObjectTemplate {
1825        &self.namespace
1826    }
1827
1828    /// Cached object from the `Promise.withResolvers` method.
1829    ///
1830    /// Transitions:
1831    ///
1832    /// 1. `__proto__`: `Object.prototype`
1833    /// 2. `"promise"`: (`WRITABLE`, `ENUMERABLE`, `CONFIGURABLE`)
1834    /// 3. `"resolve"`: (`WRITABLE`, `ENUMERABLE`, `CONFIGURABLE`)
1835    /// 4. `"reject"`: (`WRITABLE`, `ENUMERABLE`, `CONFIGURABLE`)
1836    pub(crate) const fn with_resolvers(&self) -> &ObjectTemplate {
1837        &self.with_resolvers
1838    }
1839
1840    /// Cached object from the `Atomics.waitAsync` method.
1841    ///
1842    /// Transitions:
1843    ///
1844    /// 1. `__proto__`: `Object.prototype`
1845    /// 2. `"async"`: (`WRITABLE`, `ENUMERABLE`, `CONFIGURABLE`)
1846    /// 3. `"value"`: (`WRITABLE`, `ENUMERABLE`, `CONFIGURABLE`)
1847    pub(crate) const fn wait_async(&self) -> &ObjectTemplate {
1848        &self.wait_async
1849    }
1850}