aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/Engine.cs
blob: 814f15a8024b7cfbec968e69af2d0f9d8a395128 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;

using OpenSim.Region.Environment.Scripting;

namespace OpenSim.ScriptEngines.LSL
{

    
    public class Engine
    {
        public void Start(ScriptInfo WorldAPI)
        {
            

            
            // Create Assembly Name
            AssemblyName asmName = new AssemblyName();
            asmName.Name = "TestAssembly";

            // Create Assembly
            AssemblyBuilder asmBuilder =
                Thread.GetDomain().DefineDynamicAssembly
            (asmName, AssemblyBuilderAccess.RunAndSave);

            // Create a module (and save to disk)
            ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule
                            (asmName.Name, asmName.Name  + ".dll");

            // Create a Class (/Type)
            TypeBuilder typeBuilder = modBuilder.DefineType(
                                    "MyClass",
                                    TypeAttributes.Public,
                                    typeof(object),
                                    new Type[] { typeof(LSL_CLRInterface.LSLScript) });



            /*
             * Generate the IL itself
             */

            GenerateIL(WorldAPI, typeBuilder);


            /*
             * Done generating, create a type and run it.
             */

            // Create type object for the class (after defining fields and methods)
            Type type = typeBuilder.CreateType();

            asmBuilder.Save("TestAssembly.dll");

            // Create an instance we can play with
            //LSLScript hello = (LSLScript)Activator.CreateInstance(type);
            LSL_CLRInterface.LSLScript MyScript = (LSL_CLRInterface.LSLScript)Activator.CreateInstance(type);

            // Play with it
            MyScript.event_state_entry("Test");
        }

        private void GenerateIL(ScriptInfo WorldAPI, TypeBuilder typeBuilder)
        {


            // For debug
            LSO_Parser LSOP = new LSO_Parser();
            LSOP.ParseFile("LSO\\CloseToDefault.lso", WorldAPI, ref typeBuilder);
            return;


            // Override a Method / Function
            MethodBuilder methodBuilder = typeBuilder.DefineMethod("event_state_entry",
                         MethodAttributes.Private | MethodAttributes.Virtual,
                         typeof(void),
                         new Type[] { typeof(object) });

            typeBuilder.DefineMethodOverride(methodBuilder,
                    typeof(LSL_CLRInterface.LSLScript).GetMethod("event_state_entry"));

            // Create the IL generator
            ILGenerator il = methodBuilder.GetILGenerator();
                

            /*
             * TRY
             */
            il.BeginExceptionBlock();

            // Push "Hello World!" string to stack
            il.Emit(OpCodes.Ldstr, "Hello World!");

            // Push Console.WriteLine command to stack ... Console.WriteLine("Hello World!");
            il.Emit(OpCodes.Call, typeof(Console).GetMethod
                ("WriteLine", new Type[] { typeof(string) }));

            //il.EmitCall(OpCodes.Callvirt
            //il.Emit(OpCodes.Call, typeof(WorldAPI).GetMethod
                //("TestFunction"));


            //il.ThrowException(typeof(NotSupportedException));

          
            /*
             * CATCH
             */
            il.BeginCatchBlock(typeof(Exception));

            // Push "Hello World!" string to stack
            il.Emit(OpCodes.Ldstr, "Something went wrong: ");

            //call void [mscorlib]System.Console::WriteLine(string)
            il.Emit(OpCodes.Call, typeof(Console).GetMethod
                ("Write", new Type[] { typeof(string) }));

            //callvirt instance string [mscorlib]System.Exception::get_Message()
            il.Emit(OpCodes.Callvirt, typeof(Exception).GetMethod
                ("get_Message"));
                 
            //call void [mscorlib]System.Console::WriteLine(string)
            il.Emit(OpCodes.Call, typeof(Console).GetMethod
                ("WriteLine", new Type[] { typeof(string) }));

            /*
             * END TRY
             */
            il.EndExceptionBlock();


            // Push "Return from current method, with return value if present" to stack
            il.Emit(OpCodes.Ret);


        }
    }
}