3 File to generate builtin.c
5 Copyright (c) 2008 Matthias Kramm <kramm@quiss.org>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
25 #include "../rfxswf.h"
29 #include "tokenizer.h"
30 #include "parser.tab.h"
33 void fixstring(char*s)
37 if(!((*s>='a' && *s<='z') || (*s>='A' && *s<='Z') ||
38 (*s>='0' && *s<='9' && !first))) {
45 char* mkpid(const char*package)
47 char*id = malloc(strlen(package)+20);
48 strcpy(id, "package_");
56 char* mkid(const char*package, const char*name)
58 char*id = malloc(strlen(package)+strlen(name)+10);
66 char*mkid2(multiname_t*m)
69 return mkid(m->ns->name, m->name);
70 else if(m->type == MULTINAME) {
71 namespace_list_t*l = m->namespace_set->namespaces;
73 if(l->namespace->name &&
74 l->namespace->name[0])
78 return mkid(l->namespace->name, m->name);
81 fprintf(stderr, "can't convert multiname type %d\n", m->type);
85 static array_t*tosort=0;
86 static int compare_classes(const void*v1, const void*v2)
90 abc_class_t*c1 = array_getvalue(tosort, x1);
91 abc_class_t*c2 = array_getvalue(tosort, x2);
92 int i = strcmp(c1->classname->ns->name, c2->classname->ns->name);
95 return strcmp(c1->classname->name, c2->classname->name);
98 static int compare_traits(const void*v1, const void*v2)
100 trait_t* x1 = *(trait_t**)v1;
101 trait_t* x2 = *(trait_t**)v2;
102 int i = strcmp(x1->name->ns->name, x2->name->ns->name);
105 return strcmp(x1->name->name, x2->name->name);
108 char* kind2string(int kind)
112 void write_member_info(FILE*fi, char*parent, char*id2, const char*name, int flags, trait_t*trait)
116 switch(trait->kind) {
118 multiname_t*ret = trait->method->return_type;
123 retvalue = mkid(ret->ns->name, ret->name);
124 if(ret && !strcmp(ret->name, "void"))
128 type = "MEMBER_METHOD";
134 type = "MEMBER_SLOT";
137 fprintf(stderr, "Unknown trait type %d\n", trait->kind);
139 fprintf(fi, "static memberinfo_t %s = {%s, 0x%02x, \"%s\"", id2, type, flags, name);
143 fprintf(fi, ", &%s", retvalue);
148 fprintf(fi, ", &%s", parent); // parent
153 int access2flags(multiname_t*m)
155 int access = m->ns->access;
157 if(access == ACCESS_PACKAGE) flags|=FLAG_PUBLIC;
158 if(access == ACCESS_PRIVATE) flags|=FLAG_PRIVATE;
159 if(access == ACCESS_PROTECTED) flags|=FLAG_PROTECTED;
160 if(access == ACCESS_PACKAGEINTERNAL) flags|=FLAG_PACKAGEINTERNAL;
161 if(access == ACCESS_NAMESPACE) {
162 if(!strcmp(m->ns->name, "http://adobe.com/AS3/2006/builtin")) {
163 flags|=FLAG_NAMESPACE_ADOBE;
169 void load_libraries(char*filename, int pass, FILE*fi)
172 memset(&swf, 0, sizeof(SWF));
173 TAG*tag = swf_InsertTag(0, ST_RAWABC);
174 memfile_t*file = memfile_open(filename);
175 tag->data = file->data;
176 tag->len = file->len;
177 abc_file_t*abc = swf_ReadABC(tag);
178 //swf_DumpABC(stdout, abc, "");
181 int*index = malloc(abc->classes->num*sizeof(int));
184 for(t=0;t<abc->classes->num;t++) {index[t]=t;}
185 qsort(index, abc->classes->num, sizeof(int), compare_classes);
188 const char*last_package = "-*-";
189 for(t=0;t<abc->classes->num;t++) {
190 abc_class_t*cls = array_getvalue(abc->classes, index[t]);
191 const char*package = cls->classname->ns->name;
192 char*pid = mkpid(package);
193 if(strcmp(last_package, package)) {
194 last_package = package;
195 fprintf(fi, "static packageinfo_t %s = {\"%s\"};\n", pid, package);
201 for(t=0;t<abc->classes->num;t++) {
202 abc_class_t*cls = array_getvalue(abc->classes, index[t]);
203 int access = cls->classname->ns->access;
204 if(access==ACCESS_PRIVATE ||
205 access==ACCESS_PACKAGEINTERNAL)
207 if(!strncmp(cls->classname->ns->name, "__AS3", 5))
210 const char*package = cls->classname->ns->name;
211 const char*name = cls->classname->name;
212 const char*superpackage = 0;
213 const char*supername = 0;
215 if(cls->superclass) {
216 superpackage = cls->superclass->ns->name;
217 supername = cls->superclass->name;
218 superid = mkid(superpackage, supername);
220 char*id = mkid(package, name);
221 U8 flags = cls->flags;
224 fprintf(fi, "static classinfo_t %s;\n", id);
226 fprintf(fi, "static classinfo_t %s = {0x%02x, 0x%02x, \"%s\", \"%s\"", id, access, flags, package, name);
227 fprintf(fi, ", 0"); //slot
229 fprintf(fi, ", &%s, interfaces:{", superid);
231 fprintf(fi, ", 0, {");
232 if(cls->interfaces) {
233 multiname_list_t*i=cls->interfaces;
235 char*iid = mkid2(i->multiname);
236 fprintf(fi, "&%s, ", iid);
240 fprintf(fi, "0}};\n");
242 trait_list_t*l=cls->traits;
243 fprintf(fi, " dict_put(d, &%s, &%s);\n", id, id);
244 fprintf(fi, " dict_init(&%s.members, %d);\n", id, list_length(l)+1);
250 dict_t*d = dict_new();
253 trait_t*trait = l->trait;
254 if(trait->name->ns->access==ACCESS_PRIVATE)
256 const char*name = trait->name->name;
258 sprintf(id2, "%s_%s", id, name);
260 if(dict_lookup(d, name)) {
263 dict_put(d, (char*)name, (char*)name);
265 int flags = is_static?FLAG_STATIC:0;
266 //flags |= access2flags(access);
267 flags |= access2flags(trait->name);
270 fprintf(fi, "static memberinfo_t %s;\n", id2);
272 write_member_info(fi, id, id2, name, flags, trait);
274 fprintf(fi, " dict_put(&%s.members, \"%s\", &%s);\n", id, name, id2);
278 if(!l && !is_static) {
279 l = cls->static_traits;
287 if(superid) free(superid);
292 if(pass==0 || pass==1 || pass==3) {
295 #define IS_PUBLIC_MEMBER(trait) ((trait)->kind != TRAIT_CLASS)
297 /* count public functions */
299 for(t=0;t<abc->scripts->num;t++) {
300 trait_list_t*l = ((abc_script_t*)array_getvalue(abc->scripts, t))->traits;
302 num_methods += IS_PUBLIC_MEMBER(l->trait);
305 trait_t**traits = (trait_t**)malloc(num_methods*sizeof(trait_t*));
307 for(t=0;t<abc->scripts->num;t++) {
308 trait_list_t*l = ((abc_script_t*)array_getvalue(abc->scripts, t))->traits;
310 if(IS_PUBLIC_MEMBER(l->trait)) {
311 traits[num_methods++] = l->trait;
315 qsort(traits, num_methods, sizeof(trait_t*), compare_traits);
316 const char*last_package = "-xxx-";
317 for(t=0;t<num_methods;t++) {
318 trait_t*trait = traits[t];
319 if(IS_PUBLIC_MEMBER(trait)) {
320 const char*package = trait->name->ns->name;
321 const char*name = trait->name->name;
322 char*pid = mkpid(package);
323 char*id2 = mkid2(trait->name);
324 int flags = FLAG_STATIC|access2flags(trait->name);
327 int clsflags = FLAG_STATIC | FLAG_METHOD;
329 fprintf(fi, "static memberinfo_t %s;\n", id2);
330 fprintf(fi, "static classinfo_t %s_class;\n", id2);
332 write_member_info(fi, 0, id2, name, flags, trait);
333 fprintf(fi, "static classinfo_t %s_class = {0x%02x, 0x%02x, \"%s\", \"%s\", &%s, 0, members:{0}};\n",
335 trait->name->ns->access, clsflags,
340 fprintf(fi, " dict_init(%s.classes, 1); //not used yet\n", pid);
341 fprintf(fi, " dict_init(%s.functions, 1);\n", pid);
343 fprintf(fi, " dict_put(&%s.functions, \"%s\", &%s);\n", pid, name, id2);*/
344 fprintf(fi, " dict_put(d, &%s_class, &%s_class);\n", id2, id2);
346 } else if(trait->kind == TRAIT_CLASS) {
347 // ignore classes, these are treated above
349 printf("%02x %s\n", trait->kind, multiname_tostring(trait->name));
355 memfile_close(file);tag->data=0;
356 swf_DeleteTag(0, tag);
361 FILE*fi = fopen("builtin.c", "wb");
362 fprintf(fi, "#include \"builtin.h\"\n");
364 //load_libraries("builtin.abc", -1, fi);
365 //load_libraries("playerglobal.abc", -1, fi);
366 //fprintf(fi, "static packageinfo_t package_flash_debugger = {\"flash.debugger\"};\n");
367 //fprintf(fi, "static packageinfo_t package_flash_profiler = {\"flash.profiler\"};\n");
369 load_libraries("builtin.abc", 0, fi);
370 load_libraries("playerglobal.abc", 0, fi);
372 load_libraries("builtin.abc", 1, fi);
373 load_libraries("playerglobal.abc", 1, fi);
375 fprintf(fi, "dict_t* builtin_getclasses()\n");
377 fprintf(fi, " dict_t*d = dict_new2(&classinfo_type);\n");
378 load_libraries("builtin.abc", 2, fi);
379 load_libraries("playerglobal.abc", 2, fi);
380 load_libraries("builtin.abc", 3, fi);
381 load_libraries("playerglobal.abc", 3, fi);
382 fprintf(fi, " return d;\n");
386 //fprintf(fi, "dict_t* builtin_getglobalfunctions()\n");
387 //fprintf(fi, "{\n");
388 //fprintf(fi, " dict_t*d = dict_new();\n");
389 //load_libraries("builtin.abc", 3, fi);
390 //load_libraries("playerglobal.abc", 3, fi);
391 //fprintf(fi, " return d;\n");
392 //fprintf(fi, "}\n");