4040 \ --nodejs-cps Produce JavaScript code for Node.js (CPS mode).\n \
4141 \ --webjs Produce JavaScript code for Web.\n \
4242 \ --webjs-cps Produce JavaScript code for Web (CPS mode).\n \
43+ \ --wasm Produce WebAssembly binary (.wasm).\n \
44+ \ --wasm-wat Produce WebAssembly text format (.wat).\n \
4345 \ -h,--help Show this message.\n \
4446 \ -v,--version Show version information.\n \
4547 \ --dump Dump intermediate code.\n \
@@ -94,6 +96,14 @@ struct
9496 , minInt = SOME TargetInfo.minInt54
9597 , maxInt = SOME TargetInfo.maxInt54
9698 , wordSize = 32
99+ }
100+ | BACKEND_WASM _ =>
101+ { defaultInt = Primitives.I32
102+ , defaultWord = Primitives.W32
103+ , datatypeTag = TargetInfo.STRING8
104+ , minInt = SOME TargetInfo.minInt32
105+ , maxInt = SOME TargetInfo.maxInt32
106+ , wordSize = 32
97107 })
98108 fun optimizeCps
99109 (_: {nextTyVar: int ref, nextVId: int ref, printTimings: bool}) _ cexp 0 =
@@ -361,6 +371,8 @@ struct
361371 in
362372 ()
363373 end
374+ | emit ({backend = BACKEND_WASM _, ...}: options) _ _ _ _ _ _ =
375+ raise Fail " Wasm code generation is not yet implemented"
364376 structure CheckFInit =
365377 struct
366378 fun toFTy (TypedSyntax.TyVar (_, tv)) = FSyntax.TyVar tv
@@ -456,12 +468,14 @@ struct
456468 | BACKEND_LUAJIT => " luajit"
457469 | BACKEND_JS {style = Backend.DIRECT_STYLE, ...} => " js"
458470 | BACKEND_JS {style = Backend.CPS, ...} => " js-cps"
471+ | BACKEND_WASM _ => " wasm"
459472 )
460473 , ( " TARGET_OS"
461474 , case #backend opts of
462475 BACKEND_LUA _ => " lua"
463476 | BACKEND_LUAJIT => " lua"
464477 | BACKEND_JS {os, ...} => os
478+ | BACKEND_WASM _ => " wasm"
465479 )
466480 , ( " DELIMITED_CONTINUATIONS"
467481 , case #backend opts of
@@ -718,6 +732,7 @@ struct
718732 | BACKEND_LUAJIT => true
719733 | BACKEND_JS {style = Backend.DIRECT_STYLE, ...} => false
720734 | BACKEND_JS {style = Backend.CPS, ...} => true
735+ | BACKEND_WASM _ => true
721736 val fexp =
722737 case targetInfo of
723738 {defaultInt = Primitives.INT, defaultWord = Primitives.WORD, ...} =>
@@ -878,34 +893,40 @@ struct
878893 CpsErasePoly.transform (context, cexp)
879894 end
880895 val () = checkCpsAfterErasure (" after erasePoly" , cexp)
881- (* Boxing pass: only for WasmGC backend (not yet implemented).
882- When enabled, disable CPS type checks after boxing since the checker
883- doesn't fully support BoxedType boundaries.
884896 val cexp =
885- let
886- val context =
887- { nextTyVar = nextTyVar
888- , nextVId = nextId
889- , simplificationOccurred = ref false
890- }
891- in
892- CpsBoxing.transform (context, cexp)
893- end
894- *)
897+ case #backend opts of
898+ BACKEND_WASM _ =>
899+ let
900+ val context =
901+ { nextTyVar = nextTyVar
902+ , nextVId = nextId
903+ , simplificationOccurred = ref false
904+ }
905+ in
906+ CpsBoxing.transform (context, cexp)
907+ end
908+ | _ => cexp
909+ (* After boxing, disable CPS type checks since the checker
910+ doesn't fully support BoxedType boundaries. *)
911+ val checkCpsAfterBoxing =
912+ case #backend opts of
913+ (* BACKEND_WASM _ => (fn _ => ())
914+ | *) _ => checkCpsAfterErasure
915+ val () = checkCpsAfterBoxing (" after boxing" , cexp)
895916 val cexp =
896917 optimizeCps
897918 { nextTyVar = nextTyVar
898919 , nextVId = nextId
899920 , printTimings = #printTimings opts
900- } checkCpsAfterErasure cexp (3 * (#optimizationLevel opts + 3 ))
901- val () = checkCpsAfterErasure (" optimization #3" , cexp)
921+ } checkCpsAfterBoxing cexp (3 * (#optimizationLevel opts + 3 ))
922+ val () = checkCpsAfterBoxing (" optimization #3" , cexp)
902923 val ctx' =
903924 { nextTyVar = nextTyVar
904925 , nextVId = nextId
905926 , simplificationOccurred = ref false
906927 }
907928 val cexp = CpsDeadCodeElimination.goStat (ctx', true , cexp)
908- val () = checkCpsAfterErasure (" after final DCE" , cexp)
929+ val () = checkCpsAfterBoxing (" after final DCE" , cexp)
909930 val optTime = Time.toMicroseconds (#usr (Timer.checkCPUTimer timer))
910931 val () =
911932 if #printTimings opts then
@@ -1024,6 +1045,8 @@ struct
10241045 | OPT_TARGET_NODEJS_CPS (* --nodejs-cps *)
10251046 | OPT_TARGET_WEBJS (* --webjs *)
10261047 | OPT_TARGET_WEBJS_CPS (* --webjs-cps *)
1048+ | OPT_TARGET_WASM (* --wasm *)
1049+ | OPT_TARGET_WASM_WAT (* --wasm-wat *)
10271050 | OPT_HELP (* -h,--help *)
10281051 | OPT_VERSION (* -v,--version *)
10291052 | OPT_STOP (* -- *)
@@ -1048,6 +1071,8 @@ struct
10481071 , (LONG " --nodejs-cps" , SIMPLE OPT_TARGET_NODEJS_CPS)
10491072 , (LONG " --webjs" , SIMPLE OPT_TARGET_WEBJS)
10501073 , (LONG " --webjs-cps" , SIMPLE OPT_TARGET_WEBJS_CPS)
1074+ , (LONG " --wasm" , SIMPLE OPT_TARGET_WASM)
1075+ , (LONG " --wasm-wat" , SIMPLE OPT_TARGET_WASM_WAT)
10511076 , (SHORT " -h" , SIMPLE OPT_HELP)
10521077 , (LONG " --help" , SIMPLE OPT_HELP)
10531078 , (SHORT " -v" , SIMPLE OPT_VERSION)
@@ -1117,6 +1142,13 @@ struct
11171142 (S.set.backend
11181143 (BACKEND_JS {style = Backend.CPS, os = " web" , default_ext = " .js" })
11191144 opts) args
1145+ | SOME (OPT_TARGET_WASM, args) =>
1146+ parseArgs
1147+ (S.set.backend (BACKEND_WASM {output = Backend.WASM_BINARY}) opts)
1148+ args
1149+ | SOME (OPT_TARGET_WASM_WAT, args) =>
1150+ parseArgs
1151+ (S.set.backend (BACKEND_WASM {output = Backend.WASM_TEXT}) opts) args
11201152 | SOME (OPT_HELP, _) => (showHelp (); OS.Process.exit OS.Process.success)
11211153 | SOME (OPT_VERSION, _) =>
11221154 (showVersion (); OS.Process.exit OS.Process.success)
0 commit comments