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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions