Welcome back LSO.

Added old LSO code, will use it as base to create new LSO VM.
ThreadPoolClientBranch
Tedd Hansen 2008-01-12 15:49:41 +00:00
parent 0081c060d0
commit 27859faf7a
13 changed files with 3051 additions and 0 deletions

View File

@ -0,0 +1,86 @@
/*
* 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;
namespace OpenSim.Region.ScriptEngine.LSOEngine.LSO
{
public static class Common
{
public static bool Debug = true;
public static bool IL_UseTryCatch = true;
public static bool IL_CreateConstructor = true;
public static bool IL_CreateFunctionList = true;
public static bool IL_ProcessCodeChunks = true;
public delegate void SendToDebugEventDelegate(string Message);
public delegate void SendToLogEventDelegate(string Message);
public static event SendToDebugEventDelegate SendToDebugEvent;
public static event SendToLogEventDelegate SendToLogEvent;
public static void SendToDebug(string Message)
{
//if (Debug == true)
Console.WriteLine("COMPILER:Debug: " + Message);
SendToDebugEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + Message);
}
public static void SendToLog(string Message)
{
//if (Debug == true)
Console.WriteLine("COMPILER:LOG: " + Message);
SendToLogEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + Message);
}
}
public static class IL_Helper
{
public static string ReverseFormatString(string text1, string format)
{
Common.SendToDebug("ReverseFormatString text1: " + text1);
Common.SendToDebug("ReverseFormatString format: " + format);
return string.Format(format, text1);
}
public static string ReverseFormatString(string text1, UInt32 text2, string format)
{
Common.SendToDebug("ReverseFormatString text1: " + text1);
Common.SendToDebug("ReverseFormatString text2: " + text2.ToString());
Common.SendToDebug("ReverseFormatString format: " + format);
return string.Format(format, text1, text2.ToString());
}
public static string Cast_ToString(object obj)
{
Common.SendToDebug("OBJECT TO BE CASTED: " + obj.GetType().ToString());
return "ABCDEFGIHJKLMNOPQ123";
}
}
}

View File

@ -0,0 +1,293 @@
/*
* 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.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Threading;
using OpenSim.Region.ScriptEngine.Common;
using OpenSim.Region.ScriptEngine.LSOEngine.LSO;
namespace OpenSim.Region.ScriptEngine.LSOEngine.LSO
{
public class Engine
{
//private string LSO_FileName = @"LSO\AdditionTest.lso";
private string LSO_FileName; // = @"LSO\CloseToDefault.lso";
private AppDomain appDomain;
public string Compile(string LSOFileName)
{
LSO_FileName = LSOFileName;
//appDomain = AppDomain.CreateDomain("AlternateAppDomain");
appDomain = Thread.GetDomain();
// Create Assembly Name
AssemblyName asmName = new AssemblyName();
asmName.Name = Path.GetFileNameWithoutExtension(LSO_FileName);
//asmName.Name = "TestAssembly";
string DLL_FileName = asmName.Name + ".dll";
string DLL_FileName_WithPath = Path.GetDirectoryName(LSO_FileName) + @"\" + DLL_FileName;
LSOEngine.LSO.Common.SendToLog("LSO File Name: " + Path.GetFileName(LSO_FileName));
LSOEngine.LSO.Common.SendToLog("Assembly name: " + asmName.Name);
LSOEngine.LSO.Common.SendToLog("Assembly File Name: " + asmName.Name + ".dll");
LSOEngine.LSO.Common.SendToLog("Starting processing of LSL ByteCode...");
LSOEngine.LSO.Common.SendToLog("");
// Create Assembly
AssemblyBuilder asmBuilder = appDomain.DefineDynamicAssembly(
asmName,
AssemblyBuilderAccess.RunAndSave
);
//// Create Assembly
//AssemblyBuilder asmBuilder =
// Thread.GetDomain().DefineDynamicAssembly
//(asmName, AssemblyBuilderAccess.RunAndSave);
// Create a module (and save to disk)
ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule
(asmName.Name,
DLL_FileName);
//Common.SendToDebug("asmName.Name is still \"" + asmName.Name + "\"");
// Create a Class (/Type)
TypeBuilder typeBuilder = modBuilder.DefineType(
"LSL_ScriptObject",
TypeAttributes.Public | TypeAttributes.BeforeFieldInit,
typeof (LSL_BaseClass));
//,
// typeof());
//, typeof(LSL_BuiltIn_Commands_Interface));
//,
// typeof(object),
// new Type[] { typeof(LSL_CLRInterface.LSLScript) });
/*
* Generate the IL itself
*/
LSO_Parser LSOP = new LSO_Parser(LSO_FileName, typeBuilder);
LSOP.OpenFile();
LSOP.Parse();
// Constructor has to be created AFTER LSO_Parser because of accumulated variables
if (LSOEngine.LSO.Common.IL_CreateConstructor)
IL_CREATE_CONSTRUCTOR(typeBuilder, LSOP);
LSOP.CloseFile();
/*
* Done generating. Create a type and run it.
*/
LSOEngine.LSO.Common.SendToLog("Attempting to compile assembly...");
// Compile it
Type type = typeBuilder.CreateType();
LSOEngine.LSO.Common.SendToLog("Compilation successful!");
LSOEngine.LSO.Common.SendToLog("Saving assembly: " + DLL_FileName);
asmBuilder.Save(DLL_FileName);
LSOEngine.LSO.Common.SendToLog("Returning assembly filename: " + DLL_FileName);
return DLL_FileName;
//Common.SendToLog("Creating an instance of new assembly...");
//// Create an instance we can play with
////LSLScript hello = (LSLScript)Activator.CreateInstance(type);
////LSL_CLRInterface.LSLScript MyScript = (LSL_CLRInterface.LSLScript)Activator.CreateInstance(type);
//object MyScript = (object)Activator.CreateInstance(type);
//System.Reflection.MemberInfo[] Members = type.GetMembers();
//Common.SendToLog("Members of assembly " + type.ToString() + ":");
//foreach (MemberInfo member in Members)
// Common.SendToLog(member.ToString());
//// Play with it
////MyScript.event_state_entry("Test");
//object[] args = { null };
////System.Collections.Generic.List<string> Functions = (System.Collections.Generic.List<string>)type.InvokeMember("GetFunctions", BindingFlags.InvokeMethod, null, MyScript, null);
//string[] ret = { };
//if (Common.IL_CreateFunctionList)
// ret = (string[])type.InvokeMember("GetFunctions", BindingFlags.InvokeMethod, null, MyScript, null);
//foreach (string s in ret)
//{
// Common.SendToLog("");
// Common.SendToLog("*** Executing LSL Server Event: " + s);
// //object test = type.GetMember(s);
// //object runner = type.InvokeMember(s, BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance, null, MyScript, args);
// //runner();
// //objBooks_Late = type.InvokeMember(s, BindingFlags.CreateInstance, null, objApp_Late, null);
// type.InvokeMember(s, BindingFlags.InvokeMethod, null, MyScript, new object[] { "Test" });
//}
}
private static void IL_CREATE_CONSTRUCTOR(TypeBuilder typeBuilder, LSO_Parser LSOP)
{
LSOEngine.LSO.Common.SendToDebug("IL_CREATE_CONSTRUCTOR()");
//ConstructorBuilder constructor = typeBuilder.DefineConstructor(
// MethodAttributes.Public,
// CallingConventions.Standard,
// new Type[0]);
ConstructorBuilder constructor = typeBuilder.DefineConstructor(
MethodAttributes.Public |
MethodAttributes.SpecialName |
MethodAttributes.RTSpecialName,
CallingConventions.Standard,
new Type[0]);
//Define the reflection ConstructorInfor for System.Object
ConstructorInfo conObj = typeof (LSL_BaseClass).GetConstructor(new Type[0]);
//call constructor of base object
ILGenerator il = constructor.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, conObj);
//Common.SendToDebug("IL_CREATE_CONSTRUCTOR: Creating global: UInt32 State = 0;");
//string FieldName;
//// Create state object
//FieldName = "State";
//FieldBuilder State_fb = typeBuilder.DefineField(
// FieldName,
// typeof(UInt32),
// FieldAttributes.Public);
//il.Emit(OpCodes.Ldarg_0);
//il.Emit(OpCodes.Ldc_I4, 0);
//il.Emit(OpCodes.Stfld, State_fb);
//Common.SendToDebug("IL_CREATE_CONSTRUCTOR: Creating global: LSL_BuiltIn_Commands_TestImplementation LSL_BuiltIns = New LSL_BuiltIn_Commands_TestImplementation();");
////Type objType1 = typeof(object);
//Type objType1 = typeof(LSL_BuiltIn_Commands_TestImplementation);
//FieldName = "LSL_BuiltIns";
//FieldBuilder LSL_BuiltIns_fb = typeBuilder.DefineField(
// FieldName,
// objType1,
// FieldAttributes.Public);
////LSL_BuiltIn_Commands_TestImplementation _ti = new LSL_BuiltIn_Commands_TestImplementation();
//il.Emit(OpCodes.Ldarg_0);
////il.Emit(OpCodes.Ldstr, "Test 123");
//il.Emit(OpCodes.Newobj, objType1.GetConstructor(new Type[] { }));
//il.Emit(OpCodes.Stfld, LSL_BuiltIns_fb);
foreach (UInt32 pos in LSOP.StaticBlocks.Keys)
{
LSO_Struct.StaticBlock sb;
LSOP.StaticBlocks.TryGetValue(pos, out sb);
if (sb.ObjectType > 0 && sb.ObjectType < 8)
{
// We don't want void or null's
il.Emit(OpCodes.Ldarg_0);
// Push position to stack
il.Emit(OpCodes.Ldc_I4, pos);
//il.Emit(OpCodes.Box, typeof(UInt32));
Type datatype = null;
// Push data to stack
LSOEngine.LSO.Common.SendToDebug("Adding to static (" + pos + ") type: " +
((LSO_Enums.Variable_Type_Codes) sb.ObjectType).ToString() + " (" + sb.ObjectType +
")");
switch ((LSO_Enums.Variable_Type_Codes) sb.ObjectType)
{
case LSO_Enums.Variable_Type_Codes.Float:
case LSO_Enums.Variable_Type_Codes.Integer:
//UInt32
il.Emit(OpCodes.Ldc_I4, BitConverter.ToUInt32(sb.BlockVariable, 0));
datatype = typeof (UInt32);
il.Emit(OpCodes.Box, datatype);
break;
case LSO_Enums.Variable_Type_Codes.String:
case LSO_Enums.Variable_Type_Codes.Key:
//String
LSO_Struct.HeapBlock hb =
LSOP.GetHeap(LSOP.myHeader.HR + BitConverter.ToUInt32(sb.BlockVariable, 0) - 1);
il.Emit(OpCodes.Ldstr, Encoding.UTF8.GetString(hb.Data));
datatype = typeof (string);
break;
case LSO_Enums.Variable_Type_Codes.Vector:
datatype = typeof (LSO_Enums.Vector);
//TODO: Not implemented
break;
case LSO_Enums.Variable_Type_Codes.Rotation:
//Object
//TODO: Not implemented
datatype = typeof (LSO_Enums.Rotation);
break;
default:
datatype = typeof (object);
break;
}
// Make call
il.Emit(OpCodes.Call,
typeof (LSL_BaseClass).GetMethod("AddToStatic", new Type[] {typeof (UInt32), datatype}));
}
}
////il.Emit(OpCodes.Newobj, typeof(UInt32));
//il.Emit(OpCodes.Starg_0);
//// Create LSL function library
//FieldBuilder LSL_BuiltIns_fb = typeBuilder.DefineField("LSL_BuiltIns", typeof(LSL_BuiltIn_Commands_Interface), FieldAttributes.Public);
//il.Emit(OpCodes.Newobj, typeof(LSL_BuiltIn_Commands_Interface));
//il.Emit(OpCodes.Stloc_1);
il.Emit(OpCodes.Ret);
}
// End of class
}
}

