| 210 | | recloseRef :: VRef -> STM VRef |
| 211 | | recloseRef ref@(MkRef (ICode cv)) |
| 212 | | | Just vcode <- fromTypeable cv |
| 213 | | , Nothing <- subStarted vcode |
| 214 | | , subType vcode /= SubPrim = do |
| | 209 | recloseExp :: Exp -> STM Exp |
| | 210 | recloseExp (Val val) = fmap Val (recloseVal val) |
| | 211 | recloseExp exp = return exp |
| | 212 | |
| | 213 | recloseVal :: Val -> STM Val |
| | 214 | recloseVal (VRef ref) = do |
| | 215 | fmap VRef (recloseRef ref) |
| | 216 | recloseVal (VCode code) = do |
| | 217 | fmap VCode (recloseCode code) |
| | 218 | recloseVal (VList list) = do |
| | 219 | fmap VList (mapM recloseVal list) |
| | 220 | recloseVal val = return val |
| | 221 | |
| | 222 | |
| | 223 | recloseTraitBlocks :: TraitBlocks -> STM TraitBlocks |
| | 224 | recloseTraitBlocks (MkTraitBlocks a b c d e f g h i j k) = do |
| | 225 | [a', b', c', d', e', f', g', h', i', j', k'] <- mapM (mapM recloseCode) [a, b, c, d, e, f, g, h, i, j, k] |
| | 226 | return $ MkTraitBlocks a' b' c' d' e' f' g' h' i' j' k' |
| | 227 | |
| | 228 | recloseCode :: VCode -> STM VCode |
| | 229 | recloseCode vcode |
| | 230 | | Nothing <- subStarted vcode = do |
| | 231 | -- , subType vcode /= SubPrim = do |
| 249 | | enterSub :: VCode -> Eval Val -> Eval Val |
| 250 | | enterSub sub action |
| 251 | | | typ >= SubPrim = runAction -- primitives just happen |
| 252 | | | otherwise = do |
| 253 | | env <- ask |
| 254 | | pad <- case subStarted sub of |
| 255 | | Just tvar -> do |
| 256 | | started <- stm $ readTVar tvar |
| 257 | | if started then refreshPad (subInnerPad sub) else do |
| 258 | | -- XXX - Fix up all mpads, recursively, here! |
| 259 | | stm $ writeTVar tvar True |
| 260 | | return (subInnerPad sub) |
| 261 | | _ -> return (subInnerPad sub) |
| 262 | | rv <- case typ of |
| 263 | | _ | typ >= SubBlock -> tryT $ do |
| 264 | | doFix <- fixEnv return env pad |
| 265 | | local doFix runAction |
| 266 | | |
| 267 | | -- For coroutines, we secretly store a continuation into subCont |
| 268 | | -- whenever "yield" occurs in it. However, the inner CC must be |
| 269 | | -- delimited on the subroutine boundary, otherwise the resuming |
| 270 | | -- continuation will continue into the rest of the program, |
| 271 | | -- which is now how coroutines are supposed to work. |
| 272 | | -- On the other hand, the normal &?CALLER_CONTINUATION must still |
| 273 | | -- work as an undelimiated continuation, which is why callCC here |
| 274 | | -- occurs before resetT. |
| 275 | | SubCoroutine -> tryT . callCC $ \cc -> resetT $ do |
| 276 | | doFix <- fixEnv cc env pad |
| 277 | | local doFix runAction |
| 278 | | |
| 279 | | _ -> tryT . callCC $ \cc -> do |
| 280 | | doFix <- fixEnv cc env pad |
| 281 | | local doFix runAction |
| | 276 | data ApplyKind = AKInline | AKDisplaced deriving (Show) |
| | 277 | |
| | 278 | enterSub :: ApplyKind -> VCode -> Eval Val -> Eval Val |
| | 279 | enterSub appKind sub action = do |
| | 280 | env <- ask |
| | 281 | pad <- case subStarted sub of |
| | 282 | Just tvar -> do |
| | 283 | started <- stm $ readTVar tvar |
| | 284 | if started |
| | 285 | then refreshPad (subInnerPad sub) |
| | 286 | -- `finallyM` warn "======= REFRESHED ==========" (subInnerPad sub, sub) |
| | 287 | else (stm $ do |
| | 288 | writeTVar tvar True |
| | 289 | reclosePad (subInnerPad sub)) |
| | 290 | -- `finallyM` warn "======= RECLOSED ==========" (tvar, subInnerPad sub) |
| | 291 | _ -> do |
| | 292 | -- warn "==== NOTHING ====" (subInnerPad sub) |
| | 293 | return (subInnerPad sub) |
| | 294 | rv <- case typ of |
| | 295 | -- For coroutines, we secretly store a continuation into subCont |
| | 296 | -- whenever "yield" occurs in it. However, the inner CC must be |
| | 297 | -- delimited on the subroutine boundary, otherwise the resuming |
| | 298 | -- continuation will continue into the rest of the program, |
| | 299 | -- which is now how coroutines are supposed to work. |
| | 300 | -- On the other hand, the normal &?CALLER_CONTINUATION must still |
| | 301 | -- work as an undelimiated continuation, which is why callCC here |
| | 302 | -- occurs before resetT. |
| | 303 | SubCoroutine -> tryT . callCC $ \cc -> resetT $ do |
| | 304 | doFix <- fixEnv cc env pad |
| | 305 | local doFix runAction |
| | 306 | |
| | 307 | _ | typ >= SubBlock -> tryT $ do |
| | 308 | doFix <- fixEnv return env pad |
| | 309 | local doFix runAction |
| | 310 | |
| | 311 | _ -> tryT . callCC $ \cc -> do |
| | 312 | doFix <- fixEnv cc env pad |
| | 313 | local doFix runAction |
| | 314 | |
| | 315 | -- warn "XXX" () |
| | 316 | doFix <- fixEnv return env pad |
| | 317 | local doFix $ do |