... |
... |
@@ -1407,25 +1407,49 @@ ensuring that we stop exactly when we return to the continuation. |
1407
|
1407
|
|
1408
|
1408
|
However, case continuation BCOs (produced by PUSH_ALTS and which merely compute
|
1409
|
1409
|
which case alternative BCO to enter next) contain no user-facing breakpoint
|
1410
|
|
-ticks (BRK_FUN):
|
|
1410
|
+ticks (BRK_FUN). While we could in principle add breakpoints in case continuation
|
|
1411
|
+BCOs, there are a few reasons why this is not an attractive option:
|
1411
|
1412
|
|
1412
|
1413
|
1) It's not useful to a user stepping through the program to always have a
|
1413
|
1414
|
breakpoint after the scrutinee is evaluated but before the case alternative
|
1414
|
1415
|
is selected. The source span associated with such a breakpoint would also be
|
1415
|
1416
|
slightly awkward to choose.
|
1416
|
1417
|
|
1417
|
|
- 2) It's not easy to add a source-tick before the case alternatives because in
|
|
1418
|
+ 2) It's not easy to add a breakpoint tick before the case alternatives because in
|
1418
|
1419
|
essentially all internal representations they are given as a list of Alts
|
1419
|
1420
|
rather than an expression.
|
1420
|
1421
|
|
1421
|
|
-To provide the debugger a way to enable at runtime the case continuation
|
1422
|
|
-breakpoints despite the lack of BRK_FUNs, we introduce at the start
|
1423
|
|
-of every case continuation BCO a BRK_ALTS instruction.
|
1424
|
|
-
|
1425
|
|
-The BRK_ALTS instruction, if enabled (by its single arg), ensures we stop at
|
1426
|
|
-the breakpoint heading the case alternative we take. Under the hood, this means
|
1427
|
|
-that when BRK_ALTS is enabled we set TSO_STOP_NEXT_BREAKPOINT just before
|
1428
|
|
-selecting the alternative.
|
|
1422
|
+To provide the debugger a way to break in a case continuation
|
|
1423
|
+despite the BCOs' lack of BRK_FUNs, we introduce an alternative
|
|
1424
|
+type of breakpoint, represented by the BRK_ALTS instruction,
|
|
1425
|
+at the start of every case continuation BCO. For instance,
|
|
1426
|
+
|
|
1427
|
+ case x of
|
|
1428
|
+ 0# -> ...
|
|
1429
|
+ _ -> ...
|
|
1430
|
+
|
|
1431
|
+will produce a continuation of the form (N.B. the below bytecode
|
|
1432
|
+is simplified):
|
|
1433
|
+
|
|
1434
|
+ PUSH_ALTS P
|
|
1435
|
+ BRK_ALTS 0
|
|
1436
|
+ TESTEQ_I 0 lblA
|
|
1437
|
+ PUSH_BCO
|
|
1438
|
+ BRK_FUN 0
|
|
1439
|
+ -- body of 0# alternative
|
|
1440
|
+ ENTER
|
|
1441
|
+
|
|
1442
|
+ lblA:
|
|
1443
|
+ PUSH_BCO
|
|
1444
|
+ BRK_FUN 1
|
|
1445
|
+ -- body of wildcard alternative
|
|
1446
|
+ ENTER
|
|
1447
|
+
|
|
1448
|
+When enabled (by its single boolean operand), the BRK_ALTS instruction causes
|
|
1449
|
+the program to break at the next encountered breakpoint (implemented
|
|
1450
|
+by setting the TSO's TSO_STOP_NEXT_BREAKPOINT flag). Since the case
|
|
1451
|
+continuation BCO will ultimately jump to one of the alternatives (each of
|
|
1452
|
+which having its own BRK_FUN) we are guaranteed to stop in the taken alternative.
|
1429
|
1453
|
|
1430
|
1454
|
It's important that BRK_ALTS (just like BRK_FUN) is the first instruction of
|
1431
|
1455
|
the BCO, since that's where the debugger will look to enable it at runtime.
|