aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Parser.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Parser.cs608
1 files changed, 608 insertions, 0 deletions
diff --git a/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Parser.cs b/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Parser.cs
new file mode 100644
index 0000000..5f2e3c1
--- /dev/null
+++ b/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Parser.cs
@@ -0,0 +1,608 @@
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.IO;
5 using System.Reflection;
6 using System.Reflection.Emit;
7using OpenSim.Region.Environment.Scripting;
8
9 namespace OpenSim.ScriptEngines.LSL
10 {
11 class LSO_Parser
12 {
13 private bool Debug = true;
14 private FileStream fs;
15 private BinaryReader br;
16 private LSO_Struct.Header myHeader;
17
18 private TypeBuilder typeBuilder;
19 private ScriptInfo WorldAPI;
20
21 /// <summary>
22 /// Parse LSO file.
23 /// Reads LSO ByteCode into memory structures.
24 /// TODO: What else does it do?
25 /// </summary>
26 /// <param name="FileName">FileName of LSO ByteCode file</param>
27 public void ParseFile(string FileName, ScriptInfo _WorldAPI, ref TypeBuilder _typeBuilder)
28 {
29 typeBuilder = _typeBuilder;
30 WorldAPI = _WorldAPI;
31 // Open
32 SendToDebug("Opening filename: " + FileName);
33 fs = File.Open(FileName, FileMode.Open, FileAccess.Read, FileShare.Read);
34 br = new BinaryReader(fs, Encoding.BigEndianUnicode);
35
36
37 // The LSO Format consist of 6 major blocks: header, statics, functions, states, heap, and stack.
38
39
40 // HEADER BLOCK
41 SendToDebug("Reading HEADER BLOCK at: 0");
42 fs.Seek(0, SeekOrigin.Begin);
43 myHeader = new LSO_Struct.Header();
44 myHeader.TM = BitConverter.ToUInt32(br_read(4), 0);
45 myHeader.IP = BitConverter.ToUInt32(br_read(4), 0);
46 myHeader.VN = BitConverter.ToUInt32(br_read(4), 0);
47 myHeader.BP = BitConverter.ToUInt32(br_read(4), 0);
48 myHeader.SP = BitConverter.ToUInt32(br_read(4), 0);
49 myHeader.HR = BitConverter.ToUInt32(br_read(4), 0);
50 myHeader.HP = BitConverter.ToUInt32(br_read(4), 0);
51 myHeader.CS = BitConverter.ToUInt32(br_read(4), 0);
52 myHeader.NS = BitConverter.ToUInt32(br_read(4), 0);
53 myHeader.CE = BitConverter.ToUInt32(br_read(4), 0);
54 myHeader.IE = BitConverter.ToUInt32(br_read(4), 0);
55 myHeader.ER = BitConverter.ToUInt32(br_read(4), 0);
56 myHeader.FR = BitConverter.ToUInt32(br_read(4), 0);
57 myHeader.SLR = BitConverter.ToUInt32(br_read(4), 0);
58 myHeader.GVR = BitConverter.ToUInt32(br_read(4), 0);
59 myHeader.GFR = BitConverter.ToUInt32(br_read(4), 0);
60 myHeader.PR = BitConverter.ToUInt32(br_read(4), 0);
61 myHeader.ESR = BitConverter.ToUInt32(br_read(4), 0);
62 myHeader.SR = BitConverter.ToUInt32(br_read(4), 0);
63 myHeader.NCE = BitConverter.ToUInt64(br_read(8), 0);
64 myHeader.NIE = BitConverter.ToUInt64(br_read(8), 0);
65 myHeader.NER = BitConverter.ToUInt64(br_read(8), 0);
66
67 // Print Header Block to debug
68 SendToDebug("TM - Top of memory (size): " + myHeader.TM);
69 SendToDebug("IP - Instruction Pointer (0=not running): " + myHeader.IP);
70 SendToDebug("VN - Version number: " + myHeader.VN);
71 SendToDebug("BP - Local Frame Pointer: " + myHeader.BP);
72 SendToDebug("SP - Stack Pointer: " + myHeader.SP);
73 SendToDebug("HR - Heap Register: " + myHeader.HR);
74 SendToDebug("HP - Heap Pointer: " + myHeader.HP);
75 SendToDebug("CS - Current State: " + myHeader.CS);
76 SendToDebug("NS - Next State: " + myHeader.NS);
77 SendToDebug("CE - Current Events: " + myHeader.CE);
78 SendToDebug("IE - In Event: " + myHeader.IE);
79 SendToDebug("ER - Event Register: " + myHeader.ER);
80 SendToDebug("FR - Fault Register: " + myHeader.FR);
81 SendToDebug("SLR - Sleep Register: " + myHeader.SLR);
82 SendToDebug("GVR - Global Variable Register: " + myHeader.GVR);
83 SendToDebug("GFR - Global Function Register: " + myHeader.GFR);
84 SendToDebug("PR - Parameter Register: " + myHeader.PR);
85 SendToDebug("ESR - Energy Supply Register: " + myHeader.ESR);
86 SendToDebug("SR - State Register: " + myHeader.SR);
87 SendToDebug("NCE - 64-bit Current Events: " + myHeader.NCE);
88 SendToDebug("NIE - 64-bit In Events: " + myHeader.NIE);
89 SendToDebug("NER - 64-bit Event Register: " + myHeader.NER);
90 SendToDebug("Read position when exiting HEADER BLOCK: " + fs.Position);
91
92 // STATIC BLOCK
93 SendToDebug("Reading STATIC BLOCK at: " + myHeader.GVR);
94 fs.Seek(myHeader.GVR, SeekOrigin.Begin);
95 int StaticBlockCount = 0;
96 // Read function blocks until we hit GFR
97 while (fs.Position < myHeader.GFR)
98 {
99 StaticBlockCount++;
100 SendToDebug("Reading Static Block " + StaticBlockCount + " at: " + fs.Position);
101 //fs.Seek(myHeader.GVR, SeekOrigin.Begin);
102 LSO_Struct.StaticBlock myStaticBlock = new LSO_Struct.StaticBlock();
103 myStaticBlock.Static_Chunk_Header_Size = BitConverter.ToUInt32(br_read(4), 0);
104 myStaticBlock.ObjectType = br_read(1)[0];
105 SendToDebug("Static Block ObjectType: " + ((LSO_Enums.Variable_Type_Codes)myStaticBlock.ObjectType).ToString());
106 myStaticBlock.Unknown = br_read(1)[0];
107 // Size of datatype varies
108 if (myStaticBlock.ObjectType != 0)
109 myStaticBlock.BlockVariable = br_read(getObjectSize(myStaticBlock.ObjectType));
110 }
111 SendToDebug("Number of Static Blocks read: " + StaticBlockCount);
112
113
114 // FUNCTION BLOCK
115 // Always right after STATIC BLOCK
116 LSO_Struct.FunctionBlock myFunctionBlock = new LSO_Struct.FunctionBlock();
117 if (myHeader.GFR == myHeader.SR)
118 {
119 // If GFR and SR are at same position then there is no fuction block
120 SendToDebug("No FUNCTION BLOCK found");
121 } else {
122 SendToDebug("Reading FUNCTION BLOCK at: " + myHeader.GFR);
123 fs.Seek(myHeader.GFR, SeekOrigin.Begin);
124 myFunctionBlock.FunctionCount = BitConverter.ToUInt32(br_read(4), 0);
125 SendToDebug("Number of functions in Fuction Block: " + myFunctionBlock.FunctionCount);
126 if (myFunctionBlock.FunctionCount > 0)
127 {
128 myFunctionBlock.CodeChunkPointer = new UInt32[myFunctionBlock.FunctionCount];
129 for (int i = 0; i < myFunctionBlock.FunctionCount; i++)
130 {
131 SendToDebug("Reading function " + i + " at: " + fs.Position);
132 // TODO: ADD TO FUNCTION LIST (How do we identify it later?)
133 // Note! Absolute position
134 myFunctionBlock.CodeChunkPointer[i] = BitConverter.ToUInt32(br_read(4), 0) + myHeader.GFR;
135 SendToDebug("Fuction " + i + " code chunk position: " + myFunctionBlock.CodeChunkPointer[i]);
136 }
137 }
138 }
139
140
141 // STATE FRAME BLOCK
142 // Always right after FUNCTION BLOCK
143 SendToDebug("Reading STATE BLOCK at: " + myHeader.SR);
144 fs.Seek(myHeader.SR, SeekOrigin.Begin);
145 LSO_Struct.StateFrameBlock myStateFrameBlock = new LSO_Struct.StateFrameBlock();
146 myStateFrameBlock.StateCount = BitConverter.ToUInt32(br_read(4), 0);
147 if (myStateFrameBlock.StateCount > 0)
148 {
149 // Initialize array
150 myStateFrameBlock.StatePointer = new LSO_Struct.StatePointerBlock[myStateFrameBlock.StateCount];
151 for (int i = 0; i < myStateFrameBlock.StateCount; i++)
152 {
153 SendToDebug("Reading STATE POINTER BLOCK " + (i+1) + " at: " + fs.Position);
154 // Position is relative to state frame
155 myStateFrameBlock.StatePointer[i].Location = myHeader.SR + BitConverter.ToUInt32(br_read(4), 0);
156 myStateFrameBlock.StatePointer[i].EventMask = new System.Collections.BitArray(br_read(8));
157 SendToDebug("Pointer: " + myStateFrameBlock.StatePointer[i].Location);
158 SendToDebug("Total potential EventMask bits: " + myStateFrameBlock.StatePointer[i].EventMask.Count);
159
160 //// Read STATE BLOCK
161 //long CurPos = fs.Position;
162 //fs.Seek(CurPos, SeekOrigin.Begin);
163
164 }
165 }
166
167
168 // STATE BLOCK
169 // For each StateFrameBlock there is one StateBlock with multiple event handlers
170
171 if (myStateFrameBlock.StateCount > 0)
172 {
173 // Go through all State Frame Pointers found
174 for (int i = 0; i < myStateFrameBlock.StateCount; i++)
175 {
176
177 fs.Seek(myStateFrameBlock.StatePointer[i].Location, SeekOrigin.Begin);
178 SendToDebug("Reading STATE BLOCK " + (i + 1) + " at: " + fs.Position);
179
180 // READ: STATE BLOCK HEADER
181 myStateFrameBlock.StatePointer[i].StateBlock = new LSO_Struct.StateBlock();
182 myStateFrameBlock.StatePointer[i].StateBlock.StartPos = (UInt32)fs.Position; // Note
183 myStateFrameBlock.StatePointer[i].StateBlock.HeaderSize = BitConverter.ToUInt32(br_read(4), 0);
184 myStateFrameBlock.StatePointer[i].StateBlock.Unknown = br_read(1)[0];
185 myStateFrameBlock.StatePointer[i].StateBlock.EndPos = (UInt32)fs.Position; // Note
186 SendToDebug("State block Start Pos: " + myStateFrameBlock.StatePointer[i].StateBlock.StartPos);
187 SendToDebug("State block Header Size: " + myStateFrameBlock.StatePointer[i].StateBlock.HeaderSize);
188 SendToDebug("State block Header End Pos: " + myStateFrameBlock.StatePointer[i].StateBlock.EndPos);
189
190 // We need to count number of bits flagged in EventMask?
191
192
193 // for each bit in myStateFrameBlock.StatePointer[i].EventMask
194
195 // ADDING TO ALL RIGHT NOW, SHOULD LIMIT TO ONLY THE ONES IN USE
196 //TODO: Create event hooks
197 myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers = new LSO_Struct.StateBlockHandler[myStateFrameBlock.StatePointer[i].EventMask.Count - 1];
198 for (int ii = 0; ii < myStateFrameBlock.StatePointer[i].EventMask.Count - 1; ii++)
199 {
200
201 if (myStateFrameBlock.StatePointer[i].EventMask.Get(ii) == true)
202 {
203 // We got an event
204 // READ: STATE BLOCK HANDLER
205 SendToDebug("Reading STATE BLOCK " + (i + 1) + " HANDLER matching EVENT MASK " + ii + " (" + ((LSO_Enums.Event_Mask_Values)ii).ToString() + ") at: " + fs.Position);
206 myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer = myStateFrameBlock.StatePointer[i].StateBlock.EndPos + BitConverter.ToUInt32(br_read(4), 0);
207 myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CallFrameSize = BitConverter.ToUInt32(br_read(4), 0);
208 SendToDebug("Reading STATE BLOCK " + (i + 1) + " HANDLER EVENT MASK " + ii + " (" + ((LSO_Enums.Event_Mask_Values)ii).ToString() + ") Code Chunk Pointer: " + myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer);
209 SendToDebug("Reading STATE BLOCK " + (i + 1) + " HANDLER EVENT MASK " + ii + " (" + ((LSO_Enums.Event_Mask_Values)ii).ToString() + ") Call Frame Size: " + myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CallFrameSize );
210 }
211 }
212 }
213 }
214
215
216
217
218 //// READ FUNCTION CODE CHUNKS
219 //// Functions + Function start pos (GFR)
220 //// TODO: Somehow be able to identify and reference this
221 //LSO_Struct.CodeChunk[] myFunctionCodeChunk;
222 //if (myFunctionBlock.FunctionCount > 0)
223 //{
224 // myFunctionCodeChunk = new LSO_Struct.CodeChunk[myFunctionBlock.FunctionCount];
225 // for (int i = 0; i < myFunctionBlock.FunctionCount; i++)
226 // {
227 // SendToDebug("Reading Function Code Chunk " + i);
228 // myFunctionCodeChunk[i] = GetCodeChunk((UInt32)myFunctionBlock.CodeChunkPointer[i]);
229 // }
230
231 //}
232 // READ EVENT CODE CHUNKS
233 LSO_Struct.CodeChunk[] myEventCodeChunk;
234 if (myStateFrameBlock.StateCount > 0)
235 {
236 myEventCodeChunk = new LSO_Struct.CodeChunk[myStateFrameBlock.StateCount];
237 for (int i = 0; i < myStateFrameBlock.StateCount; i++)
238 {
239 // TODO: Somehow organize events and functions so they can be found again,
240 // two level search ain't no good
241 for (int ii = 0; ii < myStateFrameBlock.StatePointer[i].EventMask.Count - 1; ii++)
242 {
243
244
245 if (myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer > 0)
246 {
247 SendToDebug("Reading Event Code Chunk state " + i + ", event " + (LSO_Enums.Event_Mask_Values)ii);
248
249
250 // Override a Method / Function
251 string eventname = "event_" + (LSO_Enums.Event_Mask_Values)ii;
252 SendToDebug("CLR:" + eventname + ":MethodBuilder methodBuilder = typeBuilder.DefineMethod...");
253 MethodBuilder methodBuilder = typeBuilder.DefineMethod(eventname,
254 MethodAttributes.Private | MethodAttributes.Virtual,
255 typeof(void),
256 new Type[] { typeof(object) });
257
258 SendToDebug("CLR:" + eventname + ":typeBuilder.DefineMethodOverride(methodBuilder...");
259 typeBuilder.DefineMethodOverride(methodBuilder,
260 typeof(LSL_CLRInterface.LSLScript).GetMethod(eventname));
261
262 // Create the IL generator
263
264 SendToDebug("CLR:" + eventname + ":ILGenerator il = methodBuilder.GetILGenerator();");
265 ILGenerator il = methodBuilder.GetILGenerator();
266
267
268 LSO_Struct.CodeChunk myECC =
269 GetCodeChunk(myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer, il, eventname);
270 }
271
272 }
273 }
274
275 }
276
277
278 // Close
279 br.Close();
280 fs.Close();
281
282 }
283
284 private LSO_Struct.HeapBlock GetHeap(UInt32 pos)
285 {
286 // HEAP BLOCK
287 // TODO:? Special read for strings/keys (null terminated) and lists (pointers to other HEAP entries)
288 SendToDebug("Reading HEAP BLOCK at: " + pos);
289 fs.Seek(pos, SeekOrigin.Begin);
290
291 LSO_Struct.HeapBlock myHeapBlock = new LSO_Struct.HeapBlock();
292 myHeapBlock.DataBlockSize = BitConverter.ToUInt32(br_read(4), 0);
293 myHeapBlock.ObjectType = br_read(1)[0];
294 myHeapBlock.ReferenceCount = BitConverter.ToUInt16(br_read(2), 0);
295 myHeapBlock.Data = br_read(getObjectSize(myHeapBlock.ObjectType));
296
297 SendToDebug("Heap Block Data Block Size: " + myHeapBlock.DataBlockSize);
298 SendToDebug("Heap Block ObjectType: " + ((LSO_Enums.Variable_Type_Codes)myHeapBlock.ObjectType).ToString());
299 SendToDebug("Heap Block Reference Count: " + myHeapBlock.ReferenceCount);
300
301 return myHeapBlock;
302 }
303
304
305
306 private byte[] br_read(int len)
307 {
308 if (len <= 0)
309 return null;
310
311 try
312 {
313 byte[] bytes = new byte[len];
314 for (int i = len - 1; i > -1; i--)
315 bytes[i] = br.ReadByte();
316 return bytes;
317 }
318 catch (Exception e)
319 {
320 SendToDebug("Exception: " + e.ToString());
321 throw (e);
322 }
323 }
324 //private byte[] br_read_smallendian(int len)
325 //{
326 // byte[] bytes = new byte[len];
327 // br.Read(bytes,0, len);
328 // return bytes;
329 //}
330
331 private int getObjectSize(byte ObjectType)
332 {
333 switch (ObjectType)
334 {
335 case 1:
336 case 2:
337 case 3:
338 case 4:
339 case 7:
340 return 4;
341 case 5:
342 return 12;
343 case 6:
344 return 16;
345 default:
346 return 0;
347 }
348 }
349 private void SendToDebug(string Message)
350 {
351 if (Debug == true)
352 Console.WriteLine("Debug: " + Message);
353 }
354
355
356 private string Read_String()
357 {
358 string ret = "";
359 byte reader = br_read(1)[0];
360 while (reader != 0x000)
361 {
362 ret += (char)reader;
363 reader = br_read(1)[0];
364 }
365 return ret;
366 }
367
368 /// <summary>
369 /// Reads a code chunk into structure and returns it.
370 /// </summary>
371 /// <param name="pos">Absolute position in file. REMEMBER TO ADD myHeader.GFR!</param>
372 /// <returns></returns>
373 private LSO_Struct.CodeChunk GetCodeChunk(UInt32 pos, ILGenerator il, string eventname)
374 {
375
376 /*
377 * CLR TRY
378 */
379 //SendToDebug("CLR:" + eventname + ":il.BeginExceptionBlock()");
380 il.BeginExceptionBlock();
381
382 // Push "Hello World!" string to stack
383 //SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Ldstr...");
384 il.Emit(OpCodes.Ldstr, "Starting CLR dynamic execution of: " + eventname);
385
386 // Push Console.WriteLine command to stack ... Console.WriteLine("Hello World!");
387 //SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call...");
388 il.Emit(OpCodes.Call, typeof(Console).GetMethod
389 ("WriteLine", new Type[] { typeof(string) }));
390
391
392 LSO_Struct.CodeChunk myCodeChunk = new LSO_Struct.CodeChunk();
393
394 SendToDebug("Reading Function Code Chunk at: " + pos);
395 fs.Seek(pos, SeekOrigin.Begin);
396 myCodeChunk.CodeChunkHeaderSize = BitConverter.ToUInt32(br_read(4), 0);
397 SendToDebug("CodeChunk Header Size: " + myCodeChunk.CodeChunkHeaderSize );
398 // Read until null
399 myCodeChunk.Comment = Read_String();
400 SendToDebug("Function comment: " + myCodeChunk.Comment);
401 myCodeChunk.ReturnType = br_read(1)[0];
402 SendToDebug("Return type: " + (LSO_Enums.Variable_Type_Codes)myCodeChunk.ReturnType);
403 // TODO: How to determine number of codechunks -- does this method work?
404 myCodeChunk.CodeChunkArguments = new System.Collections.Generic.List<LSO_Struct.CodeChunkArgument>();
405 byte reader = br_read(1)[0];
406 reader = br_read(1)[0];
407 int ccount = 0;
408 while (reader != 0x000)
409 {
410 ccount++;
411 SendToDebug("Reading Code Chunk Argument " + ccount);
412 LSO_Struct.CodeChunkArgument CCA = new LSO_Struct.CodeChunkArgument();
413 CCA.FunctionReturnType = reader;
414 reader = br_read(1)[0];
415 CCA.NullString = reader;
416 myCodeChunk.CodeChunkArguments.Add(CCA);
417 SendToDebug("Code Chunk Argument " + ccount + " return type: " + (LSO_Enums.Variable_Type_Codes)CCA.FunctionReturnType);
418 }
419 // End marker is 0x000
420 myCodeChunk.EndMarker = reader;
421 // TODO: How to read and identify following code
422 // TODO: Code is read until a return of some sort is found
423 bool FoundRet = false;
424 while (FoundRet == false)
425 {
426 //reader = br_read(1)[0];
427 //UInt16 opcode = BitConverter.ToUInt16(br_read(1),0);
428 UInt16 opcode = br_read(1)[0];
429 //long rPos = fs.Position;
430 SendToDebug("OPCODE: " + ((LSO_Enums.Operation_Table)opcode).ToString());
431 switch (opcode)
432 {
433 // LONG
434 case (UInt16)LSO_Enums.Operation_Table.POPARG:
435 case (UInt16)LSO_Enums.Operation_Table.STORE:
436 case (UInt16)LSO_Enums.Operation_Table.STORES:
437 case (UInt16)LSO_Enums.Operation_Table.STOREL:
438 case (UInt16)LSO_Enums.Operation_Table.STOREV:
439 case (UInt16)LSO_Enums.Operation_Table.STOREQ:
440 case (UInt16)LSO_Enums.Operation_Table.STOREG:
441 case (UInt16)LSO_Enums.Operation_Table.STOREGS:
442 case (UInt16)LSO_Enums.Operation_Table.STOREGL:
443 case (UInt16)LSO_Enums.Operation_Table.STOREGV:
444 case (UInt16)LSO_Enums.Operation_Table.STOREGQ:
445 case (UInt16)LSO_Enums.Operation_Table.LOADP:
446 case (UInt16)LSO_Enums.Operation_Table.LOADSP:
447 case (UInt16)LSO_Enums.Operation_Table.LOADLP:
448 case (UInt16)LSO_Enums.Operation_Table.LOADVP:
449 case (UInt16)LSO_Enums.Operation_Table.LOADQP:
450 case (UInt16)LSO_Enums.Operation_Table.PUSH:
451 case (UInt16)LSO_Enums.Operation_Table.PUSHS:
452 case (UInt16)LSO_Enums.Operation_Table.PUSHL:
453 case (UInt16)LSO_Enums.Operation_Table.PUSHV:
454 case (UInt16)LSO_Enums.Operation_Table.PUSHQ:
455 case (UInt16)LSO_Enums.Operation_Table.PUSHG:
456 case (UInt16)LSO_Enums.Operation_Table.PUSHGS:
457 case (UInt16)LSO_Enums.Operation_Table.PUSHGL:
458 case (UInt16)LSO_Enums.Operation_Table.PUSHGV:
459 case (UInt16)LSO_Enums.Operation_Table.PUSHGQ:
460 SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0));
461 break;
462 // BYTE
463 case (UInt16)LSO_Enums.Operation_Table.PUSHARGB:
464 SendToDebug("Param1: " + br_read(1)[0]);
465 break;
466 // INTEGER
467 case (UInt16)LSO_Enums.Operation_Table.PUSHARGI:
468 // TODO: What is size of integer?
469 SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0));
470 break;
471 // FLOAT
472 case (UInt16)LSO_Enums.Operation_Table.PUSHARGF:
473 // TODO: What is size of float?
474 SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0));
475 break;
476 // STRING
477 case (UInt16)LSO_Enums.Operation_Table.PUSHARGS:
478 string s = Read_String();
479 SendToDebug("Param1: " + s);
480 il.Emit(OpCodes.Ldstr, s);
481 break;
482 // VECTOR z,y,x
483 case (UInt16)LSO_Enums.Operation_Table.PUSHARGV:
484 SendToDebug("Param1 Z: " + BitConverter.ToUInt32(br_read(4),0));
485 SendToDebug("Param1 Y: " + BitConverter.ToUInt32(br_read(4),0));
486 SendToDebug("Param1 X: " + BitConverter.ToUInt32(br_read(4),0));
487 break;
488 // ROTATION s,z,y,x
489 case (UInt16)LSO_Enums.Operation_Table.PUSHARGQ:
490 SendToDebug("Param1 S: " + BitConverter.ToUInt32(br_read(4),0));
491 SendToDebug("Param1 Z: " + BitConverter.ToUInt32(br_read(4),0));
492 SendToDebug("Param1 Y: " + BitConverter.ToUInt32(br_read(4),0));
493 SendToDebug("Param1 X: " + BitConverter.ToUInt32(br_read(4),0));
494 break;
495 // LONG
496 case (UInt16)LSO_Enums.Operation_Table.PUSHARGE:
497 SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0));
498 break;
499 // BYTE
500 case (UInt16)LSO_Enums.Operation_Table.ADD:
501 case (UInt16)LSO_Enums.Operation_Table.SUB:
502 case (UInt16)LSO_Enums.Operation_Table.MUL:
503 case (UInt16)LSO_Enums.Operation_Table.DIV:
504 case (UInt16)LSO_Enums.Operation_Table.MOD:
505 case (UInt16)LSO_Enums.Operation_Table.EQ:
506 case (UInt16)LSO_Enums.Operation_Table.NEQ:
507 case (UInt16)LSO_Enums.Operation_Table.LEQ:
508 case (UInt16)LSO_Enums.Operation_Table.GEQ:
509 case (UInt16)LSO_Enums.Operation_Table.LESS:
510 case (UInt16)LSO_Enums.Operation_Table.GREATER:
511 case (UInt16)LSO_Enums.Operation_Table.BOOLOR:
512 SendToDebug("Param1: " + br_read(1)[0]);
513 break;
514 // LONG
515 case (UInt16)LSO_Enums.Operation_Table.JUMP:
516 SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0));
517 break;
518 // BYTE, LONG
519 case (UInt16)LSO_Enums.Operation_Table.JUMPIF:
520 case (UInt16)LSO_Enums.Operation_Table.JUMPNIF:
521 SendToDebug("Param1: " + br_read(1)[0]);
522 SendToDebug("Param2: " + BitConverter.ToUInt32(br_read(4),0));
523 break;
524 // LONG
525 case (UInt16)LSO_Enums.Operation_Table.STATE:
526 case (UInt16)LSO_Enums.Operation_Table.CALL:
527 SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0));
528 break;
529 // BYTE
530 case (UInt16)LSO_Enums.Operation_Table.CAST:
531 SendToDebug("Param1: " + br_read(1)[0]);
532 break;
533 // LONG
534 case (UInt16)LSO_Enums.Operation_Table.STACKTOS:
535 case (UInt16)LSO_Enums.Operation_Table.STACKTOL:
536 SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0));
537 break;
538 // BYTE
539 case (UInt16)LSO_Enums.Operation_Table.PRINT:
540 case (UInt16)LSO_Enums.Operation_Table.CALLLIB:
541 SendToDebug("Param1: " + br_read(1)[0]);
542 break;
543 // SHORT
544 case (UInt16)LSO_Enums.Operation_Table.CALLLIB_TWO_BYTE:
545 // TODO: What is size of short?
546 UInt16 _i = BitConverter.ToUInt16(br_read(2), 0);
547 SendToDebug("Param1: " + _i);
548 switch (_i)
549 {
550 case (UInt16)LSO_Enums.BuiltIn_Functions.llSay:
551 il.Emit(OpCodes.Call, typeof(Console).GetMethod
552 ("WriteLine", new Type[] { typeof(string) }));
553 break;
554 }
555 break;
556
557
558 // RETURN
559 case (UInt16)LSO_Enums.Operation_Table.RETURN:
560 SendToDebug("Last OPCODE was return command. Code chunk execution complete.");
561 FoundRet = true;
562 break;
563 }
564 //fs.Seek(rPos, SeekOrigin.Begin);
565
566 }
567
568
569 /*
570 * CATCH
571 */
572 SendToDebug("CLR:" + eventname + ":il.BeginCatchBlock(typeof(Exception));");
573 il.BeginCatchBlock(typeof(Exception));
574
575 // Push "Hello World!" string to stack
576 SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Ldstr...");
577 il.Emit(OpCodes.Ldstr, "Execption executing dynamic CLR function " + eventname + ": ");
578
579 //call void [mscorlib]System.Console::WriteLine(string)
580 SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call...");
581 il.Emit(OpCodes.Call, typeof(Console).GetMethod
582 ("Write", new Type[] { typeof(string) }));
583
584 //callvirt instance string [mscorlib]System.Exception::get_Message()
585 SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Callvirt...");
586 il.Emit(OpCodes.Callvirt, typeof(Exception).GetMethod
587 ("get_Message"));
588
589 //call void [mscorlib]System.Console::WriteLine(string)
590 SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call...");
591 il.Emit(OpCodes.Call, typeof(Console).GetMethod
592 ("WriteLine", new Type[] { typeof(string) }));
593
594 /*
595 * CLR END TRY
596 */
597 //SendToDebug("CLR:" + eventname + ":il.EndExceptionBlock();");
598 il.EndExceptionBlock();
599 // Push "Return from current method, with return value if present" to stack
600 il.Emit(OpCodes.Ret);
601
602
603
604 return myCodeChunk;
605
606 }
607 }
608}