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}