X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fas3%2Fabc.c;h=a820560403777a542951bf71abf5be6214ea566d;hb=0bd90929a97ebf149d9e2347e43d509f0db08c0e;hp=5c9b87b51d95a3880cf95ec70871ae21d4088d60;hpb=70080bc309ba2a414647d27e2f413f22bc7823e4;p=swftools.git diff --git a/lib/as3/abc.c b/lib/as3/abc.c index 5c9b87b..a820560 100644 --- a/lib/as3/abc.c +++ b/lib/as3/abc.c @@ -97,8 +97,8 @@ static void parse_metadata(TAG*tag, abc_file_t*file, pool_t*pool) for(s=0;sinterfaces, 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) +static abc_method_t* add_method(abc_file_t*file, abc_class_t*cls, multiname_t*returntype, char body) { - /* construct code (method body) object */ - NEW(abc_method_body_t,c); - array_append(file->method_bodies, NO_KEY, c); - c->file = file; - c->traits = list_new(); - c->code = 0; - /* construct method object */ NEW(abc_method_t,m); + m->index = array_length(file->methods); array_append(file->methods, NO_KEY, m); - m->return_type = returntype; - int t; - for(t=0;tparameters, multiname_fromstring(param)); + if(body) { + /* construct code (method body) object */ + NEW(abc_method_body_t,c); + array_append(file->method_bodies, NO_KEY, c); + c->index = array_length(file->method_bodies); + c->file = file; + c->traits = list_new(); + c->code = 0; + + /* crosslink the two objects */ + m->body = c; + c->method = m; } - /* crosslink the two objects */ - m->body = c; - c->method = m; - - return c; + return m; } -abc_method_body_t* abc_class_constructor(abc_class_t*cls, multiname_t*returntype, int num_params, ...) +abc_method_t* abc_class_constructor(abc_class_t*cls, multiname_t*returntype) { - va_list va; - va_start(va, num_params); - abc_method_body_t* c = add_method(cls->file, cls, returntype, num_params, va); - va_end(va); - cls->constructor = c->method; - return c; + abc_method_t* m = add_method(cls->file, cls, returntype, 1); + cls->constructor = m; + return m; } -abc_method_body_t* abc_class_staticconstructor(abc_class_t*cls, multiname_t*returntype, int num_params, ...) +abc_method_t* abc_class_staticconstructor(abc_class_t*cls, multiname_t*returntype) { - va_list va; - va_start(va, num_params); - abc_method_body_t* c = add_method(cls->file, cls, returntype, num_params, va); - va_end(va); - cls->static_constructor = c->method; - return c; + abc_method_t* m = add_method(cls->file, cls, returntype, 1); + cls->static_constructor = m; + return m; } trait_t*trait_new(int type, multiname_t*name, int data1, int data2, constant_t*v) @@ -253,27 +244,62 @@ trait_t*trait_new_method(multiname_t*name, abc_method_t*m) return trait; } -abc_method_body_t* abc_class_method(abc_class_t*cls, multiname_t*returntype, char*name, int num_params, ...) +abc_method_t* abc_class_method(abc_class_t*cls, multiname_t*returntype, multiname_t*name) { abc_file_t*file = cls->file; - va_list va; - va_start(va, num_params); - abc_method_body_t* c = add_method(cls->file, cls, returntype, num_params, va); - va_end(va); - list_append(cls->traits, trait_new_method(multiname_fromstring(name), c->method)); - return c; + abc_method_t* m = add_method(cls->file, cls, returntype, !(cls->flags&CLASS_INTERFACE)); + m->trait = trait_new_method(multiname_clone(name), m); + /* start assigning traits at position #1. + Weird things happen when assigning slot 0- slot 0 and 1 seem + to be identical */ + m->trait->slot_id = list_length(cls->traits)+1; + list_append(cls->traits, m->trait); + return m; +} +abc_method_t* abc_class_staticmethod(abc_class_t*cls, multiname_t*returntype, multiname_t*name) +{ + abc_file_t*file = cls->file; + abc_method_t* m = add_method(cls->file, cls, returntype, !(cls->flags&CLASS_INTERFACE)); + m->trait = trait_new_method(multiname_clone(name), m); + m->trait->slot_id = list_length(cls->static_traits)+1; + list_append(cls->static_traits, m->trait); + return m; } -trait_t* abc_class_slot(abc_class_t*cls, char*name, multiname_t*type) +trait_t* abc_class_slot(abc_class_t*cls, multiname_t*name, multiname_t*type) { abc_file_t*file = cls->file; - multiname_t*m_name = multiname_fromstring(name); - multiname_t*m_type = type; + multiname_t*m_name = multiname_clone(name); + multiname_t*m_type = multiname_clone(type); trait_t*t = trait_new_member(m_type, m_name, 0); - t->slot_id = list_length(cls->traits); + t->slot_id = list_length(cls->traits)+1; list_append(cls->traits, t); return t; } +trait_t* abc_class_staticslot(abc_class_t*cls, multiname_t*name, multiname_t*type) +{ + abc_file_t*file = cls->file; + multiname_t*m_name = multiname_clone(name); + multiname_t*m_type = multiname_clone(type); + trait_t*t = trait_new_member(m_type, m_name, 0); + t->slot_id = list_length(cls->static_traits)+1; + list_append(cls->static_traits, t); + return t; +} + + +trait_t* abc_class_find_slotid(abc_class_t*cls, int slotid) +{ + trait_list_t*l; + trait_t*t=0; + for(l=cls->traits;l;l=l->next) { + if(l->trait->slot_id==slotid) { + t=l->trait; + break; + } + } + return t; +} void abc_method_body_addClassTrait(abc_method_body_t*code, char*multiname, int slotid, abc_class_t*cls) { @@ -297,17 +323,14 @@ int abc_initscript_addClassTrait(abc_script_t*script, multiname_t*multiname, abc return slotid; } -abc_script_t* abc_initscript(abc_file_t*file, multiname_t*returntype, int num_params, ...) +abc_script_t* abc_initscript(abc_file_t*file, multiname_t*returntype) { - va_list va; - va_start(va, num_params); - abc_method_body_t* c = add_method(file, 0, returntype, num_params, va); + abc_method_t*m = add_method(file, 0, returntype, 1); abc_script_t* s = malloc(sizeof(abc_script_t)); - s->method = c->method; + s->method = m; s->traits = list_new(); s->file = file; array_append(file->scripts, NO_KEY, s); - va_end(va); return s; } @@ -321,7 +344,10 @@ static void dump_method(FILE*fo, const char*prefix, const char*type, const char* else return_type = strdup("void"); char*paramstr = params_tostring(m->parameters); - fprintf(fo, "%s%s %s %s=%s %s (%d params)\n", prefix, type, return_type, name, m->name, paramstr, list_length(m->parameters)); + fprintf(fo, "%s%s %s %s=%s %s (%d params, %d optional)\n", prefix, type, return_type, name, m->name, paramstr, + list_length(m->parameters), + list_length(m->optional_parameters) + ); free(paramstr);paramstr=0; free(return_type);return_type=0; @@ -343,7 +369,12 @@ static void dump_method(FILE*fo, const char*prefix, const char*type, const char* if(flags&METHOD_SET_DXNS) {fprintf(fo, " set_dxns");flags&=~METHOD_SET_DXNS;} if(flags&METHOD_HAS_PARAM_NAMES) {fprintf(fo, " has_param_names");flags&=~METHOD_HAS_PARAM_NAMES;} if(flags) fprintf(fo, " %02x", flags); - fprintf(fo, "]\n"); + fprintf(fo, "]"); + + if(m->trait) { + fprintf(fo, " slot:%d", m->trait->slot_id); + } + fprintf(fo, "\n"); char prefix2[80]; @@ -406,10 +437,12 @@ static trait_list_t* traits_parse(TAG*tag, pool_t*pool, abc_file_t*file) if(kind == TRAIT_METHOD || kind == TRAIT_GETTER || kind == TRAIT_SETTER) { // method / getter / setter trait->disp_id = swf_GetU30(tag); trait->method = (abc_method_t*)array_getvalue(file->methods, swf_GetU30(tag)); + trait->method->trait = trait; DEBUG printf(" method/getter/setter\n"); } else if(kind == TRAIT_FUNCTION) { // function trait->slot_id = swf_GetU30(tag); trait->method = (abc_method_t*)array_getvalue(file->methods, swf_GetU30(tag)); + trait->method->trait = trait; } else if(kind == TRAIT_CLASS) { // class trait->slot_id = swf_GetU30(tag); trait->cls = (abc_class_t*)array_getvalue(file->classes, swf_GetU30(tag)); @@ -688,7 +721,6 @@ void* swf_ReadABC(TAG*tag) 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 */ m->optional_parameters = list_new(); int num = swf_GetU30(tag); int s; @@ -703,10 +735,11 @@ void* swf_ReadABC(TAG*tag) /* debug information- not used by avm2 */ multiname_list_t*l = m->parameters; while(l) { - char*name = pool_lookup_string(pool, swf_GetU30(tag)); + const char*name = pool_lookup_string(pool, swf_GetU30(tag)); l = l->next; } } + m->index = array_length(file->methods); array_append(file->methods, NO_KEY, m); } @@ -874,6 +907,7 @@ void swf_WriteABC(TAG*abctag, void*code) 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); + // don't bother to set m->index body->method = m; m->body = body; __ returnvoid(body); c->constructor = m; @@ -1061,10 +1095,15 @@ void swf_WriteABC(TAG*abctag, void*code) //swf_SetU30(tag, c->old.max_scope_depth); swf_SetU30(tag, c->stats->max_stack); - if(list_length(c->method->parameters)+1 <= c->stats->local_count) + + int param_num = list_length(c->method->parameters)+1; + if(c->method->flags&METHOD_NEED_REST) + param_num++; + if(param_num <= c->stats->local_count) swf_SetU30(tag, c->stats->local_count); else - swf_SetU30(tag, list_length(c->method->parameters)+1); + swf_SetU30(tag, param_num); + swf_SetU30(tag, c->init_scope_depth); swf_SetU30(tag, c->stats->max_scope_depth+ c->init_scope_depth); @@ -1247,7 +1286,7 @@ void swf_AddButtonLinks(SWF*swf, char stop_each_frame, char events) swf_SetU16(tag, 0); swf_SetString(tag, "rfx.MainTimeline"); - c = abc_class_staticconstructor(cls, 0, 0); + c = abc_class_staticconstructor(cls, 0)->body; c->old.max_stack = 1; c->old.local_count = 1; c->old.init_scope_depth = 9; @@ -1257,7 +1296,7 @@ void swf_AddButtonLinks(SWF*swf, char stop_each_frame, char events) __ pushscope(c); __ returnvoid(c); - c = abc_class_constructor(cls, 0, 0); + c = abc_class_constructor(cls, 0)->body; c->old.max_stack = 3; c->old.local_count = 1; c->old.init_scope_depth = 10; @@ -1293,7 +1332,7 @@ void swf_AddButtonLinks(SWF*swf, char stop_each_frame, char events) __ getlex(c,framename); __ callpropvoid(c,"[package]::addFrameScript",2); - f = abc_class_method(cls, 0, framename, 0); + f = abc_class_method(cls, 0, multiname_fromstring(framename))->body; f->old.max_stack = 3; f->old.local_count = 1; f->old.init_scope_depth = 10; @@ -1321,7 +1360,9 @@ void swf_AddButtonLinks(SWF*swf, char stop_each_frame, char events) needs_framescript = 1; abc_method_body_t*h = - abc_class_method(cls, 0, functionname, 1, "flash.events::MouseEvent"); + abc_class_method(cls, 0, multiname_fromstring(functionname))->body; + list_append(h->method->parameters, multiname_fromstring("flash.events::MouseEvent")); + h->old.max_stack = 6; h->old.local_count = 2; h->old.init_scope_depth = 10; @@ -1396,13 +1437,13 @@ void swf_AddButtonLinks(SWF*swf, char stop_each_frame, char events) char buttonname[80]; sprintf(buttonname, "::button%d", swf_GetDefineID(tag)); multiname_t*s = multiname_fromstring(buttonname); - abc_class_slot(cls, buttonname, s); + abc_class_slot(cls, multiname_fromstring(buttonname), s); } tag = tag->next; } - abc_script_t*s = abc_initscript(file, 0, 0); + abc_script_t*s = abc_initscript(file, 0); c = s->method->body; c->old.max_stack = 2; c->old.local_count = 1;