ScriptX icon indicating copy to clipboard operation
ScriptX copied to clipboard

Add support for QuickJs std and os modules

Open NotFromFatec opened this issue 1 year ago • 0 comments

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.

NotFromFatec avatar Oct 24 '24 05:10 NotFromFatec