From 4b4a2c8042c0f274978ca8e89d2fa3b87ffae371 Mon Sep 17 00:00:00 2001 From: kramm Date: Fri, 2 Jan 2009 19:47:35 +0000 Subject: [PATCH] store global functions as classes, too --- lib/as3/mklib.c | 366 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 243 insertions(+), 123 deletions(-) diff --git a/lib/as3/mklib.c b/lib/as3/mklib.c index 98d54cd..1a90eb8 100644 --- a/lib/as3/mklib.c +++ b/lib/as3/mklib.c @@ -42,6 +42,17 @@ void fixstring(char*s) } } +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; +} char* mkid(const char*package, const char*name) { char*id = malloc(strlen(package)+strlen(name)+10); @@ -84,10 +95,65 @@ static int compare_classes(const void*v1, const void*v2) return strcmp(c1->classname->name, c2->classname->name); } +static int compare_traits(const void*v1, const void*v2) +{ + 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); +} + char* kind2string(int kind) { } +void write_member_info(FILE*fi, 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; + + 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 = "MEMBER_METHOD"; + break; + case TRAIT_CONST: + case TRAIT_GETTER: + case TRAIT_SETTER: + case TRAIT_SLOT: + type = "MEMBER_SLOT"; + break; + default: + fprintf(stderr, "Unknown trait type %d\n", trait->kind); + } + fprintf(fi, "static memberinfo_t %s = {%s, 0x%02x, \"%s\"", id2, type, flags, name); + if(!retvalue) + fprintf(fi, ", 0"); + else + fprintf(fi, ", &%s", retvalue); + fprintf(fi, "};\n"); +} + +int access2flags(int access) +{ + int flags=0; + if(access == ACCESS_PACKAGE) flags|=FLAG_PUBLIC; + if(access == ACCESS_PRIVATE) flags|=FLAG_PRIVATE; + if(access == ACCESS_PROTECTED) flags|=FLAG_PROTECTED; + if(access == ACCESS_PACKAGEINTERNAL) flags|=FLAG_INTERNAL; + return flags; +} + void load_libraries(char*filename, int pass, FILE*fi) { SWF swf; @@ -99,143 +165,179 @@ void load_libraries(char*filename, int pass, FILE*fi) 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; + if(pass<=2) { + 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); - 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, ", 0"); //slot - 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; + 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); } } - 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); } - - trait_list_t*l=0; - char is_static = 0; - dict_t*d = dict_new(); - l = cls->traits; - 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); - char*retvalue = 0; + 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; - if(dict_lookup(d, name)) { - goto cont; - } else { - dict_put(d, (char*)name, (char*)name); - } - char*type="0"; - switch(trait->kind) { - case TRAIT_METHOD: { - multiname_t*ret = trait->method->return_type; - 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 = "MEMBER_METHOD"; - break; - case TRAIT_CONST: - case TRAIT_GETTER: - case TRAIT_SETTER: - case TRAIT_SLOT: - type = "MEMBER_SLOT"; - break; - default: - fprintf(stderr, "Unknown trait type %d\n", trait->kind); + 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); } - int flags = is_static?FLAG_STATIC:0; - - if(access == ACCESS_PACKAGE) flags|=FLAG_PUBLIC; - if(access == ACCESS_PRIVATE) flags|=FLAG_PRIVATE; - if(access == ACCESS_PROTECTED) flags|=FLAG_PROTECTED; - if(access == ACCESS_PACKAGEINTERNAL) flags|=FLAG_INTERNAL; - - if(pass==0) { - fprintf(fi, "static memberinfo_t %s;\n", id2); - } if(pass==1) { - fprintf(fi, "static memberinfo_t %s = {%s, 0x%02x, \"%s\"", id2, type, flags, name); - if(!retvalue) - fprintf(fi, ", 0"); + 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, ", 0"); //slot + if(superid) + fprintf(fi, ", &%s, interfaces:{", superid); else - fprintf(fi, ", &%s", retvalue); - fprintf(fi, "};\n"); + 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) { - fprintf(fi, " dict_put(&%s.members, \"%s\", &%s);\n", id, name, id2); + 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); } -cont: - l = l->next; - if(!l && !is_static) { - l = cls->static_traits; - is_static = 1; + + + trait_list_t*l=0; + char is_static = 0; + dict_t*d = dict_new(); + l = cls->traits; + 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->ns->access); + + if(pass==0) { + fprintf(fi, "static memberinfo_t %s;\n", id2); + } if(pass==1) { + write_member_info(fi, id2, name, flags, trait); + } else if(pass==2) { + fprintf(fi, " dict_put(&%s.members, \"%s\", &%s);\n", id, name, id2); + } + cont: + l = l->next; + if(!l && !is_static) { + l = cls->static_traits; + is_static = 1; + } } - } - - dict_destroy(d); + + dict_destroy(d); - if(id) free(id); - if(superid) free(superid); - } - - for(t=0;tscripts->num;t++) { - abc_script_t*s = array_getvalue(abc->scripts, t); - trait_list_t*l=0; - for(l=s->traits;l;l=l->next) { - trait_t*trait = l->trait; - if(trait->kind == TRAIT_METHOD) { - printf("%s\n", multiname_tostring(trait->name)); - } - } + if(id) free(id); + if(superid) free(superid); + } + free(index); } + if(pass==0 || pass==1 || pass==3) { + int t; + +#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; + } + } + } + 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->ns->access); + NEW(memberinfo_t,m); + char np = 0; + int clsflags = FLAG_STATIC | FLAG_METHOD; + 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, id2, name, flags, trait); + fprintf(fi, "static classinfo_t %s_class = {0x%02x, 0x%02x, \"%s\", \"%s\", &%s, 0, members:{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)); + } + } + } swf_FreeABC(abc); memfile_close(file);tag->data=0; @@ -246,6 +348,12 @@ int main() { 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"); + load_libraries("builtin.abc", 0, fi); load_libraries("playerglobal.abc", 0, fi); @@ -257,7 +365,19 @@ int main() fprintf(fi, " dict_t*d = dict_new2(&classinfo_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); 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); } -- 1.7.10.4