implemented asset resolving
authorMatthias Kramm <kramm@quiss.org>
Sat, 2 Jan 2010 02:45:04 +0000 (18:45 -0800)
committerMatthias Kramm <kramm@quiss.org>
Sat, 2 Jan 2010 02:45:04 +0000 (18:45 -0800)
17 files changed:
configure.in
lib/Makefile.in
lib/as3/Makefile
lib/as3/abc.c
lib/as3/abc.h
lib/as3/assets.c [new file with mode: 0644]
lib/as3/assets.h [new file with mode: 0644]
lib/as3/compiler.c
lib/as3/compiler.h
lib/as3/import.c
lib/as3/main.c
lib/as3/parser.y
lib/as3/registry.c
lib/as3/registry.h
lib/gfxtools.c
lib/python/gfx.c
src/swfdump.c

index d32235f..ba082c5 100644 (file)
@@ -457,7 +457,7 @@ LIBPDF='libpdf$(A)'
 if test "x${DISABLEPDF2SWF}" = "xtrue"; then
   echo "* Disabling pdf2swf tool..."
   rm -f lib/pdf/Makefile
-  echo all install uninstall clean libpdf: > lib/pdf/Makefile
+  echo all install uninstall clean libpdf libgfxpdf: > lib/pdf/Makefile
   pdf2swf_makefile=""
   PDF2SWF=
   LIBPDF=
index 3c8fa52..f0b7ebe 100644 (file)
@@ -13,7 +13,7 @@ h263_objects = h.263/dct.$(O) h.263/h263tables.$(O) h.263/swfvideo.$(O)
 as12compiler_objects = action/assembler.$(O) action/compile.$(O) action/lex.swf4.$(O) action/lex.swf5.$(O) action/libming.$(O) action/swf4compiler.tab.$(O) action/swf5compiler.tab.$(O) action/actioncompiler.$(O)
 as12compiler_in_source = $(as12compiler_objects)
 
-as3compiler_objects = as3/abc.$(O) as3/pool.$(O) as3/files.$(O) as3/opcodes.$(O) as3/code.$(O) as3/registry.$(O) as3/builtin.$(O) as3/parser.tab.$(O) as3/tokenizer.yy.$(O) as3/scripts.$(O) as3/compiler.$(O) as3/import.$(O) as3/expr.$(O) as3/common.$(O) as3/initcode.$(O)
+as3compiler_objects = as3/abc.$(O) as3/pool.$(O) as3/files.$(O) as3/opcodes.$(O) as3/code.$(O) as3/registry.$(O) as3/builtin.$(O) as3/parser.tab.$(O) as3/tokenizer.yy.$(O) as3/scripts.$(O) as3/compiler.$(O) as3/import.$(O) as3/expr.$(O) as3/common.$(O) as3/initcode.$(O) as3/assets.$(O)
 gfxpoly_objects = gfxpoly/active.$(O) gfxpoly/convert.$(O) gfxpoly/poly.$(O) gfxpoly/renderpoly.$(O) gfxpoly/stroke.$(O) gfxpoly/wind.$(O) gfxpoly/xrow.$(O)
 
 rfxswf_modules =  modules/swfbits.c modules/swfaction.c modules/swfdump.c modules/swfcgi.c modules/swfbutton.c modules/swftext.c modules/swffont.c modules/swftools.c modules/swfsound.c modules/swfshape.c modules/swfobject.c modules/swfdraw.c modules/swffilter.c modules/swfrender.c h.263/swfvideo.c modules/swfalignzones.c
index b3ecd23..0ddf96a 100644 (file)
@@ -8,7 +8,7 @@ D=-g -pg
 #BISONDEBUG=yes
 
 MODULES = abc.o opcodes.o code.o pool.o scripts.o expr.o common.o initcode.o
-SOURCES = abc.c abc.h pool.c pool.h files.c files.h code.c code.h registry.c registry.h opcodes.c opcodes.h builtin.c builtin.h compiler.c compiler.h parser.tab.h parser.tab.c tokenizer.yy.c scripts.c import.c import.h expr.c expr.h common.c common.h initcode.c initcode.h
+SOURCES = abc.c abc.h pool.c pool.h files.c files.h code.c code.h registry.c registry.h opcodes.c opcodes.h builtin.c builtin.h compiler.c compiler.h parser.tab.h parser.tab.c tokenizer.yy.c scripts.c import.c import.h expr.c expr.h common.c common.h initcode.c initcode.h assets.c assets.h
 
 tokenizer.yy.c: tokenizer.lex tokenizer.h
        flex -Pas3_ -8 -B -otokenizer.yy.c tokenizer.lex
