Skip to content

Commit 8e651c2

Browse files
committed
Add and use compiler configuration implicit Config
1 parent 0c7f3be commit 8e651c2

35 files changed

+153
-92
lines changed

hkmc2/jvm/src/test/scala/hkmc2/CompileTestRunner.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ class CompileTestRunner
4444

4545
val preludePath = dir/"mlscript"/"decls"/"Prelude.mls"
4646

47+
given Config = Config.default
48+
4749
val compiler = MLsCompiler(
4850
preludePath,
4951
mkOutput =>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package hkmc2
2+
3+
import mlscript.utils.*, shorthands.*
4+
import utils.*
5+
6+
import Config.*
7+
8+
9+
def config(using Config): Config = summon
10+
11+
case class Config(
12+
sanityChecks: Opt[SanityChecks],
13+
effectHandlers: Opt[EffectHandlers],
14+
):
15+
16+
def stackSafety: Opt[StackSafety] = effectHandlers.flatMap(_.stackSafety)
17+
18+
end Config
19+
20+
21+
object Config:
22+
23+
val default: Config = Config(
24+
sanityChecks = N, // TODO make the default S
25+
// sanityChecks = S(SanityChecks(light = true)),
26+
effectHandlers = N,
27+
)
28+
29+
case class SanityChecks(light: Bool)
30+
31+
case class EffectHandlers(stackSafety: Opt[StackSafety])
32+
33+
case class StackSafety(stackLimit: Int)
34+
object StackSafety:
35+
val default: StackSafety = StackSafety(
36+
stackLimit = 500,
37+
)
38+
39+
end Config
40+
41+

hkmc2/shared/src/main/scala/hkmc2/MLsCompiler.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class ParserSetup(file: os.Path, dbgParsing: Bool)(using Elaborator.State, Raise
3737

3838

3939
// * The weird type of `mkOutput` is to allow wrapping the reporting of diagnostics in synchronized blocks
40-
class MLsCompiler(preludeFile: os.Path, mkOutput: ((Str => Unit) => Unit) => Unit):
40+
class MLsCompiler(preludeFile: os.Path, mkOutput: ((Str => Unit) => Unit) => Unit)(using Config):
4141

4242
val runtimeFile: os.Path = preludeFile/os.up/os.up/os.up/"mlscript-compile"/"Runtime.mjs"
4343

@@ -82,7 +82,8 @@ class MLsCompiler(preludeFile: os.Path, mkOutput: ((Str => Unit) => Unit) => Uni
8282
val (blk0, _) = elab.importFrom(parsed)
8383
val blk = blk0.copy(stats = semantics.Import(State.runtimeSymbol, runtimeFile.toString) :: blk0.stats)
8484
val low = ltl.givenIn:
85-
codegen.Lowering(lowerHandlers = false, stackLimit = None) // TODO: properly hook up stack limit
85+
new codegen.Lowering()
86+
with codegen.LoweringSelSanityChecks
8687
val jsb = ltl.givenIn:
8788
codegen.js.JSBuilder()
8889
val le = low.program(blk)

hkmc2/shared/src/main/scala/hkmc2/codegen/Lowering.scala

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ end Subst
5252
import Subst.subst
5353

5454

55-
class Lowering(lowerHandlers: Bool, stackLimit: Option[Int])(using TL, Raise, State, Ctx):
55+
class Lowering()(using Config, TL, Raise, State, Ctx):
56+
57+
val lowerHandlers: Bool = config.effectHandlers.isDefined
5658

5759
private lazy val unreachableFn =
5860
Select(Select(Value.Ref(State.globalThisSymbol), Tree.Ident("Predef"))(N), Tree.Ident("unreachable"))(N)
@@ -583,9 +585,9 @@ class Lowering(lowerHandlers: Bool, stackLimit: Option[Int])(using TL, Raise, St
583585

584586
def topLevel(t: st): Block =
585587
val res = term(t)(ImplctRet)(using Subst.empty)
586-
val stackSafe = stackLimit match
587-
case None => res
588-
case Some(lim) => StackSafeTransform(lim).transformTopLevel(res)
588+
val stackSafe = config.stackSafety match
589+
case N => res
590+
case S(sts) => StackSafeTransform(sts.stackLimit).transformTopLevel(res)
589591

590592
if lowerHandlers then HandlerLowering().translateTopLevel(stackSafe)
591593
else stackSafe
@@ -623,9 +625,11 @@ class Lowering(lowerHandlers: Bool, stackLimit: Option[Int])(using TL, Raise, St
623625
Nil))
624626

625627

626-
trait LoweringSelSanityChecks
627-
(instrument: Bool)(using TL, Raise, State)
628+
trait LoweringSelSanityChecks(using Config, TL, Raise, State)
628629
extends Lowering:
630+
631+
private val instrument: Bool = config.sanityChecks.isDefined
632+
629633
override def setupSelection(prefix: st, nme: Tree.Ident, sym: Opt[FieldSymbol])(k: Result => Block)(using Subst): Block =
630634
if !instrument then return super.setupSelection(prefix, nme, sym)(k)
631635
subTerm(prefix): p =>
@@ -648,10 +652,9 @@ trait LoweringSelSanityChecks
648652

649653

650654

651-
trait LoweringTraceLog
652-
(instrument: Bool)(using TL, Raise, State)
655+
trait LoweringTraceLog(instrument: Bool)(using TL, Raise, State)
653656
extends Lowering:
654-
657+
655658
private def selFromGlobalThis(path: Str*): Path =
656659
path.foldLeft[Path](Value.Ref(State.globalThisSymbol)):
657660
(qual, name) => Select(qual, Tree.Ident(name))(N)

hkmc2/shared/src/main/scala/hkmc2/codegen/js/JSBuilder.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -537,10 +537,11 @@ object JSBuilder:
537537
end JSBuilder
538538

539539

540-
trait JSBuilderArgNumSanityChecks
541-
(instrument: Bool)(using Elaborator.State)
540+
trait JSBuilderArgNumSanityChecks(using Config, Elaborator.State)
542541
extends JSBuilder:
543542

543+
val instrument: Bool = config.sanityChecks.isDefined
544+
544545
override def checkMLsCalls: Bool = instrument
545546
override def checkSelections: Bool = instrument
546547

hkmc2/shared/src/test/mlscript/handlers/BadHandlers.mls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
:js
2-
:handler
2+
:effectHandlers
33

44

55
:re

hkmc2/shared/src/test/mlscript/handlers/EffectInHandler.mls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
:js
2-
:handler
2+
:effectHandlers
33

44
class PrintEffect with
55
fun p(s: String): ()

hkmc2/shared/src/test/mlscript/handlers/Effects.mls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
:js
2-
:handler
2+
:effectHandlers
33

44

55
abstract class Effect with

hkmc2/shared/src/test/mlscript/handlers/EffectsHygiene.mls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
:js
2-
:handler
2+
:effectHandlers
33

44

55
// * Notice that the two module definitions are lifted to the top of the block.

hkmc2/shared/src/test/mlscript/handlers/EffectsInClasses.mls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
:js
2-
:handler
2+
:effectHandlers
33

44

55
abstract class Effect with

hkmc2/shared/src/test/mlscript/handlers/EffectsInMethods.mls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
:js
2-
:handler
2+
:effectHandlers
33

44

55
abstract class Effect with

hkmc2/shared/src/test/mlscript/handlers/GeneratorStack.mls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
:js
2-
:handler
2+
:effectHandlers
33

44
import "../../mlscript-compile/Stack.mls"
55
open Stack

hkmc2/shared/src/test/mlscript/handlers/Generators.mls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
:js
2-
:handler
2+
:effectHandlers
33

44
abstract class Generator with
55
fun produce(result): ()

hkmc2/shared/src/test/mlscript/handlers/HandlerBlockBindings.mls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
:js
2-
:handler
2+
:effectHandlers
33

44

55
abstract class Effect with

hkmc2/shared/src/test/mlscript/handlers/HandlersInClasses.mls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
:js
2-
:handler
2+
:effectHandlers
33

44

55
abstract class Effect with

hkmc2/shared/src/test/mlscript/handlers/HandlersInMethods.mls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
:js
2-
:handler
2+
:effectHandlers
33

44

55
abstract class Effect with

hkmc2/shared/src/test/mlscript/handlers/HandlersScratch.mls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
:js
2-
:handler
2+
:effectHandlers
33

44
abstract class Effect
55

hkmc2/shared/src/test/mlscript/handlers/LeakingEffects.mls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
:js
2-
:handler
2+
:effectHandlers
33

44

55
abstract class Effect[A] with

hkmc2/shared/src/test/mlscript/handlers/ManualStackSafety.mls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
:js
2-
:handler
2+
:effectHandlers
33

44
// * This file demonstrates the handler-based mechanism of our stack safety implementation
55
// * by manually applying the transformation of a recursive factorial function

hkmc2/shared/src/test/mlscript/handlers/MultiResumption.mls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
:js
2-
:handler
2+
:effectHandlers
33

44
class Logger with
55
fun info(s: Str): ()

hkmc2/shared/src/test/mlscript/handlers/NestedFun.mls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
:js
2-
:handler
2+
:effectHandlers
33

44
fun sum() = 0
55
fun foo(x) =

hkmc2/shared/src/test/mlscript/handlers/NestedHandlers.mls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
:js
2-
:handler
2+
:effectHandlers
33

44
let id = 0
55
//│ id = 0

hkmc2/shared/src/test/mlscript/handlers/RecursiveHandlers.mls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
:js
2-
:handler
2+
:effectHandlers
33

44

55
abstract class Effect[A] with

hkmc2/shared/src/test/mlscript/handlers/ReturnInHandler.mls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
:js
2-
:handler
2+
:effectHandlers
33

44
abstract class Effect with
55
fun f(): ()

hkmc2/shared/src/test/mlscript/handlers/StackSafety.mls

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ sum(100)
1212
// preserve tail calls
1313
// MUST see "return hi1(tmp)" in the output
1414
:stackSafe 5
15-
:handler
15+
:effectHandlers
1616
:expect 0
1717
:sjs
1818
fun hi(n) =
@@ -172,7 +172,7 @@ hi(0)
172172

173173
:sjs
174174
:stackSafe 1000
175-
:handler
175+
:effectHandlers
176176
:expect 50005000
177177
fun sum(n) =
178178
if n == 0 then 0
@@ -358,7 +358,7 @@ fun sum(n) =
358358
sum(10000)
359359
//│ ═══[RUNTIME ERROR] RangeError: Maximum call stack size exceeded
360360

361-
:handler
361+
:effectHandlers
362362
:stackSafe 100
363363
mut val ctr = 0
364364
fun dummy(x) = x
@@ -372,7 +372,7 @@ foo(foo)
372372
//│ ctr = 10001
373373

374374
:stackSafe 1000
375-
:handler
375+
:effectHandlers
376376
:expect 50005000
377377
val foo =
378378
val f = n =>
@@ -396,7 +396,7 @@ abstract class Eff with
396396
fun perform(a): ()
397397

398398
// functions and lambdas inside handlers
399-
:handler
399+
:effectHandlers
400400
:stackSafe 100
401401
:expect 50005000
402402
fun foo(h) = h.perform
@@ -410,7 +410,7 @@ foo(h)
410410
//│ = 50005000
411411

412412
// function call and defn inside handler
413-
:handler
413+
:effectHandlers
414414
:stackSafe 100
415415
:expect 50005000
416416
handle h = Eff with
@@ -425,7 +425,7 @@ in
425425
//│ = 50005000
426426

427427
:re
428-
:handler
428+
:effectHandlers
429429
fun foo(h) = h.perform(2)
430430
handle h = Eff with
431431
fun perform(a)(resume) =
@@ -436,7 +436,7 @@ handle h = Eff with
436436
foo(h)
437437
//│ ═══[RUNTIME ERROR] RangeError: Maximum call stack size exceeded
438438

439-
:handler
439+
:effectHandlers
440440
:stackSafe
441441
:sjs
442442
fun max(a, b) = if a < b then b else a
@@ -453,31 +453,23 @@ fun max(a, b) = if a < b then b else a
453453
//│ };
454454

455455

456-
// * Note that currently the `:sjs` command will not run the code if there is a compilation error
457456
:sjs
458457
:stackSafe 42
459-
:ge
460458
fun hi(n) = n
461459
hi(0)
462-
//│ ═══[COMPILATION ERROR] This code requires effect handler instrumentation but was compiled without it.
460+
//│ /!!!\ Option ':stackSafe' requires ':effectHandlers' to be set
463461
//│ JS (unsanitized):
464-
//│ let hi1, stackHandler;
465-
//│ hi1 = function hi(n) {
466-
//│ return n
467-
//│ };
468-
//│ throw globalThis.Error("This code requires effect handler instrumentation but was compiled without it.");
469-
//│ ═══[RUNTIME ERROR] Error: This code requires effect handler instrumentation but was compiled without it.
462+
//│ let hi1; hi1 = function hi(n) { return n }; hi1(0)
463+
//│ = 0
470464

471465
:stackSafe 42
472-
:ge
473-
:re
474466
hi(0)
475-
//│ ═══[COMPILATION ERROR] This code requires effect handler instrumentation but was compiled without it.
476-
//│ ═══[RUNTIME ERROR] Error: This code requires effect handler instrumentation but was compiled without it.
467+
//│ /!!!\ Option ':stackSafe' requires ':effectHandlers' to be set
468+
//│ = 0
477469

478470

479471
:stackSafe 1000
480-
:handler
472+
:effectHandlers
481473
:expect 100010000
482474
fun sum(n) =
483475
if n == 0 then 0
@@ -486,3 +478,4 @@ fun sum(n) =
486478
fun bad() = sum(10000) + sum(10000)
487479
bad()
488480
//│ = 100010000
481+

hkmc2/shared/src/test/mlscript/handlers/TailCallOptimization.mls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
:js
2-
:handler
2+
:effectHandlers
33

44
abstract class StackDelay with
55
fun perform(): ()

hkmc2/shared/src/test/mlscript/handlers/UserThreadsSafe.mls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
:js
2-
:handler
2+
:effectHandlers
33

44

55
class ThreadEffect with

0 commit comments

Comments
 (0)