- if(m->flags&0x08) {
- /* optional parameters */
- int num = swf_GetU30(tag);
- int s;
- for(s=0;s<num;s++) {
- int val = swf_GetU30(tag);
- U8 kind = swf_GetU8(tag); // specifies index type for "val"
- }
- }
- if(m->flags&0x80) {
- /* debug information- not used by avm2 */
- for(s=0;s<m->param_count;s++) {
- m->name = dict_getstr(pool->strings, swf_GetU30(tag));
- }
- }
- dict_append(pool->methods, m->name, m);
- }
-
- parse_metadata(tag, pool);
-
- /* skip classes, and scripts for now, and do the real parsing later */
- int num_classes = swf_GetU30(tag);
- int classes_pos = tag->pos;
- DEBUG printf("%d classes\n", num_classes);
- for(t=0;t<num_classes;t++) {
- abc_class_t*cls = malloc(sizeof(abc_class_t));
- memset(cls, 0, sizeof(abc_class_t));
- dict_append(pool->classes, 0, cls);
-
- DEBUG printf("class %d\n", t);
- swf_GetU30(tag); //classname
- swf_GetU30(tag); //supername
- cls->flags = swf_GetU8(tag);
- if(cls->flags&8)
- swf_GetU30(tag); //protectedNS
- int inum = swf_GetU30(tag); //interface count
- int s;
- for(s=0;s<inum;s++) {
- const char*interface = dict_getstr(pool->multinames, swf_GetU30(tag));
- DEBUG printf(" class %d interface: %s\n", t, interface);
- }
- cls->iinit = swf_GetU30(tag);
- cls->traits = traits_parse(tag, pool);
- }
- for(t=0;t<num_classes;t++) {
- abc_class_t*cls = (abc_class_t*)dict_getdata(pool->classes, t);
- cls->static_constructor_index = swf_GetU30(tag); // cinit
- cls->static_constructor_traits = traits_parse(tag, pool);
- }
- int num_scripts = swf_GetU30(tag);
- DEBUG printf("%d scripts\n", num_scripts);
- for(t=0;t<num_scripts;t++) {
- int init = swf_GetU30(tag);
- dict_t*traits = traits_parse(tag, pool); //TODO: store
- }
-
- int num_method_bodies = swf_GetU30(tag);
- DEBUG printf("%d method bodies\n", num_method_bodies);
- for(t=0;t<num_method_bodies;t++) {
- int methodnr = swf_GetU30(tag);
- if(methodnr >= pool->methods->num) {
- printf("Invalid method number: %d\n", methodnr);
- return 0;
- }
- abc_method_t*m = (abc_method_t*)dict_getdata(pool->methods, methodnr);
- abc_method_body_t*c = malloc(sizeof(abc_method_body_t));
- memset(c, 0, sizeof(abc_method_body_t));
- c->max_stack = swf_GetU30(tag);
- c->local_count = swf_GetU30(tag);
- c->init_scope_depth = swf_GetU30(tag);
- c->max_scope_depth = swf_GetU30(tag);
- int code_length = swf_GetU30(tag);
- c->method = m;
- m->method_body_index = t;
-
- c->tag = swf_InsertTag(0,0);
-
- swf_CopyData(c->tag, tag, code_length);
-
- int exception_count = swf_GetU30(tag);
- int s;
- for(s=0;s<exception_count;s++) {
- swf_GetU30(tag); //from
- swf_GetU30(tag); //to
- swf_GetU30(tag); //target
- swf_GetU30(tag); //exc_type
- swf_GetU30(tag); //var_name
- }
- c->traits = traits_parse(tag, pool);
- if(!c->traits) {
- fprintf(stderr, "Can't parse code traits\n");
- return 0;
- }
- DEBUG printf("method_body %d) (method %d), %d bytes of code", t, methodnr, code_length);
- int r,l = code_length>32?32:code_length;
- for(r=0;r<l;r++) {
- DEBUG printf("%02x ", c->tag->data[r]);
- }
- DEBUG printf("\n");
-
- dict_append(pool->method_bodies, 0, c);
- }
- if(tag->len - tag->pos) {
- fprintf(stderr, "%d unparsed bytes remaining in ABC block\n", tag->len - tag->pos);
- return 0;
- }
-
- swf_SetTagPos(tag, classes_pos);
- for(t=0;t<num_classes;t++) {
- abc_class_t*cls = (abc_class_t*)dict_getdata(pool->classes, t);
-
- cls->classname_index = swf_GetU30(tag);
- cls->superclass_index = swf_GetU30(tag);
- const char* classname = dict_getstr(pool->multinames, cls->classname_index);
- const char* supername = dict_getstr(pool->multinames, cls->superclass_index);
-
- cls->name = classname;
- cls->flags = swf_GetU8(tag);
- const char*ns = "";
- if(cls->flags&8) {
- cls->ns_index = swf_GetU30(tag);
- ns = dict_getstr(pool->namespaces, cls->ns_index);
- }
- /* TODO
-
- flags&01 = sealed
- flags&02 = final
- flags&04 = interface
- flags&08 = protectedNS
- */
- printf("class %s extends %s, %s, flags=%02x\n", classname, supername, ns, cls->flags);
- printf("{\n");
-
- dump_method(" ","staticconstructor", "", cls->static_constructor_index, pool);
- dump_traits(" ", cls->static_constructor_traits, pool);
-
- int num_interfaces = swf_GetU30(tag); //interface count
- int s;
- for(s=0;s<num_interfaces;s++) {
- swf_GetU30(tag); // multiname index TODO
- }
- cls->iinit = swf_GetU30(tag);
- dump_method(" ","constructor", classname, cls->iinit, pool);
- cls->traits = traits_parse(tag, pool);
- if(!cls->traits) {
- fprintf(stderr, "Can't parse class traits\n");
- return 0;
- }
- dump_traits(" ",cls->traits, pool);
-
- printf("}\n");
- }
- for(t=0;t<num_classes;t++) {
- /* SKIP */
- swf_GetU30(tag); // cindex
- traits_parse(tag, pool); // TODO: free
- }
- int num_scripts2 = swf_GetU30(tag);
- printf("\n");
- for(t=0;t<num_scripts2;t++) {
- int init = swf_GetU30(tag);
- abc_method_t*m = (abc_method_t*)dict_getdata(pool->methods, init);
-
- abc_script_t*s = malloc(sizeof(abc_script_t));
- memset(s, 0, sizeof(abc_script_t));
- s->method = m;
- s->traits = traits_parse(tag, pool);
- dict_append(pool->scripts, 0, s);
- if(!s->traits) {
- fprintf(stderr, "Can't parse script traits\n");
- return 0;
- }
- dump_method("","initmethod", "init", init, pool);
- dump_traits("", s->traits, pool);
- }
- return pool;
-}
-
-static int registerNameSpace(abc_file_t*file, U8 access, char*name) {
- if(access==0) { // autodetect access
- char*n = strdup(name);
- if(n[0] == '[') {
- char*bracket = strchr(n, ']');
- if(bracket) {
- *bracket = 0;
- char*a = n+1;
- name += (bracket-n)+1;
- if(!strcmp(a, "")) access=0x16;
- else if(!strcmp(a, "package")) access=0x16;
- else if(!strcmp(a, "packageinternal")) access=0x17;
- else if(!strcmp(a, "protected")) access=0x18;
- else if(!strcmp(a, "explicit")) access=0x19;
- else if(!strcmp(a, "staticprotected")) access=0x1a;
- else if(!strcmp(a, "private")) access=0x05;
- else {
- fprintf(stderr, "Undefined access level: [%s]\n", a);
- return -1;
- }
- }
- } else {
- access = 0x16;
- }
- free(n);
- }
- int t;
- for(t=0;t<file->namespaces->num;t++) {
- const char*name2 = dict_getstr(file->namespaces, t);
- U8 access2 = (U8)(ptroff_t)dict_getdata(file->namespaces, t);
- if(access == access2 && !strcmp(name, name2)) {
- return t;
- }
- }
- dict_update(file->strings, name, 0);
- return dict_append(file->namespaces, name, (void*)(ptroff_t)access);
-}
-int abc_RegisterNameSpace(abc_file_t*file, char*name) {
- return registerNameSpace(file, 0x08, name);
-}
-int abc_RegisterPackageNameSpace(abc_file_t*file, char*name) {
- return registerNameSpace(file, 0x16 , name);
-}
-int abc_RegisterPackageInternalNameSpace(abc_file_t*file, char*name) {
- return registerNameSpace(file, 0x17, name);
-}
-int abc_RegisterProtectedNameSpace(abc_file_t*file, char*name) {
- return registerNameSpace(file, 0x18, name);
-}
-int abc_RegisterExplicitNameSpace(abc_file_t*file, char*name) {
- return registerNameSpace(file, 0x19, name);
-}
-int abc_RegisterStaticProtectedNameSpace(abc_file_t*file, char*name) {
- return registerNameSpace(file, 0x1a, name);