2020-06-01 22:58:40 +00:00
|
|
|
import enum
|
|
|
|
from destruct import Struct
|
|
|
|
|
|
|
|
from .util import MultiEnum
|
|
|
|
from .common import CLIToken, CLITableType
|
|
|
|
|
|
|
|
|
|
|
|
class CILFormat(enum.Enum):
|
|
|
|
Tiny = 2
|
|
|
|
Extended = 3
|
|
|
|
|
|
|
|
class CILFlags(enum.Flag):
|
|
|
|
MoreSections = 0x8
|
|
|
|
InitLocals = 0x10
|
|
|
|
|
|
|
|
class CILAttributes(MultiEnum):
|
2020-06-02 02:37:25 +00:00
|
|
|
format = (CILFormat, 0b0011)
|
|
|
|
flags = (CILFlags, 0x0FF0 | 0b1100)
|
|
|
|
header_size = (int, 0xF000, 12)
|
2020-06-01 22:58:40 +00:00
|
|
|
|
2020-06-02 00:26:37 +00:00
|
|
|
class CILTinyHeader(Struct, nocopy=True):
|
2020-06-02 02:37:25 +00:00
|
|
|
attribs = Static(CILAttributes(CILFormat.Tiny.value))
|
2020-06-01 22:58:40 +00:00
|
|
|
stack_size = Static(0)
|
|
|
|
code_size = Process(UInt(8), lambda v: v >> 2)
|
|
|
|
vars = Static(None)
|
|
|
|
code = Data()
|
|
|
|
|
2020-06-02 02:37:25 +00:00
|
|
|
def on_attribs(self, spec, context):
|
|
|
|
self.attribs.header_size = 1
|
|
|
|
|
2020-06-01 22:58:40 +00:00
|
|
|
def on_code_size(self, spec, context):
|
|
|
|
spec.code.length = self.code_size
|
|
|
|
|
2020-06-02 00:26:37 +00:00
|
|
|
class CILExtendedHeader(Struct, nocopy=True):
|
2020-06-02 02:37:25 +00:00
|
|
|
attribs = Enum(CILAttributes, UInt(16))
|
2020-06-01 22:58:40 +00:00
|
|
|
stack_size = UInt(16)
|
|
|
|
code_size = UInt(32)
|
|
|
|
vars = CLIToken
|
|
|
|
_pad = Data()
|
|
|
|
code = Data()
|
|
|
|
|
2020-06-02 02:37:25 +00:00
|
|
|
def on_attribs(self, spec, context):
|
|
|
|
self.attribs.header_size *= 4
|
|
|
|
spec._pad.length = self.attribs.header_size - 12
|
2020-06-01 22:58:40 +00:00
|
|
|
|
|
|
|
def on_code_size(self, spec, context):
|
|
|
|
spec.code.length = self.code_size
|
|
|
|
|
|
|
|
|
|
|
|
def determine_header(b):
|
|
|
|
format = CILFormat(b[0] & 0b11)
|
|
|
|
if format == CILFormat.Tiny:
|
|
|
|
return CILTinyHeader
|
|
|
|
else:
|
|
|
|
return CILExtendedHeader
|