public static ConstantDeclaration Parse(BytecodeReader reader, BytecodeReader decReader) { var result = new ConstantDeclaration(); var nameOffset = decReader.ReadUInt32(); result.RegisterSet = (RegisterSet)decReader.ReadUInt16(); result.RegisterIndex = decReader.ReadUInt16(); result.RegisterCount = decReader.ReadUInt16(); decReader.ReadUInt16(); //Reserved var typeInfoOffset = decReader.ReadUInt32(); var defaultValueOffset = decReader.ReadUInt32(); var nameReader = reader.CopyAtOffset((int)nameOffset); result.Name = nameReader.ReadString(); var typeReader = reader.CopyAtOffset((int)typeInfoOffset); result.Type = ConstantType.Parse(reader, typeReader); if (defaultValueOffset != 0) { //Note: thre are corrisponding def instructions. TODO: check that they are the same var defaultValueReader = reader.CopyAtOffset((int)defaultValueOffset); for (int i = 0; i < 4; i++) { result.DefaultValue.Add(defaultValueReader.ReadSingle()); } } return(result); }
/// <summary> /// Get the information of register by an offset, /// relative to the register index of this const declaration. /// </summary> /// <param name="offset">The offset, relative to this const declaration's initial address.</param> /// <returns>Information about the specified register.</returns> public ConstantRegisterData GetRegisterTypeByOffset(uint offset) { if (offset > RegisterCount) { throw new ArgumentOutOfRangeException(); } var originalOffset = offset; // keep track of the last visited type, which is the type of member being found ConstantType lastType = null; TraverseChildTree(ref offset, (type, name, i, d) => { lastType = type; }); // sanity check if (lastType == null) { throw new InvalidOperationException(); } // the offset of member, relative to the constant declaration's initial address var memberOffset = originalOffset - offset; return(new ConstantRegisterData(lastType, RegisterIndex + memberOffset)); }
public static StructMember Parse(BytecodeReader reader, BytecodeReader memberReader) { var result = new StructMember(); var nameOffset = memberReader.ReadUInt32(); var typeOffset = memberReader.ReadUInt32(); var nameReader = reader.CopyAtOffset((int)nameOffset); result.Name = nameReader.ReadString(); var typeReader = reader.CopyAtOffset((int)typeOffset); result.Type = ConstantType.Parse(reader, typeReader); return(result); }
public ConstantDeclaration(string name, RegisterSet registerSet, short registerIndex, short registerCount, ParameterClass parameterClass, ParameterType parameterType, int rows, int columns, int elements, List <float> defaultValue) { Name = name; RegisterSet = registerSet; RegisterIndex = (ushort)registerIndex; RegisterCount = (ushort)registerCount; Type = new ConstantType() { ParameterClass = parameterClass, ParameterType = parameterType, Rows = (uint)rows, Columns = (uint)columns, Elements = (uint)elements, }; DefaultValue = defaultValue; }
public static ConstantType Parse(BytecodeReader reader, BytecodeReader typeReader) { var result = new ConstantType(); result.ParameterClass = (ParameterClass)typeReader.ReadUInt16(); result.ParameterType = (ParameterType)typeReader.ReadUInt16(); result.Rows = typeReader.ReadUInt16(); result.Columns = typeReader.ReadUInt16(); result.Elements = typeReader.ReadUInt16(); var memberCount = typeReader.ReadUInt16(); var memberInfoOffset = typeReader.ReadUInt32(); if (memberCount != 0) { var memberReader = reader.CopyAtOffset((int)memberInfoOffset); for (int i = 0; i < memberCount; i++) { result.Members.Add(StructMember.Parse(reader, memberReader)); } } return(result); }
private static bool TraverseChildTree( string name, ConstantType type, ref uint remainedOffset, ChildTreeVisitor visitor, int depth) { for (var i = 0u; i < type.Elements; i++) { visitor(type, name, i, depth); uint registersOccupied; switch (type.ParameterClass) { case ParameterClass.Struct: if (!type.Members.Any()) { throw new NotImplementedException(); } foreach (var member in type.Members) { var found = TraverseChildTree(member.Name, member.Type, ref remainedOffset, visitor, depth + 1); if (found) { return(true); } } continue; case ParameterClass.Object: // sanity check if (type.Members.Any()) { throw new InvalidOperationException(); } if (remainedOffset == 0) { return(true); } remainedOffset -= 1; continue; case ParameterClass.MatrixColumns: case ParameterClass.MatrixRows: case ParameterClass.Vector: case ParameterClass.Scalar: // sanity check if (type.Members.Any()) { throw new InvalidOperationException(); } registersOccupied = type.ParameterClass == ParameterClass.MatrixColumns ? type.Columns : type.Rows; break; default: throw new NotImplementedException(); } // ParameterClass.MatrixColumns / ParameterClass.Rows // ParameterClass.Vector // ParameterClass.Scalar: switch (type.ParameterType) { case ParameterType.Bool: case ParameterType.Float: case ParameterType.Int: // double is not supported for now as it occupies more than 1 register // but it's not inside ParameterType? break; default: throw new NotImplementedException(); } if (remainedOffset < registersOccupied) { return(true); // here, remainedOffset intentionally left unchanged when returning true. } remainedOffset -= registersOccupied; } return(false); }
public ConstantRegisterData(ConstantType type, uint registerIndex) { Type = type; RegisterIndex = registerIndex; }