added support for \0 in strings
[swftools.git] / lib / as3 / mkabc.py
1 #!/usr/bin/python
2
3 import re
4
5 fi = open("code.c", "rb")
6 foc = open("opcodes.c", "wb")
7 foh = open("opcodes.h", "wb")
8
9 foh.write("#ifndef __opcodes_h__\n")
10 foh.write("#define __opcodes_h__\n")
11 foh.write("#include \"abc.h\"\n")
12 foh.write("#include \"pool.h\"\n")
13 foh.write("#include \"code.h\"\n")
14
15 foc.write("#include \"opcodes.h\"\n")
16
17 R = re.compile('{(0x..),\s*"([^"]*)"\s*,\s*"([^"]*)"[^}]*}\s*')
18
19 for line in fi.readlines():
20     line = line.strip()
21     m = R.match(line)
22     if m:
23         op,name,params = m.group(1),m.group(2),m.group(3)
24
25         iterations=1
26         if "2" in params:
27             iterations=2
28
29         for iteration in range(iterations):
30             if iteration==1:
31                 name=name+"2"
32             params = params.strip()
33             paramstr = ""
34             seen = {}
35             names = []
36
37             for c in params:
38                 paramstr += ", "
39                 if c == "2":
40                     if iteration==0:
41                         type,pname="char*","name"
42                     else:
43                         type,pname="multiname_t*","name"
44                 elif c == "s":
45                     type,pname="char*","s"
46                 elif c in "nubs":
47                     type,pname="int","v"
48                 elif c == "m":
49                     type,pname="abc_method_body_t*","m"
50                 elif c == "i":
51                     type,pname="abc_method_t*","m"
52                 elif c == "c":
53                     type,pname="abc_class_t*","m"
54                 elif c == "j":
55                     type,pname="code_t*","label"
56                 elif c == "S":
57                     type,pname="lookupswitch_t*","l"
58                 elif c == "D":
59                     type,pname="void*","debuginfo"
60                 elif c == "r":
61                     type,pname="int","reg"
62                 elif c == "f":
63                     type,pname="double","f"
64                 elif c == "I":
65                     type,pname="int","i"
66                 elif c == "U":
67                     type,pname="unsigned int","u"
68                 else:
69                     raise "Unknown type "+c
70                 paramstr += type
71                 paramstr += " "
72                 if pname in seen:
73                     seen[pname]+=1
74                     pname += str(seen[pname])
75                 else:
76                     seen[pname]=1
77                 paramstr += pname
78                 names += [pname]
79
80             foh.write("code_t* abc_%s(code_t*prev%s);\n" % (name, paramstr))
81
82             foc.write("code_t* abc_%s(code_t*prev%s)\n" % (name, paramstr))
83             foc.write("{\n")
84             foc.write("    code_t*self = add_opcode(prev, %s);\n" % op)
85             i = 0
86             for pname,c in zip(names,params):
87                 if(c == "2"):
88                     if iteration==0:
89                      foc.write("    self->data[%d] = multiname_fromstring(%s);\n" % (i,pname));
90                     else:
91                      foc.write("    self->data[%d] = multiname_clone(%s);\n" % (i,pname));
92                 elif(c in "nur"):
93                     foc.write("    self->data[%d] = (void*)(ptroff_t)%s;\n" % (i,pname))
94                 elif(c in "IU"):
95                     foc.write("    self->data[%d] = (void*)(ptroff_t)%s;\n" % (i,pname))
96                 elif(c in "f"):
97                     foc.write("    double*fp = malloc(sizeof(double));\n")
98                     foc.write("    *fp = %s;\n" % (pname))
99                     foc.write("    self->data[%d] = fp;\n" % (i))
100                 elif(c == "b"):
101                     foc.write("    self->data[%d] = (void*)(ptroff_t)%s;\n" % (i,pname))
102                 elif(c == "s"):
103                     foc.write("    self->data[%d] = strdup(%s);\n" % (i,pname))
104                 elif(c == "m"):
105                     foc.write("    self->data[%d] = %s;\n" % (i,pname))
106                 elif(c == "c"):
107                     foc.write("    self->data[%d] = %s;\n" % (i,pname))
108                 elif(c == "i"):
109                     foc.write("    self->data[%d] = %s;\n" % (i,pname))
110                 elif(c == "j"):
111                     foc.write("    self->data[%d] = 0; //placeholder\n" % i)
112                     foc.write("    self->branch = %s;\n" % pname)
113                 elif(c == "S"):
114                     foc.write("    self->data[%d] = %s;\n" % (i,pname))
115                 elif(c == "D"):
116                     foc.write("    /* FIXME: write debuginfo %s */\n" % pname)
117                 else:
118                     raise "Unknown type "+c
119                 i = i+1
120             foc.write("    return self;\n")
121             foc.write("}\n")
122
123             foh.write("#define "+name+"(")
124             foh.write(",".join(["method"]+names))
125             foh.write(") (method->code = abc_"+name+"(")
126             foh.write(",".join(["method->code"]+names))
127             foh.write("))\n")
128
129 foh.write("#endif\n")
130
131 foh.close()
132 foc.close()
133 fi.close()
134 #{0x75, "convert_d", ""},
135