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