public static void walkActions()

in modules/swfutils/src/java/flash/swf/MovieMetaData.java [599:1059]


	public static void walkActions(ActionList c, int swfVersion, String[] pool, String className, List<Integer> profileOffsets)
	{
		// assumption: ActionContext c is always not null! try-catch-finally may be busted.
		if (c == null) return;

		Stack<Object> evalStack = new Stack<Object>();
		HashMap<Object, Object> variables = new HashMap<Object, Object>();

		// 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.get(key) == null)
				{
					evalStack.push(key);
				}
				else
				{
					evalStack.push(variables.get(key));
				}
				break;
			case ActionConstants.sactionStringExtract:
			case ActionConstants.sactionMBStringExtract:
				// pop, pop, pop, push
				pop(evalStack);
				pop(evalStack);
				break;
			case ActionConstants.sactionPush:
				Push p = (Push) a;
				Object o = p.value;
				int type = Push.getTypeCode(o);
				switch (type)
				{
				case Push.kPushStringType:
					evalStack.push(o);
					break;
				case Push.kPushNullType:
					evalStack.push("null");
					break;
				case Push.kPushUndefinedType:
					evalStack.push("undefined");
					break;
				case Push.kPushRegisterType:
					evalStack.push(registers[((Byte)o).intValue()&0xFF]);
					break;
				case Push.kPushConstant8Type:
				case Push.kPushConstant16Type:
					evalStack.push(pool[((Number) o).intValue()&0xFFFF]);
					break;
				case Push.kPushFloatType:
					evalStack.push(o + "F");
					break;
				case Push.kPushBooleanType:
				case Push.kPushDoubleType:
				case Push.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.put(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 (Integer.parseInt(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.put(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.size();
						if (depth != 0)
						{
							o = evalStack.peek();
							if (o == dummy)
							{
								f.name = "";
							}
							else if (o != null)
							{
								f.name = o.toString();
							}
						}
						evalStack.push(dummy);
					}

					if ("null".equals(f.name))
					{
						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)
					{
						StringBuilder buffer = new StringBuilder();
						int depth = evalStack.size();
						for (int k = depth - 1; k >= 0; k--)
						{
							o = evalStack.get(k);
							if (o == dummy)
							{
								break;
							}
							else if (k == depth - 1)
							{
								buffer.append(o);
							}
							else
							{
								buffer.insert(0, '.');
								buffer.insert(0, o);
							}
						}
						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(new Integer(offset - 13)); // Push 1
					profileOffsets.add(new Integer(offset - 5)); // Push 'profile'
					profileOffsets.add(new Integer(offset)); // CallFunction
					profileOffsets.add(new Integer(offset + 1)); // Pop
				}
				int n = ((Number) pop(evalStack)).intValue();
				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 = ((Number) pop(evalStack)).intValue();
				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 = ((Number) pop(evalStack)).intValue();
				for (int k = 0; k < num; k++)
				{
					pop(evalStack);
				}
				evalStack.push(dummy);
				break;
			case ActionConstants.sactionInitObject:
				num = ((Number) pop(evalStack)).intValue() * 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[Integer.parseInt(o2.toString())] + "." + pool[Integer.parseInt(o1.toString())]);
					}
					catch (Exception ex)
					{
						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 instanceof String)
				{
					try {
						n = Integer.parseInt((String) obj2);
					}
					catch (NumberFormatException ex)
					{
						n = 1;
					}
				}
				else
				{
					n = ((Number) obj2).intValue();
				}
				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 = ((Number) pop(evalStack)).intValue();
			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;
			}
		}
	}