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