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