aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Grid/ScriptEngine/DotNetEngine/Compiler/LSO/LSL_OPCODE_IL_processor.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Grid/ScriptEngine/DotNetEngine/Compiler/LSO/LSL_OPCODE_IL_processor.cs')
-rw-r--r--OpenSim/Grid/ScriptEngine/DotNetEngine/Compiler/LSO/LSL_OPCODE_IL_processor.cs436
1 files changed, 436 insertions, 0 deletions
diff --git a/OpenSim/Grid/ScriptEngine/DotNetEngine/Compiler/LSO/LSL_OPCODE_IL_processor.cs b/OpenSim/Grid/ScriptEngine/DotNetEngine/Compiler/LSO/LSL_OPCODE_IL_processor.cs
new file mode 100644
index 0000000..45cca25
--- /dev/null
+++ b/OpenSim/Grid/ScriptEngine/DotNetEngine/Compiler/LSO/LSL_OPCODE_IL_processor.cs
@@ -0,0 +1,436 @@
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*/
28/* Original code: Tedd Hansen */
29using System;
30using System.Collections.Generic;
31using System.Text;
32using System.Reflection;
33using System.Reflection.Emit;
34using OpenSim.Region.ScriptEngine.Common;
35
36namespace OpenSim.Grid.ScriptEngine.DotNetEngine.Compiler.LSO
37{
38 partial class LSO_Parser
39 {
40 //internal Stack<Type> ILStack = new Stack<Type>();
41 //LSO_Enums MyLSO_Enums = new LSO_Enums();
42
43 internal bool LSL_PROCESS_OPCODE(ILGenerator il)
44 {
45
46 byte bp1;
47 UInt32 u32p1;
48 float fp1;
49 UInt16 opcode = br_read(1)[0];
50 Common.SendToDebug("OPCODE: " + ((LSO_Enums.Operation_Table)opcode).ToString());
51 string idesc = ((LSO_Enums.Operation_Table)opcode).ToString();
52 switch ((LSO_Enums.Operation_Table)opcode)
53 {
54
55 /***************
56 * IMPLEMENTED *
57 ***************/
58 case LSO_Enums.Operation_Table.NOOP:
59 break;
60 case LSO_Enums.Operation_Table.PUSHSP:
61 // Push Stack Top (Memory Address) to stack
62 Common.SendToDebug("Instruction " + idesc);
63 Common.SendToDebug("Instruction " + idesc + ": Description: Pushing Stack Top (Memory Address from header) to stack");
64 IL_Push(il, (UInt32)myHeader.SP);
65 break;
66 // BYTE
67 case LSO_Enums.Operation_Table.PUSHARGB:
68 Common.SendToDebug("Param1: " + br_read(1)[0]);
69 break;
70 // INTEGER
71 case LSO_Enums.Operation_Table.PUSHARGI:
72 u32p1 = BitConverter.ToUInt32(br_read(4), 0);
73 Common.SendToDebug("Instruction " + idesc + ", Param1: " + u32p1);
74 IL_Push(il, u32p1);
75 break;
76 // FLOAT
77 case LSO_Enums.Operation_Table.PUSHARGF:
78 fp1 = BitConverter.ToUInt32(br_read(4), 0);
79 Common.SendToDebug("Instruction " + idesc + ", Param1: " + fp1);
80 IL_Push(il, fp1);
81 break;
82 // STRING
83 case LSO_Enums.Operation_Table.PUSHARGS:
84 string s = Read_String();
85 Common.SendToDebug("Instruction " + idesc + ", Param1: " + s);
86 IL_Debug(il, "OPCODE: " + idesc + ":" + s);
87 IL_Push(il, s);
88 break;
89 // VECTOR z,y,x
90 case LSO_Enums.Operation_Table.PUSHARGV:
91 LSO_Enums.Vector v = new LSO_Enums.Vector();
92 v.Z = BitConverter.ToUInt32(br_read(4), 0);
93 v.Y = BitConverter.ToUInt32(br_read(4), 0);
94 v.X = BitConverter.ToUInt32(br_read(4), 0);
95 Common.SendToDebug("Param1 Z: " + v.Z);
96 Common.SendToDebug("Param1 Y: " + v.Y);
97 Common.SendToDebug("Param1 X: " + v.X);
98 IL_Push(il, v);
99 break;
100 // ROTATION s,z,y,x
101 case LSO_Enums.Operation_Table.PUSHARGQ:
102 LSO_Enums.Rotation r = new LSO_Enums.Rotation();
103 r.S = BitConverter.ToUInt32(br_read(4), 0);
104 r.Z = BitConverter.ToUInt32(br_read(4), 0);
105 r.Y = BitConverter.ToUInt32(br_read(4), 0);
106 r.X = BitConverter.ToUInt32(br_read(4), 0);
107 Common.SendToDebug("Param1 S: " + r.S);
108 Common.SendToDebug("Param1 Z: " + r.Z);
109 Common.SendToDebug("Param1 Y: " + r.Y);
110 Common.SendToDebug("Param1 X: " + r.X);
111 IL_Push(il, r);
112 break;
113
114 case LSO_Enums.Operation_Table.PUSHE:
115 IL_Push(il, (UInt32)0);
116 break;
117
118 case LSO_Enums.Operation_Table.PUSHARGE:
119 u32p1 = BitConverter.ToUInt32(br_read(4), 0);
120 Common.SendToDebug("Param1: " + u32p1);
121 //IL_Push(il, new string(" ".ToCharArray()[0], Convert.ToInt32(u32p1)));
122 IL_Push(il, u32p1);
123 break;
124 // BYTE
125 case LSO_Enums.Operation_Table.ADD:
126 case LSO_Enums.Operation_Table.SUB:
127 case LSO_Enums.Operation_Table.MUL:
128 case LSO_Enums.Operation_Table.DIV:
129 case LSO_Enums.Operation_Table.EQ:
130 case LSO_Enums.Operation_Table.NEQ:
131 case LSO_Enums.Operation_Table.LEQ:
132 case LSO_Enums.Operation_Table.GEQ:
133 case LSO_Enums.Operation_Table.LESS:
134 case LSO_Enums.Operation_Table.GREATER:
135 case LSO_Enums.Operation_Table.NEG:
136 case LSO_Enums.Operation_Table.MOD:
137 bp1 = br_read(1)[0];
138 Common.SendToDebug("Param1: " + bp1);
139 IL_CallBaseFunction(il, idesc, (UInt32)bp1);
140 break;
141
142 // NO ARGUMENTS
143 case LSO_Enums.Operation_Table.BITAND:
144 case LSO_Enums.Operation_Table.BITOR:
145 case LSO_Enums.Operation_Table.BITXOR:
146 case LSO_Enums.Operation_Table.BOOLAND:
147 case LSO_Enums.Operation_Table.BOOLOR:
148 case LSO_Enums.Operation_Table.BITNOT:
149 case LSO_Enums.Operation_Table.BOOLNOT:
150 IL_CallBaseFunction(il, idesc);
151 break;
152 // SHORT
153 case LSO_Enums.Operation_Table.CALLLIB_TWO_BYTE:
154 // TODO: What is size of short?
155 UInt16 U16p1 = BitConverter.ToUInt16(br_read(2), 0);
156 Common.SendToDebug("Instruction " + idesc + ": Builtin Command: " + ((LSO_Enums.BuiltIn_Functions)U16p1).ToString());
157 //Common.SendToDebug("Param1: " + U16p1);
158 string fname = ((LSO_Enums.BuiltIn_Functions)U16p1).ToString();
159
160 bool cmdFound = false;
161 foreach (MethodInfo mi in typeof(LSL_BuiltIn_Commands_Interface).GetMethods())
162 {
163 // Found command
164 if (mi.Name == fname)
165 {
166 il.Emit(OpCodes.Ldarg_0);
167 il.Emit(OpCodes.Call, typeof(LSL_BaseClass).GetMethod("GetLSL_BuiltIn", new Type[] { }));
168 // Pop required number of items from my stack to .Net stack
169 IL_PopToStack(il, mi.GetParameters().Length);
170 il.Emit(OpCodes.Callvirt, mi);
171 cmdFound = true;
172 break;
173 }
174 }
175 if (cmdFound == false)
176 {
177 Common.SendToDebug("ERROR: UNABLE TO LOCATE OPCODE " + idesc + " IN BASECLASS");
178 }
179
180 break;
181
182 // RETURN
183 case LSO_Enums.Operation_Table.RETURN:
184
185 Common.SendToDebug("OPCODE: RETURN");
186 return true;
187
188 case LSO_Enums.Operation_Table.POP:
189 case LSO_Enums.Operation_Table.POPS:
190 case LSO_Enums.Operation_Table.POPL:
191 case LSO_Enums.Operation_Table.POPV:
192 case LSO_Enums.Operation_Table.POPQ:
193 // Pops a specific datatype from the stack
194 // We just ignore the datatype for now
195 IL_Pop(il);
196 break;
197
198 // LONG
199 case LSO_Enums.Operation_Table.STORE:
200 case LSO_Enums.Operation_Table.STORES:
201 case LSO_Enums.Operation_Table.STOREL:
202 case LSO_Enums.Operation_Table.STOREV:
203 case LSO_Enums.Operation_Table.STOREQ:
204 u32p1 = BitConverter.ToUInt32(br_read(4), 0);
205 Common.SendToDebug("Param1: " + u32p1.ToString());
206 IL_CallBaseFunction(il, "StoreToLocal", u32p1);
207 break;
208
209 case LSO_Enums.Operation_Table.STOREG:
210 case LSO_Enums.Operation_Table.STOREGS:
211 case LSO_Enums.Operation_Table.STOREGL:
212 case LSO_Enums.Operation_Table.STOREGV:
213 case LSO_Enums.Operation_Table.STOREGQ:
214 u32p1 = BitConverter.ToUInt32(br_read(4), 0);
215 Common.SendToDebug("Param1: " + u32p1.ToString());
216 IL_CallBaseFunction(il, "StoreToGlobal", u32p1);
217 break;
218
219 case LSO_Enums.Operation_Table.LOADP:
220 case LSO_Enums.Operation_Table.LOADSP:
221 case LSO_Enums.Operation_Table.LOADLP:
222 case LSO_Enums.Operation_Table.LOADVP:
223 case LSO_Enums.Operation_Table.LOADQP:
224 u32p1 = BitConverter.ToUInt32(br_read(4), 0);
225 Common.SendToDebug("Param1: " + u32p1.ToString());
226 IL_CallBaseFunction(il, "StoreToLocal", u32p1);
227 IL_Pop(il);
228 break;
229
230 case LSO_Enums.Operation_Table.LOADGP:
231 case LSO_Enums.Operation_Table.LOADGSP:
232 case LSO_Enums.Operation_Table.LOADGLP:
233 case LSO_Enums.Operation_Table.LOADGVP:
234 case LSO_Enums.Operation_Table.LOADGQP:
235 u32p1 = BitConverter.ToUInt32(br_read(4), 0);
236 Common.SendToDebug("Param1: " + u32p1.ToString());
237 IL_CallBaseFunction(il, "StoreToStatic", u32p1 - 6 + myHeader.GVR);
238 IL_Pop(il);
239 break;
240
241 // PUSH FROM LOCAL FRAME
242 case LSO_Enums.Operation_Table.PUSH:
243 case LSO_Enums.Operation_Table.PUSHS:
244 case LSO_Enums.Operation_Table.PUSHL:
245 case LSO_Enums.Operation_Table.PUSHV:
246 case LSO_Enums.Operation_Table.PUSHQ:
247 u32p1 = BitConverter.ToUInt32(br_read(4), 0);
248 Common.SendToDebug("Param1: " + u32p1.ToString());
249 IL_CallBaseFunction(il, "GetFromLocal", u32p1);
250
251 break;
252
253 // PUSH FROM STATIC FRAME
254 case LSO_Enums.Operation_Table.PUSHG:
255 case LSO_Enums.Operation_Table.PUSHGS:
256 case LSO_Enums.Operation_Table.PUSHGL:
257 case LSO_Enums.Operation_Table.PUSHGV:
258 case LSO_Enums.Operation_Table.PUSHGQ:
259 u32p1 = BitConverter.ToUInt32(br_read(4), 0);
260 Common.SendToDebug("Param1: " + u32p1.ToString());
261 IL_CallBaseFunction(il, "GetFromStatic", u32p1 - 6 + myHeader.GVR);
262 break;
263
264
265 /***********************
266 * NOT IMPLEMENTED YET *
267 ***********************/
268
269
270
271 case LSO_Enums.Operation_Table.POPIP:
272 case LSO_Enums.Operation_Table.POPSP:
273 case LSO_Enums.Operation_Table.POPSLR:
274 case LSO_Enums.Operation_Table.POPARG:
275 case LSO_Enums.Operation_Table.POPBP:
276 //Common.SendToDebug("Instruction " + idesc + ": Ignored");
277 Common.SendToDebug("Instruction " + idesc + ": Description: Drop x bytes from the stack (TODO: Only popping 1)");
278 //Common.SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4), 0));
279 IL_Pop(il);
280 break;
281
282
283
284 // None
285 case LSO_Enums.Operation_Table.PUSHIP:
286 // PUSH INSTRUCTION POINTER
287 break;
288 case LSO_Enums.Operation_Table.PUSHBP:
289
290 case LSO_Enums.Operation_Table.PUSHEV:
291 break;
292 case LSO_Enums.Operation_Table.PUSHEQ:
293 break;
294
295
296 // LONG
297 case LSO_Enums.Operation_Table.JUMP:
298 Common.SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4), 0));
299 break;
300 // BYTE, LONG
301 case LSO_Enums.Operation_Table.JUMPIF:
302 case LSO_Enums.Operation_Table.JUMPNIF:
303 Common.SendToDebug("Param1: " + br_read(1)[0]);
304 Common.SendToDebug("Param2: " + BitConverter.ToUInt32(br_read(4), 0));
305 break;
306 // LONG
307 case LSO_Enums.Operation_Table.STATE:
308 bp1 = br_read(1)[0];
309 //il.Emit(OpCodes.Ld); // Load local variable 0 onto stack
310 //il.Emit(OpCodes.Ldc_I4, 0); // Push index position
311 //il.Emit(OpCodes.Ldstr, EventList[p1]); // Push value
312 //il.Emit(OpCodes.Stelem_Ref); // Perform array[index] = value
313 break;
314 case LSO_Enums.Operation_Table.CALL:
315 Common.SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4), 0));
316 Common.SendToDebug("ERROR: Function CALL not implemented yet.");
317 break;
318 // BYTE
319 case LSO_Enums.Operation_Table.CAST:
320 bp1 = br_read(1)[0];
321 Common.SendToDebug("Instruction " + idesc + ": Cast to type: " + ((LSO_Enums.OpCode_Cast_TypeDefs)bp1));
322 Common.SendToDebug("Param1: " + bp1);
323 switch ((LSO_Enums.OpCode_Cast_TypeDefs)bp1)
324 {
325 case LSO_Enums.OpCode_Cast_TypeDefs.String:
326 Common.SendToDebug("Instruction " + idesc + ": il.Emit(OpCodes.Box, ILStack.Pop());");
327 break;
328 default:
329 Common.SendToDebug("Instruction " + idesc + ": Unknown cast type!");
330 break;
331 }
332 break;
333 // LONG
334 case LSO_Enums.Operation_Table.STACKTOS:
335 case LSO_Enums.Operation_Table.STACKTOL:
336 Common.SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4), 0));
337 break;
338 // BYTE
339 case LSO_Enums.Operation_Table.PRINT:
340 case LSO_Enums.Operation_Table.CALLLIB:
341 Common.SendToDebug("Param1: " + br_read(1)[0]);
342 break;
343 }
344 return false;
345 }
346
347 private void IL_PopToStack(ILGenerator il)
348 {
349 IL_PopToStack(il, 1);
350 }
351 private void IL_PopToStack(ILGenerator il, int count)
352 {
353 Common.SendToDebug("IL_PopToStack();");
354 for (int i = 0; i < count; i++)
355 {
356 IL_CallBaseFunction(il, "POPToStack");
357 //il.Emit(OpCodes.Ldarg_0);
358 //il.Emit(OpCodes.Call,
359 // typeof(LSL_BaseClass).GetMethod("POPToStack",
360 // new Type[] { }));
361 }
362 }
363 private void IL_Pop(ILGenerator il)
364 {
365 Common.SendToDebug("IL_Pop();");
366 IL_CallBaseFunction(il, "POP");
367 }
368 private void IL_Debug(ILGenerator il, string text)
369 {
370 il.Emit(OpCodes.Ldstr, text);
371 il.Emit(OpCodes.Call, typeof(Common).GetMethod("SendToDebug",
372 new Type[] { typeof(string) }
373 ));
374 }
375 private void IL_CallBaseFunction(ILGenerator il, string methodname)
376 {
377 il.Emit(OpCodes.Ldarg_0);
378 il.Emit(OpCodes.Call, typeof(LSL_BaseClass).GetMethod(methodname, new Type[] { }));
379 }
380 private void IL_CallBaseFunction(ILGenerator il, string methodname, object data)
381 {
382 il.Emit(OpCodes.Ldarg_0);
383 if (data.GetType() == typeof(string))
384 il.Emit(OpCodes.Ldstr, (string)data);
385 if (data.GetType() == typeof(UInt32))
386 il.Emit(OpCodes.Ldc_I4, (UInt32)data);
387 il.Emit(OpCodes.Call, typeof(LSL_BaseClass).GetMethod(methodname, new Type[] { data.GetType() }));
388 }
389
390 private void IL_Push(ILGenerator il, object data)
391 {
392 il.Emit(OpCodes.Ldarg_0);
393 Common.SendToDebug("PUSH datatype: " + data.GetType());
394
395 IL_PushDataTypeToILStack(il, data);
396
397 il.Emit(OpCodes.Call, typeof(LSL_BaseClass).GetMethod("PUSH", new Type[] { data.GetType() }));
398
399 }
400
401 private void IL_PushDataTypeToILStack(ILGenerator il, object data)
402 {
403 if (data.GetType() == typeof(UInt16))
404 {
405 il.Emit(OpCodes.Ldc_I4, (UInt16)data);
406 il.Emit(OpCodes.Box, data.GetType());
407 }
408 if (data.GetType() == typeof(UInt32))
409 {
410 il.Emit(OpCodes.Ldc_I4, (UInt32)data);
411 il.Emit(OpCodes.Box, data.GetType());
412 }
413 if (data.GetType() == typeof(Int32))
414 {
415 il.Emit(OpCodes.Ldc_I4, (Int32)data);
416 il.Emit(OpCodes.Box, data.GetType());
417 }
418 if (data.GetType() == typeof(float))
419 {
420 il.Emit(OpCodes.Ldc_I4, (float)data);
421 il.Emit(OpCodes.Box, data.GetType());
422 }
423 if (data.GetType() == typeof(string))
424 il.Emit(OpCodes.Ldstr, (string)data);
425 //if (data.GetType() == typeof(LSO_Enums.Rotation))
426 // il.Emit(OpCodes.Ldobj, (LSO_Enums.Rotation)data);
427 //if (data.GetType() == typeof(LSO_Enums.Vector))
428 // il.Emit(OpCodes.Ldobj, (LSO_Enums.Vector)data);
429 //if (data.GetType() == typeof(LSO_Enums.Key))
430 // il.Emit(OpCodes.Ldobj, (LSO_Enums.Key)data);
431
432 }
433
434
435 }
436}