123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- /*
- * 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;
- namespace OpenSim.Grid.ScriptEngine.DotNetEngine.Compiler.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;
- Common.SendToLog("LSO File Name: " + Path.GetFileName(LSO_FileName));
- Common.SendToLog("Assembly name: " + asmName.Name);
- Common.SendToLog("Assembly File Name: " + asmName.Name + ".dll");
- Common.SendToLog("Starting processing of LSL ByteCode...");
- 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 (Common.IL_CreateConstructor)
- IL_CREATE_CONSTRUCTOR(typeBuilder, LSOP);
- LSOP.CloseFile();
- /*
- * Done generating. Create a type and run it.
- */
- Common.SendToLog("Attempting to compile assembly...");
- // Compile it
- Type type = typeBuilder.CreateType();
- Common.SendToLog("Compilation successful!");
- Common.SendToLog("Saving assembly: " + DLL_FileName);
- asmBuilder.Save(DLL_FileName);
- 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)
- {
- 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
- 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
- }
- }
|