1use super::*;
4
5pub(crate) fn same_value_zero(a: &Value, b: &Value) -> bool {
9 if let (Value::Number(x), Value::Number(y)) = (a, b) {
10 if x.is_nan() && y.is_nan() {
11 return true;
12 }
13 }
14 a.strict_eq(b)
15}
16
17pub(crate) fn map_ctor(it: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
24 let mut entries: Vec<(Value, Value)> = Vec::new();
25 if let Some(init) = a.first() {
27 for pair in it.iter_to_vec(init) {
28 if !matches!(pair, Value::Object(_)) {
29 return Err(it.error(alloc::format!(
30 "Iterator value {} is not an entry object",
31 pair.to_js_string()
32 )));
33 }
34 let k = key_at(&pair, 0);
35 let v = key_at(&pair, 1);
36 if !entries.iter().any(|(ek, _)| same_value_zero(ek, &k)) {
37 entries.push((k, v));
38 }
39 }
40 }
41 Ok(Value::Object(Obj::map_obj(entries)))
42}
43
44pub(crate) fn set_ctor(it: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
45 let mut items: Vec<Value> = Vec::new();
46 if let Some(init) = a.first() {
47 for v in it.iter_to_vec(init) {
48 if !items.iter().any(|x| same_value_zero(x, &v)) {
49 items.push(v);
50 }
51 }
52 }
53 Ok(Value::Object(Obj::set_obj(items)))
54}
55
56pub(crate) fn key_at(v: &Value, i: usize) -> Value {
58 if let Value::Object(o) = v {
59 if let ObjKind::Array(items) = &o.borrow().kind {
60 return items.get(i).cloned().unwrap_or(Value::Undefined);
61 }
62 }
63 Value::Undefined
64}
65
66pub(crate) fn proxy_ctor(i: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
70 let target = match arg(a, 0) {
71 Value::Object(o) => o,
72 _ => return Err(i.error("Cannot create proxy with a non-object as target")),
73 };
74 let handler = match arg(a, 1) {
75 Value::Object(o) => o,
76 _ => return Err(i.error("Cannot create proxy with a non-object as handler")),
77 };
78 Ok(Value::Object(Obj::proxy(target, handler)))
79}
80
81pub(crate) fn reflect_get(i: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
83 let target = arg(a, 0);
84 let key = arg(a, 1).to_js_string();
85 i.get_property(&target, &key)
86}
87
88pub(crate) fn reflect_set(i: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
93 let target = arg(a, 0);
94 let key = arg(a, 1).to_js_string();
95 let val = arg(a, 2);
96 let blocked = matches!(&target, Value::Object(o) if {
97 let b = o.borrow();
98 (b.frozen) || ((b.sealed || b.non_extensible) && !b.props.contains_key(&key))
100 });
101 i.set_property(&target, &key, val);
102 Ok(Value::Bool(!blocked))
103}
104
105pub(crate) fn reflect_has(i: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
107 let target = arg(a, 0);
108 let key = arg(a, 1);
109 i.eval_binary(&super::super::ast::BinaryOp::In, key, target)
110}
111
112pub(crate) fn reflect_delete_property(_: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
116 if let Value::Object(o) = arg(a, 0) {
117 if o.borrow().frozen || o.borrow().sealed {
118 return Ok(Value::Bool(false));
119 }
120 let key = arg(a, 1).to_js_string();
121 let mut b = o.borrow_mut();
122 if let Some(attr) = b.attrs.get(&key) {
123 if !attr.configurable {
124 return Ok(Value::Bool(false));
125 }
126 }
127 b.props.shift_remove(&key);
128 b.accessors.shift_remove(&key);
129 b.attrs.shift_remove(&key);
130 return Ok(Value::Bool(true));
131 }
132 Ok(Value::Bool(false))
133}
134
135pub(crate) fn reflect_own_keys(i: &mut Interp, t: Value, a: &[Value]) -> Result<Value, Value> {
137 object_keys(i, t, a)
138}
139
140pub(crate) fn reflect_get_prototype_of(it: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
142 if let Value::Object(o) = arg(a, 0) {
143 return Ok(super::extra_static::effective_proto(it, &o));
144 }
145 Ok(Value::Null)
146}
147
148pub(crate) fn reflect_define_property(_: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
150 if let Value::Object(o) = arg(a, 0) {
151 let key = arg(a, 1).to_js_string();
152 if let Value::Object(desc) = arg(a, 2) {
153 if let Some(v) = desc.borrow().props.get("value") {
154 o.borrow_mut().props.insert(key, v.clone());
155 return Ok(Value::Bool(true));
156 }
157 }
158 }
159 Ok(Value::Bool(false))
160}
161
162pub(crate) fn reflect_apply(i: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
170 let func = arg(a, 0);
171 let this = arg(a, 1);
172 let args_val = arg(a, 2);
173 let args = array_like_items(i, &args_val);
174 i.call_value(&func, this, &args)
175}
176
177pub(crate) fn reflect_construct(i: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
179 let func = arg(a, 0);
180 let args_val = arg(a, 1);
181 let args = array_like_items(i, &args_val);
182 let new_target = match a.get(2) {
184 Some(nt @ Value::Object(_)) => nt.clone(),
185 _ => func.clone(),
186 };
187 i.construct_with_target(&func, &args, &new_target)
188}
189
190pub fn mapset_method(is_map: bool, key: &str) -> Value {
192 if is_map {
193 match key {
194 "set" => nv("Map.set", map_set),
195 "get" => nv("Map.get", map_get),
196 "has" => nv("Map.has", map_has),
197 "delete" => nv("Map.delete", map_delete),
198 "clear" => nv("Map.clear", map_clear),
199 "forEach" => nv("Map.forEach", map_for_each),
200 "keys" => nv("Map.keys", map_keys),
201 "values" => nv("Map.values", map_values),
202 "entries" => nv("Map.entries", map_entries),
203 "Symbol(Symbol.iterator)" => nv("[Symbol.iterator]", map_entries),
206 _ => Value::Undefined,
207 }
208 } else {
209 match key {
210 "add" => nv("Set.add", set_add),
211 "has" => nv("Set.has", set_has),
212 "delete" => nv("Set.delete", set_delete),
213 "clear" => nv("Set.clear", set_clear),
214 "forEach" => nv("Set.forEach", set_for_each),
215 "values" => nv("Set.values", set_values),
216 "keys" => nv("Set.values", set_values),
217 "Symbol(Symbol.iterator)" => nv("[Symbol.iterator]", set_values),
219 "union" => nv("Set.union", set_union),
220 "intersection" => nv("Set.intersection", set_intersection),
221 "difference" => nv("Set.difference", set_difference),
222 "symmetricDifference" => nv("Set.symmetricDifference", set_symmetric_difference),
223 "isSubsetOf" => nv("Set.isSubsetOf", set_is_subset_of),
224 "isSupersetOf" => nv("Set.isSupersetOf", set_is_superset_of),
225 "isDisjointFrom" => nv("Set.isDisjointFrom", set_is_disjoint_from),
226 _ => Value::Undefined,
227 }
228 }
229}
230
231pub(crate) fn with_map<R>(this: &Value, f: impl FnOnce(&mut Vec<(Value, Value)>) -> R) -> Option<R> {
235 if let Value::Object(o) = this {
236 let o = unwrap_proxy_target(o);
237 let mut b = o.borrow_mut();
238 if let ObjKind::MapObj(e) = &mut b.kind {
239 return Some(f(e));
240 }
241 }
242 None
243}
244pub(crate) fn with_set<R>(this: &Value, f: impl FnOnce(&mut Vec<Value>) -> R) -> Option<R> {
245 if let Value::Object(o) = this {
246 let o = unwrap_proxy_target(o);
247 let mut b = o.borrow_mut();
248 if let ObjKind::SetObj(s) = &mut b.kind {
249 return Some(f(s));
250 }
251 }
252 None
253}
254
255pub(crate) fn map_set(_: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
256 let k = arg(a, 0);
257 let v = arg(a, 1);
258 with_map(&this, |e| {
259 if let Some(slot) = e.iter_mut().find(|(ek, _)| same_value_zero(ek, &k)) {
260 slot.1 = v.clone();
261 } else {
262 e.push((k.clone(), v.clone()));
263 }
264 });
265 Ok(this) }
267pub(crate) fn map_get(_: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
268 let k = arg(a, 0);
269 Ok(with_map(&this, |e| {
270 e.iter()
271 .find(|(ek, _)| same_value_zero(ek, &k))
272 .map(|(_, v)| v.clone())
273 })
274 .flatten()
275 .unwrap_or(Value::Undefined))
276}
277pub(crate) fn map_has(_: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
278 let k = arg(a, 0);
279 Ok(Value::Bool(
280 with_map(&this, |e| e.iter().any(|(ek, _)| same_value_zero(ek, &k))).unwrap_or(false),
281 ))
282}
283pub(crate) fn map_delete(_: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
284 let k = arg(a, 0);
285 Ok(Value::Bool(
286 with_map(&this, |e| {
287 let before = e.len();
288 e.retain(|(ek, _)| !same_value_zero(ek, &k));
289 e.len() != before
290 })
291 .unwrap_or(false),
292 ))
293}
294pub(crate) fn map_clear(_: &mut Interp, this: Value, _a: &[Value]) -> Result<Value, Value> {
295 with_map(&this, |e| e.clear());
296 Ok(Value::Undefined)
297}
298pub(crate) fn map_keys(_: &mut Interp, this: Value, _a: &[Value]) -> Result<Value, Value> {
299 Ok(Value::Object(make_iterator(
300 with_map(&this, |e| e.iter().map(|(k, _)| k.clone()).collect()).unwrap_or_default(),
301 )))
302}
303pub(crate) fn map_values(_: &mut Interp, this: Value, _a: &[Value]) -> Result<Value, Value> {
304 Ok(Value::Object(make_iterator(
305 with_map(&this, |e| e.iter().map(|(_, v)| v.clone()).collect()).unwrap_or_default(),
306 )))
307}
308pub(crate) fn map_entries(_: &mut Interp, this: Value, _a: &[Value]) -> Result<Value, Value> {
309 let entries = with_map(&this, |e| e.clone()).unwrap_or_default();
310 let arr: Vec<Value> = entries
311 .into_iter()
312 .map(|(k, v)| Value::Object(Obj::array(vec![k, v])))
313 .collect();
314 Ok(Value::Object(make_iterator(arr)))
315}
316pub(crate) fn map_for_each(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
320 let cb = arg(a, 0);
321 let this_arg = arg(a, 1);
322 let entries = with_map(&this, |e| e.clone()).unwrap_or_default();
323 for (k, v) in entries {
324 it.call_value(&cb, this_arg.clone(), &[v, k, this.clone()])?;
325 }
326 Ok(Value::Undefined)
327}
328
329pub(crate) fn set_add(_: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
330 let v = arg(a, 0);
331 with_set(&this, |s| {
332 if !s.iter().any(|x| same_value_zero(x, &v)) {
333 s.push(v.clone());
334 }
335 });
336 Ok(this)
337}
338pub(crate) fn set_has(_: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
339 let v = arg(a, 0);
340 Ok(Value::Bool(
341 with_set(&this, |s| s.iter().any(|x| same_value_zero(x, &v))).unwrap_or(false),
342 ))
343}
344pub(crate) fn set_delete(_: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
345 let v = arg(a, 0);
346 Ok(Value::Bool(
347 with_set(&this, |s| {
348 let before = s.len();
349 s.retain(|x| !same_value_zero(x, &v));
350 s.len() != before
351 })
352 .unwrap_or(false),
353 ))
354}
355pub(crate) fn set_clear(_: &mut Interp, this: Value, _a: &[Value]) -> Result<Value, Value> {
356 with_set(&this, |s| s.clear());
357 Ok(Value::Undefined)
358}
359pub(crate) fn set_values(_: &mut Interp, this: Value, _a: &[Value]) -> Result<Value, Value> {
360 Ok(Value::Object(make_iterator(
361 with_set(&this, |s| s.clone()).unwrap_or_default(),
362 )))
363}
364pub(crate) fn set_for_each(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
367 let cb = arg(a, 0);
368 let this_arg = arg(a, 1);
369 let items = with_set(&this, |s| s.clone()).unwrap_or_default();
370 for v in items {
371 it.call_value(&cb, this_arg.clone(), &[v.clone(), v, this.clone()])?;
372 }
373 Ok(Value::Undefined)
374}
375
376pub(crate) fn other_set_items(it: &mut Interp, v: &Value) -> Vec<Value> {
386 if let Value::Object(o) = v {
387 if let ObjKind::SetObj(s) = &o.borrow().kind {
388 return s.clone();
389 }
390 }
391 it.iter_to_vec(v)
392}
393pub(crate) fn set_union(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
394 let mut out = with_set(&this, |s| s.clone()).unwrap_or_default();
395 for v in other_set_items(it, &arg(a, 0)) {
396 if !out.iter().any(|x| same_value_zero(x, &v)) {
397 out.push(v);
398 }
399 }
400 Ok(Value::Object(Obj::set_obj(out)))
401}
402pub(crate) fn set_intersection(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
403 let other = other_set_items(it, &arg(a, 0));
404 let mine = with_set(&this, |s| s.clone()).unwrap_or_default();
405 let out = mine
406 .into_iter()
407 .filter(|v| other.iter().any(|x| same_value_zero(x, v)))
408 .collect();
409 Ok(Value::Object(Obj::set_obj(out)))
410}
411pub(crate) fn set_difference(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
412 let other = other_set_items(it, &arg(a, 0));
413 let mine = with_set(&this, |s| s.clone()).unwrap_or_default();
414 let out = mine
415 .into_iter()
416 .filter(|v| !other.iter().any(|x| same_value_zero(x, v)))
417 .collect();
418 Ok(Value::Object(Obj::set_obj(out)))
419}
420pub(crate) fn set_symmetric_difference(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
421 let other = other_set_items(it, &arg(a, 0));
422 let mine = with_set(&this, |s| s.clone()).unwrap_or_default();
423 let mut out: Vec<Value> = mine
424 .iter()
425 .filter(|v| !other.iter().any(|x| same_value_zero(x, v)))
426 .cloned()
427 .collect();
428 for v in other {
429 if !mine.iter().any(|x| same_value_zero(x, &v)) {
430 out.push(v);
431 }
432 }
433 Ok(Value::Object(Obj::set_obj(out)))
434}
435pub(crate) fn set_is_subset_of(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
436 let other = other_set_items(it, &arg(a, 0));
437 let mine = with_set(&this, |s| s.clone()).unwrap_or_default();
438 Ok(Value::Bool(
439 mine.iter().all(|v| other.iter().any(|x| same_value_zero(x, v))),
440 ))
441}
442pub(crate) fn set_is_superset_of(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
443 let other = other_set_items(it, &arg(a, 0));
444 let mine = with_set(&this, |s| s.clone()).unwrap_or_default();
445 Ok(Value::Bool(
446 other.iter().all(|v| mine.iter().any(|x| same_value_zero(x, v))),
447 ))
448}
449pub(crate) fn set_is_disjoint_from(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
450 let other = other_set_items(it, &arg(a, 0));
451 let mine = with_set(&this, |s| s.clone()).unwrap_or_default();
452 Ok(Value::Bool(
453 !mine.iter().any(|v| other.iter().any(|x| same_value_zero(x, v))),
454 ))
455}
456