History

Made it possible to instantiate types directly, without requiring input from a file so that programs can be assembled in code. Simplified the Data class to reduce the amount of redundant information being passed around. Added shorthand names for the operand types. Changed the double offset operand classes to make them easier to use in programs at the expense of code duplication. Added a test based on the Dis file compiled from a simple Limbo program.

David Boddie committed 9 years ago

Commit de15c5f1 parent 9bbb0593 files · +135 −24Browse files

Unified · Split

3 files
  1. Tests/count.py +62 −0
  2. dis.py +52 −20
  3. opcodes.py +21 −4
Tests/count.py+62−0
@@ -0,0 +1,62 @@
1+#!/usr/bin/env python
2+
3+import sys
4+
5+import dis
6+import opcodes
7+from opcodes import Imm, LOfp, LOmp, NoOp, SOfp, SOmp, SOSOfp, SOSOmp
8+
9+if __name__ == "__main__":
10+
11+ if len(sys.argv) != 2:
12+ sys.stderr.write("Usage: %s <output file>\n" % sys.argv[0])
13+ sys.exit(1)
14+
15+ d = dis.Dis()
16+ d.runtime_flag = dis.RuntimeFlag(dis.RuntimeFlag.HASLDT)
17+ d.stack_extent = 560
18+ d.data_size = 16
19+ d.link_size = 1
20+ d.entry_pc = 0
21+ d.entry_type = 2
22+
23+ d.code = [
24+ opcodes.load(LOmp(0), Imm(0), LOfp(44)),
25+ opcodes.frame(Imm(1), LOfp(52)),
26+ opcodes.movp(LOmp(8), SOSOfp(52, 32)),
27+ opcodes.lea(LOfp(48), SOSOfp(52, 16)),
28+ opcodes.mcall(LOfp(52), Imm(0), LOfp(44)),
29+ opcodes.movw(Imm(0), LOfp(40)),
30+ opcodes.blew(Imm(0x14), SOfp(40), Imm(0xe)),
31+ opcodes.frame(Imm(1), LOfp(48)),
32+ opcodes.movp(LOmp(4), SOSOfp(48, 32)),
33+ opcodes.movw(LOfp(40), SOSOfp(48, 36)),
34+ opcodes.lea(LOfp(52), SOSOfp(48, 16)),
35+ opcodes.mcall(LOfp(48), Imm(0), LOfp(44)),
36+ opcodes.addw(Imm(1), NoOp(), LOfp(40)),
37+ opcodes.jmp(Imm(6)),
38+ opcodes.ret()
39+ ]
40+
41+ d.types = [
42+ dis.Type(0, 16, 1, "\xf0"),
43+ dis.Type(1, 40, 2, "\x00\x80"),
44+ dis.Type(2, 56, 2, "\x00\xd0")
45+ ]
46+
47+ d.data = {
48+ # code size
49+ 0: dis.Data(0, 0, 0x03, array = "$Sys"),
50+ 4: dis.Data(0, 4, 0x03, array = "%d\n"),
51+ 8: dis.Data(0, 8, 0x03, array = "Counting to 20...\n"),
52+ }
53+
54+ d.module_name = "count"
55+ d.link = [dis.Link(0, 2, 0x4244b354, "init")]
56+ d.initialised_globals = 1
57+ d.ldt = [[dis.LDT(0xac849033, "print")]]
58+ d.path = sys.argv[0]
59+
60+ d.write(open(sys.argv[1], "w"))
61+
62+ sys.exit()
dis.py+52−20
@@ -103,7 +103,7 @@ class Dis: · 102 unmodified lines
103103 i = 0
104104
105105 while i < self.type_size:
106− self.types.append(Type(f))
106+ self.types.append(Type().read(f))
107107 i += 1
108108
109109 def read_data(self, f):
@@ -162,7 +162,8 @@ class Dis: · 52 unmodified lines
162162 else:
163163 #print "Data", offset
164164 address = base + offset
165− item = Data(f, code, count, offset, base, array_type, type_)
165+ item = Data(base, offset, array_type, type_)
166+ item.read(f, count)
166167 self.data_items.append(item)
167168 if address in self.data:
168169 print "Overwriting existing data item at %x." % address
@@ -174,7 +175,7 @@ class Dis: · 5 unmodified lines
174175 i = 0
175176
176177 while i < self.link_size:
177− self.link.append(Link(f))
178+ self.link.append(Link().read(f))
178179 i += 1
179180
180181 def read_ldt(self, f):
@@ -207,6 +208,7 @@ class Dis: · 26 unmodified lines
207208
208209 # Write the header.
209210 self.code_size = len(self.code)
211+ self.type_size = len(self.types)
210212
211213 # Only unsigned files are currently supported.
212214 write_OP(f, XMAGIC)
@@ -328,12 +330,21 @@ class RuntimeFlag: · 115 unmodified lines
328330
329331 class Type:
330332
331− def __init__(self, f):
333+ def __init__(self, desc_number = 0, size = 0, number_ptrs = 0, array = ""):
334+
335+ self.desc_number = desc_number
336+ self.size = size
337+ self.number_ptrs = number_ptrs
338+ self.array = array
339+
340+ def read(self, f):
332341
333342 self.desc_number = read_OP(f)
334343 self.size = read_OP(f)
335344 self.number_ptrs = read_OP(f)
336345 self.array = f.read(self.number_ptrs)
346+
347+ return self
337348
338349 def __repr__(self):
339350
@@ -367,33 +378,36 @@ class Data: · 27 unmodified lines
367378 "UTF-8 encoded string", "64-bit float", "Array",
368379 "Set array address", "Restore load address"]
369380
370− def __init__(self, f, code, count, offset, base, array_type, type_):
381+ def __init__(self, base, offset, array_type, type_ = None, array = None):
371382
372− self.code = code
373− self.count = count
374− self.offset = offset
375383 self.base = base
384+ self.offset = offset
376385 self.array_type = array_type
377386 self.type_ = type_
378−
379− self.array = []
387+ if not array:
388+ self.array = []
389+ else:
390+ self.array = array
391+
392+ def read(self, f, count):
393+
380394 base = 0
381395 i = 0
382396 while i < count:
383397
384− if array_type == 1:
398+ if self.array_type == 1:
385399 # 8-bit byte
386400 self.array.append(read_B(f))
387− elif array_type == 2:
401+ elif self.array_type == 2:
388402 # 32-bit word
389403 self.array.append(read_W(f))
390− elif array_type == 3:
404+ elif self.array_type == 3:
391405 # UTF-8 encoded string (each item is a character)
392406 self.array.append(f.read(1))
393− elif array_type == 4:
407+ elif self.array_type == 4:
394408 # 64-bit float
395409 self.array.append(read_F(f))
396− elif array_type == 8:
410+ elif self.array_type == 8:
397411 # 64-bit integer
398412 self.array.append(read_L(f))
399413
@@ -441,10 +455,16 @@ class Data: · 41 unmodified lines
441455
442456 def write(self, f):
443457
444− write_B(f, self.code)
458+ code = self.array_type << 4
459+ count = len(self.array)
460+
461+ if count < 16:
462+ code |= count
445463
446− if self.count >= 16:
447− write_OP(f, self.count)
464+ write_B(f, code)
465+
466+ if count >= 16:
467+ write_OP(f, count)
448468
449469 write_OP(f, self.offset)
450470
@@ -464,7 +484,14 @@ class Data: · 13 unmodified lines
464484
465485 class Link:
466486
467− def __init__(self, f):
487+ def __init__(self, pc = 0, desc_number = 0, sig = 0, name = ""):
488+
489+ self.pc = pc
490+ self.desc_number = desc_number
491+ self.sig = sig
492+ self.name = name
493+
494+ def read(self, f):
468495
469496 self.pc = read_OP(f)
470497 self.desc_number = read_OP(f)
@@ -486,7 +513,12 @@ class Link: · 15 unmodified lines
486513
487514 class LDT:
488515
489− def __init__(self, f):
516+ def __init__(self, sig = 0, name = ""):
517+
518+ self.sig = sig
519+ self.name = name
520+
521+ def read(self, f):
490522
491523 self.sig = _read(f, ">I") # unsigned for hashes
492524 self.name = read_C(f)
opcodes.py+21−4
@@ -82,9 +82,9 @@ class Instruction: · 81 unmodified lines
8282 # No operand for 0x03.
8383
8484 elif operand == 0x04:
85− operand = DoubleShortOffsetMP((read_OP(f), read_OP(f)), "SO(SO(MP))")
85+ operand = DoubleShortOffsetMP(read_OP(f), read_OP(f), "SO(SO(MP))")
8686 elif operand == 0x05:
87− operand = DoubleShortOffsetFP((read_OP(f), read_OP(f)), "SO(SO(FP))")
87+ operand = DoubleShortOffsetFP(read_OP(f), read_OP(f), "SO(SO(FP))")
8888 else:
8989 operand = NoOperand()
9090
@@ -186,9 +186,18 @@ class ShortOffsetFP(ShortOffset): · 95 unmodified lines
186186
187187 class DoubleShortOffset(Operand):
188188
189+ def __init__(self, offset0, offset1, annotation = None):
190+
191+ self.offset0 = offset0
192+ self.offset1 = offset1
193+ self.annotation = annotation
194+
195+ def __str__(self):
196+ return self.str_pattern % (self.offset0, self.offset1)
197+
189198 def write(self, f):
190− write_OP(f, self.value[0] & 0xffff)
191− write_OP(f, self.value[1] & 0xffff)
199+ write_OP(f, self.offset0 & 0xffff)
200+ write_OP(f, self.offset1 & 0xffff)
192201
193202 class DoubleShortOffsetMP(DoubleShortOffset):
194203 str_pattern = "%i(%i(mp))"
@@ -198,6 +207,14 @@ class DoubleShortOffsetFP(DoubleShortOffset): · 3 unmodified lines
198207 str_pattern = "%i(%i(fp))"
199208 address_mode = 0x05
200209
210+Imm = Immediate
211+LOfp = LongOffsetFP
212+LOmp = LongOffsetMP
213+NoOp = NoOperand
214+SOfp = ShortOffsetFP
215+SOmp = ShortOffsetMP
216+SOSOfp = DoubleShortOffsetFP
217+SOSOmp = DoubleShortOffsetMP
201218
202219 # Define the instructions and their opcode values.
203220

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t