X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fas3%2Fmklib.c;h=1d186b48f9e6425cbf656bc68d5949c6fbe3974d;hb=d2bcd477230b4ac8d7e69fc253d94250b13eb37a;hp=8ef8fe7669f7d153006f51dc753fb5d638113d50;hpb=eeacf7371f20fb0413e8964bbeea6f682ad47742;p=swftools.git diff --git a/lib/as3/mklib.c b/lib/as3/mklib.c index 8ef8fe7..1d186b4 100644 --- a/lib/as3/mklib.c +++ b/lib/as3/mklib.c @@ -24,11 +24,13 @@ #include #include "../rfxswf.h" #include "../os.h" +#include "../q.h" #include "pool.h" #include "files.h" #include "tokenizer.h" #include "parser.tab.h" #include "parser.h" +#include "import.h" void fixstring(char*s) { @@ -42,7 +44,7 @@ void fixstring(char*s) } } -char* mkpid(const char*package) +static char* mkpid(const char*package) { char*id = malloc(strlen(package)+20); strcpy(id, "package_"); @@ -53,7 +55,7 @@ char* mkpid(const char*package) fixstring(id); return id; } -char* mkid(const char*package, const char*name) +static char* mkcid(const char*package, const char*name) { char*id = malloc(strlen(package)+strlen(name)+10); strcpy(id, package); @@ -62,25 +64,27 @@ char* mkid(const char*package, const char*name) fixstring(id); return id; } - -char*mkid2(multiname_t*m) +static char* mkptr2(const char*package, const char*name) { - if(m->type == QNAME) - return mkid(m->ns->name, m->name); - else if(m->type == MULTINAME) { - namespace_list_t*l = m->namespace_set->namespaces; - while(l) { - if(l->namespace->name && - l->namespace->name[0]) - break; - l = l->next; - } - return mkid(l->namespace->name, m->name); - } - else { - fprintf(stderr, "can't convert multiname type %d\n", m->type); - } + char*id = malloc(strlen(package)+strlen(name)+10); + strcpy(id, "&"); + strcat(id, package); + strcat(id, "_"); + strcat(id, name); + fixstring(id+1); + return id; } +static char* mkid2(const char*cls, const char*member) +{ + char*id = malloc(strlen(cls)+strlen(member)+10); + strcpy(id, cls); + strcat(id, "_"); + strcat(id, member); + fixstring(id); + return id; +} +#define mkid(s) ((s)?mkcid((s)->package, (s)->name):"0") +#define mkptr(s) ((s)?mkptr2((s)->package, (s)->name):"0") static array_t*tosort=0; static int compare_classes(const void*v1, const void*v2) @@ -105,282 +109,169 @@ static int compare_traits(const void*v1, const void*v2) return strcmp(x1->name->name, x2->name->name); } -char* kind2string(int kind) +dict_t* builtin_getclasses() { + return dict_new2(&slotinfo_type); } -void write_member_info(FILE*fi, char*parent, char*id2, const char*name, int flags, trait_t*trait) -{ - char*retvalue = 0; - char*type="0"; - switch(trait->kind) { - case TRAIT_METHOD: { - multiname_t*ret = trait->method->return_type; +extern dict_t*registry_classes; - if(!ret) - retvalue = 0; - else - retvalue = mkid(ret->ns->name, ret->name); - if(ret && !strcmp(ret->name, "void")) - retvalue = 0; - } //fallthrough - case TRAIT_FUNCTION: - type = "INFOTYPE_METHOD"; - break; - case TRAIT_CONST: - case TRAIT_GETTER: - case TRAIT_SETTER: - case TRAIT_SLOT: - type = "INFOTYPE_SLOT"; - break; - default: - fprintf(stderr, "Unknown trait type %d\n", trait->kind); +char*mktype(slotinfo_t*s) +{ + if(s->kind == INFOTYPE_CLASS) { + return "classinfo_t"; + } else if(s->kind == INFOTYPE_METHOD) { + return "methodinfo_t"; + } else if(s->kind == INFOTYPE_SLOT) { + return "varinfo_t"; } - fprintf(fi, "static memberinfo_t %s = {%s, 0x%02x, \"%s\"", type, flags, id2, name); - if(!retvalue) - fprintf(fi, ", 0"); - else - fprintf(fi, ", &%s", retvalue); - - if(!parent) - fprintf(fi, ", 0"); - else - fprintf(fi, ", &%s", parent); // parent - - fprintf(fi, ", 0,0,0};\n"); } -int access2flags(multiname_t*m) -{ - int access = m->ns->access; - int flags=0; - return flags; -} +void write_slotinfo(FILE*fi, slotinfo_t*s, char*id, char*prefix); -void load_libraries(char*filename, int pass, FILE*fi) +void write_slotinfo_decl(FILE*fi, slotinfo_t*s, char*prefix) { - SWF swf; - memset(&swf, 0, sizeof(SWF)); - TAG*tag = swf_InsertTag(0, ST_RAWABC); - memfile_t*file = memfile_open(filename); - tag->data = file->data; - tag->len = file->len; - abc_file_t*abc = swf_ReadABC(tag); - //swf_DumpABC(stdout, abc, ""); + fprintf(fi, "%s", prefix); + char*id = mkid(s); + fprintf(fi, "static %s %s;\n", mktype(s), id); - if(pass<=2) { - int*index = malloc(abc->classes->num*sizeof(int)); + if(s->kind == INFOTYPE_CLASS) { + classinfo_t*c = (classinfo_t*)s; + dict_t*d = &c->members; int t; - tosort=abc->classes; - for(t=0;tclasses->num;t++) {index[t]=t;} - qsort(index, abc->classes->num, sizeof(int), compare_classes); - - if(pass==-1) { - const char*last_package = "-*-"; - for(t=0;tclasses->num;t++) { - abc_class_t*cls = array_getvalue(abc->classes, index[t]); - const char*package = cls->classname->ns->name; - char*pid = mkpid(package); - if(strcmp(last_package, package)) { - last_package = package; - fprintf(fi, "static packageinfo_t %s = {\"%s\"};\n", pid, package); - } + for(t=0;thashsize;t++) { + dictentry_t*l = d->slots[t]; + while(l) { + slotinfo_t*s2 = (slotinfo_t*)l->data; + fprintf(fi, "static %s %s;\n", mktype(s2), mkid2(id, s2->name)); + l = l->next; } } - - if(pass>=0) - for(t=0;tclasses->num;t++) { - abc_class_t*cls = array_getvalue(abc->classes, index[t]); - int access = cls->classname->ns->access; - if(access==ACCESS_PRIVATE || - access==ACCESS_PACKAGEINTERNAL) - continue; - if(!strncmp(cls->classname->ns->name, "__AS3", 5)) - continue; - - const char*package = cls->classname->ns->name; - const char*name = cls->classname->name; - const char*superpackage = 0; - const char*supername = 0; - char*superid = 0; - if(cls->superclass) { - superpackage = cls->superclass->ns->name; - supername = cls->superclass->name; - superid = mkid(superpackage, supername); - } - char*id = mkid(package, name); - U8 flags = cls->flags; - - if(pass==0) { - fprintf(fi, "static classinfo_t %s;\n", id); - } else if(pass==1) { - fprintf(fi, "static classinfo_t %s = {0x%02x, 0x%02x, \"%s\", \"%s\"", id, access, flags, package, name); - fprintf(fi, ", (void*)0"); //slot - if(superid) - fprintf(fi, ", &%s, interfaces:{", superid); - else - fprintf(fi, ", (void*)0, interfaces:{"); - if(cls->interfaces) { - multiname_list_t*i=cls->interfaces; - while(i) { - char*iid = mkid2(i->multiname); - fprintf(fi, "&%s, ", iid); - i = i->next; - } - } - fprintf(fi, "(void*)0}};\n"); - } else if(pass==2) { - trait_list_t*l=cls->traits; - fprintf(fi, " dict_put(d, &%s, &%s);\n", id, id); - fprintf(fi, " dict_init(&%s.members, %d);\n", id, list_length(l)+1); - } - - - trait_list_t*l=0; - char is_static = 0; - dict_t*d = dict_new(); - l = cls->traits; + } +} +void write_initinfo(FILE*fi, slotinfo_t*s, char*prefix) +{ + if(s->kind == INFOTYPE_CLASS) { + classinfo_t*c = (classinfo_t*)s; + fprintf(fi, "%s", prefix); + char*id = mkid(c); + dict_t*d = &c->members; + fprintf(fi, "dict_init(&%s.members, %d);\n", id, d->hashsize); + int t; + for(t=0;thashsize;t++) { + dictentry_t*l = d->slots[t]; while(l) { - trait_t*trait = l->trait; - if(trait->name->ns->access==ACCESS_PRIVATE) - goto cont; - const char*name = trait->name->name; - char id2[1024]; - sprintf(id2, "%s_%s", id, name); - - if(dict_lookup(d, name)) { - goto cont; - } else { - dict_put(d, (char*)name, (char*)name); - } - int flags = is_static?FLAG_STATIC:0; - //flags |= access2flags(access); - flags |= access2flags(trait->name); - - if(pass==0) { - fprintf(fi, "static memberinfo_t %s;\n", id2); - } if(pass==1) { - write_member_info(fi, id, id2, name, flags, trait); - } else if(pass==2) { - fprintf(fi, " dict_put(&%s.members, \"%s\", &%s);\n", id, name, id2); - } - cont: + slotinfo_t*s2 = (slotinfo_t*)l->data; + fprintf(fi, "%s", prefix); + fprintf(fi, "dict_put(&%s.members, \"%s\", &%s);\n", id, s2->name, mkid2(id, s2->name)); l = l->next; - if(!l && !is_static) { - l = cls->static_traits; - is_static = 1; - } } - - dict_destroy(d); - - if(id) free(id); - if(superid) free(superid); } - free(index); } +} +void write_slotinfo(FILE*fi, slotinfo_t*s, char*id, char*prefix) +{ + fprintf(fi, "%s", prefix); + fprintf(fi, "static %s %s = {", mktype(s), id); + fprintf(fi, "0x%02x, 0x%02x, 0x%02x, 0x%02x, ", s->kind, s->subtype, s->flags, s->access); + if(s->package) + fprintf(fi, "\"%s\", ", s->package); + else + fprintf(fi, "0, "); + + if(s->name) + fprintf(fi, "\"%s\", ", s->name); + else + fprintf(fi, "0, "); - if(pass==0 || pass==1 || pass==3) { - int t; + fprintf(fi, "%d, ", s->slot); -#define IS_PUBLIC_MEMBER(trait) ((trait)->kind != TRAIT_CLASS) - - /* count public functions */ - int num_methods=0; - for(t=0;tscripts->num;t++) { - trait_list_t*l = ((abc_script_t*)array_getvalue(abc->scripts, t))->traits; - for(;l;l=l->next) { - num_methods += IS_PUBLIC_MEMBER(l->trait); - } - } - trait_t**traits = (trait_t**)malloc(num_methods*sizeof(trait_t*)); - num_methods=0; - for(t=0;tscripts->num;t++) { - trait_list_t*l = ((abc_script_t*)array_getvalue(abc->scripts, t))->traits; - for(;l;l=l->next) { - if(IS_PUBLIC_MEMBER(l->trait)) { - traits[num_methods++] = l->trait; - } - } + if(s->kind == INFOTYPE_CLASS) { + classinfo_t*c = (classinfo_t*)s; + fprintf(fi, "%s, ", mkptr(c->superclass)); + fprintf(fi, "interfaces: {"); + int t; + for(t=0;c->interfaces[t];t++) { + fprintf(fi, "%c", mkptr(c->interfaces[t])); + if(c->interfaces[t+1]) + fprintf(fi, ", "); } - qsort(traits, num_methods, sizeof(trait_t*), compare_traits); - const char*last_package = "-xxx-"; - for(t=0;tname->ns->name; - const char*name = trait->name->name; - char*pid = mkpid(package); - char*id2 = mkid2(trait->name); - int flags = FLAG_STATIC|access2flags(trait->name); - NEW(memberinfo_t,m); - char np = 0; - int clsflags = FLAG_STATIC; - if(pass==0) { - fprintf(fi, "static memberinfo_t %s;\n", id2); - fprintf(fi, "static classinfo_t %s_class;\n", id2); - } else if(pass==1) { - write_member_info(fi, 0, id2, name, flags, trait); - fprintf(fi, "static classinfo_t %s_class = {0x%02x, 0x%02x, \"%s\", \"%s\", &%s, (void*)0, members:{(void*)0}};\n", - id2, - trait->name->ns->access, clsflags, - package, name, - id2); - } else if(pass==3) { - /*if(np) { - fprintf(fi, " dict_init(%s.classes, 1); //not used yet\n", pid); - fprintf(fi, " dict_init(%s.functions, 1);\n", pid); - } - fprintf(fi, " dict_put(&%s.functions, \"%s\", &%s);\n", pid, name, id2);*/ - fprintf(fi, " dict_put(d, &%s_class, &%s_class);\n", id2, id2); - } - } else if(trait->kind == TRAIT_CLASS) { - // ignore classes, these are treated above - } else { - printf("%02x %s\n", trait->kind, multiname_tostring(trait->name)); + fprintf(fi, "0}};\n"); + } + if(s->kind == INFOTYPE_METHOD) { + methodinfo_t*m = (methodinfo_t*)s; + fprintf(fi, "%s, ", mkptr(m->return_type)); + fprintf(fi, "%s, ", mkptr(m->parent)); + fprintf(fi, "0"); // params TODO + fprintf(fi, "};\n"); + } + if(s->kind == INFOTYPE_SLOT) { + varinfo_t*m = (varinfo_t*)s; + fprintf(fi, "%s, ", mkptr(m->type)); + fprintf(fi, "%s, ", mkptr(m->parent)); + fprintf(fi, "0"); // value TODO + fprintf(fi, "};\n"); + } + + if(s->kind == INFOTYPE_CLASS) { + classinfo_t*c = (classinfo_t*)s; + dict_t*d = &c->members; + int t; + for(t=0;thashsize;t++) { + dictentry_t*l = d->slots[t]; + while(l) { + slotinfo_t*s2 = (slotinfo_t*)l->data; + write_slotinfo(fi, s2, mkid2(id,s2->name), prefix); + l = l->next; } } } - - swf_FreeABC(abc); - memfile_close(file);tag->data=0; - swf_DeleteTag(0, tag); } int main() { + registry_classes = builtin_getclasses(); + + as3_import_abc("/home/kramm/c/swftools/lib/as3/builtin.abc"); + as3_import_abc("/home/kramm/c/swftools/lib/as3/playerglobal.abc"); + FILE*fi = fopen("builtin.c", "wb"); - fprintf(fi, "#include \"builtin.h\"\n"); - //load_libraries("builtin.abc", -1, fi); - //load_libraries("playerglobal.abc", -1, fi); - //fprintf(fi, "static packageinfo_t package_flash_debugger = {\"flash.debugger\"};\n"); - //fprintf(fi, "static packageinfo_t package_flash_profiler = {\"flash.profiler\"};\n"); + int t; + int pass; - load_libraries("builtin.abc", 0, fi); - load_libraries("playerglobal.abc", 0, fi); - - load_libraries("builtin.abc", 1, fi); - load_libraries("playerglobal.abc", 1, fi); - - fprintf(fi, "dict_t* builtin_getclasses()\n"); - fprintf(fi, "{\n"); - fprintf(fi, " dict_t*d = dict_new2(&slotinfo_type);\n"); - load_libraries("builtin.abc", 2, fi); - load_libraries("playerglobal.abc", 2, fi); - load_libraries("builtin.abc", 3, fi); - load_libraries("playerglobal.abc", 3, fi); + + for(pass=1;pass<=3;pass++) { + if(pass==1) { + fprintf(fi, "#include \"builtin.h\"\n"); + fprintf(fi, "\n"); + } + if(pass==3) { + fprintf(fi, "dict_t* builtin_getclasses()\n"); + fprintf(fi, "{\n"); + fprintf(fi, " dict_t*d = dict_new2(&slotinfo_type);\n"); + } + for(t=0;thashsize;t++) { + dictentry_t*l = registry_classes->slots[t]; + while(l) { + slotinfo_t*s = (slotinfo_t*)l->key; + //printf("%08x %s %s\n", s, s->package, s->name); + char*id = mkid(s); + if(pass==1) { + write_slotinfo_decl(fi, s, ""); + } + if(pass==2) { + write_slotinfo(fi, s, mkid(s), ""); + } + if(pass==3) { + fprintf(fi, " dict_put(d, &%s, &%s);\n", id, id); + write_initinfo(fi, s, " "); + } + l = l->next; + } + } + } fprintf(fi, " return d;\n"); fprintf(fi, "}\n"); - fprintf(fi, "\n"); - - //fprintf(fi, "dict_t* builtin_getglobalfunctions()\n"); - //fprintf(fi, "{\n"); - //fprintf(fi, " dict_t*d = dict_new();\n"); - //load_libraries("builtin.abc", 3, fi); - //load_libraries("playerglobal.abc", 3, fi); - //fprintf(fi, " return d;\n"); - //fprintf(fi, "}\n"); - fclose(fi); }