summaryrefslogtreecommitdiff
path: root/python/examples/dynamic_typing/dietpass
diff options
context:
space:
mode:
Diffstat (limited to 'python/examples/dynamic_typing/dietpass')
-rwxr-xr-xpython/examples/dynamic_typing/dietpass50
1 files changed, 50 insertions, 0 deletions
diff --git a/python/examples/dynamic_typing/dietpass b/python/examples/dynamic_typing/dietpass
new file mode 100755
index 0000000..5d15e19
--- /dev/null
+++ b/python/examples/dynamic_typing/dietpass
@@ -0,0 +1,50 @@
+#!/bin/python3
+import os
+import sys
+from dietc import *
+
+def main():
+ prog = Program(open(sys.argv[1], "rb").read())
+ for function in prog.functions:
+ fn_locals = function.locals()
+ start_i = function.code_start()
+ new_body = []
+ for op in function.body:
+ new_body.append(op)
+ # only look for casts to void
+ if " = ( " not in op.line: continue
+ if op.lhs_type(prog) != PointerType(BasicType("void")): continue
+ # if one is found, construct & annotate its type
+ rhs_type = prog.object_types[op[-2]]
+ type_ptr = describe_type(prog, rhs_type, new_body)
+ new_body.append(Instruction(
+ f"annotate_type({op[0]}, {type_ptr});"))
+ function.body = new_body
+ prog.preamble.append("#include <stddef.h>")
+ prog.print()
+
+def describe_type(prog, type_, new_body):
+ name = f"type_{count()}"
+ if isinstance(type_, BasicType):
+ new_body.append(Instruction(
+ f"void *{name} = make_basic(\"{type_.name}\", sizeof({type_.name}));"))
+ elif isinstance(type_, ArrayType):
+ base = describe_type(prog, type_.base, new_body)
+ new_body.append(Instruction(
+ f"void *{name} = make_array({base}, {type_.length});"))
+ elif isinstance(type_, PointerType):
+ base = describe_type(prog, type_.base, new_body)
+ new_body.append(Instruction(
+ f"void *{name} = make_pointer({base});"))
+ elif isinstance(type_, AggregateType):
+ tname = prog.type_to_name[type_]
+ new_body.append(Instruction(
+ f"void *{name} = make_struct(sizeof({tname}));"))
+ for fn, ft in reversed(type_.fields):
+ field = describe_type(prog, ft, new_body)
+ new_body.append(Instruction(
+ f"prepend_member({name}, {field}, \"{fn}\", offsetof({tname}, {fn}));"))
+ else: raise NotImplementedError
+ return name
+
+main()
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback