Skip to content

Commit 7f8e3aa

Browse files
committed
reuse iterator record in url search params
1 parent de17de0 commit 7f8e3aa

File tree

2 files changed

+7
-113
lines changed

2 files changed

+7
-113
lines changed

core/engine/src/builtins/iterable/mod.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,7 @@ impl IteratorRecord {
575575
/// - [ECMA reference][spec]
576576
///
577577
/// [spec]: https://tc39.es/ecma262/#sec-iteratorstepvalue
578-
pub(crate) fn step_value(&mut self, context: &mut Context) -> JsResult<Option<JsValue>> {
578+
pub fn step_value(&mut self, context: &mut Context) -> JsResult<Option<JsValue>> {
579579
// 1. Let result be ? IteratorStep(iteratorRecord).
580580
if self.step(context)? {
581581
// 2. If result is done, then
@@ -601,11 +601,7 @@ impl IteratorRecord {
601601
/// - [ECMA reference][spec]
602602
///
603603
/// [spec]: https://tc39.es/ecma262/#sec-iteratorclose
604-
pub(crate) fn close(
605-
&self,
606-
completion: JsResult<JsValue>,
607-
context: &mut Context,
608-
) -> JsResult<JsValue> {
604+
pub fn close(&self, completion: JsResult<JsValue>, context: &mut Context) -> JsResult<JsValue> {
609605
// 1. Assert: Type(iteratorRecord.[[Iterator]]) is Object.
610606

611607
// 2. Let iterator be iteratorRecord.[[Iterator]].

core/runtime/src/url.rs

Lines changed: 5 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
#[cfg(test)]
1919
mod tests;
2020

21-
use boa_engine::builtins::iterable::create_iter_result_object;
21+
use boa_engine::builtins::iterable::{IteratorRecord, create_iter_result_object};
2222
use boa_engine::builtins::object::OrdinaryObject;
2323
use boa_engine::class::Class;
2424
use boa_engine::interop::{JsClass, TryFromJsArgument};
@@ -103,110 +103,8 @@ impl<'a> TryFromJsArgument<'a> for OptionalArg {
103103
}
104104
}
105105

106-
#[derive(Debug, Clone)]
107-
struct SyncIterator {
108-
iterator: JsObject,
109-
next: JsObject,
110-
done: bool,
111-
}
112-
113-
#[derive(Debug, Clone)]
114-
struct IteratorStep {
115-
done: bool,
116-
value: JsValue,
117-
}
118-
119-
impl SyncIterator {
120-
fn from_method(
121-
value: &JsValue,
122-
iterator_method: &JsObject,
123-
context: &mut Context,
124-
) -> JsResult<Self> {
125-
let iterator = iterator_method.call(value, &[], context)?;
126-
let Some(iterator) = iterator.as_object() else {
127-
return Err(js_error!(TypeError: "returned iterator is not an object"));
128-
};
129-
130-
let next = iterator.get(js_string!("next"), context)?;
131-
let Some(next) = next.as_object().filter(JsObject::is_callable) else {
132-
return Err(js_error!(
133-
TypeError: "value returned for property of object is not a function"
134-
));
135-
};
136-
137-
Ok(Self {
138-
iterator: iterator.clone(),
139-
next: next.clone(),
140-
done: false,
141-
})
142-
}
143-
144-
fn next_result(
145-
&mut self,
146-
value: Option<&JsValue>,
147-
context: &mut Context,
148-
) -> JsResult<IteratorStep> {
149-
let result = self
150-
.next
151-
.call(
152-
&self.iterator.clone().into(),
153-
value.map_or(&[], std::slice::from_ref),
154-
context,
155-
)
156-
.inspect_err(|_| {
157-
self.done = true;
158-
})?;
159-
160-
let Some(result) = result.as_object() else {
161-
self.done = true;
162-
return Err(js_error!(TypeError: "next value should be an object"));
163-
};
164-
165-
let done = result
166-
.get(js_string!("done"), context)
167-
.inspect_err(|_| {
168-
self.done = true;
169-
})?
170-
.to_boolean();
171-
let value = result.get(js_string!("value"), context).inspect_err(|_| {
172-
self.done = true;
173-
})?;
174-
175-
self.done = done;
176-
177-
Ok(IteratorStep { done, value })
178-
}
179-
180-
fn step_value(&mut self, context: &mut Context) -> JsResult<Option<JsValue>> {
181-
let result = self.next_result(None, context)?;
182-
Ok((!result.done).then_some(result.value))
183-
}
184-
185-
fn close(&self, completion: JsResult<JsValue>, context: &mut Context) -> JsResult<JsValue> {
186-
let return_method = match self.iterator.get_method(js_string!("return"), context) {
187-
Ok(Some(return_method)) => {
188-
return_method.call(&self.iterator.clone().into(), &[], context)
189-
}
190-
Ok(None) => return completion,
191-
Err(err) => {
192-
completion?;
193-
return Err(err);
194-
}
195-
};
196-
197-
let completion = completion?;
198-
let return_value = return_method?;
199-
200-
if return_value.is_object() {
201-
Ok(completion)
202-
} else {
203-
Err(js_error!(TypeError: "inner result was not an object"))
204-
}
205-
}
206-
}
207-
208106
fn close_iterator_with_error<T>(
209-
iterator: &SyncIterator,
107+
iterator: &IteratorRecord,
210108
error: JsError,
211109
context: &mut Context,
212110
) -> JsResult<T> {
@@ -226,8 +124,8 @@ fn collect_sequence_item_pair(
226124
));
227125
};
228126

229-
let mut pair_iterator =
230-
SyncIterator::from_method(&item.clone().into(), &iterator_method, context)?;
127+
let item_value = JsValue::from(item.clone());
128+
let mut pair_iterator = item_value.get_iterator_from_method(&iterator_method, context)?;
231129

232130
let Some(name) = pair_iterator.step_value(context)? else {
233131
return Err(js_error!(
@@ -267,7 +165,7 @@ fn collect_sequence_pairs(
267165
iterator_method: &JsObject,
268166
context: &mut Context,
269167
) -> JsResult<Vec<(JsString, JsString)>> {
270-
let mut items = SyncIterator::from_method(init, iterator_method, context)?;
168+
let mut items = init.get_iterator_from_method(iterator_method, context)?;
271169
let mut pairs = Vec::new();
272170

273171
while let Some(item) = items.step_value(context)? {

0 commit comments

Comments
 (0)