Engine.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSim Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. /* Original code: Tedd Hansen */
  28. using System;
  29. using System.IO;
  30. using System.Reflection;
  31. using System.Reflection.Emit;
  32. using System.Text;
  33. using System.Threading;
  34. namespace OpenSim.Grid.ScriptEngine.DotNetEngine.Compiler.LSO
  35. {
  36. public class Engine
  37. {
  38. //private string LSO_FileName = @"LSO\AdditionTest.lso";
  39. private string LSO_FileName; // = @"LSO\CloseToDefault.lso";
  40. private AppDomain appDomain;
  41. public string Compile(string LSOFileName)
  42. {
  43. LSO_FileName = LSOFileName;
  44. //appDomain = AppDomain.CreateDomain("AlternateAppDomain");
  45. appDomain = Thread.GetDomain();
  46. // Create Assembly Name
  47. AssemblyName asmName = new AssemblyName();
  48. asmName.Name = Path.GetFileNameWithoutExtension(LSO_FileName);
  49. //asmName.Name = "TestAssembly";
  50. string DLL_FileName = asmName.Name + ".dll";
  51. string DLL_FileName_WithPath = Path.GetDirectoryName(LSO_FileName) + @"\" + DLL_FileName;
  52. Common.SendToLog("LSO File Name: " + Path.GetFileName(LSO_FileName));
  53. Common.SendToLog("Assembly name: " + asmName.Name);
  54. Common.SendToLog("Assembly File Name: " + asmName.Name + ".dll");
  55. Common.SendToLog("Starting processing of LSL ByteCode...");
  56. Common.SendToLog("");
  57. // Create Assembly
  58. AssemblyBuilder asmBuilder = appDomain.DefineDynamicAssembly(
  59. asmName,
  60. AssemblyBuilderAccess.RunAndSave
  61. );
  62. //// Create Assembly
  63. //AssemblyBuilder asmBuilder =
  64. // Thread.GetDomain().DefineDynamicAssembly
  65. //(asmName, AssemblyBuilderAccess.RunAndSave);
  66. // Create a module (and save to disk)
  67. ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule
  68. (asmName.Name,
  69. DLL_FileName);
  70. //Common.SendToDebug("asmName.Name is still \"" + asmName.Name + "\"");
  71. // Create a Class (/Type)
  72. TypeBuilder typeBuilder = modBuilder.DefineType(
  73. "LSL_ScriptObject",
  74. TypeAttributes.Public | TypeAttributes.BeforeFieldInit,
  75. typeof (LSL_BaseClass));
  76. //,
  77. // typeof());
  78. //, typeof(LSL_BuiltIn_Commands_Interface));
  79. //,
  80. // typeof(object),
  81. // new Type[] { typeof(LSL_CLRInterface.LSLScript) });
  82. /*
  83. * Generate the IL itself
  84. */
  85. LSO_Parser LSOP = new LSO_Parser(LSO_FileName, typeBuilder);
  86. LSOP.OpenFile();
  87. LSOP.Parse();
  88. // Constructor has to be created AFTER LSO_Parser because of accumulated variables
  89. if (Common.IL_CreateConstructor)
  90. IL_CREATE_CONSTRUCTOR(typeBuilder, LSOP);
  91. LSOP.CloseFile();
  92. /*
  93. * Done generating. Create a type and run it.
  94. */
  95. Common.SendToLog("Attempting to compile assembly...");
  96. // Compile it
  97. Type type = typeBuilder.CreateType();
  98. Common.SendToLog("Compilation successful!");
  99. Common.SendToLog("Saving assembly: " + DLL_FileName);
  100. asmBuilder.Save(DLL_FileName);
  101. Common.SendToLog("Returning assembly filename: " + DLL_FileName);
  102. return DLL_FileName;
  103. //Common.SendToLog("Creating an instance of new assembly...");
  104. //// Create an instance we can play with
  105. ////LSLScript hello = (LSLScript)Activator.CreateInstance(type);
  106. ////LSL_CLRInterface.LSLScript MyScript = (LSL_CLRInterface.LSLScript)Activator.CreateInstance(type);
  107. //object MyScript = (object)Activator.CreateInstance(type);
  108. //System.Reflection.MemberInfo[] Members = type.GetMembers();
  109. //Common.SendToLog("Members of assembly " + type.ToString() + ":");
  110. //foreach (MemberInfo member in Members)
  111. // Common.SendToLog(member.ToString());
  112. //// Play with it
  113. ////MyScript.event_state_entry("Test");
  114. //object[] args = { null };
  115. ////System.Collections.Generic.List<string> Functions = (System.Collections.Generic.List<string>)type.InvokeMember("GetFunctions", BindingFlags.InvokeMethod, null, MyScript, null);
  116. //string[] ret = { };
  117. //if (Common.IL_CreateFunctionList)
  118. // ret = (string[])type.InvokeMember("GetFunctions", BindingFlags.InvokeMethod, null, MyScript, null);
  119. //foreach (string s in ret)
  120. //{
  121. // Common.SendToLog("");
  122. // Common.SendToLog("*** Executing LSL Server Event: " + s);
  123. // //object test = type.GetMember(s);
  124. // //object runner = type.InvokeMember(s, BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance, null, MyScript, args);
  125. // //runner();
  126. // //objBooks_Late = type.InvokeMember(s, BindingFlags.CreateInstance, null, objApp_Late, null);
  127. // type.InvokeMember(s, BindingFlags.InvokeMethod, null, MyScript, new object[] { "Test" });
  128. //}
  129. }
  130. private static void IL_CREATE_CONSTRUCTOR(TypeBuilder typeBuilder, LSO_Parser LSOP)
  131. {
  132. Common.SendToDebug("IL_CREATE_CONSTRUCTOR()");
  133. //ConstructorBuilder constructor = typeBuilder.DefineConstructor(
  134. // MethodAttributes.Public,
  135. // CallingConventions.Standard,
  136. // new Type[0]);
  137. ConstructorBuilder constructor = typeBuilder.DefineConstructor(
  138. MethodAttributes.Public |
  139. MethodAttributes.SpecialName |
  140. MethodAttributes.RTSpecialName,
  141. CallingConventions.Standard,
  142. new Type[0]);
  143. //Define the reflection ConstructorInfor for System.Object
  144. ConstructorInfo conObj = typeof (LSL_BaseClass).GetConstructor(new Type[0]);
  145. //call constructor of base object
  146. ILGenerator il = constructor.GetILGenerator();
  147. il.Emit(OpCodes.Ldarg_0);
  148. il.Emit(OpCodes.Call, conObj);
  149. //Common.SendToDebug("IL_CREATE_CONSTRUCTOR: Creating global: UInt32 State = 0;");
  150. //string FieldName;
  151. //// Create state object
  152. //FieldName = "State";
  153. //FieldBuilder State_fb = typeBuilder.DefineField(
  154. // FieldName,
  155. // typeof(UInt32),
  156. // FieldAttributes.Public);
  157. //il.Emit(OpCodes.Ldarg_0);
  158. //il.Emit(OpCodes.Ldc_I4, 0);
  159. //il.Emit(OpCodes.Stfld, State_fb);
  160. //Common.SendToDebug("IL_CREATE_CONSTRUCTOR: Creating global: LSL_BuiltIn_Commands_TestImplementation LSL_BuiltIns = New LSL_BuiltIn_Commands_TestImplementation();");
  161. ////Type objType1 = typeof(object);
  162. //Type objType1 = typeof(LSL_BuiltIn_Commands_TestImplementation);
  163. //FieldName = "LSL_BuiltIns";
  164. //FieldBuilder LSL_BuiltIns_fb = typeBuilder.DefineField(
  165. // FieldName,
  166. // objType1,
  167. // FieldAttributes.Public);
  168. ////LSL_BuiltIn_Commands_TestImplementation _ti = new LSL_BuiltIn_Commands_TestImplementation();
  169. //il.Emit(OpCodes.Ldarg_0);
  170. ////il.Emit(OpCodes.Ldstr, "Test 123");
  171. //il.Emit(OpCodes.Newobj, objType1.GetConstructor(new Type[] { }));
  172. //il.Emit(OpCodes.Stfld, LSL_BuiltIns_fb);
  173. foreach (UInt32 pos in LSOP.StaticBlocks.Keys)
  174. {
  175. LSO_Struct.StaticBlock sb;
  176. LSOP.StaticBlocks.TryGetValue(pos, out sb);
  177. if (sb.ObjectType > 0 && sb.ObjectType < 8)
  178. {
  179. // We don't want void or null's
  180. il.Emit(OpCodes.Ldarg_0);
  181. // Push position to stack
  182. il.Emit(OpCodes.Ldc_I4, pos);
  183. //il.Emit(OpCodes.Box, typeof(UInt32));
  184. Type datatype = null;
  185. // Push data to stack
  186. Common.SendToDebug("Adding to static (" + pos + ") type: " +
  187. ((LSO_Enums.Variable_Type_Codes) sb.ObjectType).ToString() + " (" + sb.ObjectType +
  188. ")");
  189. switch ((LSO_Enums.Variable_Type_Codes) sb.ObjectType)
  190. {
  191. case LSO_Enums.Variable_Type_Codes.Float:
  192. case LSO_Enums.Variable_Type_Codes.Integer:
  193. //UInt32
  194. il.Emit(OpCodes.Ldc_I4, BitConverter.ToUInt32(sb.BlockVariable, 0));
  195. datatype = typeof (UInt32);
  196. il.Emit(OpCodes.Box, datatype);
  197. break;
  198. case LSO_Enums.Variable_Type_Codes.String:
  199. case LSO_Enums.Variable_Type_Codes.Key:
  200. //String
  201. LSO_Struct.HeapBlock hb =
  202. LSOP.GetHeap(LSOP.myHeader.HR + BitConverter.ToUInt32(sb.BlockVariable, 0) - 1);
  203. il.Emit(OpCodes.Ldstr, Encoding.UTF8.GetString(hb.Data));
  204. datatype = typeof (string);
  205. break;
  206. case LSO_Enums.Variable_Type_Codes.Vector:
  207. datatype = typeof (LSO_Enums.Vector);
  208. //TODO: Not implemented
  209. break;
  210. case LSO_Enums.Variable_Type_Codes.Rotation:
  211. //Object
  212. //TODO: Not implemented
  213. datatype = typeof (LSO_Enums.Rotation);
  214. break;
  215. default:
  216. datatype = typeof (object);
  217. break;
  218. }
  219. // Make call
  220. il.Emit(OpCodes.Call,
  221. typeof (LSL_BaseClass).GetMethod("AddToStatic", new Type[] {typeof (UInt32), datatype}));
  222. }
  223. }
  224. ////il.Emit(OpCodes.Newobj, typeof(UInt32));
  225. //il.Emit(OpCodes.Starg_0);
  226. //// Create LSL function library
  227. //FieldBuilder LSL_BuiltIns_fb = typeBuilder.DefineField("LSL_BuiltIns", typeof(LSL_BuiltIn_Commands_Interface), FieldAttributes.Public);
  228. //il.Emit(OpCodes.Newobj, typeof(LSL_BuiltIn_Commands_Interface));
  229. //il.Emit(OpCodes.Stloc_1);
  230. il.Emit(OpCodes.Ret);
  231. }
  232. // End of class
  233. }
  234. }