From 9ed9a87914fc9a590967d46de404e0f6290b7bb2 Mon Sep 17 00:00:00 2001 From: Matthias Kramm Date: Fri, 1 Jan 2010 18:45:04 -0800 Subject: [PATCH] implemented asset resolving --- configure.in | 2 +- lib/Makefile.in | 2 +- lib/as3/Makefile | 8 +-- lib/as3/abc.c | 32 +++++++-- lib/as3/abc.h | 12 +++- lib/as3/assets.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/as3/assets.h | 18 +++++ lib/as3/compiler.c | 6 ++ lib/as3/compiler.h | 1 + lib/as3/import.c | 40 +++++++---- lib/as3/main.c | 8 ++- lib/as3/parser.y | 5 +- lib/as3/registry.c | 27 +++++++ lib/as3/registry.h | 15 +++- lib/gfxtools.c | 2 +- lib/python/gfx.c | 5 +- src/swfdump.c | 6 +- 17 files changed, 355 insertions(+), 36 deletions(-) create mode 100644 lib/as3/assets.c create mode 100644 lib/as3/assets.h diff --git a/configure.in b/configure.in index d32235f..ba082c5 100644 --- a/configure.in +++ b/configure.in @@ -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= diff --git a/lib/Makefile.in b/lib/Makefile.in index 3c8fa52..f0b7ebe 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -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 diff --git a/lib/as3/Makefile b/lib/as3/Makefile index b3ecd23..0ddf96a 100644 --- a/lib/as3/Makefile +++ b/lib/as3/Makefile @@ -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 - diff --git a/lib/as3/abc.c b/lib/as3/abc.c index 59aa880..6de2c2d 100644 --- a/lib/as3/abc.c +++ b/lib/as3/abc.c @@ -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;tinterfaces, 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;snum;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); diff --git a/lib/as3/abc.h b/lib/as3/abc.h index d58f2d7..3b6a134 100644 --- a/lib/as3/abc.h +++ b/lib/as3/abc.h @@ -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 index 0000000..06fadd8 --- /dev/null +++ b/lib/as3/assets.c @@ -0,0 +1,202 @@ +#include +#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;tdata[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;tmainclass_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;tclasses->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;tclasses->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;tclasses->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;tclasses->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 index 0000000..7dda7c6 --- /dev/null +++ b/lib/as3/assets.h @@ -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__ diff --git a/lib/as3/compiler.c b/lib/as3/compiler.c index 2e6beb0..e6571db 100644 --- a/lib/as3/compiler.c +++ b/lib/as3/compiler.c @@ -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 @@ -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; diff --git a/lib/as3/compiler.h b/lib/as3/compiler.h index c0092ec..8487755 100644 --- a/lib/as3/compiler.h +++ b/lib/as3/compiler.h @@ -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__ diff --git a/lib/as3/import.c b/lib/as3/import.c index 62c5152..b2255e3 100644 --- a/lib/as3/import.c +++ b/lib/as3/import.c @@ -23,11 +23,11 @@ #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); } diff --git a/lib/as3/main.c b/lib/as3/main.c index 85b36a6..1ce83a6 100644 --- a/lib/as3/main.c +++ b/lib/as3/main.c @@ -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) diff --git a/lib/as3/parser.y b/lib/as3/parser.y index a5f5224..b181866 100644 --- a/lib/as3/parser.y +++ b/lib/as3/parser.y @@ -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); diff --git a/lib/as3/registry.c b/lib/as3/registry.c index 5fd76cc..4b6b66c 100644 --- a/lib/as3/registry.c +++ b/lib/as3/registry.c @@ -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) { diff --git a/lib/as3/registry.h b/lib/as3/registry.h index 02cdbea..d63e879 100644 --- a/lib/as3/registry.h +++ b/lib/as3/registry.h @@ -24,8 +24,10 @@ #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(); diff --git a/lib/gfxtools.c b/lib/gfxtools.c index 7772273..0869455 100644 --- a/lib/gfxtools.c +++ b/lib/gfxtools.c @@ -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; } diff --git a/lib/python/gfx.c b/lib/python/gfx.c index f15c1f2..0af8b65 100644 --- a/lib/python/gfx.c +++ b/lib/python/gfx.c @@ -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;tlen; - 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) { -- 1.7.10.4