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!(), }
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 }
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 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}