summaryrefslogtreecommitdiff
path: root/python/examples/dynamic_typing/dietpass
blob: 5d15e1927f5f45667ac72e1b0c826836fb5368a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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