1use super::*;
5
6impl Interp {
7 pub(crate) fn eval_call(
8 &mut self,
9 callee: &Expression,
10 arguments: &[Expression],
11 optional: bool,
12 scope: &Rc<RefCell<Scope>>,
13 this: &Value,
14 ) -> EvalResult {
15 if matches!(callee, Expression::Super) {
17 let sc = self.super_ctor(scope)?;
18 let args = self.eval_arguments(arguments, scope, this)?;
19 return self.call_value(&sc, this.clone(), &args);
20 }
21 if let Expression::Member {
23 object, property, ..
24 } = callee
25 {
26 if matches!(**object, Expression::Super) {
27 let sp = self.super_proto(scope)?;
28 let f = self.get_property(&sp, property)?;
29 let args = self.eval_arguments(arguments, scope, this)?;
30 return self.call_value(&f, this.clone(), &args);
31 }
32 }
33 let (func, call_this, broke) = self.resolve_callee(callee, scope, this)?;
36 if broke {
37 return Ok(Value::Undefined);
38 }
39 if optional && matches!(func, Value::Undefined | Value::Null) {
40 return Ok(Value::Undefined);
41 }
42 let args = self.eval_arguments(arguments, scope, this)?;
43 self.call_value(&func, call_this, &args)
44 }
45
46 pub(crate) fn resolve_callee(
54 &mut self,
55 callee: &Expression,
56 scope: &Rc<RefCell<Scope>>,
57 this: &Value,
58 ) -> Result<(Value, Value, bool), Value> {
59 match callee {
60 Expression::Member {
61 object,
62 property,
63 optional: mopt,
64 } if !matches!(**object, Expression::Super) => {
65 let (obj, broke) = self.eval_chain_object(object, scope, this)?;
66 if broke {
67 return Ok((Value::Undefined, Value::Undefined, true));
68 }
69 if *mopt && matches!(obj, Value::Undefined | Value::Null) {
70 return Ok((Value::Undefined, Value::Undefined, true));
71 }
72 let f = self.get_property_of_expr(&obj, property, object)?;
73 Ok((f, obj, false))
74 }
75 Expression::Index {
76 object,
77 index,
78 optional: iopt,
79 } => {
80 let (obj, broke) = self.eval_chain_object(object, scope, this)?;
81 if broke {
82 return Ok((Value::Undefined, Value::Undefined, true));
83 }
84 if *iopt && matches!(obj, Value::Undefined | Value::Null) {
85 return Ok((Value::Undefined, Value::Undefined, true));
86 }
87 let key = self.eval(index, scope, this)?;
88 let f = self.get_property(&obj, &to_property_key(&key))?;
89 Ok((f, obj, false))
90 }
91 _ => {
92 let (f, broke) = self.eval_chain_object(callee, scope, this)?;
93 Ok((f, Value::Undefined, broke))
94 }
95 }
96 }
97
98 pub(crate) fn eval_chain_object(
104 &mut self,
105 expr: &Expression,
106 scope: &Rc<RefCell<Scope>>,
107 this: &Value,
108 ) -> Result<(Value, bool), Value> {
109 match expr {
110 Expression::Member {
111 object,
112 property,
113 optional,
114 } => {
115 if matches!(**object, Expression::Super) {
116 let sp = self.super_proto(scope)?;
117 return Ok((self.get_property(&sp, property)?, false));
118 }
119 let (obj, broke) = self.eval_chain_object(object, scope, this)?;
120 if broke {
121 return Ok((Value::Undefined, true));
122 }
123 if *optional && matches!(obj, Value::Undefined | Value::Null) {
124 return Ok((Value::Undefined, true));
125 }
126 Ok((self.get_property(&obj, property)?, false))
127 }
128 Expression::Index {
129 object,
130 index,
131 optional,
132 } => {
133 let (obj, broke) = self.eval_chain_object(object, scope, this)?;
134 if broke {
135 return Ok((Value::Undefined, true));
136 }
137 if *optional && matches!(obj, Value::Undefined | Value::Null) {
138 return Ok((Value::Undefined, true));
139 }
140 let key = self.eval(index, scope, this)?;
141 Ok((self.get_property(&obj, &to_property_key(&key))?, false))
142 }
143 Expression::Call {
144 callee,
145 arguments,
146 optional,
147 } => {
148 let involves_super = matches!(**callee, Expression::Super)
149 || matches!(&**callee, Expression::Member { object, .. } if matches!(**object, Expression::Super));
150 if involves_super {
151 return Ok((self.eval(expr, scope, this)?, false));
152 }
153 let (func, call_this, broke) = self.resolve_callee(callee, scope, this)?;
154 if broke {
155 return Ok((Value::Undefined, true));
156 }
157 if *optional && matches!(func, Value::Undefined | Value::Null) {
158 return Ok((Value::Undefined, true));
159 }
160 let args = self.eval_arguments(arguments, scope, this)?;
161 Ok((self.call_value(&func, call_this, &args)?, false))
162 }
163 _ => Ok((self.eval(expr, scope, this)?, false)),
164 }
165 }
166
167 pub(crate) fn eval_arguments(
169 &mut self,
170 arguments: &[Expression],
171 scope: &Rc<RefCell<Scope>>,
172 this: &Value,
173 ) -> Result<Vec<Value>, Value> {
174 let mut args = Vec::with_capacity(arguments.len());
175 for a in arguments {
176 if let Expression::Spread(inner) = a {
177 let v = self.eval(inner, scope, this)?;
178 let items = self.iter_to_vec(&v);
179 args.extend(items);
180 } else {
181 args.push(self.eval(a, scope, this)?);
182 }
183 }
184 Ok(args)
185 }
186
187 pub(crate) fn eval_new(
188 &mut self,
189 callee: &Expression,
190 arguments: &[Expression],
191 scope: &Rc<RefCell<Scope>>,
192 this: &Value,
193 ) -> EvalResult {
194 let func = self.eval(callee, scope, this)?;
195 let args = self.eval_arguments(arguments, scope, this)?;
196 let proxy = match &func {
198 Value::Object(o) => match &o.borrow().kind {
199 ObjKind::Proxy { target, handler } => Some((target.clone(), handler.clone())),
200 _ => None,
201 },
202 _ => None,
203 };
204 if let Some((target, handler)) = proxy {
205 let trap = handler.borrow().props.get("construct").cloned();
206 if let Some(trap) =
207 trap.filter(|t| matches!(t, Value::Object(f) if f.borrow().is_callable()))
208 {
209 let arg_arr = Value::Object(Obj::array(args.clone()));
210 let targs = [
211 Value::Object(target),
212 arg_arr,
213 Value::Object(handler.clone()),
214 ];
215 return self.call_value(&trap, Value::Object(handler), &targs);
216 }
217 return self.construct_object(&Value::Object(target), &args);
218 }
219 self.construct_object(&func, &args)
220 }
221
222 pub fn construct_value(&mut self, func: &Value, args: &[Value]) -> EvalResult {
224 self.construct_object(func, args)
225 }
226
227 pub(crate) fn construct_object(&mut self, func: &Value, args: &[Value]) -> EvalResult {
228 let inst_obj = Obj::plain();
230 if let Value::Object(fo) = func {
231 if let Some(Value::Object(p)) = fo.borrow().props.get("prototype") {
232 inst_obj.borrow_mut().proto = Some(p.clone());
233 }
234 }
235 let inst = Value::Object(inst_obj);
236 self.pending_new_target = Some(func.clone());
242 let ret = self.call_value(func, inst.clone(), args)?;
243 match ret {
244 Value::Object(_) => Ok(ret),
245 _ => Ok(inst),
246 }
247 }
248
249 pub fn call_value(&mut self, func: &Value, this: Value, args: &[Value]) -> EvalResult {
251 self.depth += 1;
252 if self.depth > self.max_depth {
253 self.aborted = true;
254 self.depth -= 1;
255 return Err(Value::Undefined);
256 }
257 let name = match func {
259 Value::Object(o) => o
260 .borrow()
261 .props
262 .get("name")
263 .map(|v| v.to_js_string())
264 .filter(|n| !n.is_empty())
265 .unwrap_or_else(|| String::from("<anonymous>")),
266 _ => String::from("<anonymous>"),
267 };
268 self.call_names.push(name);
269 let result = self.call_value_inner(func, this, args);
270 self.call_names.pop();
271 self.depth -= 1;
272 result
273 }
274
275 pub fn call_listener(
283 &mut self,
284 func: &Value,
285 this: Value,
286 args: &[Value],
287 context: &str,
288 ) -> bool {
289 match self.call_value(func, this, args) {
290 Ok(_) => true,
291 Err(thrown) => {
292 self.report_uncaught(context, &thrown);
293 false
294 }
295 }
296 }
297
298 pub fn report_uncaught(&mut self, context: &str, thrown: &Value) {
300 let line = crate::os_lib::js::uncaught::format_uncaught(context, &thrown.to_js_string());
301 crate::warn!("[JS] {}", line);
302 self.out.push_str(&line);
303 self.out.push('\n');
304 }
305
306 pub fn dispatch_event_in_interp(
310 &mut self,
311 node_idx: usize,
312 event_type: &str,
313 extra: &[(String, Value)],
314 ) -> (bool, bool) {
315 let path = {
317 let dom = self.dom.borrow();
318 let mut path = alloc::vec![node_idx];
319 let mut cur = node_idx;
320 let mut guard = 0;
321 while let Some(p) = dom.nodes.get(cur).and_then(|n| n.parent) {
322 path.push(p);
323 cur = p;
324 guard += 1;
325 if guard > dom.nodes.len() {
326 break;
327 }
328 }
329 path
330 };
331 let any = path
332 .iter()
333 .any(|&n| self.dom.borrow().has_listener_on(n, event_type));
334 let doc_has_listener = {
341 let doc_opt = self.global.borrow().vars.get("document").cloned();
342 doc_opt
343 .and_then(|d| super::super::builtins::event_target_listeners(&d))
344 .and_then(|listeners| listeners.borrow().props.get(event_type).cloned())
345 .is_some_and(|arr| match arr {
346 Value::Object(o) => matches!(&o.borrow().kind, ObjKind::Array(items) if !items.is_empty()),
347 _ => false,
348 })
349 };
350 let on_attr_name = alloc::format!("on{}", event_type);
351 let has_on_handler = path.iter().any(|&n| {
359 if self.dom.borrow().get_on_handler(n, &on_attr_name).is_some() {
360 return true;
361 }
362 self.dom.borrow().get_attr(n, &on_attr_name).is_some()
363 });
364 if !any && !doc_has_listener && !has_on_handler {
365 return (false, false);
366 }
367
368 let bubbles = extra
375 .iter()
376 .find(|(k, _)| k == "bubbles")
377 .map(|(_, v)| v.truthy())
378 .unwrap_or(true);
379 let composed: Vec<Value> = path.iter().map(|&n| Value::Object(Obj::dom(n))).collect();
380 let target = Value::Object(Obj::dom(node_idx));
381 let ev = Obj::plain();
382 {
383 let mut e = ev.borrow_mut();
384 e.props.insert(String::from("type"), Value::str(event_type));
385 e.props.insert(String::from("target"), target.clone());
386 e.props.insert(String::from("bubbles"), Value::Bool(true));
387 e.props.insert(String::from("cancelable"), Value::Bool(true));
393 e.props.insert(String::from("isTrusted"), Value::Bool(false));
399 e.props
400 .insert(String::from("eventPhase"), Value::Number(0.0));
401 e.props
402 .insert(String::from("defaultPrevented"), Value::Bool(false));
403 e.props.insert(
406 String::from("timeStamp"),
407 Value::Number(super::super::builtins::next_perf_timestamp()),
408 );
409 e.props.insert(String::from("returnValue"), Value::Bool(true));
412 e.props.insert(String::from("cancelBubble"), Value::Bool(false));
413 e.props.insert(String::from("srcElement"), target.clone());
414 e.props.insert(
415 String::from("_composedPath"),
416 Value::Object(Obj::array(composed)),
417 );
418 for (k, v) in extra {
419 e.props.insert(k.clone(), v.clone());
420 }
421 e.props.insert(
422 String::from("preventDefault"),
423 Value::Object(Obj::native("preventDefault", |_, this, _| {
424 if let Value::Object(o) = &this {
425 let cancelable = o
426 .borrow()
427 .props
428 .get("cancelable")
429 .map(|v| v.truthy())
430 .unwrap_or(true);
431 if cancelable {
432 let mut b = o.borrow_mut();
433 b.props
434 .insert(String::from("defaultPrevented"), Value::Bool(true));
435 b.props.insert(String::from("returnValue"), Value::Bool(false));
439 }
440 }
441 Ok(Value::Undefined)
442 })),
443 );
444 e.props.insert(
445 String::from("stopPropagation"),
446 Value::Object(Obj::native("stopPropagation", |_, this, _| {
447 if let Value::Object(o) = &this {
448 let mut b = o.borrow_mut();
449 b.props
450 .insert(String::from("_stop"), Value::Bool(true));
451 b.props.insert(String::from("cancelBubble"), Value::Bool(true));
454 }
455 Ok(Value::Undefined)
456 })),
457 );
458 e.props.insert(
459 String::from("stopImmediatePropagation"),
460 Value::Object(Obj::native("stopImmediatePropagation", |_, this, _| {
461 if let Value::Object(o) = &this {
462 let mut b = o.borrow_mut();
463 b.props.insert(String::from("_stop"), Value::Bool(true));
464 b.props
465 .insert(String::from("_stopImmediate"), Value::Bool(true));
466 b.props.insert(String::from("cancelBubble"), Value::Bool(true));
467 }
468 Ok(Value::Undefined)
469 })),
470 );
471 e.props.insert(
472 String::from("composedPath"),
473 Value::Object(Obj::native("composedPath", |_, this, _| {
474 if let Value::Object(o) = &this {
475 if let Some(p) = o.borrow().props.get("_composedPath") {
476 return Ok(p.clone());
477 }
478 }
479 Ok(Value::Object(Obj::array(Vec::new())))
480 })),
481 );
482 }
483
484 let mut steps: Vec<(usize, bool, f64)> = Vec::new();
485 for &n in path.iter().skip(1).rev() {
486 steps.push((n, true, 1.0));
487 }
488 steps.push((node_idx, true, 2.0));
489 steps.push((node_idx, false, 2.0));
490 if bubbles {
491 for &n in path.iter().skip(1) {
492 steps.push((n, false, 3.0));
493 }
494 }
495
496 let mut fired = false;
497 let mut to_remove: Vec<u64> = Vec::new();
498 let mut propagation_stopped = false;
499 let (doc_cap_fired, doc_cap_stopped) = self.fire_document_listeners(&ev, event_type, true);
507 if doc_cap_fired {
508 fired = true;
509 }
510 if doc_cap_stopped {
511 propagation_stopped = true;
512 }
513 if !propagation_stopped {
514 'outer: for (n, want_capture, phase) in steps {
515 let listeners = self
516 .dom
517 .borrow()
518 .listeners_phase(n, event_type, want_capture);
519 let on_attr_name = alloc::format!("on{}", event_type);
520 let node_this = Value::Object(Obj::dom(n));
521 if !want_capture {
522 let on_handler = self
525 .dom
526 .borrow()
527 .get_on_handler(n, &on_attr_name)
528 .filter(|v| !matches!(v, Value::Undefined | Value::Null))
529 .or_else(|| self.dom.borrow().get_attr(n, &on_attr_name).map(Value::str));
530 if let Some(h) = on_handler {
531 match h {
532 Value::Object(_) => {
533 let ctx = alloc::format!("on{} handler", event_type);
534 self.call_listener(
535 &h,
536 node_this.clone(),
537 &[Value::Object(ev.clone())],
538 &ctx,
539 );
540 fired = true;
541 }
542 Value::Str(code) if !code.is_empty() => {
543 if let Err(thrown) = self.eval_source(&code) {
544 let ctx = alloc::format!("on{} attribute", event_type);
545 self.report_uncaught(&ctx, &thrown);
546 }
547 fired = true;
548 }
549 _ => {}
550 }
551 }
552 }
553 if listeners.is_empty() {
554 continue;
555 }
556 {
557 let mut e = ev.borrow_mut();
558 e.props
559 .insert(String::from("currentTarget"), Value::Object(Obj::dom(n)));
560 e.props
561 .insert(String::from("eventPhase"), Value::Number(phase));
562 }
563 let node_this = Value::Object(Obj::dom(n));
564 for (func, once, id) in listeners {
565 let ctx = alloc::format!("{} listener", event_type);
566 self.call_listener(
567 &func,
568 node_this.clone(),
569 &[Value::Object(ev.clone())],
570 &ctx,
571 );
572 fired = true;
573 if once {
574 to_remove.push(id);
575 }
576 if ev
577 .borrow()
578 .props
579 .get("_stopImmediate")
580 .map(|v| v.truthy())
581 .unwrap_or(false)
582 {
583 propagation_stopped = true;
584 break 'outer;
585 }
586 }
587 if ev
588 .borrow()
589 .props
590 .get("_stop")
591 .map(|v| v.truthy())
592 .unwrap_or(false)
593 {
594 propagation_stopped = true;
595 break 'outer;
596 }
597 }
598 }
599 if !to_remove.is_empty() {
600 let mut dom = self.dom.borrow_mut();
601 for id in to_remove {
602 dom.remove_listener_by_id(id);
603 }
604 }
605 if bubbles && !propagation_stopped {
615 let (doc_bub_fired, _) = self.fire_document_listeners(&ev, event_type, false);
616 if doc_bub_fired {
617 fired = true;
618 }
619 }
620 let default_prevented = ev
621 .borrow()
622 .props
623 .get("defaultPrevented")
624 .map(|v| v.truthy())
625 .unwrap_or(false);
626 (fired, default_prevented)
627 }
628
629 fn fire_document_listeners(
639 &mut self,
640 ev: &super::super::value::ObjRef,
641 event_type: &str,
642 want_capture: bool,
643 ) -> (bool, bool) {
644 let mut fired = false;
645 let doc_opt = {
650 let g = self.global.borrow();
651 g.vars.get("document").cloned()
652 };
653 let Some(Value::Object(doc)) = doc_opt else {
654 return (false, false);
655 };
656 let doc_val = Value::Object(doc);
657 let Some(listeners) = super::super::builtins::event_target_listeners(&doc_val) else {
658 return (false, false);
659 };
660 let cbs: alloc::vec::Vec<Value> = match listeners.borrow().props.get(event_type) {
661 Some(Value::Object(arr)) => match &arr.borrow().kind {
662 ObjKind::Array(items) => items.clone(),
663 _ => alloc::vec::Vec::new(),
664 },
665 _ => alloc::vec::Vec::new(),
666 };
667 let matching: alloc::vec::Vec<Value> = cbs
668 .into_iter()
669 .filter(|entry| super::super::builtins::event_target_listener_capture(entry) == want_capture)
670 .collect();
671 if matching.is_empty() {
672 return (false, false);
673 }
674 {
675 let mut e = ev.borrow_mut();
676 e.props.insert(String::from("currentTarget"), doc_val.clone());
677 e.props
678 .insert(String::from("eventPhase"), Value::Number(if want_capture { 1.0 } else { 3.0 }));
679 }
680 for entry in matching {
681 if super::super::builtins::event_target_listener_aborted(&entry) {
682 continue;
683 }
684 let cb = super::super::builtins::event_target_listener_cb(&entry);
685 let once = super::super::builtins::event_target_listener_once(&entry);
686 let ctx = alloc::format!("{} listener (document)", event_type);
687 self.call_listener(&cb, doc_val.clone(), &[Value::Object(ev.clone())], &ctx);
688 fired = true;
689 if once {
690 if let Some(Value::Object(arr)) = listeners.borrow().props.get(event_type).cloned() {
691 if let ObjKind::Array(items) = &mut arr.borrow_mut().kind {
692 items.retain(|v| match (&super::super::builtins::event_target_listener_cb(v), &cb) {
693 (Value::Object(x), Value::Object(y)) => !Rc::ptr_eq(x, y),
694 _ => true,
695 });
696 }
697 }
698 }
699 if ev
700 .borrow()
701 .props
702 .get("_stopImmediate")
703 .map(|v| v.truthy())
704 .unwrap_or(false)
705 {
706 return (fired, true);
707 }
708 }
709 let stopped = ev.borrow().props.get("_stop").map(|v| v.truthy()).unwrap_or(false);
710 (fired, stopped)
711 }
712
713 pub(crate) fn call_value_inner(&mut self, func: &Value, this: Value, args: &[Value]) -> EvalResult {
714 let obj = match func {
715 Value::Object(o) => o.clone(),
716 _ => {
719 let d = alloc::format!("{}", func.to_js_string());
720 return Err(self.throw(alloc::format!("not a function: {}", d)));
723 }
724 };
725 let proxy = match &obj.borrow().kind {
727 ObjKind::Proxy { target, handler } => Some((target.clone(), handler.clone())),
728 _ => None,
729 };
730 if let Some((target, handler)) = proxy {
731 let trap = handler.borrow().props.get("apply").cloned();
732 if let Some(trap) =
733 trap.filter(|t| matches!(t, Value::Object(f) if f.borrow().is_callable()))
734 {
735 let arg_arr = Value::Object(Obj::array(args.to_vec()));
736 let targs = [Value::Object(target), this, arg_arr];
737 return self.call_value(&trap, Value::Object(handler), &targs);
738 }
739 return self.call_value(&Value::Object(target), this, args);
740 }
741 let bound = match &obj.borrow().kind {
745 ObjKind::Bound {
746 target,
747 bound_this,
748 bound_args,
749 } => Some((target.clone(), bound_this.clone(), bound_args.clone())),
750 _ => None,
751 };
752 if let Some((target, bound_this, bound_args)) = bound {
753 let mut combined = bound_args;
754 combined.extend_from_slice(args);
755 return self.call_value(&target, bound_this, &combined);
756 }
757 let kind = {
759 let b = obj.borrow();
760 match &b.kind {
761 ObjKind::Function(fd) => CallKind::User(fd.clone()),
762 ObjKind::Native { func, .. } => CallKind::Native(*func),
763 ObjKind::Resolver { state, reject } => CallKind::Resolver(state.clone(), *reject),
764 other => {
767 let kind_name = match other {
768 ObjKind::Array(_) => "array",
769 ObjKind::Plain => "object",
770 ObjKind::DomElement(_) => "dom element",
771 ObjKind::Host(_) => "host object",
772 _ => "other",
773 };
774 return Err(self.throw(alloc::format!(
775 "not a function: {} (呼べない種別)",
776 kind_name
777 )));
778 }
779 }
780 };
781 match kind {
782 CallKind::Native(f) => f(self, this, args),
783 CallKind::Resolver(state, reject) => {
784 let arg = args.first().cloned().unwrap_or(Value::Undefined);
785 if reject {
786 self.promise_reject(&state, arg);
787 } else {
788 self.promise_resolve(&state, arg);
789 }
790 Ok(Value::Undefined)
791 }
792 CallKind::User(fd) => {
793 let nt = self.pending_new_target.take().unwrap_or(Value::Undefined);
799 let pushed = !fd.is_arrow;
800 if pushed {
801 self.new_target_stack.push(nt);
802 }
803 let result = self.call_user_function(fd, this, args, func.clone());
804 if pushed {
805 self.new_target_stack.pop();
806 }
807 result
808 }
809 }
810 }
811
812 pub(crate) fn call_user_function(
813 &mut self,
814 fd: FunctionData,
815 this: Value,
816 args: &[Value],
817 callee: Value,
818 ) -> EvalResult {
819 {
820 let call_scope = Scope::child(fd.closure.clone());
821 for (i, p) in fd.params.iter().enumerate() {
822 if p.is_rest {
823 let rest_args: Vec<Value> =
825 args.get(i..).map(|s| s.to_vec()).unwrap_or_default();
826 self.bind_pattern(
827 &p.pattern,
828 Value::Object(Obj::array(rest_args)),
829 &call_scope,
830 &this,
831 )?;
832 break;
833 }
834 let mut v = args.get(i).cloned().unwrap_or(Value::Undefined);
835 if matches!(v, Value::Undefined) {
837 if let Some(def) = &p.default {
838 v = self.eval(def, &call_scope, &this)?;
839 }
840 }
841 self.bind_pattern(&p.pattern, v, &call_scope, &this)?;
842 }
843 let arguments_obj = Obj::array(args.to_vec());
847 arguments_obj.borrow_mut().props.insert("callee".into(), callee);
848 scope_declare(&call_scope, "arguments", Value::Object(arguments_obj));
849 let use_this = if fd.is_arrow {
850 fd.bound_this
851 .as_ref()
852 .map(|b| (**b).clone())
853 .unwrap_or(Value::Undefined)
854 } else {
855 this
856 };
857 if fd.is_generator {
858 return Ok(Value::Object(Obj::generator(GenState {
862 func: fd.clone(),
863 args: args.to_vec(),
864 this: use_this,
865 sent: Vec::new(),
866 started: false,
867 done: false,
868 returned: Value::Undefined,
869 })));
870 }
871 if fd.is_async {
872 let outcome = self.exec_statements(&fd.body, &call_scope, &use_this);
875 let pstate = Rc::new(RefCell::new(PromiseState::pending()));
876 match outcome {
877 Ok(Completion::Return(v)) => self.promise_resolve(&pstate, v),
878 Ok(_) => self.promise_resolve(&pstate, Value::Undefined),
879 Err(e) => {
880 if self.aborted {
881 return Err(e);
882 }
883 self.promise_reject(&pstate, e);
884 }
885 }
886 return Ok(Value::Object(Obj::promise(pstate)));
887 }
888 match self.exec_statements(&fd.body, &call_scope, &use_this)? {
889 Completion::Return(v) => Ok(v),
890 _ => Ok(Value::Undefined),
891 }
892 }
893 }
894
895 }