boa/builtins/error/
reference.rs

1//! This module implements the global `ReferenceError` object.
2//!
3//! Indicates an error that occurs when de-referencing an invalid reference
4//!
5//! More information:
6//!  - [MDN documentation][mdn]
7//!  - [ECMAScript reference][spec]
8//!
9//! [spec]: https://tc39.es/ecma262/#sec-native-error-types-used-in-this-standard-referenceerror
10//! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError
11
12use crate::{
13    builtins::BuiltIn,
14    context::StandardObjects,
15    object::{internal_methods::get_prototype_from_constructor, ConstructorBuilder, ObjectData},
16    profiler::BoaProfiler,
17    property::Attribute,
18    Context, JsResult, JsValue,
19};
20
21#[derive(Debug, Clone, Copy)]
22pub(crate) struct ReferenceError;
23
24impl BuiltIn for ReferenceError {
25    const NAME: &'static str = "ReferenceError";
26
27    fn attribute() -> Attribute {
28        Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE
29    }
30
31    fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) {
32        let _timer = BoaProfiler::global().start_event(Self::NAME, "init");
33
34        let error_prototype = context.standard_objects().error_object().prototype();
35        let attribute = Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE;
36        let reference_error_object = ConstructorBuilder::with_standard_object(
37            context,
38            Self::constructor,
39            context.standard_objects().reference_error_object().clone(),
40        )
41        .name(Self::NAME)
42        .length(Self::LENGTH)
43        .inherit(error_prototype.into())
44        .property("name", Self::NAME, attribute)
45        .property("message", "", attribute)
46        .build();
47
48        (Self::NAME, reference_error_object.into(), Self::attribute())
49    }
50}
51
52impl ReferenceError {
53    /// The amount of arguments this function object takes.
54    pub(crate) const LENGTH: usize = 1;
55
56    /// Create a new error object.
57    pub(crate) fn constructor(
58        new_target: &JsValue,
59        args: &[JsValue],
60        context: &mut Context,
61    ) -> JsResult<JsValue> {
62        let prototype =
63            get_prototype_from_constructor(new_target, StandardObjects::error_object, context)?;
64        let obj = context.construct_object();
65        obj.set_prototype_instance(prototype.into());
66        let this = JsValue::new(obj);
67        if let Some(message) = args.get(0) {
68            if !message.is_undefined() {
69                this.set_field("message", message.to_string(context)?, false, context)?;
70            }
71        }
72
73        // This value is used by console.log and other routines to match Object type
74        // to its Javascript Identifier (global constructor method name)
75        this.set_data(ObjectData::error());
76        Ok(this)
77    }
78}