annotate python/ppci/modules.py @ 101:af0d7913677a

Fixes and splitting into 3 stage
author windel
date Mon, 24 Dec 2012 17:55:08 +0100
parents a350055d6119
children
rev   line source
1
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
1 import struct
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
2 from .errors import Error
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
3 from .nodes import *
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
4 from .builtin import integer, real, char, boolean, void
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
5 import os.path
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
6
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
7 """
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
8 File format for compiled modules.
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
9 * [11] magic identifier
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
10 * [STR] mod name
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
11 * [STR] signature, a md5 signature of the module.
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
12 * [I32] size of code
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
13 * code image
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
14 * [I32] entrypoint for initcode
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
15 * imported modules
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
16 ** [I32] num of imported modules
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
17 *** [STR] name of module
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
18 *** signature of the module
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
19 *** [I32] offset in the process image where the interface symbols must be placed
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
20 * public interface
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
21 ** [I32] num of interface elements
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
22 *** [STR] proc name
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
23 *** [I32] offset in code image
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
24 *** [type] return type
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
25 *** [I32] number of parameters
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
26 **** parameter
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
27 ***** parameter kind
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
28 ***** parameter name
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
29 ***** parameter type
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
30 """
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
31
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
32 MAGIC = b'LCFOSMODC'
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
33
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
34 loadedModules = []
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
35
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
36 def loadModule(modname):
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
37 """ returns a Module object specified by a name """
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
38 # Check if the module was already loaded:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
39 for mod in loadedModules:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
40 if mod.name == modname:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
41 return mod
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
42
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
43 # Try to load the module from file:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
44 srcfilename = modname + '.mod'
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
45 binfilename = modname + '.bin'
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
46 sourceExists = os.path.exists(srcfilename)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
47 if os.path.exists(binfilename):
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
48 if sourceExists:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
49 compileModule()
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
50 else:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
51 return loadModuleFromFile(binfilename)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
52 else:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
53 Error("Cannot load module '{0}'!".format(modname))
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
54
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
55 def loadModuleFromFile(filename):
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
56 f = open(filename, 'rb')
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
57 magic = f.read(len(MAGIC))
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
58 assert(magic == MAGIC)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
59
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
60 # Helper functions:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
61 def readI32():
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
62 int32, = struct.unpack('<I', f.read(4))
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
63 return int32
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
64 def readSTR():
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
65 length = readI32()
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
66 b = f.read(length)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
67 return b.decode(encoding='ascii')
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
68 def readType():
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
69 code, = f.read(1)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
70 basetypes = {0x11:integer, 0x12:real, 0x13:char,0x14:boolean, 0x15:void}
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
71 if code in list(basetypes.keys()):
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
72 return basetypes[code]
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
73 elif code == 0x20:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
74 dimension, elementType = readI32(), readType()
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
75 return ArrayType(dimension, elementType)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
76 elif code == 0x21:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
77 returntype = readType()
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
78 numparams = readI32()
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
79 parameters = []
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
80 kinds = {0x1:'value', 0x2:'var', 0x3:'const'}
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
81 for i in range(numparams):
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
82 byt, = f.read(1)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
83 kind = kinds[byt]
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
84 name, typ = readSTR(), readType()
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
85 parameters.append(Parameter(kind, name, typ))
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
86 return ProcedureType(parameters, returntype)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
87 else:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
88 Error('Reading of this typ not supported')
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
89
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
90 # Begin of actual loading
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
91 modname = readSTR()
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
92 modsignature = readSTR()
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
93 codesize = readI32()
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
94 image = f.read(codesize)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
95 initcodeentry = readI32()
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
96 # Check which modules this module loads:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
97 numimports = readI32()
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
98 imports = []
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
99 for i in range(numimports):
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
100 modname = readSTR()
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
101 signature = readSTR()
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
102 symname = readSTR()
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
103 offset = readI32()
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
104 impsym = ImportedSymbol(modname, symname)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
105 impsym.signature = signature
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
106 impsym.offset = offset
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
107 imports.append(impsym)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
108 # Modules exported interface:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
109 numexports = readI32()
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
110 exports = []
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
111 for i in range(numexports):
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
112 name = readSTR()
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
113 imageoffset = readI32() # Offset in image where symbol is located
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
114 typ = readType()
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
115 export = ExportedSymbol(name, typ)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
116 export.imageoffset = imageoffset
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
117 exports.append(export)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
118 f.close()
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
119
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
120 # Construct imported module object:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
121 module = Module(modname)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
122 module.signature = modsignature
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
123 module.exports = exports # Symbols provided to other modules
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
124 module.imports = imports # Symbols of others used by this module.
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
125 module.initcodeentry = initcodeentry
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
126 module.image = image # The binary blob
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
127 global loadedModules
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
128 loadedModules.append(module)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
129 return module
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
130
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
131 def storeModule(mod, filename):
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
132 """ Class to store a module in a file """
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
133 f = open(filename, 'wb')
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
134
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
135 def writeI32(int32):
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
136 f.write( struct.pack('<I', int32) )
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
137 def writeSTR(s):
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
138 writeI32(len(s))
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
139 f.write(bytes(s, encoding='ascii'))
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
140 def writeType(typ):
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
141 if type(typ) is BaseType:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
142 basetypecode = {'integer': 0x11, 'real': 0x12, 'char': 0x13, 'boolean':0x14, 'void':0x15}
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
143 code = basetypecode[typ.name]
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
144 f.write( bytes([code]))
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
145 elif type(typ) is ArrayType:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
146 f.write(bytes([0x20]))
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
147 writeI32(typ.dimension)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
148 writeType(typ.elementType)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
149 elif type(typ) is ProcedureType:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
150 f.write(bytes([0x21]))
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
151 writeType(typ.returntype)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
152 writeI32(len(typ.parameters))
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
153 for parameter in typ.parameters:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
154 kinds = {'value': 0x1, 'var': 0x2, 'const': 0x3}
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
155 kind = kinds[parameter.kind]
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
156 f.write(bytes([kind]))
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
157 writeSTR(parameter.name)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
158 writeType(parameter.typ)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
159 else:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
160 Error('Type storage not implemented {0}'.format(typ))
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
161
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
162 # Begin of actual storage function
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
163 f.write(MAGIC)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
164 writeSTR(mod.name)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
165 writeSTR(mod.signature)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
166 writeI32(len(mod.image))
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
167 f.write(bytes(mod.image))
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
168 writeI32(mod.initcodeentry)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
169 # modules imported symbols:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
170 writeI32(len(mod.imports))
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
171 for imp in mod.imports:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
172 writeSTR(imp.modname)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
173 writeSTR(imp.signature)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
174 writeSTR(imp.name)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
175 writeI32(imp.offset)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
176 # modules provided interface
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
177 writeI32(len(mod.exports))
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
178 # Store exported symbols:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
179 for sym in mod.exports:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
180 writeSTR(sym.name) # proc name
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
181 writeI32(sym.imageoffset) # proc entry point
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
182 writeType(sym.typ) # Procedure type
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
183 f.close()
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
184
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
185 storeModuleInCache(mod)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
186
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
187 def storeModuleInCache(newmod):
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
188 global loadedModules
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
189 for mod in loadedModules:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
190 if newmod.name == mod.name:
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
191 return
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
192 loadedModules.append(newmod)
92df07bc2081 Initial import of compiler
windel
parents:
diff changeset
193