internal static PexObjectFunction Create(PexParseMeta parse) { var ret = new PexObjectFunction(); ret.ReturnTypeName = parse.ReadString(); ret.DocString = parse.ReadString(); ret.RawUserFlags = parse.Reader.ReadUInt32(); ret.Flags = (FunctionFlags)parse.Reader.ReadUInt8(); var parameters = parse.Reader.ReadUInt16(); for (var i = 0; i < parameters; i++) { var parameter = PexObjectFunctionVariable.Create(parse); ret.Parameters.Add(parameter); } var locals = parse.Reader.ReadUInt16(); for (var i = 0; i < locals; i++) { var local = PexObjectFunctionVariable.Create(parse); ret.Locals.Add(local); } var instructions = parse.Reader.ReadUInt16(); for (var i = 0; i < instructions; i++) { var instruction = PexObjectFunctionInstruction.Create(parse); ret.Instructions.Add(instruction); } return(ret); }
internal static PexObjectFunctionInstruction Create(PexParseMeta parse) { var ret = new PexObjectFunctionInstruction(); ret.OpCode = (InstructionOpcode)parse.Reader.ReadUInt8(); var arguments = InstructionOpCodeArguments.GetArguments(ret.OpCode); foreach (var current in arguments) { var argument = PexObjectVariableData.Create(parse); ret.Arguments.Add(argument); switch (current) { case '*' when argument.VariableType != VariableType.Integer || !argument.IntValue.HasValue: throw new InvalidDataException($"Variable-Length Arguments require an Integer Argument! Argument is {argument.VariableType}"); case '*': { for (var i = 0; i < argument.IntValue.Value; i++) { var anotherArgument = PexObjectVariableData.Create(parse); ret.Arguments.Add(anotherArgument); } break; } //TODO: figure out what do to with this /* * u apparently means unsigned integer and indicates that the integer value we get should be * interpreted as an unsigned integer. */ case 'u' when argument.VariableType != VariableType.Integer: throw new InvalidDataException($"Argument is unsigned integer but Variable Type is not integer: {argument.VariableType}"); } } return(ret); }