123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728 |
- /*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSim Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
- /* Original code: Tedd Hansen */
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.IO;
- using System.Reflection;
- using System.Reflection.Emit;
- using System.Text;
- namespace OpenSim.Grid.ScriptEngine.DotNetEngine.Compiler.LSO
- {
- internal partial class LSO_Parser
- {
- private string FileName;
- private FileStream fs;
- private BinaryReader br;
- internal LSO_Struct.Header myHeader;
- internal Dictionary<long, LSO_Struct.StaticBlock> StaticBlocks = new Dictionary<long, LSO_Struct.StaticBlock>();
- //private System.Collections.Hashtable StaticBlocks = new System.Collections.Hashtable();
- private TypeBuilder typeBuilder;
- private List<string> EventList = new List<string>();
- public LSO_Parser(string _FileName, TypeBuilder _typeBuilder)
- {
- FileName = _FileName;
- typeBuilder = _typeBuilder;
- }
- internal void OpenFile()
- {
- // Open
- Common.SendToDebug("Opening filename: " + FileName);
- fs = File.Open(FileName, FileMode.Open, FileAccess.Read, FileShare.Read);
- br = new BinaryReader(fs, Encoding.BigEndianUnicode);
- }
- internal void CloseFile()
- {
- // Close
- br.Close();
- fs.Close();
- }
- /// <summary>
- /// Parse LSO file.
- /// </summary>
- public void Parse()
- {
- // The LSO Format consist of 6 major blocks: header, statics, functions, states, heap, and stack.
- // HEADER BLOCK
- Common.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
- Common.SendToDebug("TM - Top of memory (size): " + myHeader.TM);
- Common.SendToDebug("IP - Instruction Pointer (0=not running): " + myHeader.IP);
- Common.SendToDebug("VN - Version number: " + myHeader.VN);
- Common.SendToDebug("BP - Local Frame Pointer: " + myHeader.BP);
- Common.SendToDebug("SP - Stack Pointer: " + myHeader.SP);
- Common.SendToDebug("HR - Heap Register: " + myHeader.HR);
- Common.SendToDebug("HP - Heap Pointer: " + myHeader.HP);
- Common.SendToDebug("CS - Current State: " + myHeader.CS);
- Common.SendToDebug("NS - Next State: " + myHeader.NS);
- Common.SendToDebug("CE - Current Events: " + myHeader.CE);
- Common.SendToDebug("IE - In Event: " + myHeader.IE);
- Common.SendToDebug("ER - Event Register: " + myHeader.ER);
- Common.SendToDebug("FR - Fault Register: " + myHeader.FR);
- Common.SendToDebug("SLR - Sleep Register: " + myHeader.SLR);
- Common.SendToDebug("GVR - Global Variable Register: " + myHeader.GVR);
- Common.SendToDebug("GFR - Global Function Register: " + myHeader.GFR);
- Common.SendToDebug("PR - Parameter Register: " + myHeader.PR);
- Common.SendToDebug("ESR - Energy Supply Register: " + myHeader.ESR);
- Common.SendToDebug("SR - State Register: " + myHeader.SR);
- Common.SendToDebug("NCE - 64-bit Current Events: " + myHeader.NCE);
- Common.SendToDebug("NIE - 64-bit In Events: " + myHeader.NIE);
- Common.SendToDebug("NER - 64-bit Event Register: " + myHeader.NER);
- Common.SendToDebug("Read position when exiting HEADER BLOCK: " + fs.Position);
- // STATIC BLOCK
- Common.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++;
- long startReadPos = fs.Position;
- Common.SendToDebug("Reading Static Block " + StaticBlockCount + " at: " + startReadPos);
- //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];
- Common.SendToDebug("Static Block ObjectType: " +
- ((LSO_Enums.Variable_Type_Codes) myStaticBlock.ObjectType).ToString());
- myStaticBlock.Unknown = br_read(1)[0];
- // Size of datatype varies -- what about strings?
- if (myStaticBlock.ObjectType != 0)
- myStaticBlock.BlockVariable = br_read(getObjectSize(myStaticBlock.ObjectType));
- StaticBlocks.Add((UInt32) startReadPos, myStaticBlock);
- }
- Common.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
- Common.SendToDebug("No FUNCTION BLOCK found");
- }
- else
- {
- Common.SendToDebug("Reading FUNCTION BLOCK at: " + myHeader.GFR);
- fs.Seek(myHeader.GFR, SeekOrigin.Begin);
- myFunctionBlock.FunctionCount = BitConverter.ToUInt32(br_read(4), 0);
- Common.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++)
- {
- Common.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;
- Common.SendToDebug("Fuction " + i + " code chunk position: " +
- myFunctionBlock.CodeChunkPointer[i]);
- }
- }
- }
- // STATE FRAME BLOCK
- // Always right after FUNCTION BLOCK
- Common.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++)
- {
- Common.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 BitArray(br_read(8));
- Common.SendToDebug("Pointer: " + myStateFrameBlock.StatePointer[i].Location);
- Common.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);
- Common.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
- Common.SendToDebug("State block Start Pos: " + myStateFrameBlock.StatePointer[i].StateBlock.StartPos);
- Common.SendToDebug("State block Header Size: " +
- myStateFrameBlock.StatePointer[i].StateBlock.HeaderSize);
- Common.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
- Common.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);
- Common.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);
- Common.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++)
- // {
- // Common.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)
- {
- Common.SendToDebug("Reading Event Code Chunk state " + i + ", event " +
- (LSO_Enums.Event_Mask_Values) ii);
- // Override a Method / Function
- string eventname = i + "_event_" + (LSO_Enums.Event_Mask_Values) ii;
- Common.SendToDebug("Event Name: " + eventname);
- if (Common.IL_ProcessCodeChunks)
- {
- EventList.Add(eventname);
- // JUMP TO CODE PROCESSOR
- ProcessCodeChunk(
- myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer,
- typeBuilder, eventname);
- }
- }
- }
- }
- }
- if (Common.IL_CreateFunctionList)
- IL_INSERT_FUNCTIONLIST();
- }
- internal LSO_Struct.HeapBlock GetHeap(UInt32 pos)
- {
- // HEAP BLOCK
- // TODO:? Special read for strings/keys (null terminated) and lists (pointers to other HEAP entries)
- Common.SendToDebug("Reading HEAP BLOCK at: " + pos);
- fs.Seek(pos, SeekOrigin.Begin);
- LSO_Struct.HeapBlock myHeapBlock = new LSO_Struct.HeapBlock();
- myHeapBlock.DataBlockSize = BitConverter.ToInt32(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));
- // Don't read it reversed
- myHeapBlock.Data = new byte[myHeapBlock.DataBlockSize - 1];
- br.Read(myHeapBlock.Data, 0, myHeapBlock.DataBlockSize - 1);
- Common.SendToDebug("Heap Block Data Block Size: " + myHeapBlock.DataBlockSize);
- Common.SendToDebug("Heap Block ObjectType: " +
- ((LSO_Enums.Variable_Type_Codes) myHeapBlock.ObjectType).ToString());
- Common.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)
- {
- Common.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 Type getLLObjectType(byte objectCode)
- {
- switch ((LSO_Enums.Variable_Type_Codes) objectCode)
- {
- case LSO_Enums.Variable_Type_Codes.Void:
- return typeof (void);
- case LSO_Enums.Variable_Type_Codes.Integer:
- return typeof (UInt32);
- case LSO_Enums.Variable_Type_Codes.Float:
- return typeof (float);
- case LSO_Enums.Variable_Type_Codes.String:
- return typeof (string);
- case LSO_Enums.Variable_Type_Codes.Key:
- return typeof (string);
- case LSO_Enums.Variable_Type_Codes.Vector:
- return typeof (LSO_Enums.Vector);
- case LSO_Enums.Variable_Type_Codes.Rotation:
- return typeof (LSO_Enums.Rotation);
- case LSO_Enums.Variable_Type_Codes.List:
- Common.SendToDebug("TODO: List datatype not implemented yet!");
- return typeof (ArrayList);
- case LSO_Enums.Variable_Type_Codes.Null:
- Common.SendToDebug("TODO: Datatype null is not implemented, using string instead.!");
- return typeof (string);
- default:
- Common.SendToDebug("Lookup of LSL datatype " + objectCode +
- " to .Net datatype failed: Unknown LSL datatype. Defaulting to object.");
- return typeof (object);
- }
- }
- private int getObjectSize(byte ObjectType)
- {
- switch ((LSO_Enums.Variable_Type_Codes) ObjectType)
- {
- case LSO_Enums.Variable_Type_Codes.Integer:
- case LSO_Enums.Variable_Type_Codes.Float:
- case LSO_Enums.Variable_Type_Codes.String:
- case LSO_Enums.Variable_Type_Codes.Key:
- case LSO_Enums.Variable_Type_Codes.List:
- return 4;
- case LSO_Enums.Variable_Type_Codes.Vector:
- return 12;
- case LSO_Enums.Variable_Type_Codes.Rotation:
- return 16;
- default:
- return 0;
- }
- }
- 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;
- }
- /// <summary>
- /// Reads a code chunk and creates IL
- /// </summary>
- /// <param name="pos">Absolute position in file. REMEMBER TO ADD myHeader.GFR!</param>
- /// <param name="typeBuilder">TypeBuilder for assembly</param>
- /// <param name="eventname">Name of event (function) to generate</param>
- private void ProcessCodeChunk(UInt32 pos, TypeBuilder typeBuilder, string eventname)
- {
- LSO_Struct.CodeChunk myCodeChunk = new LSO_Struct.CodeChunk();
- Common.SendToDebug("Reading Function Code Chunk at: " + pos);
- fs.Seek(pos, SeekOrigin.Begin);
- myCodeChunk.CodeChunkHeaderSize = BitConverter.ToUInt32(br_read(4), 0);
- Common.SendToDebug("CodeChunk Header Size: " + myCodeChunk.CodeChunkHeaderSize);
- // Read until null
- myCodeChunk.Comment = Read_String();
- Common.SendToDebug("Function comment: " + myCodeChunk.Comment);
- myCodeChunk.ReturnTypePos = br_read(1)[0];
- myCodeChunk.ReturnType = GetStaticBlock((long) myCodeChunk.ReturnTypePos + (long) myHeader.GVR);
- Common.SendToDebug("Return type #" + myCodeChunk.ReturnType.ObjectType + ": " +
- ((LSO_Enums.Variable_Type_Codes) myCodeChunk.ReturnType.ObjectType).ToString());
- // TODO: How to determine number of codechunks -- does this method work?
- myCodeChunk.CodeChunkArguments = new List<LSO_Struct.CodeChunkArgument>();
- byte reader = br_read(1)[0];
- reader = br_read(1)[0];
- // NOTE ON CODE CHUNK ARGUMENTS
- // This determins type definition
- int ccount = 0;
- while (reader != 0x000)
- {
- ccount++;
- Common.SendToDebug("Reading Code Chunk Argument " + ccount);
- LSO_Struct.CodeChunkArgument CCA = new LSO_Struct.CodeChunkArgument();
- CCA.FunctionReturnTypePos = reader;
- reader = br_read(1)[0];
- CCA.NullString = reader;
- CCA.FunctionReturnType = GetStaticBlock(CCA.FunctionReturnTypePos + myHeader.GVR);
- myCodeChunk.CodeChunkArguments.Add(CCA);
- Common.SendToDebug("Code Chunk Argument " + ccount + " type #" + CCA.FunctionReturnType.ObjectType +
- ": " + (LSO_Enums.Variable_Type_Codes) CCA.FunctionReturnType.ObjectType);
- }
- // Create string array
- Type[] MethodArgs = new Type[myCodeChunk.CodeChunkArguments.Count];
- for (int _ic = 0; _ic < myCodeChunk.CodeChunkArguments.Count; _ic++)
- {
- MethodArgs[_ic] = getLLObjectType(myCodeChunk.CodeChunkArguments[_ic].FunctionReturnType.ObjectType);
- Common.SendToDebug("Method argument " + _ic + ": " +
- getLLObjectType(myCodeChunk.CodeChunkArguments[_ic].FunctionReturnType.ObjectType).
- ToString());
- }
- // End marker is 0x000
- myCodeChunk.EndMarker = reader;
- //
- // Emit: START OF METHOD (FUNCTION)
- //
- Common.SendToDebug("CLR:" + eventname + ":MethodBuilder methodBuilder = typeBuilder.DefineMethod...");
- MethodBuilder methodBuilder = typeBuilder.DefineMethod(eventname,
- MethodAttributes.Public,
- typeof (void),
- new Type[] {typeof (object)});
- //MethodArgs);
- //typeof(void), //getLLObjectType(myCodeChunk.ReturnType),
- // new Type[] { typeof(object) }, //);
- //Common.SendToDebug("CLR:" + eventname + ":typeBuilder.DefineMethodOverride(methodBuilder...");
- //typeBuilder.DefineMethodOverride(methodBuilder,
- // typeof(LSL_CLRInterface.LSLScript).GetMethod(eventname));
- // Create the IL generator
- Common.SendToDebug("CLR:" + eventname + ":ILGenerator il = methodBuilder.GetILGenerator();");
- ILGenerator il = methodBuilder.GetILGenerator();
- if (Common.IL_UseTryCatch)
- IL_INSERT_TRY(il, eventname);
- // Push Console.WriteLine command to stack ... Console.WriteLine("Hello World!");
- //Common.SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call...");
- //il.Emit(OpCodes.Call, typeof(Console).GetMethod
- // ("WriteLine", new Type[] { typeof(string) }));
- //Common.SendToDebug("STARTUP: il.Emit(OpCodes.Ldc_I4_S, 0);");
- //il.Emit(OpCodes.Ldc_I4_S, 0);
- for (int _ic = 0; _ic < myCodeChunk.CodeChunkArguments.Count; _ic++)
- {
- Common.SendToDebug("PARAMS: il.Emit(OpCodes.Ldarg, " + _ic + ");");
- il.Emit(OpCodes.Ldarg, _ic);
- }
- //
- // CALLING OPCODE PROCESSOR, one command at the time TO GENERATE IL
- //
- bool FoundRet = false;
- while (FoundRet == false)
- {
- FoundRet = LSL_PROCESS_OPCODE(il);
- }
- if (Common.IL_UseTryCatch)
- IL_INSERT_END_TRY(il, eventname);
- // Emit: RETURN FROM METHOD
- il.Emit(OpCodes.Ret);
- return;
- }
- private void IL_INSERT_FUNCTIONLIST()
- {
- Common.SendToDebug("Creating function list");
- string eventname = "GetFunctions";
- Common.SendToDebug("Creating IL " + eventname);
- // Define a private String field.
- //FieldBuilder myField = myTypeBuilder.DefineField("EventList", typeof(String[]), FieldAttributes.Public);
- //FieldBuilder mem = typeBuilder.DefineField("mem", typeof(Array), FieldAttributes.Private);
- MethodBuilder methodBuilder = typeBuilder.DefineMethod(eventname,
- MethodAttributes.Public,
- typeof (string[]),
- null);
- //typeBuilder.DefineMethodOverride(methodBuilder,
- // typeof(LSL_CLRInterface.LSLScript).GetMethod(eventname));
- ILGenerator il = methodBuilder.GetILGenerator();
- // IL_INSERT_TRY(il, eventname);
- // // Push string to stack
- // il.Emit(OpCodes.Ldstr, "Inside " + eventname);
- //// Push Console.WriteLine command to stack ... Console.WriteLine("Hello World!");
- //il.Emit(OpCodes.Call, typeof(Console).GetMethod
- // ("WriteLine", new Type[] { typeof(string) }));
- //initIL.Emit(OpCodes.Newobj, typeof(string[]));
- //string[] MyArray = new string[2] { "TestItem1" , "TestItem2" };
- ////il.Emit(OpCodes.Ldarg_0);
- il.DeclareLocal(typeof (string[]));
- ////il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Ldc_I4, EventList.Count); // Specify array length
- il.Emit(OpCodes.Newarr, typeof (String)); // create new string array
- il.Emit(OpCodes.Stloc_0); // Store array as local variable 0 in stack
- ////SetFunctionList
- for (int lv = 0; lv < EventList.Count; lv++)
- {
- il.Emit(OpCodes.Ldloc_0); // Load local variable 0 onto stack
- il.Emit(OpCodes.Ldc_I4, lv); // Push index position
- il.Emit(OpCodes.Ldstr, EventList[lv]); // Push value
- il.Emit(OpCodes.Stelem_Ref); // Perform array[index] = value
- //il.Emit(OpCodes.Ldarg_0);
- //il.Emit(OpCodes.Ldstr, EventList[lv]); // Push value
- //il.Emit(OpCodes.Call, typeof(LSL_BaseClass).GetMethod("AddFunction", new Type[] { typeof(string) }));
- }
- // IL_INSERT_END_TRY(il, eventname);
- il.Emit(OpCodes.Ldloc_0); // Load local variable 0 onto stack
- // il.Emit(OpCodes.Call, typeof(LSL_BaseClass).GetMethod("SetFunctionList", new Type[] { typeof(Array) }));
- il.Emit(OpCodes.Ret); // Return
- }
- private void IL_INSERT_TRY(ILGenerator il, string eventname)
- {
- /*
- * CLR TRY
- */
- //Common.SendToDebug("CLR:" + eventname + ":il.BeginExceptionBlock()");
- il.BeginExceptionBlock();
- // Push "Hello World!" string to stack
- //Common.SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Ldstr...");
- //il.Emit(OpCodes.Ldstr, "Starting CLR dynamic execution of: " + eventname);
- }
- private void IL_INSERT_END_TRY(ILGenerator il, string eventname)
- {
- /*
- * CATCH
- */
- Common.SendToDebug("CLR:" + eventname + ":il.BeginCatchBlock(typeof(Exception));");
- il.BeginCatchBlock(typeof (Exception));
- // Push "Hello World!" string to stack
- Common.SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Ldstr...");
- il.Emit(OpCodes.Ldstr, "Execption executing dynamic CLR function " + eventname + ": ");
- //call void [mscorlib]System.Console::WriteLine(string)
- Common.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()
- Common.SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Callvirt...");
- il.Emit(OpCodes.Callvirt, typeof (Exception).GetMethod
- ("get_Message"));
- //call void [mscorlib]System.Console::WriteLine(string)
- Common.SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call...");
- il.Emit(OpCodes.Call, typeof (Console).GetMethod
- ("WriteLine", new Type[] {typeof (string)}));
- /*
- * CLR END TRY
- */
- //Common.SendToDebug("CLR:" + eventname + ":il.EndExceptionBlock();");
- il.EndExceptionBlock();
- }
- private LSO_Struct.StaticBlock GetStaticBlock(long pos)
- {
- long FirstPos = fs.Position;
- try
- {
- UInt32 position = (UInt32) pos;
- // STATIC BLOCK
- Common.SendToDebug("Reading STATIC BLOCK at: " + position);
- fs.Seek(position, SeekOrigin.Begin);
- if (StaticBlocks.ContainsKey(position) == true)
- {
- Common.SendToDebug("Found cached STATIC BLOCK");
- return StaticBlocks[pos];
- }
- //int StaticBlockCount = 0;
- // Read function blocks until we hit GFR
- //while (fs.Position < myHeader.GFR)
- //{
- //StaticBlockCount++;
- //Common.SendToDebug("Reading Static Block at: " + 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];
- Common.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));
- StaticBlocks.Add(position, myStaticBlock);
- //}
- Common.SendToDebug("Done reading Static Block.");
- return myStaticBlock;
- }
- finally
- {
- // Go back to original read pos
- fs.Seek(FirstPos, SeekOrigin.Begin);
- }
- }
- }
- }
|