Mercurial > lcfOS
diff python/ppci/core/bitreader.py @ 105:6a303f835c6d
Removed compilers directory
author | Windel Bouwman |
---|---|
date | Mon, 31 Dec 2012 17:35:17 +0100 |
parents | ed230e947dc6 |
children |
line wrap: on
line diff
--- a/python/ppci/core/bitreader.py Sun Dec 30 22:31:55 2012 +0100 +++ b/python/ppci/core/bitreader.py Mon Dec 31 17:35:17 2012 +0100 @@ -1,30 +1,90 @@ from .errors import CompilerException +from .module import Module import struct -def bits(f): - while True: - Byte = f.read(1) - for i in range(8): - yield Byte & 0x1 - Byte >>= 1 +def enum(**enums): + return type('Enum', (), enums) + +BitCodes = enum(END_BLOCK=0, ENTER_SUBBLOCK=1) + +class BitstreamReader: + def __init__(self, f): + self.f = f + # Initialize the bitreader: + self.bitsInCurrent = 32 + self.curWord = self.getWord() + self.curCodeSize = 2 + def getWord(self): + bts = self.f.read(4) + return struct.unpack('<I', bts)[0] + def Read(self, numbits): + if numbits > 32: + raise CompilerException("Cannot read more than 32 bits") + if self.bitsInCurrent >= numbits: + # numbits inside the current word: + R = self.curWord & ((1 << numbits) - 1) + self.curWord = self.curWord >> numbits + self.bitsInCurrent -= numbits + return R + R = self.curWord + self.curWord = self.getWord() + bitsLeft = numbits - self.bitsInCurrent + + # Add remaining bits: + R |= (self.curWord & (0xFFFFFFFF >> (32 - bitsLeft))) << self.bitsInCurrent -class BitReader: + # Update curword and bits in current: + self.curWord = self.curWord >> bitsLeft + self.bitsInCurrent = 32 - bitsLeft + return R + def ReadVBR(self, numbits): + """ Read variable bits, checking for the last bit is zero. """ + piece = self.Read(numbits) + if (piece & (1 << (numbits - 1))) == 0: + return piece + result = 0 + nextbit = 0 + while True: + mask = (1 << (numbits - 1)) - 1 + result |= ( piece & mask ) << nextbit + if (piece & (1 << (numbits - 1))) == 0: + return result + nextbit += numbits - 1 + piece = self.Read(numbits) + def ReadCode(self): + """ Read the code depending on the current code size """ + return self.Read(self.curCodeSize) + def ReadSubBlockId(self): + return self.ReadVBR(8) + def EnterSubBlock(self, blockId): + pass + +BLOCKINFO_BLOCKID = 0 +FIRST_APPLICATION_BLOCKID = 8 +MODULE_BLOCKID = FIRST_APPLICATION_BLOCKID + +class BitcodeReader: def __init__(self, f): - self.stream = bits(f) - self.curword = None + self.stream = BitstreamReader(f) def parseModule(self): - if self.read(8) != ord('B') or self.read(8) != ord('C'): - raise CompilerException('Invalid bitcode signature') + for bitsig in [ord('B'), ord('C')]: + if self.stream.Read(8) != bitsig: + raise CompilerException('Invalid bitcode signature') for bitsig in [0x0, 0xC, 0xE, 0xD]: - if self.read(4) != bitsig: + if self.stream.Read(4) != bitsig: raise CompilerException('Invalid bitcode signature') - - def read(self, numbits): - if numbits == 8: - b = self.stream.read(1) - print(b) - return int(b[0]) - return 2 + while True: + code = self.stream.ReadCode() + if code != BitCodes.ENTER_SUBBLOCK: + raise CompilerException('Invalid record at toplevel') + blockId = self.stream.ReadSubBlockId() + if blockId == MODULE_BLOCKID: + print('module block') + pass + else: + print('Block id:', blockId) + raise + return Module() class BitstreamWriter: def __init__(self, f):