Skip to main content

boa_engine/builtins/generator_function/
mod.rs

1//! Boa's implementation of ECMAScript's global `GeneratorFunction` object.
2//!
3//! The `GeneratorFunction` constructor creates a new generator function object.
4//! In ECMAScript, every generator function is actually a `GeneratorFunction` object.
5//!
6//! More information:
7//!  - [ECMAScript reference][spec]
8//!  - [MDN documentation][mdn]
9//!
10//! [spec]: https://tc39.es/ecma262/#sec-generatorfunction-objects
11//! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/GeneratorFunction
12
13use crate::{
14    Context, JsResult, JsString,
15    builtins::{BuiltInObject, function::BuiltInFunctionObject},
16    context::intrinsics::{Intrinsics, StandardConstructor, StandardConstructors},
17    object::PROTOTYPE,
18    property::Attribute,
19    realm::Realm,
20    string::StaticJsStrings,
21    symbol::JsSymbol,
22    value::JsValue,
23};
24
25use super::{BuiltInBuilder, BuiltInConstructor, IntrinsicObject};
26
27/// The internal representation of a `Generator` object.
28#[derive(Debug, Clone, Copy)]
29pub struct GeneratorFunction;
30
31impl IntrinsicObject for GeneratorFunction {
32    fn init(realm: &Realm) {
33        BuiltInBuilder::from_standard_constructor::<Self>(realm)
34            .inherits(Some(
35                realm.intrinsics().constructors().function().prototype(),
36            ))
37            .constructor_attributes(Attribute::CONFIGURABLE)
38            .property(
39                PROTOTYPE,
40                realm.intrinsics().objects().generator(),
41                Attribute::CONFIGURABLE,
42            )
43            .property(
44                JsSymbol::to_string_tag(),
45                Self::NAME,
46                Attribute::CONFIGURABLE,
47            )
48            .build();
49    }
50
51    fn get(intrinsics: &Intrinsics) -> crate::object::JsObject {
52        Self::STANDARD_CONSTRUCTOR(intrinsics.constructors()).constructor()
53    }
54}
55
56impl BuiltInObject for GeneratorFunction {
57    const NAME: JsString = StaticJsStrings::GENERATOR_FUNCTION;
58}
59
60impl BuiltInConstructor for GeneratorFunction {
61    const CONSTRUCTOR_ARGUMENTS: usize = 1;
62    const PROTOTYPE_STORAGE_SLOTS: usize = 2;
63    const CONSTRUCTOR_STORAGE_SLOTS: usize = 0;
64
65    const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor =
66        StandardConstructors::generator_function;
67
68    /// `GeneratorFunction ( p1, p2, … , pn, body )`
69    ///
70    /// More information:
71    ///  - [ECMAScript reference][spec]
72    ///
73    /// [spec]: https://tc39.es/ecma262/#sec-generatorfunction
74    fn constructor(
75        new_target: &JsValue,
76        args: &[JsValue],
77        context: &mut Context,
78    ) -> JsResult<JsValue> {
79        let active_function = context.active_function_object().unwrap_or_else(|| {
80            context
81                .intrinsics()
82                .constructors()
83                .generator_function()
84                .constructor()
85        });
86        BuiltInFunctionObject::create_dynamic_function(
87            active_function,
88            new_target,
89            args,
90            false,
91            true,
92            context,
93        )
94        .map(Into::into)
95    }
96}