From 1e89c03bd6957df3e662002fe86480637c25c1ae Mon Sep 17 00:00:00 2001 From: Matthias Kramm Date: Sat, 7 Feb 2009 23:34:44 +0100 Subject: [PATCH] schedule import files during parsing --- lib/as3/parser.y | 71 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 20 deletions(-) diff --git a/lib/as3/parser.y b/lib/as3/parser.y index 6f77570..3783b29 100644 --- a/lib/as3/parser.y +++ b/lib/as3/parser.y @@ -31,6 +31,7 @@ #include "registry.h" #include "code.h" #include "opcodes.h" +#include "compiler.h" extern int a3_lex(); @@ -199,8 +200,8 @@ extern int a3_lex(); %type IMPLEMENTS_LIST %type EXTENDS %type EXTENDS_LIST -%type CLASS PACKAGEANDCLASS QNAME -%type QNAME_LIST +%type CLASS PACKAGEANDCLASS CLASS_SPEC +%type CLASS_SPEC_LIST %type TYPE //%type VARIABLE %type VAR_READ @@ -458,6 +459,9 @@ static void old_state() void initialize_file(char*filename) { + if(state) { + syntaxerror("invalid call to initialize_file during parsing of another file"); + } new_state(); state->package = strdup(filename); @@ -470,7 +474,10 @@ void finish_file() if(!state || state->level!=1) { syntaxerror("unexpected end of file in pass %d", as3_pass); } - free(state->package);state->package=0; + free(state->method);state->method=0; + + //free(state->package);state->package=0; // used in registry + state_destroy(state);state=0; } @@ -705,8 +712,6 @@ static void startclass(int flags, char*classname, classinfo_t*extends, classinfo } new_state(); state->cls = rfx_calloc(sizeof(classstate_t)); - state->method = rfx_calloc(sizeof(methodstate_t)); // method state, for static constructor - state->method->variable_count = 1; token_list_t*t=0; classinfo_list_t*mlist=0; @@ -722,7 +727,7 @@ static void startclass(int flags, char*classname, classinfo_t*extends, classinfo char*package=0; if(!(flags&FLAG_PUBLIC) && !state->package) { - access = ACCESS_PRIVATE; package = current_filename; + access = ACCESS_PRIVATE; package = strdup(current_filename_short); } else if(!(flags&FLAG_PUBLIC) && state->package) { access = ACCESS_PACKAGEINTERNAL; package = state->package; } else if(state->package) { @@ -732,6 +737,10 @@ static void startclass(int flags, char*classname, classinfo_t*extends, classinfo } if(as3_pass==1) { + state->method = rfx_calloc(sizeof(methodstate_t)); // method state, for static constructor + state->method->variable_count = 1; + dict_put(global->token2info, (void*)(ptroff_t)as3_tokencount, state->method); + if(registry_findclass(package, classname)) { syntaxerror("Package \"%s\" already contains a class called \"%s\"", package, classname); } @@ -741,6 +750,8 @@ static void startclass(int flags, char*classname, classinfo_t*extends, classinfo } if(as3_pass == 2) { + state->method = dict_lookup(global->token2info, (void*)(ptroff_t)as3_tokencount); + state->cls->info = registry_findclass(package, classname); parserassert((int)state->cls->info); @@ -1310,7 +1321,7 @@ static classinfo_t* find_class(char*name) /* try global package */ c = registry_findclass("", name); if(c) return c; - + /* try local "filename" package */ c = registry_findclass(current_filename_short, name); if(c) return c; @@ -1349,7 +1360,6 @@ static code_t* toreadwrite(code_t*in, code_t*middlepart, char justassign, char r [prefix code] ([dup]) [read instruction] [middlepart] [setvar] [write instruction] [getvar] */ - if(in && in->opcode == OPCODE_COERCE_A) { in = code_cutlast(in); } @@ -1469,6 +1479,7 @@ static code_t* toreadwrite(code_t*in, code_t*middlepart, char justassign, char r c = code_append(c, write); c = code_append(c, r); } else { + code_free(r);r=0; temp = gettempvar(); if(prefix) { c = code_append(c, prefix); @@ -1639,6 +1650,7 @@ PROGRAM_CODE: PACKAGE_DECLARATION | FUNCTION_DECLARATION | SLOT_DECLARATION | PACKAGE_INITCODE + | T_IDENTIFIER "::" T_IDENTIFIER '{' PROGRAM_CODE_LIST '}' // conditional compilation | ';' MAYBE_INPACKAGE_CODE_LIST: | INPACKAGE_CODE_LIST @@ -1650,6 +1662,7 @@ INPACKAGE_CODE: INTERFACE_DECLARATION | FUNCTION_DECLARATION | SLOT_DECLARATION | PACKAGE_INITCODE + | T_IDENTIFIER "::" T_IDENTIFIER '{' INPACKAGE_CODE_LIST '}' // conditional compilation | ';' MAYBECODE: CODE {$$=$1;} @@ -1725,6 +1738,7 @@ ONE_VARIABLE: T_IDENTIFIER MAYBETYPE MAYBEEXPRESSION $$ = converttype($$, $3.t, $2); $$ = abc_setlocal($$, index); } else { + code_free($3.c); $$ = defaultvalue(0, $2); $$ = abc_setlocal($$, index); } @@ -1734,6 +1748,7 @@ ONE_VARIABLE: T_IDENTIFIER MAYBETYPE MAYBEEXPRESSION $$ = abc_coerce_a($$); $$ = abc_setlocal($$, index); } else { + code_free($3.c); $$ = code_new(); } } @@ -2083,7 +2098,13 @@ PACKAGE_DECLARATION : "package" PACKAGE '{' {PASS12 startpackage($2);free($2);$2 PACKAGE_DECLARATION : "package" '{' {PASS12 startpackage("");} MAYBE_INPACKAGE_CODE_LIST '}' {PASS12 endpackage();$$=0;} -IMPORT : "import" QNAME { +IMPORT : "import" PACKAGEANDCLASS { + PASS1 + if(!registry_findclass($2->package, $2->name)) { + as3_schedule_class($2->package, $2->name); + } + + PASS2 classinfo_t*c = $2; if(!c) syntaxerror("Couldn't import class\n"); @@ -2092,6 +2113,12 @@ IMPORT : "import" QNAME { $$=0; } IMPORT : "import" PACKAGE '.' '*' { + PASS1 + if(strncmp("flash.", $2, 6)) { + as3_schedule_package($2); + } + + PASS2 NEW(import_t,i); i->package = $2; state_has_imports(); @@ -2117,13 +2144,13 @@ MODIFIER : KW_PUBLIC {PASS12 $$=FLAG_PUBLIC;} | KW_INTERNAL {PASS12 $$=FLAG_PACKAGEINTERNAL;} EXTENDS : {$$=registry_getobjectclass();} -EXTENDS : KW_EXTENDS QNAME {$$=$2;} +EXTENDS : KW_EXTENDS CLASS_SPEC {$$=$2;} EXTENDS_LIST : {PASS12 $$=list_new();} -EXTENDS_LIST : KW_EXTENDS QNAME_LIST {PASS12 $$=$2;} +EXTENDS_LIST : KW_EXTENDS CLASS_SPEC_LIST {PASS12 $$=$2;} IMPLEMENTS_LIST : {PASS12 $$=list_new();} -IMPLEMENTS_LIST : KW_IMPLEMENTS QNAME_LIST {PASS12 $$=$2;} +IMPLEMENTS_LIST : KW_IMPLEMENTS CLASS_SPEC_LIST {PASS12 $$=$2;} CLASS_DECLARATION : MAYBE_MODIFIERS "class" T_IDENTIFIER EXTENDS IMPLEMENTS_LIST @@ -2242,7 +2269,7 @@ STATICCONSTANT : T_BYTE {$$ = constant_new_int($1);} STATICCONSTANT : T_INT {$$ = constant_new_int($1);} STATICCONSTANT : T_UINT {$$ = constant_new_uint($1);} STATICCONSTANT : T_FLOAT {$$ = constant_new_float($1);} -STATICCONSTANT : T_STRING {$$ = constant_new_string2($1.str,$1.len);} +STATICCONSTANT : T_STRING {$$ = constant_new_string2($1.str,$1.len);free((char*)$1.str);} //STATICCONSTANT : T_NAMESPACE {$$ = constant_new_namespace($1);} STATICCONSTANT : "true" {$$ = constant_new_true($1);} STATICCONSTANT : "false" {$$ = constant_new_false($1);} @@ -2354,20 +2381,24 @@ CLASS: T_IDENTIFIER { } PACKAGEANDCLASS : PACKAGE '.' T_IDENTIFIER { - PASS1 $$=0; + PASS1 static classinfo_t c; + memset(&c, 0, sizeof(c)); + c.package = $1; + c.name = $3; + $$=&c; PASS2 $$ = registry_findclass($1, $3); if(!$$) syntaxerror("Couldn't find class %s.%s\n", $1, $3); free($1);$1=0; } -QNAME: PACKAGEANDCLASS - | CLASS +CLASS_SPEC: PACKAGEANDCLASS + | CLASS -QNAME_LIST : QNAME {PASS12 $$=list_new();list_append($$, $1);} -QNAME_LIST : QNAME_LIST ',' QNAME {PASS12 $$=$1;list_append($$,$3);} +CLASS_SPEC_LIST : CLASS_SPEC {PASS12 $$=list_new();list_append($$, $1);} +CLASS_SPEC_LIST : CLASS_SPEC_LIST ',' CLASS_SPEC {PASS12 $$=$1;list_append($$,$3);} -TYPE : QNAME {$$=$1;} +TYPE : CLASS_SPEC {$$=$1;} | '*' {$$=registry_getanytype();} | "void" {$$=registry_getanytype();} /* @@ -2591,7 +2622,7 @@ CONSTANT : T_UINT {$$.c = abc_pushuint(0, $1); CONSTANT : T_FLOAT {$$.c = abc_pushdouble(0, $1); $$.t = TYPE_FLOAT; } -CONSTANT : T_STRING {$$.c = abc_pushstring2(0, &$1); +CONSTANT : T_STRING {$$.c = abc_pushstring2(0, &$1);free((char*)$1.str); $$.t = TYPE_STRING; } CONSTANT : "undefined" {$$.c = abc_pushundefined(0); -- 1.7.10.4