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(_: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
142 if let Value::Object(o) = arg(a, 0) {
143 return Ok(match o.borrow().proto.clone() {
144 Some(p) => Value::Object(p),
145 None => Value::Null,
146 });
147 }
148 Ok(Value::Null)
149}
150
151pub(crate) fn reflect_define_property(_: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
153 if let Value::Object(o) = arg(a, 0) {
154 let key = arg(a, 1).to_js_string();
155 if let Value::Object(desc) = arg(a, 2) {
156 if let Some(v) = desc.borrow().props.get("value") {
157 o.borrow_mut().props.insert(key, v.clone());
158 return Ok(Value::Bool(true));
159 }
160 }
161 }
162 Ok(Value::Bool(false))
163}
164
165pub(crate) fn reflect_apply(i: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
173 let func = arg(a, 0);
174 let this = arg(a, 1);
175 let args_val = arg(a, 2);
176 let args = array_like_items(i, &args_val);
177 i.call_value(&func, this, &args)
178}
179
180pub(crate) fn reflect_construct(i: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
182 let func = arg(a, 0);
183 let args_val = arg(a, 1);
184 let args = array_like_items(i, &args_val);
185 i.construct_value(&func, &args)
186}
187
188pub fn mapset_method(is_map: bool, key: &str) -> Value {
190 if is_map {
191 match key {
192 "set" => nv("Map.set", map_set),
193 "get" => nv("Map.get", map_get),
194 "has" => nv("Map.has", map_has),
195 "delete" => nv("Map.delete", map_delete),
196 "clear" => nv("Map.clear", map_clear),
197 "forEach" => nv("Map.forEach", map_for_each),
198 "keys" => nv("Map.keys", map_keys),
199 "values" => nv("Map.values", map_values),
200 "entries" => nv("Map.entries", map_entries),
201 "Symbol(Symbol.iterator)" => nv("[Symbol.iterator]", map_entries),
204 _ => Value::Undefined,
205 }
206 } else {
207 match key {
208 "add" => nv("Set.add", set_add),
209 "has" => nv("Set.has", set_has),
210 "delete" => nv("Set.delete", set_delete),
211 "clear" => nv("Set.clear", set_clear),
212 "forEach" => nv("Set.forEach", set_for_each),
213 "values" => nv("Set.values", set_values),
214 "keys" => nv("Set.values", set_values),
215 "Symbol(Symbol.iterator)" => nv("[Symbol.iterator]", set_values),
217 "union" => nv("Set.union", set_union),
218 "intersection" => nv("Set.intersection", set_intersection),
219 "difference" => nv("Set.difference", set_difference),
220 "symmetricDifference" => nv("Set.symmetricDifference", set_symmetric_difference),
221 "isSubsetOf" => nv("Set.isSubsetOf", set_is_subset_of),
222 "isSupersetOf" => nv("Set.isSupersetOf", set_is_superset_of),
223 "isDisjointFrom" => nv("Set.isDisjointFrom", set_is_disjoint_from),
224 _ => Value::Undefined,
225 }
226 }
227}
228
229pub(crate) fn with_map<R>(this: &Value, f: impl FnOnce(&mut Vec<(Value, Value)>) -> R) -> Option<R> {
233 if let Value::Object(o) = this {
234 let o = unwrap_proxy_target(o);
235 let mut b = o.borrow_mut();
236 if let ObjKind::MapObj(e) = &mut b.kind {
237 return Some(f(e));
238 }
239 }
240 None
241}
242pub(crate) fn with_set<R>(this: &Value, f: impl FnOnce(&mut Vec<Value>) -> R) -> Option<R> {
243 if let Value::Object(o) = this {
244 let o = unwrap_proxy_target(o);
245 let mut b = o.borrow_mut();
246 if let ObjKind::SetObj(s) = &mut b.kind {
247 return Some(f(s));
248 }
249 }
250 None
251}
252
253pub(crate) fn map_set(_: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
254 let k = arg(a, 0);
255 let v = arg(a, 1);
256 with_map(&this, |e| {
257 if let Some(slot) = e.iter_mut().find(|(ek, _)| same_value_zero(ek, &k)) {
258 slot.1 = v.clone();
259 } else {
260 e.push((k.clone(), v.clone()));
261 }
262 });
263 Ok(this) }
265pub(crate) fn map_get(_: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
266 let k = arg(a, 0);
267 Ok(with_map(&this, |e| {
268 e.iter()
269 .find(|(ek, _)| same_value_zero(ek, &k))
270 .map(|(_, v)| v.clone())
271 })
272 .flatten()
273 .unwrap_or(Value::Undefined))
274}
275pub(crate) fn map_has(_: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
276 let k = arg(a, 0);
277 Ok(Value::Bool(
278 with_map(&this, |e| e.iter().any(|(ek, _)| same_value_zero(ek, &k))).unwrap_or(false),
279 ))
280}
281pub(crate) fn map_delete(_: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
282 let k = arg(a, 0);
283 Ok(Value::Bool(
284 with_map(&this, |e| {
285 let before = e.len();
286 e.retain(|(ek, _)| !same_value_zero(ek, &k));
287 e.len() != before
288 })
289 .unwrap_or(false),
290 ))
291}
292pub(crate) fn map_clear(_: &mut Interp, this: Value, _a: &[Value]) -> Result<Value, Value> {
293 with_map(&this, |e| e.clear());
294 Ok(Value::Undefined)
295}
296pub(crate) fn map_keys(_: &mut Interp, this: Value, _a: &[Value]) -> Result<Value, Value> {
297 Ok(Value::Object(make_iterator(
298 with_map(&this, |e| e.iter().map(|(k, _)| k.clone()).collect()).unwrap_or_default(),
299 )))
300}
301pub(crate) fn map_values(_: &mut Interp, this: Value, _a: &[Value]) -> Result<Value, Value> {
302 Ok(Value::Object(make_iterator(
303 with_map(&this, |e| e.iter().map(|(_, v)| v.clone()).collect()).unwrap_or_default(),
304 )))
305}
306pub(crate) fn map_entries(_: &mut Interp, this: Value, _a: &[Value]) -> Result<Value, Value> {
307 let entries = with_map(&this, |e| e.clone()).unwrap_or_default();
308 let arr: Vec<Value> = entries
309 .into_iter()
310 .map(|(k, v)| Value::Object(Obj::array(vec![k, v])))
311 .collect();
312 Ok(Value::Object(make_iterator(arr)))
313}
314pub(crate) fn map_for_each(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
318 let cb = arg(a, 0);
319 let this_arg = arg(a, 1);
320 let entries = with_map(&this, |e| e.clone()).unwrap_or_default();
321 for (k, v) in entries {
322 it.call_value(&cb, this_arg.clone(), &[v, k, this.clone()])?;
323 }
324 Ok(Value::Undefined)
325}
326
327pub(crate) fn set_add(_: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
328 let v = arg(a, 0);
329 with_set(&this, |s| {
330 if !s.iter().any(|x| same_value_zero(x, &v)) {
331 s.push(v.clone());
332 }
333 });
334 Ok(this)
335}
336pub(crate) fn set_has(_: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
337 let v = arg(a, 0);
338 Ok(Value::Bool(
339 with_set(&this, |s| s.iter().any(|x| same_value_zero(x, &v))).unwrap_or(false),
340 ))
341}
342pub(crate) fn set_delete(_: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
343 let v = arg(a, 0);
344 Ok(Value::Bool(
345 with_set(&this, |s| {
346 let before = s.len();
347 s.retain(|x| !same_value_zero(x, &v));
348 s.len() != before
349 })
350 .unwrap_or(false),
351 ))
352}
353pub(crate) fn set_clear(_: &mut Interp, this: Value, _a: &[Value]) -> Result<Value, Value> {
354 with_set(&this, |s| s.clear());
355 Ok(Value::Undefined)
356}
357pub(crate) fn set_values(_: &mut Interp, this: Value, _a: &[Value]) -> Result<Value, Value> {
358 Ok(Value::Object(make_iterator(
359 with_set(&this, |s| s.clone()).unwrap_or_default(),
360 )))
361}
362pub(crate) fn set_for_each(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
365 let cb = arg(a, 0);
366 let this_arg = arg(a, 1);
367 let items = with_set(&this, |s| s.clone()).unwrap_or_default();
368 for v in items {
369 it.call_value(&cb, this_arg.clone(), &[v.clone(), v, this.clone()])?;
370 }
371 Ok(Value::Undefined)
372}
373
374pub(crate) fn other_set_items(it: &mut Interp, v: &Value) -> Vec<Value> {
384 if let Value::Object(o) = v {
385 if let ObjKind::SetObj(s) = &o.borrow().kind {
386 return s.clone();
387 }
388 }
389 it.iter_to_vec(v)
390}
391pub(crate) fn set_union(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
392 let mut out = with_set(&this, |s| s.clone()).unwrap_or_default();
393 for v in other_set_items(it, &arg(a, 0)) {
394 if !out.iter().any(|x| same_value_zero(x, &v)) {
395 out.push(v);
396 }
397 }
398 Ok(Value::Object(Obj::set_obj(out)))
399}
400pub(crate) fn set_intersection(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
401 let other = other_set_items(it, &arg(a, 0));
402 let mine = with_set(&this, |s| s.clone()).unwrap_or_default();
403 let out = mine
404 .into_iter()
405 .filter(|v| other.iter().any(|x| same_value_zero(x, v)))
406 .collect();
407 Ok(Value::Object(Obj::set_obj(out)))
408}
409pub(crate) fn set_difference(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
410 let other = other_set_items(it, &arg(a, 0));
411 let mine = with_set(&this, |s| s.clone()).unwrap_or_default();
412 let out = mine
413 .into_iter()
414 .filter(|v| !other.iter().any(|x| same_value_zero(x, v)))
415 .collect();
416 Ok(Value::Object(Obj::set_obj(out)))
417}
418pub(crate) fn set_symmetric_difference(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
419 let other = other_set_items(it, &arg(a, 0));
420 let mine = with_set(&this, |s| s.clone()).unwrap_or_default();
421 let mut out: Vec<Value> = mine
422 .iter()
423 .filter(|v| !other.iter().any(|x| same_value_zero(x, v)))
424 .cloned()
425 .collect();
426 for v in other {
427 if !mine.iter().any(|x| same_value_zero(x, &v)) {
428 out.push(v);
429 }
430 }
431 Ok(Value::Object(Obj::set_obj(out)))
432}
433pub(crate) fn set_is_subset_of(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
434 let other = other_set_items(it, &arg(a, 0));
435 let mine = with_set(&this, |s| s.clone()).unwrap_or_default();
436 Ok(Value::Bool(
437 mine.iter().all(|v| other.iter().any(|x| same_value_zero(x, v))),
438 ))
439}
440pub(crate) fn set_is_superset_of(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
441 let other = other_set_items(it, &arg(a, 0));
442 let mine = with_set(&this, |s| s.clone()).unwrap_or_default();
443 Ok(Value::Bool(
444 other.iter().all(|v| mine.iter().any(|x| same_value_zero(x, v))),
445 ))
446}
447pub(crate) fn set_is_disjoint_from(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
448 let other = other_set_items(it, &arg(a, 0));
449 let mine = with_set(&this, |s| s.clone()).unwrap_or_default();
450 Ok(Value::Bool(
451 !mine.iter().any(|v| other.iter().any(|x| same_value_zero(x, v))),
452 ))
453}
454