@@ -18,7 +18,7 @@ BISONDEBUGFLAGS=-t
 BISONDEBUGDEFINE=-DBISONDEBUG
 endif
 parser.tab.h parser.tab.c: parser.y parser.h skeleton.m4 Makefile
-       bison $(BISONDEBUGFLAGS) -S ./skeleton.m4 -v --defines -pa3_ parser.y -o parser.tab.c
+       /usr/local/bin/bison $(BISONDEBUGFLAGS) -S ./skeleton.m4 -v --defines -pa3_ parser.y -o parser.tab.c
 
 main.o: main.c parser.tab.h parser.h
        $(C) $(BISONDEBUGDEFINE) main.c -o main.o
@@ -30,8 +30,8 @@ parser: main.o tokenizer.yy.c ../librfxswf.a ../libbase.a parser.tab.h
        $(L) main.o ../librfxswf.a ../libbase.a -o parser -lz
 
 rfxswf_modules=../drawer.o ../rfxswf.o ../modules/*.o ../lame/*.o ../action/*.o ../MD5.o $(MODULES)
-mklib: mklib.o $(rfxswf_modules) import.o registry.o tokenizer.yy.o parser.tab.o files.o compiler.o ../libbase.a
-       $(L) mklib.o $(rfxswf_modules) import.o registry.o tokenizer.yy.o parser.tab.o files.o compiler.o ../libbase.a -o mklib $(LIBS)
+mklib: mklib.o $(rfxswf_modules) import.o registry.o tokenizer.yy.o parser.tab.o files.o compiler.o assets.o ../libbase.a
+       $(L) mklib.o $(rfxswf_modules) import.o registry.o tokenizer.yy.o parser.tab.o files.o compiler.o assets.o ../libbase.a -o mklib $(LIBS)
 
 ../q.o: ../q.c ../q.h ../mem.h
        cd ..; make q.o; cd -
index 59aa880..6de2c2d 100644 (file)
@@ -26,6 +26,7 @@
 #include "../rfxswf.h"
 #include "../q.h"
 #include "abc.h"
+#include "assets.h"
 
 char stringbuffer[2048];
 
@@ -49,12 +50,12 @@ static void params_dump(FILE*fo, multiname_list_t*l, constant_list_t*o)
     fprintf(fo, "(");
     while(l) {
         char*s = multiname_tostring(l->multiname);
-        fprintf(fo, s);
+        fprintf(fo, "%s", s);
         free(s);
         if(i>=n-no) {
             s = constant_tostring(o->constant);
             fprintf(fo, " = ");
-            fprintf(fo, s);
+            fprintf(fo, "%s", s);
             free(s);
             o = o->next;
         }
@@ -74,7 +75,7 @@ static void parse_metadata(TAG*tag, abc_file_t*file, pool_t*pool)
     int t;
     int num_metadata = swf_GetU30(tag);
 
-    DEBUG printf("%d metadata\n");
+    DEBUG printf("%d metadata\n", num_metadata);
     for(t=0;t<num_metadata;t++) {
         const char*entry_name = pool_lookup_string(pool, swf_GetU30(tag));
         int num = swf_GetU30(tag);
@@ -157,6 +158,20 @@ void abc_class_add_interface(abc_class_t*c, multiname_t*interface)
 {
     list_append(c->interfaces, multiname_clone(interface));
 }
+char*abc_class_fullname(abc_class_t*cls)
+{
+    const char*package = cls->classname->ns->name;
+    const char*name = cls->classname->name;
+    int l1 = strlen(package);
+    int l2 = strlen(name);
+    char*fullname = malloc(l1+l2+2);
+    if(l1) {
+       memcpy(fullname, package, l1);
+       fullname[l1++]='.';
+    }
+    memcpy(fullname+l1, name, l2+1);
+    return fullname;
+}
 
 void abc_method_init(abc_method_t*m, abc_file_t*file, multiname_t*returntype, char body)
 {
@@ -451,7 +466,7 @@ static trait_list_t* traits_parse(TAG*tag, pool_t*pool, abc_file_t*file)
        } else if(kind == TRAIT_CLASS) { // class
            trait->slot_id = swf_GetU30(tag);
            trait->cls = (abc_class_t*)array_getvalue(file->classes, swf_GetU30(tag));
-           DEBUG printf("  class %s %d %d\n", name, trait->slot_id, trait->cls);
+           DEBUG printf("  class %s %d %08x\n", name, trait->slot_id, (int)trait->cls);
        } else if(kind == TRAIT_SLOT || kind == TRAIT_CONST) { // slot, const
            trait->slot_id = swf_GetU30(tag);
             trait->type_name = multiname_clone(pool_lookup_multiname(pool, swf_GetU30(tag)));
@@ -620,7 +635,7 @@ void* swf_DumpABC(FILE*fo, void*code, char*prefix)
         int s;
         array_t*items = (array_t*)array_getvalue(file->metadata, t);
         for(s=0;s<items->num;s++) {
-            fprintf(fo, "%s#  %s=%s\n", prefix, array_getkey(items, s), array_getvalue(items,s));
+            fprintf(fo, "%s#  %s=%s\n", prefix, (char*)array_getkey(items, s), (char*)array_getvalue(items,s));
         }
         fprintf(fo, "%s#\n", prefix);
     }
@@ -678,6 +693,11 @@ void* swf_DumpABC(FILE*fo, void*code, char*prefix)
            dump_method(fo, prefix2, "", "constructor", n, cls->constructor, file, methods_seen);
         free(n);
        traits_dump(fo, prefix2,cls->traits, file, methods_seen);
+
+       if(cls->asset) {
+           swf_DumpAsset(fo, cls->asset, prefix2);
+       }
+
         fprintf(fo, "%s}\n", prefix);
     }
     fprintf(fo, "%s\n", prefix);
@@ -755,7 +775,7 @@ void* swf_ReadABC(TAG*tag)
 
        m->flags = swf_GetU8(tag);
        
-        DEBUG printf("method %d) %s ", m->name);
+        DEBUG printf("method %d) %s ", t, m->name);
         DEBUG params_dump(stdout, m->parameters, m->optional_parameters);
         DEBUG printf("flags=%02x\n", t, m->flags);
 
index d58f2d7..3b6a134 100644 (file)
@@ -33,7 +33,10 @@ DECLARE(abc_method_body);
 DECLARE(abc_interface);
 DECLARE(abc_class);
 DECLARE(abc_exception);
+DECLARE(abc_asset);
+DECLARE_LIST(abc_asset);
 DECLARE_LIST(abc_exception);
+DECLARE_LIST(TAG);
 
 #include "code.h"
 #include "opcodes.h"
@@ -133,8 +136,9 @@ struct _abc_class {
     
     U8 flags;
 
+    abc_asset_t*asset; // swf tags needed for this class
+
     int init_scope_depth; // volatile, might be increased during code verification
-    
     int index; //filled in during writing
 };
 
@@ -148,6 +152,7 @@ void abc_class_final(abc_class_t*c);
 void abc_class_interface(abc_class_t*c);
 void abc_class_protectedNS(abc_class_t*c, char*namespace);
 void abc_class_add_interface(abc_class_t*c, multiname_t*interface);
+char*abc_class_fullname(abc_class_t*cls);
 
 trait_t* traits_find_slotid(trait_list_t*traits, int slotid);
 
@@ -197,6 +202,11 @@ typedef struct _abc_script {
     trait_list_t*traits;
 } abc_script_t;
 
+struct _abc_asset {
+    TAG_list_t*tags;
+    abc_asset_list_t*dependencies;
+};
+
 abc_method_t* abc_nullmethod(abc_file_t*file);
 abc_script_t* abc_initscript(abc_file_t*file);
 trait_t*abc_initscript_addClassTrait(abc_script_t*script, multiname_t*multiname, abc_class_t*cls);
diff --git a/lib/as3/assets.c b/lib/as3/assets.c
new file mode 100644 (file)
index 0000000..06fadd8
--- /dev/null
@@ -0,0 +1,202 @@
+#include <assert.h>
+#include "../rfxswf.h"
+#include "assets.h"
+
+asset_resolver_t* swf_ParseAssets(SWF*swf)
+{
+    NEW(asset_resolver_t,assets);
+    assets->name2asset = dict_new2(&charptr_type);
+    assets->id2asset = malloc(sizeof(abc_asset_t*)*65536);
+
+    TAG*tag = swf->firstTag;
+    while(tag) {
+       if(swf_isDefiningTag(tag)) {
+           NEW(abc_asset_t, asset);
+           list_append(asset->tags, tag);
+           assets->id2asset[swf_GetDefineID(tag)] = asset;
+       }
+       tag = tag->next;
+    }
+
+    tag = swf->firstTag;
+    while(tag) {
+       if(swf_isDefiningTag(tag)) {
+           abc_asset_t*asset = assets->id2asset[swf_GetDefineID(tag)];
+           assert(asset);
+           int num = swf_GetNumUsedIDs(tag);
+           int*positions = malloc(sizeof(int)*num);
+           swf_GetUsedIDs(tag, positions);
+           int t;
+           for(t=0;t<num;t++) {
+               U16 id = GET16(&tag->data[positions[t]]);
+               abc_asset_t*a = assets->id2asset[id];
+               if(!a) {
+                   fprintf(stderr, "Error: ID %d referenced, but not defined\n", id);
+               } else {
+                   list_append(asset->dependencies, a);
+               }
+           }
+       } else if(swf_isPseudoDefiningTag(tag)) {
+           abc_asset_t*asset = assets->id2asset[swf_GetDefineID(tag)];
+           if(asset) {
+               list_append(asset->tags, tag);
+           }
+       } else if(tag->id == ST_SYMBOLCLASS) {
+           int t, num = swf_GetU16(tag);
+           for(t=0;t<num;t++) {
+               U16 id = swf_GetU16(tag);
+               if(!id) {
+                   assets->mainclass_id = id;
+               } else {
+                   abc_asset_t*asset = assets->id2asset[id];
+                   if(!asset) {
+                       fprintf(stderr, "Error: ID %d referenced, but not defined\n", id);
+                   } else {
+                       char*name = swf_GetString(tag);
+                       dict_put(assets->name2asset, name, asset);
+                   }
+               }
+           }
+       }
+       tag = tag->next;
+    }
+    return assets;
+}
+
+void swf_ResolveAssets(asset_resolver_t*assets, abc_file_t*file)
+{
+    int num = assets->name2asset->num;
+    int resolved = 0;
+    int t;
+    for(t=0;t<file->classes->num;t++) {
+       abc_class_t*cls = (abc_class_t*)array_getvalue(file->classes, t);
+       char*fullname = abc_class_fullname(cls);
+       abc_asset_t*a = (abc_asset_t*)dict_lookup(assets->name2asset, fullname);
+       if(a) {
+           resolved++;
+           cls->asset = a;
+       }
+       free(fullname);
+    }
+}
+
+static void dump_asset_list(FILE*fo, abc_asset_list_t*l, const char*prefix)
+{
+    while(l) {
+       TAG_list_t*t = l->abc_asset->tags;
+       while(t) {
+           TAG*tag = t->TAG;
+           fprintf(fo, "%s[tag] %s defines ID %d\n", prefix, swf_TagGetName(tag), swf_GetDefineID(tag));
+           t = t->next;
+       }
+       char*prefix2 = allocprintf("%s    ", prefix);
+       dump_asset_list(fo, l->abc_asset->dependencies, prefix2);
+       free(prefix2);
+       l = l->next;
+    }
+}
+
+void swf_DumpAsset(FILE*fo, abc_asset_t*asset, const char*prefix)
+{
+    abc_asset_list_t*l = 0;
+    list_append(l, asset);
+    dump_asset_list(fo, l, prefix);
+    list_free(l);
+}
+
+static TAG* write_tag(TAG*prev, TAG*tag, dict_t*written)
+{
+    if(!dict_contains(written, tag)) {
+       dict_put(written, tag, 0);
+       if(prev) {
+           prev->next = tag;
+       }
+       tag->prev = prev;
+       tag->next = 0;
+       prev = tag;
+    }
+    return prev;
+}
+static TAG*write_asset(TAG*tag, abc_asset_t*a, dict_t*written)
+{
+    TAG_list_t*tags = a->tags;
+    abc_asset_list_t*deps = a->dependencies;
+    while(deps) {
+       tag = write_asset(tag, deps->abc_asset, written);
+       deps = deps->next;
+    }
+    while(tags) {
+       tag = write_tag(tag, tags->TAG, written);
+       tags = tags->next;
+    }
+    return tag;
+}
+
+void swf_WriteABCSymbols(TAG*tag, abc_file_t*file)
+{
+    int num = 0;
+    int t;
+    for(t=0;t<file->classes->num;t++) {
+       abc_class_t*cls = (abc_class_t*)array_getvalue(file->classes, t);
+       abc_asset_t*a = cls->asset;
+       if(a && a->tags) {
+           num++;
+       }
+    }
+    swf_SetU16(tag, num);
+    for(t=0;t<file->classes->num;t++) {
+       abc_class_t*cls = (abc_class_t*)array_getvalue(file->classes, t);
+       abc_asset_t*a = cls->asset;
+       if(a && a->tags) {
+           U16 id = swf_GetDefineID(a->tags->TAG);
+           char*fullname = abc_class_fullname(cls);
+           swf_SetU16(tag, id);
+           swf_SetString(tag, fullname);
+       }
+    }
+}
+
+TAG*swf_AssetsToTags(TAG*itag, asset_bundle_list_t*assets)
+{
+    char* bitmap = rfx_calloc(sizeof(char)*65536);
+    asset_bundle_list_t*l = assets;
+    dict_t*written = dict_new2(&ptr_type);
+    while(l) {
+       if(l->asset_bundle->used) {
+           abc_file_t*file = l->asset_bundle->file;
+           int t;
+           TAG* tag = 0;
+           for(t=0;t<file->classes->num;t++) {
+               abc_asset_t*a = ((abc_class_t*)array_getvalue(file->classes, t))->asset;
+               if(a) {
+                   tag = write_asset(tag, a, written);
+               }
+           }
+           
+           tag = swf_InsertTag(tag, ST_DOABC);
+           swf_WriteABC(tag, file);
+           tag = swf_InsertTag(tag, ST_SYMBOLCLASS);
+           swf_WriteABCSymbols(tag, file);
+
+           TAG*first = tag;
+           while(first && first->prev) 
+               first=first->prev;
+
+           SWF swf;
+           memset(&swf, 0, sizeof(SWF));
+           swf.firstTag = first;
+           swf_Relocate(&swf, bitmap);
+           if(!itag) {
+               itag = first;
+           } else {
+               itag->next = first;
+               first->prev = itag;
+               itag = tag;
+           }
+       }
+       l = l->next;
+    }
+    dict_destroy(written);
+    free(bitmap);
+    return itag;
+}
diff --git a/lib/as3/assets.h b/lib/as3/assets.h
new file mode 100644 (file)
index 0000000..7dda7c6
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef __abc_assets_h__
+#define __abc_assets_h__
+#include "abc.h"
+#include "registry.h"
+
+typedef struct _asset_resolver {
+    SWF*swf;
+    abc_asset_t**id2asset;
+    dict_t*name2asset;
+    U16 mainclass_id;
+} asset_resolver_t;
+
+asset_resolver_t* swf_ParseAssets(SWF*swf);
+void swf_ResolveAssets(asset_resolver_t*swf, abc_file_t*file);
+void swf_DumpAsset(FILE*fo, abc_asset_t*asset, const char*prefix);
+TAG*swf_AssetsToTags(TAG*tag, asset_bundle_list_t*assets);
+
+#endif //__abc_assets_h__
index 2e6beb0..e6571db 100644 (file)
@@ -27,6 +27,8 @@
 #include "parser.h"
 #include "parser.tab.h"
 #include "compiler.h"
+#include "registry.h"
+#include "assets.h"
 #include "../os.h"
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
@@ -342,6 +344,10 @@ void* as3_getcode()
     }
     return as3code;
 }
+void* as3_getassets(void*t)
+{
+    return swf_AssetsToTags((TAG*)t, registry_getassets());
+}
 char* as3_getglobalclass()
 {
     return as3_globalclass;
index c0092ec..8487755 100644 (file)
@@ -42,6 +42,7 @@ void as3_schedule_class_noerror(const char*package, const char*cls);
 void as3_warning(const char*format, ...);
 char* as3_getglobalclass();
 void* as3_getcode();
+void* as3_getassets(void*);
 void as3_destroy();
 
 #endif //__as3_compiler_h__
index 62c5152..b2255e3 100644 (file)
 #include "abc.h"
 #include "registry.h"
 #include "common.h"
-#include "common.h"
 #include "tokenizer.h"
+#include "assets.h"
 #include "../os.h"
 
-static void import_code(void*_abc, char*filename, int pass);
+static void import_code(void*_abc, char*filename, int pass, asset_bundle_t*a);
 
 void as3_import_abc(char*filename)
 {
@@ -36,8 +36,8 @@ void as3_import_abc(char*filename)
     tag->data = file->data;
     tag->len = file->len;
     abc_file_t*abc = swf_ReadABC(tag);
-    import_code(abc, filename, 0);
-    import_code(abc, filename, 1);
+    import_code(abc, filename, 0, 0);
+    import_code(abc, filename, 1, 0);
     swf_FreeABC(abc);
     memfile_close(file);
     free(tag);
@@ -48,13 +48,17 @@ void as3_import_swf(char*filename)
     SWF* swf = swf_OpenSWF(filename);
     if(!swf)
         return;
+    swf_FoldAll(swf);
+
     TAG*tag = swf->firstTag;
 
+    asset_resolver_t* assets =  swf_ParseAssets(swf);
+
     /* pass 1 */
     while(tag) {
         if(tag->id == ST_DOABC || tag->id == ST_RAWABC) {
             abc_file_t*abc = swf_ReadABC(tag);
-            import_code(abc, filename, 0);
+            import_code(abc, filename, 0, 0);
             swf_FreeABC(abc);
         }
         tag = tag->next;
@@ -64,15 +68,19 @@ void as3_import_swf(char*filename)
     /* pass 2 */
     while(tag) {
         if(tag->id == ST_DOABC || tag->id == ST_RAWABC) {
-            abc_file_t*abc = swf_ReadABC(tag);
-            import_code(abc, filename, 1);
-            swf_FreeABC(abc);
+            abc_file_t*abc = swf_ReadABC(tag); //FIXME: mem leak
+           swf_ResolveAssets(assets, abc);
+           NEW(asset_bundle_t, a);
+           a->file = abc;
+           registry_add_asset(a);
+            import_code(abc, filename, 1, a);
         }
         tag = tag->next;
     }
 
-    swf_FreeTags(swf);
+    //swf_FreeTags(swf); // FIXME: mem leak
     free(swf);
+
 }
 
 void as3_import_file(char*filename)
