Skip to content

Add support for QuickJs std and os modules #111

@NotFromFatec

Description

@NotFromFatec

With this simple changes in these two files are possible to acess the QuickJs std and os modules (these modules seems to work on any plataform, i have tested it on Web (emscripten), Windows and Android).

In the file backend/QuickJs/QjsEngine.cc replace the constructor QjsEngine(std::shared_ptr<utils::MessageQueue> queue, const QjsFactory& factory):

QjsEngine::QjsEngine(std::shared_ptr<utils::MessageQueue> queue, const QjsFactory& factory)
    : queue_(queue ? std::move(queue) : std::make_shared<utils::MessageQueue>()) {
  if (factory) {
    std::tie(runtime_, context_) = factory();
  } else {
    runtime_ = JS_NewRuntime();
    if (runtime_) {
      context_ = JS_NewContext(runtime_);
    }
  }

  if (!runtime_ || !context_) {
    throw std::logic_error("QjsEngine: runtime or context is nullptr");
  }

  initEngineResource();
}

With the following:

QjsEngine::QjsEngine(std::shared_ptr<utils::MessageQueue> queue, const QjsFactory& factory)
    : queue_(queue ? std::move(queue) : std::make_shared<utils::MessageQueue>()) {
  if (factory) {
    std::tie(runtime_, context_) = factory();
  } else {
    runtime_ = JS_NewRuntime();
    if (runtime_) {
      context_ = JS_NewContext(runtime_);

        // add support for the quickjs std and os modules

        JS_AddIntrinsicBigFloat(context_);
        JS_AddIntrinsicBigDecimal(context_);
        JS_AddIntrinsicOperators(context_);
        JS_EnableBignumExt(context_, 1);
        JS_SetModuleLoaderFunc(runtime_, NULL, js_module_loader, NULL);
        // JS_SetInterruptHandler(JS_GetRuntime(context_), interrupt_handler, NULL);
        js_std_add_helpers(context_, 0, NULL);
    
        // Load os and std
        js_std_init_handlers(runtime_);
        js_init_module_std(context_, "std");
        js_init_module_os(context_, "os");
        const char *str =   "import * as std from 'std';\n"
                            "import * as os from 'os';\n"
                            "globalThis.std = std;\n"
                            "globalThis.os = os;\n";
        JSValue std_val = JS_Eval(context_, str, strlen(str), "<input>", JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
        if (!JS_IsException(std_val)) {
            js_module_set_import_meta(context_, std_val, 1, 1);
            std_val = JS_EvalFunction(context_, std_val);
        } else {
            js_std_dump_error(context_);
        }
        std_val = js_std_await(context_, std_val);
        JS_FreeValue(context_, std_val);

        // addition end
    }
  }

  if (!runtime_ || !context_) {
    throw std::logic_error("QjsEngine: runtime or context is nullptr");
  }

  initEngineResource();
}

And in the file backend/QuickJs/QjsHelper.h add the following include after the quickjs.h include: #include <quickjs-libc.h>.

The code i got from the quickjs repo in the fuzz/fuzz_commom.c this code seems to don't break anything and can be wrapped in a #ifdef SCRIPTX_QUICKJS_MODULES so it can be optional. It also enables BigFloat and BigDecimal if needed.

This is my first issue so sorry for any mistake.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions