@@ -591,8 +591,72 @@ int js_module_set_import_meta(JSContext *ctx, JSValueConst func_val,
591591 return 0 ;
592592}
593593
594+ static int json_module_init (JSContext * ctx , JSModuleDef * m )
595+ {
596+ JSValue val ;
597+ val = JS_GetModulePrivateValue (ctx , m );
598+ JS_SetModuleExport (ctx , m , "default" , val );
599+ return 0 ;
600+ }
601+
602+ /* in order to conform with the specification, only the keys should be
603+ tested and not the associated values. */
604+ int js_module_check_attributes (JSContext * ctx , void * opaque ,
605+ JSValueConst attributes )
606+ {
607+ JSPropertyEnum * tab ;
608+ uint32_t i , len ;
609+ int ret ;
610+ const char * cstr ;
611+ size_t cstr_len ;
612+
613+ if (JS_GetOwnPropertyNames (ctx , & tab , & len , attributes , JS_GPN_ENUM_ONLY | JS_GPN_STRING_MASK ))
614+ return -1 ;
615+ ret = 0 ;
616+ for (i = 0 ; i < len ; i ++ ) {
617+ cstr = JS_AtomToCStringLen (ctx , & cstr_len , tab [i ].atom );
618+ if (!cstr ) {
619+ ret = -1 ;
620+ break ;
621+ }
622+ if (!(cstr_len == 4 && !memcmp (cstr , "type" , cstr_len ))) {
623+ JS_ThrowTypeError (ctx , "import attribute '%s' is not supported" , cstr );
624+ ret = -1 ;
625+ }
626+ JS_FreeCString (ctx , cstr );
627+ if (ret )
628+ break ;
629+ }
630+ JS_FreePropertyEnum (ctx , tab , len );
631+ return ret ;
632+ }
633+
634+ /* return TRUE if the attributes indicate a JSON module */
635+ JS_BOOL js_module_test_json (JSContext * ctx , JSValueConst attributes )
636+ {
637+ JSValue str ;
638+ const char * cstr ;
639+ size_t len ;
640+ BOOL res ;
641+
642+ if (JS_IsUndefined (attributes ))
643+ return FALSE;
644+ str = JS_GetPropertyStr (ctx , attributes , "type" );
645+ if (!JS_IsString (str ))
646+ return FALSE;
647+ cstr = JS_ToCStringLen (ctx , & len , str );
648+ JS_FreeValue (ctx , str );
649+ if (!cstr )
650+ return FALSE;
651+ /* XXX: raise an error if unknown type ? */
652+ res = (len == 4 && !memcmp (cstr , "json" , len ));
653+ JS_FreeCString (ctx , cstr );
654+ return res ;
655+ }
656+
594657JSModuleDef * js_module_loader (JSContext * ctx ,
595- const char * module_name , void * opaque )
658+ const char * module_name , void * opaque ,
659+ JSValueConst attributes )
596660{
597661 JSModuleDef * m ;
598662
@@ -601,26 +665,44 @@ JSModuleDef *js_module_loader(JSContext *ctx,
601665 } else {
602666 size_t buf_len ;
603667 uint8_t * buf ;
604- JSValue func_val ;
605668
606669 buf = js_load_file (ctx , & buf_len , module_name );
607670 if (!buf ) {
608671 JS_ThrowReferenceError (ctx , "could not load module filename '%s'" ,
609672 module_name );
610673 return NULL ;
611674 }
612-
613- /* compile the module */
614- func_val = JS_Eval (ctx , (char * )buf , buf_len , module_name ,
615- JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY );
616- js_free (ctx , buf );
617- if (JS_IsException (func_val ))
618- return NULL ;
619- /* XXX: could propagate the exception */
620- js_module_set_import_meta (ctx , func_val , TRUE, FALSE);
621- /* the module is already referenced, so we must free it */
622- m = JS_VALUE_GET_PTR (func_val );
623- JS_FreeValue (ctx , func_val );
675+
676+ if (has_suffix (module_name , ".json" ) ||
677+ js_module_test_json (ctx , attributes )) {
678+ /* compile as JSON */
679+ JSValue val ;
680+ val = JS_ParseJSON (ctx , (char * )buf , buf_len , module_name );
681+ js_free (ctx , buf );
682+ if (JS_IsException (val ))
683+ return NULL ;
684+ m = JS_NewCModule (ctx , module_name , json_module_init );
685+ if (!m ) {
686+ JS_FreeValue (ctx , val );
687+ return NULL ;
688+ }
689+ /* only export the "default" symbol which will contain the JSON object */
690+ JS_AddModuleExport (ctx , m , "default" );
691+ JS_SetModulePrivateValue (ctx , m , val );
692+ } else {
693+ JSValue func_val ;
694+ /* compile the module */
695+ func_val = JS_Eval (ctx , (char * )buf , buf_len , module_name ,
696+ JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY );
697+ js_free (ctx , buf );
698+ if (JS_IsException (func_val ))
699+ return NULL ;
700+ /* XXX: could propagate the exception */
701+ js_module_set_import_meta (ctx , func_val , TRUE, FALSE);
702+ /* the module is already referenced, so we must free it */
703+ m = JS_VALUE_GET_PTR (func_val );
704+ JS_FreeValue (ctx , func_val );
705+ }
624706 }
625707 return m ;
626708}
@@ -3478,7 +3560,7 @@ static void *worker_func(void *opaque)
34783560 JS_SetStripInfo (rt , args -> strip_flags );
34793561 js_std_init_handlers (rt );
34803562
3481- JS_SetModuleLoaderFunc (rt , NULL , js_module_loader , NULL );
3563+ JS_SetModuleLoaderFunc2 (rt , NULL , js_module_loader , js_module_check_attributes , NULL );
34823564
34833565 /* set the pipe to communicate with the parent */
34843566 ts = JS_GetRuntimeOpaque (rt );
0 commit comments