refactoring: renamed 'pool' variables to 'file'
[swftools.git] / lib / as3 / abc.c
index abdc258..b37dea8 100644 (file)
@@ -136,12 +136,12 @@ abc_file_t*abc_file_new()
 #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;
@@ -177,18 +177,18 @@ void abc_class_add_interface(abc_class_t*c, multiname_t*interface)
     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);
@@ -212,7 +212,7 @@ abc_method_body_t* abc_class_constructor(abc_class_t*cls, char*returntype, int n
 {
     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;
@@ -222,7 +222,7 @@ abc_method_body_t* abc_class_staticconstructor(abc_class_t*cls, char*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->static_constructor = c->method;
     return c;
@@ -255,10 +255,10 @@ trait_t*trait_new_method(multiname_t*name, abc_method_t*m)
 
 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;
@@ -266,14 +266,14 @@ abc_method_body_t* abc_class_method(abc_class_t*cls, char*returntype, char*name,
 
 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;
@@ -284,23 +284,23 @@ void abc_method_body_addClassTrait(abc_method_body_t*code, char*multiname, int s
    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;
 }
@@ -309,27 +309,29 @@ static void dump_traits(FILE*fo, const char*prefix, trait_list_t*traits, abc_fil
 
 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);
 }
 
@@ -634,8 +636,9 @@ void* swf_ReadABC(TAG*tag)
        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);
         }
 
@@ -650,7 +653,7 @@ void* swf_ReadABC(TAG*tag)
         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++) {
@@ -735,18 +738,27 @@ void* swf_ReadABC(TAG*tag)
        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);
@@ -847,6 +859,16 @@ void swf_WriteABC(TAG*abctag, void*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++) {
@@ -948,7 +970,18 @@ void swf_WriteABC(TAG*abctag, void*code)
 
         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);
     }
 
@@ -972,9 +1005,8 @@ void swf_WriteABC(TAG*abctag, void*code)
     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++) {
@@ -1055,6 +1087,12 @@ void swf_FreeABC(void*code)
     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;