View File

@ -0,0 +1,51 @@
/*
* 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.Reflection;
using System.Reflection.Emit;
namespace OpenSim.Region.ScriptEngine.LSOEngine.LSO
{
internal partial class LSO_Parser
{
private static TypeBuilder CreateType(ModuleBuilder modBuilder, string typeName)
{
TypeBuilder typeBuilder = modBuilder.DefineType(typeName,
TypeAttributes.Public |
TypeAttributes.Class |
TypeAttributes.AutoClass |
TypeAttributes.AnsiClass |
TypeAttributes.BeforeFieldInit |
TypeAttributes.AutoLayout,
typeof (object),
new Type[] {typeof (object)});
return typeBuilder;
}
}
}

View File

@ -0,0 +1,395 @@
/*
* 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.
*
*/
using System;
using System.Collections.Generic;
namespace OpenSim.Region.ScriptEngine.LSOEngine.LSO
{
//public partial class LSL_BaseClass
//{
// /*
// * OPCODES
// *
// * These are internal "assembly" commands,
// * basic operators like "ADD", "PUSH" and "POP"
// *
// * It also contains managed stack and keeps track of internal variables, etc.
// *
// */
// public void StoreToLocal(UInt32 index)
// {
// // TODO: How to determine local?
// LSOEngine.LSO.Common.SendToDebug("::StoreToLocal " + index);
// if (LocalVariables.ContainsKey(index))
// LocalVariables.Remove(index);
// LocalVariables.Add(index, LSLStack.Peek());
// }
// public void StoreToGlobal(UInt32 index)
// {
// LSOEngine.LSO.Common.SendToDebug("::StoreToGlobal " + index);
// if (GlobalVariables.ContainsKey(index))
// GlobalVariables.Remove(index);
// GlobalVariables.Add(index, LSLStack.Peek());
// }
// public void StoreToStatic(UInt32 index)
// {
// LSOEngine.LSO.Common.SendToDebug("::StoreToStatic " + index);
// //if (StaticVariables.ContainsKey(index))
// // StaticVariables.Remove(index);
// StaticVariables.Add(index, LSLStack.Peek());
// }
// public void GetFromLocal(UInt32 index)
// {
// // TODO: How to determine local?
// LSOEngine.LSO.Common.SendToDebug("::GetFromLocal " + index);
// object ret;
// LocalVariables.TryGetValue(index, out ret);
// LSLStack.Push(ret);
// //return ret;
// }
// public void GetFromGlobal(UInt32 index)
// {
// LSOEngine.LSO.Common.SendToDebug("::GetFromGlobal " + index);
// object ret;
// GlobalVariables.TryGetValue(index, out ret);
// LSLStack.Push(ret);
// //return ret;
// }
// public void GetFromStatic(UInt32 index)
// {
// LSOEngine.LSO.Common.SendToDebug("::GetFromStatic " + index);
// object ret;
// StaticVariables.TryGetValue(index, out ret);
// LSOEngine.LSO.Common.SendToDebug("::GetFromStatic - ObjectType: " + ret.GetType().ToString());
// LSLStack.Push(ret);
// //return ret;
// }
// public object POPToStack()
// {
// LSOEngine.LSO.Common.SendToDebug("::POPToStack");
// //return LSLStack.Pop();
// object p = LSLStack.Pop();
// if (p.GetType() == typeof (UInt32))
// return (UInt32) p;
// if (p.GetType() == typeof (string))
// return (string) p;
// if (p.GetType() == typeof (Int32))
// return (Int32) p;
// if (p.GetType() == typeof (UInt16))
// return (UInt16) p;
// if (p.GetType() == typeof (float))
// return (float) p;
// if (p.GetType() == typeof (LSO_Enums.Vector))
// return (LSO_Enums.Vector) p;
// if (p.GetType() == typeof (LSO_Enums.Rotation))
// return (LSO_Enums.Rotation) p;
// if (p.GetType() == typeof (LSO_Enums.Key))
// return (LSO_Enums.Key) p;
// return p;
// }
// //public object POPToStack(UInt32 count)
// //{
// // // POP NUMBER FROM TOP OF STACK
// // //LSLStack.SetLength(LSLStack.Length - 4);
// // Common.SendToDebug("::POPToStack " + count);
// // if (count < 2)
// // return LSLStack.Pop();
// // Stack<object> s = new Stack<object>();
// // for (int i = 0; i < count; i++)
// // {
// // s.Push(LSLStack.Pop);
// // }
// //}
// public void POP()
// {
// // POP NUMBER FROM TOP OF STACK
// //LSLStack.SetLength(LSLStack.Length - 4);
// LSOEngine.LSO.Common.SendToDebug("::POP");
// if (LSLStack.Count < 1)
// {
// //TODO: Temporary fix
// LSOEngine.LSO.Common.SendToDebug("ERROR: TRYING TO POP EMPTY STACK!");
// }
// else
// {
// LSLStack.Pop();
// }
// }
// public void PUSH(object Param)
// {
// if (Param == null)
// {
// LSOEngine.LSO.Common.SendToDebug("::PUSH: <null>");
// }
// else
// {
// //Common.SendToDebug("::PUSH: " + Param.GetType());
// }
// LSLStack.Push(Param);
// }
// public void ADD(UInt32 Param)
// {
// LSOEngine.LSO.Common.SendToDebug("::ADD: " + Param);
// object o2 = LSLStack.Pop();
// object o1 = LSLStack.Pop();
// LSOEngine.LSO.Common.SendToDebug("::ADD: Debug: o1: " + o1.GetType() + " (" + o1.ToString() + "), o2: " + o2.GetType() +
// " (" + o2.ToString() + ")");
// if (o2.GetType() == typeof (string))
// {
// LSLStack.Push((string) o1 + (string) o2);
// return;
// }
// if (o2.GetType() == typeof (UInt32))
// {
// LSLStack.Push((UInt32) o1 + (UInt32) o2);
// return;
// }
// }
// public void SUB(UInt32 Param)
// {
// LSOEngine.LSO.Common.SendToDebug("::SUB: " + Param);
// UInt32 i2 = (UInt32) LSLStack.Pop();
// UInt32 i1 = (UInt32) LSLStack.Pop();
// LSLStack.Push((UInt32) (i1 - i2));
// }
// public void MUL(UInt32 Param)
// {
// LSOEngine.LSO.Common.SendToDebug("::SUB: " + Param);
// UInt32 i2 = (UInt32) LSLStack.Pop();
// UInt32 i1 = (UInt32) LSLStack.Pop();
// LSLStack.Push((UInt32) (i1*i2));
// }
// public void DIV(UInt32 Param)
// {
// LSOEngine.LSO.Common.SendToDebug("::DIV: " + Param);
// UInt32 i2 = (UInt32) LSLStack.Pop();
// UInt32 i1 = (UInt32) LSLStack.Pop();
// LSLStack.Push((UInt32) (i1/i2));
// }
// public void MOD(UInt32 Param)
// {
// LSOEngine.LSO.Common.SendToDebug("::MOD: " + Param);
// UInt32 i2 = (UInt32) LSLStack.Pop();
// UInt32 i1 = (UInt32) LSLStack.Pop();
// LSLStack.Push((UInt32) (i1%i2));
// }
// public void EQ(UInt32 Param)
// {
// LSOEngine.LSO.Common.SendToDebug("::EQ: " + Param);
// UInt32 i2 = (UInt32) LSLStack.Pop();
// UInt32 i1 = (UInt32) LSLStack.Pop();
// if (i1 == i2)
// {
// LSLStack.Push((UInt32) 1);
// }
// else
// {
// LSLStack.Push((UInt32) 0);
// }
// }
// public void NEQ(UInt32 Param)
// {
// LSOEngine.LSO.Common.SendToDebug("::NEQ: " + Param);
// UInt32 i2 = (UInt32) LSLStack.Pop();
// UInt32 i1 = (UInt32) LSLStack.Pop();
// if (i1 != i2)
// {
// LSLStack.Push((UInt32) 1);
// }
// else
// {
// LSLStack.Push((UInt32) 0);
// }
// }
// public void LEQ(UInt32 Param)
// {
// LSOEngine.LSO.Common.SendToDebug("::LEQ: " + Param);
// UInt32 i2 = (UInt32) LSLStack.Pop();
// UInt32 i1 = (UInt32) LSLStack.Pop();
// if (i1 <= i2)
// {
// LSLStack.Push((UInt32) 1);
// }
// else
// {
// LSLStack.Push((UInt32) 0);
// }
// }
// public void GEQ(UInt32 Param)
// {
// LSOEngine.LSO.Common.SendToDebug("::GEQ: " + Param);
// UInt32 i2 = (UInt32) LSLStack.Pop();
// UInt32 i1 = (UInt32) LSLStack.Pop();
// if (i1 >= i2)
// {
// LSLStack.Push((UInt32) 1);
// }
// else
// {
// LSLStack.Push((UInt32) 0);
// }
// }
// public void LESS(UInt32 Param)
// {
// LSOEngine.LSO.Common.SendToDebug("::LESS: " + Param);
// UInt32 i2 = (UInt32) LSLStack.Pop();
// UInt32 i1 = (UInt32) LSLStack.Pop();
// if (i1 < i2)
// {
// LSLStack.Push((UInt32) 1);
// }
// else
// {
// LSLStack.Push((UInt32) 0);
// }
// }
// public void GREATER(UInt32 Param)
// {
// LSOEngine.LSO.Common.SendToDebug("::GREATER: " + Param);
// UInt32 i2 = (UInt32) LSLStack.Pop();
// UInt32 i1 = (UInt32) LSLStack.Pop();
// if (i1 > i2)
// {
// LSLStack.Push((UInt32) 1);
// }
// else
// {
// LSLStack.Push((UInt32) 0);
// }
// }
// public void BITAND()
// {
// LSOEngine.LSO.Common.SendToDebug("::BITAND");
// UInt32 i2 = (UInt32) LSLStack.Pop();
// UInt32 i1 = (UInt32) LSLStack.Pop();
// LSLStack.Push((UInt32) (i1 & i2));
// }
// public void BITOR()
// {
// LSOEngine.LSO.Common.SendToDebug("::BITOR");
// UInt32 i2 = (UInt32) LSLStack.Pop();
// UInt32 i1 = (UInt32) LSLStack.Pop();
// LSLStack.Push((UInt32) (i1 | i2));
// }
// public void BITXOR()
// {
// LSOEngine.LSO.Common.SendToDebug("::BITXOR");
// UInt32 i2 = (UInt32) LSLStack.Pop();
// UInt32 i1 = (UInt32) LSLStack.Pop();
// LSLStack.Push((UInt32) (i1 ^ i2));
// }
// public void BOOLAND()
// {
// LSOEngine.LSO.Common.SendToDebug("::BOOLAND");
// bool b2 = bool.Parse((string) LSLStack.Pop());
// bool b1 = bool.Parse((string) LSLStack.Pop());
// if (b1 && b2)
// {
// LSLStack.Push((UInt32) 1);
// }
// else
// {
// LSLStack.Push((UInt32) 0);
// }
// }
// public void BOOLOR()
// {
// LSOEngine.LSO.Common.SendToDebug("::BOOLOR");
// bool b2 = bool.Parse((string) LSLStack.Pop());
// bool b1 = bool.Parse((string) LSLStack.Pop());
// if (b1 || b2)
// {
// LSLStack.Push((UInt32) 1);
// }
// else
// {
// LSLStack.Push((UInt32) 0);
// }
// }
// public void NEG(UInt32 Param)
// {
// LSOEngine.LSO.Common.SendToDebug("::NEG: " + Param);
// //UInt32 i2 = (UInt32)LSLStack.Pop();
// UInt32 i1 = (UInt32) LSLStack.Pop();
// LSLStack.Push((UInt32) (i1*-1));
// }
// public void BITNOT()
// {
// //Common.SendToDebug("::BITNOT");
// //UInt32 i2 = (UInt32)LSLStack.Pop();
// //UInt32 i1 = (UInt32)LSLStack.Pop();
// //LSLStack.Push((UInt32)(i1 / i2));
// }
// public void BOOLNOT()
// {
// //Common.SendToDebug("::BOOLNOT");
// ////UInt32 i2 = (UInt32)LSLStack.Pop();
// //UInt32 i1 = (UInt32)LSLStack.Pop();
// //LSLStack.Push((UInt32)(i1));
// }
//}
}

View File

@ -0,0 +1,75 @@
/*
* 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 */
namespace OpenSim.Region.ScriptEngine.LSOEngine.LSO
{
public class LSL_CLRInterface
{
public interface LSLScript
{
//public virtual void Run(object arg)
//{
//}
//void Run(object arg);
//void event_state_entry(object arg);
//void event_state_exit();
//void event_touch_start(object arg);
//void event_touch();
//void event_touch_end();
//void event_collision_start();
//void event_collision();
//void event_collision_end();
//void event_land_collision_start();
//void event_land_collision();
//void event_land_collision_end();
//void event_timer();
//void event_listen();
//void event_on_rez();
//void event_sensor();
//void event_no_sensor();
//void event_control();
//void event_money();
//void event_email();
//void event_at_target();
//void event_not_at_target();
//void event_at_rot_target();
//void event_not_at_rot_target();
//void event_run_time_permissions();
//void event_changed();
//void event_attach();
//void event_dataserver();
//void event_link_message();
//void event_moving_start();
//void event_moving_end();
//void event_object_rez();
//void event_remote_data();
//void event_http_response();
}
}
}

View File

@ -0,0 +1,435 @@
/*
* 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.Reflection;
using System.Reflection.Emit;
using OpenSim.Region.ScriptEngine.Common;
namespace OpenSim.Region.ScriptEngine.LSOEngine.LSO
{
internal partial class LSO_Parser
{
//internal Stack<Type> ILStack = new Stack<Type>();
//LSO_Enums MyLSO_Enums = new LSO_Enums();
internal bool LSL_PROCESS_OPCODE(ILGenerator il)
{
byte bp1;
UInt32 u32p1;
float fp1;
UInt16 opcode = br_read(1)[0];
Common.SendToDebug("OPCODE: " + ((LSO_Enums.Operation_Table) opcode).ToString());
string idesc = ((LSO_Enums.Operation_Table) opcode).ToString();
switch ((LSO_Enums.Operation_Table) opcode)
{
/***************
* IMPLEMENTED *
***************/
case LSO_Enums.Operation_Table.NOOP:
break;
case LSO_Enums.Operation_Table.PUSHSP:
// Push Stack Top (Memory Address) to stack
Common.SendToDebug("Instruction " + idesc);
Common.SendToDebug("Instruction " + idesc +
": Description: Pushing Stack Top (Memory Address from header) to stack");
IL_Push(il, (UInt32) myHeader.SP);
break;
// BYTE
case LSO_Enums.Operation_Table.PUSHARGB:
Common.SendToDebug("Param1: " + br_read(1)[0]);
break;
// INTEGER
case LSO_Enums.Operation_Table.PUSHARGI:
u32p1 = BitConverter.ToUInt32(br_read(4), 0);
Common.SendToDebug("Instruction " + idesc + ", Param1: " + u32p1);
IL_Push(il, u32p1);
break;
// FLOAT
case LSO_Enums.Operation_Table.PUSHARGF:
fp1 = BitConverter.ToUInt32(br_read(4), 0);
Common.SendToDebug("Instruction " + idesc + ", Param1: " + fp1);
IL_Push(il, fp1);
break;
// STRING
case LSO_Enums.Operation_Table.PUSHARGS:
string s = Read_String();
Common.SendToDebug("Instruction " + idesc + ", Param1: " + s);
IL_Debug(il, "OPCODE: " + idesc + ":" + s);
IL_Push(il, s);
break;
// VECTOR z,y,x
case LSO_Enums.Operation_Table.PUSHARGV:
LSO_Enums.Vector v = new LSO_Enums.Vector();
v.Z = BitConverter.ToUInt32(br_read(4), 0);
v.Y = BitConverter.ToUInt32(br_read(4), 0);
v.X = BitConverter.ToUInt32(br_read(4), 0);
Common.SendToDebug("Param1 Z: " + v.Z);
Common.SendToDebug("Param1 Y: " + v.Y);
Common.SendToDebug("Param1 X: " + v.X);
IL_Push(il, v);
break;
// ROTATION s,z,y,x
case LSO_Enums.Operation_Table.PUSHARGQ:
LSO_Enums.Rotation r = new LSO_Enums.Rotation();
r.S = BitConverter.ToUInt32(br_read(4), 0);
r.Z = BitConverter.ToUInt32(br_read(4), 0);
r.Y = BitConverter.ToUInt32(br_read(4), 0);
r.X = BitConverter.ToUInt32(br_read(4), 0);
Common.SendToDebug("Param1 S: " + r.S);
Common.SendToDebug("Param1 Z: " + r.Z);
Common.SendToDebug("Param1 Y: " + r.Y);
Common.SendToDebug("Param1 X: " + r.X);
IL_Push(il, r);
break;
case LSO_Enums.Operation_Table.PUSHE:
IL_Push(il, (UInt32) 0);
break;
case LSO_Enums.Operation_Table.PUSHARGE:
u32p1 = BitConverter.ToUInt32(br_read(4), 0);
Common.SendToDebug("Param1: " + u32p1);
//IL_Push(il, new string(" ".ToCharArray()[0], Convert.ToInt32(u32p1)));
IL_Push(il, u32p1);
break;
// BYTE
case LSO_Enums.Operation_Table.ADD:
case LSO_Enums.Operation_Table.SUB:
case LSO_Enums.Operation_Table.MUL:
case LSO_Enums.Operation_Table.DIV:
case LSO_Enums.Operation_Table.EQ:
case LSO_Enums.Operation_Table.NEQ:
case LSO_Enums.Operation_Table.LEQ:
case LSO_Enums.Operation_Table.GEQ:
case LSO_Enums.Operation_Table.LESS:
case LSO_Enums.Operation_Table.GREATER:
case LSO_Enums.Operation_Table.NEG:
case LSO_Enums.Operation_Table.MOD:
bp1 = br_read(1)[0];
Common.SendToDebug("Param1: " + bp1);
IL_CallBaseFunction(il, idesc, (UInt32) bp1);
break;
// NO ARGUMENTS
case LSO_Enums.Operation_Table.BITAND:
case LSO_Enums.Operation_Table.BITOR:
case LSO_Enums.Operation_Table.BITXOR:
case LSO_Enums.Operation_Table.BOOLAND:
case LSO_Enums.Operation_Table.BOOLOR:
case LSO_Enums.Operation_Table.BITNOT:
case LSO_Enums.Operation_Table.BOOLNOT:
IL_CallBaseFunction(il, idesc);
break;
// SHORT
case LSO_Enums.Operation_Table.CALLLIB_TWO_BYTE:
// TODO: What is size of short?
UInt16 U16p1 = BitConverter.ToUInt16(br_read(2), 0);
Common.SendToDebug("Instruction " + idesc + ": Builtin Command: " +
((LSO_Enums.BuiltIn_Functions) U16p1).ToString());
//Common.SendToDebug("Param1: " + U16p1);
string fname = ((LSO_Enums.BuiltIn_Functions) U16p1).ToString();
bool cmdFound = false;
foreach (MethodInfo mi in typeof (LSL_BuiltIn_Commands_Interface).GetMethods())
{
// Found command
if (mi.Name == fname)
{
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, typeof (LSL_BaseClass).GetMethod("GetLSL_BuiltIn", new Type[] {}));
// Pop required number of items from my stack to .Net stack
IL_PopToStack(il, mi.GetParameters().Length);
il.Emit(OpCodes.Callvirt, mi);
cmdFound = true;
break;
}
}
if (cmdFound == false)
{
Common.SendToDebug("ERROR: UNABLE TO LOCATE OPCODE " + idesc + " IN BASECLASS");
}
break;
// RETURN
case LSO_Enums.Operation_Table.RETURN:
Common.SendToDebug("OPCODE: RETURN");
return true;
case LSO_Enums.Operation_Table.POP:
case LSO_Enums.Operation_Table.POPS:
case LSO_Enums.Operation_Table.POPL:
case LSO_Enums.Operation_Table.POPV:
case LSO_Enums.Operation_Table.POPQ:
// Pops a specific datatype from the stack
// We just ignore the datatype for now
IL_Pop(il);
break;
// LONG
case LSO_Enums.Operation_Table.STORE:
case LSO_Enums.Operation_Table.STORES:
case LSO_Enums.Operation_Table.STOREL:
case LSO_Enums.Operation_Table.STOREV:
case LSO_Enums.Operation_Table.STOREQ:
u32p1 = BitConverter.ToUInt32(br_read(4), 0);
Common.SendToDebug("Param1: " + u32p1.ToString());
IL_CallBaseFunction(il, "StoreToLocal", u32p1);
break;
case LSO_Enums.Operation_Table.STOREG:
case LSO_Enums.Operation_Table.STOREGS:
case LSO_Enums.Operation_Table.STOREGL:
case LSO_Enums.Operation_Table.STOREGV:
case LSO_Enums.Operation_Table.STOREGQ:
u32p1 = BitConverter.ToUInt32(br_read(4), 0);
Common.SendToDebug("Param1: " + u32p1.ToString());
IL_CallBaseFunction(il, "StoreToGlobal", u32p1);
break;
case LSO_Enums.Operation_Table.LOADP:
case LSO_Enums.Operation_Table.LOADSP:
case LSO_Enums.Operation_Table.LOADLP:
case LSO_Enums.Operation_Table.LOADVP:
case LSO_Enums.Operation_Table.LOADQP:
u32p1 = BitConverter.ToUInt32(br_read(4), 0);
Common.SendToDebug("Param1: " + u32p1.ToString());
IL_CallBaseFunction(il, "StoreToLocal", u32p1);
IL_Pop(il);
break;
case LSO_Enums.Operation_Table.LOADGP:
case LSO_Enums.Operation_Table.LOADGSP:
case LSO_Enums.Operation_Table.LOADGLP:
case LSO_Enums.Operation_Table.LOADGVP:
case LSO_Enums.Operation_Table.LOADGQP:
u32p1 = BitConverter.ToUInt32(br_read(4), 0);
Common.SendToDebug("Param1: " + u32p1.ToString());
IL_CallBaseFunction(il, "StoreToStatic", u32p1 - 6 + myHeader.GVR);
IL_Pop(il);
break;
// PUSH FROM LOCAL FRAME
case LSO_Enums.Operation_Table.PUSH:
case LSO_Enums.Operation_Table.PUSHS:
case LSO_Enums.Operation_Table.PUSHL:
case LSO_Enums.Operation_Table.PUSHV:
case LSO_Enums.Operation_Table.PUSHQ:
u32p1 = BitConverter.ToUInt32(br_read(4), 0);
Common.SendToDebug("Param1: " + u32p1.ToString());
IL_CallBaseFunction(il, "GetFromLocal", u32p1);
break;
// PUSH FROM STATIC FRAME
case LSO_Enums.Operation_Table.PUSHG:
case LSO_Enums.Operation_Table.PUSHGS:
case LSO_Enums.Operation_Table.PUSHGL:
case LSO_Enums.Operation_Table.PUSHGV:
case LSO_Enums.Operation_Table.PUSHGQ:
u32p1 = BitConverter.ToUInt32(br_read(4), 0);
Common.SendToDebug("Param1: " + u32p1.ToString());
IL_CallBaseFunction(il, "GetFromStatic", u32p1 - 6 + myHeader.GVR);
break;
/***********************
* NOT IMPLEMENTED YET *
***********************/
case LSO_Enums.Operation_Table.POPIP:
case LSO_Enums.Operation_Table.POPSP:
case LSO_Enums.Operation_Table.POPSLR:
case LSO_Enums.Operation_Table.POPARG:
case LSO_Enums.Operation_Table.POPBP:
//Common.SendToDebug("Instruction " + idesc + ": Ignored");
Common.SendToDebug("Instruction " + idesc +
": Description: Drop x bytes from the stack (TODO: Only popping 1)");
//Common.SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4), 0));
IL_Pop(il);
break;
// None
case LSO_Enums.Operation_Table.PUSHIP:
// PUSH INSTRUCTION POINTER
break;
case LSO_Enums.Operation_Table.PUSHBP:
case LSO_Enums.Operation_Table.PUSHEV:
break;
case LSO_Enums.Operation_Table.PUSHEQ:
break;
// LONG
case LSO_Enums.Operation_Table.JUMP:
Common.SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4), 0));
break;
// BYTE, LONG
case LSO_Enums.Operation_Table.JUMPIF:
case LSO_Enums.Operation_Table.JUMPNIF:
Common.SendToDebug("Param1: " + br_read(1)[0]);
Common.SendToDebug("Param2: " + BitConverter.ToUInt32(br_read(4), 0));
break;
// LONG
case LSO_Enums.Operation_Table.STATE:
bp1 = br_read(1)[0];
//il.Emit(OpCodes.Ld); // Load local variable 0 onto stack
//il.Emit(OpCodes.Ldc_I4, 0); // Push index position
//il.Emit(OpCodes.Ldstr, EventList[p1]); // Push value
//il.Emit(OpCodes.Stelem_Ref); // Perform array[index] = value
break;
case LSO_Enums.Operation_Table.CALL:
Common.SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4), 0));
Common.SendToDebug("ERROR: Function CALL not implemented yet.");
break;
// BYTE
case LSO_Enums.Operation_Table.CAST:
bp1 = br_read(1)[0];
Common.SendToDebug("Instruction " + idesc + ": Cast to type: " +
((LSO_Enums.OpCode_Cast_TypeDefs) bp1));
Common.SendToDebug("Param1: " + bp1);
switch ((LSO_Enums.OpCode_Cast_TypeDefs) bp1)
{
case LSO_Enums.OpCode_Cast_TypeDefs.String:
Common.SendToDebug("Instruction " + idesc + ": il.Emit(OpCodes.Box, ILStack.Pop());");
break;
default:
Common.SendToDebug("Instruction " + idesc + ": Unknown cast type!");
break;
}
break;
// LONG
case LSO_Enums.Operation_Table.STACKTOS:
case LSO_Enums.Operation_Table.STACKTOL:
Common.SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4), 0));
break;
// BYTE
case LSO_Enums.Operation_Table.PRINT:
case LSO_Enums.Operation_Table.CALLLIB:
Common.SendToDebug("Param1: " + br_read(1)[0]);
break;
}
return false;
}
private void IL_PopToStack(ILGenerator il)
{
IL_PopToStack(il, 1);
}
private void IL_PopToStack(ILGenerator il, int count)
{
Common.SendToDebug("IL_PopToStack();");
for (int i = 0; i < count; i++)
{
IL_CallBaseFunction(il, "POPToStack");
//il.Emit(OpCodes.Ldarg_0);
//il.Emit(OpCodes.Call,
// typeof(LSL_BaseClass).GetMethod("POPToStack",
// new Type[] { }));
}
}
private void IL_Pop(ILGenerator il)
{
Common.SendToDebug("IL_Pop();");
IL_CallBaseFunction(il, "POP");
}
private void IL_Debug(ILGenerator il, string text)
{
il.Emit(OpCodes.Ldstr, text);
il.Emit(OpCodes.Call, typeof (Common).GetMethod("SendToDebug",
new Type[] {typeof (string)}
));
}
private void IL_CallBaseFunction(ILGenerator il, string methodname)
{
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, typeof (LSL_BaseClass).GetMethod(methodname, new Type[] {}));
}
private void IL_CallBaseFunction(ILGenerator il, string methodname, object data)
{
il.Emit(OpCodes.Ldarg_0);
if (data.GetType() == typeof (string))
il.Emit(OpCodes.Ldstr, (string) data);
if (data.GetType() == typeof (UInt32))
il.Emit(OpCodes.Ldc_I4, (UInt32) data);
il.Emit(OpCodes.Call, typeof (LSL_BaseClass).GetMethod(methodname, new Type[] {data.GetType()}));
}
private void IL_Push(ILGenerator il, object data)
{
il.Emit(OpCodes.Ldarg_0);
Common.SendToDebug("PUSH datatype: " + data.GetType());
IL_PushDataTypeToILStack(il, data);
il.Emit(OpCodes.Call, typeof (LSL_BaseClass).GetMethod("PUSH", new Type[] {data.GetType()}));
}
private void IL_PushDataTypeToILStack(ILGenerator il, object data)
{
if (data.GetType() == typeof (UInt16))
{
il.Emit(OpCodes.Ldc_I4, (UInt16) data);
il.Emit(OpCodes.Box, data.GetType());
}
if (data.GetType() == typeof (UInt32))
{
il.Emit(OpCodes.Ldc_I4, (UInt32) data);
il.Emit(OpCodes.Box, data.GetType());
}
if (data.GetType() == typeof (Int32))
{
il.Emit(OpCodes.Ldc_I4, (Int32) data);
il.Emit(OpCodes.Box, data.GetType());
}
if (data.GetType() == typeof (float))
{
il.Emit(OpCodes.Ldc_I4, (float) data);
il.Emit(OpCodes.Box, data.GetType());
}
if (data.GetType() == typeof (string))
il.Emit(OpCodes.Ldstr, (string) data);
//if (data.GetType() == typeof(LSO_Enums.Rotation))
// il.Emit(OpCodes.Ldobj, (LSO_Enums.Rotation)data);
//if (data.GetType() == typeof(LSO_Enums.Vector))
// il.Emit(OpCodes.Ldobj, (LSO_Enums.Vector)data);
//if (data.GetType() == typeof(LSO_Enums.Key))
// il.Emit(OpCodes.Ldobj, (LSO_Enums.Key)data);
}
}
}

View File

@ -0,0 +1,560 @@
/*
* 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;
namespace OpenSim.Region.ScriptEngine.LSOEngine.LSO
{
public static class LSO_Enums
{
//public System.Collections.Generic.Dictionary<Byte, Type> OpCode_Add_Types;
//LSO_Enums() {
// OpCode_Add_Types.Add(51, typeof(String));
// OpCode_Add_Types.Add(17, typeof(UInt32));
//}
[Serializable]
public enum OpCode_Add_TypeDefs
{
String = 51,
UInt32 = 17
}
[Serializable]
public enum OpCode_Cast_TypeDefs
{
String = 19
}
[Serializable]
public struct Key
{
public string KeyString;
}
[Serializable]
public struct Vector
{
public UInt32 Z;
public UInt32 Y;
public UInt32 X;
}
[Serializable]
public struct Rotation
{
public UInt32 S;
public UInt32 Z;
public UInt32 Y;
public UInt32 X;
}
[Serializable]
public enum Variable_Type_Codes
{
Void = 0,
Integer = 1,
Float = 2,
String = 3,
Key = 4,
Vector = 5,
Rotation = 6,
List = 7,
Null = 8
}
[Serializable]
public enum Event_Mask_Values
{
state_entry = 0,
state_exit = 1,
touch_start = 2,
touch = 3,
touch_end = 4,
collision_start = 5,
collision = 6,
collision_end = 7,
land_collision_start = 8,
land_collision = 9,
land_collision_end = 10,
timer = 11,
listen = 12,
on_rez = 13,
sensor = 14,
no_sensor = 15,
control = 16,
money = 17,
email = 18,
at_target = 19,
not_at_target = 20,
at_rot_target = 21,
not_at_rot_target = 22,
run_time_permissions = 23,
changed = 24,
attach = 25,
dataserver = 26,
link_message = 27,
moving_start = 28,
moving_end = 29,
object_rez = 30,
remote_data = 31,
http_response = 32
}
[Serializable]
public enum Operation_Table
{
NOOP = 0x0,
POP = 0x1,
POPS = 0x2,
POPL = 0x3,
POPV = 0x4,
POPQ = 0x5,
POPARG = 0x6,
POPIP = 0x7,
POPBP = 0x8,
POPSP = 0x9,
POPSLR = 0xa,
DUP = 0x20,
DUPS = 0x21,
DUPL = 0x22,
DUPV = 0x23,
DUPQ = 0x24,
STORE = 0x30,
STORES = 0x31,
STOREL = 0x32,
STOREV = 0x33,
STOREQ = 0x34,
STOREG = 0x35,
STOREGS = 0x36,
STOREGL = 0x37,
STOREGV = 0x38,
STOREGQ = 0x39,
LOADP = 0x3a,
LOADSP = 0x3b,
LOADLP = 0x3c,
LOADVP = 0x3d,
LOADQP = 0x3e,
LOADGP = 0x3f,
LOADGSP = 0x40,
LOADGLP = 0x41,
LOADGVP = 0x42,
LOADGQP = 0x43,
PUSH = 0x50,
PUSHS = 0x51,
PUSHL = 0x52,
PUSHV = 0x53,
PUSHQ = 0x54,
PUSHG = 0x55,
PUSHGS = 0x56,
PUSHGL = 0x57,
PUSHGV = 0x58,
PUSHGQ = 0x59,
PUSHIP = 0x5a,
PUSHBP = 0x5b,
PUSHSP = 0x5c,
PUSHARGB = 0x5d,
PUSHARGI = 0x5e,
PUSHARGF = 0x5f,
PUSHARGS = 0x60,
PUSHARGV = 0x61,
PUSHARGQ = 0x62,
PUSHE = 0x63,
PUSHEV = 0x64,
PUSHEQ = 0x65,
PUSHARGE = 0x66,
ADD = 0x70,
SUB = 0x71,
MUL = 0x72,
DIV = 0x73,
MOD = 0x74,
EQ = 0x75,
NEQ = 0x76,
LEQ = 0x77,
GEQ = 0x78,
LESS = 0x79,
GREATER = 0x7a,
BITAND = 0x7b,
BITOR = 0x7c,
BITXOR = 0x7d,
BOOLAND = 0x7e,
BOOLOR = 0x7f,
NEG = 0x80,
BITNOT = 0x81,
BOOLNOT = 0x82,
JUMP = 0x90,
JUMPIF = 0x91,
JUMPNIF = 0x92,
STATE = 0x93,
CALL = 0x94,
RETURN = 0x95,
CAST = 0xa0,
STACKTOS = 0xb0,
STACKTOL = 0xb1,
PRINT = 0xc0,
CALLLIB = 0xd0,
CALLLIB_TWO_BYTE = 0xd1,
SHL = 0xe0,
SHR = 0xe1
}
[Serializable]
public enum BuiltIn_Functions
{
llSin = 0,
llCos = 1,
llTan = 2,
llAtan2 = 3,
llSqrt = 4,
llPow = 5,
llAbs = 6,
llFabs = 7,
llFrand = 8,
llFloor = 9,
llCeil = 10,
llRound = 11,
llVecMag = 12,
llVecNorm = 13,
llVecDist = 14,
llRot2Euler = 15,
llEuler2Rot = 16,
llAxes2Rot = 17,
llRot2Fwd = 18,
llRot2Left = 19,
llRot2Up = 20,
llRotBetween = 21,
llWhisper = 22,
llSay = 23,
llShout = 24,
llListen = 25,
llListenControl = 26,
llListenRemove = 27,
llSensor = 28,
llSensorRepeat = 29,
llSensorRemove = 30,
llDetectedName = 31,
llDetectedKey = 32,
llDetectedOwner = 33,
llDetectedType = 34,
llDetectedPos = 35,
llDetectedVel = 36,
llDetectedGrab = 37,
llDetectedRot = 38,
llDetectedGroup = 39,
llDetectedLinkNumber = 40,
llDie = 41,
llGround = 42,
llCloud = 43,
llWind = 44,
llSetStatus = 45,
llGetStatus = 46,
llSetScale = 47,
llGetScale = 48,
llSetColor = 49,
llGetAlpha = 50,
llSetAlpha = 51,
llGetColor = 52,
llSetTexture = 53,
llScaleTexture = 54,
llOffsetTexture = 55,
llRotateTexture = 56,
llGetTexture = 57,
llSetPos = 58,
llGetPos = 59,
llGetLocalPos = 60,
llSetRot = 61,
llGetRot = 62,
llGetLocalRot = 63,
llSetForce = 64,
llGetForce = 65,
llTarget = 66,
llTargetRemove = 67,
llRotTarget = 68,
llRotTargetRemove = 69,
llMoveToTarget = 70,
llStopMoveToTarget = 71,
llApplyImpulse = 72,
llApplyRotationalImpulse = 73,
llSetTorque = 74,
llGetTorque = 75,
llSetForceAndTorque = 76,
llGetVel = 77,
llGetAccel = 78,
llGetOmega = 79,
llGetTimeOfDay = 80,
llGetWallclock = 81,
llGetTime = 82,
llResetTime = 83,
llGetAndResetTime = 84,
llSound = 85,
llPlaySound = 86,
llLoopSound = 87,
llLoopSoundMaster = 88,
llLoopSoundSlave = 89,
llPlaySoundSlave = 90,
llTriggerSound = 91,
llStopSound = 92,
llPreloadSound = 93,
llGetSubString = 94,
llDeleteSubString = 95,
llInsertString = 96,
llToUpper = 97,
llToLower = 98,
llGiveMoney = 99,
llMakeExplosion = 100,
llMakeFountain = 101,
llMakeSmoke = 102,
llMakeFire = 103,
llRezObject = 104,
llLookAt = 105,
llStopLookAt = 106,
llSetTimerEvent = 107,
llSleep = 108,
llGetMass = 109,
llCollisionFilter = 110,
llTakeControls = 111,
llReleaseControls = 112,
llAttachToAvatar = 113,
llDetachFromAvatar = 114,
llTakeCamera = 115,
llReleaseCamera = 116,
llGetOwner = 117,
llInstantMessage = 118,
llEmail = 119,
llGetNextEmail = 120,
llGetKey = 121,
llSetBuoyancy = 122,
llSetHoverHeight = 123,
llStopHover = 124,
llMinEventDelay = 125,
llSoundPreload = 126,
llRotLookAt = 127,
llStringLength = 128,
llStartAnimation = 129,
llStopAnimation = 130,
llPointAt = 131,
llStopPointAt = 132,
llTargetOmega = 133,
llGetStartParameter = 134,
llGodLikeRezObject = 135,
llRequestPermissions = 136,
llGetPermissionsKey = 137,
llGetPermissions = 138,
llGetLinkNumber = 139,
llSetLinkColor = 140,
llCreateLink = 141,
llBreakLink = 142,
llBreakAllLinks = 143,
llGetLinkKey = 144,
llGetLinkName = 145,
llGetInventoryNumber = 146,
llGetInventoryName = 147,
llSetScriptState = 148,
llGetEnergy = 149,
llGiveInventory = 150,
llRemoveInventory = 151,
llSetText = 152,
llWater = 153,
llPassTouches = 154,
llRequestAgentData = 155,
llRequestInventoryData = 156,
llSetDamage = 157,
llTeleportAgentHome = 158,
llModifyLand = 159,
llCollisionSound = 160,
llCollisionSprite = 161,
llGetAnimation = 162,
llResetScript = 163,
llMessageLinked = 164,
llPushObject = 165,
llPassCollisions = 166,
llGetScriptName = 167,
llGetNumberOfSides = 168,
llAxisAngle2Rot = 169,
llRot2Axis = 170,
llRot2Angle = 171,
llAcos = 172,
llAsin = 173,
llAngleBetween = 174,
llGetInventoryKey = 175,
llAllowInventoryDrop = 176,
llGetSunDirection = 177,
llGetTextureOffset = 178,
llGetTextureScale = 179,
llGetTextureRot = 180,
llSubStringIndex = 181,
llGetOwnerKey = 182,
llGetCenterOfMass = 183,
llListSort = 184,
llGetListLength = 185,
llList2Integer = 186,
llList2Float = 187,
llList2String = 188,
llList2Key = 189,
llList2Vector = 190,
llList2Rot = 191,
llList2List = 192,
llDeleteSubList = 193,
llGetListEntryType = 194,
llList2CSV = 195,
llCSV2List = 196,
llListRandomize = 197,
llList2ListStrided = 198,
llGetRegionCorner = 199,
llListInsertList = 200,
llListFindList = 201,
llGetObjectName = 202,
llSetObjectName = 203,
llGetDate = 204,
llEdgeOfWorld = 205,
llGetAgentInfo = 206,
llAdjustSoundVolume = 207,
llSetSoundQueueing = 208,
llSetSoundRadius = 209,
llKey2Name = 210,
llSetTextureAnim = 211,
llTriggerSoundLimited = 212,
llEjectFromLand = 213,
llParseString2List = 214,
llOverMyLand = 215,
llGetLandOwnerAt = 216,
llGetNotecardLine = 217,
llGetAgentSize = 218,
llSameGroup = 219,
llUnSit = 220,
llGroundSlope = 221,
llGroundNormal = 222,
llGroundContour = 223,
llGetAttached = 224,
llGetFreeMemory = 225,
llGetRegionName = 226,
llGetRegionTimeDilation = 227,
llGetRegionFPS = 228,
llParticleSystem = 229,
llGroundRepel = 230,
llGiveInventoryList = 231,
llSetVehicleType = 232,
llSetVehicleFloatParam = 233,
llSetVehicleVectorParam = 234,
llSetVehicleRotationParam = 235,
llSetVehicleFlags = 236,
llRemoveVehicleFlags = 237,
llSitTarget = 238,
llAvatarOnSitTarget = 239,
llAddToLandPassList = 240,
llSetTouchText = 241,
llSetSitText = 242,
llSetCameraEyeOffset = 243,
llSetCameraAtOffset = 244,
llDumpList2String = 245,
llScriptDanger = 246,
llDialog = 247,
llVolumeDetect = 248,
llResetOtherScript = 249,
llGetScriptState = 250,
llRemoteLoadScript = 251,
llSetRemoteScriptAccessPin = 252,
llRemoteLoadScriptPin = 253,
llOpenRemoteDataChannel = 254,
llSendRemoteData = 255,
llRemoteDataReply = 256,
llCloseRemoteDataChannel = 257,
llMD5String = 258,
llSetPrimitiveParams = 259,
llStringToBase64 = 260,
llBase64ToString = 261,
llXorBase64Strings = 262,
llRemoteDataSetRegion = 263,
llLog10 = 264,
llLog = 265,
llGetAnimationList = 266,
llSetParcelMusicURL = 267,
llGetRootPosition = 268,
llGetRootRotation = 269,
llGetObjectDesc = 270,
llSetObjectDesc = 271,
llGetCreator = 272,
llGetTimestamp = 273,
llSetLinkAlpha = 274,
llGetNumberOfPrims = 275,
llGetNumberOfNotecardLines = 276,
llGetBoundingBox = 277,
llGetGeometricCenter = 278,
llGetPrimitiveParams = 279,
llIntegerToBase64 = 280,
llBase64ToInteger = 281,
llGetGMTclock = 282,
llGetSimulatorHostname = 283,
llSetLocalRot = 284,
llParseStringKeepNulls = 285,
llRezAtRoot = 286,
llGetObjectPermMask = 287,
llSetObjectPermMask = 288,
llGetInventoryPermMask = 289,
llSetInventoryPermMask = 290,
llGetInventoryCreator = 291,
llOwnerSay = 292,
llRequestSimulatorData = 293,
llForceMouselook = 294,
llGetObjectMass = 295,
llListReplaceList = 296,
llLoadURL = 297,
llParcelMediaCommandList = 298,
llParcelMediaQuery = 299,
llModPow = 300,
llGetInventoryType = 301,
llSetPayPrice = 302,
llGetCameraPos = 303,
llGetCameraRot = 304,
llSetPrimURL = 305,
llRefreshPrimURL = 306,
llEscapeURL = 307,
llUnescapeURL = 308,
llMapDestination = 309,
llAddToLandBanList = 310,
llRemoveFromLandPassList = 311,
llRemoveFromLandBanList = 312,
llSetCameraParams = 313,
llClearCameraParams = 314,
llListStatistics = 315,
llGetUnixTime = 316,
llGetParcelFlags = 317,
llGetRegionFlags = 318,
llXorBase64StringsCorrect = 319,
llHTTPRequest = 320,
llResetLandBanList = 321,
llResetLandPassList = 322,
llGetParcelPrimCount = 323,
llGetParcelPrimOwners = 324,
llGetObjectPrimCount = 325,
llGetParcelMaxPrims = 326,
llGetParcelDetails = 327
}
}
}

View File

@ -0,0 +1,729 @@
/*
* 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;
using OpenSim.Region.ScriptEngine.LSOEngine.LSO;
namespace OpenSim.Region.ScriptEngine.LSOEngine.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);
}
}
}
}

View File

@ -0,0 +1,143 @@
/*
* 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;
namespace OpenSim.Region.ScriptEngine.LSOEngine.LSO
{
internal static class LSO_Struct
{
public struct Header
{
public UInt32 TM;
public UInt32 IP;
public UInt32 VN;
public UInt32 BP;
public UInt32 SP;
public UInt32 HR;
public UInt32 HP;
public UInt32 CS;
public UInt32 NS;
public UInt32 CE;
public UInt32 IE;
public UInt32 ER;
public UInt32 FR;
public UInt32 SLR;
public UInt32 GVR;
public UInt32 GFR;
public UInt32 PR;
public UInt32 ESR;
public UInt32 SR;
public UInt64 NCE;
public UInt64 NIE;
public UInt64 NER;
}
public struct StaticBlock
{
public UInt32 Static_Chunk_Header_Size;
public byte ObjectType;
public byte Unknown;
public byte[] BlockVariable;
}
/* Not actually a structure
public struct StaticBlockVariable
{
public UInt32 Integer1;
public UInt32 Float1;
public UInt32 HeapPointer_String;
public UInt32 HeapPointer_Key;
public byte[] Vector_12;
public byte[] Rotation_16;
public UInt32 Pointer_List_Structure;
} */
public struct HeapBlock
{
public Int32 DataBlockSize;
public byte ObjectType;
public UInt16 ReferenceCount;
public byte[] Data;
}
public struct StateFrameBlock
{
public UInt32 StateCount;
public StatePointerBlock[] StatePointer;
}
public struct StatePointerBlock
{
public UInt32 Location;
public BitArray EventMask;
public StateBlock StateBlock;
}
public struct StateBlock
{
public UInt32 StartPos;
public UInt32 EndPos;
public UInt32 HeaderSize;
public byte Unknown;
public StateBlockHandler[] StateBlockHandlers;
}
public struct StateBlockHandler
{
public UInt32 CodeChunkPointer;
public UInt32 CallFrameSize;
}
public struct FunctionBlock
{
public UInt32 FunctionCount;
public UInt32[] CodeChunkPointer;
}
public struct CodeChunk
{
public UInt32 CodeChunkHeaderSize;
public string Comment;
public List<CodeChunkArgument> CodeChunkArguments;
public byte EndMarker;
public byte ReturnTypePos;
public StaticBlock ReturnType;
}
public struct CodeChunkArgument
{
public byte FunctionReturnTypePos;
public byte NullString;
public StaticBlock FunctionReturnType;
}
}
}

