1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
use crate::{
builtins::{
array, boolean, console, function,
function::NativeFunctionData,
json, math, number, object, regexp, string, symbol,
value::{ToValue, Value, ValueData},
},
environment::{
declarative_environment_record::DeclarativeEnvironmentRecord,
global_environment_record::GlobalEnvironmentRecord,
lexical_environment::LexicalEnvironment,
object_environment_record::ObjectEnvironmentRecord,
},
};
use gc::{Gc, GcCell};
use std::collections::{hash_map::HashMap, hash_set::HashSet};
#[derive(Debug)]
pub struct Realm {
pub global_obj: Value,
pub global_env: Gc<GcCell<Box<GlobalEnvironmentRecord>>>,
pub environment: LexicalEnvironment,
}
impl Realm {
pub fn create() -> Realm {
let global = ValueData::new_obj(None);
let global_env = new_global_environment(global.clone(), global.clone());
let new_realm = Realm {
global_obj: global.clone(),
global_env,
environment: LexicalEnvironment::new(global),
};
new_realm.create_instrinsics();
new_realm
}
fn create_instrinsics(&self) {
let global = &self.global_obj;
function::init(global);
global.set_field_slice("Array", array::create_constructor(global));
global.set_field_slice("Boolean", boolean::create_constructor(global));
global.set_field_slice("JSON", json::create_constructor(global));
global.set_field_slice("Math", math::create_constructor(global));
global.set_field_slice("Number", number::create_constructor(global));
global.set_field_slice("Object", object::create_constructor(global));
global.set_field_slice("RegExp", regexp::create_constructor(global));
global.set_field_slice("String", string::create_constructor(global));
global.set_field_slice("Symbol", symbol::create_constructor(global));
global.set_field_slice("console", console::create_constructor(global));
}
pub fn register_global_func(self, func_name: &str, func: NativeFunctionData) -> Self {
self.global_obj
.set_field(func_name.to_value(), func.to_value());
self
}
}
fn new_global_environment(
global: Value,
this_value: Value,
) -> Gc<GcCell<Box<GlobalEnvironmentRecord>>> {
let obj_rec = Box::new(ObjectEnvironmentRecord {
bindings: global,
outer_env: None,
with_environment: false,
});
let dcl_rec = Box::new(DeclarativeEnvironmentRecord {
env_rec: HashMap::new(),
outer_env: None,
});
Gc::new(GcCell::new(Box::new(GlobalEnvironmentRecord {
object_record: obj_rec,
global_this_binding: this_value,
declarative_record: dcl_rec,
var_names: HashSet::new(),
})))
}