mirror of
				https://github.com/bellard/quickjs.git
				synced 2025-05-29 01:49:18 +08:00 
			
		
		
		
	added JSON modules and import attributes
This commit is contained in:
		
							parent
							
								
									838124580b
								
							
						
					
					
						commit
						f10ef299a6
					
				
							
								
								
									
										2
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								TODO
									
									
									
									
									
								
							@ -62,5 +62,5 @@ Optimization ideas:
 | 
				
			|||||||
Test262o:   0/11262 errors, 463 excluded
 | 
					Test262o:   0/11262 errors, 463 excluded
 | 
				
			||||||
Test262o commit: 7da91bceb9ce7613f87db47ddd1292a2dda58b42 (es5-tests branch)
 | 
					Test262o commit: 7da91bceb9ce7613f87db47ddd1292a2dda58b42 (es5-tests branch)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Result: 58/79202 errors, 1610 excluded, 6738 skipped
 | 
					Result: 58/79349 errors, 1610 excluded, 6649 skipped
 | 
				
			||||||
Test262 commit: 27622d764767dcb3778784884022c2c7de5769b8
 | 
					Test262 commit: 27622d764767dcb3778784884022c2c7de5769b8
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2
									
								
								qjs.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								qjs.c
									
									
									
									
									
								
							@ -465,7 +465,7 @@ int main(int argc, char **argv)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* loader for ES6 modules */
 | 
					    /* loader for ES6 modules */
 | 
				
			||||||
    JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
 | 
					    JS_SetModuleLoaderFunc2(rt, NULL, js_module_loader, js_module_check_attributes, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (dump_unhandled_promise_rejection) {
 | 
					    if (dump_unhandled_promise_rejection) {
 | 
				
			||||||
        JS_SetHostPromiseRejectionTracker(rt, js_std_promise_rejection_tracker,
 | 
					        JS_SetHostPromiseRejectionTracker(rt, js_std_promise_rejection_tracker,
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2
									
								
								qjsc.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								qjsc.c
									
									
									
									
									
								
							@ -788,7 +788,7 @@ int main(int argc, char **argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        /* add the module loader if necessary */
 | 
					        /* add the module loader if necessary */
 | 
				
			||||||
        if (feature_bitmap & (1 << FE_MODULE_LOADER)) {
 | 
					        if (feature_bitmap & (1 << FE_MODULE_LOADER)) {
 | 
				
			||||||
            fprintf(fo, "  JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);\n");
 | 
					            fprintf(fo, "  JS_SetModuleLoaderFunc2(rt, NULL, js_module_loader, js_module_check_attributes, NULL);\n");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        fprintf(fo,
 | 
					        fprintf(fo,
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										112
									
								
								quickjs-libc.c
									
									
									
									
									
								
							
							
						
						
									
										112
									
								
								quickjs-libc.c
									
									
									
									
									
								
							@ -591,8 +591,72 @@ int js_module_set_import_meta(JSContext *ctx, JSValueConst func_val,
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int json_module_init(JSContext *ctx, JSModuleDef *m)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    JSValue val;
 | 
				
			||||||
 | 
					    val = JS_GetModulePrivateValue(ctx, m);
 | 
				
			||||||
 | 
					    JS_SetModuleExport(ctx, m, "default", val);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* in order to conform with the specification, only the keys should be
 | 
				
			||||||
 | 
					   tested and not the associated values. */
 | 
				
			||||||
 | 
					int js_module_check_attributes(JSContext *ctx, void *opaque,
 | 
				
			||||||
 | 
					                               JSValueConst attributes)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    JSPropertyEnum *tab;
 | 
				
			||||||
 | 
					    uint32_t i, len;
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					    const char *cstr;
 | 
				
			||||||
 | 
					    size_t cstr_len;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (JS_GetOwnPropertyNames(ctx, &tab, &len, attributes, JS_GPN_ENUM_ONLY | JS_GPN_STRING_MASK))
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    ret = 0;
 | 
				
			||||||
 | 
					    for(i = 0; i < len; i++) {
 | 
				
			||||||
 | 
					        cstr = JS_AtomToCStringLen(ctx, &cstr_len, tab[i].atom);
 | 
				
			||||||
 | 
					        if (!cstr) {
 | 
				
			||||||
 | 
					            ret = -1;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (!(cstr_len == 4 && !memcmp(cstr, "type", cstr_len))) {
 | 
				
			||||||
 | 
					            JS_ThrowTypeError(ctx, "import attribute '%s' is not supported", cstr);
 | 
				
			||||||
 | 
					            ret = -1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        JS_FreeCString(ctx, cstr);
 | 
				
			||||||
 | 
					        if (ret)
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    JS_FreePropertyEnum(ctx, tab, len);
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* return TRUE if the attributes indicate a JSON module */
 | 
				
			||||||
 | 
					JS_BOOL js_module_test_json(JSContext *ctx, JSValueConst attributes)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    JSValue str;
 | 
				
			||||||
 | 
					    const char *cstr;
 | 
				
			||||||
 | 
					    size_t len;
 | 
				
			||||||
 | 
					    BOOL res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (JS_IsUndefined(attributes))
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					    str = JS_GetPropertyStr(ctx, attributes, "type");
 | 
				
			||||||
 | 
					    if (!JS_IsString(str))
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					    cstr = JS_ToCStringLen(ctx, &len, str);
 | 
				
			||||||
 | 
					    JS_FreeValue(ctx, str);
 | 
				
			||||||
 | 
					    if (!cstr)
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					    /* XXX: raise an error if unknown type ? */
 | 
				
			||||||
 | 
					    res = (len == 4 && !memcmp(cstr, "json", len));
 | 
				
			||||||
 | 
					    JS_FreeCString(ctx, cstr);
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
JSModuleDef *js_module_loader(JSContext *ctx,
 | 
					JSModuleDef *js_module_loader(JSContext *ctx,
 | 
				
			||||||
                              const char *module_name, void *opaque)
 | 
					                              const char *module_name, void *opaque,
 | 
				
			||||||
 | 
					                              JSValueConst attributes)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    JSModuleDef *m;
 | 
					    JSModuleDef *m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -601,7 +665,6 @@ JSModuleDef *js_module_loader(JSContext *ctx,
 | 
				
			|||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        size_t buf_len;
 | 
					        size_t buf_len;
 | 
				
			||||||
        uint8_t *buf;
 | 
					        uint8_t *buf;
 | 
				
			||||||
        JSValue func_val;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        buf = js_load_file(ctx, &buf_len, module_name);
 | 
					        buf = js_load_file(ctx, &buf_len, module_name);
 | 
				
			||||||
        if (!buf) {
 | 
					        if (!buf) {
 | 
				
			||||||
@ -609,18 +672,37 @@ JSModuleDef *js_module_loader(JSContext *ctx,
 | 
				
			|||||||
                                   module_name);
 | 
					                                   module_name);
 | 
				
			||||||
            return NULL;
 | 
					            return NULL;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        /* compile the module */
 | 
					        if (has_suffix(module_name, ".json") ||
 | 
				
			||||||
        func_val = JS_Eval(ctx, (char *)buf, buf_len, module_name,
 | 
					            js_module_test_json(ctx, attributes)) {
 | 
				
			||||||
                           JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
 | 
					            /* compile as JSON */
 | 
				
			||||||
        js_free(ctx, buf);
 | 
					            JSValue val;
 | 
				
			||||||
        if (JS_IsException(func_val))
 | 
					            val = JS_ParseJSON(ctx, (char *)buf, buf_len, module_name);
 | 
				
			||||||
            return NULL;
 | 
					            js_free(ctx, buf);
 | 
				
			||||||
        /* XXX: could propagate the exception */
 | 
					            if (JS_IsException(val))
 | 
				
			||||||
        js_module_set_import_meta(ctx, func_val, TRUE, FALSE);
 | 
					                return NULL;
 | 
				
			||||||
        /* the module is already referenced, so we must free it */
 | 
					            m = JS_NewCModule(ctx, module_name, json_module_init);
 | 
				
			||||||
        m = JS_VALUE_GET_PTR(func_val);
 | 
					            if (!m) {
 | 
				
			||||||
        JS_FreeValue(ctx, func_val);
 | 
					                JS_FreeValue(ctx, val);
 | 
				
			||||||
 | 
					                return NULL;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            /* 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;
 | 
				
			||||||
 | 
					            /* 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;
 | 
					    return m;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -3478,7 +3560,7 @@ static void *worker_func(void *opaque)
 | 
				
			|||||||
    JS_SetStripInfo(rt, args->strip_flags);
 | 
					    JS_SetStripInfo(rt, args->strip_flags);
 | 
				
			||||||
    js_std_init_handlers(rt);
 | 
					    js_std_init_handlers(rt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
 | 
					    JS_SetModuleLoaderFunc2(rt, NULL, js_module_loader, js_module_check_attributes, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* set the pipe to communicate with the parent */
 | 
					    /* set the pipe to communicate with the parent */
 | 
				
			||||||
    ts = JS_GetRuntimeOpaque(rt);
 | 
					    ts = JS_GetRuntimeOpaque(rt);
 | 
				
			||||||
 | 
				
			|||||||
@ -44,8 +44,11 @@ void js_std_dump_error(JSContext *ctx);
 | 
				
			|||||||
uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename);
 | 
					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,
 | 
					int js_module_set_import_meta(JSContext *ctx, JSValueConst func_val,
 | 
				
			||||||
                              JS_BOOL use_realpath, JS_BOOL is_main);
 | 
					                              JS_BOOL use_realpath, JS_BOOL is_main);
 | 
				
			||||||
 | 
					JS_BOOL js_module_test_json(JSContext *ctx, JSValueConst attributes);
 | 
				
			||||||
 | 
					int js_module_check_attributes(JSContext *ctx, void *opaque, JSValueConst attributes);
 | 
				
			||||||
JSModuleDef *js_module_loader(JSContext *ctx,
 | 
					JSModuleDef *js_module_loader(JSContext *ctx,
 | 
				
			||||||
                              const char *module_name, void *opaque);
 | 
					                              const char *module_name, void *opaque,
 | 
				
			||||||
 | 
					                              JSValueConst attributes);
 | 
				
			||||||
void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len,
 | 
					void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len,
 | 
				
			||||||
                        int flags);
 | 
					                        int flags);
 | 
				
			||||||
void js_std_promise_rejection_tracker(JSContext *ctx, JSValueConst promise,
 | 
					void js_std_promise_rejection_tracker(JSContext *ctx, JSValueConst promise,
 | 
				
			||||||
 | 
				
			|||||||
@ -121,7 +121,7 @@ DEF(     apply_eval, 3, 2, 1, u16) /* func array -> ret_eval */
 | 
				
			|||||||
DEF(         regexp, 1, 2, 1, none) /* create a RegExp object from the pattern and a
 | 
					DEF(         regexp, 1, 2, 1, none) /* create a RegExp object from the pattern and a
 | 
				
			||||||
                                       bytecode string */
 | 
					                                       bytecode string */
 | 
				
			||||||
DEF(      get_super, 1, 1, 1, none)
 | 
					DEF(      get_super, 1, 1, 1, none)
 | 
				
			||||||
DEF(         import, 1, 1, 1, none) /* dynamic module import */
 | 
					DEF(         import, 1, 2, 1, none) /* dynamic module import */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEF(      check_var, 5, 0, 1, atom) /* check if a variable exists */
 | 
					DEF(      check_var, 5, 0, 1, atom) /* check if a variable exists */
 | 
				
			||||||
DEF(  get_var_undef, 5, 0, 1, atom) /* push undefined if the variable does not exist */
 | 
					DEF(  get_var_undef, 5, 0, 1, atom) /* push undefined if the variable does not exist */
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										321
									
								
								quickjs.c
									
									
									
									
									
								
							
							
						
						
									
										321
									
								
								quickjs.c
									
									
									
									
									
								
							@ -280,7 +280,12 @@ struct JSRuntime {
 | 
				
			|||||||
    struct list_head job_list; /* list of JSJobEntry.link */
 | 
					    struct list_head job_list; /* list of JSJobEntry.link */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    JSModuleNormalizeFunc *module_normalize_func;
 | 
					    JSModuleNormalizeFunc *module_normalize_func;
 | 
				
			||||||
    JSModuleLoaderFunc *module_loader_func;
 | 
					    BOOL module_loader_has_attr;
 | 
				
			||||||
 | 
					    union {
 | 
				
			||||||
 | 
					        JSModuleLoaderFunc *module_loader_func;
 | 
				
			||||||
 | 
					        JSModuleLoaderFunc2 *module_loader_func2;
 | 
				
			||||||
 | 
					    } u;
 | 
				
			||||||
 | 
					    JSModuleCheckSupportedImportAttributes *module_check_attrs;
 | 
				
			||||||
    void *module_loader_opaque;
 | 
					    void *module_loader_opaque;
 | 
				
			||||||
    /* timestamp for internal use in module evaluation */
 | 
					    /* timestamp for internal use in module evaluation */
 | 
				
			||||||
    int64_t module_async_evaluation_next_timestamp;
 | 
					    int64_t module_async_evaluation_next_timestamp;
 | 
				
			||||||
@ -756,6 +761,7 @@ typedef struct {
 | 
				
			|||||||
typedef struct JSReqModuleEntry {
 | 
					typedef struct JSReqModuleEntry {
 | 
				
			||||||
    JSAtom module_name;
 | 
					    JSAtom module_name;
 | 
				
			||||||
    JSModuleDef *module; /* used using resolution */
 | 
					    JSModuleDef *module; /* used using resolution */
 | 
				
			||||||
 | 
					    JSValue attributes; /* JS_UNDEFINED or an object contains the attributes as key/value */
 | 
				
			||||||
} JSReqModuleEntry;
 | 
					} JSReqModuleEntry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef enum JSExportTypeEnum {
 | 
					typedef enum JSExportTypeEnum {
 | 
				
			||||||
@ -844,6 +850,7 @@ struct JSModuleDef {
 | 
				
			|||||||
    BOOL eval_has_exception : 8;
 | 
					    BOOL eval_has_exception : 8;
 | 
				
			||||||
    JSValue eval_exception;
 | 
					    JSValue eval_exception;
 | 
				
			||||||
    JSValue meta_obj; /* for import.meta */
 | 
					    JSValue meta_obj; /* for import.meta */
 | 
				
			||||||
 | 
					    JSValue private_value; /* private value for C modules */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct JSJobEntry {
 | 
					typedef struct JSJobEntry {
 | 
				
			||||||
@ -1217,7 +1224,7 @@ static void js_free_module_def(JSContext *ctx, JSModuleDef *m);
 | 
				
			|||||||
static void js_mark_module_def(JSRuntime *rt, JSModuleDef *m,
 | 
					static void js_mark_module_def(JSRuntime *rt, JSModuleDef *m,
 | 
				
			||||||
                               JS_MarkFunc *mark_func);
 | 
					                               JS_MarkFunc *mark_func);
 | 
				
			||||||
static JSValue js_import_meta(JSContext *ctx);
 | 
					static JSValue js_import_meta(JSContext *ctx);
 | 
				
			||||||
static JSValue js_dynamic_import(JSContext *ctx, JSValueConst specifier);
 | 
					static JSValue js_dynamic_import(JSContext *ctx, JSValueConst specifier, JSValueConst options);
 | 
				
			||||||
static void free_var_ref(JSRuntime *rt, JSVarRef *var_ref);
 | 
					static void free_var_ref(JSRuntime *rt, JSVarRef *var_ref);
 | 
				
			||||||
static JSValue js_new_promise_capability(JSContext *ctx,
 | 
					static JSValue js_new_promise_capability(JSContext *ctx,
 | 
				
			||||||
                                         JSValue *resolving_funcs,
 | 
					                                         JSValue *resolving_funcs,
 | 
				
			||||||
@ -17383,10 +17390,12 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                JSValue val;
 | 
					                JSValue val;
 | 
				
			||||||
                sf->cur_pc = pc;
 | 
					                sf->cur_pc = pc;
 | 
				
			||||||
                val = js_dynamic_import(ctx, sp[-1]);
 | 
					                val = js_dynamic_import(ctx, sp[-2], sp[-1]);
 | 
				
			||||||
                if (JS_IsException(val))
 | 
					                if (JS_IsException(val))
 | 
				
			||||||
                    goto exception;
 | 
					                    goto exception;
 | 
				
			||||||
 | 
					                JS_FreeValue(ctx, sp[-2]);
 | 
				
			||||||
                JS_FreeValue(ctx, sp[-1]);
 | 
					                JS_FreeValue(ctx, sp[-1]);
 | 
				
			||||||
 | 
					                sp--;
 | 
				
			||||||
                sp[-1] = val;
 | 
					                sp[-1] = val;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            BREAK;
 | 
					            BREAK;
 | 
				
			||||||
@ -25538,6 +25547,23 @@ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags)
 | 
				
			|||||||
                return js_parse_error(s, "invalid use of 'import()'");
 | 
					                return js_parse_error(s, "invalid use of 'import()'");
 | 
				
			||||||
            if (js_parse_assign_expr(s))
 | 
					            if (js_parse_assign_expr(s))
 | 
				
			||||||
                return -1;
 | 
					                return -1;
 | 
				
			||||||
 | 
					            if (s->token.val == ',') {
 | 
				
			||||||
 | 
					                if (next_token(s))
 | 
				
			||||||
 | 
					                    return -1;
 | 
				
			||||||
 | 
					                if (s->token.val != ')') {
 | 
				
			||||||
 | 
					                    if (js_parse_assign_expr(s))
 | 
				
			||||||
 | 
					                        return -1;
 | 
				
			||||||
 | 
					                    /* accept a trailing comma */
 | 
				
			||||||
 | 
					                    if (s->token.val == ',') {
 | 
				
			||||||
 | 
					                        if (next_token(s))
 | 
				
			||||||
 | 
					                            return -1;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    emit_op(s, OP_undefined);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                emit_op(s, OP_undefined);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            if (js_parse_expect(s, ')'))
 | 
					            if (js_parse_expect(s, ')'))
 | 
				
			||||||
                return -1;
 | 
					                return -1;
 | 
				
			||||||
            emit_op(s, OP_import);
 | 
					            emit_op(s, OP_import);
 | 
				
			||||||
@ -28115,6 +28141,7 @@ static JSModuleDef *js_new_module_def(JSContext *ctx, JSAtom name)
 | 
				
			|||||||
    m->promise = JS_UNDEFINED;
 | 
					    m->promise = JS_UNDEFINED;
 | 
				
			||||||
    m->resolving_funcs[0] = JS_UNDEFINED;
 | 
					    m->resolving_funcs[0] = JS_UNDEFINED;
 | 
				
			||||||
    m->resolving_funcs[1] = JS_UNDEFINED;
 | 
					    m->resolving_funcs[1] = JS_UNDEFINED;
 | 
				
			||||||
 | 
					    m->private_value = JS_UNDEFINED;
 | 
				
			||||||
    list_add_tail(&m->link, &ctx->loaded_modules);
 | 
					    list_add_tail(&m->link, &ctx->loaded_modules);
 | 
				
			||||||
    return m;
 | 
					    return m;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -28124,6 +28151,11 @@ static void js_mark_module_def(JSRuntime *rt, JSModuleDef *m,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    int i;
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for(i = 0; i < m->req_module_entries_count; i++) {
 | 
				
			||||||
 | 
					        JSReqModuleEntry *rme = &m->req_module_entries[i];
 | 
				
			||||||
 | 
					        JS_MarkValue(rt, rme->attributes, mark_func);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    for(i = 0; i < m->export_entries_count; i++) {
 | 
					    for(i = 0; i < m->export_entries_count; i++) {
 | 
				
			||||||
        JSExportEntry *me = &m->export_entries[i];
 | 
					        JSExportEntry *me = &m->export_entries[i];
 | 
				
			||||||
        if (me->export_type == JS_EXPORT_TYPE_LOCAL &&
 | 
					        if (me->export_type == JS_EXPORT_TYPE_LOCAL &&
 | 
				
			||||||
@ -28139,6 +28171,7 @@ static void js_mark_module_def(JSRuntime *rt, JSModuleDef *m,
 | 
				
			|||||||
    JS_MarkValue(rt, m->promise, mark_func);
 | 
					    JS_MarkValue(rt, m->promise, mark_func);
 | 
				
			||||||
    JS_MarkValue(rt, m->resolving_funcs[0], mark_func);
 | 
					    JS_MarkValue(rt, m->resolving_funcs[0], mark_func);
 | 
				
			||||||
    JS_MarkValue(rt, m->resolving_funcs[1], mark_func);
 | 
					    JS_MarkValue(rt, m->resolving_funcs[1], mark_func);
 | 
				
			||||||
 | 
					    JS_MarkValue(rt, m->private_value, mark_func);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void js_free_module_def(JSContext *ctx, JSModuleDef *m)
 | 
					static void js_free_module_def(JSContext *ctx, JSModuleDef *m)
 | 
				
			||||||
@ -28150,6 +28183,7 @@ static void js_free_module_def(JSContext *ctx, JSModuleDef *m)
 | 
				
			|||||||
    for(i = 0; i < m->req_module_entries_count; i++) {
 | 
					    for(i = 0; i < m->req_module_entries_count; i++) {
 | 
				
			||||||
        JSReqModuleEntry *rme = &m->req_module_entries[i];
 | 
					        JSReqModuleEntry *rme = &m->req_module_entries[i];
 | 
				
			||||||
        JS_FreeAtom(ctx, rme->module_name);
 | 
					        JS_FreeAtom(ctx, rme->module_name);
 | 
				
			||||||
 | 
					        JS_FreeValue(ctx, rme->attributes);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    js_free(ctx, m->req_module_entries);
 | 
					    js_free(ctx, m->req_module_entries);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -28178,6 +28212,7 @@ static void js_free_module_def(JSContext *ctx, JSModuleDef *m)
 | 
				
			|||||||
    JS_FreeValue(ctx, m->promise);
 | 
					    JS_FreeValue(ctx, m->promise);
 | 
				
			||||||
    JS_FreeValue(ctx, m->resolving_funcs[0]);
 | 
					    JS_FreeValue(ctx, m->resolving_funcs[0]);
 | 
				
			||||||
    JS_FreeValue(ctx, m->resolving_funcs[1]);
 | 
					    JS_FreeValue(ctx, m->resolving_funcs[1]);
 | 
				
			||||||
 | 
					    JS_FreeValue(ctx, m->private_value);
 | 
				
			||||||
    list_del(&m->link);
 | 
					    list_del(&m->link);
 | 
				
			||||||
    js_free(ctx, m);
 | 
					    js_free(ctx, m);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -28186,14 +28221,6 @@ static int add_req_module_entry(JSContext *ctx, JSModuleDef *m,
 | 
				
			|||||||
                                JSAtom module_name)
 | 
					                                JSAtom module_name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    JSReqModuleEntry *rme;
 | 
					    JSReqModuleEntry *rme;
 | 
				
			||||||
    int i;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* no need to add the module request if it is already present */
 | 
					 | 
				
			||||||
    for(i = 0; i < m->req_module_entries_count; i++) {
 | 
					 | 
				
			||||||
        rme = &m->req_module_entries[i];
 | 
					 | 
				
			||||||
        if (rme->module_name == module_name)
 | 
					 | 
				
			||||||
            return i;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (js_resize_array(ctx, (void **)&m->req_module_entries,
 | 
					    if (js_resize_array(ctx, (void **)&m->req_module_entries,
 | 
				
			||||||
                        sizeof(JSReqModuleEntry),
 | 
					                        sizeof(JSReqModuleEntry),
 | 
				
			||||||
@ -28203,7 +28230,8 @@ static int add_req_module_entry(JSContext *ctx, JSModuleDef *m,
 | 
				
			|||||||
    rme = &m->req_module_entries[m->req_module_entries_count++];
 | 
					    rme = &m->req_module_entries[m->req_module_entries_count++];
 | 
				
			||||||
    rme->module_name = JS_DupAtom(ctx, module_name);
 | 
					    rme->module_name = JS_DupAtom(ctx, module_name);
 | 
				
			||||||
    rme->module = NULL;
 | 
					    rme->module = NULL;
 | 
				
			||||||
    return i;
 | 
					    rme->attributes = JS_UNDEFINED;
 | 
				
			||||||
 | 
					    return m->req_module_entries_count - 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static JSExportEntry *find_export_entry(JSContext *ctx, JSModuleDef *m,
 | 
					static JSExportEntry *find_export_entry(JSContext *ctx, JSModuleDef *m,
 | 
				
			||||||
@ -28322,12 +28350,38 @@ int JS_SetModuleExport(JSContext *ctx, JSModuleDef *m, const char *export_name,
 | 
				
			|||||||
    return -1;
 | 
					    return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int JS_SetModulePrivateValue(JSContext *ctx, JSModuleDef *m, JSValue val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    set_value(ctx, &m->private_value, val);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					JSValue JS_GetModulePrivateValue(JSContext *ctx, JSModuleDef *m)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return JS_DupValue(ctx, m->private_value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void JS_SetModuleLoaderFunc(JSRuntime *rt,
 | 
					void JS_SetModuleLoaderFunc(JSRuntime *rt,
 | 
				
			||||||
                            JSModuleNormalizeFunc *module_normalize,
 | 
					                            JSModuleNormalizeFunc *module_normalize,
 | 
				
			||||||
                            JSModuleLoaderFunc *module_loader, void *opaque)
 | 
					                            JSModuleLoaderFunc *module_loader, void *opaque)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    rt->module_normalize_func = module_normalize;
 | 
					    rt->module_normalize_func = module_normalize;
 | 
				
			||||||
    rt->module_loader_func = module_loader;
 | 
					    rt->module_loader_has_attr = FALSE;
 | 
				
			||||||
 | 
					    rt->u.module_loader_func = module_loader;
 | 
				
			||||||
 | 
					    rt->module_check_attrs = NULL;
 | 
				
			||||||
 | 
					    rt->module_loader_opaque = opaque;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void JS_SetModuleLoaderFunc2(JSRuntime *rt,
 | 
				
			||||||
 | 
					                             JSModuleNormalizeFunc *module_normalize,
 | 
				
			||||||
 | 
					                             JSModuleLoaderFunc2 *module_loader,
 | 
				
			||||||
 | 
					                             JSModuleCheckSupportedImportAttributes *module_check_attrs,
 | 
				
			||||||
 | 
					                             void *opaque)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    rt->module_normalize_func = module_normalize;
 | 
				
			||||||
 | 
					    rt->module_loader_has_attr = TRUE;
 | 
				
			||||||
 | 
					    rt->u.module_loader_func2 = module_loader;
 | 
				
			||||||
 | 
					    rt->module_check_attrs = module_check_attrs;
 | 
				
			||||||
    rt->module_loader_opaque = opaque;
 | 
					    rt->module_loader_opaque = opaque;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -28408,7 +28462,8 @@ static JSModuleDef *js_find_loaded_module(JSContext *ctx, JSAtom name)
 | 
				
			|||||||
/* return NULL in case of exception (e.g. module could not be loaded) */
 | 
					/* return NULL in case of exception (e.g. module could not be loaded) */
 | 
				
			||||||
static JSModuleDef *js_host_resolve_imported_module(JSContext *ctx,
 | 
					static JSModuleDef *js_host_resolve_imported_module(JSContext *ctx,
 | 
				
			||||||
                                                    const char *base_cname,
 | 
					                                                    const char *base_cname,
 | 
				
			||||||
                                                    const char *cname1)
 | 
					                                                    const char *cname1,
 | 
				
			||||||
 | 
					                                                    JSValueConst attributes)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    JSRuntime *rt = ctx->rt;
 | 
					    JSRuntime *rt = ctx->rt;
 | 
				
			||||||
    JSModuleDef *m;
 | 
					    JSModuleDef *m;
 | 
				
			||||||
@ -28441,22 +28496,26 @@ static JSModuleDef *js_host_resolve_imported_module(JSContext *ctx,
 | 
				
			|||||||
    JS_FreeAtom(ctx, module_name);
 | 
					    JS_FreeAtom(ctx, module_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* load the module */
 | 
					    /* load the module */
 | 
				
			||||||
    if (!rt->module_loader_func) {
 | 
					    if (!rt->u.module_loader_func) {
 | 
				
			||||||
        /* XXX: use a syntax error ? */
 | 
					        /* XXX: use a syntax error ? */
 | 
				
			||||||
        JS_ThrowReferenceError(ctx, "could not load module '%s'",
 | 
					        JS_ThrowReferenceError(ctx, "could not load module '%s'",
 | 
				
			||||||
                               cname);
 | 
					                               cname);
 | 
				
			||||||
        js_free(ctx, cname);
 | 
					        js_free(ctx, cname);
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if (rt->module_loader_has_attr) {
 | 
				
			||||||
    m = rt->module_loader_func(ctx, cname, rt->module_loader_opaque);
 | 
					        m = rt->u.module_loader_func2(ctx, cname, rt->module_loader_opaque, attributes);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        m = rt->u.module_loader_func(ctx, cname, rt->module_loader_opaque);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    js_free(ctx, cname);
 | 
					    js_free(ctx, cname);
 | 
				
			||||||
    return m;
 | 
					    return m;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static JSModuleDef *js_host_resolve_imported_module_atom(JSContext *ctx,
 | 
					static JSModuleDef *js_host_resolve_imported_module_atom(JSContext *ctx,
 | 
				
			||||||
                                                    JSAtom base_module_name,
 | 
					                                                         JSAtom base_module_name,
 | 
				
			||||||
                                                    JSAtom module_name1)
 | 
					                                                         JSAtom module_name1,
 | 
				
			||||||
 | 
					                                                         JSValueConst attributes)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    const char *base_cname, *cname;
 | 
					    const char *base_cname, *cname;
 | 
				
			||||||
    JSModuleDef *m;
 | 
					    JSModuleDef *m;
 | 
				
			||||||
@ -28469,7 +28528,7 @@ static JSModuleDef *js_host_resolve_imported_module_atom(JSContext *ctx,
 | 
				
			|||||||
        JS_FreeCString(ctx, base_cname);
 | 
					        JS_FreeCString(ctx, base_cname);
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    m = js_host_resolve_imported_module(ctx, base_cname, cname);
 | 
					    m = js_host_resolve_imported_module(ctx, base_cname, cname, attributes);
 | 
				
			||||||
    JS_FreeCString(ctx, base_cname);
 | 
					    JS_FreeCString(ctx, base_cname);
 | 
				
			||||||
    JS_FreeCString(ctx, cname);
 | 
					    JS_FreeCString(ctx, cname);
 | 
				
			||||||
    return m;
 | 
					    return m;
 | 
				
			||||||
@ -28931,7 +28990,8 @@ static int js_resolve_module(JSContext *ctx, JSModuleDef *m)
 | 
				
			|||||||
    for(i = 0; i < m->req_module_entries_count; i++) {
 | 
					    for(i = 0; i < m->req_module_entries_count; i++) {
 | 
				
			||||||
        JSReqModuleEntry *rme = &m->req_module_entries[i];
 | 
					        JSReqModuleEntry *rme = &m->req_module_entries[i];
 | 
				
			||||||
        m1 = js_host_resolve_imported_module_atom(ctx, m->module_name,
 | 
					        m1 = js_host_resolve_imported_module_atom(ctx, m->module_name,
 | 
				
			||||||
                                                  rme->module_name);
 | 
					                                                  rme->module_name,
 | 
				
			||||||
 | 
					                                                  rme->attributes);
 | 
				
			||||||
        if (!m1)
 | 
					        if (!m1)
 | 
				
			||||||
            return -1;
 | 
					            return -1;
 | 
				
			||||||
        rme->module = m1;
 | 
					        rme->module = m1;
 | 
				
			||||||
@ -29408,14 +29468,15 @@ static JSValue js_load_module_fulfilled(JSContext *ctx, JSValueConst this_val,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static void JS_LoadModuleInternal(JSContext *ctx, const char *basename,
 | 
					static void JS_LoadModuleInternal(JSContext *ctx, const char *basename,
 | 
				
			||||||
                                  const char *filename,
 | 
					                                  const char *filename,
 | 
				
			||||||
                                  JSValueConst *resolving_funcs)
 | 
					                                  JSValueConst *resolving_funcs,
 | 
				
			||||||
 | 
					                                  JSValueConst attributes)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    JSValue evaluate_promise;
 | 
					    JSValue evaluate_promise;
 | 
				
			||||||
    JSModuleDef *m;
 | 
					    JSModuleDef *m;
 | 
				
			||||||
    JSValue ret, err, func_obj, evaluate_resolving_funcs[2];
 | 
					    JSValue ret, err, func_obj, evaluate_resolving_funcs[2];
 | 
				
			||||||
    JSValueConst func_data[3];
 | 
					    JSValueConst func_data[3];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    m = js_host_resolve_imported_module(ctx, basename, filename);
 | 
					    m = js_host_resolve_imported_module(ctx, basename, filename, attributes);
 | 
				
			||||||
    if (!m)
 | 
					    if (!m)
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -29462,7 +29523,7 @@ JSValue JS_LoadModule(JSContext *ctx, const char *basename,
 | 
				
			|||||||
    if (JS_IsException(promise))
 | 
					    if (JS_IsException(promise))
 | 
				
			||||||
        return JS_EXCEPTION;
 | 
					        return JS_EXCEPTION;
 | 
				
			||||||
    JS_LoadModuleInternal(ctx, basename, filename,
 | 
					    JS_LoadModuleInternal(ctx, basename, filename,
 | 
				
			||||||
                          (JSValueConst *)resolving_funcs);
 | 
					                          (JSValueConst *)resolving_funcs, JS_UNDEFINED);
 | 
				
			||||||
    JS_FreeValue(ctx, resolving_funcs[0]);
 | 
					    JS_FreeValue(ctx, resolving_funcs[0]);
 | 
				
			||||||
    JS_FreeValue(ctx, resolving_funcs[1]);
 | 
					    JS_FreeValue(ctx, resolving_funcs[1]);
 | 
				
			||||||
    return promise;
 | 
					    return promise;
 | 
				
			||||||
@ -29474,6 +29535,7 @@ static JSValue js_dynamic_import_job(JSContext *ctx,
 | 
				
			|||||||
    JSValueConst *resolving_funcs = argv;
 | 
					    JSValueConst *resolving_funcs = argv;
 | 
				
			||||||
    JSValueConst basename_val = argv[2];
 | 
					    JSValueConst basename_val = argv[2];
 | 
				
			||||||
    JSValueConst specifier = argv[3];
 | 
					    JSValueConst specifier = argv[3];
 | 
				
			||||||
 | 
					    JSValueConst attributes = argv[4];
 | 
				
			||||||
    const char *basename = NULL, *filename;
 | 
					    const char *basename = NULL, *filename;
 | 
				
			||||||
    JSValue ret, err;
 | 
					    JSValue ret, err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -29490,7 +29552,7 @@ static JSValue js_dynamic_import_job(JSContext *ctx,
 | 
				
			|||||||
        goto exception;
 | 
					        goto exception;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    JS_LoadModuleInternal(ctx, basename, filename,
 | 
					    JS_LoadModuleInternal(ctx, basename, filename,
 | 
				
			||||||
                          resolving_funcs);
 | 
					                          resolving_funcs, attributes);
 | 
				
			||||||
    JS_FreeCString(ctx, filename);
 | 
					    JS_FreeCString(ctx, filename);
 | 
				
			||||||
    JS_FreeCString(ctx, basename);
 | 
					    JS_FreeCString(ctx, basename);
 | 
				
			||||||
    return JS_UNDEFINED;
 | 
					    return JS_UNDEFINED;
 | 
				
			||||||
@ -29504,11 +29566,12 @@ static JSValue js_dynamic_import_job(JSContext *ctx,
 | 
				
			|||||||
    return JS_UNDEFINED;
 | 
					    return JS_UNDEFINED;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static JSValue js_dynamic_import(JSContext *ctx, JSValueConst specifier)
 | 
					static JSValue js_dynamic_import(JSContext *ctx, JSValueConst specifier, JSValueConst options)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    JSAtom basename;
 | 
					    JSAtom basename;
 | 
				
			||||||
    JSValue promise, resolving_funcs[2], basename_val;
 | 
					    JSValue promise, resolving_funcs[2], basename_val, err, ret;
 | 
				
			||||||
    JSValueConst args[4];
 | 
					    JSValue specifier_str = JS_UNDEFINED, attributes = JS_UNDEFINED, attributes_obj = JS_UNDEFINED;
 | 
				
			||||||
 | 
					    JSValueConst args[5];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    basename = JS_GetScriptOrModuleName(ctx, 0);
 | 
					    basename = JS_GetScriptOrModuleName(ctx, 0);
 | 
				
			||||||
    if (basename == JS_ATOM_NULL)
 | 
					    if (basename == JS_ATOM_NULL)
 | 
				
			||||||
@ -29525,19 +29588,82 @@ static JSValue js_dynamic_import(JSContext *ctx, JSValueConst specifier)
 | 
				
			|||||||
        return promise;
 | 
					        return promise;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* the string conversion must occur here */
 | 
				
			||||||
 | 
					    specifier_str = JS_ToString(ctx, specifier);
 | 
				
			||||||
 | 
					    if (JS_IsException(specifier_str))
 | 
				
			||||||
 | 
					        goto exception;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (!JS_IsUndefined(options)) {
 | 
				
			||||||
 | 
					        if (!JS_IsObject(options)) {
 | 
				
			||||||
 | 
					            JS_ThrowTypeError(ctx, "options must be an object");
 | 
				
			||||||
 | 
					            goto exception;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        attributes_obj = JS_GetProperty(ctx, options, JS_ATOM_with);
 | 
				
			||||||
 | 
					        if (JS_IsException(attributes_obj))
 | 
				
			||||||
 | 
					            goto exception;
 | 
				
			||||||
 | 
					        if (!JS_IsUndefined(attributes_obj)) {
 | 
				
			||||||
 | 
					            JSPropertyEnum *atoms;
 | 
				
			||||||
 | 
					            uint32_t atoms_len, i;
 | 
				
			||||||
 | 
					            JSValue val;
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            if (!JS_IsObject(attributes_obj)) {
 | 
				
			||||||
 | 
					                JS_ThrowTypeError(ctx, "options.with must be an object");
 | 
				
			||||||
 | 
					                goto exception;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            attributes = JS_NewObjectProto(ctx, JS_NULL);
 | 
				
			||||||
 | 
					            if (JS_GetOwnPropertyNamesInternal(ctx, &atoms, &atoms_len, JS_VALUE_GET_OBJ(attributes_obj),
 | 
				
			||||||
 | 
					                                               JS_GPN_STRING_MASK | JS_GPN_ENUM_ONLY)) {
 | 
				
			||||||
 | 
					                goto exception;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            for(i = 0; i < atoms_len; i++) {
 | 
				
			||||||
 | 
					                val = JS_GetProperty(ctx, attributes_obj, atoms[i].atom);
 | 
				
			||||||
 | 
					                if (JS_IsException(val))
 | 
				
			||||||
 | 
					                    goto exception1;
 | 
				
			||||||
 | 
					                if (!JS_IsString(val)) {
 | 
				
			||||||
 | 
					                    JS_FreeValue(ctx, val);
 | 
				
			||||||
 | 
					                    JS_ThrowTypeError(ctx, "module attribute values must be strings");
 | 
				
			||||||
 | 
					                    goto exception1;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (JS_DefinePropertyValue(ctx, attributes,  atoms[i].atom, val,
 | 
				
			||||||
 | 
					                                           JS_PROP_C_W_E) < 0) {
 | 
				
			||||||
 | 
					                exception1:
 | 
				
			||||||
 | 
					                    JS_FreePropertyEnum(ctx, atoms, atoms_len);
 | 
				
			||||||
 | 
					                    goto exception;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            JS_FreePropertyEnum(ctx, atoms, atoms_len);
 | 
				
			||||||
 | 
					            if (ctx->rt->module_check_attrs &&
 | 
				
			||||||
 | 
					                ctx->rt->module_check_attrs(ctx, ctx->rt->module_loader_opaque, attributes) < 0) {
 | 
				
			||||||
 | 
					                goto exception;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            JS_FreeValue(ctx, attributes_obj);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    args[0] = resolving_funcs[0];
 | 
					    args[0] = resolving_funcs[0];
 | 
				
			||||||
    args[1] = resolving_funcs[1];
 | 
					    args[1] = resolving_funcs[1];
 | 
				
			||||||
    args[2] = basename_val;
 | 
					    args[2] = basename_val;
 | 
				
			||||||
    args[3] = specifier;
 | 
					    args[3] = specifier_str;
 | 
				
			||||||
 | 
					    args[4] = attributes;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    /* cannot run JS_LoadModuleInternal synchronously because it would
 | 
					    /* cannot run JS_LoadModuleInternal synchronously because it would
 | 
				
			||||||
       cause an unexpected recursion in js_evaluate_module() */
 | 
					       cause an unexpected recursion in js_evaluate_module() */
 | 
				
			||||||
    JS_EnqueueJob(ctx, js_dynamic_import_job, 4, args);
 | 
					    JS_EnqueueJob(ctx, js_dynamic_import_job, 5, args);
 | 
				
			||||||
 | 
					 done:
 | 
				
			||||||
    JS_FreeValue(ctx, basename_val);
 | 
					    JS_FreeValue(ctx, basename_val);
 | 
				
			||||||
    JS_FreeValue(ctx, resolving_funcs[0]);
 | 
					    JS_FreeValue(ctx, resolving_funcs[0]);
 | 
				
			||||||
    JS_FreeValue(ctx, resolving_funcs[1]);
 | 
					    JS_FreeValue(ctx, resolving_funcs[1]);
 | 
				
			||||||
 | 
					    JS_FreeValue(ctx, specifier_str);
 | 
				
			||||||
 | 
					    JS_FreeValue(ctx, attributes);
 | 
				
			||||||
    return promise;
 | 
					    return promise;
 | 
				
			||||||
 | 
					 exception:
 | 
				
			||||||
 | 
					    JS_FreeValue(ctx, attributes_obj);
 | 
				
			||||||
 | 
					    err = JS_GetException(ctx);
 | 
				
			||||||
 | 
					    ret = JS_Call(ctx, resolving_funcs[1], JS_UNDEFINED,
 | 
				
			||||||
 | 
					                   1, (JSValueConst *)&err);
 | 
				
			||||||
 | 
					    JS_FreeValue(ctx, ret);
 | 
				
			||||||
 | 
					    JS_FreeValue(ctx, err);
 | 
				
			||||||
 | 
					    goto done;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void js_set_module_evaluated(JSContext *ctx, JSModuleDef *m)
 | 
					static void js_set_module_evaluated(JSContext *ctx, JSModuleDef *m)
 | 
				
			||||||
@ -29933,27 +30059,109 @@ static JSValue js_evaluate_module(JSContext *ctx, JSModuleDef *m)
 | 
				
			|||||||
    return JS_DupValue(ctx, m->promise);
 | 
					    return JS_DupValue(ctx, m->promise);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static __exception JSAtom js_parse_from_clause(JSParseState *s)
 | 
					static __exception int js_parse_with_clause(JSParseState *s, JSReqModuleEntry *rme)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    JSContext *ctx = s->ctx;
 | 
				
			||||||
 | 
					    JSAtom key;
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					    const uint8_t *key_token_ptr;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (next_token(s))
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    if (js_parse_expect(s, '{'))
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    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;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            if (!token_is_ident(s->token.val)) {
 | 
				
			||||||
 | 
					                js_parse_error(s, "identifier expected");
 | 
				
			||||||
 | 
					                return -1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            key = JS_DupAtom(ctx, s->token.u.ident.atom);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (next_token(s))
 | 
				
			||||||
 | 
					            return -1;
 | 
				
			||||||
 | 
					        if (js_parse_expect(s, ':')) {
 | 
				
			||||||
 | 
					            JS_FreeAtom(ctx, key);
 | 
				
			||||||
 | 
					            return -1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (s->token.val != TOK_STRING) {
 | 
				
			||||||
 | 
					            js_parse_error_pos(s, key_token_ptr, "string expected");
 | 
				
			||||||
 | 
					            return -1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (JS_IsUndefined(rme->attributes)) {
 | 
				
			||||||
 | 
					            JSValue attributes = JS_NewObjectProto(ctx, JS_NULL);
 | 
				
			||||||
 | 
					            if (JS_IsException(attributes)) {
 | 
				
			||||||
 | 
					                JS_FreeAtom(ctx, key);
 | 
				
			||||||
 | 
					                return -1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            rme->attributes = attributes;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        ret = JS_HasProperty(ctx, rme->attributes, key);
 | 
				
			||||||
 | 
					        if (ret != 0) {
 | 
				
			||||||
 | 
					            JS_FreeAtom(ctx, key);
 | 
				
			||||||
 | 
					            if (ret < 0)
 | 
				
			||||||
 | 
					                return -1;
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                return js_parse_error(s, "duplicate with key");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        ret = JS_DefinePropertyValue(ctx, rme->attributes, key,
 | 
				
			||||||
 | 
					                                     JS_DupValue(ctx, s->token.u.str.str), JS_PROP_C_W_E);
 | 
				
			||||||
 | 
					        JS_FreeAtom(ctx, key);
 | 
				
			||||||
 | 
					        if (ret < 0)
 | 
				
			||||||
 | 
					            return -1;
 | 
				
			||||||
 | 
					        if (next_token(s))
 | 
				
			||||||
 | 
					            return -1;
 | 
				
			||||||
 | 
					        if (s->token.val != ',')
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        if (next_token(s))
 | 
				
			||||||
 | 
					            return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (!JS_IsUndefined(rme->attributes) &&
 | 
				
			||||||
 | 
					        ctx->rt->module_check_attrs &&
 | 
				
			||||||
 | 
					        ctx->rt->module_check_attrs(ctx, ctx->rt->module_loader_opaque, rme->attributes) < 0) {
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return js_parse_expect(s, '}');
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* return the module index in m->req_module_entries[] or < 0 if error */
 | 
				
			||||||
 | 
					static __exception int js_parse_from_clause(JSParseState *s, JSModuleDef *m)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    JSAtom module_name;
 | 
					    JSAtom module_name;
 | 
				
			||||||
 | 
					    int idx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!token_is_pseudo_keyword(s, JS_ATOM_from)) {
 | 
					    if (!token_is_pseudo_keyword(s, JS_ATOM_from)) {
 | 
				
			||||||
        js_parse_error(s, "from clause expected");
 | 
					        js_parse_error(s, "from clause expected");
 | 
				
			||||||
        return JS_ATOM_NULL;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (next_token(s))
 | 
					    if (next_token(s))
 | 
				
			||||||
        return JS_ATOM_NULL;
 | 
					        return -1;
 | 
				
			||||||
    if (s->token.val != TOK_STRING) {
 | 
					    if (s->token.val != TOK_STRING) {
 | 
				
			||||||
        js_parse_error(s, "string expected");
 | 
					        js_parse_error(s, "string expected");
 | 
				
			||||||
        return JS_ATOM_NULL;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    module_name = JS_ValueToAtom(s->ctx, s->token.u.str.str);
 | 
					    module_name = JS_ValueToAtom(s->ctx, s->token.u.str.str);
 | 
				
			||||||
    if (module_name == JS_ATOM_NULL)
 | 
					    if (module_name == JS_ATOM_NULL)
 | 
				
			||||||
        return JS_ATOM_NULL;
 | 
					        return -1;
 | 
				
			||||||
    if (next_token(s)) {
 | 
					    if (next_token(s)) {
 | 
				
			||||||
        JS_FreeAtom(s->ctx, module_name);
 | 
					        JS_FreeAtom(s->ctx, module_name);
 | 
				
			||||||
        return JS_ATOM_NULL;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return module_name;
 | 
					
 | 
				
			||||||
 | 
					    idx = add_req_module_entry(s->ctx, m, module_name);
 | 
				
			||||||
 | 
					    JS_FreeAtom(s->ctx, module_name);
 | 
				
			||||||
 | 
					    if (idx < 0)
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    if (s->token.val == TOK_WITH) {
 | 
				
			||||||
 | 
					        if (js_parse_with_clause(s, &m->req_module_entries[idx]))
 | 
				
			||||||
 | 
					            return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return idx;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static __exception int js_parse_export(JSParseState *s)
 | 
					static __exception int js_parse_export(JSParseState *s)
 | 
				
			||||||
@ -29962,7 +30170,6 @@ static __exception int js_parse_export(JSParseState *s)
 | 
				
			|||||||
    JSModuleDef *m = s->cur_func->module;
 | 
					    JSModuleDef *m = s->cur_func->module;
 | 
				
			||||||
    JSAtom local_name, export_name;
 | 
					    JSAtom local_name, export_name;
 | 
				
			||||||
    int first_export, idx, i, tok;
 | 
					    int first_export, idx, i, tok;
 | 
				
			||||||
    JSAtom module_name;
 | 
					 | 
				
			||||||
    JSExportEntry *me;
 | 
					    JSExportEntry *me;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (next_token(s))
 | 
					    if (next_token(s))
 | 
				
			||||||
@ -30037,11 +30244,7 @@ static __exception int js_parse_export(JSParseState *s)
 | 
				
			|||||||
        if (js_parse_expect(s, '}'))
 | 
					        if (js_parse_expect(s, '}'))
 | 
				
			||||||
            return -1;
 | 
					            return -1;
 | 
				
			||||||
        if (token_is_pseudo_keyword(s, JS_ATOM_from)) {
 | 
					        if (token_is_pseudo_keyword(s, JS_ATOM_from)) {
 | 
				
			||||||
            module_name = js_parse_from_clause(s);
 | 
					            idx = js_parse_from_clause(s, m);
 | 
				
			||||||
            if (module_name == JS_ATOM_NULL)
 | 
					 | 
				
			||||||
                return -1;
 | 
					 | 
				
			||||||
            idx = add_req_module_entry(ctx, m, module_name);
 | 
					 | 
				
			||||||
            JS_FreeAtom(ctx, module_name);
 | 
					 | 
				
			||||||
            if (idx < 0)
 | 
					            if (idx < 0)
 | 
				
			||||||
                return -1;
 | 
					                return -1;
 | 
				
			||||||
            for(i = first_export; i < m->export_entries_count; i++) {
 | 
					            for(i = first_export; i < m->export_entries_count; i++) {
 | 
				
			||||||
@ -30063,11 +30266,7 @@ static __exception int js_parse_export(JSParseState *s)
 | 
				
			|||||||
            export_name = JS_DupAtom(ctx, s->token.u.ident.atom);
 | 
					            export_name = JS_DupAtom(ctx, s->token.u.ident.atom);
 | 
				
			||||||
            if (next_token(s))
 | 
					            if (next_token(s))
 | 
				
			||||||
                goto fail1;
 | 
					                goto fail1;
 | 
				
			||||||
            module_name = js_parse_from_clause(s);
 | 
					            idx = js_parse_from_clause(s, m);
 | 
				
			||||||
            if (module_name == JS_ATOM_NULL)
 | 
					 | 
				
			||||||
                goto fail1;
 | 
					 | 
				
			||||||
            idx = add_req_module_entry(ctx, m, module_name);
 | 
					 | 
				
			||||||
            JS_FreeAtom(ctx, module_name);
 | 
					 | 
				
			||||||
            if (idx < 0)
 | 
					            if (idx < 0)
 | 
				
			||||||
                goto fail1;
 | 
					                goto fail1;
 | 
				
			||||||
            me = add_export_entry(s, m, JS_ATOM__star_, export_name,
 | 
					            me = add_export_entry(s, m, JS_ATOM__star_, export_name,
 | 
				
			||||||
@ -30077,11 +30276,7 @@ static __exception int js_parse_export(JSParseState *s)
 | 
				
			|||||||
                return -1;
 | 
					                return -1;
 | 
				
			||||||
            me->u.req_module_idx = idx;
 | 
					            me->u.req_module_idx = idx;
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            module_name = js_parse_from_clause(s);
 | 
					            idx = js_parse_from_clause(s, m);
 | 
				
			||||||
            if (module_name == JS_ATOM_NULL)
 | 
					 | 
				
			||||||
                return -1;
 | 
					 | 
				
			||||||
            idx = add_req_module_entry(ctx, m, module_name);
 | 
					 | 
				
			||||||
            JS_FreeAtom(ctx, module_name);
 | 
					 | 
				
			||||||
            if (idx < 0)
 | 
					            if (idx < 0)
 | 
				
			||||||
                return -1;
 | 
					                return -1;
 | 
				
			||||||
            if (add_star_export_entry(ctx, m, idx) < 0)
 | 
					            if (add_star_export_entry(ctx, m, idx) < 0)
 | 
				
			||||||
@ -30187,6 +30382,14 @@ static __exception int js_parse_import(JSParseState *s)
 | 
				
			|||||||
            JS_FreeAtom(ctx, module_name);
 | 
					            JS_FreeAtom(ctx, module_name);
 | 
				
			||||||
            return -1;
 | 
					            return -1;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        idx = add_req_module_entry(ctx, m, module_name);
 | 
				
			||||||
 | 
					        JS_FreeAtom(ctx, module_name);
 | 
				
			||||||
 | 
					        if (idx < 0)
 | 
				
			||||||
 | 
					            return -1;
 | 
				
			||||||
 | 
					        if (s->token.val == TOK_WITH) {
 | 
				
			||||||
 | 
					            if (js_parse_with_clause(s, &m->req_module_entries[idx]))
 | 
				
			||||||
 | 
					                return -1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        if (s->token.val == TOK_IDENT) {
 | 
					        if (s->token.val == TOK_IDENT) {
 | 
				
			||||||
            if (s->token.u.ident.is_reserved) {
 | 
					            if (s->token.u.ident.is_reserved) {
 | 
				
			||||||
@ -30285,14 +30488,10 @@ static __exception int js_parse_import(JSParseState *s)
 | 
				
			|||||||
                return -1;
 | 
					                return -1;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    end_import_clause:
 | 
					    end_import_clause:
 | 
				
			||||||
        module_name = js_parse_from_clause(s);
 | 
					        idx = js_parse_from_clause(s, m);
 | 
				
			||||||
        if (module_name == JS_ATOM_NULL)
 | 
					        if (idx < 0)
 | 
				
			||||||
            return -1;
 | 
					            return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    idx = add_req_module_entry(ctx, m, module_name);
 | 
					 | 
				
			||||||
    JS_FreeAtom(ctx, module_name);
 | 
					 | 
				
			||||||
    if (idx < 0)
 | 
					 | 
				
			||||||
        return -1;
 | 
					 | 
				
			||||||
    for(i = first_import; i < m->import_entries_count; i++)
 | 
					    for(i = first_import; i < m->import_entries_count; i++)
 | 
				
			||||||
        m->import_entries[i].req_module_idx = idx;
 | 
					        m->import_entries[i].req_module_idx = idx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										20
									
								
								quickjs.h
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								quickjs.h
									
									
									
									
									
								
							@ -936,12 +936,25 @@ typedef char *JSModuleNormalizeFunc(JSContext *ctx,
 | 
				
			|||||||
                                    const char *module_name, void *opaque);
 | 
					                                    const char *module_name, void *opaque);
 | 
				
			||||||
typedef JSModuleDef *JSModuleLoaderFunc(JSContext *ctx,
 | 
					typedef JSModuleDef *JSModuleLoaderFunc(JSContext *ctx,
 | 
				
			||||||
                                        const char *module_name, void *opaque);
 | 
					                                        const char *module_name, void *opaque);
 | 
				
			||||||
 | 
					typedef JSModuleDef *JSModuleLoaderFunc2(JSContext *ctx,
 | 
				
			||||||
 | 
					                                         const char *module_name, void *opaque,
 | 
				
			||||||
 | 
					                                         JSValueConst attributes);
 | 
				
			||||||
 | 
					/* return -1 if exception, 0 if OK */
 | 
				
			||||||
 | 
					typedef int JSModuleCheckSupportedImportAttributes(JSContext *ctx, void *opaque,
 | 
				
			||||||
 | 
					                                                   JSValueConst attributes);
 | 
				
			||||||
 | 
					                                                   
 | 
				
			||||||
/* module_normalize = NULL is allowed and invokes the default module
 | 
					/* module_normalize = NULL is allowed and invokes the default module
 | 
				
			||||||
   filename normalizer */
 | 
					   filename normalizer */
 | 
				
			||||||
void JS_SetModuleLoaderFunc(JSRuntime *rt,
 | 
					void JS_SetModuleLoaderFunc(JSRuntime *rt,
 | 
				
			||||||
                            JSModuleNormalizeFunc *module_normalize,
 | 
					                            JSModuleNormalizeFunc *module_normalize,
 | 
				
			||||||
                            JSModuleLoaderFunc *module_loader, void *opaque);
 | 
					                            JSModuleLoaderFunc *module_loader, void *opaque);
 | 
				
			||||||
 | 
					/* same as JS_SetModuleLoaderFunc but with attributes. if
 | 
				
			||||||
 | 
					   module_check_attrs = NULL, no attribute checking is done. */
 | 
				
			||||||
 | 
					void JS_SetModuleLoaderFunc2(JSRuntime *rt,
 | 
				
			||||||
 | 
					                             JSModuleNormalizeFunc *module_normalize,
 | 
				
			||||||
 | 
					                             JSModuleLoaderFunc2 *module_loader,
 | 
				
			||||||
 | 
					                             JSModuleCheckSupportedImportAttributes *module_check_attrs,
 | 
				
			||||||
 | 
					                             void *opaque);
 | 
				
			||||||
/* return the import.meta object of a module */
 | 
					/* return the import.meta object of a module */
 | 
				
			||||||
JSValue JS_GetImportMeta(JSContext *ctx, JSModuleDef *m);
 | 
					JSValue JS_GetImportMeta(JSContext *ctx, JSModuleDef *m);
 | 
				
			||||||
JSAtom JS_GetModuleName(JSContext *ctx, JSModuleDef *m);
 | 
					JSAtom JS_GetModuleName(JSContext *ctx, JSModuleDef *m);
 | 
				
			||||||
@ -1119,7 +1132,10 @@ int JS_SetModuleExport(JSContext *ctx, JSModuleDef *m, const char *export_name,
 | 
				
			|||||||
                       JSValue val);
 | 
					                       JSValue val);
 | 
				
			||||||
int JS_SetModuleExportList(JSContext *ctx, JSModuleDef *m,
 | 
					int JS_SetModuleExportList(JSContext *ctx, JSModuleDef *m,
 | 
				
			||||||
                           const JSCFunctionListEntry *tab, int len);
 | 
					                           const JSCFunctionListEntry *tab, int len);
 | 
				
			||||||
 | 
					/* associate a JSValue to a C module */
 | 
				
			||||||
 | 
					int JS_SetModulePrivateValue(JSContext *ctx, JSModuleDef *m, JSValue val);
 | 
				
			||||||
 | 
					JSValue JS_GetModulePrivateValue(JSContext *ctx, JSModuleDef *m);
 | 
				
			||||||
 | 
					                        
 | 
				
			||||||
/* debug value output */
 | 
					/* debug value output */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
 | 
				
			|||||||
@ -836,13 +836,21 @@ static char *load_file(const char *filename, size_t *lenp)
 | 
				
			|||||||
    return buf;
 | 
					    return buf;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int json_module_init_test(JSContext *ctx, JSModuleDef *m)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    JSValue val;
 | 
				
			||||||
 | 
					    val = JS_GetModulePrivateValue(ctx, m);
 | 
				
			||||||
 | 
					    JS_SetModuleExport(ctx, m, "default", val);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static JSModuleDef *js_module_loader_test(JSContext *ctx,
 | 
					static JSModuleDef *js_module_loader_test(JSContext *ctx,
 | 
				
			||||||
                                          const char *module_name, void *opaque)
 | 
					                                          const char *module_name, void *opaque,
 | 
				
			||||||
 | 
					                                          JSValueConst attributes)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    size_t buf_len;
 | 
					    size_t buf_len;
 | 
				
			||||||
    uint8_t *buf;
 | 
					    uint8_t *buf;
 | 
				
			||||||
    JSModuleDef *m;
 | 
					    JSModuleDef *m;
 | 
				
			||||||
    JSValue func_val;
 | 
					 | 
				
			||||||
    char *filename, *slash, path[1024];
 | 
					    char *filename, *slash, path[1024];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // interpret import("bar.js") from path/to/foo.js as
 | 
					    // interpret import("bar.js") from path/to/foo.js as
 | 
				
			||||||
@ -864,15 +872,33 @@ static JSModuleDef *js_module_loader_test(JSContext *ctx,
 | 
				
			|||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* compile the module */
 | 
					    if (js_module_test_json(ctx, attributes)) {
 | 
				
			||||||
    func_val = JS_Eval(ctx, (char *)buf, buf_len, module_name,
 | 
					        /* compile as JSON */
 | 
				
			||||||
                       JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
 | 
					        JSValue val;
 | 
				
			||||||
    js_free(ctx, buf);
 | 
					        val = JS_ParseJSON(ctx, (char *)buf, buf_len, module_name);
 | 
				
			||||||
    if (JS_IsException(func_val))
 | 
					        js_free(ctx, buf);
 | 
				
			||||||
        return NULL;
 | 
					        if (JS_IsException(val))
 | 
				
			||||||
    /* the module is already referenced, so we must free it */
 | 
					            return NULL;
 | 
				
			||||||
    m = JS_VALUE_GET_PTR(func_val);
 | 
					        m = JS_NewCModule(ctx, module_name, json_module_init_test);
 | 
				
			||||||
    JS_FreeValue(ctx, func_val);
 | 
					        if (!m) {
 | 
				
			||||||
 | 
					            JS_FreeValue(ctx, val);
 | 
				
			||||||
 | 
					            return NULL;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        /* 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;
 | 
					    return m;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1587,7 +1613,7 @@ int run_test_buf(const char *filename, const char *harness, namelist_t *ip,
 | 
				
			|||||||
    JS_SetCanBlock(rt, can_block);
 | 
					    JS_SetCanBlock(rt, can_block);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* loader for ES6 modules */
 | 
					    /* loader for ES6 modules */
 | 
				
			||||||
    JS_SetModuleLoaderFunc(rt, NULL, js_module_loader_test, (void *)filename);
 | 
					    JS_SetModuleLoaderFunc2(rt, NULL, js_module_loader_test, NULL, (void *)filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    add_helpers(ctx);
 | 
					    add_helpers(ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1888,7 +1914,7 @@ int run_test262_harness_test(const char *filename, BOOL is_module)
 | 
				
			|||||||
    JS_SetCanBlock(rt, can_block);
 | 
					    JS_SetCanBlock(rt, can_block);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* loader for ES6 modules */
 | 
					    /* loader for ES6 modules */
 | 
				
			||||||
    JS_SetModuleLoaderFunc(rt, NULL, js_module_loader_test, (void *)filename);
 | 
					    JS_SetModuleLoaderFunc2(rt, NULL, js_module_loader_test, NULL, (void *)filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    add_helpers(ctx);
 | 
					    add_helpers(ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -116,9 +116,7 @@ for-of
 | 
				
			|||||||
generators
 | 
					generators
 | 
				
			||||||
globalThis
 | 
					globalThis
 | 
				
			||||||
hashbang
 | 
					hashbang
 | 
				
			||||||
host-gc-required=skip
 | 
					import-attributes
 | 
				
			||||||
import-assertions=skip
 | 
					 | 
				
			||||||
import-attributes=skip
 | 
					 | 
				
			||||||
import-defer=skip
 | 
					import-defer=skip
 | 
				
			||||||
import.meta
 | 
					import.meta
 | 
				
			||||||
Int16Array
 | 
					Int16Array
 | 
				
			||||||
@ -144,7 +142,7 @@ Intl.Segmenter=skip
 | 
				
			|||||||
IsHTMLDDA
 | 
					IsHTMLDDA
 | 
				
			||||||
iterator-helpers=skip
 | 
					iterator-helpers=skip
 | 
				
			||||||
iterator-sequencing=skip
 | 
					iterator-sequencing=skip
 | 
				
			||||||
json-modules=skip
 | 
					json-modules
 | 
				
			||||||
json-parse-with-source=skip
 | 
					json-parse-with-source=skip
 | 
				
			||||||
json-superset
 | 
					json-superset
 | 
				
			||||||
legacy-regexp=skip
 | 
					legacy-regexp=skip
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user