View File

@ -0,0 +1,38 @@
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("OpenSim.Region.ScriptEngine.LSOEngine")]
[assembly : AssemblyDescription("")]
[assembly : AssemblyConfiguration("")]
[assembly : AssemblyCompany("")]
[assembly: AssemblyProduct("OpenSim.Region.ScriptEngine.LSOEngine")]
[assembly : AssemblyCopyright("Copyright © 2007")]
[assembly : AssemblyTrademark("")]
[assembly : AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly : ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly : Guid("2842257e-6fde-4460-9368-4cde57fa9cc4")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly : AssemblyVersion("1.0.0.0")]
[assembly : AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1,55 @@
/*
* 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.
*
*/
using System;
using Nini.Config;
using OpenSim.Framework.Console;
using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.Environment.Scenes;
using OpenSim.Region.ScriptEngine.Common;
using OpenSim.Region.ScriptEngine.Common.ScriptEngineBase;
using EventManager = OpenSim.Region.ScriptEngine.Common.ScriptEngineBase.EventManager;
using ScriptManager=OpenSim.Region.ScriptEngine.LSOEngine.ScriptManager;
namespace OpenSim.Region.ScriptEngine.LSOEngine
{
[Serializable]
public class ScriptEngine : OpenSim.Region.ScriptEngine.Common.ScriptEngineBase.ScriptEngine
{
// We need to override a few things for our DotNetEngine
public override void Initialise(Scene scene, IConfigSource config)
{
InitializeEngine(scene, MainLog.Instance, true, GetScriptManager());
}
public override OpenSim.Region.ScriptEngine.Common.ScriptEngineBase.ScriptManager _GetScriptManager()
{
return new ScriptManager(this);
}
}
}

View File

@ -0,0 +1,158 @@
/*
* 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.
*
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using libsecondlife;
using OpenSim.Framework;
using OpenSim.Region.Environment.Scenes;
using OpenSim.Region.ScriptEngine.Common;
namespace OpenSim.Region.ScriptEngine.LSOEngine
{
public class ScriptManager : OpenSim.Region.ScriptEngine.Common.ScriptEngineBase.ScriptManager
{
public ScriptManager(Common.ScriptEngineBase.ScriptEngine scriptEngine)
: base(scriptEngine)
{
base.m_scriptEngine = scriptEngine;
}
// KEEP TRACK OF SCRIPTS <int id, whatever script>
//internal Dictionary<uint, Dictionary<LLUUID, LSL_BaseClass>> Scripts = new Dictionary<uint, Dictionary<LLUUID, LSL_BaseClass>>();
// LOAD SCRIPT
// UNLOAD SCRIPT
// PROVIDE SCRIPT WITH ITS INTERFACE TO OpenSim
public override void _StartScript(uint localID, LLUUID itemID, string Script)
{
//IScriptHost root = host.GetRoot();
Console.WriteLine("ScriptManager StartScript: localID: " + localID + ", itemID: " + itemID);
// We will initialize and start the script.
// It will be up to the script itself to hook up the correct events.
string ScriptSource = "";
SceneObjectPart m_host = World.GetSceneObjectPart(localID);
try
{
// Compile (We assume LSL)
//ScriptSource = LSLCompiler.CompileFromLSLText(Script);
#if DEBUG
long before;
before = GC.GetTotalMemory(true);
#endif
IScript CompiledScript;
CompiledScript = m_scriptEngine.m_AppDomainManager.LoadScript(ScriptSource);
#if DEBUG
Console.WriteLine("Script " + itemID + " occupies {0} bytes", GC.GetTotalMemory(true) - before);
#endif
CompiledScript.Source = ScriptSource;
// Add it to our script memstruct
SetScript(localID, itemID, CompiledScript);
// We need to give (untrusted) assembly a private instance of BuiltIns
// this private copy will contain Read-Only FullitemID so that it can bring that on to the server whenever needed.
LSL_BuiltIn_Commands LSLB = new LSL_BuiltIn_Commands(m_scriptEngine, m_host, localID, itemID);
// Start the script - giving it BuiltIns
CompiledScript.Start(LSLB);
// Fire the first start-event
m_scriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "state_entry", new object[] { });
}
catch (Exception e)
{
//m_scriptEngine.Log.Error("ScriptEngine", "Error compiling script: " + e.ToString());
try
{
// DISPLAY ERROR INWORLD
string text = "Error compiling script:\r\n" + e.Message.ToString();
if (text.Length > 1500)
text = text.Substring(0, 1500);
World.SimChat(Helpers.StringToField(text), ChatTypeEnum.Say, 0, m_host.AbsolutePosition,
m_host.Name, m_host.UUID);
}
catch (Exception e2)
{
m_scriptEngine.Log.Error("ScriptEngine", "Error displaying error in-world: " + e2.ToString());
m_scriptEngine.Log.Error("ScriptEngine",
"Errormessage: Error compiling script:\r\n" + e.Message.ToString());
}
}
}
public override void _StopScript(uint localID, LLUUID itemID)
{
// Stop script
Console.WriteLine("Stop script localID: " + localID + " LLUID: " + itemID.ToString());
// Stop long command on script
m_scriptEngine.m_LSLLongCmdHandler.RemoveScript(localID, itemID);
IScript LSLBC = GetScript(localID, itemID);
if (LSLBC == null)
return;
// TEMP: First serialize it
//GetSerializedScript(localID, itemID);
try
{
// Get AppDomain
AppDomain ad = LSLBC.Exec.GetAppDomain();
// Tell script not to accept new requests
GetScript(localID, itemID).Exec.StopScript();
// Remove from internal structure
RemoveScript(localID, itemID);
// Tell AppDomain that we have stopped script
m_scriptEngine.m_AppDomainManager.StopScript(ad);
}
catch (Exception e)
{
Console.WriteLine("Exception stopping script localID: " + localID + " LLUID: " + itemID.ToString() +
": " + e.ToString());
}
}
}
}

View File

@ -1165,6 +1165,39 @@
</Files> </Files>
</Project> </Project>
<Project name="OpenSim.Region.ScriptEngine.LSOEngine" path="OpenSim/Region/ScriptEngine/LSOEngine" type="Library">
<Configuration name="Debug">
<Options>
<OutputPath>../../../../bin/ScriptEngines/</OutputPath>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<OutputPath>../../../../bin/ScriptEngines/</OutputPath>
</Options>
</Configuration>
<ReferencePath>../../../../bin/</ReferencePath>
<ReferencePath>../../../../bin/ScriptEngines/</ReferencePath>
<Reference name="System" localCopy="false"/>
<Reference name="System.Data" localCopy="false"/>
<Reference name="System.Xml" localCopy="false"/>
<Reference name="System.Runtime.Remoting" localCopy="false"/>
<Reference name="libsecondlife.dll"/>
<Reference name="RAIL.dll"/>
<Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Region.Environment" />
<Reference name="OpenSim.Region.ScriptEngine.Common"/>
<Reference name="OpenSim.Region.Terrain.BasicTerrain"/>
<Reference name="Axiom.MathLib.dll" localCopy="false"/>
<Reference name="Nini.dll" />
<Files>
<Match pattern="*.cs" recurse="true"/>
</Files>
</Project>
<Project name="OpenSim.Grid.ScriptServer" path="OpenSim/Grid/ScriptServer" type="Exe"> <Project name="OpenSim.Grid.ScriptServer" path="OpenSim/Grid/ScriptServer" type="Exe">
<Configuration name="Debug"> <Configuration name="Debug">
<Options> <Options>