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):