module Unison.Runtime.Wide
( wideOn,
setWide,
wideK,
wideWidth,
widePad,
)
where
import Control.Exception (throwIO)
import Data.Char (toLower)
import Data.IORef
import Data.Maybe (fromMaybe)
import System.Environment (lookupEnv)
import System.IO.Unsafe (unsafePerformIO)
import Unison.Runtime.Optimizations (Optimization (..), optimizationSetting)
wideOn :: Bool
wideOn :: Bool
wideOn = IO Bool -> Bool
forall a. IO a -> a
unsafePerformIO (IO Bool -> Bool) -> IO Bool -> Bool
forall a b. (a -> b) -> a -> b
$ do
Maybe Bool
chosen <- IORef (Maybe Bool) -> IO (Maybe Bool)
forall a. IORef a -> IO a
readIORef IORef (Maybe Bool)
wideRef
Bool
w <- IO Bool -> (Bool -> IO Bool) -> Maybe Bool -> IO Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe IO Bool
wideFromEnvironment Bool -> IO Bool
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Bool
chosen
IORef (Maybe Bool) -> Maybe Bool -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (Maybe Bool)
wideRef (Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
w)
IORef Bool -> Bool -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Bool
wideUsed Bool
True
pure Bool
w
{-# NOINLINE wideOn #-}
wideFromEnvironment :: IO Bool
wideFromEnvironment :: IO Bool
wideFromEnvironment = do
Maybe [Char]
mode <- [Char] -> IO (Maybe [Char])
lookupEnv [Char]
"UNISON_JIT"
pure $ case (Optimization -> Maybe Bool
optimizationSetting Optimization
Wide, (Char -> Char) -> [Char] -> [Char]
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower ([Char] -> Maybe [Char] -> [Char]
forall a. a -> Maybe a -> a
fromMaybe [Char]
"off" Maybe [Char]
mode)) of
(Just Bool
w, [Char]
_) -> Bool
w
(Maybe Bool
_, [Char]
"on") -> Bool
True
(Maybe Bool
_, [Char]
"eager") -> Bool
True
(Maybe Bool, [Char])
_ -> Bool
False
wideRef :: IORef (Maybe Bool)
wideRef :: IORef (Maybe Bool)
wideRef = IO (IORef (Maybe Bool)) -> IORef (Maybe Bool)
forall a. IO a -> a
unsafePerformIO (Maybe Bool -> IO (IORef (Maybe Bool))
forall a. a -> IO (IORef a)
newIORef Maybe Bool
forall a. Maybe a
Nothing)
{-# NOINLINE wideRef #-}
wideUsed :: IORef Bool
wideUsed :: IORef Bool
wideUsed = IO (IORef Bool) -> IORef Bool
forall a. IO a -> a
unsafePerformIO (Bool -> IO (IORef Bool)
forall a. a -> IO (IORef a)
newIORef Bool
False)
{-# NOINLINE wideUsed #-}
setWide :: Bool -> IO ()
setWide :: Bool -> IO ()
setWide Bool
w = do
Bool
used <- IORef Bool -> IO Bool
forall a. IORef a -> IO a
readIORef IORef Bool
wideUsed
Maybe Bool
chosen <- IORef (Maybe Bool) -> IO (Maybe Bool)
forall a. IORef a -> IO a
readIORef IORef (Maybe Bool)
wideRef
case Maybe Bool
chosen of
Just Bool
w' | Bool
used Bool -> Bool -> Bool
&& Bool
w' Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
/= Bool
w -> IOError -> IO ()
forall e a. (HasCallStack, Exception e) => e -> IO a
throwIO ([Char] -> IOError
userError ([Char]
"the wide calling convention is " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ (if Bool
w' then [Char]
"on" else [Char]
"off") [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" and already in use; it cannot be changed to " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ (if Bool
w then [Char]
"on" else [Char]
"off")))
Maybe Bool
_ -> IORef (Maybe Bool) -> Maybe Bool -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (Maybe Bool)
wideRef (Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
w)
wideK :: Int
wideK :: Int
wideK = Int
1
wideWidth :: Int
wideWidth :: Int
wideWidth
| Bool
wideOn = Int
wideK Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
| Bool
otherwise = Int
1
widePad :: Int
widePad :: Int
widePad = Int
wideWidth Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1