public override void storeRegister(StoreRegister action) { start(action); String variableName = variableNameForRegister(action.register); out_Renamed.WriteLine(" $" + action.register + ((variableName == null)?"":" \t\t; " + variableName)); }
public virtual void storeRegister(StoreRegister action) { }
/// <summary> Walk the actions filling in the names of functions as we go. /// This is done by looking for DefineFunction's actions and then /// examining the content of the stack for a name. /// /// </summary> /// <param name="c">list of actions to be traversed /// </param> /// <param name="swfVersion">version of swf file that housed the ActionList (just use 7 if you don't know) /// </param> /// <param name="pool">optional; constant pool for the list of actions /// </param> /// <param name="className">optional; used to locate a constructor function (i.e if funcName == className) /// </param> /// <param name="profileOffsets">optional; is filled with offsets if a call to a /// function named 'profile' is encountered. Can be null if caller is not /// interested in obtaining this information. /// </param> public static void walkActions(ActionList c, int swfVersion, String[] pool, String className, System.Collections.IList profileOffsets) { // assumption: ActionContext c is always not null! try-catch-finally may be busted. if (c == null) { return; } System.Collections.Stack evalStack = new System.Collections.Stack(); System.Collections.Hashtable variables = new System.Collections.Hashtable(); // loop again, this time, we register all the actions... int offset; Action a; for (int i = 0; i < c.size(); i++) { offset = c.getOffset(i); a = c.getAction(i); switch (a.code) { // Flash 1 and 2 actions case ActionConstants.sactionHasLength: case ActionConstants.sactionNone: case ActionConstants.sactionGotoFrame: case ActionConstants.sactionGetURL: case ActionConstants.sactionNextFrame: case ActionConstants.sactionPrevFrame: case ActionConstants.sactionPlay: case ActionConstants.sactionStop: case ActionConstants.sactionToggleQuality: case ActionConstants.sactionStopSounds: case ActionConstants.sactionWaitForFrame: // Flash 3 Actions case ActionConstants.sactionSetTarget: case ActionConstants.sactionGotoLabel: // no action break; // Flash 4 Actions case ActionConstants.sactionAdd: case ActionConstants.sactionSubtract: case ActionConstants.sactionMultiply: case ActionConstants.sactionDivide: case ActionConstants.sactionEquals: case ActionConstants.sactionLess: case ActionConstants.sactionAnd: case ActionConstants.sactionOr: case ActionConstants.sactionStringEquals: case ActionConstants.sactionStringAdd: case ActionConstants.sactionStringLess: case ActionConstants.sactionMBStringLength: case ActionConstants.sactionGetProperty: // pop, pop, push pop(evalStack); break; case ActionConstants.sactionNot: case ActionConstants.sactionStringLength: case ActionConstants.sactionToInteger: case ActionConstants.sactionCharToAscii: case ActionConstants.sactionAsciiToChar: case ActionConstants.sactionMBCharToAscii: case ActionConstants.sactionMBAsciiToChar: case ActionConstants.sactionRandomNumber: // pop, push break; case ActionConstants.sactionGetVariable: Object key = pop(evalStack); if (variables[key] == null) { evalStack.Push(key); } else { evalStack.Push(variables[key]); } break; case ActionConstants.sactionStringExtract: case ActionConstants.sactionMBStringExtract: // pop, pop, pop, push pop(evalStack); pop(evalStack); break; case ActionConstants.sactionPush: Push p = (Push)a; System.Object o = p.value; int type = Push.getTypeCode(o); switch (type) { case ActionConstants.kPushStringType: evalStack.Push(o); break; case ActionConstants.kPushNullType: evalStack.Push("null"); break; case ActionConstants.kPushUndefinedType: evalStack.Push("undefined"); break; case ActionConstants.kPushRegisterType: evalStack.Push(registers[(int)((SByte)o) & 0xFF]); break; case ActionConstants.kPushConstant8Type: case ActionConstants.kPushConstant16Type: evalStack.Push(pool[Convert.ToInt32(((ValueType)o)) & 0xFFFF]); break; case ActionConstants.kPushFloatType: evalStack.Push(o + "F"); break; case ActionConstants.kPushBooleanType: case ActionConstants.kPushDoubleType: case ActionConstants.kPushIntegerType: evalStack.Push(o); break; default: evalStack.Push("type" + type); break; } break; case ActionConstants.sactionIf: pop(evalStack); break; case ActionConstants.sactionPop: case ActionConstants.sactionCall: case ActionConstants.sactionGotoFrame2: case ActionConstants.sactionSetTarget2: case ActionConstants.sactionRemoveSprite: case ActionConstants.sactionWaitForFrame2: case ActionConstants.sactionTrace: // pop pop(evalStack); break; case ActionConstants.sactionJump: case ActionConstants.sactionEndDrag: // no action break; case ActionConstants.sactionSetVariable: key = pop(evalStack); Object val = pop(evalStack); variables[key] = val; break; case ActionConstants.sactionGetURL2: // pop, pop pop(evalStack); pop(evalStack); break; case ActionConstants.sactionSetProperty: case ActionConstants.sactionCloneSprite: // pop, pop, pop pop(evalStack); pop(evalStack); pop(evalStack); break; case ActionConstants.sactionStartDrag: // pop, pop, pop, if the 3rd pop is non-zero, pop, pop, pop, pop pop(evalStack); pop(evalStack); Object obj = pop(evalStack); if (Int32.Parse(obj.ToString()) != 0) { pop(evalStack); pop(evalStack); pop(evalStack); pop(evalStack); } break; case ActionConstants.sactionGetTime: // push evalStack.Push(dummy); break; // Flash 5 actions case ActionConstants.sactionDelete: pop(evalStack); break; case ActionConstants.sactionDefineLocal: // pop, pop val = pop(evalStack); key = pop(evalStack); variables[key] = val; break; case ActionConstants.sactionDefineFunction: case ActionConstants.sactionDefineFunction2: DefineFunction f = (DefineFunction)a; if (swfVersion > 6 && className != null) { if (f.name == null || f.name.Length == 0) { int depth = evalStack.Count; if (depth != 0) { o = evalStack.Peek(); if (o == dummy) { f.name = ""; } else if (o != null) { f.name = o.ToString(); } } evalStack.Push(dummy); } if (f.name == "null") { f.name = ""; } if (f.name == null || f.name.Length == 0) { // do nothing... it's an anonymous function! } else if (!className.EndsWith(f.name)) { f.name = className + "." + f.name; } else { f.name = className + ".[constructor]"; } } else { if (f.name == null || f.name.Length == 0) { System.Text.StringBuilder buffer = new System.Text.StringBuilder(); Boolean bFirst = true; foreach (Object ob in evalStack) { if (ob == dummy) { break; } else if (bFirst) { buffer.Append(ob); bFirst = false; } else { buffer.Insert(0, '.'); buffer.Insert(0, ob); } } f.name = buffer.ToString(); if (f.name != null && f.name.IndexOf(".prototype.") == -1) { f.name = ""; } evalStack.Push(dummy); } } // evalActions(f.actions); break; case ActionConstants.sactionCallFunction: Object function = pop(evalStack); if (profileOffsets != null && "profile".Equals(function)) { profileOffsets.Add((Int32)(offset - 13)); // Push 1 profileOffsets.Add((Int32)(offset - 5)); // Push 'profile' profileOffsets.Add((Int32)offset); // CallFunction profileOffsets.Add((Int32)(offset + 1)); // Pop } int n = Convert.ToInt32(((System.ValueType)pop(evalStack))); for (int k = 0; k < n; k++) { pop(evalStack); } evalStack.Push(dummy); break; case ActionConstants.sactionReturn: // return function() { ... } doesn't push... pop(evalStack); break; case ActionConstants.sactionModulo: // pop, push break; case ActionConstants.sactionNewObject: pop(evalStack); int num = Convert.ToInt32(((ValueType)pop(evalStack))); for (int k = 0; k < num; k++) { pop(evalStack); } evalStack.Push(dummy); break; case ActionConstants.sactionDefineLocal2: case ActionConstants.sactionDelete2: case ActionConstants.sactionAdd2: case ActionConstants.sactionLess2: // pop pop(evalStack); break; case ActionConstants.sactionInitArray: // pop, if the first pop is non-zero, keep popping num = Convert.ToInt32(((ValueType)pop(evalStack))); for (int k = 0; k < num; k++) { pop(evalStack); } evalStack.Push(dummy); break; case ActionConstants.sactionInitObject: num = Convert.ToInt32(((ValueType)pop(evalStack))) * 2; for (int k = 0; k < num; k++) { pop(evalStack); } evalStack.Push(dummy); break; case ActionConstants.sactionTargetPath: case ActionConstants.sactionEnumerate: case ActionConstants.sactionToNumber: case ActionConstants.sactionToString: case ActionConstants.sactionTypeOf: // no action break; case ActionConstants.sactionStoreRegister: StoreRegister r = (StoreRegister)a; registers[r.register] = evalStack.Peek(); break; case ActionConstants.sactionEquals2: // pop, pop, push // if (evalStack.size() >= 2) { pop(evalStack); } break; case ActionConstants.sactionPushDuplicate: evalStack.Push(dummy); break; case ActionConstants.sactionStackSwap: // pop, pop, push, push break; case ActionConstants.sactionGetMember: // pop, pop, concat, push Object o1 = pop(evalStack); Object o2 = pop(evalStack); if (pool != null) { try { evalStack.Push(pool[Int32.Parse(o2.ToString())] + "." + pool[Int32.Parse(o1.ToString())]); } catch (Exception) { if (o1 == dummy || o2 == dummy) { evalStack.Push(dummy); } else { evalStack.Push(o2 + "." + o1); } } } else { evalStack.Push(o2 + "." + o1); } break; case ActionConstants.sactionSetMember: // pop, pop, pop pop(evalStack); pop(evalStack); pop(evalStack); break; case ActionConstants.sactionIncrement: case ActionConstants.sactionDecrement: break; case ActionConstants.sactionCallMethod: pop(evalStack); pop(evalStack); Object obj2 = pop(evalStack); if (obj2 is String) { try { n = Int32.Parse((String)obj2); } catch (FormatException) { n = 1; } } else { n = Convert.ToInt32(((ValueType)obj2)); } for (int k = 0; k < n; k++) { pop(evalStack); } evalStack.Push(dummy); break; case ActionConstants.sactionNewMethod: /*Object meth =*/ pop(evalStack); /*Object cls =*/ pop(evalStack); num = Convert.ToInt32(((ValueType)pop(evalStack))); for (int k = 0; k < num; k++) { pop(evalStack); } evalStack.Push(dummy); break; case ActionConstants.sactionWith: // pop pop(evalStack); break; case ActionConstants.sactionConstantPool: pool = ((ConstantPool)a).pool; // no action break; case ActionConstants.sactionStrictMode: break; case ActionConstants.sactionBitAnd: case ActionConstants.sactionBitOr: case ActionConstants.sactionBitLShift: // pop, push break; case ActionConstants.sactionBitXor: case ActionConstants.sactionBitRShift: case ActionConstants.sactionBitURShift: pop(evalStack); break; // Flash 6 actions case ActionConstants.sactionInstanceOf: pop(evalStack); break; case ActionConstants.sactionEnumerate2: // pop, push, more pushes? break; case ActionConstants.sactionStrictEquals: case ActionConstants.sactionGreater: case ActionConstants.sactionStringGreater: pop(evalStack); break; // FEATURE_EXCEPTIONS case ActionConstants.sactionTry: // do nothing break; case ActionConstants.sactionThrow: pop(evalStack); break; // FEATURE_AS2_INTERFACES case ActionConstants.sactionCastOp: break; case ActionConstants.sactionImplementsOp: break; // Reserved for Quicktime case ActionConstants.sactionQuickTime: break; default: break; } } }