/// <summary> /// Convenience method for creating an opcode from a position in a byte array. /// Returns an opcode object with references resolved and advances the position /// to the next place in the byte array. /// </summary> /// <param name="reader">Where to read the next opcode from</param> /// <param name="abc">The code within which we're reading</param> /// <returns>A new Opcode object, or null if there was no more data to be read</returns> public static Opcode BuildOpcode(ABCDataTypeReader reader, AbcCode abc) { Opcode op = new Opcode(abc); int code; code = reader.ReadUI8(); if (code == -1) { return(null); } op.Instruction = (uint)code; if (OpcodeTable[code] == null) { throw new SWFModellerException( SWFModellerError.Internal, "Bad opcode 0x" + code.ToString("X") + " at @" + (reader.Offset - 1)); } OpcodeDef info = (OpcodeDef)OpcodeTable[code]; List <object> args = new List <object>(); if (info.Mnemonic == Mnemonics.LookupSwitch) { /* Special case: Has a variable arg */ args.Add(reader.ReadSI24()); /* default offset */ uint caseCount = reader.ReadU30(); args.Add(caseCount); for (int i = 0; i < caseCount + 1; i++) { args.Add(reader.ReadSI24()); } } else { if (info.Args != null) { foreach (ArgType type in info.Args) { switch (type) { case ArgType.MultinameU30: args.Add(abc.GetMultiname((int)reader.ReadU30())); break; case ArgType.OffsetS24: args.Add(reader.ReadSI24()); break; case ArgType.StringU30: args.Add(abc.StringConsts[reader.ReadU30()]); break; case ArgType.RegisterU30: case ArgType.ObjectRegisterU30: case ArgType.PropertyRegisterU30: args.Add(reader.ReadU30()); break; case ArgType.ByteU8: args.Add((byte)reader.ReadUI8()); break; case ArgType.ShortU30: case ArgType.IntU30: case ArgType.UintU30: case ArgType.DoubleU30: args.Add(reader.ReadU30()); break; case ArgType.ShortS30: args.Add((int)reader.ReadU30()); break; case ArgType.ByteS8: args.Add(reader.ReadSI8()); break; case ArgType.NamespaceU30: args.Add(abc.GetNamespace((int)reader.ReadU30())); break; case ArgType.MethodU30: args.Add(abc.GetMethod((int)reader.ReadU30())); break; case ArgType.CountU30: args.Add(reader.ReadU30()); break; case ArgType.ClassU30: args.Add(abc.GetClass((int)reader.ReadU30())); break; case ArgType.ExceptionU30: args.Add(reader.ReadU30()); break; case ArgType.StackU8: args.Add((byte)reader.ReadUI8()); break; case ArgType.SlotU30: args.Add(reader.ReadU30()); break; case ArgType.DebugU8: args.Add((byte)reader.ReadUI8()); break; case ArgType.DebugTypeU30: args.Add(reader.ReadU30()); break; case ArgType.StringU8: args.Add(abc.StringConsts[reader.ReadUI8()]); break; case ArgType.LineNumberU30: args.Add(reader.ReadU30()); break; default: /* ISSUE 73 */ throw new SWFModellerException( SWFModellerError.UnimplementedFeature, "Oops. Not done " + type.ToString()); } } } } op.Args = args.ToArray(); return(op); }
/// <summary> /// Convenience method for creating an opcode from a position in a byte array. /// Returns an opcode object with references resolved and advances the position /// to the next place in the byte array. /// </summary> /// <param name="reader">Where to read the next opcode from</param> /// <param name="abc">The code within which we're reading</param> /// <returns>A new Opcode object, or null if there was no more data to be read</returns> public static Opcode BuildOpcode(ABCDataTypeReader reader, AbcCode abc) { Opcode op = new Opcode(abc); int code; code = reader.ReadUI8(); if (code == -1) { return null; } op.Instruction = (uint)code; if (OpcodeTable[code] == null) { throw new SWFModellerException( SWFModellerError.Internal, "Bad opcode 0x" + code.ToString("X") + " at @" + (reader.Offset - 1)); } OpcodeDef info = (OpcodeDef)OpcodeTable[code]; List<object> args = new List<object>(); if (info.Mnemonic == Mnemonics.LookupSwitch) { /* Special case: Has a variable arg */ args.Add(reader.ReadSI24()); /* default offset */ uint caseCount = reader.ReadU30(); args.Add(caseCount); for (int i = 0; i < caseCount + 1; i++) { args.Add(reader.ReadSI24()); } } else { if (info.Args != null) { foreach (ArgType type in info.Args) { switch (type) { case ArgType.MultinameU30: args.Add(abc.GetMultiname((int)reader.ReadU30())); break; case ArgType.OffsetS24: args.Add(reader.ReadSI24()); break; case ArgType.StringU30: args.Add(abc.StringConsts[reader.ReadU30()]); break; case ArgType.RegisterU30: case ArgType.ObjectRegisterU30: case ArgType.PropertyRegisterU30: args.Add(reader.ReadU30()); break; case ArgType.ByteU8: args.Add((byte)reader.ReadUI8()); break; case ArgType.ShortU30: case ArgType.IntU30: case ArgType.UintU30: case ArgType.DoubleU30: args.Add(reader.ReadU30()); break; case ArgType.ShortS30: args.Add((int)reader.ReadU30()); break; case ArgType.ByteS8: args.Add(reader.ReadSI8()); break; case ArgType.NamespaceU30: args.Add(abc.GetNamespace((int)reader.ReadU30())); break; case ArgType.MethodU30: args.Add(abc.GetMethod((int)reader.ReadU30())); break; case ArgType.CountU30: args.Add(reader.ReadU30()); break; case ArgType.ClassU30: args.Add(abc.GetClass((int)reader.ReadU30())); break; case ArgType.ExceptionU30: args.Add(reader.ReadU30()); break; case ArgType.StackU8: args.Add((byte)reader.ReadUI8()); break; case ArgType.SlotU30: args.Add(reader.ReadU30()); break; case ArgType.DebugU8: args.Add((byte)reader.ReadUI8()); break; case ArgType.DebugTypeU30: args.Add(reader.ReadU30()); break; case ArgType.StringU8: args.Add(abc.StringConsts[reader.ReadUI8()]); break; case ArgType.LineNumberU30: args.Add(reader.ReadU30()); break; default: /* ISSUE 73 */ throw new SWFModellerException( SWFModellerError.UnimplementedFeature, "Oops. Not done " + type.ToString()); } } } } op.Args = args.ToArray(); return op; }