1pub mod array;
4pub mod array_buffer;
5pub mod async_function;
6pub mod async_generator;
7pub mod async_generator_function;
8pub mod atomics;
9pub mod bigint;
10pub mod boolean;
11pub mod dataview;
12pub mod date;
13pub mod error;
14pub mod eval;
15pub mod finalization_registry;
16pub mod function;
17pub mod generator;
18pub mod generator_function;
19#[cfg(feature = "annex-b")]
20pub mod is_html_dda;
21pub mod iterable;
22pub mod json;
23pub mod map;
24pub mod math;
25pub mod number;
26pub mod object;
27pub mod promise;
28pub mod proxy;
29pub mod reflect;
30pub mod regexp;
31pub mod set;
32pub mod string;
33pub mod symbol;
34pub mod typed_array;
35pub mod uri;
36pub mod weak;
37pub mod weak_map;
38pub mod weak_set;
39
40mod builder;
41
42use builder::BuiltInBuilder;
43use error::Error;
44use num_traits::Zero;
45
46#[cfg(feature = "annex-b")]
47pub mod escape;
48
49#[cfg(feature = "intl")]
50pub mod intl;
51
52#[cfg(any(feature = "intl", feature = "temporal"))]
54pub(crate) mod options;
55
56#[cfg(feature = "temporal")]
57pub mod temporal;
58
59pub(crate) use self::{
60 array::Array,
61 async_function::AsyncFunction,
62 bigint::BigInt,
63 boolean::Boolean,
64 dataview::DataView,
65 date::Date,
66 error::{
67 AggregateError, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, UriError,
68 },
69 eval::Eval,
70 finalization_registry::FinalizationRegistry,
71 function::BuiltInFunctionObject,
72 json::Json,
73 map::Map,
74 math::Math,
75 number::{IsFinite, IsNaN, Number, ParseFloat, ParseInt},
76 object::OrdinaryObject,
77 promise::Promise,
78 proxy::Proxy,
79 reflect::Reflect,
80 regexp::RegExp,
81 set::Set,
82 string::String,
83 symbol::Symbol,
84 typed_array::{
85 BigInt64Array, BigUint64Array, Float32Array, Float64Array, Int8Array, Int16Array,
86 Int32Array, Uint8Array, Uint8ClampedArray, Uint16Array, Uint32Array,
87 },
88};
89
90use crate::{
91 Context, JsResult, JsString, JsValue,
92 builtins::{
93 array::ArrayIterator,
94 array_buffer::{ArrayBuffer, SharedArrayBuffer},
95 async_generator::AsyncGenerator,
96 async_generator_function::AsyncGeneratorFunction,
97 atomics::Atomics,
98 error::r#type::ThrowTypeError,
99 generator::Generator,
100 generator_function::GeneratorFunction,
101 iterable::iterator_constructor::IteratorConstructor,
102 iterable::iterator_helper::IteratorHelper,
103 iterable::wrap_for_valid_iterator::WrapForValidIterator,
104 iterable::{AsyncFromSyncIterator, AsyncIterator, Iterator},
105 map::MapIterator,
106 regexp::RegExpStringIterator,
107 set::SetIterator,
108 string::StringIterator,
109 typed_array::BuiltinTypedArray,
110 uri::{DecodeUri, DecodeUriComponent, EncodeUri, EncodeUriComponent},
111 weak::WeakRef,
112 weak_map::WeakMap,
113 weak_set::WeakSet,
114 },
115 context::intrinsics::{Intrinsics, StandardConstructor, StandardConstructors},
116 js_string,
117 object::JsObject,
118 property::{Attribute, PropertyDescriptor},
119 realm::Realm,
120};
121
122pub(crate) trait IntrinsicObject {
129 fn init(realm: &Realm);
134
135 fn get(intrinsics: &Intrinsics) -> JsObject;
137}
138
139pub(crate) trait BuiltInObject: IntrinsicObject {
145 #[allow(clippy::declare_interior_mutable_const)]
152 const NAME: JsString;
153
154 const ATTRIBUTE: Attribute = Attribute::WRITABLE
156 .union(Attribute::NON_ENUMERABLE)
157 .union(Attribute::CONFIGURABLE);
158}
159
160pub(crate) trait BuiltInConstructor: BuiltInObject {
167 const PROTOTYPE_STORAGE_SLOTS: usize;
178
179 const CONSTRUCTOR_STORAGE_SLOTS: usize;
190
191 const CONSTRUCTOR_ARGUMENTS: usize;
193
194 const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor;
196
197 fn constructor(
199 new_target: &JsValue,
200 args: &[JsValue],
201 context: &mut Context,
202 ) -> JsResult<JsValue>;
203}
204
205fn global_binding<B: BuiltInObject>(context: &mut Context) -> JsResult<()> {
206 let name = B::NAME;
207 let attr = B::ATTRIBUTE;
208 let intrinsic = B::get(context.intrinsics());
209 let global_object = context.global_object();
210
211 global_object.define_property_or_throw(
212 name,
213 PropertyDescriptor::builder()
214 .value(intrinsic)
215 .writable(attr.writable())
216 .enumerable(attr.enumerable())
217 .configurable(attr.configurable())
218 .build(),
219 context,
220 )?;
221 Ok(())
222}
223
224pub(crate) fn canonicalize_keyed_collection_key(value: JsValue) -> JsValue {
235 match value.as_number() {
236 Some(n) if n.is_zero() => JsValue::new(0),
237 _ => value,
238 }
239}
240
241impl Realm {
242 pub(crate) fn initialize(&self) {
246 BuiltInFunctionObject::init(self);
247 OrdinaryObject::init(self);
248 Iterator::init(self);
249 AsyncIterator::init(self);
250 AsyncFromSyncIterator::init(self);
251 IteratorConstructor::init(self);
252 WrapForValidIterator::init(self);
253 IteratorHelper::init(self);
254 Math::init(self);
255 Json::init(self);
256 Array::init(self);
257 ArrayIterator::init(self);
258 Proxy::init(self);
259 ArrayBuffer::init(self);
260 SharedArrayBuffer::init(self);
261 BigInt::init(self);
262 Boolean::init(self);
263 Date::init(self);
264 DataView::init(self);
265 Map::init(self);
266 MapIterator::init(self);
267 IsFinite::init(self);
268 IsNaN::init(self);
269 ParseInt::init(self);
270 ParseFloat::init(self);
271 Number::init(self);
272 Eval::init(self);
273 Set::init(self);
274 SetIterator::init(self);
275 String::init(self);
276 StringIterator::init(self);
277 RegExp::init(self);
278 RegExpStringIterator::init(self);
279 BuiltinTypedArray::init(self);
280 Int8Array::init(self);
281 Uint8Array::init(self);
282 Uint8ClampedArray::init(self);
283 Int16Array::init(self);
284 Uint16Array::init(self);
285 Int32Array::init(self);
286 Uint32Array::init(self);
287 BigInt64Array::init(self);
288 BigUint64Array::init(self);
289 #[cfg(feature = "float16")]
290 typed_array::Float16Array::init(self);
291 Float32Array::init(self);
292 Float64Array::init(self);
293 Symbol::init(self);
294 Error::init(self);
295 RangeError::init(self);
296 ReferenceError::init(self);
297 TypeError::init(self);
298 ThrowTypeError::init(self);
299 SyntaxError::init(self);
300 EvalError::init(self);
301 UriError::init(self);
302 AggregateError::init(self);
303 Reflect::init(self);
304 Generator::init(self);
305 GeneratorFunction::init(self);
306 Promise::init(self);
307 AsyncFunction::init(self);
308 AsyncGenerator::init(self);
309 AsyncGeneratorFunction::init(self);
310 EncodeUri::init(self);
311 EncodeUriComponent::init(self);
312 DecodeUri::init(self);
313 DecodeUriComponent::init(self);
314 WeakRef::init(self);
315 WeakMap::init(self);
316 WeakSet::init(self);
317 Atomics::init(self);
318 FinalizationRegistry::init(self);
319
320 #[cfg(feature = "annex-b")]
321 {
322 escape::Escape::init(self);
323 escape::Unescape::init(self);
324 }
325
326 #[cfg(feature = "intl")]
327 {
328 intl::Intl::init(self);
329 intl::Collator::init(self);
330 intl::ListFormat::init(self);
331 intl::Locale::init(self);
332 intl::DateTimeFormat::init(self);
333 intl::Segmenter::init(self);
334 intl::segmenter::Segments::init(self);
335 intl::segmenter::SegmentIterator::init(self);
336 intl::PluralRules::init(self);
337 intl::NumberFormat::init(self);
338 }
339
340 #[cfg(feature = "temporal")]
341 {
342 temporal::Temporal::init(self);
343 temporal::Now::init(self);
344 temporal::Instant::init(self);
345 temporal::Duration::init(self);
346 temporal::PlainDate::init(self);
347 temporal::PlainTime::init(self);
348 temporal::PlainDateTime::init(self);
349 temporal::PlainMonthDay::init(self);
350 temporal::PlainYearMonth::init(self);
351 temporal::ZonedDateTime::init(self);
352 }
353 }
354}
355
356pub(crate) fn set_default_global_bindings(context: &mut Context) -> JsResult<()> {
360 let global_object = context.global_object();
361
362 global_object.define_property_or_throw(
363 js_string!("globalThis"),
364 PropertyDescriptor::builder()
365 .value(context.realm().global_this().clone())
366 .writable(true)
367 .enumerable(false)
368 .configurable(true),
369 context,
370 )?;
371 let restricted = PropertyDescriptor::builder()
372 .writable(false)
373 .enumerable(false)
374 .configurable(false);
375 global_object.define_property_or_throw(
376 js_string!("Infinity"),
377 restricted.clone().value(f64::INFINITY),
378 context,
379 )?;
380 global_object.define_property_or_throw(
381 js_string!("NaN"),
382 restricted.clone().value(f64::NAN),
383 context,
384 )?;
385 global_object.define_property_or_throw(
386 js_string!("undefined"),
387 restricted.value(JsValue::undefined()),
388 context,
389 )?;
390
391 global_binding::<BuiltInFunctionObject>(context)?;
392 global_binding::<OrdinaryObject>(context)?;
393 global_binding::<Math>(context)?;
394 global_binding::<Json>(context)?;
395 global_binding::<Array>(context)?;
396 global_binding::<Proxy>(context)?;
397 global_binding::<ArrayBuffer>(context)?;
398 global_binding::<SharedArrayBuffer>(context)?;
399 global_binding::<BigInt>(context)?;
400 global_binding::<Boolean>(context)?;
401 global_binding::<Date>(context)?;
402 global_binding::<DataView>(context)?;
403 global_binding::<Map>(context)?;
404 global_binding::<IsFinite>(context)?;
405 global_binding::<IsNaN>(context)?;
406 global_binding::<ParseInt>(context)?;
407 global_binding::<ParseFloat>(context)?;
408 global_binding::<Number>(context)?;
409 global_binding::<Eval>(context)?;
410 global_binding::<Set>(context)?;
411 global_binding::<String>(context)?;
412 global_binding::<RegExp>(context)?;
413 global_binding::<BuiltinTypedArray>(context)?;
414 global_binding::<Int8Array>(context)?;
415 global_binding::<Uint8Array>(context)?;
416 global_binding::<Uint8ClampedArray>(context)?;
417 global_binding::<Int16Array>(context)?;
418 global_binding::<Uint16Array>(context)?;
419 global_binding::<Int32Array>(context)?;
420 global_binding::<Uint32Array>(context)?;
421 global_binding::<BigInt64Array>(context)?;
422 global_binding::<BigUint64Array>(context)?;
423 #[cfg(feature = "float16")]
424 global_binding::<typed_array::Float16Array>(context)?;
425 global_binding::<Float32Array>(context)?;
426 global_binding::<Float64Array>(context)?;
427 global_binding::<Symbol>(context)?;
428 global_binding::<Error>(context)?;
429 global_binding::<RangeError>(context)?;
430 global_binding::<ReferenceError>(context)?;
431 global_binding::<TypeError>(context)?;
432 global_binding::<SyntaxError>(context)?;
433 global_binding::<EvalError>(context)?;
434 global_binding::<UriError>(context)?;
435 global_binding::<AggregateError>(context)?;
436 global_binding::<Reflect>(context)?;
437 global_binding::<Promise>(context)?;
438 global_binding::<EncodeUri>(context)?;
439 global_binding::<EncodeUriComponent>(context)?;
440 global_binding::<DecodeUri>(context)?;
441 global_binding::<DecodeUriComponent>(context)?;
442 global_binding::<WeakRef>(context)?;
443 global_binding::<WeakMap>(context)?;
444 global_binding::<WeakSet>(context)?;
445 global_binding::<IteratorConstructor>(context)?;
446 global_binding::<Atomics>(context)?;
447 global_binding::<FinalizationRegistry>(context)?;
448
449 #[cfg(feature = "annex-b")]
450 {
451 global_binding::<escape::Escape>(context)?;
452 global_binding::<escape::Unescape>(context)?;
453 }
454
455 #[cfg(feature = "intl")]
456 global_binding::<intl::Intl>(context)?;
457
458 #[cfg(feature = "temporal")]
459 {
460 global_binding::<temporal::Temporal>(context)?;
461 }
462
463 context.realm().mark_math_pristine();
464
465 Ok(())
466}