import { fib } from "./fib_module.js";
import msg from "./message.json";
+import msg2 from "./message.json" with { type: "text" };
console.log("Hello World");
console.log("fib(10)=", fib(10));
console.log("msg=", msg);
+console.log("msg2=", msg2);
{ "x" : 1, "tab": [ 1, 2, 3 ] }
-
typedef enum {
CNAME_TYPE_SCRIPT,
CNAME_TYPE_MODULE,
- CNAME_TYPE_JSON_MODULE,
+ CNAME_TYPE_DATA_MODULE,
} CNameTypeEnum;
static void output_object_code(JSContext *ctx,
size_t out_buf_len;
int flags;
- if (c_name_type == CNAME_TYPE_JSON_MODULE)
+ if (c_name_type == CNAME_TYPE_DATA_MODULE)
flags = 0;
else
flags = JS_WRITE_OBJ_BYTECODE;
size_t buf_len;
uint8_t *buf;
char cname[1024];
- int res;
+ int type;
+ JSValue val;
+ type = js_module_import_type(ctx, attributes);
+ if (type < 0)
+ return NULL;
+
buf = js_load_file(ctx, &buf_len, module_name);
if (!buf) {
JS_ThrowReferenceError(ctx, "could not load module filename '%s'",
return NULL;
}
- res = js_module_test_json(ctx, attributes);
- if (has_suffix(module_name, ".json") || res > 0) {
- /* compile as JSON or JSON5 depending on "type" */
- JSValue val;
- int flags;
-
- if (res == 2)
- flags = JS_PARSE_JSON_EXT;
- else
- flags = 0;
- val = JS_ParseJSON2(ctx, (char *)buf, buf_len, module_name, flags);
- js_free(ctx, buf);
- if (JS_IsException(val))
- return NULL;
+ if (type == JS_IMPORT_TYPE_JS) {
+ if (has_suffix(module_name, ".json"))
+ type = JS_IMPORT_TYPE_JSON;
+ }
+
+ switch(type) {
+ case JS_IMPORT_TYPE_JS:
+ val = JS_Eval(ctx, (char *)buf, buf_len, module_name,
+ JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
+ break;
+ case JS_IMPORT_TYPE_JSON:
+ case JS_IMPORT_TYPE_JSON5:
+ {
+ int flags;
+ if (type == JS_IMPORT_TYPE_JSON5)
+ flags = JS_PARSE_JSON_EXT;
+ else
+ flags = 0;
+ val = JS_ParseJSON2(ctx, (char *)buf, buf_len, module_name, flags);
+ }
+ break;
+ case JS_IMPORT_TYPE_TEXT:
+ val = JS_NewStringLen(ctx, (char *)buf, buf_len);
+ break;
+ default:
+ val = JS_ThrowInternalError(ctx, "unhandled import type");
+ break;
+ }
+ js_free(ctx, buf);
+ if (JS_IsException(val))
+ return NULL;
+
+ if (type == JS_IMPORT_TYPE_JS) {
+ get_c_name(cname, sizeof(cname), module_name);
+ if (namelist_find(&cname_list, cname)) {
+ find_unique_cname(cname, sizeof(cname));
+ }
+ output_object_code(ctx, outfile, val, cname, CNAME_TYPE_MODULE);
+
+ /* the module is already referenced, so we must free it */
+ m = JS_VALUE_GET_PTR(val);
+ JS_FreeValue(ctx, val);
+ } else {
/* create a dummy module */
m = JS_NewCModule(ctx, module_name, js_module_dummy_init);
if (!m) {
dump_hex(outfile, (const uint8_t *)module_name, strlen(module_name) + 1);
fprintf(outfile, "};\n\n");
- output_object_code(ctx, outfile, val, cname, CNAME_TYPE_JSON_MODULE);
+ output_object_code(ctx, outfile, val, cname, CNAME_TYPE_DATA_MODULE);
JS_FreeValue(ctx, val);
- } else {
- JSValue func_val;
-
- /* compile the module */
- func_val = JS_Eval(ctx, (char *)buf, buf_len, module_name,
- JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
- js_free(ctx, buf);
- if (JS_IsException(func_val))
- return NULL;
- get_c_name(cname, sizeof(cname), module_name);
- if (namelist_find(&cname_list, cname)) {
- find_unique_cname(cname, sizeof(cname));
- }
- output_object_code(ctx, outfile, func_val, cname, CNAME_TYPE_MODULE);
-
- /* the module is already referenced, so we must free it */
- m = JS_VALUE_GET_PTR(func_val);
- JS_FreeValue(ctx, func_val);
}
}
return m;
if (e->flags == CNAME_TYPE_MODULE) {
fprintf(fo, " js_std_eval_binary(ctx, %s, %s_size, 1);\n",
e->name, e->name);
- } else if (e->flags == CNAME_TYPE_JSON_MODULE) {
- fprintf(fo, " js_std_eval_binary_json_module(ctx, %s, %s_size, (const char *)%s_module_name);\n",
+ } else if (e->flags == CNAME_TYPE_DATA_MODULE) {
+ fprintf(fo, " js_std_eval_binary_data_module(ctx, %s, %s_size, (const char *)%s_module_name);\n",
e->name, e->name, e->name);
}
}
return 0;
}
-static JSModuleDef *create_json_module(JSContext *ctx, const char *module_name, JSValue val)
+static JSModuleDef *create_data_module(JSContext *ctx, const char *module_name, JSValue val)
{
JSModuleDef *m;
m = JS_NewCModule(ctx, module_name, json_module_init);
return ret;
}
-/* return > 0 if the attributes indicate a JSON module */
-int js_module_test_json(JSContext *ctx, JSValueConst attributes)
+/* return the module type according to 'attributes' or -1 if error */
+int js_module_import_type(JSContext *ctx, JSValueConst attributes)
{
JSValue str;
const char *cstr;
BOOL res;
if (JS_IsUndefined(attributes))
- return FALSE;
+ return JS_IMPORT_TYPE_JS;
str = JS_GetPropertyStr(ctx, attributes, "type");
+ if (JS_IsException(str))
+ return -1;
if (!JS_IsString(str))
- return FALSE;
+ return JS_IMPORT_TYPE_JS;
cstr = JS_ToCStringLen(ctx, &len, str);
JS_FreeValue(ctx, str);
if (!cstr)
- return FALSE;
+ return -1;
/* XXX: raise an error if unknown type ? */
if (len == 4 && !memcmp(cstr, "json", len)) {
- res = 1;
+ res = JS_IMPORT_TYPE_JSON;
} else if (len == 5 && !memcmp(cstr, "json5", len)) {
- res = 2;
+ res = JS_IMPORT_TYPE_JSON5;
+ } else if (len == 4 && !memcmp(cstr, "text", len)) {
+ res = JS_IMPORT_TYPE_TEXT;
} else {
- res = 0;
+ /* unknown type - throw error */
+ JS_ThrowTypeError(ctx, "unsupported module type: '%s'", cstr);
+ res = -1;
}
JS_FreeCString(ctx, cstr);
return res;
JSValueConst attributes)
{
JSModuleDef *m;
- int res;
if (has_suffix(module_name, ".so")) {
m = js_module_loader_so(ctx, module_name);
} else {
size_t buf_len;
uint8_t *buf;
+ int type;
+ JSValue val;
+
+ type = js_module_import_type(ctx, attributes);
+ if (type < 0)
+ return NULL;
buf = js_load_file(ctx, &buf_len, module_name);
if (!buf) {
module_name);
return NULL;
}
- res = js_module_test_json(ctx, attributes);
- if (has_suffix(module_name, ".json") || res > 0) {
- /* compile as JSON or JSON5 depending on "type" */
- JSValue val;
- int flags;
- if (res == 2)
- flags = JS_PARSE_JSON_EXT;
- else
- flags = 0;
- val = JS_ParseJSON2(ctx, (char *)buf, buf_len, module_name, flags);
- js_free(ctx, buf);
- if (JS_IsException(val))
- return NULL;
- m = create_json_module(ctx, module_name, val);
- if (!m)
- return NULL;
+
+ /* the .json suffix only selects the JSON type when no type attribute
+ was given, so that e.g. 'with { type: "text" }' is honored */
+ if (type == JS_IMPORT_TYPE_JS) {
+ if (has_suffix(module_name, ".json"))
+ type = JS_IMPORT_TYPE_JSON;
+ }
+
+ switch(type) {
+ case JS_IMPORT_TYPE_JS:
+ val = JS_Eval(ctx, (char *)buf, buf_len, module_name,
+ JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
+ break;
+ case JS_IMPORT_TYPE_JSON:
+ case JS_IMPORT_TYPE_JSON5:
+ {
+ int flags;
+ if (type == JS_IMPORT_TYPE_JSON5)
+ flags = JS_PARSE_JSON_EXT;
+ else
+ flags = 0;
+ val = JS_ParseJSON2(ctx, (char *)buf, buf_len, module_name, flags);
+ }
+ break;
+ case JS_IMPORT_TYPE_TEXT:
+ val = JS_NewStringLen(ctx, (char *)buf, buf_len);
+ break;
+ default:
+ val = JS_ThrowInternalError(ctx, "unhandled import type");
+ break;
+ }
+ js_free(ctx, buf);
+ if (JS_IsException(val))
+ return NULL;
+
+ if (type == JS_IMPORT_TYPE_JS) {
+ js_module_set_import_meta(ctx, val, TRUE, FALSE);
+ /* the module is already referenced, so we must free it */
+ m = JS_VALUE_GET_PTR(val);
+ JS_FreeValue(ctx, val);
} else {
- JSValue func_val;
- /* compile the module */
- func_val = JS_Eval(ctx, (char *)buf, buf_len, module_name,
- JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
- js_free(ctx, buf);
- if (JS_IsException(func_val))
+ m = create_data_module(ctx, module_name, val);
+ if (!m)
return NULL;
- /* XXX: could propagate the exception */
- js_module_set_import_meta(ctx, func_val, TRUE, FALSE);
- /* the module is already referenced, so we must free it */
- m = JS_VALUE_GET_PTR(func_val);
- JS_FreeValue(ctx, func_val);
}
}
return m;
}
}
-void js_std_eval_binary_json_module(JSContext *ctx,
+void js_std_eval_binary_data_module(JSContext *ctx,
const uint8_t *buf, size_t buf_len,
const char *module_name)
{
obj = JS_ReadObject(ctx, buf, buf_len, 0);
if (JS_IsException(obj))
goto exception;
- m = create_json_module(ctx, module_name, obj);
+ m = create_data_module(ctx, module_name, obj);
if (!m) {
exception:
js_std_dump_error(ctx);
uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename);
int js_module_set_import_meta(JSContext *ctx, JSValueConst func_val,
JS_BOOL use_realpath, JS_BOOL is_main);
-int js_module_test_json(JSContext *ctx, JSValueConst attributes);
+enum {
+ JS_IMPORT_TYPE_JS,
+ JS_IMPORT_TYPE_JSON,
+ JS_IMPORT_TYPE_JSON5,
+ JS_IMPORT_TYPE_TEXT,
+};
+int js_module_import_type(JSContext *ctx, JSValueConst attributes);
+
int js_module_check_attributes(JSContext *ctx, void *opaque, JSValueConst attributes);
JSModuleDef *js_module_loader(JSContext *ctx,
const char *module_name, void *opaque,
JSValueConst attributes);
void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len,
int flags);
-void js_std_eval_binary_json_module(JSContext *ctx,
+void js_std_eval_binary_data_module(JSContext *ctx,
const uint8_t *buf, size_t buf_len,
const char *module_name);
void js_std_promise_rejection_tracker(JSContext *ctx, JSValueConst promise,
int import_entries_count;
int import_entries_size;
+ JSValue attributes;
JSValue module_ns;
JSValue func_obj; /* only used for JS modules */
JSModuleInitFunc *init_func; /* only used for C modules */
m->resolving_funcs[0] = JS_UNDEFINED;
m->resolving_funcs[1] = JS_UNDEFINED;
m->private_value = JS_UNDEFINED;
+ m->attributes = JS_UNDEFINED;
list_add_tail(&m->link, &ctx->loaded_modules);
return m;
}
JS_MarkValue(rt, m->resolving_funcs[0], mark_func);
JS_MarkValue(rt, m->resolving_funcs[1], mark_func);
JS_MarkValue(rt, m->private_value, mark_func);
+ JS_MarkValue(rt, m->attributes, mark_func);
}
static void js_free_module_def(JSRuntime *rt, JSModuleDef *m)
JS_FreeValueRT(rt, m->resolving_funcs[0]);
JS_FreeValueRT(rt, m->resolving_funcs[1]);
JS_FreeValueRT(rt, m->private_value);
+ JS_FreeValueRT(rt, m->attributes);
/* during the GC the finalizers are called in an arbitrary
order so the module may no longer be referenced by the JSContext list */
if (m->link.next) {
}
static int add_req_module_entry(JSContext *ctx, JSModuleDef *m,
- JSAtom module_name)
+ JSAtom module_name, JSValueConst attributes)
{
JSReqModuleEntry *rme;
rme = &m->req_module_entries[m->req_module_entries_count++];
rme->module_name = JS_DupAtom(ctx, module_name);
rme->module = NULL;
- rme->attributes = JS_UNDEFINED;
+ rme->attributes = JS_DupValue(ctx, attributes);
return m->req_module_entries_count - 1;
}
return filename;
}
-static JSModuleDef *js_find_loaded_module(JSContext *ctx, JSAtom name)
+/* the objects are assumed to be normal objects with string properties */
+static BOOL js_module_attributes_equal(JSContext *ctx, JSValueConst attr1,
+ JSValueConst attr2)
+{
+ JSObject *p1, *p2;
+ int len1, len2, i;
+ JSShapeProperty *prs1, *prs2;
+ JSProperty *pr1, *pr2;
+ JSShape *sh;
+
+ if (JS_IsObject(attr1)) {
+ p1 = JS_VALUE_GET_OBJ(attr1);
+ len1 = p1->shape->prop_count - p1->shape->deleted_prop_count;
+ } else {
+ p1 = NULL;
+ len1 = 0;
+ }
+
+ if (JS_IsObject(attr2)) {
+ p2 = JS_VALUE_GET_OBJ(attr2);
+ len2 = p2->shape->prop_count - p2->shape->deleted_prop_count;
+ } else {
+ p2 = NULL;
+ len2 = 0;
+ }
+
+ if (len1 != len2)
+ return FALSE;
+ if (len1 == 0)
+ return TRUE;
+ sh = p1->shape;
+ for(i = 0, prs1 = get_shape_prop(sh); i < sh->prop_count;
+ i++, prs1++) {
+ if (prs1->atom != JS_ATOM_NULL) {
+ assert((prs1->flags & JS_PROP_TMASK) == 0);
+ prs2 = find_own_property(&pr2, p2, prs1->atom);
+ if (!prs2)
+ return FALSE;
+ assert((prs2->flags & JS_PROP_TMASK) == 0);
+ pr1 = &p1->prop[i];
+ if (!js_same_value(ctx, pr1->u.value, pr2->u.value))
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static JSModuleDef *js_find_loaded_module(JSContext *ctx, JSAtom name, JSValueConst attributes)
+{
+ struct list_head *el;
+ JSModuleDef *m;
+
+ /* first look at the loaded modules */
+ list_for_each(el, &ctx->loaded_modules) {
+ m = list_entry(el, JSModuleDef, link);
+ if (m->module_name == name && js_module_attributes_equal(ctx, m->attributes, attributes))
+ return m;
+ }
+ return NULL;
+}
+
+static JSModuleDef *js_find_loaded_module_by_name(JSContext *ctx, JSAtom name)
{
struct list_head *el;
JSModuleDef *m;
}
/* first look at the loaded modules */
- m = js_find_loaded_module(ctx, module_name);
+ m = js_find_loaded_module(ctx, module_name, attributes);
if (m) {
js_free(ctx, cname);
JS_FreeAtom(ctx, module_name);
} else {
m = rt->u.module_loader_func(ctx, cname, rt->module_loader_opaque);
}
+ if (m) {
+ assert(JS_IsUndefined(m->attributes));
+ m->attributes = JS_DupValue(ctx, attributes);
+ }
js_free(ctx, cname);
return m;
}
/* XXX: inefficient, need to add a module or script pointer in
JSFunctionBytecode */
- m = js_find_loaded_module(ctx, filename);
+ m = js_find_loaded_module_by_name(ctx, filename);
JS_FreeAtom(ctx, filename);
if (!m) {
fail:
return JS_DupValue(ctx, m->promise);
}
-static __exception int js_parse_with_clause(JSParseState *s, JSReqModuleEntry *rme)
+static __exception JSValue js_parse_with_clause(JSParseState *s)
{
JSContext *ctx = s->ctx;
JSAtom key;
int ret;
const uint8_t *key_token_ptr;
+ JSValue attributes = JS_UNDEFINED;
if (next_token(s))
- return -1;
+ goto fail;
if (js_parse_expect(s, '{'))
- return -1;
+ goto fail;
while (s->token.val != '}') {
key_token_ptr = s->token.ptr;
if (s->token.val == TOK_STRING) {
key = JS_ValueToAtom(ctx, s->token.u.str.str);
if (key == JS_ATOM_NULL)
- return -1;
+ goto fail;
} else {
if (!token_is_ident(s->token.val)) {
js_parse_error(s, "identifier expected");
- return -1;
+ goto fail;
}
key = JS_DupAtom(ctx, s->token.u.ident.atom);
}
if (next_token(s))
- return -1;
+ goto fail;
if (js_parse_expect(s, ':')) {
JS_FreeAtom(ctx, key);
- return -1;
+ goto fail;
}
if (s->token.val != TOK_STRING) {
js_parse_error_pos(s, key_token_ptr, "string expected");
- return -1;
+ goto fail;
}
- if (JS_IsUndefined(rme->attributes)) {
- JSValue attributes = JS_NewObjectProto(ctx, JS_NULL);
+ if (JS_IsUndefined(attributes)) {
+ attributes = JS_NewObjectProto(ctx, JS_NULL);
if (JS_IsException(attributes)) {
JS_FreeAtom(ctx, key);
- return -1;
+ goto fail;
}
- rme->attributes = attributes;
}
- ret = JS_HasProperty(ctx, rme->attributes, key);
+ ret = JS_HasProperty(ctx, attributes, key);
if (ret != 0) {
JS_FreeAtom(ctx, key);
- if (ret < 0)
- return -1;
- else
- return js_parse_error(s, "duplicate with key");
+ if (ret < 0) {
+ goto fail;
+ } else {
+ js_parse_error(s, "duplicate with key");
+ goto fail;
+ }
}
- ret = JS_DefinePropertyValue(ctx, rme->attributes, key,
+ ret = JS_DefinePropertyValue(ctx, attributes, key,
JS_DupValue(ctx, s->token.u.str.str), JS_PROP_C_W_E);
JS_FreeAtom(ctx, key);
if (ret < 0)
- return -1;
+ goto fail;
if (next_token(s))
- return -1;
+ goto fail;
if (s->token.val != ',')
break;
if (next_token(s))
- return -1;
+ goto fail;
}
- if (!JS_IsUndefined(rme->attributes) &&
+ if (!JS_IsUndefined(attributes) &&
ctx->rt->module_check_attrs &&
- ctx->rt->module_check_attrs(ctx, ctx->rt->module_loader_opaque, rme->attributes) < 0) {
- return -1;
+ ctx->rt->module_check_attrs(ctx, ctx->rt->module_loader_opaque, attributes) < 0) {
+ goto fail;
}
- return js_parse_expect(s, '}');
+ if (js_parse_expect(s, '}'))
+ goto fail;
+ return attributes;
+ fail:
+ JS_FreeValue(ctx, attributes);
+ return JS_EXCEPTION;
}
/* return the module index in m->req_module_entries[] or < 0 if error */
{
JSAtom module_name;
int idx;
-
+ JSValue attributes;
+
if (!token_is_pseudo_keyword(s, JS_ATOM_from)) {
js_parse_error(s, "from clause expected");
return -1;
JS_FreeAtom(s->ctx, module_name);
return -1;
}
-
- idx = add_req_module_entry(s->ctx, m, module_name);
- JS_FreeAtom(s->ctx, module_name);
- if (idx < 0)
- return -1;
+ attributes = JS_UNDEFINED;
if (s->token.val == TOK_WITH) {
- if (js_parse_with_clause(s, &m->req_module_entries[idx]))
+ attributes = js_parse_with_clause(s);
+ if (JS_IsException(attributes)) {
+ JS_FreeAtom(s->ctx, module_name);
return -1;
+ }
}
+ idx = add_req_module_entry(s->ctx, m, module_name, attributes);
+ JS_FreeAtom(s->ctx, module_name);
+ JS_FreeValue(s->ctx, attributes);
+ if (idx < 0)
+ return -1;
return idx;
}
first_import = m->import_entries_count;
if (s->token.val == TOK_STRING) {
+ JSValue attributes;
module_name = JS_ValueToAtom(ctx, s->token.u.str.str);
if (module_name == JS_ATOM_NULL)
return -1;
JS_FreeAtom(ctx, module_name);
return -1;
}
- idx = add_req_module_entry(ctx, m, module_name);
- JS_FreeAtom(ctx, module_name);
- if (idx < 0)
- return -1;
+ attributes = JS_UNDEFINED;
if (s->token.val == TOK_WITH) {
- if (js_parse_with_clause(s, &m->req_module_entries[idx]))
+ attributes = js_parse_with_clause(s);
+ if (JS_IsException(attributes)) {
+ JS_FreeAtom(s->ctx, module_name);
return -1;
+ }
}
+ idx = add_req_module_entry(ctx, m, module_name, attributes);
+ JS_FreeAtom(ctx, module_name);
+ JS_FreeValue(ctx, attributes);
+ if (idx < 0)
+ return -1;
} else {
if (s->token.val == TOK_IDENT) {
if (s->token.u.ident.is_reserved) {
uint8_t *buf;
JSModuleDef *m;
char *filename, *slash, path[1024];
-
+ int type;
+ JSValue val;
+
// interpret import("bar.js") from path/to/foo.js as
// import("path/to/bar.js") but leave import("./bar.js") untouched
filename = opaque;
}
}
+ type = js_module_import_type(ctx, attributes);
+ if (type < 0)
+ return NULL;
+
buf = js_load_file(ctx, &buf_len, module_name);
if (!buf) {
JS_ThrowReferenceError(ctx, "could not load module filename '%s'",
return NULL;
}
- if (js_module_test_json(ctx, attributes) == 1) {
- /* compile as JSON */
- JSValue val;
+ switch(type) {
+ case JS_IMPORT_TYPE_JS:
+ val = JS_Eval(ctx, (char *)buf, buf_len, module_name,
+ JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
+ break;
+ case JS_IMPORT_TYPE_JSON:
val = JS_ParseJSON(ctx, (char *)buf, buf_len, module_name);
- js_free(ctx, buf);
- if (JS_IsException(val))
- return NULL;
+ break;
+ case JS_IMPORT_TYPE_TEXT:
+ val = JS_NewStringLen(ctx, (char *)buf, buf_len);
+ break;
+ default:
+ val = JS_ThrowInternalError(ctx, "unhandled import type");
+ break;
+ }
+
+ js_free(ctx, buf);
+ if (JS_IsException(val))
+ return NULL;
+
+ if (type == JS_IMPORT_TYPE_JS) {
+ /* the module is already referenced, so we must free it */
+ m = JS_VALUE_GET_PTR(val);
+ JS_FreeValue(ctx, val);
+ } else {
m = JS_NewCModule(ctx, module_name, json_module_init_test);
if (!m) {
JS_FreeValue(ctx, val);
/* only export the "default" symbol which will contain the JSON object */
JS_AddModuleExport(ctx, m, "default");
JS_SetModulePrivateValue(ctx, m, val);
- } else {
- JSValue func_val;
- /* compile the module */
- func_val = JS_Eval(ctx, (char *)buf, buf_len, module_name,
- JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
- js_free(ctx, buf);
- if (JS_IsException(func_val))
- return NULL;
- /* the module is already referenced, so we must free it */
- m = JS_VALUE_GET_PTR(func_val);
- JS_FreeValue(ctx, func_val);
}
return m;
}
import-attributes
import-bytes=skip
import-defer=skip
-import-text=skip
+import-text
import.meta
joint-iteration
Int16Array