@@ -591,8 +591,72 @@ int js_module_set_import_meta(JSContext *ctx, JSValueConst func_val,
591
591
return 0 ;
592
592
}
593
593
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
+
594
657
JSModuleDef * js_module_loader (JSContext * ctx ,
595
- const char * module_name , void * opaque )
658
+ const char * module_name , void * opaque ,
659
+ JSValueConst attributes )
596
660
{
597
661
JSModuleDef * m ;
598
662
@@ -601,26 +665,44 @@ JSModuleDef *js_module_loader(JSContext *ctx,
601
665
} else {
602
666
size_t buf_len ;
603
667
uint8_t * buf ;
604
- JSValue func_val ;
605
668
606
669
buf = js_load_file (ctx , & buf_len , module_name );
607
670
if (!buf ) {
608
671
JS_ThrowReferenceError (ctx , "could not load module filename '%s'" ,
609
672
module_name );
610
673
return NULL ;
611
674
}
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
+ }
624
706
}
625
707
return m ;
626
708
}
@@ -3478,7 +3560,7 @@ static void *worker_func(void *opaque)
3478
3560
JS_SetStripInfo (rt , args -> strip_flags );
3479
3561
js_std_init_handlers (rt );
3480
3562
3481
- JS_SetModuleLoaderFunc (rt , NULL , js_module_loader , NULL );
3563
+ JS_SetModuleLoaderFunc2 (rt , NULL , js_module_loader , js_module_check_attributes , NULL );
3482
3564
3483
3565
/* set the pipe to communicate with the parent */
3484
3566
ts = JS_GetRuntimeOpaque (rt );
0 commit comments