@@ -92,9 +92,9 @@ addLibs xs = vcat (map addOneLib xs)
92
92
93
93
data TheState = TheState { freshCounter :: Integer
94
94
, frameSize :: Int
95
- , boundSlot :: Int
96
- , consts :: Raw. Consts
97
- , stHFN :: IR. HFN }
95
+ , sparseSlot :: Int
96
+ , consts :: Raw. Consts
97
+ , stHFN :: IR. HFN }
98
98
99
99
type RetKontText = PP. Doc
100
100
@@ -103,7 +103,7 @@ type W = RWS Bool ([LibAccess], [Basics.AtomName], [RetKontText]) TheState
103
103
104
104
initState = TheState { freshCounter = 0
105
105
, frameSize = error " frameSize should not be accessed yet"
106
- , boundSlot = error " boundSlot should not be accessed yet"
106
+ , sparseSlot = error " sparseSlot should not be accessed yet"
107
107
, consts = error " consts should not be accessed yet"
108
108
, stHFN = error " stHFN should not be accessed yet"
109
109
}
@@ -207,22 +207,21 @@ constsToJS consts =
207
207
instance ToJS FunDef where
208
208
toJS fdef@ (FunDef hfn stacksize consts bb irfdef) = do
209
209
{- -
210
- | | | ... | <bound_slot > |
210
+ | | | ... | <sparse slot > |
211
211
^ ^
212
212
| |
213
213
SP stacksize
214
214
215
215
--}
216
216
let _frameSize = stacksize + 1
217
217
218
- modify (\ s -> s { frameSize = _frameSize, boundSlot = stacksize, stHFN = hfn, consts = consts } ) -- + 1 for the _data_bound_by_pc flag; 2021-03-17; AA
219
- let lits = constsToJS consts
218
+ modify (\ s -> s { frameSize = _frameSize, sparseSlot = stacksize, stHFN = hfn, consts = consts } ) -- + 1 for the sparse flag; 2021-03-17; AA
219
+ let lits = constsToJS consts
220
220
jj <- toJS bb
221
221
debug <- ask
222
- let (irdeps, libdeps, atomdeps ) = IR. ppDeps irfdef
223
- b_slot_index = text " _SP + " PP. <> (PP. int stacksize)
224
- data_bound_by_pc_slot = text " _STACK[ " PP. <> b_slot_index PP. <> " ]"
225
-
222
+ let (irdeps, libdeps, atomdeps ) = IR. ppDeps irfdef
223
+ sparseSlotIdxPP <- ppSparseSlotIdx
224
+
226
225
return $
227
226
vcat [text " this." PP. <> ppId hfn <+> text " =" <+> ppArgs [" $env" ] <+> text " => {"
228
227
, if debug then nest 2 $ text " rt.debug" <+> (PP. parens . PP. quotes. ppId) hfn
@@ -232,8 +231,11 @@ instance ToJS FunDef where
232
231
" let _STACK = _T.callStack" ,
233
232
" let _SP = _T._sp" ,
234
233
" let _SP_OLD" ,
235
- data_bound_by_pc_slot <+> " = _T.checkDataBoundsEntry($env.__dataLevel)" ,
236
- " _T.boundSlot = " <+> b_slot_index,
234
+ -- Update sparse bit at function entry:
235
+ -- Check whether environment's data level, and the label and data level of R0 are bound by PC.
236
+ -- Requires sparseSlot to be updated first.
237
+ " _T.sparseSlot = " <+> sparseSlotIdxPP,
238
+ " _T.updateSparseBitOnEntry($env.__dataLevel)" ,
237
239
lits,
238
240
jj]
239
241
, text " }"
@@ -285,7 +287,7 @@ binOpToJS = \case
285
287
Neq -> " rt.neq"
286
288
Concat -> " +"
287
289
HasField -> " rt.hasField"
288
- LatticeJoin -> " rt.join "
290
+ LatticeJoin -> " rt.raw_join "
289
291
-- No RT operations (should be moved to a different datatype)
290
292
RaisedTo -> error " Not a runtime operation"
291
293
-- Not yet implemented in IR2Raw
@@ -350,25 +352,22 @@ ir2js (MkFunClosures envBindings funBindings) = do
350
352
where ppEnvIds env ls =
351
353
vcat (
352
354
(map (\ (a,b) -> semi $ (ppId env) PP. <> text " ." PP. <> (ppId a) <+> text " =" <+> ppId b ) ls)
353
- ++
354
- [ppId env PP. <> text " .__dataLevel = " <+> ( jsFunCall " rt.join " (map (\ (_, b) -> ppId b <> text " .dataLevel" ) ls ) ) ]
355
+ ++
356
+ [ppId env PP. <> text " .__dataLevel = " <+> jsFunCall (text $ binOpToJS Basics. LatticeJoin ) (map (\ (_, b) -> ppId b <> text " .dataLevel" ) ls ) ]
355
357
)
356
358
hsepc ls = semi $ PP. hsep (PP. punctuate (text " ," ) ls)
357
359
358
360
359
- ir2js (SetState c x) =
360
- let rhs = case c of MonBlock -> ppFunCall " rt.wrap_block_rhs" [ppId x]
361
- _ -> ppId x
362
-
363
- in return $ semi $ monStateToJs c <+> " =" <+> rhs
361
+ ir2js (SetState c x) = return $ semi $ monStateToJs c <+> " =" <+> ppId x
364
362
365
363
ir2js (RTAssertion a) = return $ ppRTAssertionCode jsFunCall a
366
364
367
- ir2js (LabelGroup ii) = do
368
- ii' <- mapM ppLevelOp ii
369
- b_slot <- data_bounded_by_pc_slot
365
+ ir2js (LabelGroup ii) = do
366
+ ii' <- mapM ppLevelOp ii
367
+ sparseSlot <- ppSparseSlot
370
368
return $ vcat $
371
- [ " if (!" <+> b_slot <+> " ) {"
369
+ [ -- "if (! _T.getSparseBit()) {" -- Alternative, but involves extra call to RT
370
+ " if (!" <+> sparseSlot <+> " ) {"
372
371
, nest 2 (vcat ii')
373
372
, text " }"
374
373
]
@@ -391,30 +390,33 @@ ir2js InvalidateSparseBit = return $
391
390
{- - TERMINATORS --}
392
391
393
392
394
- tr2js (Call bb bb2) = do
395
- _frameSize <- frameSize <$> get
396
- _boundSlot <- boundSlot <$> get
397
- _consts <- consts <$> get
398
- modify (\ s -> s {frameSize = 0 , boundSlot = _boundSlot - _frameSize - 5 })
393
+ tr2js (Call bb bb2) = do
394
+ _frameSize <- gets frameSize
395
+ _sparseSlot <- gets sparseSlot
396
+ _consts <- gets consts
397
+ modify (\ s -> s {frameSize = 0 , sparseSlot = _sparseSlot - _frameSize - 5 })
399
398
-- AA; 2021-04-24; Because
400
399
js <- toJS bb
401
- modify (\ s -> s { frameSize = _frameSize, boundSlot = _boundSlot })
400
+ modify (\ s -> s { frameSize = _frameSize, sparseSlot = _sparseSlot })
402
401
-- TODO: AA; 2021-04-24; we should really be using a reader monad here for frame size
403
402
-- #codedebt
404
403
js2 <- toJS bb2
405
- kname <- freshKontName
406
- b_slot <- data_bounded_by_pc_slot
407
- b_slot_index <- b_slot_absolute_index
408
- let jsKont =
409
- vcat [" this." PP. <> ppId kname <+> text " = () => {" ,
410
- nest 2 $
411
- vcat [
404
+ kname <- freshKontName
405
+ sparseSlotIdxPP <- ppSparseSlotIdx
406
+ let jsKont =
407
+ vcat [" this." PP. <> ppId kname <+> text " = () => {" ,
408
+ nest 2 $
409
+ vcat [
412
410
" let _T = rt.runtime.$t" ,
413
411
" let _STACK = _T.callStack" ,
414
412
" let _SP = _T._sp" ,
413
+ -- TODO Do we need this? It seems to be only used zero or one time in the generated places.
414
+ -- So we could instead just use the let where it is actually set.
415
415
" let _SP_OLD" ,
416
- b_slot <+> " = _T.checkDataBounds(" <+> b_slot <+> " )" ,
417
- " _T.boundSlot =" <+> b_slot_index ,
416
+ -- Check data bound at return point (could have received labelled information or raised).
417
+ -- Requires sparseSlot to be updated first.
418
+ " _T.sparseSlot =" <+> sparseSlotIdxPP,
419
+ " _T.updateSparseBitOnReturn()" ,
418
420
constsToJS _consts , -- 2021-05-18; TODO: optimize by including only the _used_ constants
419
421
js2
420
422
],
@@ -479,15 +481,16 @@ monStateToJs c =
479
481
R0_TLev -> text " r0_tlev"
480
482
481
483
482
- data_bounded_by_pc_slot :: W PP. Doc
483
- data_bounded_by_pc_slot = do
484
- _b <- boundSlot <$> get
485
- return $ text " _STACK[ _SP + " PP. <> (text (show (_b))) PP. <> text " ]"
484
+ ppSparseSlotIdx :: W PP. Doc
485
+ ppSparseSlotIdx = do
486
+ s <- gets sparseSlot
487
+ return $ text " _SP + " PP. <+> PP. int s
488
+
489
+ ppSparseSlot :: W PP. Doc
490
+ ppSparseSlot = do
491
+ idx <- ppSparseSlotIdx
492
+ return $ text " _STACK[ " PP. <> idx PP. <> text " ]"
486
493
487
- b_slot_absolute_index :: W PP. Doc
488
- b_slot_absolute_index = do
489
- _b <- boundSlot<$> get
490
- return $ text " _SP +" PP. <+> (PP. int _b)
491
494
-----------------------------------------------------------
492
495
493
496
@@ -563,16 +566,16 @@ jsFunCall a b = semi $ ppFunCall a b
563
566
564
567
565
568
freshEnvVar :: W VarName
566
- freshEnvVar = do
567
- k <- freshCounter <$> get
568
- modify (\ s -> s { freshCounter = k + 1 } )
569
+ freshEnvVar = do
570
+ k <- gets freshCounter
571
+ modify (\ s -> s { freshCounter = k + 1 } )
569
572
return $ VN $ " $$$env" ++ (show k)
570
573
571
-
574
+
572
575
freshKontName :: W VarName
573
- freshKontName = do
574
- j <- freshCounter <$> get
575
- HFN s <- stHFN <$> get
576
+ freshKontName = do
577
+ j <- gets freshCounter
578
+ HFN s <- gets stHFN
576
579
modify (\ s -> s { freshCounter = j + 1 })
577
580
return $ VN $ " $$$" ++ s ++ " $$$kont" ++ (show j)
578
581
0 commit comments