1use super::*;
4
5pub(crate) fn arr_at(it: &mut Interp, t: Value, a: &[Value]) -> Result<Value, Value> {
7 let items = generic_array_items(it, &t);
8 let n = arg(a, 0).to_number() as i64;
9 let len = items.len() as i64;
10 let idx = if n < 0 { len + n } else { n };
11 if idx >= 0 && idx < len {
12 Ok(items[idx as usize].clone())
13 } else {
14 Ok(Value::Undefined)
15 }
16}
17pub(crate) fn arr_find_last(it: &mut Interp, t: Value, a: &[Value]) -> Result<Value, Value> {
18 let items = generic_array_items(it, &t);
19 let f = arg(a, 0);
20 let this_arg = arg(a, 1);
21 for i in (0..items.len()).rev() {
22 if it
23 .call_value(
24 &f,
25 this_arg.clone(),
26 &[items[i].clone(), Value::Number(i as f64), t.clone()],
27 )?
28 .truthy()
29 {
30 return Ok(items[i].clone());
31 }
32 }
33 Ok(Value::Undefined)
34}
35pub(crate) fn arr_find_last_index(it: &mut Interp, t: Value, a: &[Value]) -> Result<Value, Value> {
36 let items = generic_array_items(it, &t);
37 let f = arg(a, 0);
38 let this_arg = arg(a, 1);
39 for i in (0..items.len()).rev() {
40 if it
41 .call_value(
42 &f,
43 this_arg.clone(),
44 &[items[i].clone(), Value::Number(i as f64), t.clone()],
45 )?
46 .truthy()
47 {
48 return Ok(Value::Number(i as f64));
49 }
50 }
51 Ok(Value::Number(-1.0))
52}
53pub(crate) fn arr_flat_map(it: &mut Interp, t: Value, a: &[Value]) -> Result<Value, Value> {
54 let items = generic_array_items(it, &t);
55 let f = arg(a, 0);
56 let this_arg = arg(a, 1);
57 let mut out: Vec<Value> = Vec::new();
58 for (i, v) in items.iter().enumerate() {
59 let r = it.call_value(
60 &f,
61 this_arg.clone(),
62 &[v.clone(), Value::Number(i as f64), t.clone()],
63 )?;
64 let inner = if let Value::Object(o) = &r {
65 if let ObjKind::Array(items) = &o.borrow().kind {
66 Some(items.clone())
67 } else {
68 None
69 }
70 } else {
71 None
72 };
73 match inner {
74 Some(arr) => out.extend(arr),
75 None => out.push(r),
76 }
77 }
78 let a_obj = array_species_create(it, &t, 0)?;
79 populate_array_species(it, &a_obj, out)
80}
81pub fn make_iterator(items: Vec<Value>) -> super::super::value::ObjRef {
89 let o = Obj::host("iterator");
90 o.borrow_mut().props.insert("_items".into(), Value::Object(Obj::array(items)));
91 o.borrow_mut().props.insert("_pos".into(), Value::Number(0.0));
92 o
93}
94pub fn iterator_next(_it: &mut Interp, this: Value, _a: &[Value]) -> Result<Value, Value> {
95 if let Value::Object(o) = &this {
96 let items = o.borrow().props.get("_items").cloned();
97 let pos = o
98 .borrow()
99 .props
100 .get("_pos")
101 .map(|v| v.to_number() as usize)
102 .unwrap_or(0);
103 if let Some(Value::Object(arr)) = items {
104 let item = if let ObjKind::Array(v) = &arr.borrow().kind {
105 v.get(pos).cloned()
106 } else {
107 None
108 };
109 if let Some(value) = item {
110 o.borrow_mut().props.insert("_pos".into(), Value::Number((pos + 1) as f64));
111 return Ok(iter_result(value, false));
112 }
113 }
114 }
115 Ok(iter_result(Value::Undefined, true))
116}
117pub fn iterator_self(_it: &mut Interp, this: Value, _a: &[Value]) -> Result<Value, Value> {
118 Ok(this)
119}
120pub(crate) fn iterator_remaining(this: &Value) -> Vec<Value> {
127 if let Value::Object(o) = this {
128 let items = o.borrow().props.get("_items").cloned();
129 let pos = o
130 .borrow()
131 .props
132 .get("_pos")
133 .map(|v| v.to_number() as usize)
134 .unwrap_or(0);
135 if let Some(Value::Object(arr)) = items {
136 let rest: Option<Vec<Value>> = if let ObjKind::Array(v) = &arr.borrow().kind {
137 Some(v.iter().skip(pos).cloned().collect())
138 } else {
139 None
140 };
141 if let Some(rest) = rest {
142 let len = if let ObjKind::Array(v) = &arr.borrow().kind { v.len() } else { pos };
143 o.borrow_mut().props.insert("_pos".into(), Value::Number(len as f64));
144 return rest;
145 }
146 }
147 }
148 Vec::new()
149}
150pub fn iterator_map(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
152 let cb = arg(a, 0);
153 let items = iterator_remaining(&this);
154 let mut out = Vec::with_capacity(items.len());
155 for (i, v) in items.into_iter().enumerate() {
156 out.push(it.call_value(&cb, Value::Undefined, &[v, Value::Number(i as f64)])?);
157 }
158 Ok(Value::Object(make_iterator(out)))
159}
160pub fn iterator_filter(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
162 let cb = arg(a, 0);
163 let items = iterator_remaining(&this);
164 let mut out = Vec::new();
165 for (i, v) in items.into_iter().enumerate() {
166 let keep = it.call_value(&cb, Value::Undefined, &[v.clone(), Value::Number(i as f64)])?;
167 if keep.truthy() {
168 out.push(v);
169 }
170 }
171 Ok(Value::Object(make_iterator(out)))
172}
173pub fn iterator_take(_it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
175 let n = arg(a, 0).to_number();
176 let n = if n.is_finite() && n > 0.0 { n as usize } else { 0 };
177 let items = iterator_remaining(&this);
178 Ok(Value::Object(make_iterator(items.into_iter().take(n).collect())))
179}
180pub fn iterator_drop(_it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
182 let n = arg(a, 0).to_number();
183 let n = if n.is_finite() && n > 0.0 { n as usize } else { 0 };
184 let items = iterator_remaining(&this);
185 Ok(Value::Object(make_iterator(items.into_iter().skip(n).collect())))
186}
187pub fn iterator_to_array(_it: &mut Interp, this: Value, _a: &[Value]) -> Result<Value, Value> {
189 Ok(Value::Object(Obj::array(iterator_remaining(&this))))
190}
191pub fn iterator_for_each(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
193 let cb = arg(a, 0);
194 let items = iterator_remaining(&this);
195 for (i, v) in items.into_iter().enumerate() {
196 it.call_value(&cb, Value::Undefined, &[v, Value::Number(i as f64)])?;
197 }
198 Ok(Value::Undefined)
199}
200pub fn iterator_flat_map(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
206 let cb = arg(a, 0);
207 let items = iterator_remaining(&this);
208 let mut out = Vec::new();
209 for (i, v) in items.into_iter().enumerate() {
210 let mapped = it.call_value(&cb, Value::Undefined, &[v, Value::Number(i as f64)])?;
211 out.extend(it.iter_to_vec(&mapped));
212 }
213 Ok(Value::Object(make_iterator(out)))
214}
215pub fn iterator_some(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
220 let cb = arg(a, 0);
221 let items = iterator_remaining(&this);
222 for (i, v) in items.into_iter().enumerate() {
223 let r = it.call_value(&cb, Value::Undefined, &[v, Value::Number(i as f64)])?;
224 if r.truthy() {
225 return Ok(Value::Bool(true));
226 }
227 }
228 Ok(Value::Bool(false))
229}
230pub fn iterator_every(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
231 let cb = arg(a, 0);
232 let items = iterator_remaining(&this);
233 for (i, v) in items.into_iter().enumerate() {
234 let r = it.call_value(&cb, Value::Undefined, &[v, Value::Number(i as f64)])?;
235 if !r.truthy() {
236 return Ok(Value::Bool(false));
237 }
238 }
239 Ok(Value::Bool(true))
240}
241pub fn iterator_find(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
242 let cb = arg(a, 0);
243 let items = iterator_remaining(&this);
244 for (i, v) in items.into_iter().enumerate() {
245 let r = it.call_value(&cb, Value::Undefined, &[v.clone(), Value::Number(i as f64)])?;
246 if r.truthy() {
247 return Ok(v);
248 }
249 }
250 Ok(Value::Undefined)
251}
252pub fn iterator_reduce(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
254 let cb = arg(a, 0);
255 let items = iterator_remaining(&this);
256 let mut iter = items.into_iter().enumerate();
257 let mut acc = if a.len() > 1 {
258 arg(a, 1)
259 } else {
260 match iter.next() {
261 Some((_, v)) => v,
262 None => return Err(it.error("Reduce of empty iterator with no initial value")),
263 }
264 };
265 for (i, v) in iter {
266 acc = it.call_value(&cb, Value::Undefined, &[acc, v, Value::Number(i as f64)])?;
267 }
268 Ok(acc)
269}
270pub(crate) fn arr_entries(it: &mut Interp, t: Value, _a: &[Value]) -> Result<Value, Value> {
271 let out: Vec<Value> = generic_array_items(it, &t)
272 .into_iter()
273 .enumerate()
274 .map(|(i, v)| Value::Object(Obj::array(alloc::vec![Value::Number(i as f64), v])))
275 .collect();
276 Ok(Value::Object(make_iterator(out)))
277}
278pub(crate) fn arr_keys(it: &mut Interp, t: Value, _a: &[Value]) -> Result<Value, Value> {
279 let n = generic_array_items(it, &t).len();
280 Ok(Value::Object(make_iterator(
281 (0..n).map(|i| Value::Number(i as f64)).collect(),
282 )))
283}
284pub(crate) fn arr_values(it: &mut Interp, t: Value, _a: &[Value]) -> Result<Value, Value> {
285 let items = generic_array_items(it, &t);
286 Ok(Value::Object(make_iterator(items)))
287}
288pub(crate) fn arr_reduce_right(it: &mut Interp, t: Value, a: &[Value]) -> Result<Value, Value> {
289 let items = generic_array_items(it, &t);
290 let f = arg(a, 0);
291 let (mut acc, start) = if a.len() > 1 {
292 (arg(a, 1), items.len())
293 } else if items.is_empty() {
294 return Err(it.error("Reduce of empty array with no initial value"));
295 } else {
296 (items[items.len() - 1].clone(), items.len() - 1)
297 };
298 for i in (0..start).rev() {
299 acc = it.call_value(
300 &f,
301 Value::Undefined,
302 &[acc, items[i].clone(), Value::Number(i as f64), t.clone()],
303 )?;
304 }
305 Ok(acc)
306}
307
308pub(crate) fn str_at(_it: &mut Interp, t: Value, a: &[Value]) -> Result<Value, Value> {
310 let chars: Vec<char> = this_str(&t).chars().collect();
311 let n = arg(a, 0).to_number() as i64;
312 let len = chars.len() as i64;
313 let idx = if n < 0 { len + n } else { n };
314 if idx >= 0 && idx < len {
315 Ok(Value::str(chars[idx as usize].to_string()))
316 } else {
317 Ok(Value::Undefined)
318 }
319}
320
321pub(crate) fn resolve_maybe_thenable(
329 it: &mut Interp,
330 item: &Value,
331) -> Option<PromiseRc<PromiseRefCell<PromiseState>>> {
332 if let Some(s) = this_promise_state(item) {
333 return Some(s);
334 }
335 let then_fn = if matches!(item, Value::Object(_)) {
340 it.get_property(item, "then").unwrap_or(Value::Undefined)
341 } else {
342 Value::Undefined
343 };
344 let has_then = matches!(&then_fn, Value::Object(f) if f.borrow().is_callable());
345 if has_then {
346 let s = new_pending();
347 it.promise_resolve(&s, item.clone());
348 Some(s)
349 } else {
350 None
351 }
352}
353pub(crate) fn promise_all_settled_static(it: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
354 let items = it.iter_to_vec(&arg(a, 0));
355 let result = new_pending();
356 it.run_microtasks();
357 let mut out: Vec<Value> = Vec::new();
358 for item in items {
359 let o = Obj::plain();
360 {
361 let mut b = o.borrow_mut();
362 match resolve_maybe_thenable(it, &item) {
363 Some(s) => {
364 let st = s.borrow();
365 match st.status {
366 PromiseStatus::Rejected => {
367 b.props.insert("status".into(), Value::str("rejected"));
368 b.props.insert("reason".into(), st.value.clone());
369 }
370 _ => {
371 b.props.insert("status".into(), Value::str("fulfilled"));
372 b.props.insert("value".into(), st.value.clone());
373 }
374 }
375 }
376 None => {
377 b.props.insert("status".into(), Value::str("fulfilled"));
378 b.props.insert("value".into(), item.clone());
379 }
380 }
381 }
382 out.push(Value::Object(o));
383 }
384 it.promise_resolve(&result, Value::Object(Obj::array(out)));
385 Ok(Value::Object(Obj::promise(result)))
386}
387pub(crate) fn promise_race_static(it: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
388 let items = it.iter_to_vec(&arg(a, 0));
389 let result = new_pending();
390 it.run_microtasks();
391 for item in items {
392 match resolve_maybe_thenable(it, &item) {
393 Some(s) => {
394 let (status, val) = {
395 let b = s.borrow();
396 (b.status, b.value.clone())
397 };
398 match status {
399 PromiseStatus::Fulfilled => {
400 it.promise_resolve(&result, val);
401 return Ok(Value::Object(Obj::promise(result)));
402 }
403 PromiseStatus::Rejected => {
404 it.promise_reject(&result, val);
405 return Ok(Value::Object(Obj::promise(result)));
406 }
407 PromiseStatus::Pending => {}
408 }
409 }
410 None => {
411 it.promise_resolve(&result, item.clone());
412 return Ok(Value::Object(Obj::promise(result)));
413 }
414 }
415 }
416 Ok(Value::Object(Obj::promise(result)))
417}
418pub(crate) fn promise_any_static(it: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
423 let items = it.iter_to_vec(&arg(a, 0));
424 let result = new_pending();
425 it.run_microtasks();
426 let mut reasons: Vec<Value> = Vec::new();
427 for item in items {
428 match resolve_maybe_thenable(it, &item) {
429 Some(s) => {
430 let (status, val) = {
431 let b = s.borrow();
432 (b.status, b.value.clone())
433 };
434 match status {
435 PromiseStatus::Fulfilled => {
436 it.promise_resolve(&result, val);
437 return Ok(Value::Object(Obj::promise(result)));
438 }
439 PromiseStatus::Rejected => {
440 reasons.push(val);
441 }
442 PromiseStatus::Pending => {}
443 }
444 }
445 None => {
446 it.promise_resolve(&result, item.clone());
447 return Ok(Value::Object(Obj::promise(result)));
448 }
449 }
450 }
451 let agg = make_aggregate_error(it, reasons, "All promises were rejected");
452 it.promise_reject(&result, agg);
453 Ok(Value::Object(Obj::promise(result)))
454}
455
456pub fn iterator_concat_static(it: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
459 let mut combined = Vec::new();
460 for arg_val in a {
461 let items = it.iter_to_vec(arg_val);
462 combined.extend(items);
463 }
464 Ok(Value::Object(make_iterator(combined)))
465}
466
467pub fn iterator_from_static(it: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
470 let source = arg(a, 0);
471 let items = it.iter_to_vec(&source);
472 Ok(Value::Object(make_iterator(items)))
473}