X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fas3%2Fmklib.c;h=1d186b48f9e6425cbf656bc68d5949c6fbe3974d;hb=d2bcd477230b4ac8d7e69fc253d94250b13eb37a;hp=e67df89efbdb020001e40211ac9c2ed9f6175417;hpb=64d4105a9226d5a78ea2da83549f7708d768c7bd;p=swftools.git diff --git a/lib/as3/mklib.c b/lib/as3/mklib.c index e67df89..1d186b4 100644 --- a/lib/as3/mklib.c +++ b/lib/as3/mklib.c @@ -24,10 +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) { @@ -41,7 +44,18 @@ void fixstring(char*s) } } -char* mkid(const char*package, const char*name) +static char* mkpid(const char*package) +{ + char*id = malloc(strlen(package)+20); + strcpy(id, "package_"); + if(!*package) + strcat(id, "global"); + else + strcat(id, package); + fixstring(id); + return id; +} +static char* mkcid(const char*package, const char*name) { char*id = malloc(strlen(package)+strlen(name)+10); strcpy(id, package); @@ -50,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) @@ -83,142 +99,179 @@ static int compare_classes(const void*v1, const void*v2) return strcmp(c1->classname->name, c2->classname->name); } -void load_libraries(char*filename, int pass, FILE*fi) +static int compare_traits(const void*v1, const void*v2) { - 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, ""); - - int*index = malloc(abc->classes->num*sizeof(int)); - int t; - tosort=abc->classes; - for(t=0;tclasses->num;t++) {index[t]=t;} - qsort(index, abc->classes->num, sizeof(int), compare_classes); - - 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); - - if(pass==0) - fprintf(fi, "static class_signature_t %s;\n", id); - else if(pass==1) { - fprintf(fi, "static class_signature_t %s = {0x%02x, \"%s\", \"%s\"", id, access, package, name); - if(superid) - fprintf(fi, ", &%s, interfaces:{", superid); - else - fprintf(fi, ", 0, {"); - 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, "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); - int j; - dict_t*d = dict_new(); - for(;l;l=l->next) { - trait_t*trait = l->trait; - if(trait->name->ns->access==ACCESS_PRIVATE) - continue; - char*type="something"; - const char*name = trait->name->name; - if(dict_lookup(d, name)) { - continue; - } else { - dict_put(d, (char*)name, (char*)name); - } - switch(trait->kind) { - case TRAIT_METHOD: type="method";break; - case TRAIT_CONST: type="const";break; - case TRAIT_FUNCTION: type="function";break; - case TRAIT_GETTER: type="member";break; - case TRAIT_SETTER: type="member";break; - case TRAIT_SLOT: type="member";break; - case TRAIT_CLASS: type="subclass";break; - } - fprintf(fi, " dict_put(&%s.members, \"%s\", \"%s\");\n", - id, name, type); + trait_t* x1 = *(trait_t**)v1; + trait_t* x2 = *(trait_t**)v2; + int i = strcmp(x1->name->ns->name, x2->name->ns->name); + if(i) + return i; + return strcmp(x1->name->name, x2->name->name); +} + +dict_t* builtin_getclasses() +{ + return dict_new2(&slotinfo_type); +} + +extern dict_t*registry_classes; + +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"; + } +} + +void write_slotinfo(FILE*fi, slotinfo_t*s, char*id, char*prefix); + +void write_slotinfo_decl(FILE*fi, slotinfo_t*s, char*prefix) +{ + fprintf(fi, "%s", prefix); + char*id = mkid(s); + fprintf(fi, "static %s %s;\n", mktype(s), id); + + 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; + fprintf(fi, "static %s %s;\n", mktype(s2), mkid2(id, s2->name)); + l = l->next; } - l=cls->static_traits; - for(;l;l=l->next) { - trait_t*trait = l->trait; - if(trait->name->ns->access==ACCESS_PRIVATE) - continue; - char*type="static entity"; - const char*name = trait->name->name; - if(dict_lookup(d, name)) { - continue; - } else { - dict_put(d, (char*)name, (char*)name); - } - switch(trait->kind) { - case TRAIT_METHOD: type="static method";break; - case TRAIT_CONST: type="constant";break; - case TRAIT_FUNCTION: type="static function";break; - case TRAIT_GETTER: type="static variable";break; - case TRAIT_SETTER: type="static variable";break; - case TRAIT_SLOT: type="static variable";break; - case TRAIT_CLASS: type="static subclass";break; - } - fprintf(fi, " dict_put(&%s.members, \"%s\", \"%s\");\n", - id, name, type); + } + } +} +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) { + 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; } - dict_destroy(d); } - - if(id) free(id); - if(superid) free(superid); } +} +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, "); + + fprintf(fi, "%d, ", s->slot); - swf_FreeABC(abc); - memfile_close(file);tag->data=0; - swf_DeleteTag(0, tag); + 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, ", "); + } + 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; + } + } + } } 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", 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(&class_signature_type);\n"); - load_libraries("builtin.abc", 2, fi); - load_libraries("playerglobal.abc", 2, fi); + + int t; + int pass; + + + 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"); - fclose(fi); + }