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