@@ -340,29 +340,29 @@ inlineST = everywhere (mkT convertBlock)
340 -- Look for runST blocks and inline the STRefs there.
340 -- Look for runST blocks and inline the STRefs there.
341 -- If all STRefs are used in the scope of the same runST, only using { read, write, modify }STRef then
341 -- If all STRefs are used in the scope of the same runST, only using { read, write, modify }STRef then
342 -- we can be more aggressive about inlining, and actually turn STRefs into local variables.
342 -- we can be more aggressive about inlining, and actually turn STRefs into local variables.
343− convertBlock (JSApp f [arg]) | isSTFunc "runST" f =
343+ convertBlock (JSApp f [arg]) | isSTFunc "runST" f || isSTFunc "runSTArray" f =
344 let refs = nub . findSTRefsIn $ arg
344 let refs = nub . findSTRefsIn $ arg
345 usages = findAllSTUsagesIn arg
345 usages = findAllSTUsagesIn arg
346 allUsagesAreLocalVars = all (\u -> let v = toVar u in isJust v && fromJust v `elem` refs) usages
346 allUsagesAreLocalVars = all (\u -> let v = toVar u in isJust v && fromJust v `elem` refs) usages
347 localVarsDoNotEscape = all (\r -> length (r `appearingIn` arg) == length (filter (\u -> let v = toVar u in v == Just r) usages)) refs
347 localVarsDoNotEscape = all (\r -> length (r `appearingIn` arg) == length (filter (\u -> let v = toVar u in v == Just r) usages)) refs
348− in everywhere (mkT $ if allUsagesAreLocalVars then convertAggressive else convertSafe) arg
348+ in everywhere (mkT $ convert allUsagesAreLocalVars) arg
349 convertBlock other = other
349 convertBlock other = other
350− -- Convert a block in a safe way, preserving object wrappers of references
350+ -- Convert a block in a safe way, preserving object wrappers of references,
351− convertSafe (JSApp (JSApp f [arg]) []) | isSTFunc "newSTRef" f =
352− JSObjectLiteral [("value", arg)]
353− convertSafe (JSApp (JSApp f [ref]) []) | isSTFunc "readSTRef" f =
354− JSAccessor "value" ref
355− convertSafe (JSApp (JSApp (JSApp f [ref]) [arg]) []) | isSTFunc "writeSTRef" f =
356− JSAssignment (JSAccessor "value" ref) arg
357− convertSafe (JSApp (JSApp (JSApp f [ref]) [func]) []) | isSTFunc "modifySTRef" f =
358− JSAssignment (JSAccessor "value" ref) (JSApp func [JSAccessor "value" ref])
359− convertSafe other = other
360− -- Convert a block in a more agressive way, unwrapping object wrappers into local variables
351+ -- or in a more aggressive way, turning wrappers into local variables depending on the
352+ -- agg(ressive) parameter.
361− convertAggressive (JSApp (JSApp f [arg]) []) | isSTFunc "newSTRef" f = arg
353+ convert agg (JSApp (JSApp f [arg]) []) | isSTFunc "newSTRef" f =
354+ if agg then arg else JSObjectLiteral [("value", arg)]
362− convertAggressive (JSApp (JSApp f [ref]) []) | isSTFunc "readSTRef" f = ref
355+ convert agg (JSApp (JSApp f [ref]) []) | isSTFunc "readSTRef" f =
356+ if agg then ref else JSAccessor "value" ref
363− convertAggressive (JSApp (JSApp (JSApp f [ref]) [arg]) []) | isSTFunc "writeSTRef" f = JSAssignment ref arg
357+ convert agg (JSApp (JSApp (JSApp f [ref]) [arg]) []) | isSTFunc "writeSTRef" f =
358+ if agg then JSAssignment ref arg else JSAssignment (JSAccessor "value" ref) arg
364− convertAggressive (JSApp (JSApp (JSApp f [ref]) [func]) []) | isSTFunc "modifySTRef" f = JSAssignment ref (JSApp func [ref])
359+ convert agg (JSApp (JSApp (JSApp f [ref]) [func]) []) | isSTFunc "modifySTRef" f =
360+ if agg then JSAssignment ref (JSApp func [ref]) else JSAssignment (JSAccessor "value" ref) (JSApp func [JSAccessor "value" ref])
361+ convert _ (JSApp (JSApp (JSApp f [arr]) [i]) []) | isSTFunc "peekSTArray" f =
363+ convert _ (JSApp (JSApp (JSApp (JSApp f [arr]) [i]) [val]) []) | isSTFunc "pokeSTArray" f =
364+ JSAssignment (JSIndexer i arr) val
365− convertAggressive other = other
365+ convert _ other = other
366 -- Check if an expression represents a function in the ST module
366 -- Check if an expression represents a function in the ST module
367 isSTFunc name (JSAccessor name' (JSAccessor "ST" (JSVar "_ps"))) | name == name' = True
367 isSTFunc name (JSAccessor name' (JSAccessor "ST" (JSVar "_ps"))) | name == name' = True
368 isSTFunc _ _ = False
368 isSTFunc _ _ = False