@@ -129,7 +137,7 @@ static classinfo_t*resolve_class(char*filename, char*what, multiname_t*n)
     return c;
 }
 
-static void import_code(void*_abc, char*filename, int pass)
+static void import_code(void*_abc, char*filename, int pass, asset_bundle_t*asset_bundle)
 {
     abc_file_t*abc = _abc;
     int t;
@@ -148,7 +156,7 @@ static void import_code(void*_abc, char*filename, int pass)
 
             multiname_list_t*i=cls->interfaces;
             classinfo_t*c = classinfo_register(access, package, name, list_length(i));
-            c->flags|=FLAG_BUILTIN;
+            c->flags|=FLAG_ASSET;
 
             if(cls->flags & CLASS_FINAL)
                 c->flags |= FLAG_FINAL;
@@ -167,6 +175,10 @@ static void import_code(void*_abc, char*filename, int pass)
         classinfo_t*c = (classinfo_t*)registry_find(package, name);
         if(!c) continue;
 
+       if(cls->asset) {
+           c->assets = asset_bundle;
+       }
+
         int nr = 0;
         multiname_list_t*i = cls->interfaces;
         while(i) {
@@ -281,7 +293,7 @@ static void import_code(void*_abc, char*filename, int pass)
                 v->flags |= trait->kind==TRAIT_CONST?FLAG_CONST:0;
                 m = (memberinfo_t*)v;
             }
-            m->flags |= FLAG_BUILTIN;
+            m->flags |= FLAG_ASSET;
             m->parent = 0;
         }
     }
