atmos/os_lib/js/builtins/
weak_symbol.rs1use super::*;
4
5pub(crate) fn wm_get(_it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
10 let entries = wm_entries(&this);
11 let key = arg(a, 0);
12 if let Value::Object(arr) = entries {
13 let items = match &arr.borrow().kind {
14 super::super::value::ObjKind::Array(v) => v.clone(),
15 _ => alloc::vec![],
16 };
17 for pair in items {
18 if let Value::Object(p) = pair {
19 let b = p.borrow();
20 if let super::super::value::ObjKind::Array(kv) = &b.kind {
21 if kv.len() == 2 && kv[0].same_ref(&key) {
22 return Ok(kv[1].clone());
23 }
24 }
25 }
26 }
27 }
28 Ok(Value::Undefined)
29}
30pub(crate) fn wm_set(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
31 let key = arg(a, 0);
32 let val = arg(a, 1);
33 if !matches!(key, Value::Object(_)) {
37 return Err(it.error("Invalid value used as weak map key"));
38 }
39 let entries = wm_entries(&this);
40 if let Value::Object(arr) = &entries {
41 let found = {
43 let b = arr.borrow();
44 if let super::super::value::ObjKind::Array(items) = &b.kind {
45 items.iter().enumerate().find_map(|(i, p)| {
46 if let Value::Object(pair) = p {
47 if let super::super::value::ObjKind::Array(kv) = &pair.borrow().kind {
48 if kv.len() == 2 && kv[0].same_ref(&key) {
49 return Some(i);
50 }
51 }
52 }
53 None
54 })
55 } else { None }
56 };
57 if let Some(i) = found {
58 let new_pair = Obj::array(alloc::vec![key, val]);
59 if let super::super::value::ObjKind::Array(items) = &mut arr.borrow_mut().kind {
60 items[i] = Value::Object(new_pair);
61 }
62 } else {
63 let new_pair = Obj::array(alloc::vec![key, val]);
64 if let super::super::value::ObjKind::Array(items) = &mut arr.borrow_mut().kind {
65 items.push(Value::Object(new_pair));
66 }
67 }
68 }
69 Ok(this)
70}
71pub(crate) fn wm_has(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
72 let key = arg(a, 0);
73 let got = wm_get(it, this, core::slice::from_ref(&key))?;
74 Ok(Value::Bool(!matches!(got, Value::Undefined)))
75}
76pub(crate) fn wm_delete(_it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
77 let key = arg(a, 0);
78 let entries = wm_entries(&this);
79 if let Value::Object(arr) = entries {
80 let mut b = arr.borrow_mut();
81 if let super::super::value::ObjKind::Array(items) = &mut b.kind {
82 let before = items.len();
83 items.retain(|p| {
84 if let Value::Object(pair) = p {
85 if let super::super::value::ObjKind::Array(kv) = &pair.borrow().kind {
86 return !kv[0].same_ref(&key);
87 }
88 }
89 true
90 });
91 return Ok(Value::Bool(items.len() < before));
92 }
93 }
94 Ok(Value::Bool(false))
95}
96pub(crate) fn wm_entries(this: &Value) -> Value {
97 if let Value::Object(o) = this {
98 let o = unwrap_proxy_target(o);
99 let b = o.borrow();
100 b.props.get("_e").cloned().unwrap_or(Value::Undefined)
101 } else {
102 Value::Undefined
103 }
104}
105pub(crate) fn weakmap_ctor(it: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
108 let obj = Obj::plain();
109 {
110 let mut b = obj.borrow_mut();
111 b.props.insert("_e".into(), Value::Object(Obj::array(alloc::vec![])));
112 b.props.insert("get".into(), nv("get", wm_get));
113 b.props.insert("set".into(), nv("set", wm_set));
114 b.props.insert("has".into(), nv("has", wm_has));
115 b.props.insert("delete".into(), nv("delete", wm_delete));
116 }
117 let result = Value::Object(obj);
118 if let Some(init) = a.first() {
119 for pair in it.iter_to_vec(init) {
120 let k = key_at(&pair, 0);
121 let v = key_at(&pair, 1);
122 wm_set(it, result.clone(), &[k, v])?;
123 }
124 }
125 Ok(result)
126}
127
128pub(crate) fn ws_add(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
130 let val = arg(a, 0);
131 if !matches!(val, Value::Object(_)) {
133 return Err(it.error("Invalid value used in weak set"));
134 }
135 if let Value::Object(arr) = wm_entries(&this) {
136 let already = if let super::super::value::ObjKind::Array(items) = &arr.borrow().kind {
137 items.iter().any(|v| v.same_ref(&val))
138 } else { false };
139 if !already {
140 if let super::super::value::ObjKind::Array(items) = &mut arr.borrow_mut().kind {
141 items.push(val);
142 }
143 }
144 }
145 Ok(this)
146}
147pub(crate) fn ws_has(_it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
148 let val = arg(a, 0);
149 if let Value::Object(arr) = wm_entries(&this) {
150 if let super::super::value::ObjKind::Array(items) = &arr.borrow().kind {
151 return Ok(Value::Bool(items.iter().any(|v| v.same_ref(&val))));
152 }
153 }
154 Ok(Value::Bool(false))
155}
156pub(crate) fn ws_delete(_it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
157 let val = arg(a, 0);
158 if let Value::Object(arr) = wm_entries(&this) {
159 if let super::super::value::ObjKind::Array(items) = &mut arr.borrow_mut().kind {
160 let before = items.len();
161 items.retain(|v| !v.same_ref(&val));
162 return Ok(Value::Bool(items.len() < before));
163 }
164 }
165 Ok(Value::Bool(false))
166}
167pub(crate) fn weakset_ctor(it: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
170 let obj = Obj::plain();
171 {
172 let mut b = obj.borrow_mut();
173 b.props.insert("_e".into(), Value::Object(Obj::array(alloc::vec![])));
174 b.props.insert("add".into(), nv("add", ws_add));
175 b.props.insert("has".into(), nv("has", ws_has));
176 b.props.insert("delete".into(), nv("delete", ws_delete));
177 }
178 let result = Value::Object(obj);
179 if let Some(init) = a.first() {
180 for v in it.iter_to_vec(init) {
181 ws_add(it, result.clone(), &[v])?;
182 }
183 }
184 Ok(result)
185}
186
187pub(crate) fn wr_deref(_it: &mut Interp, this: Value, _a: &[Value]) -> Result<Value, Value> {
189 if let Value::Object(o) = &this {
190 return Ok(o.borrow().props.get("_t").cloned().unwrap_or(Value::Undefined));
191 }
192 Ok(Value::Undefined)
193}
194pub(crate) fn weakref_ctor(_it: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
195 let target = arg(a, 0);
196 let obj = Obj::plain();
197 obj.borrow_mut().props.insert("_t".into(), target);
198 obj.borrow_mut().props.insert("deref".into(), nv("deref", wr_deref));
199 Ok(Value::Object(obj))
200}
201
202pub(crate) static SYMBOL_CTR: spin::Mutex<u64> = spin::Mutex::new(0);
204pub(crate) fn symbol_fn(_it: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
205 let label = arg(a, 0).to_js_string();
206 let id = {
207 let mut ctr = SYMBOL_CTR.lock();
208 *ctr += 1;
209 *ctr
210 };
211 let s = if label == "undefined" {
213 alloc::format!("Symbol(@{})", id)
214 } else {
215 alloc::format!("Symbol({},@{})", label, id)
216 };
217 Ok(Value::str(&s))
218}
219pub(crate) fn symbol_for(_it: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
220 let key = arg(a, 0).to_js_string();
221 Ok(Value::str(alloc::format!("Symbol({})", key)))
222}
223pub(crate) fn symbol_key_for(_it: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
230 let s = arg(a, 0).to_js_string();
231 if let Some(inner) = s.strip_prefix("Symbol(").and_then(|s| s.strip_suffix(')')) {
232 if !inner.contains(",@") {
233 return Ok(Value::str(inner));
234 }
235 }
236 Ok(Value::Undefined)
237}
238
239pub(crate) fn symbol_species_getter(_it: &mut Interp, this: Value, _a: &[Value]) -> Result<Value, Value> {
241 Ok(this)
242}