module Language.Lua.Bytecode where
import Data.Vector(Vector)
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
newtype Reg = Reg Int
deriving (Read,Show,Eq,Ord)
instance Enum Reg where
toEnum = Reg
fromEnum (Reg r) = r
newtype UpIx = UpIx Int
deriving (Read,Show,Eq,Ord)
newtype ProtoIx = ProtoIx Int
deriving (Read,Show,Eq,Ord)
newtype Kst = Kst Int
deriving (Read,Show,Eq,Ord)
data RK = RK_Reg Reg | RK_Kst Kst
deriving (Read,Show,Eq,Ord)
data Chunk = Chunk Int Function
deriving (Read,Show,Eq)
data OpCode
= OP_MOVE Reg Reg
| OP_LOADK Reg Kst
| OP_LOADKX Reg
| OP_LOADBOOL Reg Bool Bool
| OP_LOADNIL Reg Int
| OP_GETUPVAL Reg UpIx
| OP_GETTABUP Reg UpIx RK
| OP_GETTABLE Reg Reg RK
| OP_SETTABUP UpIx RK RK
| OP_SETUPVAL Reg UpIx
| OP_SETTABLE Reg RK RK
| OP_NEWTABLE Reg Int Int
| OP_SELF Reg Reg RK
| OP_ADD Reg RK RK
| OP_SUB Reg RK RK
| OP_MUL Reg RK RK
| OP_MOD Reg RK RK
| OP_POW Reg RK RK
| OP_DIV Reg RK RK
| OP_IDIV Reg RK RK
| OP_BAND Reg RK RK
| OP_BOR Reg RK RK
| OP_BXOR Reg RK RK
| OP_SHL Reg RK RK
| OP_SHR Reg RK RK
| OP_UNM Reg Reg
| OP_BNOT Reg Reg
| OP_NOT Reg Reg
| OP_LEN Reg Reg
| OP_CONCAT Reg Reg Reg
| OP_JMP (Maybe Reg) Int
| OP_EQ Bool RK RK
| OP_LT Bool RK RK
| OP_LE Bool RK RK
| OP_TEST Reg Bool
| OP_TESTSET Reg Reg Bool
| OP_CALL Reg Count Count
| OP_TAILCALL Reg Count Count
| OP_RETURN Reg Count
| OP_FORLOOP Reg Int
| OP_FORPREP Reg Int
| OP_TFORCALL Reg Int
| OP_TFORLOOP Reg Int
| OP_SETLIST Reg Int Int
| OP_CLOSURE Reg ProtoIx
| OP_VARARG Reg Count
| OP_EXTRAARG Int
deriving (Read, Show, Eq, Ord)
data Count = CountInt Int | CountTop
deriving (Read, Show, Eq, Ord)
data Function = Function
{ funcSource :: !(Maybe ByteString)
, funcLineDefined :: !Int
, funcLastLineDefined :: !Int
, funcNumParams :: !Int
, funcIsVararg :: !Bool
, funcMaxStackSize :: !Int
, funcCode :: !(Vector OpCode)
, funcConstants :: !(Vector Constant)
, funcUpvalues :: !(Vector Upvalue)
, funcProtos :: !(Vector Function)
, funcDebug :: !DebugInfo
}
deriving (Read, Show, Eq)
data Constant = KNil | KBool Bool | KNum Double | KInt Int | KString ByteString | KLongString ByteString
deriving (Read, Show, Eq, Ord)
data Upvalue = UpReg Reg | UpUp UpIx
deriving (Read, Show, Eq, Ord)
type LineNumber = Int
data DebugInfo = DebugInfo
{ debugInfoLines :: !(Vector LineNumber)
, debugInfoVars :: !(Vector VarInfo)
, debugInfoUpvalues :: !(Vector ByteString)
}
deriving (Read, Show, Eq)
data VarInfo = VarInfo
{ varInfoName :: !ByteString
, varInfoStart, varInfoEnd :: !Int
}
deriving (Read, Show, Eq)
propagateSources :: Function -> Function
propagateSources = go B.empty
where
go name func =
case funcSource func of
Nothing ->
func { funcSource = (Just name)
, funcProtos = fmap (go name) (funcProtos func) }
Just src ->
func { funcProtos = fmap (go src) (funcProtos func) }
plusReg :: Reg -> Int -> Reg
plusReg (Reg i) j = Reg (i+j)
diffReg :: Reg -> Reg -> Int
diffReg (Reg i) (Reg j) = i j
regRange :: Reg -> Int -> [Reg]
regRange start n = take n [start ..]