From 2a3c79df83e800d5dfe75a1a3b140ed81da2b1d6 Mon Sep 17 00:00:00 2001 From: Sean Dague Date: Mon, 16 Jul 2007 15:40:11 +0000 Subject: changed to native line ending encoding --- .../Engines/LSLEngine/LSLHandler/LSO_Parser.cs | 1216 ++++++++++---------- 1 file changed, 608 insertions(+), 608 deletions(-) (limited to 'OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Parser.cs') diff --git a/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Parser.cs b/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Parser.cs index 2da1189..ebe4465 100644 --- a/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Parser.cs +++ b/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Parser.cs @@ -1,608 +1,608 @@ - using System; - using System.Collections.Generic; - using System.Text; - using System.IO; - using System.Reflection; - using System.Reflection.Emit; -using OpenSim.Region.Scripting; - - namespace OpenSim.ScriptEngines.LSL - { - class LSO_Parser - { - private bool Debug = true; - private FileStream fs; - private BinaryReader br; - private LSO_Struct.Header myHeader; - - private TypeBuilder typeBuilder; - private ScriptInfo WorldAPI; - - /// - /// Parse LSO file. - /// Reads LSO ByteCode into memory structures. - /// TODO: What else does it do? - /// - /// FileName of LSO ByteCode file - public void ParseFile(string FileName, ScriptInfo _WorldAPI, ref TypeBuilder _typeBuilder) - { - typeBuilder = _typeBuilder; - WorldAPI = _WorldAPI; - // Open - SendToDebug("Opening filename: " + FileName); - fs = File.Open(FileName, FileMode.Open, FileAccess.Read, FileShare.Read); - br = new BinaryReader(fs, Encoding.BigEndianUnicode); - - - // The LSO Format consist of 6 major blocks: header, statics, functions, states, heap, and stack. - - - // HEADER BLOCK - SendToDebug("Reading HEADER BLOCK at: 0"); - fs.Seek(0, SeekOrigin.Begin); - myHeader = new LSO_Struct.Header(); - myHeader.TM = BitConverter.ToUInt32(br_read(4), 0); - myHeader.IP = BitConverter.ToUInt32(br_read(4), 0); - myHeader.VN = BitConverter.ToUInt32(br_read(4), 0); - myHeader.BP = BitConverter.ToUInt32(br_read(4), 0); - myHeader.SP = BitConverter.ToUInt32(br_read(4), 0); - myHeader.HR = BitConverter.ToUInt32(br_read(4), 0); - myHeader.HP = BitConverter.ToUInt32(br_read(4), 0); - myHeader.CS = BitConverter.ToUInt32(br_read(4), 0); - myHeader.NS = BitConverter.ToUInt32(br_read(4), 0); - myHeader.CE = BitConverter.ToUInt32(br_read(4), 0); - myHeader.IE = BitConverter.ToUInt32(br_read(4), 0); - myHeader.ER = BitConverter.ToUInt32(br_read(4), 0); - myHeader.FR = BitConverter.ToUInt32(br_read(4), 0); - myHeader.SLR = BitConverter.ToUInt32(br_read(4), 0); - myHeader.GVR = BitConverter.ToUInt32(br_read(4), 0); - myHeader.GFR = BitConverter.ToUInt32(br_read(4), 0); - myHeader.PR = BitConverter.ToUInt32(br_read(4), 0); - myHeader.ESR = BitConverter.ToUInt32(br_read(4), 0); - myHeader.SR = BitConverter.ToUInt32(br_read(4), 0); - myHeader.NCE = BitConverter.ToUInt64(br_read(8), 0); - myHeader.NIE = BitConverter.ToUInt64(br_read(8), 0); - myHeader.NER = BitConverter.ToUInt64(br_read(8), 0); - - // Print Header Block to debug - SendToDebug("TM - Top of memory (size): " + myHeader.TM); - SendToDebug("IP - Instruction Pointer (0=not running): " + myHeader.IP); - SendToDebug("VN - Version number: " + myHeader.VN); - SendToDebug("BP - Local Frame Pointer: " + myHeader.BP); - SendToDebug("SP - Stack Pointer: " + myHeader.SP); - SendToDebug("HR - Heap Register: " + myHeader.HR); - SendToDebug("HP - Heap Pointer: " + myHeader.HP); - SendToDebug("CS - Current State: " + myHeader.CS); - SendToDebug("NS - Next State: " + myHeader.NS); - SendToDebug("CE - Current Events: " + myHeader.CE); - SendToDebug("IE - In Event: " + myHeader.IE); - SendToDebug("ER - Event Register: " + myHeader.ER); - SendToDebug("FR - Fault Register: " + myHeader.FR); - SendToDebug("SLR - Sleep Register: " + myHeader.SLR); - SendToDebug("GVR - Global Variable Register: " + myHeader.GVR); - SendToDebug("GFR - Global Function Register: " + myHeader.GFR); - SendToDebug("PR - Parameter Register: " + myHeader.PR); - SendToDebug("ESR - Energy Supply Register: " + myHeader.ESR); - SendToDebug("SR - State Register: " + myHeader.SR); - SendToDebug("NCE - 64-bit Current Events: " + myHeader.NCE); - SendToDebug("NIE - 64-bit In Events: " + myHeader.NIE); - SendToDebug("NER - 64-bit Event Register: " + myHeader.NER); - SendToDebug("Read position when exiting HEADER BLOCK: " + fs.Position); - - // STATIC BLOCK - SendToDebug("Reading STATIC BLOCK at: " + myHeader.GVR); - fs.Seek(myHeader.GVR, SeekOrigin.Begin); - int StaticBlockCount = 0; - // Read function blocks until we hit GFR - while (fs.Position < myHeader.GFR) - { - StaticBlockCount++; - SendToDebug("Reading Static Block " + StaticBlockCount + " at: " + fs.Position); - //fs.Seek(myHeader.GVR, SeekOrigin.Begin); - LSO_Struct.StaticBlock myStaticBlock = new LSO_Struct.StaticBlock(); - myStaticBlock.Static_Chunk_Header_Size = BitConverter.ToUInt32(br_read(4), 0); - myStaticBlock.ObjectType = br_read(1)[0]; - SendToDebug("Static Block ObjectType: " + ((LSO_Enums.Variable_Type_Codes)myStaticBlock.ObjectType).ToString()); - myStaticBlock.Unknown = br_read(1)[0]; - // Size of datatype varies - if (myStaticBlock.ObjectType != 0) - myStaticBlock.BlockVariable = br_read(getObjectSize(myStaticBlock.ObjectType)); - } - SendToDebug("Number of Static Blocks read: " + StaticBlockCount); - - - // FUNCTION BLOCK - // Always right after STATIC BLOCK - LSO_Struct.FunctionBlock myFunctionBlock = new LSO_Struct.FunctionBlock(); - if (myHeader.GFR == myHeader.SR) - { - // If GFR and SR are at same position then there is no fuction block - SendToDebug("No FUNCTION BLOCK found"); - } else { - SendToDebug("Reading FUNCTION BLOCK at: " + myHeader.GFR); - fs.Seek(myHeader.GFR, SeekOrigin.Begin); - myFunctionBlock.FunctionCount = BitConverter.ToUInt32(br_read(4), 0); - SendToDebug("Number of functions in Fuction Block: " + myFunctionBlock.FunctionCount); - if (myFunctionBlock.FunctionCount > 0) - { - myFunctionBlock.CodeChunkPointer = new UInt32[myFunctionBlock.FunctionCount]; - for (int i = 0; i < myFunctionBlock.FunctionCount; i++) - { - SendToDebug("Reading function " + i + " at: " + fs.Position); - // TODO: ADD TO FUNCTION LIST (How do we identify it later?) - // Note! Absolute position - myFunctionBlock.CodeChunkPointer[i] = BitConverter.ToUInt32(br_read(4), 0) + myHeader.GFR; - SendToDebug("Fuction " + i + " code chunk position: " + myFunctionBlock.CodeChunkPointer[i]); - } - } - } - - - // STATE FRAME BLOCK - // Always right after FUNCTION BLOCK - SendToDebug("Reading STATE BLOCK at: " + myHeader.SR); - fs.Seek(myHeader.SR, SeekOrigin.Begin); - LSO_Struct.StateFrameBlock myStateFrameBlock = new LSO_Struct.StateFrameBlock(); - myStateFrameBlock.StateCount = BitConverter.ToUInt32(br_read(4), 0); - if (myStateFrameBlock.StateCount > 0) - { - // Initialize array - myStateFrameBlock.StatePointer = new LSO_Struct.StatePointerBlock[myStateFrameBlock.StateCount]; - for (int i = 0; i < myStateFrameBlock.StateCount; i++) - { - SendToDebug("Reading STATE POINTER BLOCK " + (i+1) + " at: " + fs.Position); - // Position is relative to state frame - myStateFrameBlock.StatePointer[i].Location = myHeader.SR + BitConverter.ToUInt32(br_read(4), 0); - myStateFrameBlock.StatePointer[i].EventMask = new System.Collections.BitArray(br_read(8)); - SendToDebug("Pointer: " + myStateFrameBlock.StatePointer[i].Location); - SendToDebug("Total potential EventMask bits: " + myStateFrameBlock.StatePointer[i].EventMask.Count); - - //// Read STATE BLOCK - //long CurPos = fs.Position; - //fs.Seek(CurPos, SeekOrigin.Begin); - - } - } - - - // STATE BLOCK - // For each StateFrameBlock there is one StateBlock with multiple event handlers - - if (myStateFrameBlock.StateCount > 0) - { - // Go through all State Frame Pointers found - for (int i = 0; i < myStateFrameBlock.StateCount; i++) - { - - fs.Seek(myStateFrameBlock.StatePointer[i].Location, SeekOrigin.Begin); - SendToDebug("Reading STATE BLOCK " + (i + 1) + " at: " + fs.Position); - - // READ: STATE BLOCK HEADER - myStateFrameBlock.StatePointer[i].StateBlock = new LSO_Struct.StateBlock(); - myStateFrameBlock.StatePointer[i].StateBlock.StartPos = (UInt32)fs.Position; // Note - myStateFrameBlock.StatePointer[i].StateBlock.HeaderSize = BitConverter.ToUInt32(br_read(4), 0); - myStateFrameBlock.StatePointer[i].StateBlock.Unknown = br_read(1)[0]; - myStateFrameBlock.StatePointer[i].StateBlock.EndPos = (UInt32)fs.Position; // Note - SendToDebug("State block Start Pos: " + myStateFrameBlock.StatePointer[i].StateBlock.StartPos); - SendToDebug("State block Header Size: " + myStateFrameBlock.StatePointer[i].StateBlock.HeaderSize); - SendToDebug("State block Header End Pos: " + myStateFrameBlock.StatePointer[i].StateBlock.EndPos); - - // We need to count number of bits flagged in EventMask? - - - // for each bit in myStateFrameBlock.StatePointer[i].EventMask - - // ADDING TO ALL RIGHT NOW, SHOULD LIMIT TO ONLY THE ONES IN USE - //TODO: Create event hooks - myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers = new LSO_Struct.StateBlockHandler[myStateFrameBlock.StatePointer[i].EventMask.Count - 1]; - for (int ii = 0; ii < myStateFrameBlock.StatePointer[i].EventMask.Count - 1; ii++) - { - - if (myStateFrameBlock.StatePointer[i].EventMask.Get(ii) == true) - { - // We got an event - // READ: STATE BLOCK HANDLER - SendToDebug("Reading STATE BLOCK " + (i + 1) + " HANDLER matching EVENT MASK " + ii + " (" + ((LSO_Enums.Event_Mask_Values)ii).ToString() + ") at: " + fs.Position); - myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer = myStateFrameBlock.StatePointer[i].StateBlock.EndPos + BitConverter.ToUInt32(br_read(4), 0); - myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CallFrameSize = BitConverter.ToUInt32(br_read(4), 0); - SendToDebug("Reading STATE BLOCK " + (i + 1) + " HANDLER EVENT MASK " + ii + " (" + ((LSO_Enums.Event_Mask_Values)ii).ToString() + ") Code Chunk Pointer: " + myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer); - SendToDebug("Reading STATE BLOCK " + (i + 1) + " HANDLER EVENT MASK " + ii + " (" + ((LSO_Enums.Event_Mask_Values)ii).ToString() + ") Call Frame Size: " + myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CallFrameSize ); - } - } - } - } - - - - - //// READ FUNCTION CODE CHUNKS - //// Functions + Function start pos (GFR) - //// TODO: Somehow be able to identify and reference this - //LSO_Struct.CodeChunk[] myFunctionCodeChunk; - //if (myFunctionBlock.FunctionCount > 0) - //{ - // myFunctionCodeChunk = new LSO_Struct.CodeChunk[myFunctionBlock.FunctionCount]; - // for (int i = 0; i < myFunctionBlock.FunctionCount; i++) - // { - // SendToDebug("Reading Function Code Chunk " + i); - // myFunctionCodeChunk[i] = GetCodeChunk((UInt32)myFunctionBlock.CodeChunkPointer[i]); - // } - - //} - // READ EVENT CODE CHUNKS - LSO_Struct.CodeChunk[] myEventCodeChunk; - if (myStateFrameBlock.StateCount > 0) - { - myEventCodeChunk = new LSO_Struct.CodeChunk[myStateFrameBlock.StateCount]; - for (int i = 0; i < myStateFrameBlock.StateCount; i++) - { - // TODO: Somehow organize events and functions so they can be found again, - // two level search ain't no good - for (int ii = 0; ii < myStateFrameBlock.StatePointer[i].EventMask.Count - 1; ii++) - { - - - if (myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer > 0) - { - SendToDebug("Reading Event Code Chunk state " + i + ", event " + (LSO_Enums.Event_Mask_Values)ii); - - - // Override a Method / Function - string eventname = "event_" + (LSO_Enums.Event_Mask_Values)ii; - SendToDebug("CLR:" + eventname + ":MethodBuilder methodBuilder = typeBuilder.DefineMethod..."); - MethodBuilder methodBuilder = typeBuilder.DefineMethod(eventname, - MethodAttributes.Private | MethodAttributes.Virtual, - typeof(void), - new Type[] { typeof(object) }); - - SendToDebug("CLR:" + eventname + ":typeBuilder.DefineMethodOverride(methodBuilder..."); - typeBuilder.DefineMethodOverride(methodBuilder, - typeof(LSL_CLRInterface.LSLScript).GetMethod(eventname)); - - // Create the IL generator - - SendToDebug("CLR:" + eventname + ":ILGenerator il = methodBuilder.GetILGenerator();"); - ILGenerator il = methodBuilder.GetILGenerator(); - - - LSO_Struct.CodeChunk myECC = - GetCodeChunk(myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer, il, eventname); - } - - } - } - - } - - - // Close - br.Close(); - fs.Close(); - - } - - private LSO_Struct.HeapBlock GetHeap(UInt32 pos) - { - // HEAP BLOCK - // TODO:? Special read for strings/keys (null terminated) and lists (pointers to other HEAP entries) - SendToDebug("Reading HEAP BLOCK at: " + pos); - fs.Seek(pos, SeekOrigin.Begin); - - LSO_Struct.HeapBlock myHeapBlock = new LSO_Struct.HeapBlock(); - myHeapBlock.DataBlockSize = BitConverter.ToUInt32(br_read(4), 0); - myHeapBlock.ObjectType = br_read(1)[0]; - myHeapBlock.ReferenceCount = BitConverter.ToUInt16(br_read(2), 0); - myHeapBlock.Data = br_read(getObjectSize(myHeapBlock.ObjectType)); - - SendToDebug("Heap Block Data Block Size: " + myHeapBlock.DataBlockSize); - SendToDebug("Heap Block ObjectType: " + ((LSO_Enums.Variable_Type_Codes)myHeapBlock.ObjectType).ToString()); - SendToDebug("Heap Block Reference Count: " + myHeapBlock.ReferenceCount); - - return myHeapBlock; - } - - - - private byte[] br_read(int len) - { - if (len <= 0) - return null; - - try - { - byte[] bytes = new byte[len]; - for (int i = len - 1; i > -1; i--) - bytes[i] = br.ReadByte(); - return bytes; - } - catch (Exception e) - { - SendToDebug("Exception: " + e.ToString()); - throw (e); - } - } - //private byte[] br_read_smallendian(int len) - //{ - // byte[] bytes = new byte[len]; - // br.Read(bytes,0, len); - // return bytes; - //} - - private int getObjectSize(byte ObjectType) - { - switch (ObjectType) - { - case 1: - case 2: - case 3: - case 4: - case 7: - return 4; - case 5: - return 12; - case 6: - return 16; - default: - return 0; - } - } - private void SendToDebug(string Message) - { - if (Debug == true) - Console.WriteLine("Debug: " + Message); - } - - - private string Read_String() - { - string ret = ""; - byte reader = br_read(1)[0]; - while (reader != 0x000) - { - ret += (char)reader; - reader = br_read(1)[0]; - } - return ret; - } - - /// - /// Reads a code chunk into structure and returns it. - /// - /// Absolute position in file. REMEMBER TO ADD myHeader.GFR! - /// - private LSO_Struct.CodeChunk GetCodeChunk(UInt32 pos, ILGenerator il, string eventname) - { - - /* - * CLR TRY - */ - //SendToDebug("CLR:" + eventname + ":il.BeginExceptionBlock()"); - il.BeginExceptionBlock(); - - // Push "Hello World!" string to stack - //SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Ldstr..."); - il.Emit(OpCodes.Ldstr, "Starting CLR dynamic execution of: " + eventname); - - // Push Console.WriteLine command to stack ... Console.WriteLine("Hello World!"); - //SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call..."); - il.Emit(OpCodes.Call, typeof(Console).GetMethod - ("WriteLine", new Type[] { typeof(string) })); - - - LSO_Struct.CodeChunk myCodeChunk = new LSO_Struct.CodeChunk(); - - SendToDebug("Reading Function Code Chunk at: " + pos); - fs.Seek(pos, SeekOrigin.Begin); - myCodeChunk.CodeChunkHeaderSize = BitConverter.ToUInt32(br_read(4), 0); - SendToDebug("CodeChunk Header Size: " + myCodeChunk.CodeChunkHeaderSize ); - // Read until null - myCodeChunk.Comment = Read_String(); - SendToDebug("Function comment: " + myCodeChunk.Comment); - myCodeChunk.ReturnType = br_read(1)[0]; - SendToDebug("Return type: " + (LSO_Enums.Variable_Type_Codes)myCodeChunk.ReturnType); - // TODO: How to determine number of codechunks -- does this method work? - myCodeChunk.CodeChunkArguments = new System.Collections.Generic.List(); - byte reader = br_read(1)[0]; - reader = br_read(1)[0]; - int ccount = 0; - while (reader != 0x000) - { - ccount++; - SendToDebug("Reading Code Chunk Argument " + ccount); - LSO_Struct.CodeChunkArgument CCA = new LSO_Struct.CodeChunkArgument(); - CCA.FunctionReturnType = reader; - reader = br_read(1)[0]; - CCA.NullString = reader; - myCodeChunk.CodeChunkArguments.Add(CCA); - SendToDebug("Code Chunk Argument " + ccount + " return type: " + (LSO_Enums.Variable_Type_Codes)CCA.FunctionReturnType); - } - // End marker is 0x000 - myCodeChunk.EndMarker = reader; - // TODO: How to read and identify following code - // TODO: Code is read until a return of some sort is found - bool FoundRet = false; - while (FoundRet == false) - { - //reader = br_read(1)[0]; - //UInt16 opcode = BitConverter.ToUInt16(br_read(1),0); - UInt16 opcode = br_read(1)[0]; - //long rPos = fs.Position; - SendToDebug("OPCODE: " + ((LSO_Enums.Operation_Table)opcode).ToString()); - switch (opcode) - { - // LONG - case (UInt16)LSO_Enums.Operation_Table.POPARG: - case (UInt16)LSO_Enums.Operation_Table.STORE: - case (UInt16)LSO_Enums.Operation_Table.STORES: - case (UInt16)LSO_Enums.Operation_Table.STOREL: - case (UInt16)LSO_Enums.Operation_Table.STOREV: - case (UInt16)LSO_Enums.Operation_Table.STOREQ: - case (UInt16)LSO_Enums.Operation_Table.STOREG: - case (UInt16)LSO_Enums.Operation_Table.STOREGS: - case (UInt16)LSO_Enums.Operation_Table.STOREGL: - case (UInt16)LSO_Enums.Operation_Table.STOREGV: - case (UInt16)LSO_Enums.Operation_Table.STOREGQ: - case (UInt16)LSO_Enums.Operation_Table.LOADP: - case (UInt16)LSO_Enums.Operation_Table.LOADSP: - case (UInt16)LSO_Enums.Operation_Table.LOADLP: - case (UInt16)LSO_Enums.Operation_Table.LOADVP: - case (UInt16)LSO_Enums.Operation_Table.LOADQP: - case (UInt16)LSO_Enums.Operation_Table.PUSH: - case (UInt16)LSO_Enums.Operation_Table.PUSHS: - case (UInt16)LSO_Enums.Operation_Table.PUSHL: - case (UInt16)LSO_Enums.Operation_Table.PUSHV: - case (UInt16)LSO_Enums.Operation_Table.PUSHQ: - case (UInt16)LSO_Enums.Operation_Table.PUSHG: - case (UInt16)LSO_Enums.Operation_Table.PUSHGS: - case (UInt16)LSO_Enums.Operation_Table.PUSHGL: - case (UInt16)LSO_Enums.Operation_Table.PUSHGV: - case (UInt16)LSO_Enums.Operation_Table.PUSHGQ: - SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0)); - break; - // BYTE - case (UInt16)LSO_Enums.Operation_Table.PUSHARGB: - SendToDebug("Param1: " + br_read(1)[0]); - break; - // INTEGER - case (UInt16)LSO_Enums.Operation_Table.PUSHARGI: - // TODO: What is size of integer? - SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0)); - break; - // FLOAT - case (UInt16)LSO_Enums.Operation_Table.PUSHARGF: - // TODO: What is size of float? - SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0)); - break; - // STRING - case (UInt16)LSO_Enums.Operation_Table.PUSHARGS: - string s = Read_String(); - SendToDebug("Param1: " + s); - il.Emit(OpCodes.Ldstr, s); - break; - // VECTOR z,y,x - case (UInt16)LSO_Enums.Operation_Table.PUSHARGV: - SendToDebug("Param1 Z: " + BitConverter.ToUInt32(br_read(4),0)); - SendToDebug("Param1 Y: " + BitConverter.ToUInt32(br_read(4),0)); - SendToDebug("Param1 X: " + BitConverter.ToUInt32(br_read(4),0)); - break; - // ROTATION s,z,y,x - case (UInt16)LSO_Enums.Operation_Table.PUSHARGQ: - SendToDebug("Param1 S: " + BitConverter.ToUInt32(br_read(4),0)); - SendToDebug("Param1 Z: " + BitConverter.ToUInt32(br_read(4),0)); - SendToDebug("Param1 Y: " + BitConverter.ToUInt32(br_read(4),0)); - SendToDebug("Param1 X: " + BitConverter.ToUInt32(br_read(4),0)); - break; - // LONG - case (UInt16)LSO_Enums.Operation_Table.PUSHARGE: - SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0)); - break; - // BYTE - case (UInt16)LSO_Enums.Operation_Table.ADD: - case (UInt16)LSO_Enums.Operation_Table.SUB: - case (UInt16)LSO_Enums.Operation_Table.MUL: - case (UInt16)LSO_Enums.Operation_Table.DIV: - case (UInt16)LSO_Enums.Operation_Table.MOD: - case (UInt16)LSO_Enums.Operation_Table.EQ: - case (UInt16)LSO_Enums.Operation_Table.NEQ: - case (UInt16)LSO_Enums.Operation_Table.LEQ: - case (UInt16)LSO_Enums.Operation_Table.GEQ: - case (UInt16)LSO_Enums.Operation_Table.LESS: - case (UInt16)LSO_Enums.Operation_Table.GREATER: - case (UInt16)LSO_Enums.Operation_Table.BOOLOR: - SendToDebug("Param1: " + br_read(1)[0]); - break; - // LONG - case (UInt16)LSO_Enums.Operation_Table.JUMP: - SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0)); - break; - // BYTE, LONG - case (UInt16)LSO_Enums.Operation_Table.JUMPIF: - case (UInt16)LSO_Enums.Operation_Table.JUMPNIF: - SendToDebug("Param1: " + br_read(1)[0]); - SendToDebug("Param2: " + BitConverter.ToUInt32(br_read(4),0)); - break; - // LONG - case (UInt16)LSO_Enums.Operation_Table.STATE: - case (UInt16)LSO_Enums.Operation_Table.CALL: - SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0)); - break; - // BYTE - case (UInt16)LSO_Enums.Operation_Table.CAST: - SendToDebug("Param1: " + br_read(1)[0]); - break; - // LONG - case (UInt16)LSO_Enums.Operation_Table.STACKTOS: - case (UInt16)LSO_Enums.Operation_Table.STACKTOL: - SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0)); - break; - // BYTE - case (UInt16)LSO_Enums.Operation_Table.PRINT: - case (UInt16)LSO_Enums.Operation_Table.CALLLIB: - SendToDebug("Param1: " + br_read(1)[0]); - break; - // SHORT - case (UInt16)LSO_Enums.Operation_Table.CALLLIB_TWO_BYTE: - // TODO: What is size of short? - UInt16 _i = BitConverter.ToUInt16(br_read(2), 0); - SendToDebug("Param1: " + _i); - switch (_i) - { - case (UInt16)LSO_Enums.BuiltIn_Functions.llSay: - il.Emit(OpCodes.Call, typeof(Console).GetMethod - ("WriteLine", new Type[] { typeof(string) })); - break; - } - break; - - - // RETURN - case (UInt16)LSO_Enums.Operation_Table.RETURN: - SendToDebug("Last OPCODE was return command. Code chunk execution complete."); - FoundRet = true; - break; - } - //fs.Seek(rPos, SeekOrigin.Begin); - - } - - - /* - * CATCH - */ - SendToDebug("CLR:" + eventname + ":il.BeginCatchBlock(typeof(Exception));"); - il.BeginCatchBlock(typeof(Exception)); - - // Push "Hello World!" string to stack - SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Ldstr..."); - il.Emit(OpCodes.Ldstr, "Execption executing dynamic CLR function " + eventname + ": "); - - //call void [mscorlib]System.Console::WriteLine(string) - SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call..."); - il.Emit(OpCodes.Call, typeof(Console).GetMethod - ("Write", new Type[] { typeof(string) })); - - //callvirt instance string [mscorlib]System.Exception::get_Message() - SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Callvirt..."); - il.Emit(OpCodes.Callvirt, typeof(Exception).GetMethod - ("get_Message")); - - //call void [mscorlib]System.Console::WriteLine(string) - SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call..."); - il.Emit(OpCodes.Call, typeof(Console).GetMethod - ("WriteLine", new Type[] { typeof(string) })); - - /* - * CLR END TRY - */ - //SendToDebug("CLR:" + eventname + ":il.EndExceptionBlock();"); - il.EndExceptionBlock(); - // Push "Return from current method, with return value if present" to stack - il.Emit(OpCodes.Ret); - - - - return myCodeChunk; - - } - } -} + using System; + using System.Collections.Generic; + using System.Text; + using System.IO; + using System.Reflection; + using System.Reflection.Emit; +using OpenSim.Region.Scripting; + + namespace OpenSim.ScriptEngines.LSL + { + class LSO_Parser + { + private bool Debug = true; + private FileStream fs; + private BinaryReader br; + private LSO_Struct.Header myHeader; + + private TypeBuilder typeBuilder; + private ScriptInfo WorldAPI; + + /// + /// Parse LSO file. + /// Reads LSO ByteCode into memory structures. + /// TODO: What else does it do? + /// + /// FileName of LSO ByteCode file + public void ParseFile(string FileName, ScriptInfo _WorldAPI, ref TypeBuilder _typeBuilder) + { + typeBuilder = _typeBuilder; + WorldAPI = _WorldAPI; + // Open + SendToDebug("Opening filename: " + FileName); + fs = File.Open(FileName, FileMode.Open, FileAccess.Read, FileShare.Read); + br = new BinaryReader(fs, Encoding.BigEndianUnicode); + + + // The LSO Format consist of 6 major blocks: header, statics, functions, states, heap, and stack. + + + // HEADER BLOCK + SendToDebug("Reading HEADER BLOCK at: 0"); + fs.Seek(0, SeekOrigin.Begin); + myHeader = new LSO_Struct.Header(); + myHeader.TM = BitConverter.ToUInt32(br_read(4), 0); + myHeader.IP = BitConverter.ToUInt32(br_read(4), 0); + myHeader.VN = BitConverter.ToUInt32(br_read(4), 0); + myHeader.BP = BitConverter.ToUInt32(br_read(4), 0); + myHeader.SP = BitConverter.ToUInt32(br_read(4), 0); + myHeader.HR = BitConverter.ToUInt32(br_read(4), 0); + myHeader.HP = BitConverter.ToUInt32(br_read(4), 0); + myHeader.CS = BitConverter.ToUInt32(br_read(4), 0); + myHeader.NS = BitConverter.ToUInt32(br_read(4), 0); + myHeader.CE = BitConverter.ToUInt32(br_read(4), 0); + myHeader.IE = BitConverter.ToUInt32(br_read(4), 0); + myHeader.ER = BitConverter.ToUInt32(br_read(4), 0); + myHeader.FR = BitConverter.ToUInt32(br_read(4), 0); + myHeader.SLR = BitConverter.ToUInt32(br_read(4), 0); + myHeader.GVR = BitConverter.ToUInt32(br_read(4), 0); + myHeader.GFR = BitConverter.ToUInt32(br_read(4), 0); + myHeader.PR = BitConverter.ToUInt32(br_read(4), 0); + myHeader.ESR = BitConverter.ToUInt32(br_read(4), 0); + myHeader.SR = BitConverter.ToUInt32(br_read(4), 0); + myHeader.NCE = BitConverter.ToUInt64(br_read(8), 0); + myHeader.NIE = BitConverter.ToUInt64(br_read(8), 0); + myHeader.NER = BitConverter.ToUInt64(br_read(8), 0); + + // Print Header Block to debug + SendToDebug("TM - Top of memory (size): " + myHeader.TM); + SendToDebug("IP - Instruction Pointer (0=not running): " + myHeader.IP); + SendToDebug("VN - Version number: " + myHeader.VN); + SendToDebug("BP - Local Frame Pointer: " + myHeader.BP); + SendToDebug("SP - Stack Pointer: " + myHeader.SP); + SendToDebug("HR - Heap Register: " + myHeader.HR); + SendToDebug("HP - Heap Pointer: " + myHeader.HP); + SendToDebug("CS - Current State: " + myHeader.CS); + SendToDebug("NS - Next State: " + myHeader.NS); + SendToDebug("CE - Current Events: " + myHeader.CE); + SendToDebug("IE - In Event: " + myHeader.IE); + SendToDebug("ER - Event Register: " + myHeader.ER); + SendToDebug("FR - Fault Register: " + myHeader.FR); + SendToDebug("SLR - Sleep Register: " + myHeader.SLR); + SendToDebug("GVR - Global Variable Register: " + myHeader.GVR); + SendToDebug("GFR - Global Function Register: " + myHeader.GFR); + SendToDebug("PR - Parameter Register: " + myHeader.PR); + SendToDebug("ESR - Energy Supply Register: " + myHeader.ESR); + SendToDebug("SR - State Register: " + myHeader.SR); + SendToDebug("NCE - 64-bit Current Events: " + myHeader.NCE); + SendToDebug("NIE - 64-bit In Events: " + myHeader.NIE); + SendToDebug("NER - 64-bit Event Register: " + myHeader.NER); + SendToDebug("Read position when exiting HEADER BLOCK: " + fs.Position); + + // STATIC BLOCK + SendToDebug("Reading STATIC BLOCK at: " + myHeader.GVR); + fs.Seek(myHeader.GVR, SeekOrigin.Begin); + int StaticBlockCount = 0; + // Read function blocks until we hit GFR + while (fs.Position < myHeader.GFR) + { + StaticBlockCount++; + SendToDebug("Reading Static Block " + StaticBlockCount + " at: " + fs.Position); + //fs.Seek(myHeader.GVR, SeekOrigin.Begin); + LSO_Struct.StaticBlock myStaticBlock = new LSO_Struct.StaticBlock(); + myStaticBlock.Static_Chunk_Header_Size = BitConverter.ToUInt32(br_read(4), 0); + myStaticBlock.ObjectType = br_read(1)[0]; + SendToDebug("Static Block ObjectType: " + ((LSO_Enums.Variable_Type_Codes)myStaticBlock.ObjectType).ToString()); + myStaticBlock.Unknown = br_read(1)[0]; + // Size of datatype varies + if (myStaticBlock.ObjectType != 0) + myStaticBlock.BlockVariable = br_read(getObjectSize(myStaticBlock.ObjectType)); + } + SendToDebug("Number of Static Blocks read: " + StaticBlockCount); + + + // FUNCTION BLOCK + // Always right after STATIC BLOCK + LSO_Struct.FunctionBlock myFunctionBlock = new LSO_Struct.FunctionBlock(); + if (myHeader.GFR == myHeader.SR) + { + // If GFR and SR are at same position then there is no fuction block + SendToDebug("No FUNCTION BLOCK found"); + } else { + SendToDebug("Reading FUNCTION BLOCK at: " + myHeader.GFR); + fs.Seek(myHeader.GFR, SeekOrigin.Begin); + myFunctionBlock.FunctionCount = BitConverter.ToUInt32(br_read(4), 0); + SendToDebug("Number of functions in Fuction Block: " + myFunctionBlock.FunctionCount); + if (myFunctionBlock.FunctionCount > 0) + { + myFunctionBlock.CodeChunkPointer = new UInt32[myFunctionBlock.FunctionCount]; + for (int i = 0; i < myFunctionBlock.FunctionCount; i++) + { + SendToDebug("Reading function " + i + " at: " + fs.Position); + // TODO: ADD TO FUNCTION LIST (How do we identify it later?) + // Note! Absolute position + myFunctionBlock.CodeChunkPointer[i] = BitConverter.ToUInt32(br_read(4), 0) + myHeader.GFR; + SendToDebug("Fuction " + i + " code chunk position: " + myFunctionBlock.CodeChunkPointer[i]); + } + } + } + + + // STATE FRAME BLOCK + // Always right after FUNCTION BLOCK + SendToDebug("Reading STATE BLOCK at: " + myHeader.SR); + fs.Seek(myHeader.SR, SeekOrigin.Begin); + LSO_Struct.StateFrameBlock myStateFrameBlock = new LSO_Struct.StateFrameBlock(); + myStateFrameBlock.StateCount = BitConverter.ToUInt32(br_read(4), 0); + if (myStateFrameBlock.StateCount > 0) + { + // Initialize array + myStateFrameBlock.StatePointer = new LSO_Struct.StatePointerBlock[myStateFrameBlock.StateCount]; + for (int i = 0; i < myStateFrameBlock.StateCount; i++) + { + SendToDebug("Reading STATE POINTER BLOCK " + (i+1) + " at: " + fs.Position); + // Position is relative to state frame + myStateFrameBlock.StatePointer[i].Location = myHeader.SR + BitConverter.ToUInt32(br_read(4), 0); + myStateFrameBlock.StatePointer[i].EventMask = new System.Collections.BitArray(br_read(8)); + SendToDebug("Pointer: " + myStateFrameBlock.StatePointer[i].Location); + SendToDebug("Total potential EventMask bits: " + myStateFrameBlock.StatePointer[i].EventMask.Count); + + //// Read STATE BLOCK + //long CurPos = fs.Position; + //fs.Seek(CurPos, SeekOrigin.Begin); + + } + } + + + // STATE BLOCK + // For each StateFrameBlock there is one StateBlock with multiple event handlers + + if (myStateFrameBlock.StateCount > 0) + { + // Go through all State Frame Pointers found + for (int i = 0; i < myStateFrameBlock.StateCount; i++) + { + + fs.Seek(myStateFrameBlock.StatePointer[i].Location, SeekOrigin.Begin); + SendToDebug("Reading STATE BLOCK " + (i + 1) + " at: " + fs.Position); + + // READ: STATE BLOCK HEADER + myStateFrameBlock.StatePointer[i].StateBlock = new LSO_Struct.StateBlock(); + myStateFrameBlock.StatePointer[i].StateBlock.StartPos = (UInt32)fs.Position; // Note + myStateFrameBlock.StatePointer[i].StateBlock.HeaderSize = BitConverter.ToUInt32(br_read(4), 0); + myStateFrameBlock.StatePointer[i].StateBlock.Unknown = br_read(1)[0]; + myStateFrameBlock.StatePointer[i].StateBlock.EndPos = (UInt32)fs.Position; // Note + SendToDebug("State block Start Pos: " + myStateFrameBlock.StatePointer[i].StateBlock.StartPos); + SendToDebug("State block Header Size: " + myStateFrameBlock.StatePointer[i].StateBlock.HeaderSize); + SendToDebug("State block Header End Pos: " + myStateFrameBlock.StatePointer[i].StateBlock.EndPos); + + // We need to count number of bits flagged in EventMask? + + + // for each bit in myStateFrameBlock.StatePointer[i].EventMask + + // ADDING TO ALL RIGHT NOW, SHOULD LIMIT TO ONLY THE ONES IN USE + //TODO: Create event hooks + myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers = new LSO_Struct.StateBlockHandler[myStateFrameBlock.StatePointer[i].EventMask.Count - 1]; + for (int ii = 0; ii < myStateFrameBlock.StatePointer[i].EventMask.Count - 1; ii++) + { + + if (myStateFrameBlock.StatePointer[i].EventMask.Get(ii) == true) + { + // We got an event + // READ: STATE BLOCK HANDLER + SendToDebug("Reading STATE BLOCK " + (i + 1) + " HANDLER matching EVENT MASK " + ii + " (" + ((LSO_Enums.Event_Mask_Values)ii).ToString() + ") at: " + fs.Position); + myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer = myStateFrameBlock.StatePointer[i].StateBlock.EndPos + BitConverter.ToUInt32(br_read(4), 0); + myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CallFrameSize = BitConverter.ToUInt32(br_read(4), 0); + SendToDebug("Reading STATE BLOCK " + (i + 1) + " HANDLER EVENT MASK " + ii + " (" + ((LSO_Enums.Event_Mask_Values)ii).ToString() + ") Code Chunk Pointer: " + myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer); + SendToDebug("Reading STATE BLOCK " + (i + 1) + " HANDLER EVENT MASK " + ii + " (" + ((LSO_Enums.Event_Mask_Values)ii).ToString() + ") Call Frame Size: " + myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CallFrameSize ); + } + } + } + } + + + + + //// READ FUNCTION CODE CHUNKS + //// Functions + Function start pos (GFR) + //// TODO: Somehow be able to identify and reference this + //LSO_Struct.CodeChunk[] myFunctionCodeChunk; + //if (myFunctionBlock.FunctionCount > 0) + //{ + // myFunctionCodeChunk = new LSO_Struct.CodeChunk[myFunctionBlock.FunctionCount]; + // for (int i = 0; i < myFunctionBlock.FunctionCount; i++) + // { + // SendToDebug("Reading Function Code Chunk " + i); + // myFunctionCodeChunk[i] = GetCodeChunk((UInt32)myFunctionBlock.CodeChunkPointer[i]); + // } + + //} + // READ EVENT CODE CHUNKS + LSO_Struct.CodeChunk[] myEventCodeChunk; + if (myStateFrameBlock.StateCount > 0) + { + myEventCodeChunk = new LSO_Struct.CodeChunk[myStateFrameBlock.StateCount]; + for (int i = 0; i < myStateFrameBlock.StateCount; i++) + { + // TODO: Somehow organize events and functions so they can be found again, + // two level search ain't no good + for (int ii = 0; ii < myStateFrameBlock.StatePointer[i].EventMask.Count - 1; ii++) + { + + + if (myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer > 0) + { + SendToDebug("Reading Event Code Chunk state " + i + ", event " + (LSO_Enums.Event_Mask_Values)ii); + + + // Override a Method / Function + string eventname = "event_" + (LSO_Enums.Event_Mask_Values)ii; + SendToDebug("CLR:" + eventname + ":MethodBuilder methodBuilder = typeBuilder.DefineMethod..."); + MethodBuilder methodBuilder = typeBuilder.DefineMethod(eventname, + MethodAttributes.Private | MethodAttributes.Virtual, + typeof(void), + new Type[] { typeof(object) }); + + SendToDebug("CLR:" + eventname + ":typeBuilder.DefineMethodOverride(methodBuilder..."); + typeBuilder.DefineMethodOverride(methodBuilder, + typeof(LSL_CLRInterface.LSLScript).GetMethod(eventname)); + + // Create the IL generator + + SendToDebug("CLR:" + eventname + ":ILGenerator il = methodBuilder.GetILGenerator();"); + ILGenerator il = methodBuilder.GetILGenerator(); + + + LSO_Struct.CodeChunk myECC = + GetCodeChunk(myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer, il, eventname); + } + + } + } + + } + + + // Close + br.Close(); + fs.Close(); + + } + + private LSO_Struct.HeapBlock GetHeap(UInt32 pos) + { + // HEAP BLOCK + // TODO:? Special read for strings/keys (null terminated) and lists (pointers to other HEAP entries) + SendToDebug("Reading HEAP BLOCK at: " + pos); + fs.Seek(pos, SeekOrigin.Begin); + + LSO_Struct.HeapBlock myHeapBlock = new LSO_Struct.HeapBlock(); + myHeapBlock.DataBlockSize = BitConverter.ToUInt32(br_read(4), 0); + myHeapBlock.ObjectType = br_read(1)[0]; + myHeapBlock.ReferenceCount = BitConverter.ToUInt16(br_read(2), 0); + myHeapBlock.Data = br_read(getObjectSize(myHeapBlock.ObjectType)); + + SendToDebug("Heap Block Data Block Size: " + myHeapBlock.DataBlockSize); + SendToDebug("Heap Block ObjectType: " + ((LSO_Enums.Variable_Type_Codes)myHeapBlock.ObjectType).ToString()); + SendToDebug("Heap Block Reference Count: " + myHeapBlock.ReferenceCount); + + return myHeapBlock; + } + + + + private byte[] br_read(int len) + { + if (len <= 0) + return null; + + try + { + byte[] bytes = new byte[len]; + for (int i = len - 1; i > -1; i--) + bytes[i] = br.ReadByte(); + return bytes; + } + catch (Exception e) + { + SendToDebug("Exception: " + e.ToString()); + throw (e); + } + } + //private byte[] br_read_smallendian(int len) + //{ + // byte[] bytes = new byte[len]; + // br.Read(bytes,0, len); + // return bytes; + //} + + private int getObjectSize(byte ObjectType) + { + switch (ObjectType) + { + case 1: + case 2: + case 3: + case 4: + case 7: + return 4; + case 5: + return 12; + case 6: + return 16; + default: + return 0; + } + } + private void SendToDebug(string Message) + { + if (Debug == true) + Console.WriteLine("Debug: " + Message); + } + + + private string Read_String() + { + string ret = ""; + byte reader = br_read(1)[0]; + while (reader != 0x000) + { + ret += (char)reader; + reader = br_read(1)[0]; + } + return ret; + } + + /// + /// Reads a code chunk into structure and returns it. + /// + /// Absolute position in file. REMEMBER TO ADD myHeader.GFR! + /// + private LSO_Struct.CodeChunk GetCodeChunk(UInt32 pos, ILGenerator il, string eventname) + { + + /* + * CLR TRY + */ + //SendToDebug("CLR:" + eventname + ":il.BeginExceptionBlock()"); + il.BeginExceptionBlock(); + + // Push "Hello World!" string to stack + //SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Ldstr..."); + il.Emit(OpCodes.Ldstr, "Starting CLR dynamic execution of: " + eventname); + + // Push Console.WriteLine command to stack ... Console.WriteLine("Hello World!"); + //SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call..."); + il.Emit(OpCodes.Call, typeof(Console).GetMethod + ("WriteLine", new Type[] { typeof(string) })); + + + LSO_Struct.CodeChunk myCodeChunk = new LSO_Struct.CodeChunk(); + + SendToDebug("Reading Function Code Chunk at: " + pos); + fs.Seek(pos, SeekOrigin.Begin); + myCodeChunk.CodeChunkHeaderSize = BitConverter.ToUInt32(br_read(4), 0); + SendToDebug("CodeChunk Header Size: " + myCodeChunk.CodeChunkHeaderSize ); + // Read until null + myCodeChunk.Comment = Read_String(); + SendToDebug("Function comment: " + myCodeChunk.Comment); + myCodeChunk.ReturnType = br_read(1)[0]; + SendToDebug("Return type: " + (LSO_Enums.Variable_Type_Codes)myCodeChunk.ReturnType); + // TODO: How to determine number of codechunks -- does this method work? + myCodeChunk.CodeChunkArguments = new System.Collections.Generic.List(); + byte reader = br_read(1)[0]; + reader = br_read(1)[0]; + int ccount = 0; + while (reader != 0x000) + { + ccount++; + SendToDebug("Reading Code Chunk Argument " + ccount); + LSO_Struct.CodeChunkArgument CCA = new LSO_Struct.CodeChunkArgument(); + CCA.FunctionReturnType = reader; + reader = br_read(1)[0]; + CCA.NullString = reader; + myCodeChunk.CodeChunkArguments.Add(CCA); + SendToDebug("Code Chunk Argument " + ccount + " return type: " + (LSO_Enums.Variable_Type_Codes)CCA.FunctionReturnType); + } + // End marker is 0x000 + myCodeChunk.EndMarker = reader; + // TODO: How to read and identify following code + // TODO: Code is read until a return of some sort is found + bool FoundRet = false; + while (FoundRet == false) + { + //reader = br_read(1)[0]; + //UInt16 opcode = BitConverter.ToUInt16(br_read(1),0); + UInt16 opcode = br_read(1)[0]; + //long rPos = fs.Position; + SendToDebug("OPCODE: " + ((LSO_Enums.Operation_Table)opcode).ToString()); + switch (opcode) + { + // LONG + case (UInt16)LSO_Enums.Operation_Table.POPARG: + case (UInt16)LSO_Enums.Operation_Table.STORE: + case (UInt16)LSO_Enums.Operation_Table.STORES: + case (UInt16)LSO_Enums.Operation_Table.STOREL: + case (UInt16)LSO_Enums.Operation_Table.STOREV: + case (UInt16)LSO_Enums.Operation_Table.STOREQ: + case (UInt16)LSO_Enums.Operation_Table.STOREG: + case (UInt16)LSO_Enums.Operation_Table.STOREGS: + case (UInt16)LSO_Enums.Operation_Table.STOREGL: + case (UInt16)LSO_Enums.Operation_Table.STOREGV: + case (UInt16)LSO_Enums.Operation_Table.STOREGQ: + case (UInt16)LSO_Enums.Operation_Table.LOADP: + case (UInt16)LSO_Enums.Operation_Table.LOADSP: + case (UInt16)LSO_Enums.Operation_Table.LOADLP: + case (UInt16)LSO_Enums.Operation_Table.LOADVP: + case (UInt16)LSO_Enums.Operation_Table.LOADQP: + case (UInt16)LSO_Enums.Operation_Table.PUSH: + case (UInt16)LSO_Enums.Operation_Table.PUSHS: + case (UInt16)LSO_Enums.Operation_Table.PUSHL: + case (UInt16)LSO_Enums.Operation_Table.PUSHV: + case (UInt16)LSO_Enums.Operation_Table.PUSHQ: + case (UInt16)LSO_Enums.Operation_Table.PUSHG: + case (UInt16)LSO_Enums.Operation_Table.PUSHGS: + case (UInt16)LSO_Enums.Operation_Table.PUSHGL: + case (UInt16)LSO_Enums.Operation_Table.PUSHGV: + case (UInt16)LSO_Enums.Operation_Table.PUSHGQ: + SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0)); + break; + // BYTE + case (UInt16)LSO_Enums.Operation_Table.PUSHARGB: + SendToDebug("Param1: " + br_read(1)[0]); + break; + // INTEGER + case (UInt16)LSO_Enums.Operation_Table.PUSHARGI: + // TODO: What is size of integer? + SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0)); + break; + // FLOAT + case (UInt16)LSO_Enums.Operation_Table.PUSHARGF: + // TODO: What is size of float? + SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0)); + break; + // STRING + case (UInt16)LSO_Enums.Operation_Table.PUSHARGS: + string s = Read_String(); + SendToDebug("Param1: " + s); + il.Emit(OpCodes.Ldstr, s); + break; + // VECTOR z,y,x + case (UInt16)LSO_Enums.Operation_Table.PUSHARGV: + SendToDebug("Param1 Z: " + BitConverter.ToUInt32(br_read(4),0)); + SendToDebug("Param1 Y: " + BitConverter.ToUInt32(br_read(4),0)); + SendToDebug("Param1 X: " + BitConverter.ToUInt32(br_read(4),0)); + break; + // ROTATION s,z,y,x + case (UInt16)LSO_Enums.Operation_Table.PUSHARGQ: + SendToDebug("Param1 S: " + BitConverter.ToUInt32(br_read(4),0)); + SendToDebug("Param1 Z: " + BitConverter.ToUInt32(br_read(4),0)); + SendToDebug("Param1 Y: " + BitConverter.ToUInt32(br_read(4),0)); + SendToDebug("Param1 X: " + BitConverter.ToUInt32(br_read(4),0)); + break; + // LONG + case (UInt16)LSO_Enums.Operation_Table.PUSHARGE: + SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0)); + break; + // BYTE + case (UInt16)LSO_Enums.Operation_Table.ADD: + case (UInt16)LSO_Enums.Operation_Table.SUB: + case (UInt16)LSO_Enums.Operation_Table.MUL: + case (UInt16)LSO_Enums.Operation_Table.DIV: + case (UInt16)LSO_Enums.Operation_Table.MOD: + case (UInt16)LSO_Enums.Operation_Table.EQ: + case (UInt16)LSO_Enums.Operation_Table.NEQ: + case (UInt16)LSO_Enums.Operation_Table.LEQ: + case (UInt16)LSO_Enums.Operation_Table.GEQ: + case (UInt16)LSO_Enums.Operation_Table.LESS: + case (UInt16)LSO_Enums.Operation_Table.GREATER: + case (UInt16)LSO_Enums.Operation_Table.BOOLOR: + SendToDebug("Param1: " + br_read(1)[0]); + break; + // LONG + case (UInt16)LSO_Enums.Operation_Table.JUMP: + SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0)); + break; + // BYTE, LONG + case (UInt16)LSO_Enums.Operation_Table.JUMPIF: + case (UInt16)LSO_Enums.Operation_Table.JUMPNIF: + SendToDebug("Param1: " + br_read(1)[0]); + SendToDebug("Param2: " + BitConverter.ToUInt32(br_read(4),0)); + break; + // LONG + case (UInt16)LSO_Enums.Operation_Table.STATE: + case (UInt16)LSO_Enums.Operation_Table.CALL: + SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0)); + break; + // BYTE + case (UInt16)LSO_Enums.Operation_Table.CAST: + SendToDebug("Param1: " + br_read(1)[0]); + break; + // LONG + case (UInt16)LSO_Enums.Operation_Table.STACKTOS: + case (UInt16)LSO_Enums.Operation_Table.STACKTOL: + SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0)); + break; + // BYTE + case (UInt16)LSO_Enums.Operation_Table.PRINT: + case (UInt16)LSO_Enums.Operation_Table.CALLLIB: + SendToDebug("Param1: " + br_read(1)[0]); + break; + // SHORT + case (UInt16)LSO_Enums.Operation_Table.CALLLIB_TWO_BYTE: + // TODO: What is size of short? + UInt16 _i = BitConverter.ToUInt16(br_read(2), 0); + SendToDebug("Param1: " + _i); + switch (_i) + { + case (UInt16)LSO_Enums.BuiltIn_Functions.llSay: + il.Emit(OpCodes.Call, typeof(Console).GetMethod + ("WriteLine", new Type[] { typeof(string) })); + break; + } + break; + + + // RETURN + case (UInt16)LSO_Enums.Operation_Table.RETURN: + SendToDebug("Last OPCODE was return command. Code chunk execution complete."); + FoundRet = true; + break; + } + //fs.Seek(rPos, SeekOrigin.Begin); + + } + + + /* + * CATCH + */ + SendToDebug("CLR:" + eventname + ":il.BeginCatchBlock(typeof(Exception));"); + il.BeginCatchBlock(typeof(Exception)); + + // Push "Hello World!" string to stack + SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Ldstr..."); + il.Emit(OpCodes.Ldstr, "Execption executing dynamic CLR function " + eventname + ": "); + + //call void [mscorlib]System.Console::WriteLine(string) + SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call..."); + il.Emit(OpCodes.Call, typeof(Console).GetMethod + ("Write", new Type[] { typeof(string) })); + + //callvirt instance string [mscorlib]System.Exception::get_Message() + SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Callvirt..."); + il.Emit(OpCodes.Callvirt, typeof(Exception).GetMethod + ("get_Message")); + + //call void [mscorlib]System.Console::WriteLine(string) + SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call..."); + il.Emit(OpCodes.Call, typeof(Console).GetMethod + ("WriteLine", new Type[] { typeof(string) })); + + /* + * CLR END TRY + */ + //SendToDebug("CLR:" + eventname + ":il.EndExceptionBlock();"); + il.EndExceptionBlock(); + // Push "Return from current method, with return value if present" to stack + il.Emit(OpCodes.Ret); + + + + return myCodeChunk; + + } + } +} -- cgit v1.1