📄 swf5compiler.y
字号:
bufferWriteOp($1, SWFACTION_NEWEQUALS); } | expr "!=" expr { bufferConcat($1, $3); bufferWriteOp($1, SWFACTION_NEWEQUALS); bufferWriteOp($1, SWFACTION_LOGICALNOT); } | expr "<<" expr { bufferConcat($1, $3); bufferWriteOp($1, SWFACTION_SHIFTLEFT); } | expr ">>" expr { bufferConcat($1, $3); bufferWriteOp($1, SWFACTION_SHIFTRIGHT); } | expr ">>>" expr { bufferConcat($1, $3); bufferWriteOp($1, SWFACTION_SHIFTRIGHT2); } | expr '?' expr ':' expr { bufferWriteOp($1, SWFACTION_BRANCHIFTRUE); bufferWriteS16($1, 2); bufferWriteS16($1, bufferLength($5)+5); bufferConcat($1, $5); bufferWriteOp($1, SWFACTION_BRANCHALWAYS); bufferWriteS16($1, 2); bufferWriteS16($1, bufferLength($3)); bufferConcat($1, $3); } | lvalue '=' expr_or_obj { if($1.obj) /* obj[memexpr] or obj.ident */ { $$ = $1.obj; if($1.ident) bufferConcat($$, $1.ident); else bufferConcat($$, $1.memexpr); bufferConcat($$, $3); bufferWriteSetRegister($$, 0); bufferWriteOp($$, SWFACTION_SETMEMBER); bufferWriteRegister($$, 0); } else /* just ident */ { $$ = $3; bufferWriteOp($$, SWFACTION_DUP); bufferConcat($$, $1.ident); bufferWriteOp($$, SWFACTION_SWAP); bufferWriteOp($$, SWFACTION_SETVARIABLE); }/* tricky case missing here: lvalue ASSIGN expr *//* like in x = y += z; */ } | expr INSTANCEOF lvalue_expr { $$ = $1; bufferConcat($$, $3); bufferWriteOp($$, SWFACTION_INSTANCEOF); } ;expr_or_obj : expr | NEW identifier { $$ = newBuffer(); bufferWriteInt($$, 0); bufferWriteString($$, $2, strlen($2)+1); bufferWriteOp($$, SWFACTION_NEW); } | NEW identifier '(' expr_list ')' { $$ = $4.buffer; bufferWriteInt($$, $4.count); bufferWriteString($$, $2, strlen($2)+1); bufferWriteOp($$, SWFACTION_NEW); } | '[' expr_list ']' { $$ = $2.buffer; bufferWriteInt($$, $2.count); bufferWriteOp($$, SWFACTION_INITARRAY); } | emptybraces { $$ = newBuffer(); bufferWriteInt($$, 0); bufferWriteOp($$, SWFACTION_INITOBJECT); } | '{' objexpr_list '}' { $$ = $2.buffer; bufferWriteInt($$, $2.count); bufferWriteOp($$, SWFACTION_INITOBJECT); } ;primary : function_call | anon_function_decl | method_call | lvalue_expr | incdecop lvalue %prec "++" { if($2.obj) { if($2.ident) // expr . identifier { $$ = $2.obj; bufferWriteOp($$, SWFACTION_DUP); /* a, a */ bufferWriteBuffer($$, $2.ident); /* a, a, i */ bufferWriteOp($$, SWFACTION_SWAP); /* a, i, a */ bufferConcat($$, $2.ident); /* a, i, a, i */ bufferWriteOp($$, SWFACTION_GETMEMBER); bufferWriteOp($$, $1); bufferWriteSetRegister($$, 0); bufferWriteOp($$, SWFACTION_SETMEMBER); /* a.i = a.i+1 */ bufferWriteRegister($$, 0); /* a.i+1 */ } else // expr [ expr ] { $$ = $2.memexpr; /* i */ bufferConcat($$, $2.obj); /* i, a */ bufferWriteSetRegister($$, 0); /* ($2.memexpr can use reg0) */ bufferWriteOp($$, SWFACTION_SWAP); /* a, i */ bufferWriteOp($$, SWFACTION_DUP); /* a, i, i */ bufferWriteRegister($$, 0); /* a, i, i, a */ bufferWriteOp($$, SWFACTION_SWAP); /* a, i, a, i */ bufferWriteOp($$, SWFACTION_GETMEMBER); /* a, i, a[i] */ bufferWriteOp($$, $1); /* a, i, a[i]+1 */ bufferWriteSetRegister($$, 0); bufferWriteOp($$, SWFACTION_SETMEMBER); /* a[i] = a[i]+1 */ bufferWriteRegister($$, 0); /* a[i]+1 */ } } else // identifier { $$ = newBuffer(); bufferWriteBuffer($$, $2.ident); bufferWriteOp($$, SWFACTION_GETVARIABLE); bufferWriteOp($$, $1); bufferWriteOp($$, SWFACTION_DUP); bufferConcat($$, $2.ident); bufferWriteOp($$, SWFACTION_SWAP); bufferWriteOp($$, SWFACTION_SETVARIABLE); } } | lvalue incdecop %prec POSTFIX { if($1.obj) { if($1.ident) { $$ = $1.obj; /* a */ bufferWriteOp($$, SWFACTION_DUP); /* a, a */ bufferWriteBuffer($$, $1.ident); /* a, a, i */ bufferWriteOp($$, SWFACTION_GETMEMBER); /* a, a.i */ bufferWriteSetRegister($$, 0); bufferWriteOp($$, SWFACTION_SWAP); /* a.i, a */ bufferConcat($$, $1.ident); /* a.i, a, i */ bufferWriteRegister($$, 0); /* a.i, a, i, a.i */ bufferWriteOp($$, $2); /* a.i, a, i, a.i+1 */ bufferWriteOp($$, SWFACTION_SETMEMBER); } else { $$ = $1.memexpr; bufferConcat($$, $1.obj); /* i, a */ bufferWriteSetRegister($$, 0); bufferWriteOp($$, SWFACTION_SWAP); /* a, i */ bufferWriteOp($$, SWFACTION_DUP); /* a, i, i */ bufferWriteRegister($$, 0); /* a, i, i, a */ bufferWriteOp($$, SWFACTION_SWAP); /* a, i, a, i */ bufferWriteOp($$, SWFACTION_GETMEMBER); /* a, i, a[i] */ bufferWriteSetRegister($$, 0); bufferWriteOp($$, $2); /* a, i, a[i]+1 */ bufferWriteOp($$, SWFACTION_SETMEMBER); bufferWriteRegister($$, 0); /* a[i] */ } } else { $$ = newBuffer(); bufferWriteBuffer($$, $1.ident); bufferWriteOp($$, SWFACTION_GETVARIABLE); bufferWriteOp($$, SWFACTION_DUP); bufferWriteOp($$, $2); bufferConcat($$, $1.ident); bufferWriteOp($$, SWFACTION_SWAP); bufferWriteOp($$, SWFACTION_SETVARIABLE); } } | '(' expr ')' { $$ = $2; } | '-' INTEGER %prec UMINUS { $$ = newBuffer(); bufferWriteInt($$, -$2); } | INTEGER { $$ = newBuffer(); bufferWriteInt($$, $1); } | '-' DOUBLE %prec UMINUS { $$ = newBuffer(); bufferWriteDouble($$, -$2); } | DOUBLE { $$ = newBuffer(); bufferWriteDouble($$, $1); } | BOOLEAN { $$ = newBuffer(); bufferWriteBoolean($$, $1); } | NULLVAL { $$ = newBuffer(); bufferWriteNull($$); } | STRING { $$ = newBuffer(); bufferWriteString($$, $1, strlen($1)+1); free($1); } ;init_vars : init_var | init_vars ',' init_var { $$ = $1; bufferConcat($$, $3); } ;init_var : identifier '=' expr_or_obj { $$ = newBuffer(); bufferWriteString($$, $1, strlen($1)+1); bufferConcat($$, $3); bufferWriteOp($$, SWFACTION_VAREQUALS); } | identifier { $$ = newBuffer(); bufferWriteString($$, $1, strlen($1)+1); bufferWriteOp($$, SWFACTION_VAR); } ;assign_stmt : ASM '{' { asmBuffer = newBuffer(); } opcode_list '}' { $$ = asmBuffer; } | VAR init_vars { $$ = $2; } | void_function_call | function_call { $$ = $1; bufferWriteOp($$, SWFACTION_POP); } | method_call { $$ = $1; bufferWriteOp($$, SWFACTION_POP); } | incdecop lvalue %prec INCR { if($2.obj) { if($2.ident) { $$ = $2.obj; /* a */ bufferWriteOp($$, SWFACTION_DUP); /* a, a */ bufferWriteBuffer($$, $2.ident); /* a, a, i */ bufferWriteOp($$, SWFACTION_GETMEMBER); /* a, a.i */ bufferWriteOp($$, $1); /* a, a.i+1 */ bufferConcat($$, $2.ident); /* a, a.i+1, i */ bufferWriteOp($$, SWFACTION_SWAP); /* a, i, a.i+1 */ bufferWriteOp($$, SWFACTION_SETMEMBER); /* a.i = a.i+1 */ } else { /* weird contortions so that $2.memexpr can use reg 0 */ $$ = $2.memexpr; /* i */ bufferConcat($$, $2.obj); /* i, a */ bufferWriteSetRegister($$, 0); bufferWriteOp($$, SWFACTION_SWAP); /* a, i */ bufferWriteOp($$, SWFACTION_DUP); /* a, i, i */ bufferWriteRegister($$, 0); /* a, i, i, a */ bufferWriteOp($$, SWFACTION_SWAP); /* a, i, a, i */ bufferWriteOp($$, SWFACTION_GETMEMBER); /* a, i, a[i] */ bufferWriteOp($$, $1); /* a, i, a[i]+1 */ bufferWriteOp($$, SWFACTION_SETMEMBER); /* a[i] = a[i]+1 */ } } else { $$ = $2.ident; bufferWriteOp($$, SWFACTION_DUP); bufferWriteOp($$, SWFACTION_GETVARIABLE); bufferWriteOp($$, $1); bufferWriteOp($$, SWFACTION_SETVARIABLE); } } | lvalue incdecop %prec POSTFIX { if($1.obj) { if($1.ident) { $$ = $1.obj; /* a */ bufferWriteOp($$, SWFACTION_DUP); /* a, a */ bufferWriteBuffer($$, $1.ident); /* a, a, i */ bufferWriteOp($$, SWFACTION_GETMEMBER); /* a, a.i */ bufferWriteOp($$, $2); /* a, a.i+1 */ bufferConcat($$, $1.ident); /* a, a.i+1, i */ bufferWriteOp($$, SWFACTION_SWAP); /* a, i, a.i+1 */ bufferWriteOp($$, SWFACTION_SETMEMBER); /* a.i = a.i+1 */ } else { /* weird contortions so that $1.memexpr can use reg 0 */ $$ = $1.memexpr; /* i */ bufferConcat($$, $1.obj); /* i, a */ bufferWriteSetRegister($$, 0); bufferWriteOp($$, SWFACTION_SWAP); /* a, i */ bufferWriteOp($$, SWFACTION_DUP); /* a, i, i */ bufferWriteRegister($$, 0); /* a, i, i, a */ bufferWriteOp($$, SWFACTION_SWAP); /* a, i, a, i */ bufferWriteOp($$, SWFACTION_GETMEMBER); /* a, i, a[i] */ bufferWriteOp($$, $2); /* a, i, a[i]+1 */ bufferWriteOp($$, SWFACTION_SETMEMBER); /* a[i] = a[i]+1 */ } } else { $$ = $1.ident; bufferWriteOp($$, SWFACTION_DUP); bufferWriteOp($$, SWFACTION_GETVARIABLE); bufferWriteOp($$, $2); bufferWriteOp($$, SWFACTION_SETVARIABLE); } } | lvalue '=' expr_or_obj { if($1.obj) { $$ = $1.obj; if($1.ident) bufferConcat($$, $1.ident); else bufferConcat($$, $1.memexpr); bufferConcat($$, $3); bufferWriteOp($$, SWFACTION_SETMEMBER); } else { $$ = $1.ident; bufferConcat($$, $3); bufferWriteOp($$, SWFACTION_SETVARIABLE); } } | lvalue assignop expr { if($1.obj) { if($1.ident) { $$ = $1.obj; /* a */ bufferWriteOp($$, SWFACTION_DUP); /* a, a */ bufferWriteBuffer($$, $1.ident); /* a, a, i */ bufferWriteOp($$, SWFACTION_GETMEMBER); /* a, a.i */ bufferConcat($$, $3); /* a, a.i, v */ bufferWriteOp($$, $2); /* a, a.i+v */ bufferConcat($$, $1.ident); /* a, a.i+v, i */ bufferWriteOp($$, SWFACTION_SWAP); /* a, i, a.i+v */ bufferWriteOp($$, SWFACTION_SETMEMBER); /* a.i = a.i+v */ } else { $$ = $1.memexpr; /* i */ bufferConcat($$, $1.obj); /* i, a */ bufferWriteSetRegister($$, 0); bufferWriteOp($$, SWFACTION_SWAP); /* a, i */ bufferWriteOp($$, SWFACTION_DUP); /* a, i, i */ bufferWriteRegister($$, 0); /* a, i, i, a */ bufferWriteOp($$, SWFACTION_SWAP); /* a, i, a, i */ bufferWriteOp($$, SWFACTION_GETMEMBER); /* a, i, a[i] */ bufferConcat($$, $3); /* a, i, a[i], v */ bufferWriteOp($$, $2); /* a, i, a[i]+v */ bufferWriteOp($$, SWFACTION_SETMEMBER); /* a[i] = a[i]+v */ } } else { $$ = $1.ident; bufferWriteOp($$, SWFACTION_DUP); bufferWriteOp($$, SWFACTION_GETVARIABLE); bufferConcat($$, $3); bufferWriteOp($$, $2); bufferWriteOp($$, SWFACTION_SETVARIABLE); } } ;/* assembler stuff */opcode_list : opcode | opcode_list opcode { $$ = $1 + $2; } ;with : WITH { $$ = bufferWriteOp(asmBuffer, SWFACTION_WITH); } opcode_list END { $$ = $<len>2 + $3; bufferPatchLength(asmBuffer, $3); } ;push_item : STRING { $$ = bufferWriteConstantString(asmBuffer,(byte*) $1, strlen($1)+1); } | INTEGER { bufferWriteU8(asmBuffer, PUSH_INT); $$ = bufferWriteInt(asmBuffer, $1)+1; } | DOUBLE { bufferWriteU8(asmBuffer, PUSH_DOUBLE); $$ = bufferWriteDouble(asmBuffer, $1)+1; } | BOOLEAN { bufferWriteU8(asmBuffer, PUSH_BOOLEAN); $$ = bufferWriteU8(asmBuffer, $1)+1; } | NULLVAL { $$ = bufferWriteU8(asmBuffer, PUSH_NULL); } | REGISTER { bufferWriteU8(asmBuffer, PUSH_REGISTER); $$ = bufferWriteU8(asmBuffer, (char)atoi($1))+1; } ;push_list : push_item { $$ = $1; } | push_list ',' push_item { $$ += $3; } ;opcode : PUSH { $$ = bufferWriteOp(asmBuffer, SWFACTION_PUSHDATA); $$ += bufferWriteS16(asmBuffer, 0); } push_list { $$ = $<len>2 + $3; bufferPatchLength(asmBuffer, $3); } | with | SETREGISTER REGISTER { $$ = bufferWriteOp(asmBuffer, SWFACTION_SETREGISTER); $$ += bufferWriteS16(asmBuffer, 1); $$ += bufferWriteU8(asmBuffer, (char)atoi($2)); } /* no args */ | CALLFUNCTION { $$ = bufferWriteOp(asmBuffer, SWFACTION_CALLFUNCTION); } | RETURN { $$ = bufferWriteOp(asmBuffer, SWFACTION_RETURN); } | CALLMETHOD { $$ = bufferWriteOp(asmBuffer, SWFACTION_CALLMETHOD); } | AND { $$ = bufferWriteOp(asmBuffer, SWFACTION_BITWISEAND); } | OR { $$ = bufferWriteOp(asmBuffer, SWFACTION_BITWISEOR); } | XOR { $$ = bufferWriteOp(asmBuffer, SWFACTION_BITWISEXOR); } | MODULO { $$ = bufferWriteOp(asmBuffer, SWFACTION_MODULO); } | ADD { $$ = bufferWriteOp(asmBuffer, SWFACTION_NEWADD); } | LESSTHAN { $$ = bufferWriteOp(asmBuffer, SWFACTION_NEWLESSTHAN); } | EQUALS { $$ = bufferWriteOp(asmBuffer, SWFACTION_NEWEQUALS); } | INC { $$ = bufferWriteOp(asmBuffer, SWFACTION_INCREMENT); } | DEC { $$ = bufferWriteOp(asmBuffer, SWFACTION_DECREMENT); } | TYPEOF { $$ = bufferWriteOp(asmBuffer, SWFACTION_TYPEOF); } | INSTANCEOF { $$ = bufferWriteOp(asmBuffer, SWFACTION_INSTANCEOF); } | ENUMERATE { $$ = bufferWriteOp(asmBuffer, SWFACTION_ENUMERATE); } | DELETE { $$ = bufferWriteOp(asmBuffer, SWFACTION_DELETE); } | NEW { $$ = bufferWriteOp(asmBuffer, SWFACTION_NEW); } | INITARRAY { $$ = bufferWriteOp(asmBuffer, SWFACTION_INITARRAY); } | INITOBJECT { $$ = bufferWriteOp(asmBuffer, SWFACTION_INITOBJECT); } | GETMEMBER { $$ = bufferWriteOp(asmBuffer, SWFACTION_GETMEMBER); } | SETMEMBER { $$ = bufferWriteOp(asmBuffer, SWFACTION_SETMEMBER); } | SHIFTLEFT { $$ = bufferWriteOp(asmBuffer, SWFACTION_SHIFTLEFT); } | SHIFTRIGHT { $$ = bufferWriteOp(asmBuffer, SWFACTION_SHIFTRIGHT); } | SHIFTRIGHT2 { $$ = bufferWriteOp(asmBuffer, SWFACTION_SHIFTRIGHT2); } | VAR { $$ = bufferWriteOp(asmBuffer, SWFACTION_VAR); } | VAREQUALS { $$ = bufferWriteOp(asmBuffer, SWFACTION_VAREQUALS); } /* f4 ops */ | OLDADD { $$ = bufferWriteOp(asmBuffer, SWFACTION_ADD); } | SUBTRACT { $$ = bufferWriteOp(asmBuffer, SWFACTION_SUBTRACT); } | MULTIPLY { $$ = bufferWriteOp(asmBuffer, SWFACTION_MULTIPLY); } | DIVIDE { $$ = bufferWriteOp(asmBuffer, SWFACTION_DIVIDE); } | OLDEQUALS { $$ = bufferWriteOp(asmBuffer, SWFACTION_EQUAL); } | OLDLESSTHAN { $$ = bufferWriteOp(asmBuffer, SWFACTION_LESSTHAN); } | LOGICALAND { $$ = bufferWriteOp(asmBuffer, SWFACTION_LOGICALAND); } | LOGICALOR { $$ = bufferWriteOp(asmBuffer, SWFACTION_LOGICALOR); } | NOT { $$ = bufferWriteOp(asmBuffer, SWFACTION_LOGICALNOT); } | STRINGEQ { $$ = bufferWriteOp(asmBuffer, SWFACTION_STRINGEQ); } | STRINGLENGTH { $$ = bufferWriteOp(asmBuffer, SWFACTION_STRINGLENGTH); } | SUBSTRING { $$ = bufferWriteOp(asmBuffer, SWFACTION_SUBSTRING); } | INT { $$ = bufferWriteOp(asmBuffer, SWFACTION_INT); } | DUP { $$ = bufferWriteOp(asmBuffer, SWFACTION_DUP); } | SWAP { $$ = bufferWriteOp(asmBuffer, SWFACTION_SWAP); } | POP { $$ = bufferWriteOp(asmBuffer, SWFACTION_POP); } | GETVARIABLE { $$ = bufferWriteOp(asmBuffer, SWFACTION_GETVARIABLE); } | SETVARIABLE { $$ = bufferWriteOp(asmBuffer, SWFACTION_SETVARIABLE); } | SETTARGETEXPRESSION { $$ = bufferWriteOp(asmBuffer, SWFACTION_SETTARGETEXPRESSION); } | CONCAT { $$ = bufferWriteOp(asmBuffer, SWFACTION_STRINGCONCAT); } | DUPLICATEMOVIECLIP { $$ = bufferWriteOp(asmBuffer, SWFACTION_DUPLICATECLIP); } | REMOVEMOVIECLIP { $$ = bufferWriteOp(asmBuffer, SWFACTION_REMOVECLIP); } | TRACE { $$ = bufferWriteOp(asmBuffer, SWFACTION_TRACE); } | STRINGLESSTHAN { $$ = bufferWriteOp(asmBuffer, SWFACTION_STRINGCOMPARE); } | RANDOM { $$ = bufferWriteOp(asmBuffer, SWFACTION_RANDOM); } | MBLENGTH { $$ = bufferWriteOp(asmBuffer, SWFACTION_MBLENGTH); } | ORD { $$ = bufferWriteOp(asmBuffer, SWFACTION_ORD); } | CHR { $$ = bufferWriteOp(asmBuffer, SWFACTION_CHR); } | GETTIMER { $$ = bufferWriteOp(asmBuffer, SWFACTION_GETTIMER); } | MBSUBSTRING { $$ = bufferWriteOp(asmBuffer, SWFACTION_MBSUBSTRING); } | MBORD { $$ = bufferWriteOp(asmBuffer, SWFACTION_MBORD); } | MBCHR { $$ = bufferWriteOp(asmBuffer, SWFACTION_MBCHR); } /* with args */ | BRANCHALWAYS STRING { $$ = bufferWriteOp(asmBuffer, SWFACTION_BRANCHALWAYS); $$ += bufferWriteS16(asmBuffer, 2); $$ += bufferBranchTarget(asmBuffer, $2); } | BRANCHIFTRUE STRING { $$ = bufferWriteOp(asmBuffer, SWFACTION_BRANCHIFTRUE); $$ += bufferWriteS16(asmBuffer, 2); $$ += bufferBranchTarget(asmBuffer, $2); } ;%%
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -