public static bool VerifyArgTypes(Mnemonics mnemonic, object[] args) { OpcodeDef?defRef = OpcodeTable[(uint)mnemonic]; if (defRef == null) { return(false); } OpcodeDef def = defRef.Value; if (def.Args == null) { return(args.Length == 0); } if (def.Args.Length != args.Length) { return(false); } for (int i = 0; i < args.Length; i++) { Type expected = Opcode.InternalTypes[(int)def.Args[i]]; Type passed = args[i].GetType(); if (expected != passed) { return(false); } if (def.Args[i] == ArgType.ByteS8) { if ((int)args[i] > 127 || (int)args[i] < -128) { return(false); } } } return(true); }
/// <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); }