aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Parser.cs
diff options
context:
space:
mode:
authorlbsa712007-08-06 12:54:13 +0000
committerlbsa712007-08-06 12:54:13 +0000
commit74cd26b7228f20bcd9fb2503a81045a36d80a63a (patch)
tree77770b931db549155b9340fb6f8d60fa8d601287 /OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Parser.cs
parent* Now we have boxes. Yay! (diff)
downloadopensim-SC_OLD-74cd26b7228f20bcd9fb2503a81045a36d80a63a.zip
opensim-SC_OLD-74cd26b7228f20bcd9fb2503a81045a36d80a63a.tar.gz
opensim-SC_OLD-74cd26b7228f20bcd9fb2503a81045a36d80a63a.tar.bz2
opensim-SC_OLD-74cd26b7228f20bcd9fb2503a81045a36d80a63a.tar.xz
Part 1 of a two-part commit to change caps of 'scripting' dir...
Diffstat (limited to 'OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Parser.cs')
-rw-r--r--OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Parser.cs629
1 files changed, 0 insertions, 629 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
deleted file mode 100644
index 4ad1f83..0000000
--- a/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Parser.cs
+++ /dev/null
@@ -1,629 +0,0 @@
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.IO;
33using System.Reflection;
34using System.Reflection.Emit;
35
36namespace OpenSim.Region.Scripting.LSL
37{
38 partial class LSO_Parser
39 {
40 private FileStream fs;
41 private BinaryReader br;
42 private LSO_Struct.Header myHeader;
43
44 private TypeBuilder typeBuilder;
45 private System.Collections.Generic.List<string> EventList = new System.Collections.Generic.List<string>();
46
47 /// <summary>
48 /// Parse LSO file.
49 /// Reads LSO ByteCode into memory structures.
50 /// TODO: What else does it do?
51 /// </summary>
52 /// <param name="FileName">FileName of LSO ByteCode file</param>
53 public void ParseFile(string FileName, TypeBuilder _typeBuilder)
54 {
55 typeBuilder = _typeBuilder;
56 //WorldAPI = _WorldAPI;
57 // Open
58 Common.SendToDebug("Opening filename: " + FileName);
59 fs = File.Open(FileName, FileMode.Open, FileAccess.Read, FileShare.Read);
60 br = new BinaryReader(fs, Encoding.BigEndianUnicode);
61
62
63 // The LSO Format consist of 6 major blocks: header, statics, functions, states, heap, and stack.
64
65
66 // HEADER BLOCK
67 Common.SendToDebug("Reading HEADER BLOCK at: 0");
68 fs.Seek(0, SeekOrigin.Begin);
69 myHeader = new LSO_Struct.Header();
70 myHeader.TM = BitConverter.ToUInt32(br_read(4), 0);
71 myHeader.IP = BitConverter.ToUInt32(br_read(4), 0);
72 myHeader.VN = BitConverter.ToUInt32(br_read(4), 0);
73 myHeader.BP = BitConverter.ToUInt32(br_read(4), 0);
74 myHeader.SP = BitConverter.ToUInt32(br_read(4), 0);
75 myHeader.HR = BitConverter.ToUInt32(br_read(4), 0);
76 myHeader.HP = BitConverter.ToUInt32(br_read(4), 0);
77 myHeader.CS = BitConverter.ToUInt32(br_read(4), 0);
78 myHeader.NS = BitConverter.ToUInt32(br_read(4), 0);
79 myHeader.CE = BitConverter.ToUInt32(br_read(4), 0);
80 myHeader.IE = BitConverter.ToUInt32(br_read(4), 0);
81 myHeader.ER = BitConverter.ToUInt32(br_read(4), 0);
82 myHeader.FR = BitConverter.ToUInt32(br_read(4), 0);
83 myHeader.SLR = BitConverter.ToUInt32(br_read(4), 0);
84 myHeader.GVR = BitConverter.ToUInt32(br_read(4), 0);
85 myHeader.GFR = BitConverter.ToUInt32(br_read(4), 0);
86 myHeader.PR = BitConverter.ToUInt32(br_read(4), 0);
87 myHeader.ESR = BitConverter.ToUInt32(br_read(4), 0);
88 myHeader.SR = BitConverter.ToUInt32(br_read(4), 0);
89 myHeader.NCE = BitConverter.ToUInt64(br_read(8), 0);
90 myHeader.NIE = BitConverter.ToUInt64(br_read(8), 0);
91 myHeader.NER = BitConverter.ToUInt64(br_read(8), 0);
92
93 // Print Header Block to debug
94 Common.SendToDebug("TM - Top of memory (size): " + myHeader.TM);
95 Common.SendToDebug("IP - Instruction Pointer (0=not running): " + myHeader.IP);
96 Common.SendToDebug("VN - Version number: " + myHeader.VN);
97 Common.SendToDebug("BP - Local Frame Pointer: " + myHeader.BP);
98 Common.SendToDebug("SP - Stack Pointer: " + myHeader.SP);
99 Common.SendToDebug("HR - Heap Register: " + myHeader.HR);
100 Common.SendToDebug("HP - Heap Pointer: " + myHeader.HP);
101 Common.SendToDebug("CS - Current State: " + myHeader.CS);
102 Common.SendToDebug("NS - Next State: " + myHeader.NS);
103 Common.SendToDebug("CE - Current Events: " + myHeader.CE);
104 Common.SendToDebug("IE - In Event: " + myHeader.IE);
105 Common.SendToDebug("ER - Event Register: " + myHeader.ER);
106 Common.SendToDebug("FR - Fault Register: " + myHeader.FR);
107 Common.SendToDebug("SLR - Sleep Register: " + myHeader.SLR);
108 Common.SendToDebug("GVR - Global Variable Register: " + myHeader.GVR);
109 Common.SendToDebug("GFR - Global Function Register: " + myHeader.GFR);
110 Common.SendToDebug("PR - Parameter Register: " + myHeader.PR);
111 Common.SendToDebug("ESR - Energy Supply Register: " + myHeader.ESR);
112 Common.SendToDebug("SR - State Register: " + myHeader.SR);
113 Common.SendToDebug("NCE - 64-bit Current Events: " + myHeader.NCE);
114 Common.SendToDebug("NIE - 64-bit In Events: " + myHeader.NIE);
115 Common.SendToDebug("NER - 64-bit Event Register: " + myHeader.NER);
116 Common.SendToDebug("Read position when exiting HEADER BLOCK: " + fs.Position);
117
118 // STATIC BLOCK
119 Common.SendToDebug("Reading STATIC BLOCK at: " + myHeader.GVR);
120 fs.Seek(myHeader.GVR, SeekOrigin.Begin);
121 int StaticBlockCount = 0;
122 // Read function blocks until we hit GFR
123 while (fs.Position < myHeader.GFR)
124 {
125 StaticBlockCount++;
126 Common.SendToDebug("Reading Static Block " + StaticBlockCount + " at: " + fs.Position);
127 //fs.Seek(myHeader.GVR, SeekOrigin.Begin);
128 LSO_Struct.StaticBlock myStaticBlock = new LSO_Struct.StaticBlock();
129 myStaticBlock.Static_Chunk_Header_Size = BitConverter.ToUInt32(br_read(4), 0);
130 myStaticBlock.ObjectType = br_read(1)[0];
131 Common.SendToDebug("Static Block ObjectType: " + ((LSO_Enums.Variable_Type_Codes)myStaticBlock.ObjectType).ToString());
132 myStaticBlock.Unknown = br_read(1)[0];
133 // Size of datatype varies
134 if (myStaticBlock.ObjectType != 0)
135 myStaticBlock.BlockVariable = br_read(getObjectSize(myStaticBlock.ObjectType));
136 }
137 Common.SendToDebug("Number of Static Blocks read: " + StaticBlockCount);
138
139
140 // FUNCTION BLOCK
141 // Always right after STATIC BLOCK
142 LSO_Struct.FunctionBlock myFunctionBlock = new LSO_Struct.FunctionBlock();
143 if (myHeader.GFR == myHeader.SR)
144 {
145 // If GFR and SR are at same position then there is no fuction block
146 Common.SendToDebug("No FUNCTION BLOCK found");
147 }
148 else
149 {
150 Common.SendToDebug("Reading FUNCTION BLOCK at: " + myHeader.GFR);
151 fs.Seek(myHeader.GFR, SeekOrigin.Begin);
152 myFunctionBlock.FunctionCount = BitConverter.ToUInt32(br_read(4), 0);
153 Common.SendToDebug("Number of functions in Fuction Block: " + myFunctionBlock.FunctionCount);
154 if (myFunctionBlock.FunctionCount > 0)
155 {
156 myFunctionBlock.CodeChunkPointer = new UInt32[myFunctionBlock.FunctionCount];
157 for (int i = 0; i < myFunctionBlock.FunctionCount; i++)
158 {
159 Common.SendToDebug("Reading function " + i + " at: " + fs.Position);
160 // TODO: ADD TO FUNCTION LIST (How do we identify it later?)
161 // Note! Absolute position
162 myFunctionBlock.CodeChunkPointer[i] = BitConverter.ToUInt32(br_read(4), 0) + myHeader.GFR;
163 Common.SendToDebug("Fuction " + i + " code chunk position: " + myFunctionBlock.CodeChunkPointer[i]);
164 }
165 }
166 }
167
168
169 // STATE FRAME BLOCK
170 // Always right after FUNCTION BLOCK
171 Common.SendToDebug("Reading STATE BLOCK at: " + myHeader.SR);
172 fs.Seek(myHeader.SR, SeekOrigin.Begin);
173 LSO_Struct.StateFrameBlock myStateFrameBlock = new LSO_Struct.StateFrameBlock();
174 myStateFrameBlock.StateCount = BitConverter.ToUInt32(br_read(4), 0);
175 if (myStateFrameBlock.StateCount > 0)
176 {
177 // Initialize array
178 myStateFrameBlock.StatePointer = new LSO_Struct.StatePointerBlock[myStateFrameBlock.StateCount];
179 for (int i = 0; i < myStateFrameBlock.StateCount; i++)
180 {
181 Common.SendToDebug("Reading STATE POINTER BLOCK " + (i + 1) + " at: " + fs.Position);
182 // Position is relative to state frame
183 myStateFrameBlock.StatePointer[i].Location = myHeader.SR + BitConverter.ToUInt32(br_read(4), 0);
184 myStateFrameBlock.StatePointer[i].EventMask = new System.Collections.BitArray(br_read(8));
185 Common.SendToDebug("Pointer: " + myStateFrameBlock.StatePointer[i].Location);
186 Common.SendToDebug("Total potential EventMask bits: " + myStateFrameBlock.StatePointer[i].EventMask.Count);
187
188 //// Read STATE BLOCK
189 //long CurPos = fs.Position;
190 //fs.Seek(CurPos, SeekOrigin.Begin);
191
192 }
193 }
194
195
196 // STATE BLOCK
197 // For each StateFrameBlock there is one StateBlock with multiple event handlers
198
199 if (myStateFrameBlock.StateCount > 0)
200 {
201 // Go through all State Frame Pointers found
202 for (int i = 0; i < myStateFrameBlock.StateCount; i++)
203 {
204
205 fs.Seek(myStateFrameBlock.StatePointer[i].Location, SeekOrigin.Begin);
206 Common.SendToDebug("Reading STATE BLOCK " + (i + 1) + " at: " + fs.Position);
207
208 // READ: STATE BLOCK HEADER
209 myStateFrameBlock.StatePointer[i].StateBlock = new LSO_Struct.StateBlock();
210 myStateFrameBlock.StatePointer[i].StateBlock.StartPos = (UInt32)fs.Position; // Note
211 myStateFrameBlock.StatePointer[i].StateBlock.HeaderSize = BitConverter.ToUInt32(br_read(4), 0);
212 myStateFrameBlock.StatePointer[i].StateBlock.Unknown = br_read(1)[0];
213 myStateFrameBlock.StatePointer[i].StateBlock.EndPos = (UInt32)fs.Position; // Note
214 Common.SendToDebug("State block Start Pos: " + myStateFrameBlock.StatePointer[i].StateBlock.StartPos);
215 Common.SendToDebug("State block Header Size: " + myStateFrameBlock.StatePointer[i].StateBlock.HeaderSize);
216 Common.SendToDebug("State block Header End Pos: " + myStateFrameBlock.StatePointer[i].StateBlock.EndPos);
217
218 // We need to count number of bits flagged in EventMask?
219
220
221 // for each bit in myStateFrameBlock.StatePointer[i].EventMask
222
223 // ADDING TO ALL RIGHT NOW, SHOULD LIMIT TO ONLY THE ONES IN USE
224 //TODO: Create event hooks
225 myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers = new LSO_Struct.StateBlockHandler[myStateFrameBlock.StatePointer[i].EventMask.Count - 1];
226 for (int ii = 0; ii < myStateFrameBlock.StatePointer[i].EventMask.Count - 1; ii++)
227 {
228
229 if (myStateFrameBlock.StatePointer[i].EventMask.Get(ii) == true)
230 {
231 // We got an event
232 // READ: STATE BLOCK HANDLER
233 Common.SendToDebug("Reading STATE BLOCK " + (i + 1) + " HANDLER matching EVENT MASK " + ii + " (" + ((LSO_Enums.Event_Mask_Values)ii).ToString() + ") at: " + fs.Position);
234 myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer = myStateFrameBlock.StatePointer[i].StateBlock.EndPos + BitConverter.ToUInt32(br_read(4), 0);
235 myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CallFrameSize = BitConverter.ToUInt32(br_read(4), 0);
236 Common.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);
237 Common.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);
238 }
239 }
240 }
241 }
242
243
244
245
246 //// READ FUNCTION CODE CHUNKS
247 //// Functions + Function start pos (GFR)
248 //// TODO: Somehow be able to identify and reference this
249 //LSO_Struct.CodeChunk[] myFunctionCodeChunk;
250 //if (myFunctionBlock.FunctionCount > 0)
251 //{
252 // myFunctionCodeChunk = new LSO_Struct.CodeChunk[myFunctionBlock.FunctionCount];
253 // for (int i = 0; i < myFunctionBlock.FunctionCount; i++)
254 // {
255 // Common.SendToDebug("Reading Function Code Chunk " + i);
256 // myFunctionCodeChunk[i] = GetCodeChunk((UInt32)myFunctionBlock.CodeChunkPointer[i]);
257 // }
258
259 //}
260 // READ EVENT CODE CHUNKS
261 LSO_Struct.CodeChunk[] myEventCodeChunk;
262 if (myStateFrameBlock.StateCount > 0)
263 {
264 myEventCodeChunk = new LSO_Struct.CodeChunk[myStateFrameBlock.StateCount];
265 for (int i = 0; i < myStateFrameBlock.StateCount; i++)
266 {
267 // TODO: Somehow organize events and functions so they can be found again,
268 // two level search ain't no good
269 for (int ii = 0; ii < myStateFrameBlock.StatePointer[i].EventMask.Count - 1; ii++)
270 {
271
272
273 if (myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer > 0)
274 {
275 Common.SendToDebug("Reading Event Code Chunk state " + i + ", event " + (LSO_Enums.Event_Mask_Values)ii);
276
277
278 // Override a Method / Function
279 string eventname = i + "_event_" + (LSO_Enums.Event_Mask_Values)ii;
280 Common.SendToDebug("Event Name: " + eventname);
281 if (Common.IL_ProcessCodeChunks)
282 {
283 EventList.Add(eventname);
284
285 // JUMP TO CODE PROCESSOR
286 ProcessCodeChunk(myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer, typeBuilder, eventname);
287 }
288 }
289
290 }
291
292 }
293
294 }
295
296
297 // Close
298 br.Close();
299 fs.Close();
300
301 if (Common.IL_CreateFunctionList)
302 IL_INSERT_FUNCTIONLIST();
303
304 }
305
306 private LSO_Struct.HeapBlock GetHeap(UInt32 pos)
307 {
308 // HEAP BLOCK
309 // TODO:? Special read for strings/keys (null terminated) and lists (pointers to other HEAP entries)
310 Common.SendToDebug("Reading HEAP BLOCK at: " + pos);
311 fs.Seek(pos, SeekOrigin.Begin);
312
313 LSO_Struct.HeapBlock myHeapBlock = new LSO_Struct.HeapBlock();
314 myHeapBlock.DataBlockSize = BitConverter.ToUInt32(br_read(4), 0);
315 myHeapBlock.ObjectType = br_read(1)[0];
316 myHeapBlock.ReferenceCount = BitConverter.ToUInt16(br_read(2), 0);
317 myHeapBlock.Data = br_read(getObjectSize(myHeapBlock.ObjectType));
318
319 Common.SendToDebug("Heap Block Data Block Size: " + myHeapBlock.DataBlockSize);
320 Common.SendToDebug("Heap Block ObjectType: " + ((LSO_Enums.Variable_Type_Codes)myHeapBlock.ObjectType).ToString());
321 Common.SendToDebug("Heap Block Reference Count: " + myHeapBlock.ReferenceCount);
322
323 return myHeapBlock;
324 }
325 private byte[] br_read(int len)
326 {
327 if (len <= 0)
328 return null;
329
330 try
331 {
332 byte[] bytes = new byte[len];
333 for (int i = len - 1; i > -1; i--)
334 bytes[i] = br.ReadByte();
335 return bytes;
336 }
337 catch (Exception e)
338 {
339 Common.SendToDebug("Exception: " + e.ToString());
340 throw (e);
341 }
342 }
343 //private byte[] br_read_smallendian(int len)
344 //{
345 // byte[] bytes = new byte[len];
346 // br.Read(bytes,0, len);
347 // return bytes;
348 //}
349 private Type getLLObjectType(byte objectCode)
350 {
351 switch ((LSO_Enums.Variable_Type_Codes)objectCode)
352 {
353 case LSO_Enums.Variable_Type_Codes.Void: return typeof(void);
354 case LSO_Enums.Variable_Type_Codes.Integer: return typeof(UInt32);
355 case LSO_Enums.Variable_Type_Codes.Float: return typeof(float);
356 case LSO_Enums.Variable_Type_Codes.String: return typeof(string);
357 case LSO_Enums.Variable_Type_Codes.Key: return typeof(string);
358 case LSO_Enums.Variable_Type_Codes.Vector: return typeof(LSO_Enums.Vector);
359 case LSO_Enums.Variable_Type_Codes.Rotation: return typeof(LSO_Enums.Rotation);
360 case LSO_Enums.Variable_Type_Codes.List:
361 Common.SendToDebug("TODO: List datatype not implemented yet!");
362 return typeof(System.Collections.ArrayList);
363 default:
364 Common.SendToDebug("Lookup of LSL datatype " + objectCode + " to .Net datatype failed: Unknown LSL datatype. Defaulting to object.");
365 return typeof(object);
366 }
367 }
368 private int getObjectSize(byte ObjectType)
369 {
370 switch (ObjectType)
371 {
372 case 1:
373 case 2:
374 case 3:
375 case 4:
376 case 7:
377 return 4;
378 case 5:
379 return 12;
380 case 6:
381 return 16;
382 default:
383 return 0;
384 }
385 }
386 private string Read_String()
387 {
388 string ret = "";
389 byte reader = br_read(1)[0];
390 while (reader != 0x000)
391 {
392 ret += (char)reader;
393 reader = br_read(1)[0];
394 }
395 return ret;
396 }
397
398 /// <summary>
399 /// Reads a code chunk and creates IL
400 /// </summary>
401 /// <param name="pos">Absolute position in file. REMEMBER TO ADD myHeader.GFR!</param>
402 /// <param name="typeBuilder">TypeBuilder for assembly</param>
403 /// <param name="eventname">Name of event (function) to generate</param>
404 private void ProcessCodeChunk(UInt32 pos, TypeBuilder typeBuilder, string eventname)
405 {
406
407 LSO_Struct.CodeChunk myCodeChunk = new LSO_Struct.CodeChunk();
408
409 Common.SendToDebug("Reading Function Code Chunk at: " + pos);
410 fs.Seek(pos, SeekOrigin.Begin);
411 myCodeChunk.CodeChunkHeaderSize = BitConverter.ToUInt32(br_read(4), 0);
412 Common.SendToDebug("CodeChunk Header Size: " + myCodeChunk.CodeChunkHeaderSize);
413 // Read until null
414 myCodeChunk.Comment = Read_String();
415 Common.SendToDebug("Function comment: " + myCodeChunk.Comment);
416 myCodeChunk.ReturnType = br_read(1)[0];
417 Common.SendToDebug("Return type #" + myCodeChunk.ReturnType + ": " + (getLLObjectType(myCodeChunk.ReturnType).ToString()));
418
419 // TODO: How to determine number of codechunks -- does this method work?
420 myCodeChunk.CodeChunkArguments = new System.Collections.Generic.List<LSO_Struct.CodeChunkArgument>();
421 byte reader = br_read(1)[0];
422 reader = br_read(1)[0];
423
424 // NOTE ON CODE CHUNK ARGUMENTS
425 // This determins type definition
426 int ccount = 0;
427 while (reader != 0x000)
428 {
429 ccount++;
430 Common.SendToDebug("Reading Code Chunk Argument " + ccount);
431 LSO_Struct.CodeChunkArgument CCA = new LSO_Struct.CodeChunkArgument();
432 CCA.FunctionReturnType = reader;
433 reader = br_read(1)[0];
434 CCA.NullString = reader;
435 myCodeChunk.CodeChunkArguments.Add(CCA);
436 Common.SendToDebug("Code Chunk Argument " + ccount + " type: " + (LSO_Enums.Variable_Type_Codes)CCA.FunctionReturnType);
437 }
438 // Create string array
439 Type[] MethodArgs = new Type[myCodeChunk.CodeChunkArguments.Count];
440 for (int _ic = 0; _ic < myCodeChunk.CodeChunkArguments.Count; _ic++)
441 {
442 MethodArgs[_ic] = getLLObjectType(myCodeChunk.CodeChunkArguments[_ic].FunctionReturnType);
443 Common.SendToDebug("Method argument " + _ic + ": " + getLLObjectType(myCodeChunk.CodeChunkArguments[_ic].FunctionReturnType).ToString());
444 }
445 // End marker is 0x000
446 myCodeChunk.EndMarker = reader;
447
448
449 //
450 // Emit: START OF METHOD (FUNCTION)
451 //
452
453 Common.SendToDebug("CLR:" + eventname + ":MethodBuilder methodBuilder = typeBuilder.DefineMethod...");
454 MethodBuilder methodBuilder = typeBuilder.DefineMethod(eventname,
455 MethodAttributes.Public,
456 typeof(void),
457 MethodArgs);
458 //typeof(void), //getLLObjectType(myCodeChunk.ReturnType),
459 // new Type[] { typeof(object) }, //);
460
461 //Common.SendToDebug("CLR:" + eventname + ":typeBuilder.DefineMethodOverride(methodBuilder...");
462 //typeBuilder.DefineMethodOverride(methodBuilder,
463 // typeof(LSL_CLRInterface.LSLScript).GetMethod(eventname));
464
465 // Create the IL generator
466
467 Common.SendToDebug("CLR:" + eventname + ":ILGenerator il = methodBuilder.GetILGenerator();");
468 ILGenerator il = methodBuilder.GetILGenerator();
469
470
471 if (Common.IL_UseTryCatch)
472 IL_INSERT_TRY(il, eventname);
473
474
475
476 // Push Console.WriteLine command to stack ... Console.WriteLine("Hello World!");
477 //Common.SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call...");
478 //il.Emit(OpCodes.Call, typeof(Console).GetMethod
479 // ("WriteLine", new Type[] { typeof(string) }));
480
481 //Common.SendToDebug("STARTUP: il.Emit(OpCodes.Ldc_I4_S, 0);");
482
483 //il.Emit(OpCodes.Ldc_I4_S, 0);
484 for (int _ic = 0; _ic < myCodeChunk.CodeChunkArguments.Count; _ic++)
485 {
486 Common.SendToDebug("PARAMS: il.Emit(OpCodes.Ldarg, " + _ic + ");");
487 il.Emit(OpCodes.Ldarg, _ic);
488 }
489
490
491
492 //
493 // CALLING OPCODE PROCESSOR, one command at the time TO GENERATE IL
494 //
495 bool FoundRet = false;
496 while (FoundRet == false)
497 {
498 FoundRet = LSL_PROCESS_OPCODE(il);
499 }
500
501
502 if (Common.IL_UseTryCatch)
503 IL_INSERT_END_TRY(il, eventname);
504
505 // Emit: RETURN FROM METHOD
506 il.Emit(OpCodes.Ret);
507
508 return;
509
510 }
511
512 private void IL_INSERT_FUNCTIONLIST()
513 {
514
515 Common.SendToDebug("Creating function list");
516
517
518 string eventname = "GetFunctions";
519
520 Common.SendToDebug("Creating IL " + eventname);
521 // Define a private String field.
522 //FieldBuilder myField = myTypeBuilder.DefineField("EventList", typeof(String[]), FieldAttributes.Public);
523
524
525 //FieldBuilder mem = typeBuilder.DefineField("mem", typeof(Array), FieldAttributes.Private);
526
527
528
529 MethodBuilder methodBuilder = typeBuilder.DefineMethod(eventname,
530 MethodAttributes.Public,
531 typeof(string[]),
532 null);
533
534 //typeBuilder.DefineMethodOverride(methodBuilder,
535 // typeof(LSL_CLRInterface.LSLScript).GetMethod(eventname));
536
537 ILGenerator il = methodBuilder.GetILGenerator();
538
539
540
541
542 // IL_INSERT_TRY(il, eventname);
543
544 // // Push string to stack
545 // il.Emit(OpCodes.Ldstr, "Inside " + eventname);
546
547 //// Push Console.WriteLine command to stack ... Console.WriteLine("Hello World!");
548 //il.Emit(OpCodes.Call, typeof(Console).GetMethod
549 // ("WriteLine", new Type[] { typeof(string) }));
550
551 //initIL.Emit(OpCodes.Newobj, typeof(string[]));
552
553 //string[] MyArray = new string[2] { "TestItem1" , "TestItem2" };
554
555 il.DeclareLocal(typeof(string[]));
556
557 //il.Emit(OpCodes.Ldarg_0);
558 il.Emit(OpCodes.Ldc_I4, EventList.Count); // Specify array length
559 il.Emit(OpCodes.Newarr, typeof(String)); // create new string array
560 il.Emit(OpCodes.Stloc_0); // Store array as local variable 0 in stack
561
562 for (int lv = 0; lv < EventList.Count; lv++)
563 {
564 il.Emit(OpCodes.Ldloc_0); // Load local variable 0 onto stack
565 il.Emit(OpCodes.Ldc_I4, lv); // Push index position
566 il.Emit(OpCodes.Ldstr, EventList[lv]); // Push value
567 il.Emit(OpCodes.Stelem_Ref); // Perform array[index] = value
568 }
569
570
571
572 // IL_INSERT_END_TRY(il, eventname);
573
574 il.Emit(OpCodes.Ldloc_0); // Load local variable 0 onto stack
575 il.Emit(OpCodes.Ret); // Return
576
577 }
578
579
580 private void IL_INSERT_TRY(ILGenerator il, string eventname)
581 {
582 /*
583 * CLR TRY
584 */
585 //Common.SendToDebug("CLR:" + eventname + ":il.BeginExceptionBlock()");
586 il.BeginExceptionBlock();
587
588 // Push "Hello World!" string to stack
589 //Common.SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Ldstr...");
590 il.Emit(OpCodes.Ldstr, "Starting CLR dynamic execution of: " + eventname);
591
592 }
593
594 private void IL_INSERT_END_TRY(ILGenerator il, string eventname)
595 {
596 /*
597 * CATCH
598 */
599 Common.SendToDebug("CLR:" + eventname + ":il.BeginCatchBlock(typeof(Exception));");
600 il.BeginCatchBlock(typeof(Exception));
601
602 // Push "Hello World!" string to stack
603 Common.SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Ldstr...");
604 il.Emit(OpCodes.Ldstr, "Execption executing dynamic CLR function " + eventname + ": ");
605
606 //call void [mscorlib]System.Console::WriteLine(string)
607 Common.SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call...");
608 il.Emit(OpCodes.Call, typeof(Console).GetMethod
609 ("Write", new Type[] { typeof(string) }));
610
611 //callvirt instance string [mscorlib]System.Exception::get_Message()
612 Common.SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Callvirt...");
613 il.Emit(OpCodes.Callvirt, typeof(Exception).GetMethod
614 ("get_Message"));
615
616 //call void [mscorlib]System.Console::WriteLine(string)
617 Common.SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call...");
618 il.Emit(OpCodes.Call, typeof(Console).GetMethod
619 ("WriteLine", new Type[] { typeof(string) }));
620
621 /*
622 * CLR END TRY
623 */
624 //Common.SendToDebug("CLR:" + eventname + ":il.EndExceptionBlock();");
625 il.EndExceptionBlock();
626 }
627
628 }
629}