internal static Proto Load(BinaryReader reader, bool isChunk) { var lineDefined = reader.ReadInt32(); var lastLineDefined = reader.ReadInt32(); var numParams = reader.ReadByte(); var hasVarArgs = reader.ReadByte() != 0; var maxStack = reader.ReadByte(); //code var codeLen = reader.ReadInt32(); var code = new Instruction[codeLen]; for (int i = 0; i < code.Length; i++) { code[i].PackedValue = reader.ReadUInt32(); } //constants Value[] constants; var numConsts = reader.ReadInt32(); if (numConsts != 0) { constants = new Value[numConsts]; for (int i = 0; i < constants.Length; i++) { var type = reader.ReadByte(); switch (type) { case 0: //nil break; case 1: //bool constants[i].Set(reader.ReadByte() != 0); break; case 3: //number constants[i].Set(reader.ReadDouble()); break; case 4: //string constants[i].Set(LoadString(reader)); break; default: throw new InvalidDataException("Invalid constant type."); } } } else { constants = null; } //inner functions Proto[] innerProtos; int numInnerProtos = reader.ReadInt32(); if (numInnerProtos != 0) { innerProtos = new Proto[numInnerProtos]; for (int i = 0; i < innerProtos.Length; i++) { innerProtos[i] = Load(reader, false); } } else { innerProtos = null; } //upvalues UpValDesc[] upValues; int numUpValues = reader.ReadInt32(); if (numUpValues != 0) { upValues = new UpValDesc[numUpValues]; for (int i = 0; i < upValues.Length; i++) { upValues[i].Kind = reader.ReadByte() != 0 ? UpValueKind.StackPointing : UpValueKind.ValuePointing; upValues[i].Index = reader.ReadByte(); } } else { upValues = null; } //debug info #if DEBUG_API var source = LoadString(reader); int[] lineInfos; int numLineInfos = reader.ReadInt32(); if (numLineInfos != 0) { lineInfos = new int[numLineInfos]; for (int i = 0; i < lineInfos.Length; i++) { lineInfos[i] = reader.ReadInt32(); } } else { lineInfos = null; } LocalVarDesc[] localVars; int numLocalVars = reader.ReadInt32(); if (numLocalVars != 0) { localVars = new LocalVarDesc[numLocalVars]; for (int i = 0; i < numLocalVars; i++) { localVars[i].Name = LoadString(reader); localVars[i].StartPC = reader.ReadInt32(); localVars[i].endPC = reader.ReadInt32(); } } else { localVars = null; } int numUpValueInfos = reader.ReadInt32(); if (numUpValueInfos > numUpValues) { throw new InvalidDataException("Too much debug info."); } for (int i = 0; i < numUpValueInfos; i++) { upValues[i].Name = LoadString(reader); } #else SkipString(reader); //source int numLineInfos = reader.ReadInt32(); reader.BaseStream.Seek(numLineInfos * 4, SeekOrigin.Current); int numLocalVars = reader.ReadInt32(); for (int i = 0; i < numLocalVars; i++) { SkipString(reader); reader.BaseStream.Seek(8, SeekOrigin.Current); } int numUpValueInfos = reader.ReadInt32(); if (numUpValueInfos > numUpValues) { throw new InvalidDataException("Too much debug info."); } for (int i = 0; i < numUpValueInfos; i++) { SkipString(reader); } #endif //and done! var ret = isChunk ? new ChunkProto() : new Proto(); ret.NumParams = numParams; ret.HasVarArgs = hasVarArgs; ret.MaxStack = maxStack; ret.Code = code; ret.Constants = constants; ret.InnerProtos = innerProtos; ret.UpValues = upValues; ret.startLine = lineDefined; ret.endLine = lastLineDefined; #if DEBUG_API ret.source = source; ret.lineInfo = lineInfos; ret.localVars = localVars; #endif return(ret); }
internal static Proto Load( BinaryReader reader, bool isChunk ) { var lineDefined = reader.ReadInt32(); var lastLineDefined = reader.ReadInt32(); var numParams = reader.ReadByte(); var hasVarArgs = reader.ReadByte() != 0; var maxStack = reader.ReadByte(); //code var codeLen = reader.ReadInt32(); var code = new Instruction[codeLen]; for( int i = 0; i < code.Length; i++ ) code[i].PackedValue = reader.ReadUInt32(); //constants Value[] constants; var numConsts = reader.ReadInt32(); if( numConsts != 0 ) { constants = new Value[numConsts]; for( int i = 0; i < constants.Length; i++ ) { var type = reader.ReadByte(); switch( type ) { case 0: //nil break; case 1: //bool constants[i].Set( reader.ReadByte() != 0 ); break; case 3: //number constants[i].Set( reader.ReadDouble() ); break; case 4: //string constants[i].Set( LoadString( reader ) ); break; default: throw new InvalidDataException( "Invalid constant type." ); } } } else { constants = null; } //inner functions Proto[] innerProtos; int numInnerProtos = reader.ReadInt32(); if( numInnerProtos != 0 ) { innerProtos = new Proto[numInnerProtos]; for( int i = 0; i < innerProtos.Length; i++ ) innerProtos[i] = Load( reader, false ); } else { innerProtos = null; } //upvalues UpValDesc[] upValues; int numUpValues = reader.ReadInt32(); if( numUpValues != 0 ) { upValues = new UpValDesc[numUpValues]; for( int i = 0; i < upValues.Length; i++ ) { upValues[i].Kind = reader.ReadByte() != 0 ? UpValueKind.StackPointing : UpValueKind.ValuePointing; upValues[i].Index = reader.ReadByte(); } } else { upValues = null; } //debug info #if DEBUG_API var source = LoadString( reader ); int[] lineInfos; int numLineInfos = reader.ReadInt32(); if( numLineInfos != 0 ) { lineInfos = new int[numLineInfos]; for( int i = 0; i < lineInfos.Length; i++ ) lineInfos[i] = reader.ReadInt32(); } else { lineInfos = null; } LocalVarDesc[] localVars; int numLocalVars = reader.ReadInt32(); if( numLocalVars != 0 ) { localVars = new LocalVarDesc[numLocalVars]; for( int i = 0; i < numLocalVars; i++ ) { localVars[i].Name = LoadString( reader ); localVars[i].StartPC = reader.ReadInt32(); localVars[i].endPC = reader.ReadInt32(); } } else { localVars = null; } int numUpValueInfos = reader.ReadInt32(); if( numUpValueInfos > numUpValues ) throw new InvalidDataException( "Too much debug info." ); for( int i = 0; i < numUpValueInfos; i++ ) upValues[i].Name = LoadString( reader ); #else SkipString( reader ); //source int numLineInfos = reader.ReadInt32(); reader.BaseStream.Seek( numLineInfos * 4, SeekOrigin.Current ); int numLocalVars = reader.ReadInt32(); for( int i = 0; i < numLocalVars; i++ ) { SkipString( reader ); reader.BaseStream.Seek( 8, SeekOrigin.Current ); } int numUpValueInfos = reader.ReadInt32(); if( numUpValueInfos > numUpValues ) throw new InvalidDataException( "Too much debug info." ); for( int i = 0; i < numUpValueInfos; i++ ) SkipString( reader ); #endif //and done! var ret = isChunk ? new ChunkProto() : new Proto(); ret.NumParams = numParams; ret.HasVarArgs = hasVarArgs; ret.MaxStack = maxStack; ret.Code = code; ret.Constants = constants; ret.InnerProtos = innerProtos; ret.UpValues = upValues; ret.startLine = lineDefined; ret.endLine = lastLineDefined; #if DEBUG_API ret.source = source; ret.lineInfo = lineInfos; ret.localVars = localVars; #endif return ret; }