X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fas3%2Fabc.c;h=5c9b87b51d95a3880cf95ec70871ae21d4088d60;hb=70080bc309ba2a414647d27e2f413f22bc7823e4;hp=f44a0909e8e846790b1b1bb3948b8eafa8dfd364;hpb=0e36e7af23c9e55097f02f3cac55df6da3f18c9b;p=swftools.git diff --git a/lib/as3/abc.c b/lib/as3/abc.c index f44a090..5c9b87b 100644 --- a/lib/as3/abc.c +++ b/lib/as3/abc.c @@ -129,19 +129,14 @@ abc_file_t*abc_file_new() return f; } -#define CLASS_SEALED 1 -#define CLASS_FINAL 2 -#define CLASS_INTERFACE 4 -#define CLASS_PROTECTED_NS 8 - abc_class_t* abc_class_new(abc_file_t*file, multiname_t*classname, multiname_t*superclass) { NEW(abc_class_t,c); array_append(file->classes, NO_KEY, c); c->file = file; - c->classname = classname; - c->superclass = superclass; + c->classname = multiname_clone(classname); + c->superclass = multiname_clone(superclass); c->flags = 0; c->constructor = 0; c->static_constructor = 0; @@ -172,7 +167,7 @@ void abc_class_protectedNS(abc_class_t*c, char*namespace) } void abc_class_add_interface(abc_class_t*c, multiname_t*interface) { - list_append(c->interfaces, interface); + list_append(c->interfaces, multiname_clone(interface)); } abc_method_body_t* add_method(abc_file_t*file, abc_class_t*cls, multiname_t*returntype, int num_params, va_list va) @@ -269,14 +264,15 @@ abc_method_body_t* abc_class_method(abc_class_t*cls, multiname_t*returntype, cha return c; } -void abc_AddSlot(abc_class_t*cls, char*name, int slot, char*type) +trait_t* abc_class_slot(abc_class_t*cls, char*name, multiname_t*type) { abc_file_t*file = cls->file; multiname_t*m_name = multiname_fromstring(name); - multiname_t*m_type = multiname_fromstring(type); + multiname_t*m_type = type; trait_t*t = trait_new_member(m_type, m_name, 0); t->slot_id = list_length(cls->traits); list_append(cls->traits, t); + return t; } void abc_method_body_addClassTrait(abc_method_body_t*code, char*multiname, int slotid, abc_class_t*cls) @@ -689,7 +685,7 @@ void* swf_ReadABC(TAG*tag) m->flags = swf_GetU8(tag); - DEBUG printf("method %d) %s flags=%02x\n", t, params_tostring(m->parameters), m->flags); + DEBUG printf("method %d) %s %s flags=%02x\n", t, m->name, params_tostring(m->parameters), m->flags); if(m->flags&0x08) { /* TODO optional parameters */ @@ -724,13 +720,13 @@ void* swf_ReadABC(TAG*tag) abc_class_t*cls = malloc(sizeof(abc_class_t)); memset(cls, 0, sizeof(abc_class_t)); - DEBUG printf("class %d\n", t); swf_GetU30(tag); //classname swf_GetU30(tag); //supername array_append(file->classes, NO_KEY, cls); cls->flags = swf_GetU8(tag); + DEBUG printf("class %d %02x\n", t, cls->flags); if(cls->flags&8) swf_GetU30(tag); //protectedNS int s; @@ -743,12 +739,14 @@ void* swf_ReadABC(TAG*tag) DEBUG printf(" class %d interface: %s\n", t, m->name); } - swf_GetU30(tag); //iinit + int iinit = swf_GetU30(tag); //iinit + DEBUG printf("--iinit-->%d\n", iinit); traits_skip(tag); } for(t=0;tclasses, t); int cinit = swf_GetU30(tag); + DEBUG printf("--cinit(%d)-->%d\n", t, cinit); cls->static_constructor = (abc_method_t*)array_getvalue(file->methods, cinit); traits_skip(tag); } @@ -790,7 +788,7 @@ void* swf_ReadABC(TAG*tag) int s; c->exceptions = list_new(); for(s=0;sfrom = code_atposition(codelookup, swf_GetU30(tag)); e->to = code_atposition(codelookup, swf_GetU30(tag)); @@ -805,7 +803,7 @@ void* swf_ReadABC(TAG*tag) codelookup_free(codelookup); c->traits = traits_parse(tag, pool, file); - DEBUG printf("method_body %d) (method %d), %d bytes of code", t, methodnr, code_length); + DEBUG printf("method_body %d) (method %d), %d bytes of code\n", t, methodnr, code_length); array_append(file->method_bodies, NO_KEY, c); } @@ -832,7 +830,7 @@ void* swf_ReadABC(TAG*tag) int num_interfaces = swf_GetU30(tag); //interface count int s; for(s=0;sconstructor = (abc_method_t*)array_getvalue(file->methods, iinit); @@ -868,36 +866,31 @@ void swf_WriteABC(TAG*abctag, void*code) TAG*tmp = swf_InsertTag(0,0); TAG*tag = tmp; int t; - - char need_null_method=0; + + /* add method bodies where needed */ for(t=0;tclasses->num;t++) { abc_class_t*c = (abc_class_t*)array_getvalue(file->classes, t); - if(!c->constructor || !c->static_constructor) { - need_null_method=1; - break; + if(!c->constructor) { + if(!(c->flags&CLASS_INTERFACE)) { + NEW(abc_method_t,m);array_append(file->methods, NO_KEY, m); + NEW(abc_method_body_t,body);array_append(file->method_bodies, NO_KEY, body); + body->method = m; m->body = body; + __ returnvoid(body); + c->constructor = m; + } else { + NEW(abc_method_t,m);array_append(file->methods, NO_KEY, m); + c->constructor = m; + } + } + if(!c->static_constructor) { + NEW(abc_method_t,m);array_append(file->methods, NO_KEY, m); + NEW(abc_method_body_t,body);array_append(file->method_bodies, NO_KEY, body); + body->method = m; m->body = body; + __ returnvoid(body); + c->static_constructor = m; } } - abc_method_t*nullmethod = 0; - if(need_null_method) { - NEW(abc_method_t,m); - nullmethod = m; - /*TODO: might be more efficient to have this at the beginning */ - array_append(file->methods, NO_KEY, nullmethod); - - NEW(abc_method_body_t,body); - body->method = m; - m->body = body; - __ returnvoid(body); - array_append(file->method_bodies, NO_KEY, body); - } - for(t=0;tclasses->num;t++) { - abc_class_t*c = (abc_class_t*)array_getvalue(file->classes, t); - if(!c->constructor) - c->constructor = nullmethod; - if(!c->static_constructor) - c->static_constructor = nullmethod; - } swf_SetU30(tag, file->methods->num); /* enumerate classes, methods and method bodies */ @@ -928,6 +921,8 @@ void swf_WriteABC(TAG*abctag, void*code) Not sure yet what to do with methods which are used at different locations- e.g. the nullmethod is used all over the place. + EDIT: flashplayer doesn't allow this anyway- a method can only + be used once Also, I have the strong suspicion that flash player uses only the difference between max_scope_stack and init_scope_stack, anyway. @@ -935,11 +930,11 @@ void swf_WriteABC(TAG*abctag, void*code) for(t=0;tclasses->num;t++) { abc_class_t*c = (abc_class_t*)array_getvalue(file->classes, t); trait_list_t*traits = c->traits; - if(c->constructor && + if(c->constructor && c->constructor->body && c->constructor->body->init_scope_depth < c->init_scope_depth) { c->constructor->body->init_scope_depth = c->init_scope_depth; } - if(c->static_constructor && + if(c->static_constructor && c->static_constructor->body && c->static_constructor->body->init_scope_depth < c->init_scope_depth) { c->static_constructor->body->init_scope_depth = c->init_scope_depth; } @@ -1034,20 +1029,16 @@ void swf_WriteABC(TAG*abctag, void*code) interface = interface->next; } - if(!c->constructor) { - swf_SetU30(tag, nullmethod->index); - } else { - swf_SetU30(tag, c->constructor->index); - } + assert(c->constructor); + swf_SetU30(tag, c->constructor->index); + traits_write(pool, tag, c->traits); } for(t=0;tclasses->num;t++) { abc_class_t*c = (abc_class_t*)array_getvalue(file->classes, t); - if(!c->static_constructor) { - swf_SetU30(tag, nullmethod->index); - } else { - swf_SetU30(tag, c->static_constructor->index); - } + assert(c->static_constructor); + swf_SetU30(tag, c->static_constructor->index); + traits_write(pool, tag, c->static_traits); } @@ -1081,14 +1072,14 @@ void swf_WriteABC(TAG*abctag, void*code) code_write(tag, c->code, pool, file); swf_SetU30(tag, list_length(c->exceptions)); - exception_list_t*l = c->exceptions; + abc_exception_list_t*l = c->exceptions; while(l) { // warning: assumes "pos" in each code_t is up-to-date - swf_SetU30(tag, l->exception->from->pos); - swf_SetU30(tag, l->exception->to->pos); - swf_SetU30(tag, l->exception->target->pos); - swf_SetU30(tag, pool_register_multiname(pool, l->exception->exc_type)); - swf_SetU30(tag, pool_register_multiname(pool, l->exception->var_name)); + swf_SetU30(tag, l->abc_exception->from->pos); + swf_SetU30(tag, l->abc_exception->to->pos); + swf_SetU30(tag, l->abc_exception->target->pos); + swf_SetU30(tag, pool_register_multiname(pool, l->abc_exception->exc_type)); + swf_SetU30(tag, pool_register_multiname(pool, l->abc_exception->var_name)); l = l->next; } @@ -1202,9 +1193,9 @@ void abc_file_free(abc_file_t*file) code_free(body->code);body->code=0; traits_free(body->traits);body->traits=0; - exception_list_t*ee = body->exceptions; + abc_exception_list_t*ee = body->exceptions; while(ee) { - exception_t*e=ee->exception;ee->exception=0; + abc_exception_t*e=ee->abc_exception;ee->abc_exception=0; e->from = e->to = e->target = 0; multiname_destroy(e->exc_type);e->exc_type=0; multiname_destroy(e->var_name);e->var_name=0; @@ -1311,6 +1302,10 @@ void swf_AddButtonLinks(SWF*swf, char stop_each_frame, char events) __ debugline(f, 1); __ getlocal_0(f); __ pushscope(f); + if(stop_each_frame) { + __ findpropstrict(f, "[package]::stop"); + __ callpropvoid(f, "[package]::stop", 0); + } } if(tag->id == ST_DEFINEBUTTON || tag->id == ST_DEFINEBUTTON2) { @@ -1323,10 +1318,6 @@ void swf_AddButtonLinks(SWF*swf, char stop_each_frame, char events) __ getlex(f,functionname); __ callpropvoid(f, "::addEventListener" ,2); - if(stop_each_frame) { - __ findpropstrict(f, "[package]::stop"); - __ callpropvoid(f, "[package]::stop", 0); - } needs_framescript = 1; abc_method_body_t*h = @@ -1404,7 +1395,8 @@ void swf_AddButtonLinks(SWF*swf, char stop_each_frame, char events) if(tag->id == ST_DEFINEBUTTON || tag->id == ST_DEFINEBUTTON2) { char buttonname[80]; sprintf(buttonname, "::button%d", swf_GetDefineID(tag)); - abc_AddSlot(cls, buttonname, 0, "flash.display::SimpleButton"); + multiname_t*s = multiname_fromstring(buttonname); + abc_class_slot(cls, buttonname, s); } tag = tag->next; }