| 1505 | } |
| 1506 | |
| 1507 | GErrorResult<> GjsContextPrivate::eval_module(const char* identifier, |
| 1508 | uint8_t* exit_code_p) { |
| 1509 | AutoResetExit reset(this); |
| 1510 | |
| 1511 | bool auto_profile = auto_profile_enter(); |
| 1512 | |
| 1513 | Gjs::AutoMainRealm ar{this}; |
| 1514 | |
| 1515 | JS::RootedObject registry(m_cx, gjs_get_module_registry(m_global)); |
| 1516 | JS::RootedId key(m_cx, gjs_intern_string_to_id(m_cx, identifier)); |
| 1517 | JS::RootedObject obj(m_cx); |
| 1518 | if (!gjs_global_registry_get(m_cx, registry, key, &obj) || !obj) { |
| 1519 | Gjs::AutoError error; |
| 1520 | g_set_error(error.out(), GJS_ERROR, GJS_ERROR_FAILED, |
| 1521 | "Cannot load module with identifier: '%s'", identifier); |
| 1522 | |
| 1523 | if (exit_code_p) |
| 1524 | *exit_code_p = 1; |
| 1525 | return Err(error.release()); |
| 1526 | } |
| 1527 | |
| 1528 | if (!JS::ModuleLink(m_cx, obj)) { |
| 1529 | gjs_log_exception(m_cx); |
| 1530 | Gjs::AutoError error; |
| 1531 | g_set_error(error.out(), GJS_ERROR, GJS_ERROR_FAILED, |
| 1532 | "Failed to resolve imports for module: '%s'", identifier); |
| 1533 | |
| 1534 | if (exit_code_p) |
| 1535 | *exit_code_p = 1; |
| 1536 | return Err(error.release()); |
| 1537 | } |
| 1538 | |
| 1539 | JS::RootedValue evaluation_promise(m_cx); |
| 1540 | bool ok = JS::ModuleEvaluate(m_cx, obj, &evaluation_promise); |
| 1541 | |
| 1542 | if (ok) { |
| 1543 | GjsContextPrivate::from_cx(m_cx)->main_loop_hold(); |
| 1544 | |
| 1545 | ok = add_promise_reactions( |
| 1546 | m_cx, evaluation_promise, on_context_module_resolved, |
| 1547 | on_context_module_rejected_log_exception, identifier); |
| 1548 | } |
| 1549 | |
| 1550 | bool exiting = false; |
| 1551 | |
| 1552 | do { |
| 1553 | // If there are no errors and the mainloop hook is set, call it. |
| 1554 | if (ok && m_main_loop_hook) |
| 1555 | ok = run_main_loop_hook(); |
| 1556 | |
| 1557 | // Spin the internal loop until the main loop hook is set or no holds |
| 1558 | // remain. |
| 1559 | // |
| 1560 | // If the main loop returns false we cannot guarantee the state of our |
| 1561 | // promise queue (a module promise could be pending) so instead of |
| 1562 | // draining the queue we instead just exit. |
| 1563 | // |
| 1564 | // Additional jobs could have been enqueued from the |
no test coverage detected