@@ -289,6 +301,6 @@ static void import_code(void*_abc, char*filename, int pass)
 
 void as3_import_code(void*_abc)
 {
-    import_code(_abc, "", 0);
-    import_code(_abc, "", 1);
+    import_code(_abc, "", 0, 0);
+    import_code(_abc, "", 1, 0);
 }
index 85b36a6..1ce83a6 100644 (file)
@@ -126,7 +126,13 @@ int main(int argn, char*argv[])
     swf.movieSize.xmin = swf.movieSize.ymin = 0;
     swf.movieSize.xmax = 20*20;
     swf.movieSize.ymax = 10*20;
-    TAG*tag = swf.firstTag = swf_InsertTag(0, ST_DOABC);
+    TAG*tag = (TAG*)as3_getassets(0);
+    if(!swf.firstTag && tag) swf.firstTag = tag;
+
+    while(tag && tag->next) tag = tag->next;
+
+    tag = swf_InsertTag(tag, ST_DOABC);
+    if(!swf.firstTag && tag) swf.firstTag = tag;
     swf_WriteABC(tag, code);
 
     if(!mainclass)
index a5f5224..b181866 100644 (file)
@@ -2586,7 +2586,7 @@ IMPORT : "import" T_IDENTIFIER {
 IMPORT : "import" PACKAGEANDCLASS {
        PASS12
        slotinfo_t*s = registry_find($2->package, $2->name);
-       if(!s && as3_pass==1) {// || !(s->flags&FLAG_BUILTIN)) {
+       if(!s && as3_pass==1) {
            as3_schedule_class($2->package, $2->name);
        }
        /*if(s && s->kind == INFOTYPE_VAR && TYPE_IS_NAMESPACE(s->type)) {
@@ -3088,6 +3088,7 @@ CLASS: X_IDENTIFIER {
     slotinfo_t*s = find_class($1);
     if(!s) syntaxerror("Could not find class/method %s (current package: %s)\n", $1, state->package);
     $$ = (classinfo_t*)s;
+    registry_use(s);
 }
 
 PACKAGEANDCLASS : PACKAGE '.' X_IDENTIFIER {
@@ -3102,6 +3103,7 @@ PACKAGEANDCLASS : PACKAGE '.' X_IDENTIFIER {
     if(!s) syntaxerror("Couldn't find class/method %s.%s\n", $1, $3);
     free($1);$1=0;
     $$ = (classinfo_t*)s;
+    registry_use(s);
 }
 
 CLASS_SPEC: PACKAGEANDCLASS
@@ -3802,6 +3804,7 @@ MEMBER : E '.' SUBNODE {
         
         /* look at actual classes, in the current package and imported */
         if(!state->xmlfilter && (a = find_class(name))) {
+           registry_use(a);
             if(state->cls && state->cls->info == (classinfo_t*)a && i_am_static) {
                 o.c = abc_getlocal_0(0);
                 o.t = TYPE_CLASS((classinfo_t*)a);
index 5fd76cc..4b6b66c 100644 (file)
@@ -27,6 +27,7 @@
 #include "builtin.h"
 
 dict_t*registry_classes=0;
+asset_bundle_list_t*assets=0;
 
 // ----------------------- class signature ------------------------------
 
@@ -71,6 +72,32 @@ type_t memberinfo_type = {
     free: (free_func)dummy_destroy,
 };
 
+// ----------------------- assets -------------------------------------
+void registry_use(slotinfo_t*s)
+{
+    if(s->kind == INFOTYPE_CLASS) {
+       classinfo_t*c=(classinfo_t*)s;
+       if(c->assets) c->assets->used = 1;
+    } else if(s->kind == INFOTYPE_METHOD) {
+       methodinfo_t*m=(methodinfo_t*)s;
+       if(m->parent) {
+           registry_use((slotinfo_t*)m->parent);
+       }
+    } else if(s->kind == INFOTYPE_VAR) {
+       varinfo_t*v=(varinfo_t*)s;
+       if(v->parent) {
+           registry_use((slotinfo_t*)v->parent);
+       }
+    }
+}
+void registry_add_asset(asset_bundle_t*bundle)
+{
+    list_append(assets, bundle);
+}
+asset_bundle_list_t*registry_getassets()
+{
+    return assets;
+}
 // ----------------------- resolving ----------------------------------
 slotinfo_t* registry_resolve(slotinfo_t*_s)
 {
index 02cdbea..d63e879 100644 (file)
 #ifndef __abc_registry_h__
 #define __abc_registry_h__
 
-#include "pool.h"
+#include "abc.h"
 
+DECLARE(asset_bundle);
+DECLARE_LIST(asset_bundle);
 DECLARE(slotinfo);
 DECLARE(classinfo);
 DECLARE(memberinfo);
@@ -38,6 +40,7 @@ DECLARE_LIST(slotinfo);
 /* member/class flags */
 #define FLAG_FINAL 1
 #define FLAG_BUILTIN 128
+#define FLAG_ASSET 64
 
 /* member flags */
 #define FLAG_STATIC 2
@@ -79,6 +82,7 @@ struct _classinfo {
     dict_t members;
     dict_t static_members;
     void*data; //TODO: get rid of this- parser.y should pass type/value/code triples around
+    asset_bundle_t*assets;
     classinfo_t*interfaces[];
 };
 struct _memberinfo {
@@ -111,6 +115,11 @@ struct _varinfo /*extends memberinfo*/ {
     constant_t*value;
 };
 
+struct _asset_bundle {
+    abc_file_t*file;
+    char used;
+};
+
 extern type_t memberinfo_type;
 extern type_t slotinfo_type;
 char slotinfo_equals(slotinfo_t*c1, slotinfo_t*c2);
@@ -150,6 +159,10 @@ namespace_t access2namespace(U8 access, char*package);
 
 char registry_ispackage(const char*package);
 
+void registry_add_asset(asset_bundle_t*bundle);
+void registry_use(slotinfo_t*s);
+asset_bundle_list_t*registry_getassets();
+
 // static multinames
 classinfo_t voidclass;
 classinfo_t* registry_getanytype();
index 7772273..0869455 100644 (file)
@@ -234,7 +234,7 @@ void gfxtool_draw_dashed_line(gfxdrawer_t*d, gfxline_t*line, float*r, float phas
         return;
     }
     if(r[0]<0 || phase<0) {
-       fprintf(stderr, "gfxtool: invalid (negative) dashes: %f, phase=%f", r[0], phase);
+       fprintf(stderr, "gfxtool: invalid (negative) dashes: %f, phase=%f\n", r[0], phase);
        return;
     }
 
index f15c1f2..0af8b65 100644 (file)
@@ -76,7 +76,7 @@ static char* strf(char*format, ...)
     va_end(arglist);
     return strdup(buf);
 }
-#define PY_ERROR(s,args...) (PyErr_SetString(PyExc_Exception, strf(s, ## args)),(PyObject*)NULL)
+#define PY_ERROR(s,args...) (PyErr_SetString(PyExc_Exception, strf(s, ## args)),(void*)NULL)
 #define PY_NONE Py_BuildValue("s", 0)
 
 //---------------------------------------------------------------------
@@ -158,8 +158,9 @@ static gfxline_t*toLine(PyObject*_line)
     gfxline_t*last=&first;
     for(t=0;t<num;t++) {
         PyObject*p= PySequence_GetItem(_line, t);
-        if(!PyTuple_Check(p))
+        if(!PyTuple_Check(p)) {
             return PY_ERROR("each point must be a tuple");
+       }
         PyObject*_type = PyTuple_GetItem(p, 0);
         if(!PyString_Check(_type))
             return PY_ERROR("point tuples must start with a string");
index f903aa7..61bdc34 100644 (file)
@@ -1232,7 +1232,7 @@ int main (int argc,char ** argv)
        else
            printf("\n");
     }
-    printf("[HEADER]        File size: %ld%s\n", swf.fileSize, swf.compressed?" (Depacked)":"");
+    printf("[HEADER]        File size: %d%s\n", swf.fileSize, swf.compressed?" (Depacked)":"");
     printf("[HEADER]        Frame rate: %f\n",swf.frameRate/256.0);
     printf("[HEADER]        Frame count: %d\n",swf.frameCount);
     printf("[HEADER]        Movie width: %.2f",(swf.movieSize.xmax-swf.movieSize.xmin)/20.0);
@@ -1269,9 +1269,9 @@ int main (int argc,char ** argv)
        }
        if(cumulative) {
            filepos += tag->len;
-           printf("[%03x] %9ld %9ld %s%s", tag->id, tag->len, filepos, prefix, swf_TagGetName(tag));
+           printf("[%03x] %9d %9d %s%s", tag->id, tag->len, filepos, prefix, swf_TagGetName(tag));
        } else {
-           printf("[%03x] %9ld %s%s", tag->id, tag->len, prefix, swf_TagGetName(tag));
+           printf("[%03x] %9d %s%s", tag->id, tag->len, prefix, swf_TagGetName(tag));
        }
        
         if(tag->id == ST_PLACEOBJECT) {