Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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;
        }