Skip to content

Problem with custom import function #1322

@JerrySievert

Description

@JerrySievert

My goal is to have a custom import function, such as:

const { bar } = await my_import('foo.mjs');

or

const { bar } = my_import('foo.mjs');

from looking at code, it should be fairly straightforward:

  • read the module from somewhere
  • eval it as a module
  • get its pointer
  • get the module namespace
  • return the module namespace

but, when I do this, I get an illegal access in js_build_module_ns().

here's a quick, dumbed down repo of the inner workings:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "quickjs.h"

const char *module = "const bar = (foo) => { console.log(`foo = ${foo}`); }; export { bar };";

const char *read_module(size_t *buf_len, const char *module_name) {
  if (strcmp(module_name, "bar.mjs") == 0) {
    *buf_len = strlen(module);
    return module;
  }

  return NULL;
}

JSValue module_load(JSContext *ctx, const char *module_name) {
  size_t buf_len;
  const char *buf;

  buf = read_module(&buf_len, module_name);
  if (!buf) {
    fprintf(stderr, "could not load module '%s'", module_name);

    JS_ThrowReferenceError(ctx, "could not load module '%s'", module_name);

    return JS_EXCEPTION;
  }

  fprintf(stderr, "Read module '%s': %s (%ld)", module_name, buf, buf_len);

  /* compile the module */
  JSValue res = JS_Eval(ctx, buf, buf_len, module_name,
                        JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);

  if (JS_IsException(res)) {
    const char *err = JS_ToCString(ctx, res);
    fprintf(stderr, "could not compile module '%s': %s", module_name, err);
    return JS_EXCEPTION;
  }

  JSModuleDef *module = (JSModuleDef *)JS_VALUE_GET_PTR(res);
  JSValue ns = JS_GetModuleNamespace(ctx, module);
  return ns;
}

int main() {
  JSRuntime *rt = JS_NewRuntime();
  JSContext *ctx = JS_NewContext(rt);

  JSValue ns = module_load(ctx, "bar.mjs");

  JS_FreeValue(ctx, ns);

  JS_FreeContext(ctx);
  JS_FreeRuntime(rt);

  return 0;
}

and my invalid access occurs here:

    frame #0: 0x000000010003a280 repro`js_build_module_ns(ctx=0x000000013f804470, m=0x000000013f8078c0) at quickjs.c:28712:42
   28709	                                  JS_PROP_VARREF);
   28710	                if (!pr)
   28711	                    goto fail;
-> 28712	                var_ref->header.ref_count++;
   28713	                pr->u.var_ref = var_ref;
   28714	            }
   28715	            break;

any help or pointers would be very much appreciated.

thanks!

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