module VM.VMState
( VMState(..)
, VirtualMachine
, createVMState
, createSnapshot
, doSnapshot
) where
import qualified Data.Map.Strict as Map
import qualified Data.ByteString as BS
import qualified Data.Vector as V
import Control.Monad.State.Strict (StateT, get, put)
import System.IO (Handle, stdin, stdout, stderr)
import VM.VMValue (VMValue)
import VM.CallSnapshot (CallSnapshot(..))
data VMState = VMState
{ VMState -> ByteString
bytecode :: BS.ByteString
, VMState -> Int
bytecodeIndex :: Int
, VMState -> Vector VMValue
vStack :: V.Vector VMValue
, VMState -> Int
baseVStackIndex :: Int
, VMState -> [CallSnapshot]
snapshotStack :: [CallSnapshot]
, VMState -> Vector VMValue
env :: V.Vector VMValue
, VMState -> Vector VMValue
globalEnv :: V.Vector VMValue
, VMState -> Bool
isRunning :: Bool
, VMState -> Bool
isDebug :: Bool
, VMState -> Map Int Handle
vmFds :: Map.Map Int Handle
, VMState -> Int
nextFd :: Int
}
type VirtualMachine a = StateT VMState IO a
createVMState :: BS.ByteString -> Bool -> VMState
createVMState :: ByteString -> Bool -> VMState
createVMState ByteString
code Bool
debug = VMState
{ bytecode :: ByteString
bytecode = ByteString
code, bytecodeIndex :: Int
bytecodeIndex = Int
0
, vStack :: Vector VMValue
vStack = Vector VMValue
forall a. Vector a
V.empty, baseVStackIndex :: Int
baseVStackIndex = Int
0
, snapshotStack :: [CallSnapshot]
snapshotStack = [], env :: Vector VMValue
env = Vector VMValue
forall a. Vector a
V.empty
, globalEnv :: Vector VMValue
globalEnv = Int -> VMValue -> Vector VMValue
forall a. Int -> a -> Vector a
V.replicate Int
1024 (VMValue
forall a. HasCallStack => a
undefined)
, isRunning :: Bool
isRunning = Bool
True, isDebug :: Bool
isDebug = Bool
debug
, vmFds :: Map Int Handle
vmFds = [(Int, Handle)] -> Map Int Handle
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(Int
0, Handle
stdin), (Int
1, Handle
stdout), (Int
2, Handle
stderr)]
, nextFd :: Int
nextFd = Int
3 }
createSnapshot :: VMState -> CallSnapshot
createSnapshot :: VMState -> CallSnapshot
createSnapshot VMState
vm = CallSnapshot
{ callbackIndex :: Int
callbackIndex = VMState -> Int
bytecodeIndex VMState
vm
, vStackIndex :: Int
vStackIndex = VMState -> Int
baseVStackIndex VMState
vm
, vEnv :: Vector VMValue
vEnv = VMState -> Vector VMValue
env VMState
vm }
doSnapshot :: Int -> V.Vector VMValue -> VirtualMachine ()
doSnapshot :: Int -> Vector VMValue -> VirtualMachine ()
doSnapshot Int
idx Vector VMValue
nEnv = do
vm <- StateT VMState IO VMState
forall s (m :: * -> *). MonadState s m => m s
get
put $ vm { snapshotStack = createSnapshot vm : snapshotStack vm
, baseVStackIndex = V.length (vStack vm)
, bytecodeIndex = idx
, env = nEnv }