#define CLASS_INTERFACE 4
#define CLASS_PROTECTED_NS 8
-abc_class_t* abc_class_new(abc_file_t*pool, multiname_t*classname, multiname_t*superclass) {
+abc_class_t* abc_class_new(abc_file_t*file, multiname_t*classname, multiname_t*superclass) {
NEW(abc_class_t,c);
- array_append(pool->classes, NO_KEY, c);
+ array_append(file->classes, NO_KEY, c);
- c->pool = pool;
+ c->file = file;
c->classname = classname;
c->superclass = superclass;
c->flags = 0;
list_append(c->interfaces, interface);
}
-abc_method_body_t* add_method(abc_file_t*pool, abc_class_t*cls, char*returntype, int num_params, va_list va)
+abc_method_body_t* add_method(abc_file_t*file, abc_class_t*cls, char*returntype, int num_params, va_list va)
{
/* construct code (method body) object */
NEW(abc_method_body_t,c);
- array_append(pool->method_bodies, NO_KEY, c);
- c->pool = pool;
+ 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);
- array_append(pool->methods, NO_KEY, m);
+ array_append(file->methods, NO_KEY, m);
if(returntype && strcmp(returntype, "void")) {
m->return_type = multiname_fromstring(returntype);
{
va_list va;
va_start(va, num_params);
- abc_method_body_t* c = add_method(cls->pool, cls, returntype, num_params, va);
+ abc_method_body_t* c = add_method(cls->file, cls, returntype, num_params, va);
va_end(va);
cls->constructor = c->method;
return c;
{
va_list va;
va_start(va, num_params);
- abc_method_body_t* c = add_method(cls->pool, cls, returntype, num_params, va);
+ 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_body_t* abc_class_method(abc_class_t*cls, char*returntype, char*name, int num_params, ...)
{
- abc_file_t*pool = cls->pool;
+ abc_file_t*file = cls->file;
va_list va;
va_start(va, num_params);
- abc_method_body_t* c = add_method(cls->pool, cls, returntype, num_params, va);
+ 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;
void abc_AddSlot(abc_class_t*cls, char*name, int slot, char*multiname)
{
- abc_file_t*pool = cls->pool;
+ abc_file_t*file = cls->file;
multiname_t*m = multiname_fromstring(multiname);
list_append(cls->traits, trait_new(TRAIT_SLOT, m, slot, 0, 0, 0));
}
void abc_method_body_addClassTrait(abc_method_body_t*code, char*multiname, int slotid, abc_class_t*cls)
{
- abc_file_t*pool = code->pool;
+ abc_file_t*file = code->file;
multiname_t*m = multiname_fromstring(multiname);
trait_t*trait = trait_new(TRAIT_CLASS, m, slotid, 0, 0, 0);
trait->cls = cls;
and traits of the init script are *not* the same thing */
void abc_initscript_addClassTrait(abc_script_t*script, char*multiname, int slotid, abc_class_t*cls)
{
- abc_file_t*pool = script->pool;
+ abc_file_t*file = script->file;
multiname_t*m = multiname_fromstring(multiname);
trait_t*trait = trait_new(TRAIT_CLASS, m, slotid, 0, 0, 0);
trait->cls = cls;
list_append(script->traits, trait);
}
-abc_script_t* abc_initscript(abc_file_t*pool, char*returntype, int num_params, ...)
+abc_script_t* abc_initscript(abc_file_t*file, char*returntype, int num_params, ...)
{
va_list va;
va_start(va, num_params);
- abc_method_body_t* c = add_method(pool, 0, returntype, num_params, va);
+ abc_method_body_t* c = add_method(file, 0, returntype, num_params, va);
abc_script_t* s = malloc(sizeof(abc_script_t));
s->method = c->method;
s->traits = list_new();
- s->pool = pool;
- array_append(pool->scripts, NO_KEY, s);
+ s->file = file;
+ array_append(file->scripts, NO_KEY, s);
va_end(va);
return s;
}
static void dump_method(FILE*fo, const char*prefix, const char*type, const char*name, abc_method_t*m, abc_file_t*file)
{
- const char*return_type = "void";
+ char*return_type = 0;
if(m->return_type)
return_type = multiname_to_string(m->return_type);
-
+ else
+ return_type = strdup("void");
char*paramstr = params_to_string(m->parameters);
-
fprintf(fo, "%s%s %s %s=%s %s\n", prefix, type, return_type, name, m->name, paramstr);
+ free(paramstr);paramstr=0;
+ free(return_type);return_type=0;
abc_method_body_t*c = m->body;
if(!c) {
return;
}
- fprintf(fo, "%s[%d %d %d %d %d]\n", prefix, c->max_stack, c->local_count, c->init_scope_depth, c->max_scope_depth, c->exception_count);
+ fprintf(fo, "%s[%d %d %d %d %d]\n", prefix, c->max_stack, c->local_count, c->init_scope_depth, c->max_scope_depth, list_length(c->exceptions));
char prefix2[80];
sprintf(prefix2, "%s ", prefix);
if(c->traits)
dump_traits(fo, prefix, c->traits, file);
fprintf(fo, "%s{\n", prefix);
- code_dump(c->code, file, prefix2, fo);
+ code_dump(c->code, c->exceptions, file, prefix2, fo);
fprintf(fo, "%s}\n\n", prefix);
}
int s;
for(s=0;s<param_count;s++) {
int type_index = swf_GetU30(tag);
- multiname_t*param = multiname_clone(pool_lookup_multiname(pool, type_index));
+
/* type_index might be 0, which probably means "..." (varargs) */
+ multiname_t*param = type_index?multiname_clone(pool_lookup_multiname(pool, type_index)):0;
list_append(m->parameters, param);
}
DEBUG printf("method %d) %s flags=%02x\n", t, params_to_string(m->parameters), m->flags);
if(m->flags&0x08) {
- /* optional parameters */
+ /* TODO optional parameters */
int num = swf_GetU30(tag);
int s;
for(s=0;s<num;s++) {
m->body = c;
int pos = tag->pos + code_length;
- c->code = code_parse(tag, code_length, file, pool);
+ codelookup_t*codelookup = 0;
+ c->code = code_parse(tag, code_length, file, pool, &codelookup);
tag->pos = pos;
int exception_count = swf_GetU30(tag);
int s;
+ c->exceptions = list_new();
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
+ exception_t*e = malloc(sizeof(exception_t));
+
+ e->from = code_atposition(codelookup, swf_GetU30(tag));
+ e->to = code_atposition(codelookup, swf_GetU30(tag));
+ e->target = code_atposition(codelookup, swf_GetU30(tag));
+
+ e->exc_type = multiname_clone(pool_lookup_multiname(pool, swf_GetU30(tag)));
+ e->var_name = multiname_clone(pool_lookup_multiname(pool, swf_GetU30(tag)));
+ //e->var_name = pool_lookup_string(pool, swf_GetU30(tag));
+ //if(e->var_name) e->var_name = strdup(e->var_name);
+ list_append(c->exceptions, e);
}
+ 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);
return file;
}
-static void code_write(TAG*tag, abc_code_t*code, pool_t*pool, abc_file_t*file)
-{
- int len = 0;
- abc_code_t*c = code;
- while(c) {
- len += opcode_write(0, c, pool, file);
- c = c->next;
- }
- swf_SetU30(tag, len);
- int pos = tag->len;
- c = code;
- while(c) {
- opcode_write(tag, c, pool, file);
- c = c->next;
- }
- assert(tag->len - pos == len);
-}
-
void swf_WriteABC(TAG*abctag, void*code)
{
abc_file_t*file = (abc_file_t*)code;
for(t=0;t<file->method_bodies->num;t++) {
abc_method_body_t*m = (abc_method_body_t*)array_getvalue(file->method_bodies, t);
m->index = t;
+ exception_list_t*ee = m->exceptions;
+ while(ee) {
+ exception_t*e=ee->exception;ee->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;
+ free(e);
+ ee=ee->next;
+ }
+ list_free(m->exceptions);m->exceptions=0;
}
for(t=0;t<file->methods->num;t++) {
code_write(tag, c->code, pool, file);
- swf_SetU30(tag, c->exception_count);
+ swf_SetU30(tag, list_length(c->exceptions));
+ 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));
+ l = l->next;
+ }
+
traits_write(pool, tag, c->traits);
}
pool_destroy(pool);
}
-void swf_FreeABC(void*code)
+void abc_file_free(abc_file_t*file)
{
- abc_file_t*file= (abc_file_t*)code;
int t;
for(t=0;t<file->metadata->num;t++) {
free(file);
}
+void swf_FreeABC(void*code)
+{
+ abc_file_t*file= (abc_file_t*)code;
+ abc_file_free(file);
+}
+
void swf_AddButtonLinks(SWF*swf, char stop_each_frame, char events)
{
int num_frames = 0;