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
3import sys
4
5import dis
6import opcodes
7from opcodes import Imm, LOfp, LOmp, NoOp, SOfp, SOmp, SOSOfp, SOSOmp
8
9if __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
103 i = 0103 i = 0
104 104
105 while i < self.type_size:105 while i < self.type_size:
106 self.types.append(Type(f))106 self.types.append(Type().read(f))
107 i += 1107 i += 1
108 108
109 def read_data(self, f):109 def read_data(self, f):
@@ -162,7 +162,8 @@ class Dis: · 52 unmodified lines
162 else:162 else:
163 #print "Data", offset163 #print "Data", offset
164 address = base + offset164 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)
166 self.data_items.append(item)167 self.data_items.append(item)
167 if address in self.data:168 if address in self.data:
168 print "Overwriting existing data item at %x." % address169 print "Overwriting existing data item at %x." % address
@@ -174,7 +175,7 @@ class Dis: · 5 unmodified lines
174 i = 0175 i = 0
175 176
176 while i < self.link_size:177 while i < self.link_size:
177 self.link.append(Link(f))178 self.link.append(Link().read(f))
178 i += 1179 i += 1
179 180
180 def read_ldt(self, f):181 def read_ldt(self, f):
@@ -207,6 +208,7 @@ class Dis: · 26 unmodified lines
207 208
208 # Write the header.209 # Write the header.
209 self.code_size = len(self.code)210 self.code_size = len(self.code)
211 self.type_size = len(self.types)
210 212
211 # Only unsigned files are currently supported.213 # Only unsigned files are currently supported.
212 write_OP(f, XMAGIC)214 write_OP(f, XMAGIC)
@@ -328,12 +330,21 @@ class RuntimeFlag: · 115 unmodified lines
328 330
329class Type:331class Type:
330 332
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):
332 341
333 self.desc_number = read_OP(f)342 self.desc_number = read_OP(f)
334 self.size = read_OP(f)343 self.size = read_OP(f)
335 self.number_ptrs = read_OP(f)344 self.number_ptrs = read_OP(f)
336 self.array = f.read(self.number_ptrs)345 self.array = f.read(self.number_ptrs)
346
347 return self
337 348
338 def __repr__(self):349 def __repr__(self):
339 350
@@ -367,33 +378,36 @@ class Data: · 27 unmodified lines
367 "UTF-8 encoded string", "64-bit float", "Array",378 "UTF-8 encoded string", "64-bit float", "Array",
368 "Set array address", "Restore load address"]379 "Set array address", "Restore load address"]
369 380
370 def __init__(self, f, code, count, offset, base, array_type, type_):381 def __init__(self, base, offset, array_type, type_ = None, array = None):
371 382
372 self.code = code
373 self.count = count
374 self.offset = offset
375 self.base = base383 self.base = base
384 self.offset = offset
376 self.array_type = array_type385 self.array_type = array_type
377 self.type_ = type_386 self.type_ = type_
378 387 if not array:
379 self.array = []388 self.array = []
389 else:
390 self.array = array
391
392 def read(self, f, count):
393
380 base = 0394 base = 0
381 i = 0395 i = 0
382 while i < count:396 while i < count:
383 397
384 if array_type == 1:398 if self.array_type == 1:
385 # 8-bit byte399 # 8-bit byte
386 self.array.append(read_B(f))400 self.array.append(read_B(f))
387 elif array_type == 2:401 elif self.array_type == 2:
388 # 32-bit word402 # 32-bit word
389 self.array.append(read_W(f))403 self.array.append(read_W(f))
390 elif array_type == 3:404 elif self.array_type == 3:
391 # UTF-8 encoded string (each item is a character)405 # UTF-8 encoded string (each item is a character)
392 self.array.append(f.read(1))406 self.array.append(f.read(1))
393 elif array_type == 4:407 elif self.array_type == 4:
394 # 64-bit float408 # 64-bit float
395 self.array.append(read_F(f))409 self.array.append(read_F(f))
396 elif array_type == 8:410 elif self.array_type == 8:
397 # 64-bit integer411 # 64-bit integer
398 self.array.append(read_L(f))412 self.array.append(read_L(f))
399 413
@@ -441,10 +455,16 @@ class Data: · 41 unmodified lines
441 455
442 def write(self, f):456 def write(self, f):
443 457
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
445 463
446 if self.count >= 16:464 write_B(f, code)
447 write_OP(f, self.count)465
466 if count >= 16:
467 write_OP(f, count)
448 468
449 write_OP(f, self.offset)469 write_OP(f, self.offset)
450 470
@@ -464,7 +484,14 @@ class Data: · 13 unmodified lines
464 484
465class Link:485class Link:
466 486
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):
468 495
469 self.pc = read_OP(f)496 self.pc = read_OP(f)
470 self.desc_number = read_OP(f)497 self.desc_number = read_OP(f)
@@ -486,7 +513,12 @@ class Link: · 15 unmodified lines
486 513
487class LDT:514class LDT:
488 515
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):
490 522
491 self.sig = _read(f, ">I") # unsigned for hashes523 self.sig = _read(f, ">I") # unsigned for hashes
492 self.name = read_C(f)524 self.name = read_C(f)
opcodes.py+21−4
@@ -82,9 +82,9 @@ class Instruction: · 81 unmodified lines
82 # No operand for 0x03.82 # No operand for 0x03.
83 83
84 elif operand == 0x04:84 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))")
86 elif operand == 0x05:86 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))")
88 else:88 else:
89 operand = NoOperand()89 operand = NoOperand()
90 90
@@ -186,9 +186,18 @@ class ShortOffsetFP(ShortOffset): · 95 unmodified lines
186 186
187class DoubleShortOffset(Operand):187class DoubleShortOffset(Operand):
188 188
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
189 def write(self, f):198 def write(self, f):
190 write_OP(f, self.value[0] & 0xffff)199 write_OP(f, self.offset0 & 0xffff)
191 write_OP(f, self.value[1] & 0xffff)200 write_OP(f, self.offset1 & 0xffff)
192 201
193class DoubleShortOffsetMP(DoubleShortOffset):202class DoubleShortOffsetMP(DoubleShortOffset):
194 str_pattern = "%i(%i(mp))"203 str_pattern = "%i(%i(mp))"
@@ -198,6 +207,14 @@ class DoubleShortOffsetFP(DoubleShortOffset): · 3 unmodified lines
198 str_pattern = "%i(%i(fp))"207 str_pattern = "%i(%i(fp))"
199 address_mode = 0x05208 address_mode = 0x05
200 209
210Imm = Immediate
211LOfp = LongOffsetFP
212LOmp = LongOffsetMP
213NoOp = NoOperand
214SOfp = ShortOffsetFP
215SOmp = ShortOffsetMP
216SOSOfp = DoubleShortOffsetFP
217SOSOmp = DoubleShortOffsetMP
201 218
202# Define the instructions and their opcode values.219# Define the instructions and their opcode values.
203 220

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