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