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;
}
}
}