1

I'm new to QuickJS, and I'm trying to make a basic program that loads and runs a script.

Here's the snippet of code that loads and runs the script:


       auto jsr = shared_ptr<JSRuntime>(JS_NewRuntime(), JS_FreeRuntime);
       for (auto &f : files){
            auto ctx = shared_ptr<JSContext>(JS_NewContext(jsr.get()), JS_FreeContext);
            js_init_module_os(ctx.get(), "os");
            js_init_module_std(ctx.get(), "std");
            size_t bufLen = 0;
            auto buf = js_load_file(ctx.get(), &bufLen, f.c_str());
            cout << "Starting Evaluation\n";
            JS_Eval(ctx.get(), (char*)buf, bufLen, f.c_str(), JS_EVAL_TYPE_MODULE);
            cout << "Ending Evaluation\n";
       }

And here is the script I'm running:

import {sleep} from 'os';

for (let i = 0; i < 100; i++)
{
    print("First Sleep: "+i);
    sleep(1000);
}

When This executes, I get a segfault Right after "Starting Evaluation", so I know it's happening inside the JS_Eval call.

I can run this script just fine using the qjs utility. Looking at qjs.c, there's quite a bit of additional processing done by qjs compared to my program. However, it's very complex and I don't understand exactly what I'm doing wrong compared to qjs.

Has anyone encountered this kind of issue before?

Thanks

JvJ
  • 112
  • 3

1 Answers1

0

I recently wrote a "minimal" c program with embedded quickjs, and had a similar problem. Here are the lines I ended up needing to add to get things working:

  • js_std_init_handlers(runtime);: not sure? but segfaults without it
  • js_std_add_helpers(ctx, 0, 0);: adds print()

With those lines, in addition to the ones you have above, I was able to execute your script.

Here's my c program

// gcc mvp.c -o mvp -lm -Lquickjs -Iquickjs -lquickjs
#include "quickjs-libc.h"
#include "quickjs.h"

int main(const int argc, const char **argv) {
  JSRuntime *runtime = JS_NewRuntime();
  js_std_init_handlers(runtime);
  // JS_SetModuleLoaderFunc(runtime, NULL, js_module_loader, NULL);

  JSContext *ctx = JS_NewContext(runtime);
  js_init_module_std(ctx, "std");
  js_init_module_os(ctx, "os");
  js_std_add_helpers(ctx, 0, 0);

  size_t buf_len;
  uint8_t *buf = js_load_file(ctx, &buf_len, argv[1]);

  JSValue result = JS_Eval(ctx, buf, buf_len, argv[1], JS_EVAL_TYPE_MODULE);
  // js_std_loop(ctx);
}

Two lines that I've commented out above, as not necessary for your sample script:

  • JS_SetModuleLoaderFunc: necessary if I imported any non-native modules.
  • js_std_loop: "event loop," necessary for promises/timeouts to work
David784
  • 7,031
  • 2
  • 22
  • 29