Skip to main content

just_engine/runner/ds/
realm.rs

1use crate::runner::ds::env_record::new_global_environment;
2use crate::runner::ds::error::JErrorType;
3use crate::runner::ds::lex_env::JsLexEnvironmentType;
4use crate::runner::ds::object::{object_create, JsObjectType, ObjectType};
5use crate::runner::ds::object_property::{
6    PropertyDescriptor, PropertyDescriptorData, PropertyDescriptorSetter, PropertyKey,
7};
8use crate::runner::ds::operations::object::define_property_or_throw;
9use crate::runner::ds::value::{JsNumberType, JsValue};
10use std::cell::RefCell;
11use std::collections::HashMap;
12use std::hash::{Hash, Hasher};
13use std::rc::Rc;
14
15pub enum WellKnownIntrinsics {
16    Array,
17    ArrayBuffer,
18    ArrayBufferPrototype,
19    ArrayIteratorPrototype,
20    ArrayPrototype,
21    ArrayProtoValues,
22    Boolean,
23    BooleanPrototype,
24    Date,
25    DatePrototype,
26    DecodeURI,
27    DecodeURIComponent,
28    EncodeURI,
29    EncodeURIComponent,
30    Error,
31    ErrorPrototype,
32    Function,
33    FunctionPrototype,
34    Generator,
35    GeneratorFunction,
36    GeneratorPrototype,
37    IsFinite,
38    IsNaN,
39    IteratorPrototype,
40    JSON,
41    Map,
42    MapIteratorPrototype,
43    MapPrototype,
44    Math,
45    Number,
46    NumberPrototype,
47    Object,
48    ObjectPrototype,
49    ObjProtoToString,
50    ParseFloat,
51    ParseInt,
52    Promise,
53    PromisePrototype,
54    RangeError,
55    RangeErrorPrototype,
56    ReferenceError,
57    ReferenceErrorPrototype,
58    RegExp,
59    RegExpPrototype,
60    Set,
61    SetIteratorPrototype,
62    SetPrototype,
63    String,
64    StringIteratorPrototype,
65    StringPrototype,
66    Symbol,
67    SymbolPrototype,
68    SyntaxError,
69    SyntaxErrorPrototype,
70    ThrowTypeError,
71    TypeError,
72    TypeErrorPrototype,
73    URIError,
74    URIErrorPrototype,
75}
76impl WellKnownIntrinsics {
77    pub fn value(&self) -> JsObjectType {
78        match self {
79            WellKnownIntrinsics::ObjectPrototype => Rc::new(RefCell::new(ObjectType::Ordinary(
80                Box::new(object_create(None)),
81            ))),
82            _ => todo!(), // WellKnownIntrinsics::ThrowTypeError => {}
83                          // WellKnownIntrinsics::Array => {}
84                          // WellKnownIntrinsics::ArrayBuffer => {}
85                          // WellKnownIntrinsics::ArrayBufferPrototype => {}
86                          // WellKnownIntrinsics::ArrayIteratorPrototype => {}
87                          // WellKnownIntrinsics::ArrayPrototype => {}
88                          // WellKnownIntrinsics::ArrayProtoValues => {}
89                          // WellKnownIntrinsics::Boolean => {}
90                          // WellKnownIntrinsics::BooleanPrototype => {}
91                          // WellKnownIntrinsics::Date => {}
92                          // WellKnownIntrinsics::DatePrototype => {}
93                          // WellKnownIntrinsics::DecodeURI => {}
94                          // WellKnownIntrinsics::DecodeURIComponent => {}
95                          // WellKnownIntrinsics::EncodeURI => {}
96                          // WellKnownIntrinsics::EncodeURIComponent => {}
97                          // WellKnownIntrinsics::Error => {}
98                          // WellKnownIntrinsics::ErrorPrototype => {}
99                          // WellKnownIntrinsics::Function => {}
100                          // WellKnownIntrinsics::FunctionPrototype => {}
101                          // WellKnownIntrinsics::Generator => {}
102                          // WellKnownIntrinsics::GeneratorFunction => {}
103                          // WellKnownIntrinsics::GeneratorPrototype => {}
104                          // WellKnownIntrinsics::IsFinite => {}
105                          // WellKnownIntrinsics::IsNaN => {}
106                          // WellKnownIntrinsics::IteratorPrototype => {}
107                          // WellKnownIntrinsics::JSON => {}
108                          // WellKnownIntrinsics::Map => {}
109                          // WellKnownIntrinsics::MapIteratorPrototype => {}
110                          // WellKnownIntrinsics::MapPrototype => {}
111                          // WellKnownIntrinsics::Math => {}
112                          // WellKnownIntrinsics::Number => {}
113                          // WellKnownIntrinsics::NumberPrototype => {}
114                          // WellKnownIntrinsics::Object => {}
115                          // WellKnownIntrinsics::ObjProtoToString => {}
116                          // WellKnownIntrinsics::ParseFloat => {}
117                          // WellKnownIntrinsics::ParseInt => {}
118                          // WellKnownIntrinsics::Promise => {}
119                          // WellKnownIntrinsics::PromisePrototype => {}
120                          // WellKnownIntrinsics::RangeError => {}
121                          // WellKnownIntrinsics::RangeErrorPrototype => {}
122                          // WellKnownIntrinsics::ReferenceError => {}
123                          // WellKnownIntrinsics::ReferenceErrorPrototype => {}
124                          // WellKnownIntrinsics::RegExp => {}
125                          // WellKnownIntrinsics::RegExpPrototype => {}
126                          // WellKnownIntrinsics::Set => {}
127                          // WellKnownIntrinsics::SetIteratorPrototype => {}
128                          // WellKnownIntrinsics::SetPrototype => {}
129                          // WellKnownIntrinsics::String => {}
130                          // WellKnownIntrinsics::StringIteratorPrototype => {}
131                          // WellKnownIntrinsics::StringPrototype => {}
132                          // WellKnownIntrinsics::Symbol => {}
133                          // WellKnownIntrinsics::SymbolPrototype => {}
134                          // WellKnownIntrinsics::SyntaxError => {}
135                          // WellKnownIntrinsics::SyntaxErrorPrototype => {}
136                          // WellKnownIntrinsics::TypeError => {}
137                          // WellKnownIntrinsics::TypeErrorPrototype => {}
138                          // WellKnownIntrinsics::URIError => {}
139                          // WellKnownIntrinsics::URIErrorPrototype => {}
140        }
141    }
142}
143impl PartialEq for WellKnownIntrinsics {
144    fn eq(&self, _other: &Self) -> bool {
145        todo!()
146    }
147}
148impl Eq for WellKnownIntrinsics {}
149impl Hash for WellKnownIntrinsics {
150    fn hash<H: Hasher>(&self, _state: &mut H) {
151        todo!()
152    }
153}
154
155pub type JsCodeRealmType = Rc<RefCell<CodeRealm>>;
156
157pub struct CodeRealm {
158    pub intrinsics: HashMap<WellKnownIntrinsics, JsObjectType>,
159    pub global_this: Option<JsObjectType>,
160    pub global_env: Option<JsLexEnvironmentType>,
161    // template_map
162}
163impl CodeRealm {
164    pub fn new() -> Self {
165        CodeRealm {
166            intrinsics: create_intrinsics(),
167            global_this: None,
168            global_env: None,
169        }
170    }
171
172    pub fn get_intrinsics_value(&self, int_name: &WellKnownIntrinsics) -> &JsObjectType {
173        self.intrinsics.get(int_name).unwrap()
174    }
175}
176
177fn insert_into_realm(
178    map: &mut HashMap<WellKnownIntrinsics, JsObjectType>,
179    int: WellKnownIntrinsics,
180) {
181    let v = int.value();
182    map.insert(int, v);
183}
184
185pub fn create_intrinsics() -> HashMap<WellKnownIntrinsics, JsObjectType> {
186    let mut intrinsics = HashMap::new();
187    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::ObjectPrototype);
188    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::Array);
189    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::ArrayBuffer);
190    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::ArrayBufferPrototype);
191    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::ArrayIteratorPrototype);
192    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::ArrayPrototype);
193    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::ArrayProtoValues);
194    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::Boolean);
195    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::BooleanPrototype);
196    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::Date);
197    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::DatePrototype);
198    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::DecodeURI);
199    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::DecodeURIComponent);
200    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::EncodeURI);
201    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::EncodeURIComponent);
202    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::Error);
203    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::ErrorPrototype);
204    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::Function);
205    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::FunctionPrototype);
206    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::Generator);
207    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::GeneratorFunction);
208    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::GeneratorPrototype);
209    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::IsFinite);
210    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::IsNaN);
211    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::IteratorPrototype);
212    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::JSON);
213    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::Map);
214    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::MapIteratorPrototype);
215    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::MapPrototype);
216    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::Math);
217    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::Number);
218    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::NumberPrototype);
219    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::Object);
220    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::ObjProtoToString);
221    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::ParseFloat);
222    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::ParseInt);
223    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::Promise);
224    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::PromisePrototype);
225    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::RangeError);
226    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::RangeErrorPrototype);
227    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::ReferenceError);
228    insert_into_realm(
229        &mut intrinsics,
230        WellKnownIntrinsics::ReferenceErrorPrototype,
231    );
232    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::RegExp);
233    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::RegExpPrototype);
234    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::Set);
235    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::SetIteratorPrototype);
236    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::SetPrototype);
237    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::String);
238    insert_into_realm(
239        &mut intrinsics,
240        WellKnownIntrinsics::StringIteratorPrototype,
241    );
242    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::StringPrototype);
243    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::Symbol);
244    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::SymbolPrototype);
245    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::SyntaxError);
246    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::SyntaxErrorPrototype);
247    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::ThrowTypeError);
248    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::TypeError);
249    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::TypeErrorPrototype);
250    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::URIError);
251    insert_into_realm(&mut intrinsics, WellKnownIntrinsics::URIErrorPrototype);
252
253    intrinsics
254}
255
256pub fn set_realm_global_object(r: &mut CodeRealm, global_obj: Option<JsObjectType>) {
257    let (final_global_obj, inner_global_obj) = if let Some(g) = global_obj {
258        let inner = g.clone();
259        (Some(g), inner)
260    } else {
261        let intrinsic = r.get_intrinsics_value(&WellKnownIntrinsics::ObjectPrototype).clone();
262        (Some(intrinsic.clone()), intrinsic)
263    };
264    r.global_this = final_global_obj;
265    r.global_env = Some(new_global_environment(inner_global_obj));
266}
267
268pub fn set_default_global_bindings(r: &mut CodeRealm) -> Result<(), JErrorType> {
269    // Get intrinsic values first to avoid borrow conflicts
270    let is_finite_intrinsic = r.get_intrinsics_value(&WellKnownIntrinsics::IsFinite).clone();
271
272    if let Some(global_obj) = &mut r.global_this {
273        define_property_or_throw(
274            (**global_obj).borrow_mut().as_js_object_mut(),
275            PropertyKey::Str("Infinity".to_string()),
276            PropertyDescriptorSetter::new_from_property_descriptor(PropertyDescriptor::Data(
277                PropertyDescriptorData {
278                    value: JsValue::Number(JsNumberType::PositiveInfinity),
279                    writable: false,
280                    enumerable: false,
281                    configurable: false,
282                },
283            )),
284        )?;
285        define_property_or_throw(
286            (**global_obj).borrow_mut().as_js_object_mut(),
287            PropertyKey::Str("NaN".to_string()),
288            PropertyDescriptorSetter::new_from_property_descriptor(PropertyDescriptor::Data(
289                PropertyDescriptorData {
290                    value: JsValue::Number(JsNumberType::NaN),
291                    writable: false,
292                    enumerable: false,
293                    configurable: false,
294                },
295            )),
296        )?;
297        define_property_or_throw(
298            (**global_obj).borrow_mut().as_js_object_mut(),
299            PropertyKey::Str("undefined".to_string()),
300            PropertyDescriptorSetter::new_from_property_descriptor(PropertyDescriptor::Data(
301                PropertyDescriptorData {
302                    value: JsValue::Undefined,
303                    writable: false,
304                    enumerable: false,
305                    configurable: false,
306                },
307            )),
308        )?;
309        define_property_or_throw(
310            (**global_obj).borrow_mut().as_js_object_mut(),
311            PropertyKey::Str("isFinite".to_string()),
312            PropertyDescriptorSetter::new_from_property_descriptor(PropertyDescriptor::Data(
313                PropertyDescriptorData {
314                    value: JsValue::Object(is_finite_intrinsic),
315                    writable: false,
316                    enumerable: false,
317                    configurable: false,
318                },
319            )),
320        )?;
321        todo!()
322    }
323    Ok(())
324}