1use super::*;
5
6impl Interp {
7 pub fn promise_resolve(&mut self, state: &Rc<RefCell<PromiseState>>, value: Value) {
9 if state.borrow().status != PromiseStatus::Pending {
10 return;
11 }
12 if let Value::Object(o) = &value {
14 let inner = match &o.borrow().kind {
15 ObjKind::PromiseObj(s) => Some(s.clone()),
16 _ => None,
17 };
18 if let Some(inner) = inner {
19 let on_f = Value::Object(Obj::resolver(state.clone(), false));
20 let on_r = Value::Object(Obj::resolver(state.clone(), true));
21 self.promise_then(&inner, Some(on_f), Some(on_r));
22 return;
23 }
24 }
25 if matches!(&value, Value::Object(_)) {
33 let then_fn = self.get_property(&value, "then").unwrap_or(Value::Undefined);
39 if matches!(&then_fn, Value::Object(f) if f.borrow().is_callable()) {
40 let on_f = Value::Object(Obj::resolver(state.clone(), false));
41 let on_r = Value::Object(Obj::resolver(state.clone(), true));
42 if let Err(e) = self.call_value(&then_fn, value.clone(), &[on_f, on_r]) {
43 self.promise_reject(state, e);
45 }
46 return;
47 }
48 }
49 let reactions = {
50 let mut b = state.borrow_mut();
51 b.status = PromiseStatus::Fulfilled;
52 b.value = value.clone();
53 core::mem::take(&mut b.reactions)
54 };
55 for r in &reactions {
56 self.schedule_reaction(r, value.clone(), true);
57 }
58 }
59
60 pub fn promise_reject(&mut self, state: &Rc<RefCell<PromiseState>>, reason: Value) {
62 if state.borrow().status != PromiseStatus::Pending {
63 return;
64 }
65 let reactions = {
66 let mut b = state.borrow_mut();
67 b.status = PromiseStatus::Rejected;
68 b.value = reason.clone();
69 core::mem::take(&mut b.reactions)
70 };
71 for r in &reactions {
72 self.schedule_reaction(r, reason.clone(), false);
73 }
74 }
75
76 pub fn promise_then(
78 &mut self,
79 state: &Rc<RefCell<PromiseState>>,
80 on_fulfilled: Option<Value>,
81 on_rejected: Option<Value>,
82 ) -> Value {
83 let result = Rc::new(RefCell::new(PromiseState::pending()));
84 let reaction = Reaction {
85 on_fulfilled,
86 on_rejected,
87 result: result.clone(),
88 };
89 let status = state.borrow().status;
90 match status {
91 PromiseStatus::Pending => state.borrow_mut().reactions.push(reaction),
92 PromiseStatus::Fulfilled => {
93 let v = state.borrow().value.clone();
94 self.schedule_reaction(&reaction, v, true);
95 }
96 PromiseStatus::Rejected => {
97 let v = state.borrow().value.clone();
98 self.schedule_reaction(&reaction, v, false);
99 }
100 }
101 Value::Object(Obj::promise(result))
102 }
103
104 pub(crate) fn schedule_reaction(&self, reaction: &Reaction, value: Value, is_fulfill: bool) {
105 let handler = if is_fulfill {
106 reaction.on_fulfilled.clone()
107 } else {
108 reaction.on_rejected.clone()
109 };
110 self.microtasks.borrow_mut().push_back(Job {
111 handler,
112 arg: value,
113 is_fulfill,
114 result: reaction.result.clone(),
115 });
116 }
117
118 pub(crate) fn run_one_microtask(&mut self) -> bool {
120 let job = self.microtasks.borrow_mut().pop_front();
121 let job = match job {
122 Some(j) => j,
123 None => return false,
124 };
125 match job.handler {
126 Some(h) => match self.call_value(&h, Value::Undefined, &[job.arg]) {
127 Ok(v) => self.promise_resolve(&job.result, v),
128 Err(e) => {
129 if !self.aborted {
130 self.promise_reject(&job.result, e);
131 }
132 }
133 },
134 None => {
135 if job.is_fulfill {
136 self.promise_resolve(&job.result, job.arg);
137 } else {
138 self.promise_reject(&job.result, job.arg);
139 }
140 }
141 }
142 true
143 }
144
145 pub fn run_microtasks(&mut self) {
147 while !self.aborted && self.run_one_microtask() {}
148 }
149
150 pub(crate) fn run_one_macrotask(&mut self) -> bool {
152 let task = self.macrotasks.borrow_mut().pop_front();
153 let (cb, args, _id) = match task {
154 Some(t) => t,
155 None => return false,
156 };
157 self.call_listener(&cb, Value::Undefined, &args, "setTimeout callback");
159 true
160 }
161
162 pub(crate) fn run_intervals(&mut self) -> bool {
164 if self.intervals.is_empty() {
165 return false;
166 }
167 let ids: Vec<u64> = self.intervals.iter().map(|(id, _, _, _)| *id).collect();
168 for id in ids {
169 let entry = self.intervals.iter().position(|(i, _, _, _)| *i == id);
170 if let Some(pos) = entry {
171 let (_, cb, args, remaining) = self.intervals[pos].clone();
172 if remaining == 0 {
173 self.intervals.remove(pos);
174 continue;
175 }
176 self.intervals[pos].3 -= 1;
177 self.call_listener(&cb, Value::Undefined, &args, "setInterval callback");
178 }
179 }
180 self.intervals.iter().any(|(_, _, _, r)| *r > 0)
181 }
182
183 pub fn run_event_loop(&mut self) {
185 loop {
186 self.run_microtasks();
187 if self.aborted {
188 break;
189 }
190 let has_macro = self.run_one_macrotask();
191 let has_interval = self.run_intervals();
192 if !has_macro && !has_interval {
193 break;
194 }
195 }
196 }
197
198 pub(crate) fn chain_suppressed(&mut self, prev: Option<Value>, new_err: Value) -> Value {
203 let Some(suppressed) = prev else {
204 return new_err;
205 };
206 let Some(ctor) = scope_get(&self.global, "SuppressedError") else {
207 return new_err;
208 };
209 self.call_value(&ctor, Value::Undefined, &[new_err.clone(), suppressed, Value::str("")])
210 .unwrap_or(new_err)
211 }
212
213 pub(crate) fn await_value(&mut self, v: Value) -> EvalResult {
214 let state = match &v {
215 Value::Object(o) => match &o.borrow().kind {
216 ObjKind::PromiseObj(s) => Some(s.clone()),
217 _ => None,
218 },
219 _ => None,
220 };
221 let state = match state {
228 Some(s) => s,
229 None => {
230 let new_state = Rc::new(RefCell::new(PromiseState::pending()));
231 self.promise_resolve(&new_state, v);
232 new_state
233 }
234 };
235 loop {
236 let status = state.borrow().status;
237 match status {
238 PromiseStatus::Fulfilled => return Ok(state.borrow().value.clone()),
239 PromiseStatus::Rejected => return Err(state.borrow().value.clone()),
240 PromiseStatus::Pending => {
241 if self.aborted {
242 return Err(Value::Undefined);
243 }
244 let has_micro = self.run_one_microtask();
246 let has_macro = self.run_one_macrotask();
247 let has_interval = self.run_intervals();
248 if !has_micro && !has_macro && !has_interval {
249 return Ok(Value::Undefined);
250 }
251 }
252 }
253 }
254 }
255
256}