diff options
Diffstat (limited to '')
5 files changed, 1389 insertions, 0 deletions
diff --git a/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/Engine.cs b/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/Engine.cs new file mode 100644 index 0000000..814f15a --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/Engine.cs | |||
@@ -0,0 +1,140 @@ | |||
1 | using System; | ||
2 | using System.Reflection; | ||
3 | using System.Reflection.Emit; | ||
4 | using System.Threading; | ||
5 | |||
6 | using OpenSim.Region.Environment.Scripting; | ||
7 | |||
8 | namespace OpenSim.ScriptEngines.LSL | ||
9 | { | ||
10 | |||
11 | |||
12 | public class Engine | ||
13 | { | ||
14 | public void Start(ScriptInfo WorldAPI) | ||
15 | { | ||
16 | |||
17 | |||
18 | |||
19 | // Create Assembly Name | ||
20 | AssemblyName asmName = new AssemblyName(); | ||
21 | asmName.Name = "TestAssembly"; | ||
22 | |||
23 | // Create Assembly | ||
24 | AssemblyBuilder asmBuilder = | ||
25 | Thread.GetDomain().DefineDynamicAssembly | ||
26 | (asmName, AssemblyBuilderAccess.RunAndSave); | ||
27 | |||
28 | // Create a module (and save to disk) | ||
29 | ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule | ||
30 | (asmName.Name, asmName.Name + ".dll"); | ||
31 | |||
32 | // Create a Class (/Type) | ||
33 | TypeBuilder typeBuilder = modBuilder.DefineType( | ||
34 | "MyClass", | ||
35 | TypeAttributes.Public, | ||
36 | typeof(object), | ||
37 | new Type[] { typeof(LSL_CLRInterface.LSLScript) }); | ||
38 | |||
39 | |||
40 | |||
41 | /* | ||
42 | * Generate the IL itself | ||
43 | */ | ||
44 | |||
45 | GenerateIL(WorldAPI, typeBuilder); | ||
46 | |||
47 | |||
48 | /* | ||
49 | * Done generating, create a type and run it. | ||
50 | */ | ||
51 | |||
52 | // Create type object for the class (after defining fields and methods) | ||
53 | Type type = typeBuilder.CreateType(); | ||
54 | |||
55 | asmBuilder.Save("TestAssembly.dll"); | ||
56 | |||
57 | // Create an instance we can play with | ||
58 | //LSLScript hello = (LSLScript)Activator.CreateInstance(type); | ||
59 | LSL_CLRInterface.LSLScript MyScript = (LSL_CLRInterface.LSLScript)Activator.CreateInstance(type); | ||
60 | |||
61 | // Play with it | ||
62 | MyScript.event_state_entry("Test"); | ||
63 | } | ||
64 | |||
65 | private void GenerateIL(ScriptInfo WorldAPI, TypeBuilder typeBuilder) | ||
66 | { | ||
67 | |||
68 | |||
69 | // For debug | ||
70 | LSO_Parser LSOP = new LSO_Parser(); | ||
71 | LSOP.ParseFile("LSO\\CloseToDefault.lso", WorldAPI, ref typeBuilder); | ||
72 | return; | ||
73 | |||
74 | |||
75 | // Override a Method / Function | ||
76 | MethodBuilder methodBuilder = typeBuilder.DefineMethod("event_state_entry", | ||
77 | MethodAttributes.Private | MethodAttributes.Virtual, | ||
78 | typeof(void), | ||
79 | new Type[] { typeof(object) }); | ||
80 | |||
81 | typeBuilder.DefineMethodOverride(methodBuilder, | ||
82 | typeof(LSL_CLRInterface.LSLScript).GetMethod("event_state_entry")); | ||
83 | |||
84 | // Create the IL generator | ||
85 | ILGenerator il = methodBuilder.GetILGenerator(); | ||
86 | |||
87 | |||
88 | /* | ||
89 | * TRY | ||
90 | */ | ||
91 | il.BeginExceptionBlock(); | ||
92 | |||
93 | // Push "Hello World!" string to stack | ||
94 | il.Emit(OpCodes.Ldstr, "Hello World!"); | ||
95 | |||
96 | // Push Console.WriteLine command to stack ... Console.WriteLine("Hello World!"); | ||
97 | il.Emit(OpCodes.Call, typeof(Console).GetMethod | ||
98 | ("WriteLine", new Type[] { typeof(string) })); | ||
99 | |||
100 | //il.EmitCall(OpCodes.Callvirt | ||
101 | //il.Emit(OpCodes.Call, typeof(WorldAPI).GetMethod | ||
102 | //("TestFunction")); | ||
103 | |||
104 | |||
105 | //il.ThrowException(typeof(NotSupportedException)); | ||
106 | |||
107 | |||
108 | /* | ||
109 | * CATCH | ||
110 | */ | ||
111 | il.BeginCatchBlock(typeof(Exception)); | ||
112 | |||
113 | // Push "Hello World!" string to stack | ||
114 | il.Emit(OpCodes.Ldstr, "Something went wrong: "); | ||
115 | |||
116 | //call void [mscorlib]System.Console::WriteLine(string) | ||
117 | il.Emit(OpCodes.Call, typeof(Console).GetMethod | ||
118 | ("Write", new Type[] { typeof(string) })); | ||
119 | |||
120 | //callvirt instance string [mscorlib]System.Exception::get_Message() | ||
121 | il.Emit(OpCodes.Callvirt, typeof(Exception).GetMethod | ||
122 | ("get_Message")); | ||
123 | |||
124 | //call void [mscorlib]System.Console::WriteLine(string) | ||
125 | il.Emit(OpCodes.Call, typeof(Console).GetMethod | ||
126 | ("WriteLine", new Type[] { typeof(string) })); | ||
127 | |||
128 | /* | ||
129 | * END TRY | ||
130 | */ | ||
131 | il.EndExceptionBlock(); | ||
132 | |||
133 | |||
134 | // Push "Return from current method, with return value if present" to stack | ||
135 | il.Emit(OpCodes.Ret); | ||
136 | |||
137 | |||
138 | } | ||
139 | } | ||
140 | } | ||
diff --git a/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSL_CLRInterface.cs b/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSL_CLRInterface.cs new file mode 100644 index 0000000..dc612ff --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSL_CLRInterface.cs | |||
@@ -0,0 +1,51 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | |||
5 | namespace OpenSim.ScriptEngines.LSL | ||
6 | { | ||
7 | public class LSL_CLRInterface | ||
8 | { | ||
9 | public interface LSLScript | ||
10 | { | ||
11 | //public virtual void Run(object arg) | ||
12 | //{ | ||
13 | //} | ||
14 | //void Run(object arg); | ||
15 | |||
16 | void event_state_entry(object arg); | ||
17 | //void event_state_exit(); | ||
18 | void event_touch_start(object arg); | ||
19 | //void event_touch(); | ||
20 | //void event_touch_end(); | ||
21 | //void event_collision_start(); | ||
22 | //void event_collision(); | ||
23 | //void event_collision_end(); | ||
24 | //void event_land_collision_start(); | ||
25 | //void event_land_collision(); | ||
26 | //void event_land_collision_end(); | ||
27 | //void event_timer(); | ||
28 | //void event_listen(); | ||
29 | //void event_on_rez(); | ||
30 | //void event_sensor(); | ||
31 | //void event_no_sensor(); | ||
32 | //void event_control(); | ||
33 | //void event_money(); | ||
34 | //void event_email(); | ||
35 | //void event_at_target(); | ||
36 | //void event_not_at_target(); | ||
37 | //void event_at_rot_target(); | ||
38 | //void event_not_at_rot_target(); | ||
39 | //void event_run_time_permissions(); | ||
40 | //void event_changed(); | ||
41 | //void event_attach(); | ||
42 | //void event_dataserver(); | ||
43 | //void event_link_message(); | ||
44 | //void event_moving_start(); | ||
45 | //void event_moving_end(); | ||
46 | //void event_object_rez(); | ||
47 | //void event_remote_data(); | ||
48 | //void event_http_response(); | ||
49 | } | ||
50 | } | ||
51 | } | ||
diff --git a/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Enums.cs b/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Enums.cs new file mode 100644 index 0000000..edeccdd --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Enums.cs | |||
@@ -0,0 +1,485 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | |||
5 | namespace OpenSim.ScriptEngines.LSL | ||
6 | { | ||
7 | static class LSO_Enums | ||
8 | { | ||
9 | |||
10 | public enum Variable_Type_Codes | ||
11 | { | ||
12 | Void = 0, | ||
13 | Integer = 1, | ||
14 | Float = 2, | ||
15 | String = 3, | ||
16 | Key = 4, | ||
17 | Vector = 5, | ||
18 | Rotation = 6, | ||
19 | List = 7 | ||
20 | } | ||
21 | public enum Event_Mask_Values | ||
22 | { | ||
23 | state_entry = 0, | ||
24 | state_exit = 1, | ||
25 | touch_start = 2, | ||
26 | touch = 3, | ||
27 | touch_end = 4, | ||
28 | collision_start = 5, | ||
29 | collision = 6, | ||
30 | collision_end = 7, | ||
31 | land_collision_start = 8, | ||
32 | land_collision = 9, | ||
33 | land_collision_end = 10, | ||
34 | timer = 11, | ||
35 | listen = 12, | ||
36 | on_rez = 13, | ||
37 | sensor = 14, | ||
38 | no_sensor = 15, | ||
39 | control = 16, | ||
40 | money = 17, | ||
41 | email = 18, | ||
42 | at_target = 19, | ||
43 | not_at_target = 20, | ||
44 | at_rot_target = 21, | ||
45 | not_at_rot_target = 22, | ||
46 | run_time_permissions = 23, | ||
47 | changed = 24, | ||
48 | attach = 25, | ||
49 | dataserver = 26, | ||
50 | link_message = 27, | ||
51 | moving_start = 28, | ||
52 | moving_end = 29, | ||
53 | object_rez = 30, | ||
54 | remote_data = 31, | ||
55 | http_response = 32 | ||
56 | } | ||
57 | public enum Operation_Table | ||
58 | { | ||
59 | NOOP = 0x0, | ||
60 | POP = 0x1, | ||
61 | POPS = 0x2, | ||
62 | POPL = 0x3, | ||
63 | POPV = 0x4, | ||
64 | POPQ = 0x5, | ||
65 | POPARG = 0x6, | ||
66 | POPIP = 0x7, | ||
67 | POPBP = 0x8, | ||
68 | POPSP = 0x9, | ||
69 | POPSLR = 0xa, | ||
70 | DUP = 0x20, | ||
71 | DUPS = 0x21, | ||
72 | DUPL = 0x22, | ||
73 | DUPV = 0x23, | ||
74 | DUPQ = 0x24, | ||
75 | STORE = 0x30, | ||
76 | STORES = 0x31, | ||
77 | STOREL = 0x32, | ||
78 | STOREV = 0x33, | ||
79 | STOREQ = 0x34, | ||
80 | STOREG = 0x35, | ||
81 | STOREGS = 0x36, | ||
82 | STOREGL = 0x37, | ||
83 | STOREGV = 0x38, | ||
84 | STOREGQ = 0x39, | ||
85 | LOADP = 0x3a, | ||
86 | LOADSP = 0x3b, | ||
87 | LOADLP = 0x3c, | ||
88 | LOADVP = 0x3d, | ||
89 | LOADQP = 0x3e, | ||
90 | LOADGP = 0x3f, | ||
91 | LOADGSP = 0x40, | ||
92 | LOADGLP = 0x41, | ||
93 | LOADGVP = 0x42, | ||
94 | LOADGQP = 0x43, | ||
95 | PUSH = 0x50, | ||
96 | PUSHS = 0x51, | ||
97 | PUSHL = 0x52, | ||
98 | PUSHV = 0x53, | ||
99 | PUSHQ = 0x54, | ||
100 | PUSHG = 0x55, | ||
101 | PUSHGS = 0x56, | ||
102 | PUSHGL = 0x57, | ||
103 | PUSHGV = 0x58, | ||
104 | PUSHGQ = 0x59, | ||
105 | PUSHIP = 0x5a, | ||
106 | PUSHBP = 0x5b, | ||
107 | PUSHSP = 0x5c, | ||
108 | PUSHARGB = 0x5d, | ||
109 | PUSHARGI = 0x5e, | ||
110 | PUSHARGF = 0x5f, | ||
111 | PUSHARGS = 0x60, | ||
112 | PUSHARGV = 0x61, | ||
113 | PUSHARGQ = 0x62, | ||
114 | PUSHE = 0x63, | ||
115 | PUSHEV = 0x64, | ||
116 | PUSHEQ = 0x65, | ||
117 | PUSHARGE = 0x66, | ||
118 | ADD = 0x70, | ||
119 | SUB = 0x71, | ||
120 | MUL = 0x72, | ||
121 | DIV = 0x73, | ||
122 | MOD = 0x74, | ||
123 | EQ = 0x75, | ||
124 | NEQ = 0x76, | ||
125 | LEQ = 0x77, | ||
126 | GEQ = 0x78, | ||
127 | LESS = 0x79, | ||
128 | GREATER = 0x7a, | ||
129 | BITAND = 0x7b, | ||
130 | BITOR = 0x7c, | ||
131 | BITXOR = 0x7d, | ||
132 | BOOLAND = 0x7e, | ||
133 | BOOLOR = 0x7f, | ||
134 | NEG = 0x80, | ||
135 | BITNOT = 0x81, | ||
136 | BOOLNOT = 0x82, | ||
137 | JUMP = 0x90, | ||
138 | JUMPIF = 0x91, | ||
139 | JUMPNIF = 0x92, | ||
140 | STATE = 0x93, | ||
141 | CALL = 0x94, | ||
142 | RETURN = 0x95, | ||
143 | CAST = 0xa0, | ||
144 | STACKTOS = 0xb0, | ||
145 | STACKTOL = 0xb1, | ||
146 | PRINT = 0xc0, | ||
147 | CALLLIB = 0xd0, | ||
148 | CALLLIB_TWO_BYTE = 0xd1, | ||
149 | SHL = 0xe0, | ||
150 | SHR = 0xe1 | ||
151 | } | ||
152 | public enum BuiltIn_Functions | ||
153 | { | ||
154 | llSin = 0, | ||
155 | llCos = 1, | ||
156 | llTan = 2, | ||
157 | llAtan2 = 3, | ||
158 | llSqrt = 4, | ||
159 | llPow = 5, | ||
160 | llAbs = 6, | ||
161 | llFabs = 7, | ||
162 | llFrand = 8, | ||
163 | llFloor = 9, | ||
164 | llCeil = 10, | ||
165 | llRound = 11, | ||
166 | llVecMag = 12, | ||
167 | llVecNorm = 13, | ||
168 | llVecDist = 14, | ||
169 | llRot2Euler = 15, | ||
170 | llEuler2Rot = 16, | ||
171 | llAxes2Rot = 17, | ||
172 | llRot2Fwd = 18, | ||
173 | llRot2Left = 19, | ||
174 | llRot2Up = 20, | ||
175 | llRotBetween = 21, | ||
176 | llWhisper = 22, | ||
177 | llSay = 23, | ||
178 | llShout = 24, | ||
179 | llListen = 25, | ||
180 | llListenControl = 26, | ||
181 | llListenRemove = 27, | ||
182 | llSensor = 28, | ||
183 | llSensorRepeat = 29, | ||
184 | llSensorRemove = 30, | ||
185 | llDetectedName = 31, | ||
186 | llDetectedKey = 32, | ||
187 | llDetectedOwner = 33, | ||
188 | llDetectedType = 34, | ||
189 | llDetectedPos = 35, | ||
190 | llDetectedVel = 36, | ||
191 | llDetectedGrab = 37, | ||
192 | llDetectedRot = 38, | ||
193 | llDetectedGroup = 39, | ||
194 | llDetectedLinkNumber = 40, | ||
195 | llDie = 41, | ||
196 | llGround = 42, | ||
197 | llCloud = 43, | ||
198 | llWind = 44, | ||
199 | llSetStatus = 45, | ||
200 | llGetStatus = 46, | ||
201 | llSetScale = 47, | ||
202 | llGetScale = 48, | ||
203 | llSetColor = 49, | ||
204 | llGetAlpha = 50, | ||
205 | llSetAlpha = 51, | ||
206 | llGetColor = 52, | ||
207 | llSetTexture = 53, | ||
208 | llScaleTexture = 54, | ||
209 | llOffsetTexture = 55, | ||
210 | llRotateTexture = 56, | ||
211 | llGetTexture = 57, | ||
212 | llSetPos = 58, | ||
213 | llGetPos = 59, | ||
214 | llGetLocalPos = 60, | ||
215 | llSetRot = 61, | ||
216 | llGetRot = 62, | ||
217 | llGetLocalRot = 63, | ||
218 | llSetForce = 64, | ||
219 | llGetForce = 65, | ||
220 | llTarget = 66, | ||
221 | llTargetRemove = 67, | ||
222 | llRotTarget = 68, | ||
223 | llRotTargetRemove = 69, | ||
224 | llMoveToTarget = 70, | ||
225 | llStopMoveToTarget = 71, | ||
226 | llApplyImpulse = 72, | ||
227 | llApplyRotationalImpulse = 73, | ||
228 | llSetTorque = 74, | ||
229 | llGetTorque = 75, | ||
230 | llSetForceAndTorque = 76, | ||
231 | llGetVel = 77, | ||
232 | llGetAccel = 78, | ||
233 | llGetOmega = 79, | ||
234 | llGetTimeOfDay = 80, | ||
235 | llGetWallclock = 81, | ||
236 | llGetTime = 82, | ||
237 | llResetTime = 83, | ||
238 | llGetAndResetTime = 84, | ||
239 | llSound = 85, | ||
240 | llPlaySound = 86, | ||
241 | llLoopSound = 87, | ||
242 | llLoopSoundMaster = 88, | ||
243 | llLoopSoundSlave = 89, | ||
244 | llPlaySoundSlave = 90, | ||
245 | llTriggerSound = 91, | ||
246 | llStopSound = 92, | ||
247 | llPreloadSound = 93, | ||
248 | llGetSubString = 94, | ||
249 | llDeleteSubString = 95, | ||
250 | llInsertString = 96, | ||
251 | llToUpper = 97, | ||
252 | llToLower = 98, | ||
253 | llGiveMoney = 99, | ||
254 | llMakeExplosion = 100, | ||
255 | llMakeFountain = 101, | ||
256 | llMakeSmoke = 102, | ||
257 | llMakeFire = 103, | ||
258 | llRezObject = 104, | ||
259 | llLookAt = 105, | ||
260 | llStopLookAt = 106, | ||
261 | llSetTimerEvent = 107, | ||
262 | llSleep = 108, | ||
263 | llGetMass = 109, | ||
264 | llCollisionFilter = 110, | ||
265 | llTakeControls = 111, | ||
266 | llReleaseControls = 112, | ||
267 | llAttachToAvatar = 113, | ||
268 | llDetachFromAvatar = 114, | ||
269 | llTakeCamera = 115, | ||
270 | llReleaseCamera = 116, | ||
271 | llGetOwner = 117, | ||
272 | llInstantMessage = 118, | ||
273 | llEmail = 119, | ||
274 | llGetNextEmail = 120, | ||
275 | llGetKey = 121, | ||
276 | llSetBuoyancy = 122, | ||
277 | llSetHoverHeight = 123, | ||
278 | llStopHover = 124, | ||
279 | llMinEventDelay = 125, | ||
280 | llSoundPreload = 126, | ||
281 | llRotLookAt = 127, | ||
282 | llStringLength = 128, | ||
283 | llStartAnimation = 129, | ||
284 | llStopAnimation = 130, | ||
285 | llPointAt = 131, | ||
286 | llStopPointAt = 132, | ||
287 | llTargetOmega = 133, | ||
288 | llGetStartParameter = 134, | ||
289 | llGodLikeRezObject = 135, | ||
290 | llRequestPermissions = 136, | ||
291 | llGetPermissionsKey = 137, | ||
292 | llGetPermissions = 138, | ||
293 | llGetLinkNumber = 139, | ||
294 | llSetLinkColor = 140, | ||
295 | llCreateLink = 141, | ||
296 | llBreakLink = 142, | ||
297 | llBreakAllLinks = 143, | ||
298 | llGetLinkKey = 144, | ||
299 | llGetLinkName = 145, | ||
300 | llGetInventoryNumber = 146, | ||
301 | llGetInventoryName = 147, | ||
302 | llSetScriptState = 148, | ||
303 | llGetEnergy = 149, | ||
304 | llGiveInventory = 150, | ||
305 | llRemoveInventory = 151, | ||
306 | llSetText = 152, | ||
307 | llWater = 153, | ||
308 | llPassTouches = 154, | ||
309 | llRequestAgentData = 155, | ||
310 | llRequestInventoryData = 156, | ||
311 | llSetDamage = 157, | ||
312 | llTeleportAgentHome = 158, | ||
313 | llModifyLand = 159, | ||
314 | llCollisionSound = 160, | ||
315 | llCollisionSprite = 161, | ||
316 | llGetAnimation = 162, | ||
317 | llResetScript = 163, | ||
318 | llMessageLinked = 164, | ||
319 | llPushObject = 165, | ||
320 | llPassCollisions = 166, | ||
321 | llGetScriptName = 167, | ||
322 | llGetNumberOfSides = 168, | ||
323 | llAxisAngle2Rot = 169, | ||
324 | llRot2Axis = 170, | ||
325 | llRot2Angle = 171, | ||
326 | llAcos = 172, | ||
327 | llAsin = 173, | ||
328 | llAngleBetween = 174, | ||
329 | llGetInventoryKey = 175, | ||
330 | llAllowInventoryDrop = 176, | ||
331 | llGetSunDirection = 177, | ||
332 | llGetTextureOffset = 178, | ||
333 | llGetTextureScale = 179, | ||
334 | llGetTextureRot = 180, | ||
335 | llSubStringIndex = 181, | ||
336 | llGetOwnerKey = 182, | ||
337 | llGetCenterOfMass = 183, | ||
338 | llListSort = 184, | ||
339 | llGetListLength = 185, | ||
340 | llList2Integer = 186, | ||
341 | llList2Float = 187, | ||
342 | llList2String = 188, | ||
343 | llList2Key = 189, | ||
344 | llList2Vector = 190, | ||
345 | llList2Rot = 191, | ||
346 | llList2List = 192, | ||
347 | llDeleteSubList = 193, | ||
348 | llGetListEntryType = 194, | ||
349 | llList2CSV = 195, | ||
350 | llCSV2List = 196, | ||
351 | llListRandomize = 197, | ||
352 | llList2ListStrided = 198, | ||
353 | llGetRegionCorner = 199, | ||
354 | llListInsertList = 200, | ||
355 | llListFindList = 201, | ||
356 | llGetObjectName = 202, | ||
357 | llSetObjectName = 203, | ||
358 | llGetDate = 204, | ||
359 | llEdgeOfWorld = 205, | ||
360 | llGetAgentInfo = 206, | ||
361 | llAdjustSoundVolume = 207, | ||
362 | llSetSoundQueueing = 208, | ||
363 | llSetSoundRadius = 209, | ||
364 | llKey2Name = 210, | ||
365 | llSetTextureAnim = 211, | ||
366 | llTriggerSoundLimited = 212, | ||
367 | llEjectFromLand = 213, | ||
368 | llParseString2List = 214, | ||
369 | llOverMyLand = 215, | ||
370 | llGetLandOwnerAt = 216, | ||
371 | llGetNotecardLine = 217, | ||
372 | llGetAgentSize = 218, | ||
373 | llSameGroup = 219, | ||
374 | llUnSit = 220, | ||
375 | llGroundSlope = 221, | ||
376 | llGroundNormal = 222, | ||
377 | llGroundContour = 223, | ||
378 | llGetAttached = 224, | ||
379 | llGetFreeMemory = 225, | ||
380 | llGetRegionName = 226, | ||
381 | llGetRegionTimeDilation = 227, | ||
382 | llGetRegionFPS = 228, | ||
383 | llParticleSystem = 229, | ||
384 | llGroundRepel = 230, | ||
385 | llGiveInventoryList = 231, | ||
386 | llSetVehicleType = 232, | ||
387 | llSetVehicleFloatParam = 233, | ||
388 | llSetVehicleVectorParam = 234, | ||
389 | llSetVehicleRotationParam = 235, | ||
390 | llSetVehicleFlags = 236, | ||
391 | llRemoveVehicleFlags = 237, | ||
392 | llSitTarget = 238, | ||
393 | llAvatarOnSitTarget = 239, | ||
394 | llAddToLandPassList = 240, | ||
395 | llSetTouchText = 241, | ||
396 | llSetSitText = 242, | ||
397 | llSetCameraEyeOffset = 243, | ||
398 | llSetCameraAtOffset = 244, | ||
399 | llDumpList2String = 245, | ||
400 | llScriptDanger = 246, | ||
401 | llDialog = 247, | ||
402 | llVolumeDetect = 248, | ||
403 | llResetOtherScript = 249, | ||
404 | llGetScriptState = 250, | ||
405 | llRemoteLoadScript = 251, | ||
406 | llSetRemoteScriptAccessPin = 252, | ||
407 | llRemoteLoadScriptPin = 253, | ||
408 | llOpenRemoteDataChannel = 254, | ||
409 | llSendRemoteData = 255, | ||
410 | llRemoteDataReply = 256, | ||
411 | llCloseRemoteDataChannel = 257, | ||
412 | llMD5String = 258, | ||
413 | llSetPrimitiveParams = 259, | ||
414 | llStringToBase64 = 260, | ||
415 | llBase64ToString = 261, | ||
416 | llXorBase64Strings = 262, | ||
417 | llRemoteDataSetRegion = 263, | ||
418 | llLog10 = 264, | ||
419 | llLog = 265, | ||
420 | llGetAnimationList = 266, | ||
421 | llSetParcelMusicURL = 267, | ||
422 | llGetRootPosition = 268, | ||
423 | llGetRootRotation = 269, | ||
424 | llGetObjectDesc = 270, | ||
425 | llSetObjectDesc = 271, | ||
426 | llGetCreator = 272, | ||
427 | llGetTimestamp = 273, | ||
428 | llSetLinkAlpha = 274, | ||
429 | llGetNumberOfPrims = 275, | ||
430 | llGetNumberOfNotecardLines = 276, | ||
431 | llGetBoundingBox = 277, | ||
432 | llGetGeometricCenter = 278, | ||
433 | llGetPrimitiveParams = 279, | ||
434 | llIntegerToBase64 = 280, | ||
435 | llBase64ToInteger = 281, | ||
436 | llGetGMTclock = 282, | ||
437 | llGetSimulatorHostname = 283, | ||
438 | llSetLocalRot = 284, | ||
439 | llParseStringKeepNulls = 285, | ||
440 | llRezAtRoot = 286, | ||
441 | llGetObjectPermMask = 287, | ||
442 | llSetObjectPermMask = 288, | ||
443 | llGetInventoryPermMask = 289, | ||
444 | llSetInventoryPermMask = 290, | ||
445 | llGetInventoryCreator = 291, | ||
446 | llOwnerSay = 292, | ||
447 | llRequestSimulatorData = 293, | ||
448 | llForceMouselook = 294, | ||
449 | llGetObjectMass = 295, | ||
450 | llListReplaceList = 296, | ||
451 | llLoadURL = 297, | ||
452 | llParcelMediaCommandList = 298, | ||
453 | llParcelMediaQuery = 299, | ||
454 | llModPow = 300, | ||
455 | llGetInventoryType = 301, | ||
456 | llSetPayPrice = 302, | ||
457 | llGetCameraPos = 303, | ||
458 | llGetCameraRot = 304, | ||
459 | llSetPrimURL = 305, | ||
460 | llRefreshPrimURL = 306, | ||
461 | llEscapeURL = 307, | ||
462 | llUnescapeURL = 308, | ||
463 | llMapDestination = 309, | ||
464 | llAddToLandBanList = 310, | ||
465 | llRemoveFromLandPassList = 311, | ||
466 | llRemoveFromLandBanList = 312, | ||
467 | llSetCameraParams = 313, | ||
468 | llClearCameraParams = 314, | ||
469 | llListStatistics = 315, | ||
470 | llGetUnixTime = 316, | ||
471 | llGetParcelFlags = 317, | ||
472 | llGetRegionFlags = 318, | ||
473 | llXorBase64StringsCorrect = 319, | ||
474 | llHTTPRequest = 320, | ||
475 | llResetLandBanList = 321, | ||
476 | llResetLandPassList = 322, | ||
477 | llGetParcelPrimCount = 323, | ||
478 | llGetParcelPrimOwners = 324, | ||
479 | llGetObjectPrimCount = 325, | ||
480 | llGetParcelMaxPrims = 326, | ||
481 | llGetParcelDetails = 327 | ||
482 | } | ||
483 | |||
484 | } | ||
485 | } | ||
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 new file mode 100644 index 0000000..5f2e3c1 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Parser.cs | |||
@@ -0,0 +1,608 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | using System.IO; | ||
5 | using System.Reflection; | ||
6 | using System.Reflection.Emit; | ||
7 | using OpenSim.Region.Environment.Scripting; | ||
8 | |||
9 | namespace OpenSim.ScriptEngines.LSL | ||
10 | { | ||
11 | class LSO_Parser | ||
12 | { | ||
13 | private bool Debug = true; | ||
14 | private FileStream fs; | ||
15 | private BinaryReader br; | ||
16 | private LSO_Struct.Header myHeader; | ||
17 | |||
18 | private TypeBuilder typeBuilder; | ||
19 | private ScriptInfo WorldAPI; | ||
20 | |||
21 | /// <summary> | ||
22 | /// Parse LSO file. | ||
23 | /// Reads LSO ByteCode into memory structures. | ||
24 | /// TODO: What else does it do? | ||
25 | /// </summary> | ||
26 | /// <param name="FileName">FileName of LSO ByteCode file</param> | ||
27 | public void ParseFile(string FileName, ScriptInfo _WorldAPI, ref TypeBuilder _typeBuilder) | ||
28 | { | ||
29 | typeBuilder = _typeBuilder; | ||
30 | WorldAPI = _WorldAPI; | ||
31 | // Open | ||
32 | SendToDebug("Opening filename: " + FileName); | ||
33 | fs = File.Open(FileName, FileMode.Open, FileAccess.Read, FileShare.Read); | ||
34 | br = new BinaryReader(fs, Encoding.BigEndianUnicode); | ||
35 | |||
36 | |||
37 | // The LSO Format consist of 6 major blocks: header, statics, functions, states, heap, and stack. | ||
38 | |||
39 | |||
40 | // HEADER BLOCK | ||
41 | SendToDebug("Reading HEADER BLOCK at: 0"); | ||
42 | fs.Seek(0, SeekOrigin.Begin); | ||
43 | myHeader = new LSO_Struct.Header(); | ||
44 | myHeader.TM = BitConverter.ToUInt32(br_read(4), 0); | ||
45 | myHeader.IP = BitConverter.ToUInt32(br_read(4), 0); | ||
46 | myHeader.VN = BitConverter.ToUInt32(br_read(4), 0); | ||
47 | myHeader.BP = BitConverter.ToUInt32(br_read(4), 0); | ||
48 | myHeader.SP = BitConverter.ToUInt32(br_read(4), 0); | ||
49 | myHeader.HR = BitConverter.ToUInt32(br_read(4), 0); | ||
50 | myHeader.HP = BitConverter.ToUInt32(br_read(4), 0); | ||
51 | myHeader.CS = BitConverter.ToUInt32(br_read(4), 0); | ||
52 | myHeader.NS = BitConverter.ToUInt32(br_read(4), 0); | ||
53 | myHeader.CE = BitConverter.ToUInt32(br_read(4), 0); | ||
54 | myHeader.IE = BitConverter.ToUInt32(br_read(4), 0); | ||
55 | myHeader.ER = BitConverter.ToUInt32(br_read(4), 0); | ||
56 | myHeader.FR = BitConverter.ToUInt32(br_read(4), 0); | ||
57 | myHeader.SLR = BitConverter.ToUInt32(br_read(4), 0); | ||
58 | myHeader.GVR = BitConverter.ToUInt32(br_read(4), 0); | ||
59 | myHeader.GFR = BitConverter.ToUInt32(br_read(4), 0); | ||
60 | myHeader.PR = BitConverter.ToUInt32(br_read(4), 0); | ||
61 | myHeader.ESR = BitConverter.ToUInt32(br_read(4), 0); | ||
62 | myHeader.SR = BitConverter.ToUInt32(br_read(4), 0); | ||
63 | myHeader.NCE = BitConverter.ToUInt64(br_read(8), 0); | ||
64 | myHeader.NIE = BitConverter.ToUInt64(br_read(8), 0); | ||
65 | myHeader.NER = BitConverter.ToUInt64(br_read(8), 0); | ||
66 | |||
67 | // Print Header Block to debug | ||
68 | SendToDebug("TM - Top of memory (size): " + myHeader.TM); | ||
69 | SendToDebug("IP - Instruction Pointer (0=not running): " + myHeader.IP); | ||
70 | SendToDebug("VN - Version number: " + myHeader.VN); | ||
71 | SendToDebug("BP - Local Frame Pointer: " + myHeader.BP); | ||
72 | SendToDebug("SP - Stack Pointer: " + myHeader.SP); | ||
73 | SendToDebug("HR - Heap Register: " + myHeader.HR); | ||
74 | SendToDebug("HP - Heap Pointer: " + myHeader.HP); | ||
75 | SendToDebug("CS - Current State: " + myHeader.CS); | ||
76 | SendToDebug("NS - Next State: " + myHeader.NS); | ||
77 | SendToDebug("CE - Current Events: " + myHeader.CE); | ||
78 | SendToDebug("IE - In Event: " + myHeader.IE); | ||
79 | SendToDebug("ER - Event Register: " + myHeader.ER); | ||
80 | SendToDebug("FR - Fault Register: " + myHeader.FR); | ||
81 | SendToDebug("SLR - Sleep Register: " + myHeader.SLR); | ||
82 | SendToDebug("GVR - Global Variable Register: " + myHeader.GVR); | ||
83 | SendToDebug("GFR - Global Function Register: " + myHeader.GFR); | ||
84 | SendToDebug("PR - Parameter Register: " + myHeader.PR); | ||
85 | SendToDebug("ESR - Energy Supply Register: " + myHeader.ESR); | ||
86 | SendToDebug("SR - State Register: " + myHeader.SR); | ||
87 | SendToDebug("NCE - 64-bit Current Events: " + myHeader.NCE); | ||
88 | SendToDebug("NIE - 64-bit In Events: " + myHeader.NIE); | ||
89 | SendToDebug("NER - 64-bit Event Register: " + myHeader.NER); | ||
90 | SendToDebug("Read position when exiting HEADER BLOCK: " + fs.Position); | ||
91 | |||
92 | // STATIC BLOCK | ||
93 | SendToDebug("Reading STATIC BLOCK at: " + myHeader.GVR); | ||
94 | fs.Seek(myHeader.GVR, SeekOrigin.Begin); | ||
95 | int StaticBlockCount = 0; | ||
96 | // Read function blocks until we hit GFR | ||
97 | while (fs.Position < myHeader.GFR) | ||
98 | { | ||
99 | StaticBlockCount++; | ||
100 | SendToDebug("Reading Static Block " + StaticBlockCount + " at: " + fs.Position); | ||
101 | //fs.Seek(myHeader.GVR, SeekOrigin.Begin); | ||
102 | LSO_Struct.StaticBlock myStaticBlock = new LSO_Struct.StaticBlock(); | ||
103 | myStaticBlock.Static_Chunk_Header_Size = BitConverter.ToUInt32(br_read(4), 0); | ||
104 | myStaticBlock.ObjectType = br_read(1)[0]; | ||
105 | SendToDebug("Static Block ObjectType: " + ((LSO_Enums.Variable_Type_Codes)myStaticBlock.ObjectType).ToString()); | ||
106 | myStaticBlock.Unknown = br_read(1)[0]; | ||
107 | // Size of datatype varies | ||
108 | if (myStaticBlock.ObjectType != 0) | ||
109 | myStaticBlock.BlockVariable = br_read(getObjectSize(myStaticBlock.ObjectType)); | ||
110 | } | ||
111 | SendToDebug("Number of Static Blocks read: " + StaticBlockCount); | ||
112 | |||
113 | |||
114 | // FUNCTION BLOCK | ||
115 | // Always right after STATIC BLOCK | ||
116 | LSO_Struct.FunctionBlock myFunctionBlock = new LSO_Struct.FunctionBlock(); | ||
117 | if (myHeader.GFR == myHeader.SR) | ||
118 | { | ||
119 | // If GFR and SR are at same position then there is no fuction block | ||
120 | SendToDebug("No FUNCTION BLOCK found"); | ||
121 | } else { | ||
122 | SendToDebug("Reading FUNCTION BLOCK at: " + myHeader.GFR); | ||
123 | fs.Seek(myHeader.GFR, SeekOrigin.Begin); | ||
124 | myFunctionBlock.FunctionCount = BitConverter.ToUInt32(br_read(4), 0); | ||
125 | SendToDebug("Number of functions in Fuction Block: " + myFunctionBlock.FunctionCount); | ||
126 | if (myFunctionBlock.FunctionCount > 0) | ||
127 | { | ||
128 | myFunctionBlock.CodeChunkPointer = new UInt32[myFunctionBlock.FunctionCount]; | ||
129 | for (int i = 0; i < myFunctionBlock.FunctionCount; i++) | ||
130 | { | ||
131 | SendToDebug("Reading function " + i + " at: " + fs.Position); | ||
132 | // TODO: ADD TO FUNCTION LIST (How do we identify it later?) | ||
133 | // Note! Absolute position | ||
134 | myFunctionBlock.CodeChunkPointer[i] = BitConverter.ToUInt32(br_read(4), 0) + myHeader.GFR; | ||
135 | SendToDebug("Fuction " + i + " code chunk position: " + myFunctionBlock.CodeChunkPointer[i]); | ||
136 | } | ||
137 | } | ||
138 | } | ||
139 | |||
140 | |||
141 | // STATE FRAME BLOCK | ||
142 | // Always right after FUNCTION BLOCK | ||
143 | SendToDebug("Reading STATE BLOCK at: " + myHeader.SR); | ||
144 | fs.Seek(myHeader.SR, SeekOrigin.Begin); | ||
145 | LSO_Struct.StateFrameBlock myStateFrameBlock = new LSO_Struct.StateFrameBlock(); | ||
146 | myStateFrameBlock.StateCount = BitConverter.ToUInt32(br_read(4), 0); | ||
147 | if (myStateFrameBlock.StateCount > 0) | ||
148 | { | ||
149 | // Initialize array | ||
150 | myStateFrameBlock.StatePointer = new LSO_Struct.StatePointerBlock[myStateFrameBlock.StateCount]; | ||
151 | for (int i = 0; i < myStateFrameBlock.StateCount; i++) | ||
152 | { | ||
153 | SendToDebug("Reading STATE POINTER BLOCK " + (i+1) + " at: " + fs.Position); | ||
154 | // Position is relative to state frame | ||
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)); | ||
157 | SendToDebug("Pointer: " + myStateFrameBlock.StatePointer[i].Location); | ||
158 | SendToDebug("Total potential EventMask bits: " + myStateFrameBlock.StatePointer[i].EventMask.Count); | ||
159 | |||
160 | //// Read STATE BLOCK | ||
161 | //long CurPos = fs.Position; | ||
162 | //fs.Seek(CurPos, SeekOrigin.Begin); | ||
163 | |||
164 | } | ||
165 | } | ||
166 | |||
167 | |||
168 | // STATE BLOCK | ||
169 | // For each StateFrameBlock there is one StateBlock with multiple event handlers | ||
170 | |||
171 | if (myStateFrameBlock.StateCount > 0) | ||
172 | { | ||
173 | // Go through all State Frame Pointers found | ||
174 | for (int i = 0; i < myStateFrameBlock.StateCount; i++) | ||
175 | { | ||
176 | |||
177 | fs.Seek(myStateFrameBlock.StatePointer[i].Location, SeekOrigin.Begin); | ||
178 | SendToDebug("Reading STATE BLOCK " + (i + 1) + " at: " + fs.Position); | ||
179 | |||
180 | // READ: STATE BLOCK HEADER | ||
181 | myStateFrameBlock.StatePointer[i].StateBlock = new LSO_Struct.StateBlock(); | ||
182 | myStateFrameBlock.StatePointer[i].StateBlock.StartPos = (UInt32)fs.Position; // Note | ||
183 | myStateFrameBlock.StatePointer[i].StateBlock.HeaderSize = BitConverter.ToUInt32(br_read(4), 0); | ||
184 | myStateFrameBlock.StatePointer[i].StateBlock.Unknown = br_read(1)[0]; | ||
185 | myStateFrameBlock.StatePointer[i].StateBlock.EndPos = (UInt32)fs.Position; // Note | ||
186 | SendToDebug("State block Start Pos: " + myStateFrameBlock.StatePointer[i].StateBlock.StartPos); | ||
187 | SendToDebug("State block Header Size: " + myStateFrameBlock.StatePointer[i].StateBlock.HeaderSize); | ||
188 | SendToDebug("State block Header End Pos: " + myStateFrameBlock.StatePointer[i].StateBlock.EndPos); | ||
189 | |||
190 | // We need to count number of bits flagged in EventMask? | ||
191 | |||
192 | |||
193 | // for each bit in myStateFrameBlock.StatePointer[i].EventMask | ||
194 | |||
195 | // ADDING TO ALL RIGHT NOW, SHOULD LIMIT TO ONLY THE ONES IN USE | ||
196 | //TODO: Create event hooks | ||
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++) | ||
199 | { | ||
200 | |||
201 | if (myStateFrameBlock.StatePointer[i].EventMask.Get(ii) == true) | ||
202 | { | ||
203 | // We got an event | ||
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); | ||
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); | ||
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 ); | ||
210 | } | ||
211 | } | ||
212 | } | ||
213 | } | ||
214 | |||
215 | |||
216 | |||
217 | |||
218 | //// READ FUNCTION CODE CHUNKS | ||
219 | //// Functions + Function start pos (GFR) | ||
220 | //// TODO: Somehow be able to identify and reference this | ||
221 | //LSO_Struct.CodeChunk[] myFunctionCodeChunk; | ||
222 | //if (myFunctionBlock.FunctionCount > 0) | ||
223 | //{ | ||
224 | // myFunctionCodeChunk = new LSO_Struct.CodeChunk[myFunctionBlock.FunctionCount]; | ||
225 | // for (int i = 0; i < myFunctionBlock.FunctionCount; i++) | ||
226 | // { | ||
227 | // SendToDebug("Reading Function Code Chunk " + i); | ||
228 | // myFunctionCodeChunk[i] = GetCodeChunk((UInt32)myFunctionBlock.CodeChunkPointer[i]); | ||
229 | // } | ||
230 | |||
231 | //} | ||
232 | // READ EVENT CODE CHUNKS | ||
233 | LSO_Struct.CodeChunk[] myEventCodeChunk; | ||
234 | if (myStateFrameBlock.StateCount > 0) | ||
235 | { | ||
236 | myEventCodeChunk = new LSO_Struct.CodeChunk[myStateFrameBlock.StateCount]; | ||
237 | for (int i = 0; i < myStateFrameBlock.StateCount; i++) | ||
238 | { | ||
239 | // TODO: Somehow organize events and functions so they can be found again, | ||
240 | // two level search ain't no good | ||
241 | for (int ii = 0; ii < myStateFrameBlock.StatePointer[i].EventMask.Count - 1; ii++) | ||
242 | { | ||
243 | |||
244 | |||
245 | if (myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer > 0) | ||
246 | { | ||
247 | SendToDebug("Reading Event Code Chunk state " + i + ", event " + (LSO_Enums.Event_Mask_Values)ii); | ||
248 | |||
249 | |||
250 | // Override a Method / Function | ||
251 | string eventname = "event_" + (LSO_Enums.Event_Mask_Values)ii; | ||
252 | SendToDebug("CLR:" + eventname + ":MethodBuilder methodBuilder = typeBuilder.DefineMethod..."); | ||
253 | MethodBuilder methodBuilder = typeBuilder.DefineMethod(eventname, | ||
254 | MethodAttributes.Private | MethodAttributes.Virtual, | ||
255 | typeof(void), | ||
256 | new Type[] { typeof(object) }); | ||
257 | |||
258 | SendToDebug("CLR:" + eventname + ":typeBuilder.DefineMethodOverride(methodBuilder..."); | ||
259 | typeBuilder.DefineMethodOverride(methodBuilder, | ||
260 | typeof(LSL_CLRInterface.LSLScript).GetMethod(eventname)); | ||
261 | |||
262 | // Create the IL generator | ||
263 | |||
264 | SendToDebug("CLR:" + eventname + ":ILGenerator il = methodBuilder.GetILGenerator();"); | ||
265 | ILGenerator il = methodBuilder.GetILGenerator(); | ||
266 | |||
267 | |||
268 | LSO_Struct.CodeChunk myECC = | ||
269 | GetCodeChunk(myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer, il, eventname); | ||
270 | } | ||
271 | |||
272 | } | ||
273 | } | ||
274 | |||
275 | } | ||
276 | |||
277 | |||
278 | // Close | ||
279 | br.Close(); | ||
280 | fs.Close(); | ||
281 | |||
282 | } | ||
283 | |||
284 | private LSO_Struct.HeapBlock GetHeap(UInt32 pos) | ||
285 | { | ||
286 | // HEAP BLOCK | ||
287 | // TODO:? Special read for strings/keys (null terminated) and lists (pointers to other HEAP entries) | ||
288 | SendToDebug("Reading HEAP BLOCK at: " + pos); | ||
289 | fs.Seek(pos, SeekOrigin.Begin); | ||
290 | |||
291 | LSO_Struct.HeapBlock myHeapBlock = new LSO_Struct.HeapBlock(); | ||
292 | myHeapBlock.DataBlockSize = BitConverter.ToUInt32(br_read(4), 0); | ||
293 | myHeapBlock.ObjectType = br_read(1)[0]; | ||
294 | myHeapBlock.ReferenceCount = BitConverter.ToUInt16(br_read(2), 0); | ||
295 | myHeapBlock.Data = br_read(getObjectSize(myHeapBlock.ObjectType)); | ||
296 | |||
297 | SendToDebug("Heap Block Data Block Size: " + myHeapBlock.DataBlockSize); | ||
298 | SendToDebug("Heap Block ObjectType: " + ((LSO_Enums.Variable_Type_Codes)myHeapBlock.ObjectType).ToString()); | ||
299 | SendToDebug("Heap Block Reference Count: " + myHeapBlock.ReferenceCount); | ||
300 | |||
301 | return myHeapBlock; | ||
302 | } | ||
303 | |||
304 | |||
305 | |||
306 | private byte[] br_read(int len) | ||
307 | { | ||
308 | if (len <= 0) | ||
309 | return null; | ||
310 | |||
311 | try | ||
312 | { | ||
313 | byte[] bytes = new byte[len]; | ||
314 | for (int i = len - 1; i > -1; i--) | ||
315 | bytes[i] = br.ReadByte(); | ||
316 | return bytes; | ||
317 | } | ||
318 | catch (Exception e) | ||
319 | { | ||
320 | SendToDebug("Exception: " + e.ToString()); | ||
321 | throw (e); | ||
322 | } | ||
323 | } | ||
324 | //private byte[] br_read_smallendian(int len) | ||
325 | //{ | ||
326 | // byte[] bytes = new byte[len]; | ||
327 | // br.Read(bytes,0, len); | ||
328 | // return bytes; | ||
329 | //} | ||
330 | |||
331 | private int getObjectSize(byte ObjectType) | ||
332 | { | ||
333 | switch (ObjectType) | ||
334 | { | ||
335 | case 1: | ||
336 | case 2: | ||
337 | case 3: | ||
338 | case 4: | ||
339 | case 7: | ||
340 | return 4; | ||
341 | case 5: | ||
342 | return 12; | ||
343 | case 6: | ||
344 | return 16; | ||
345 | default: | ||
346 | return 0; | ||
347 | } | ||
348 | } | ||
349 | private void SendToDebug(string Message) | ||
350 | { | ||
351 | if (Debug == true) | ||
352 | Console.WriteLine("Debug: " + Message); | ||
353 | } | ||
354 | |||
355 | |||
356 | private string Read_String() | ||
357 | { | ||
358 | string ret = ""; | ||
359 | byte reader = br_read(1)[0]; | ||
360 | while (reader != 0x000) | ||
361 | { | ||
362 | ret += (char)reader; | ||
363 | reader = br_read(1)[0]; | ||
364 | } | ||
365 | return ret; | ||
366 | } | ||
367 | |||
368 | /// <summary> | ||
369 | /// Reads a code chunk into structure and returns it. | ||
370 | /// </summary> | ||
371 | /// <param name="pos">Absolute position in file. REMEMBER TO ADD myHeader.GFR!</param> | ||
372 | /// <returns></returns> | ||
373 | private LSO_Struct.CodeChunk GetCodeChunk(UInt32 pos, ILGenerator il, string eventname) | ||
374 | { | ||
375 | |||
376 | /* | ||
377 | * CLR TRY | ||
378 | */ | ||
379 | //SendToDebug("CLR:" + eventname + ":il.BeginExceptionBlock()"); | ||
380 | il.BeginExceptionBlock(); | ||
381 | |||
382 | // Push "Hello World!" string to stack | ||
383 | //SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Ldstr..."); | ||
384 | il.Emit(OpCodes.Ldstr, "Starting CLR dynamic execution of: " + eventname); | ||
385 | |||
386 | // Push Console.WriteLine command to stack ... Console.WriteLine("Hello World!"); | ||
387 | //SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call..."); | ||
388 | il.Emit(OpCodes.Call, typeof(Console).GetMethod | ||
389 | ("WriteLine", new Type[] { typeof(string) })); | ||
390 | |||
391 | |||
392 | LSO_Struct.CodeChunk myCodeChunk = new LSO_Struct.CodeChunk(); | ||
393 | |||
394 | SendToDebug("Reading Function Code Chunk at: " + pos); | ||
395 | fs.Seek(pos, SeekOrigin.Begin); | ||
396 | myCodeChunk.CodeChunkHeaderSize = BitConverter.ToUInt32(br_read(4), 0); | ||
397 | SendToDebug("CodeChunk Header Size: " + myCodeChunk.CodeChunkHeaderSize ); | ||
398 | // Read until null | ||
399 | myCodeChunk.Comment = Read_String(); | ||
400 | SendToDebug("Function comment: " + myCodeChunk.Comment); | ||
401 | myCodeChunk.ReturnType = br_read(1)[0]; | ||
402 | SendToDebug("Return type: " + (LSO_Enums.Variable_Type_Codes)myCodeChunk.ReturnType); | ||
403 | // TODO: How to determine number of codechunks -- does this method work? | ||
404 | myCodeChunk.CodeChunkArguments = new System.Collections.Generic.List<LSO_Struct.CodeChunkArgument>(); | ||
405 | byte reader = br_read(1)[0]; | ||
406 | reader = br_read(1)[0]; | ||
407 | int ccount = 0; | ||
408 | while (reader != 0x000) | ||
409 | { | ||
410 | ccount++; | ||
411 | SendToDebug("Reading Code Chunk Argument " + ccount); | ||
412 | LSO_Struct.CodeChunkArgument CCA = new LSO_Struct.CodeChunkArgument(); | ||
413 | CCA.FunctionReturnType = reader; | ||
414 | reader = br_read(1)[0]; | ||
415 | CCA.NullString = reader; | ||
416 | myCodeChunk.CodeChunkArguments.Add(CCA); | ||
417 | SendToDebug("Code Chunk Argument " + ccount + " return type: " + (LSO_Enums.Variable_Type_Codes)CCA.FunctionReturnType); | ||
418 | } | ||
419 | // End marker is 0x000 | ||
420 | myCodeChunk.EndMarker = reader; | ||
421 | // TODO: How to read and identify following code | ||
422 | // TODO: Code is read until a return of some sort is found | ||
423 | bool FoundRet = false; | ||
424 | while (FoundRet == false) | ||
425 | { | ||
426 | //reader = br_read(1)[0]; | ||
427 | //UInt16 opcode = BitConverter.ToUInt16(br_read(1),0); | ||
428 | UInt16 opcode = br_read(1)[0]; | ||
429 | //long rPos = fs.Position; | ||
430 | SendToDebug("OPCODE: " + ((LSO_Enums.Operation_Table)opcode).ToString()); | ||
431 | switch (opcode) | ||
432 | { | ||
433 | // LONG | ||
434 | case (UInt16)LSO_Enums.Operation_Table.POPARG: | ||
435 | case (UInt16)LSO_Enums.Operation_Table.STORE: | ||
436 | case (UInt16)LSO_Enums.Operation_Table.STORES: | ||
437 | case (UInt16)LSO_Enums.Operation_Table.STOREL: | ||
438 | case (UInt16)LSO_Enums.Operation_Table.STOREV: | ||
439 | case (UInt16)LSO_Enums.Operation_Table.STOREQ: | ||
440 | case (UInt16)LSO_Enums.Operation_Table.STOREG: | ||
441 | case (UInt16)LSO_Enums.Operation_Table.STOREGS: | ||
442 | case (UInt16)LSO_Enums.Operation_Table.STOREGL: | ||
443 | case (UInt16)LSO_Enums.Operation_Table.STOREGV: | ||
444 | case (UInt16)LSO_Enums.Operation_Table.STOREGQ: | ||
445 | case (UInt16)LSO_Enums.Operation_Table.LOADP: | ||
446 | case (UInt16)LSO_Enums.Operation_Table.LOADSP: | ||
447 | case (UInt16)LSO_Enums.Operation_Table.LOADLP: | ||
448 | case (UInt16)LSO_Enums.Operation_Table.LOADVP: | ||
449 | case (UInt16)LSO_Enums.Operation_Table.LOADQP: | ||
450 | case (UInt16)LSO_Enums.Operation_Table.PUSH: | ||
451 | case (UInt16)LSO_Enums.Operation_Table.PUSHS: | ||
452 | case (UInt16)LSO_Enums.Operation_Table.PUSHL: | ||
453 | case (UInt16)LSO_Enums.Operation_Table.PUSHV: | ||
454 | case (UInt16)LSO_Enums.Operation_Table.PUSHQ: | ||
455 | case (UInt16)LSO_Enums.Operation_Table.PUSHG: | ||
456 | case (UInt16)LSO_Enums.Operation_Table.PUSHGS: | ||
457 | case (UInt16)LSO_Enums.Operation_Table.PUSHGL: | ||
458 | case (UInt16)LSO_Enums.Operation_Table.PUSHGV: | ||
459 | case (UInt16)LSO_Enums.Operation_Table.PUSHGQ: | ||
460 | SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0)); | ||
461 | break; | ||
462 | // BYTE | ||
463 | case (UInt16)LSO_Enums.Operation_Table.PUSHARGB: | ||
464 | SendToDebug("Param1: " + br_read(1)[0]); | ||
465 | break; | ||
466 | // INTEGER | ||
467 | case (UInt16)LSO_Enums.Operation_Table.PUSHARGI: | ||
468 | // TODO: What is size of integer? | ||
469 | SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0)); | ||
470 | break; | ||
471 | // FLOAT | ||
472 | case (UInt16)LSO_Enums.Operation_Table.PUSHARGF: | ||
473 | // TODO: What is size of float? | ||
474 | SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0)); | ||
475 | break; | ||
476 | // STRING | ||
477 | case (UInt16)LSO_Enums.Operation_Table.PUSHARGS: | ||
478 | string s = Read_String(); | ||
479 | SendToDebug("Param1: " + s); | ||
480 | il.Emit(OpCodes.Ldstr, s); | ||
481 | break; | ||
482 | // VECTOR z,y,x | ||
483 | case (UInt16)LSO_Enums.Operation_Table.PUSHARGV: | ||
484 | SendToDebug("Param1 Z: " + 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)); | ||
487 | break; | ||
488 | // ROTATION s,z,y,x | ||
489 | case (UInt16)LSO_Enums.Operation_Table.PUSHARGQ: | ||
490 | SendToDebug("Param1 S: " + 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)); | ||
493 | SendToDebug("Param1 X: " + BitConverter.ToUInt32(br_read(4),0)); | ||
494 | break; | ||
495 | // LONG | ||
496 | case (UInt16)LSO_Enums.Operation_Table.PUSHARGE: | ||
497 | SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0)); | ||
498 | break; | ||
499 | // BYTE | ||
500 | case (UInt16)LSO_Enums.Operation_Table.ADD: | ||
501 | case (UInt16)LSO_Enums.Operation_Table.SUB: | ||
502 | case (UInt16)LSO_Enums.Operation_Table.MUL: | ||
503 | case (UInt16)LSO_Enums.Operation_Table.DIV: | ||
504 | case (UInt16)LSO_Enums.Operation_Table.MOD: | ||
505 | case (UInt16)LSO_Enums.Operation_Table.EQ: | ||
506 | case (UInt16)LSO_Enums.Operation_Table.NEQ: | ||
507 | case (UInt16)LSO_Enums.Operation_Table.LEQ: | ||
508 | case (UInt16)LSO_Enums.Operation_Table.GEQ: | ||
509 | case (UInt16)LSO_Enums.Operation_Table.LESS: | ||
510 | case (UInt16)LSO_Enums.Operation_Table.GREATER: | ||
511 | case (UInt16)LSO_Enums.Operation_Table.BOOLOR: | ||
512 | SendToDebug("Param1: " + br_read(1)[0]); | ||
513 | break; | ||
514 | // LONG | ||
515 | case (UInt16)LSO_Enums.Operation_Table.JUMP: | ||
516 | SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0)); | ||
517 | break; | ||
518 | // BYTE, LONG | ||
519 | case (UInt16)LSO_Enums.Operation_Table.JUMPIF: | ||
520 | case (UInt16)LSO_Enums.Operation_Table.JUMPNIF: | ||
521 | SendToDebug("Param1: " + br_read(1)[0]); | ||
522 | SendToDebug("Param2: " + BitConverter.ToUInt32(br_read(4),0)); | ||
523 | break; | ||
524 | // LONG | ||
525 | case (UInt16)LSO_Enums.Operation_Table.STATE: | ||
526 | case (UInt16)LSO_Enums.Operation_Table.CALL: | ||
527 | SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0)); | ||
528 | break; | ||
529 | // BYTE | ||
530 | case (UInt16)LSO_Enums.Operation_Table.CAST: | ||
531 | SendToDebug("Param1: " + br_read(1)[0]); | ||
532 | break; | ||
533 | // LONG | ||
534 | case (UInt16)LSO_Enums.Operation_Table.STACKTOS: | ||
535 | case (UInt16)LSO_Enums.Operation_Table.STACKTOL: | ||
536 | SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4),0)); | ||
537 | break; | ||
538 | // BYTE | ||
539 | case (UInt16)LSO_Enums.Operation_Table.PRINT: | ||
540 | case (UInt16)LSO_Enums.Operation_Table.CALLLIB: | ||
541 | SendToDebug("Param1: " + br_read(1)[0]); | ||
542 | break; | ||
543 | // SHORT | ||
544 | case (UInt16)LSO_Enums.Operation_Table.CALLLIB_TWO_BYTE: | ||
545 | // TODO: What is size of short? | ||
546 | UInt16 _i = BitConverter.ToUInt16(br_read(2), 0); | ||
547 | SendToDebug("Param1: " + _i); | ||
548 | switch (_i) | ||
549 | { | ||
550 | case (UInt16)LSO_Enums.BuiltIn_Functions.llSay: | ||
551 | il.Emit(OpCodes.Call, typeof(Console).GetMethod | ||
552 | ("WriteLine", new Type[] { typeof(string) })); | ||
553 | break; | ||
554 | } | ||
555 | break; | ||
556 | |||
557 | |||
558 | // RETURN | ||
559 | case (UInt16)LSO_Enums.Operation_Table.RETURN: | ||
560 | SendToDebug("Last OPCODE was return command. Code chunk execution complete."); | ||
561 | FoundRet = true; | ||
562 | break; | ||
563 | } | ||
564 | //fs.Seek(rPos, SeekOrigin.Begin); | ||
565 | |||
566 | } | ||
567 | |||
568 | |||
569 | /* | ||
570 | * CATCH | ||
571 | */ | ||
572 | SendToDebug("CLR:" + eventname + ":il.BeginCatchBlock(typeof(Exception));"); | ||
573 | il.BeginCatchBlock(typeof(Exception)); | ||
574 | |||
575 | // Push "Hello World!" string to stack | ||
576 | SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Ldstr..."); | ||
577 | il.Emit(OpCodes.Ldstr, "Execption executing dynamic CLR function " + eventname + ": "); | ||
578 | |||
579 | //call void [mscorlib]System.Console::WriteLine(string) | ||
580 | SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call..."); | ||
581 | il.Emit(OpCodes.Call, typeof(Console).GetMethod | ||
582 | ("Write", new Type[] { typeof(string) })); | ||
583 | |||
584 | //callvirt instance string [mscorlib]System.Exception::get_Message() | ||
585 | SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Callvirt..."); | ||
586 | il.Emit(OpCodes.Callvirt, typeof(Exception).GetMethod | ||
587 | ("get_Message")); | ||
588 | |||
589 | //call void [mscorlib]System.Console::WriteLine(string) | ||
590 | SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call..."); | ||
591 | il.Emit(OpCodes.Call, typeof(Console).GetMethod | ||
592 | ("WriteLine", new Type[] { typeof(string) })); | ||
593 | |||
594 | /* | ||
595 | * CLR END TRY | ||
596 | */ | ||
597 | //SendToDebug("CLR:" + eventname + ":il.EndExceptionBlock();"); | ||
598 | il.EndExceptionBlock(); | ||
599 | // Push "Return from current method, with return value if present" to stack | ||
600 | il.Emit(OpCodes.Ret); | ||
601 | |||
602 | |||
603 | |||
604 | return myCodeChunk; | ||
605 | |||
606 | } | ||
607 | } | ||
608 | } | ||
diff --git a/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Struct.cs b/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Struct.cs new file mode 100644 index 0000000..3b91e9f --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/scripting/Engines/LSLEngine/LSLHandler/LSO_Struct.cs | |||
@@ -0,0 +1,105 @@ | |||
1 | |||
2 | using System; | ||
3 | using System.Collections.Generic; | ||
4 | using System.Text; | ||
5 | |||
6 | namespace OpenSim.ScriptEngines.LSL | ||
7 | { | ||
8 | static class LSO_Struct | ||
9 | { | ||
10 | |||
11 | public struct Header | ||
12 | { | ||
13 | public UInt32 TM; | ||
14 | public UInt32 IP; | ||
15 | public UInt32 VN; | ||
16 | public UInt32 BP; | ||
17 | public UInt32 SP; | ||
18 | public UInt32 HR; | ||
19 | public UInt32 HP; | ||
20 | public UInt32 CS; | ||
21 | public UInt32 NS; | ||
22 | public UInt32 CE; | ||
23 | public UInt32 IE; | ||
24 | public UInt32 ER; | ||
25 | public UInt32 FR; | ||
26 | public UInt32 SLR; | ||
27 | public UInt32 GVR; | ||
28 | public UInt32 GFR; | ||
29 | public UInt32 PR; | ||
30 | public UInt32 ESR; | ||
31 | public UInt32 SR; | ||
32 | public UInt64 NCE; | ||
33 | public UInt64 NIE; | ||
34 | public UInt64 NER; | ||
35 | } | ||
36 | |||
37 | public struct StaticBlock | ||
38 | { | ||
39 | public UInt32 Static_Chunk_Header_Size; | ||
40 | public byte ObjectType; | ||
41 | public byte Unknown; | ||
42 | public byte[] BlockVariable; | ||
43 | } | ||
44 | /* Not actually a structure | ||
45 | public struct StaticBlockVariable | ||
46 | { | ||
47 | public UInt32 Integer1; | ||
48 | public UInt32 Float1; | ||
49 | public UInt32 HeapPointer_String; | ||
50 | public UInt32 HeapPointer_Key; | ||
51 | public byte[] Vector_12; | ||
52 | public byte[] Rotation_16; | ||
53 | public UInt32 Pointer_List_Structure; | ||
54 | } */ | ||
55 | public struct HeapBlock | ||
56 | { | ||
57 | public UInt32 DataBlockSize; | ||
58 | public byte ObjectType; | ||
59 | public UInt16 ReferenceCount; | ||
60 | public byte[] Data; | ||
61 | } | ||
62 | public struct StateFrameBlock | ||
63 | { | ||
64 | public UInt32 StateCount; | ||
65 | public StatePointerBlock[] StatePointer; | ||
66 | } | ||
67 | public struct StatePointerBlock | ||
68 | { | ||
69 | public UInt32 Location; | ||
70 | public System.Collections.BitArray EventMask; | ||
71 | public StateBlock StateBlock; | ||
72 | } | ||
73 | public struct StateBlock | ||
74 | { | ||
75 | public UInt32 StartPos; | ||
76 | public UInt32 EndPos; | ||
77 | public UInt32 HeaderSize; | ||
78 | public byte Unknown; | ||
79 | public StateBlockHandler[] StateBlockHandlers; | ||
80 | } | ||
81 | public struct StateBlockHandler | ||
82 | { | ||
83 | public UInt32 CodeChunkPointer; | ||
84 | public UInt32 CallFrameSize; | ||
85 | } | ||
86 | public struct FunctionBlock | ||
87 | { | ||
88 | public UInt32 FunctionCount; | ||
89 | public UInt32[] CodeChunkPointer; | ||
90 | } | ||
91 | public struct CodeChunk | ||
92 | { | ||
93 | public UInt32 CodeChunkHeaderSize; | ||
94 | public string Comment; | ||
95 | public System.Collections.Generic.List<CodeChunkArgument> CodeChunkArguments; | ||
96 | public byte EndMarker; | ||
97 | public byte ReturnType; | ||
98 | } | ||
99 | public struct CodeChunkArgument | ||
100 | { | ||
101 | public byte FunctionReturnType; | ||
102 | public byte NullString; | ||
103 | } | ||
104 | } | ||
105 | } | ||