XMRInstAbstract.cs 75 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963
  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSimulator Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
  28. using System;
  29. using System.Collections.Generic;
  30. using System.Globalization;
  31. using System.IO;
  32. using System.Reflection.Emit;
  33. using System.Runtime.Serialization;
  34. using System.Text;
  35. using System.Threading;
  36. using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
  37. using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
  38. using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
  39. using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
  40. using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
  41. using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
  42. using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
  43. namespace OpenSim.Region.ScriptEngine.Yengine
  44. {
  45. public class XMRInstArrays
  46. {
  47. public XMR_Array[] iarArrays;
  48. public char[] iarChars;
  49. public double[] iarFloats;
  50. public int[] iarIntegers;
  51. public LSL_List[] iarLists;
  52. public object[] iarObjects;
  53. public LSL_Rotation[] iarRotations;
  54. public string[] iarStrings;
  55. public LSL_Vector[] iarVectors;
  56. public XMRSDTypeClObj[] iarSDTClObjs;
  57. public Delegate[][] iarSDTIntfObjs;
  58. private XMRInstAbstract instance;
  59. private int heapUse;
  60. private static readonly XMR_Array[] noArrays = new XMR_Array[0];
  61. private static readonly char[] noChars = new char[0];
  62. private static readonly double[] noFloats = new double[0];
  63. private static readonly int[] noIntegers = new int[0];
  64. private static readonly LSL_List[] noLists = new LSL_List[0];
  65. private static readonly object[] noObjects = new object[0];
  66. private static readonly LSL_Rotation[] noRotations = new LSL_Rotation[0];
  67. private static readonly string[] noStrings = new string[0];
  68. private static readonly LSL_Vector[] noVectors = new LSL_Vector[0];
  69. private static readonly XMRSDTypeClObj[] noSDTClObjs = new XMRSDTypeClObj[0];
  70. private static readonly Delegate[][] noSDTIntfObjs = new Delegate[0][];
  71. public XMRInstArrays(XMRInstAbstract inst)
  72. {
  73. instance = inst;
  74. }
  75. ~XMRInstArrays()
  76. {
  77. heapUse = instance.UpdateHeapUse(heapUse, 0);
  78. }
  79. public void AllocVarArrays(XMRInstArSizes ars)
  80. {
  81. ClearOldArrays();
  82. heapUse = instance.UpdateHeapUse(heapUse,
  83. ars.iasChars * HeapTrackerObject.HT_CHAR +
  84. ars.iasFloats * HeapTrackerObject.HT_SFLT +
  85. ars.iasIntegers * HeapTrackerObject.HT_INT +
  86. ars.iasRotations * HeapTrackerObject.HT_ROT +
  87. ars.iasVectors * HeapTrackerObject.HT_VEC +
  88. ars.iasSDTIntfObjs * HeapTrackerObject.HT_DELE);
  89. iarArrays = (ars.iasArrays > 0) ? new XMR_Array[ars.iasArrays] : noArrays;
  90. iarChars = (ars.iasChars > 0) ? new char[ars.iasChars] : noChars;
  91. iarFloats = (ars.iasFloats > 0) ? new double[ars.iasFloats] : noFloats;
  92. iarIntegers = (ars.iasIntegers > 0) ? new int[ars.iasIntegers] : noIntegers;
  93. iarLists = (ars.iasLists > 0) ? new LSL_List[ars.iasLists] : noLists;
  94. iarObjects = (ars.iasObjects > 0) ? new object[ars.iasObjects] : noObjects;
  95. iarRotations = (ars.iasRotations > 0) ? new LSL_Rotation[ars.iasRotations] : noRotations;
  96. iarStrings = (ars.iasStrings > 0) ? new string[ars.iasStrings] : noStrings;
  97. iarVectors = (ars.iasVectors > 0) ? new LSL_Vector[ars.iasVectors] : noVectors;
  98. iarSDTClObjs = (ars.iasSDTClObjs > 0) ? new XMRSDTypeClObj[ars.iasSDTClObjs] : noSDTClObjs;
  99. iarSDTIntfObjs = (ars.iasSDTIntfObjs > 0) ? new Delegate[ars.iasSDTIntfObjs][] : noSDTIntfObjs;
  100. }
  101. /**
  102. * @brief Do not write directly to iarLists[index], rather use this method.
  103. */
  104. public void PopList(int index, LSL_List lis)
  105. {
  106. LSL_List old = iarLists[index];
  107. int newheapuse = heapUse + HeapTrackerList.Size(lis) - HeapTrackerList.Size(old);
  108. heapUse = instance.UpdateHeapUse(heapUse, newheapuse);
  109. iarLists[index] = lis;
  110. }
  111. /**
  112. * @brief Do not write directly to iarObjects[index], rather use this method.
  113. */
  114. public void PopObject(int index, object obj)
  115. {
  116. object old = iarObjects[index];
  117. int newheapuse = heapUse + HeapTrackerObject.Size(obj) - HeapTrackerObject.Size(old);
  118. heapUse = instance.UpdateHeapUse(heapUse, newheapuse);
  119. iarObjects[index] = obj;
  120. }
  121. /**
  122. * @brief Do not write directly to iarStrings[index], rather use this method.
  123. */
  124. public void PopString(int index, string str)
  125. {
  126. string old = iarStrings[index];
  127. int newheapuse = heapUse + HeapTrackerString.Size(str) - HeapTrackerString.Size(old);
  128. heapUse = instance.UpdateHeapUse(heapUse, newheapuse);
  129. iarStrings[index] = str;
  130. }
  131. /**
  132. * @brief Write all arrays out to a file.
  133. */
  134. public delegate void Sender(object value);
  135. public void SendArrays(Sender sender)
  136. {
  137. sender(iarArrays);
  138. sender(iarChars);
  139. sender(iarFloats);
  140. sender(iarIntegers);
  141. sender(iarLists);
  142. sender(iarObjects);
  143. sender(iarRotations);
  144. sender(iarStrings);
  145. sender(iarVectors);
  146. sender(iarSDTClObjs);
  147. sender(iarSDTIntfObjs);
  148. }
  149. /**
  150. * @brief Read all arrays in from a file.
  151. */
  152. public delegate object Recver();
  153. public void RecvArrays(Recver recver)
  154. {
  155. ClearOldArrays();
  156. iarArrays = (XMR_Array[])recver();
  157. char[] chrs = (char[])recver();
  158. double[] flts = (double[])recver();
  159. int[] ints = (int[])recver();
  160. LSL_List[] liss = (LSL_List[])recver();
  161. object[] objs = (object[])recver();
  162. LSL_Rotation[] rots = (LSL_Rotation[])recver();
  163. string[] strs = (string[])recver();
  164. LSL_Vector[] vecs = (LSL_Vector[])recver();
  165. iarSDTClObjs = (XMRSDTypeClObj[])recver();
  166. Delegate[][] dels = (Delegate[][])recver();
  167. int newheapuse = heapUse;
  168. // value types simply are the size of the value * number of values
  169. newheapuse += chrs.Length * HeapTrackerObject.HT_CHAR;
  170. newheapuse += flts.Length * HeapTrackerObject.HT_SFLT;
  171. newheapuse += ints.Length * HeapTrackerObject.HT_INT;
  172. newheapuse += rots.Length * HeapTrackerObject.HT_ROT;
  173. newheapuse += vecs.Length * HeapTrackerObject.HT_VEC;
  174. newheapuse += dels.Length * HeapTrackerObject.HT_DELE;
  175. // lists, objects, strings are the sum of the size of each element
  176. foreach(LSL_List lis in liss)
  177. newheapuse += HeapTrackerList.Size(lis);
  178. foreach(object obj in objs)
  179. newheapuse += HeapTrackerObject.Size(obj);
  180. foreach(string str in strs)
  181. newheapuse += HeapTrackerString.Size(str);
  182. // others (XMR_Array, XMRSDTypeClObj) keep track of their own heap usage
  183. // update script heap usage, throwing an exception before finalizing changes
  184. heapUse = instance.UpdateHeapUse(heapUse, newheapuse);
  185. iarChars = chrs;
  186. iarFloats = flts;
  187. iarIntegers = ints;
  188. iarLists = liss;
  189. iarObjects = objs;
  190. iarRotations = rots;
  191. iarStrings = strs;
  192. iarVectors = vecs;
  193. iarSDTIntfObjs = dels;
  194. }
  195. private void ClearOldArrays()
  196. {
  197. int newheapuse = heapUse;
  198. iarArrays = null;
  199. if(iarChars != null)
  200. {
  201. newheapuse -= iarChars.Length * HeapTrackerObject.HT_CHAR;
  202. iarChars = null;
  203. }
  204. if(iarFloats != null)
  205. {
  206. newheapuse -= iarFloats.Length * HeapTrackerObject.HT_SFLT;
  207. iarFloats = null;
  208. }
  209. if(iarIntegers != null)
  210. {
  211. newheapuse -= iarIntegers.Length * HeapTrackerObject.HT_INT;
  212. iarIntegers = null;
  213. }
  214. if(iarLists != null)
  215. {
  216. foreach(LSL_List lis in iarLists)
  217. newheapuse -= HeapTrackerList.Size(lis);
  218. iarLists = null;
  219. }
  220. if(iarObjects != null)
  221. {
  222. foreach(object obj in iarObjects)
  223. newheapuse -= HeapTrackerObject.Size(obj);
  224. iarObjects = null;
  225. }
  226. if(iarRotations != null)
  227. {
  228. newheapuse -= iarRotations.Length * HeapTrackerObject.HT_ROT;
  229. iarRotations = null;
  230. }
  231. if(iarStrings != null)
  232. {
  233. foreach(string str in iarStrings)
  234. newheapuse -= HeapTrackerString.Size(str);
  235. iarStrings = null;
  236. }
  237. if(iarVectors != null)
  238. {
  239. newheapuse -= iarVectors.Length * HeapTrackerObject.HT_VEC;
  240. iarVectors = null;
  241. }
  242. iarSDTClObjs = null;
  243. if(iarSDTIntfObjs != null)
  244. {
  245. newheapuse -= iarSDTIntfObjs.Length * HeapTrackerObject.HT_DELE;
  246. iarSDTIntfObjs = null;
  247. }
  248. heapUse = instance.UpdateHeapUse(heapUse, newheapuse);
  249. }
  250. }
  251. public class XMRInstArSizes
  252. {
  253. public int iasArrays;
  254. public int iasChars;
  255. public int iasFloats;
  256. public int iasIntegers;
  257. public int iasLists;
  258. public int iasObjects;
  259. public int iasRotations;
  260. public int iasStrings;
  261. public int iasVectors;
  262. public int iasSDTClObjs;
  263. public int iasSDTIntfObjs;
  264. public void WriteAsmFile(TextWriter asmFileWriter, string label)
  265. {
  266. asmFileWriter.WriteLine(" {0}Arrays {1}", label, iasArrays);
  267. asmFileWriter.WriteLine(" {0}Chars {1}", label, iasChars);
  268. asmFileWriter.WriteLine(" {0}Floats {1}", label, iasFloats);
  269. asmFileWriter.WriteLine(" {0}Integers {1}", label, iasIntegers);
  270. asmFileWriter.WriteLine(" {0}Lists {1}", label, iasLists);
  271. asmFileWriter.WriteLine(" {0}Objects {1}", label, iasObjects);
  272. asmFileWriter.WriteLine(" {0}Rotations {1}", label, iasRotations);
  273. asmFileWriter.WriteLine(" {0}Strings {1}", label, iasStrings);
  274. asmFileWriter.WriteLine(" {0}Vectors {1}", label, iasVectors);
  275. asmFileWriter.WriteLine(" {0}SDTClObjs {1}", label, iasSDTClObjs);
  276. asmFileWriter.WriteLine(" {0}SDTIntfObjs {1}", label, iasSDTIntfObjs);
  277. }
  278. public void WriteToFile(BinaryWriter objFileWriter)
  279. {
  280. objFileWriter.Write(iasArrays);
  281. objFileWriter.Write(iasChars);
  282. objFileWriter.Write(iasFloats);
  283. objFileWriter.Write(iasIntegers);
  284. objFileWriter.Write(iasLists);
  285. objFileWriter.Write(iasObjects);
  286. objFileWriter.Write(iasRotations);
  287. objFileWriter.Write(iasStrings);
  288. objFileWriter.Write(iasVectors);
  289. objFileWriter.Write(iasSDTClObjs);
  290. objFileWriter.Write(iasSDTIntfObjs);
  291. }
  292. public void ReadFromFile(BinaryReader objFileReader)
  293. {
  294. iasArrays = objFileReader.ReadInt32();
  295. iasChars = objFileReader.ReadInt32();
  296. iasFloats = objFileReader.ReadInt32();
  297. iasIntegers = objFileReader.ReadInt32();
  298. iasLists = objFileReader.ReadInt32();
  299. iasObjects = objFileReader.ReadInt32();
  300. iasRotations = objFileReader.ReadInt32();
  301. iasStrings = objFileReader.ReadInt32();
  302. iasVectors = objFileReader.ReadInt32();
  303. iasSDTClObjs = objFileReader.ReadInt32();
  304. iasSDTIntfObjs = objFileReader.ReadInt32();
  305. }
  306. }
  307. public class XMRStackFrame
  308. {
  309. public XMRStackFrame nextSF;
  310. public string funcName;
  311. public int callNo;
  312. public object[] objArray;
  313. }
  314. /*
  315. * Contains only items required by the stand-alone compiler
  316. * so the compiler doesn't need to pull in all of OpenSim.
  317. *
  318. * Inherit from ScriptBaseClass so we can be used as 'this'
  319. * parameter for backend-API calls, eg llSay().
  320. */
  321. public abstract class XMRInstAbstract: ScriptBaseClass
  322. {
  323. public const int CallMode_NORMAL = 0; // when function is called, it proceeds normally
  324. public const int CallMode_SAVE = 1; // StackSaveException() was thrown, push args/locals to stackFrames
  325. public const int CallMode_RESTORE = 2; // when function is called, it pops state from stackFrames
  326. public bool suspendOnCheckRunHold; // suspend script execution until explicitly set false
  327. public bool suspendOnCheckRunTemp; // suspend script execution for single step only
  328. public int stackLimit; // stack must have at least this many bytes free on entry to functions
  329. public int m_StackLeft; // total number of stack bytes yet to be used (init to stacksize)
  330. public ScriptObjCode m_ObjCode; // script object code this instance was created from
  331. public object[] ehArgs; // event handler argument array
  332. public bool doGblInit = true; // default state_entry() needs to initialize global variables
  333. public int stateCode = 0; // state the script is in (0 = 'default')
  334. public int newStateCode = -1; // if >= 0, in the middle of exiting 'stateCode' and entering 'newStateCode'
  335. public ScriptEventCode eventCode = ScriptEventCode.None;
  336. // what event handler is executing (or None if not)
  337. public int callMode = CallMode_NORMAL;
  338. // to capture stack frames on stackFrames:
  339. // set to CallMode_SAVE just before throwing StackSaveException()
  340. // from within CheckRun() and cleared to CallMode_NORMAL when
  341. // the exception is caught
  342. // to restore stack frames from stackFrames:
  343. // set to CallMode_RESTORE just before calling CallSEH() and
  344. // cleared to CallMode_NORMAL by CheckRun()
  345. public XMRStackFrame stackFrames; // stack frames being saved/restored
  346. private static readonly char[] justacomma = { ',' };
  347. /*
  348. * These arrays hold the global variable values for the script instance.
  349. * The array lengths are determined by the script compilation,
  350. * and are found in ScriptObjCode.glblSizes.
  351. */
  352. public XMRInstArrays glblVars;
  353. public XMRInstAbstract()
  354. {
  355. glblVars = new XMRInstArrays(this);
  356. }
  357. /****************************************************************\
  358. * Abstract function prototypes. *
  359. * These functions require access to the OpenSim environment. *
  360. \****************************************************************/
  361. public abstract void CheckRunWork();
  362. public abstract void StateChange();
  363. [xmrMethodCallsCheckRunAttribute] // calls CheckRun()
  364. [xmrMethodIsNoisyAttribute] // calls Stub<somethingorother>()
  365. public abstract LSL_List xmrEventDequeue(double timeout, int returnMask1, int returnMask2,
  366. int backgroundMask1, int backgroundMask2);
  367. [xmrMethodIsNoisyAttribute] // calls Stub<somethingorother>()
  368. public abstract void xmrEventEnqueue(LSL_List ev);
  369. [xmrMethodIsNoisyAttribute] // calls Stub<somethingorother>()
  370. public abstract LSL_List xmrEventSaveDets();
  371. [xmrMethodIsNoisyAttribute] // calls Stub<somethingorother>()
  372. public abstract void xmrEventLoadDets(LSL_List dpList);
  373. /**************************************************\
  374. * Functions what don't require runtime support *
  375. * beyond what the compiler provides. *
  376. \**************************************************/
  377. protected int heapLimit;
  378. private int heapUsed;
  379. public virtual int UpdateHeapUse(int olduse, int newuse)
  380. {
  381. if(newuse <= olduse)
  382. Interlocked.Add(ref heapUsed, newuse - olduse);
  383. else
  384. {
  385. int newtotal, oldtotal;
  386. do
  387. {
  388. oldtotal = Interlocked.Add(ref heapUsed, 0);
  389. newtotal = oldtotal + newuse - olduse;
  390. if(newtotal > heapLimit)
  391. {
  392. // System.GC.Collect ();
  393. // System.GC.WaitForPendingFinalizers ();
  394. oldtotal = Interlocked.Add(ref heapUsed, 0);
  395. newtotal = oldtotal + newuse - olduse;
  396. if(newtotal > heapLimit)
  397. throw new OutOfHeapException(oldtotal, newtotal, heapLimit);
  398. }
  399. } while(Interlocked.CompareExchange(ref heapUsed, newtotal, oldtotal) != oldtotal);
  400. }
  401. return newuse;
  402. }
  403. public virtual void AddHeapUse(int delta)
  404. {
  405. Interlocked.Add(ref heapUsed, delta);
  406. }
  407. public int xmrHeapLeft()
  408. {
  409. return heapLimit - heapUsed;
  410. }
  411. public int xmrHeapUsed()
  412. {
  413. return heapUsed;
  414. }
  415. /**
  416. * @brief Call script's event handler function from the very beginning.
  417. * @param instance.stateCode = which state the event is happening in
  418. * @param instance.eventCode = which event is happening in that state
  419. * @returns when event handler has completed or throws an exception
  420. * with instance.eventCode = ScriptEventCode.None
  421. */
  422. public void CallSEH()
  423. {
  424. ScriptEventHandler seh;
  425. // CallMode_NORMAL: run event handler from the beginning normally
  426. // CallMode_RESTORE: restore event handler stack from stackFrames
  427. callMode = (stackFrames == null) ? XMRInstAbstract.CallMode_NORMAL :
  428. XMRInstAbstract.CallMode_RESTORE;
  429. while(true)
  430. {
  431. if(this.newStateCode < 0)
  432. {
  433. // Process event given by 'stateCode' and 'eventCode'.
  434. // The event handler should call CheckRun() as often as convenient.
  435. int newState = this.stateCode;
  436. seh = this.m_ObjCode.scriptEventHandlerTable[newState, (int)this.eventCode];
  437. if(seh != null)
  438. {
  439. try
  440. {
  441. seh(this);
  442. }
  443. catch(ScriptChangeStateException scse)
  444. {
  445. newState = scse.newState;
  446. }
  447. }
  448. this.ehArgs = null; // we are done with them and no args for
  449. // exit_state()/enter_state() anyway
  450. // The usual case is no state change.
  451. // Even a 'state <samestate>;' statement has no effect except to exit out.
  452. // It does not execute the state_exit() or state_entry() handlers.
  453. // See http://wiki.secondlife.com/wiki/State
  454. if(newState == this.stateCode)
  455. break;
  456. // Save new state in a more permanent location in case we
  457. // get serialized out while in the state_exit() handler.
  458. this.newStateCode = newState;
  459. }
  460. // Call old state's state_exit() handler.
  461. this.eventCode = ScriptEventCode.state_exit;
  462. seh = this.m_ObjCode.scriptEventHandlerTable[this.stateCode, (int)ScriptEventCode.state_exit];
  463. if(seh != null)
  464. {
  465. try
  466. {
  467. seh(this);
  468. }
  469. catch(ScriptChangeStateException scse)
  470. {
  471. this.newStateCode = scse.newState;
  472. }
  473. }
  474. // Switch over to the new state's state_entry() handler.
  475. this.stateCode = this.newStateCode;
  476. this.eventCode = ScriptEventCode.state_entry;
  477. this.newStateCode = -1;
  478. // Now that the old state can't possibly start any more activity,
  479. // cancel any listening handlers, etc, of the old state.
  480. this.StateChange();
  481. // Loop back to execute new state's state_entry() handler.
  482. }
  483. // Event no longer being processed.
  484. this.eventCode = ScriptEventCode.None;
  485. }
  486. /**
  487. * @brief For compatibility with old code.
  488. */
  489. public void CheckRun(int line)
  490. {
  491. CheckRunStack();
  492. }
  493. /**
  494. * @brief Called at beginning of complex functions to see if they
  495. * are nested too deep possibly in a recursive loop.
  496. */
  497. public void CheckRunStack()
  498. {
  499. if(m_StackLeft < stackLimit)
  500. throw new OutOfStackException();
  501. CheckRunQuick();
  502. }
  503. /**
  504. * @brief Called in each iteration of a loop to see if running too long.
  505. */
  506. public void CheckRunQuick()
  507. {
  508. // if (suspendOnCheckRunHold || suspendOnCheckRunTemp)
  509. CheckRunWork();
  510. }
  511. /**
  512. * @brief Called during CallMode_SAVE to create a stackframe save object that saves
  513. * local variables and calling point within the function.
  514. * @param funcName = name of function whose frame is being saved
  515. * @param callNo = call number (ie, return address) within function to restart at
  516. * @param nSaves = number of variables the function will save
  517. * @returns an object[nSaves] where function can save variables
  518. */
  519. public object[] CaptureStackFrame(string funcName, int callNo, int nSaves)
  520. {
  521. XMRStackFrame sf = new XMRStackFrame();
  522. sf.nextSF = stackFrames;
  523. sf.funcName = funcName;
  524. sf.callNo = callNo;
  525. sf.objArray = new object[nSaves];
  526. stackFrames = sf;
  527. return sf.objArray;
  528. }
  529. /**
  530. * @brief Called during CallMode_RESTORE to pop a stackframe object to restore
  531. * local variables and calling point within the function.
  532. * @param funcName = name of function whose frame is being restored
  533. * @returns the object[nSaves] where function can retrieve variables
  534. * callNo = as passed to CaptureStackFrame() indicating restart point
  535. */
  536. public object[] RestoreStackFrame(string funcName, out int callNo)
  537. {
  538. XMRStackFrame sf = stackFrames;
  539. if(sf.funcName != funcName)
  540. throw new Exception("frame mismatch " + sf.funcName + " vs " + funcName);
  541. callNo = sf.callNo;
  542. stackFrames = sf.nextSF;
  543. return sf.objArray;
  544. }
  545. /**
  546. * @brief Convert all LSL_Integers in a list to System.Int32s,
  547. * as required by llParcelMediaQuery().
  548. */
  549. public static LSL_List FixLLParcelMediaQuery(LSL_List oldlist)
  550. {
  551. object[] oldarray = oldlist.Data;
  552. int len = oldarray.Length;
  553. object[] newarray = new object[len];
  554. for(int i = 0; i < len; i++)
  555. {
  556. object obj = oldarray[i];
  557. if(obj is LSL_Integer)
  558. obj = (int)(LSL_Integer)obj;
  559. newarray[i] = obj;
  560. }
  561. return new LSL_List(newarray);
  562. }
  563. /**
  564. * @brief Convert *SOME* LSL_Integers in a list to System.Int32s,
  565. * as required by llParcelMediaCommandList().
  566. */
  567. public static LSL_List FixLLParcelMediaCommandList(LSL_List oldlist)
  568. {
  569. object[] oldarray = oldlist.Data;
  570. int len = oldarray.Length;
  571. object[] newarray = new object[len];
  572. int verbatim = 0;
  573. for(int i = 0; i < len; i++)
  574. {
  575. object obj = oldarray[i];
  576. if(--verbatim < 0)
  577. {
  578. if(obj is LSL_Integer)
  579. obj = (int)(LSL_Integer)obj;
  580. if(obj is int)
  581. {
  582. switch((int)obj)
  583. {
  584. case ScriptBaseClass.PARCEL_MEDIA_COMMAND_AUTO_ALIGN:
  585. // leave next integer as LSL_Integer
  586. verbatim = 1;
  587. break;
  588. case ScriptBaseClass.PARCEL_MEDIA_COMMAND_SIZE:
  589. // leave next two integers as LSL_Integer
  590. verbatim = 2;
  591. break;
  592. }
  593. }
  594. }
  595. newarray[i] = obj;
  596. }
  597. return new LSL_List(newarray);
  598. }
  599. public static int xmrHashCode(int i)
  600. {
  601. return i.GetHashCode();
  602. }
  603. public static int xmrHashCode(double f)
  604. {
  605. return f.GetHashCode();
  606. }
  607. public static int xmrHashCode(object o)
  608. {
  609. return o.GetHashCode();
  610. }
  611. public static int xmrHashCode(string s)
  612. {
  613. return s.GetHashCode();
  614. }
  615. public string xmrTypeName(object o)
  616. {
  617. /*
  618. * Basic types return constant strings of the script-visible type name.
  619. */
  620. if(o is XMR_Array)
  621. return "array";
  622. if(o is bool)
  623. return "bool";
  624. if(o is char)
  625. return "char";
  626. if(o is Exception)
  627. return "exception";
  628. if(o is double)
  629. return "float";
  630. if(o is float)
  631. return "float";
  632. if(o is LSL_Float)
  633. return "float";
  634. if(o is int)
  635. return "integer";
  636. if(o is LSL_Integer)
  637. return "integer";
  638. if(o is LSL_List)
  639. return "list";
  640. if(o is LSL_Rotation)
  641. return "rotation";
  642. if(o is LSL_String)
  643. return "string";
  644. if(o is string)
  645. return "string";
  646. if(o is LSL_Vector)
  647. return "vector";
  648. // A script-defined interface is represented as an array of delegates.
  649. // If that is the case, convert it to the object of the script-defined
  650. // class that is implementing the interface. This should let the next
  651. // step get the script-defined type name of the object.
  652. if(o is Delegate[])
  653. o = ((Delegate[])o)[0].Target;
  654. // If script-defined class instance, get the script-defined
  655. // type name.
  656. if(o is XMRSDTypeClObj)
  657. return ((XMRSDTypeClObj)o).sdtcClass.longName.val;
  658. // If it's a delegate, maybe we can look up its script-defined type name.
  659. Type ot = o.GetType();
  660. if(o is Delegate)
  661. {
  662. String os;
  663. if(m_ObjCode.sdDelTypes.TryGetValue(ot, out os))
  664. return os;
  665. }
  666. // Don't know what it is, get the C#-level type name.
  667. return ot.ToString();
  668. }
  669. /**
  670. * @brief Call the current state's event handler.
  671. * @param ev = as returned by xmrEventDequeue saying which event handler to call
  672. * and what argument list to pass to it. The llDetect...() parameters
  673. * are as currently set for the script (use xmrEventLoadDets to set how
  674. * you want them to be different).
  675. */
  676. public void xmrEventCallHandler(LSL_List ev)
  677. {
  678. object[] data = ev.Data;
  679. int evc = (int)(ev.GetLSLIntegerItem(0).value & 0xFFFFFFFF);
  680. ScriptEventHandler seh = m_ObjCode.scriptEventHandlerTable[stateCode, evc];
  681. if(seh != null)
  682. {
  683. int nargs = data.Length - 1;
  684. object[] args = new object[nargs];
  685. Array.Copy(data, 1, args, 0, nargs);
  686. object[] saveEHArgs = this.ehArgs;
  687. ScriptEventCode saveEventCode = this.eventCode;
  688. this.ehArgs = args;
  689. this.eventCode = (ScriptEventCode)evc;
  690. seh(this);
  691. this.ehArgs = saveEHArgs;
  692. this.eventCode = saveEventCode;
  693. }
  694. }
  695. /**
  696. * @brief These conversions throw exceptions if there is anything stinky...
  697. */
  698. public double xmrString2Float(string s)
  699. {
  700. return double.Parse(s, CultureInfo.InvariantCulture);
  701. }
  702. public int xmrString2Integer(string s)
  703. {
  704. s = s.Trim();
  705. if(s.StartsWith("0x") || s.StartsWith("0X"))
  706. return int.Parse(s.Substring(2), NumberStyles.HexNumber);
  707. return int.Parse(s, CultureInfo.InvariantCulture);
  708. }
  709. public LSL_Rotation xmrString2Rotation(string s)
  710. {
  711. s = s.Trim();
  712. if(!s.StartsWith("<") || !s.EndsWith(">"))
  713. throw new FormatException("doesn't begin with < and end with >");
  714. s = s.Substring(1, s.Length - 2);
  715. string[] splitup = s.Split(justacomma, 5);
  716. if(splitup.Length != 4)
  717. throw new FormatException("doesn't have exactly 3 commas");
  718. double x = double.Parse(splitup[0], CultureInfo.InvariantCulture);
  719. double y = double.Parse(splitup[1], CultureInfo.InvariantCulture);
  720. double z = double.Parse(splitup[2], CultureInfo.InvariantCulture);
  721. double w = double.Parse(splitup[3], CultureInfo.InvariantCulture);
  722. return new LSL_Rotation(x, y, z, w);
  723. }
  724. public LSL_Vector xmrString2Vector(string s)
  725. {
  726. s = s.Trim();
  727. if(!s.StartsWith("<") || !s.EndsWith(">"))
  728. throw new FormatException("doesn't begin with < and end with >");
  729. s = s.Substring(1, s.Length - 2);
  730. string[] splitup = s.Split(justacomma, 4);
  731. if(splitup.Length != 3)
  732. throw new FormatException("doesn't have exactly 2 commas");
  733. double x = double.Parse(splitup[0], CultureInfo.InvariantCulture);
  734. double y = double.Parse(splitup[1], CultureInfo.InvariantCulture);
  735. double z = double.Parse(splitup[2], CultureInfo.InvariantCulture);
  736. return new LSL_Vector(x, y, z);
  737. }
  738. /**
  739. * @brief Access C#-style formatted numeric conversions.
  740. */
  741. public string xmrFloat2String(double val, string fmt)
  742. {
  743. return val.ToString(fmt, CultureInfo.InvariantCulture);
  744. }
  745. public string xmrInteger2String(int val, string fmt)
  746. {
  747. return val.ToString(fmt, CultureInfo.InvariantCulture);
  748. }
  749. public string xmrRotation2String(LSL_Rotation val, string fmt)
  750. {
  751. return "<" + val.x.ToString(fmt, CultureInfo.InvariantCulture) + "," +
  752. val.y.ToString(fmt, CultureInfo.InvariantCulture) + "," +
  753. val.z.ToString(fmt, CultureInfo.InvariantCulture) + "," +
  754. val.s.ToString(fmt, CultureInfo.InvariantCulture) + ">";
  755. }
  756. public string xmrVector2String(LSL_Vector val, string fmt)
  757. {
  758. return "<" + val.x.ToString(fmt, CultureInfo.InvariantCulture) + "," +
  759. val.y.ToString(fmt, CultureInfo.InvariantCulture) + "," +
  760. val.z.ToString(fmt, CultureInfo.InvariantCulture) + ">";
  761. }
  762. /**
  763. * @brief Get a delegate for a script-defined function.
  764. * @param name = name of the function including arg types, eg,
  765. * "Verify(array,list,string)"
  766. * @param sig = script-defined type name
  767. * @param targ = function's 'this' pointer or null if static
  768. * @returns delegate for the script-defined function
  769. */
  770. public Delegate GetScriptMethodDelegate(string name, string sig, object targ)
  771. {
  772. DynamicMethod dm = m_ObjCode.dynamicMethods[name];
  773. TokenDeclSDTypeDelegate dt = (TokenDeclSDTypeDelegate)m_ObjCode.sdObjTypesName[sig];
  774. return dm.CreateDelegate(dt.GetSysType(), targ);
  775. }
  776. /**
  777. * @brief Try to cast the thrown object to the given script-defined type.
  778. * @param thrown = what object was thrown
  779. * @param inst = what script instance we are running in
  780. * @param sdtypeindex = script-defined type to try to cast it to
  781. * @returns null: thrown is not castable to sdtypename
  782. * else: an object casted to sdtypename
  783. */
  784. public static object XMRSDTypeCatchTryCastToSDType(object thrown, XMRInstAbstract inst, int sdtypeindex)
  785. {
  786. TokenDeclSDType sdType = inst.m_ObjCode.sdObjTypesIndx[sdtypeindex];
  787. // If it is a script-defined interface object, convert to the original XMRSDTypeClObj.
  788. if(thrown is Delegate[])
  789. {
  790. thrown = ((Delegate[])thrown)[0].Target;
  791. }
  792. // If it is a script-defined delegate object, make sure it is an instance of the expected type.
  793. if(thrown is Delegate)
  794. {
  795. Type ot = thrown.GetType();
  796. Type tt = sdType.GetSysType();
  797. return (ot == tt) ? thrown : null;
  798. }
  799. // If it is a script-defined class object, make sure it is an instance of the expected class.
  800. if(thrown is XMRSDTypeClObj)
  801. {
  802. // Step from the object's actual class rootward.
  803. // If we find the requested class along the way, the cast is valid.
  804. // If we run off the end of the root, the cast is not valid.
  805. for(TokenDeclSDTypeClass ac = ((XMRSDTypeClObj)thrown).sdtcClass; ac != null; ac = ac.extends)
  806. {
  807. if(ac == sdType)
  808. return thrown;
  809. }
  810. }
  811. // Don't know what it is, assume it is not what caller wants.
  812. return null;
  813. }
  814. /**
  815. * @brief Allocate and access fixed-dimension arrays.
  816. */
  817. public static object xmrFixedArrayAllocC(int len)
  818. {
  819. return new char[len];
  820. }
  821. public static object xmrFixedArrayAllocF(int len)
  822. {
  823. return new double[len];
  824. }
  825. public static object xmrFixedArrayAllocI(int len)
  826. {
  827. return new int[len];
  828. }
  829. public static object xmrFixedArrayAllocO(int len)
  830. {
  831. return new object[len];
  832. }
  833. public static char xmrFixedArrayGetC(object arr, int idx)
  834. {
  835. return ((char[])arr)[idx];
  836. }
  837. public static double xmrFixedArrayGetF(object arr, int idx)
  838. {
  839. return ((double[])arr)[idx];
  840. }
  841. public static int xmrFixedArrayGetI(object arr, int idx)
  842. {
  843. return ((int[])arr)[idx];
  844. }
  845. public static object xmrFixedArrayGetO(object arr, int idx)
  846. {
  847. return ((object[])arr)[idx];
  848. }
  849. public static void xmrFixedArraySetC(object arr, int idx, char val)
  850. {
  851. ((char[])arr)[idx] = val;
  852. }
  853. public static void xmrFixedArraySetF(object arr, int idx, double val)
  854. {
  855. ((double[])arr)[idx] = val;
  856. }
  857. public static void xmrFixedArraySetI(object arr, int idx, int val)
  858. {
  859. ((int[])arr)[idx] = val;
  860. }
  861. public static void xmrFixedArraySetO(object arr, int idx, object val)
  862. {
  863. ((object[])arr)[idx] = val;
  864. }
  865. /**
  866. * @brief Copy from one script-defined array to another.
  867. * @param srcobj = source script-defined array class object pointer
  868. * @param srcstart = offset in source array to start copying from
  869. * @param dstobj = destination script-defined array class object pointer
  870. * @param dststart = offset in destination arry to start copying to
  871. * @param count = number of elements to copy
  872. */
  873. public static void xmrArrayCopy(object srcobj, int srcstart, object dstobj, int dststart, int count)
  874. {
  875. // The script writer should only pass us script-defined class objects.
  876. // Throw exception otherwise.
  877. XMRSDTypeClObj srcsdt = (XMRSDTypeClObj)srcobj;
  878. XMRSDTypeClObj dstsdt = (XMRSDTypeClObj)dstobj;
  879. // Get the script-visible type name of the arrays, brackets and all.
  880. string srctypename = srcsdt.sdtcClass.longName.val;
  881. string dsttypename = dstsdt.sdtcClass.longName.val;
  882. // The part before the first '[' of each should match exactly,
  883. // meaning the basic data type (eg, float, List<string>) is the same.
  884. // And there must be a '[' in each meaning that it is a script-defined array type.
  885. int i = srctypename.IndexOf('[');
  886. int j = dsttypename.IndexOf('[');
  887. if((i < 0) || (j < 0))
  888. throw new InvalidCastException("non-array passed: " + srctypename + " and/or " + dsttypename);
  889. if((i != j) || !srctypename.StartsWith(dsttypename.Substring(0, j)))
  890. throw new ArrayTypeMismatchException(srctypename + " vs " + dsttypename);
  891. // The number of brackets must match exactly.
  892. // This permits copying from something like a float[,][] to something like a float[][].
  893. // But you cannot copy from a float[][] to a float[] or wisa wersa.
  894. // Counting either '[' or ']' would work equally well.
  895. int srclen = srctypename.Length;
  896. int dstlen = dsttypename.Length;
  897. int srcjags = 0;
  898. int dstjags = 0;
  899. while(++i < srclen)
  900. if(srctypename[i] == ']')
  901. srcjags++;
  902. while(++j < dstlen)
  903. if(dsttypename[j] == ']')
  904. dstjags++;
  905. if(dstjags != srcjags)
  906. throw new ArrayTypeMismatchException(srctypename + " vs " + dsttypename);
  907. // Perform the copy.
  908. Array srcarray = (Array)srcsdt.instVars.iarObjects[0];
  909. Array dstarray = (Array)dstsdt.instVars.iarObjects[0];
  910. Array.Copy(srcarray, srcstart, dstarray, dststart, count);
  911. }
  912. /**
  913. * @brief Copy from an array to a list.
  914. * @param srcar = the array to copy from
  915. * @param start = where to start in the array
  916. * @param count = number of elements
  917. * @returns the list
  918. */
  919. public static LSL_List xmrArray2List(object srcar, int start, int count)
  920. {
  921. // Get the script-visible type of the array.
  922. // We only do arrays.
  923. XMRSDTypeClObj array = (XMRSDTypeClObj)srcar;
  924. TokenDeclSDTypeClass sdtClass = array.sdtcClass;
  925. if(sdtClass.arrayOfRank == 0)
  926. throw new InvalidCastException("only do arrays not " + sdtClass.longName.val);
  927. // Validate objects they want to put in the list.
  928. // We can't allow anything funky that OpenSim runtime doesn't expect.
  929. Array srcarray = (Array)array.instVars.iarObjects[0];
  930. object[] output = new object[count];
  931. for(int i = 0; i < count; i++)
  932. {
  933. object src = srcarray.GetValue(i + start);
  934. if(src == null)
  935. throw new NullReferenceException("null element " + i);
  936. if(src is double)
  937. {
  938. output[i] = new LSL_Float((double)src);
  939. continue;
  940. }
  941. if(src is int)
  942. {
  943. output[i] = new LSL_Integer((int)src);
  944. continue;
  945. }
  946. if(src is LSL_Rotation)
  947. {
  948. output[i] = src;
  949. continue;
  950. }
  951. if(src is LSL_Vector)
  952. {
  953. output[i] = src;
  954. continue;
  955. }
  956. if(src is string)
  957. {
  958. output[i] = new LSL_String((string)src);
  959. continue;
  960. }
  961. throw new InvalidCastException("invalid element " + i + " type " + src.GetType().Name);
  962. }
  963. // Make a list out of that now immutable array.
  964. return new LSL_List(output);
  965. }
  966. /**
  967. * @brief Copy from a list to an array.
  968. * @param srclist = list to copy from
  969. * @param srcstart = where to start in the list
  970. * @param dstobj = array to copy to
  971. * @param dststart = where to start in the array
  972. * @param count = number of elements
  973. */
  974. public static void xmrList2Array(LSL_List srclist, int srcstart, object dstobj, int dststart, int count)
  975. {
  976. // Get the script-visible type of the destination.
  977. // We only do arrays.
  978. XMRSDTypeClObj dstarray = (XMRSDTypeClObj)dstobj;
  979. TokenDeclSDTypeClass sdtClass = dstarray.sdtcClass;
  980. if(sdtClass.arrayOfType == null)
  981. throw new InvalidCastException("only do arrays not " + sdtClass.longName.val);
  982. // Copy from the immutable array to the mutable array.
  983. // Strip off any LSL wrappers as the script code doesn't expect any.
  984. object[] srcarr = srclist.Data;
  985. Array dstarr = (Array)dstarray.instVars.iarObjects[0];
  986. for(int i = 0; i < count; i++)
  987. {
  988. object obj = srcarr[i + srcstart];
  989. if(obj is LSL_Float)
  990. obj = ((LSL_Float)obj).value;
  991. else if(obj is LSL_Integer)
  992. obj = ((LSL_Integer)obj).value;
  993. else if(obj is LSL_String)
  994. obj = ((LSL_String)obj).m_string;
  995. dstarr.SetValue(obj, i + dststart);
  996. }
  997. }
  998. /**
  999. * @brief Copy from an array of characters to a string.
  1000. * @param srcar = the array to copy from
  1001. * @param start = where to start in the array
  1002. * @param count = number of elements
  1003. * @returns the string
  1004. */
  1005. public static string xmrChars2String(object srcar, int start, int count)
  1006. {
  1007. // Make sure they gave us a script-defined array object.
  1008. XMRSDTypeClObj array = (XMRSDTypeClObj)srcar;
  1009. TokenDeclSDTypeClass sdtClass = array.sdtcClass;
  1010. if(sdtClass.arrayOfRank == 0)
  1011. throw new InvalidCastException("only do arrays not " + sdtClass.longName.val);
  1012. // We get a type cast error from mono if they didn't give us a character array.
  1013. // But if it is ok, create a string from the requested characters.
  1014. char[] srcarray = (char[])array.instVars.iarObjects[0];
  1015. return new string(srcarray, start, count);
  1016. }
  1017. /**
  1018. * @brief Copy from a string to a character array.
  1019. * @param srcstr = string to copy from
  1020. * @param srcstart = where to start in the string
  1021. * @param dstobj = array to copy to
  1022. * @param dststart = where to start in the array
  1023. * @param count = number of elements
  1024. */
  1025. public static void xmrString2Chars(string srcstr, int srcstart, object dstobj, int dststart, int count)
  1026. {
  1027. // Make sure they gave us a script-defined array object.
  1028. XMRSDTypeClObj dstarray = (XMRSDTypeClObj)dstobj;
  1029. TokenDeclSDTypeClass sdtClass = dstarray.sdtcClass;
  1030. if(sdtClass.arrayOfType == null)
  1031. throw new InvalidCastException("only do arrays not " + sdtClass.longName.val);
  1032. // We get a type cast error from mono if they didn't give us a character array.
  1033. // But if it is ok, copy from the string to the character array.
  1034. char[] dstarr = (char[])dstarray.instVars.iarObjects[0];
  1035. for(int i = 0; i < count; i++)
  1036. dstarr[i + dststart] = srcstr[i + srcstart];
  1037. }
  1038. /**
  1039. * @brief Exception-related runtime calls.
  1040. */
  1041. // Return exception message (no type information just the message)
  1042. public static string xmrExceptionMessage(Exception ex)
  1043. {
  1044. return ex.Message;
  1045. }
  1046. // Return stack trace (no type or message, just stack trace lines: at ... \n)
  1047. public string xmrExceptionStackTrace(Exception ex)
  1048. {
  1049. return XMRExceptionStackString(ex);
  1050. }
  1051. // Return value thrown by a throw statement
  1052. public static object xmrExceptionThrownValue(Exception ex)
  1053. {
  1054. return ((ScriptThrownException)ex).thrown;
  1055. }
  1056. // Return exception's short type name, eg, NullReferenceException, ScriptThrownException, etc.
  1057. public static string xmrExceptionTypeName(Exception ex)
  1058. {
  1059. return ex.GetType().Name;
  1060. }
  1061. // internal use only: converts any IL addresses in script-defined methods to source location equivalent
  1062. // Mono ex.StackTrace:
  1063. // at OpenSim.Region.ScriptEngine.YEngine.TypeCast.ObjectToInteger (System.Object x) [0x0005e] in /home/kunta/opensim-0.9/addon-modules/YEngine/Module/MMRScriptTypeCast.cs:750
  1064. // at (wrapper dynamic-method) System.Object:default state_entry (OpenSim.Region.ScriptEngine.YEngine.XMRInstAbstract) [0x00196]
  1065. // Microsoft ex.StackTrace:
  1066. // at OpenSim.Region.ScriptEngine.YEngine.TypeCast.ObjectToInteger(Object x) in C:\Users\mrieker\opensim-0.9-source\addon-modules\YEngine\Module\MMRScriptTypeCast.cs:line 750
  1067. // at default state_entry (XMRInstAbstract )
  1068. public string XMRExceptionStackString(Exception ex)
  1069. {
  1070. string stwhole = ex.StackTrace;
  1071. string[] stlines = stwhole.Split(new char[] { '\n' });
  1072. StringBuilder sb = new StringBuilder();
  1073. foreach(string st in stlines)
  1074. {
  1075. string stline = st.Trim();
  1076. if(stline == "")
  1077. continue;
  1078. // strip 'at' off the front of line
  1079. if(stline.StartsWith("at "))
  1080. {
  1081. stline = stline.Substring(3);
  1082. }
  1083. // strip '(wrapper ...' off front of line
  1084. if(stline.StartsWith("(wrapper dynamic-method) System.Object:"))
  1085. {
  1086. stline = stline.Substring(39);
  1087. }
  1088. // strip the (systemargtypes...) from our dynamic method names cuz it's messy
  1089. // 'default state_entry (XMRInstAbstract )'
  1090. // => 'default state_entry'
  1091. // 'CallSomethingThatThrows(string) (OpenSim.Region.ScriptEngine.YEngine.XMRInstance,string)'
  1092. // => 'CallSomethingThatThrows(string)'
  1093. int kwin = stline.IndexOf(" in ");
  1094. int br0x = stline.IndexOf(" [0x");
  1095. int pastCloseParen = stline.Length;
  1096. if((kwin >= 0) && (br0x >= 0))
  1097. pastCloseParen = Math.Min(kwin, br0x);
  1098. else if(kwin >= 0)
  1099. pastCloseParen = kwin;
  1100. else if(br0x >= 0)
  1101. pastCloseParen = br0x;
  1102. else
  1103. pastCloseParen = stline.Length;
  1104. int endFuncName = pastCloseParen;
  1105. while(endFuncName > 0)
  1106. {
  1107. if(stline[--endFuncName] == '(')
  1108. break;
  1109. }
  1110. while(endFuncName > 0)
  1111. {
  1112. if(stline[endFuncName - 1] != ' ')
  1113. break;
  1114. --endFuncName;
  1115. }
  1116. string funcName = stline.Substring(0, endFuncName);
  1117. KeyValuePair<int, ScriptSrcLoc>[] srcLocs;
  1118. if(m_ObjCode.scriptSrcLocss.TryGetValue(funcName, out srcLocs))
  1119. {
  1120. stline = stline.Substring(0, endFuncName) + stline.Substring(pastCloseParen);
  1121. kwin = stline.IndexOf(" in ");
  1122. br0x = stline.IndexOf(" [0x");
  1123. }
  1124. // keyword 'in' is just before filename:linenumber that goes to end of line
  1125. // trim up the corresponding filename (ie, remove useless path info)
  1126. if(kwin >= 0)
  1127. {
  1128. int begfn = kwin + 4;
  1129. int slash = begfn;
  1130. for(int i = begfn; i < stline.Length; i++)
  1131. {
  1132. char c = stline[i];
  1133. if((c == '/') || (c == '\\'))
  1134. slash = i + 1;
  1135. }
  1136. stline = stline.Substring(0, begfn) + stline.Substring(slash);
  1137. }
  1138. else if(srcLocs != null)
  1139. {
  1140. // no filename:linenumber info, try to convert IL offset
  1141. if(br0x >= 0)
  1142. {
  1143. try
  1144. {
  1145. int begiloffs = br0x + 4;
  1146. int endiloffs = stline.IndexOf("]", begiloffs);
  1147. int iloffset = int.Parse(stline.Substring(begiloffs, endiloffs - begiloffs),
  1148. System.Globalization.NumberStyles.HexNumber);
  1149. int srcLocIdx;
  1150. int srcLocLen = srcLocs.Length;
  1151. for(srcLocIdx = 0; ++srcLocIdx < srcLocLen;)
  1152. {
  1153. if(iloffset < srcLocs[srcLocIdx].Key)
  1154. break;
  1155. }
  1156. ScriptSrcLoc srcLoc = srcLocs[--srcLocIdx].Value;
  1157. stline = stline.Substring(0, br0x) + " <" +
  1158. srcLoc.file + '(' + srcLoc.line + ',' + srcLoc.posn + ")>";
  1159. }
  1160. catch
  1161. {
  1162. }
  1163. }
  1164. }
  1165. // put edited line in output string
  1166. if(sb.Length > 0)
  1167. sb.AppendLine();
  1168. sb.Append(" at ");
  1169. sb.Append(stline);
  1170. }
  1171. return sb.ToString();
  1172. }
  1173. /**
  1174. * @brief List fonts available.
  1175. */
  1176. public LSL_List xmrFontsAvailable()
  1177. {
  1178. System.Drawing.FontFamily[] families = System.Drawing.FontFamily.Families;
  1179. object[] output = new object[families.Length];
  1180. for(int i = 0; i < families.Length; i++)
  1181. output[i] = new LSL_String(families[i].Name);
  1182. return new LSL_List(output);
  1183. }
  1184. /************************\
  1185. * Used by decompiler *
  1186. \************************/
  1187. public bool xmrRotationToBool(LSL_Rotation x)
  1188. {
  1189. return TypeCast.RotationToBool(x);
  1190. }
  1191. public bool xmrStringToBool(string x)
  1192. {
  1193. return TypeCast.StringToBool(x);
  1194. }
  1195. public bool xmrVectorToBool(LSL_Vector x)
  1196. {
  1197. return TypeCast.VectorToBool(x);
  1198. }
  1199. public bool xmrKeyToBool(string x)
  1200. {
  1201. return TypeCast.KeyToBool(x);
  1202. }
  1203. public bool xmrListToBool(LSL_List x)
  1204. {
  1205. return TypeCast.ListToBool(x);
  1206. }
  1207. public int xmrStringCompare(string x, string y)
  1208. {
  1209. return string.Compare(x, y);
  1210. }
  1211. /**
  1212. * @brief types of data we serialize
  1213. */
  1214. private enum Ser: byte
  1215. {
  1216. NULL,
  1217. EVENTCODE,
  1218. LSLFLOAT,
  1219. LSLINT,
  1220. LSLKEY,
  1221. LSLLIST,
  1222. LSLROT,
  1223. LSLSTR,
  1224. LSLVEC,
  1225. SYSARRAY,
  1226. SYSDOUB,
  1227. SYSFLOAT,
  1228. SYSINT,
  1229. SYSSTR,
  1230. XMRARRAY,
  1231. DUPREF,
  1232. SYSBOOL,
  1233. XMRINST,
  1234. DELEGATE,
  1235. SDTCLOBJ,
  1236. SYSCHAR,
  1237. SYSERIAL,
  1238. THROWNEX
  1239. }
  1240. /**
  1241. * @brief Write state out to a stream.
  1242. * Do not change script state.
  1243. */
  1244. public void MigrateOut(BinaryWriter mow)
  1245. {
  1246. try
  1247. {
  1248. this.migrateOutWriter = mow;
  1249. this.migrateOutObjects = new Dictionary<object, int>();
  1250. this.migrateOutLists = new Dictionary<object[], ObjLslList>();
  1251. this.SendObjValue(this.ehArgs);
  1252. mow.Write(this.doGblInit);
  1253. mow.Write(this.stateCode);
  1254. mow.Write((int)this.eventCode);
  1255. this.glblVars.SendArrays(this.SendObjValue);
  1256. if(this.newStateCode >= 0)
  1257. {
  1258. mow.Write("**newStateCode**");
  1259. mow.Write(this.newStateCode);
  1260. }
  1261. for(XMRStackFrame thisSF = this.stackFrames; thisSF != null; thisSF = thisSF.nextSF)
  1262. {
  1263. mow.Write(thisSF.funcName);
  1264. mow.Write(thisSF.callNo);
  1265. this.SendObjValue(thisSF.objArray);
  1266. }
  1267. mow.Write("");
  1268. }
  1269. finally
  1270. {
  1271. this.migrateOutWriter = null;
  1272. this.migrateOutObjects = null;
  1273. this.migrateOutLists = null;
  1274. }
  1275. }
  1276. /**
  1277. * @brief Write an object to the output stream.
  1278. * @param graph = object to send
  1279. */
  1280. private BinaryWriter migrateOutWriter;
  1281. private Dictionary<object, int> migrateOutObjects;
  1282. private Dictionary<object[], ObjLslList> migrateOutLists;
  1283. public void SendObjValue(object graph)
  1284. {
  1285. BinaryWriter mow = this.migrateOutWriter;
  1286. // Value types (including nulls) are always output directly.
  1287. if(graph == null)
  1288. {
  1289. mow.Write((byte)Ser.NULL);
  1290. return;
  1291. }
  1292. if(graph is ScriptEventCode)
  1293. {
  1294. mow.Write((byte)Ser.EVENTCODE);
  1295. mow.Write((int)graph);
  1296. return;
  1297. }
  1298. if(graph is LSL_Float)
  1299. {
  1300. mow.Write((byte)Ser.LSLFLOAT);
  1301. mow.Write((double)((LSL_Float)graph).value);
  1302. return;
  1303. }
  1304. if(graph is LSL_Integer)
  1305. {
  1306. mow.Write((byte)Ser.LSLINT);
  1307. mow.Write((int)((LSL_Integer)graph).value);
  1308. return;
  1309. }
  1310. if(graph is LSL_Key)
  1311. {
  1312. mow.Write((byte)Ser.LSLKEY);
  1313. LSL_Key key = (LSL_Key)graph;
  1314. SendObjValue(key.m_string); // m_string can be null
  1315. return;
  1316. }
  1317. if(graph is LSL_Rotation)
  1318. {
  1319. mow.Write((byte)Ser.LSLROT);
  1320. mow.Write((double)((LSL_Rotation)graph).x);
  1321. mow.Write((double)((LSL_Rotation)graph).y);
  1322. mow.Write((double)((LSL_Rotation)graph).z);
  1323. mow.Write((double)((LSL_Rotation)graph).s);
  1324. return;
  1325. }
  1326. if(graph is LSL_String)
  1327. {
  1328. mow.Write((byte)Ser.LSLSTR);
  1329. LSL_String str = (LSL_String)graph;
  1330. SendObjValue(str.m_string); // m_string can be null
  1331. return;
  1332. }
  1333. if(graph is LSL_Vector)
  1334. {
  1335. mow.Write((byte)Ser.LSLVEC);
  1336. mow.Write((double)((LSL_Vector)graph).x);
  1337. mow.Write((double)((LSL_Vector)graph).y);
  1338. mow.Write((double)((LSL_Vector)graph).z);
  1339. return;
  1340. }
  1341. if(graph is bool)
  1342. {
  1343. mow.Write((byte)Ser.SYSBOOL);
  1344. mow.Write((bool)graph);
  1345. return;
  1346. }
  1347. if(graph is double)
  1348. {
  1349. mow.Write((byte)Ser.SYSDOUB);
  1350. mow.Write((double)graph);
  1351. return;
  1352. }
  1353. if(graph is float)
  1354. {
  1355. mow.Write((byte)Ser.SYSFLOAT);
  1356. mow.Write((float)graph);
  1357. return;
  1358. }
  1359. if(graph is int)
  1360. {
  1361. mow.Write((byte)Ser.SYSINT);
  1362. mow.Write((int)graph);
  1363. return;
  1364. }
  1365. if(graph is char)
  1366. {
  1367. mow.Write((byte)Ser.SYSCHAR);
  1368. mow.Write((char)graph);
  1369. return;
  1370. }
  1371. // Script instance pointer is always just that.
  1372. if(graph == this)
  1373. {
  1374. mow.Write((byte)Ser.XMRINST);
  1375. return;
  1376. }
  1377. // Convert lists to object type.
  1378. // This is compatible with old migration data and also
  1379. // two vars pointing to same list won't duplicate it.
  1380. if(graph is LSL_List)
  1381. {
  1382. object[] data = ((LSL_List)graph).Data;
  1383. ObjLslList oll;
  1384. if(!this.migrateOutLists.TryGetValue(data, out oll))
  1385. {
  1386. oll = new ObjLslList();
  1387. oll.objarray = data;
  1388. this.migrateOutLists[data] = oll;
  1389. }
  1390. graph = oll;
  1391. }
  1392. // If this same exact object was already serialized,
  1393. // just output an index telling the receiver to use
  1394. // that same old object, rather than creating a whole
  1395. // new object with the same values. Also this prevents
  1396. // self-referencing objects (like arrays) from causing
  1397. // an infinite loop.
  1398. int ident;
  1399. if(this.migrateOutObjects.TryGetValue(graph, out ident))
  1400. {
  1401. mow.Write((byte)Ser.DUPREF);
  1402. mow.Write(ident);
  1403. return;
  1404. }
  1405. // Object not seen before, save its address with an unique
  1406. // ident number that the receiver can easily regenerate.
  1407. ident = this.migrateOutObjects.Count;
  1408. this.migrateOutObjects.Add(graph, ident);
  1409. // Now output the object's value(s).
  1410. // If the object self-references, the object is alreay entered
  1411. // in the dictionary and so the self-reference will just emit
  1412. // a DUPREF tag instead of trying to output the whole object
  1413. // again.
  1414. if(graph is ObjLslList)
  1415. {
  1416. mow.Write((byte)Ser.LSLLIST);
  1417. ObjLslList oll = (ObjLslList)graph;
  1418. SendObjValue(oll.objarray);
  1419. }
  1420. else if(graph is XMR_Array)
  1421. {
  1422. mow.Write((byte)Ser.XMRARRAY);
  1423. ((XMR_Array)graph).SendArrayObj(this.SendObjValue);
  1424. }
  1425. else if(graph is Array)
  1426. {
  1427. Array array = (Array)graph;
  1428. mow.Write((byte)Ser.SYSARRAY);
  1429. mow.Write(SysType2String(array.GetType().GetElementType()));
  1430. mow.Write((int)array.Length);
  1431. for(int i = 0; i < array.Length; i++)
  1432. this.SendObjValue(array.GetValue(i));
  1433. }
  1434. else if(graph is string)
  1435. {
  1436. mow.Write((byte)Ser.SYSSTR);
  1437. mow.Write((string)graph);
  1438. }
  1439. else if(graph is Delegate)
  1440. {
  1441. Delegate del = (Delegate)graph;
  1442. mow.Write((byte)Ser.DELEGATE);
  1443. mow.Write(del.Method.Name);
  1444. Type delType = del.GetType();
  1445. foreach(KeyValuePair<string, TokenDeclSDType> kvp in m_ObjCode.sdObjTypesName)
  1446. {
  1447. TokenDeclSDType sdt = kvp.Value;
  1448. if(sdt is TokenDeclSDTypeDelegate)
  1449. {
  1450. TokenDeclSDTypeDelegate sdtd = (TokenDeclSDTypeDelegate)sdt;
  1451. if(sdtd.GetSysType() == delType)
  1452. {
  1453. mow.Write(kvp.Key);
  1454. goto found;
  1455. }
  1456. }
  1457. }
  1458. throw new Exception("cant find script-defined delegate for " + del.Method.Name + " type " + del.GetType());
  1459. found:
  1460. SendObjValue(del.Target);
  1461. }
  1462. else if(graph is XMRSDTypeClObj)
  1463. {
  1464. mow.Write((byte)Ser.SDTCLOBJ);
  1465. ((XMRSDTypeClObj)graph).Capture(this.SendObjValue);
  1466. }
  1467. else if(graph is ScriptThrownException)
  1468. {
  1469. MemoryStream memoryStream = new MemoryStream();
  1470. System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bformatter =
  1471. new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
  1472. bformatter.Serialize(memoryStream, graph);
  1473. byte[] rawBytes = memoryStream.ToArray();
  1474. mow.Write((byte)Ser.THROWNEX);
  1475. mow.Write((int)rawBytes.Length);
  1476. mow.Write(rawBytes);
  1477. SendObjValue(((ScriptThrownException)graph).thrown);
  1478. }
  1479. else
  1480. {
  1481. MemoryStream memoryStream = new MemoryStream();
  1482. System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bformatter =
  1483. new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
  1484. bformatter.Serialize(memoryStream, graph);
  1485. byte[] rawBytes = memoryStream.ToArray();
  1486. mow.Write((byte)Ser.SYSERIAL);
  1487. mow.Write((int)rawBytes.Length);
  1488. mow.Write(rawBytes);
  1489. }
  1490. }
  1491. /**
  1492. * @brief Use short strings for known type names.
  1493. */
  1494. private static string SysType2String(Type type)
  1495. {
  1496. if(type.IsArray && (type.GetArrayRank() == 1))
  1497. {
  1498. string str = KnownSysType2String(type.GetElementType());
  1499. if(str != null)
  1500. return str + "[]";
  1501. }
  1502. else
  1503. {
  1504. string str = KnownSysType2String(type);
  1505. if(str != null)
  1506. return str;
  1507. }
  1508. return type.ToString();
  1509. }
  1510. private static string KnownSysType2String(Type type)
  1511. {
  1512. if(type == typeof(bool))
  1513. return "bo";
  1514. if(type == typeof(char))
  1515. return "ch";
  1516. if(type == typeof(Delegate))
  1517. return "de";
  1518. if(type == typeof(double))
  1519. return "do";
  1520. if(type == typeof(float))
  1521. return "fl";
  1522. if(type == typeof(int))
  1523. return "in";
  1524. if(type == typeof(LSL_List))
  1525. return "li";
  1526. if(type == typeof(object))
  1527. return "ob";
  1528. if(type == typeof(LSL_Rotation))
  1529. return "ro";
  1530. if(type == typeof(XMRSDTypeClObj))
  1531. return "sc";
  1532. if(type == typeof(string))
  1533. return "st";
  1534. if(type == typeof(LSL_Vector))
  1535. return "ve";
  1536. if(type == typeof(XMR_Array))
  1537. return "xa";
  1538. return null;
  1539. }
  1540. private static Type String2SysType(string str)
  1541. {
  1542. if(str.EndsWith("[]"))
  1543. return String2SysType(str.Substring(0, str.Length - 2)).MakeArrayType();
  1544. if(str == "bo")
  1545. return typeof(bool);
  1546. if(str == "ch")
  1547. return typeof(char);
  1548. if(str == "de")
  1549. return typeof(Delegate);
  1550. if(str == "do")
  1551. return typeof(double);
  1552. if(str == "fl")
  1553. return typeof(float);
  1554. if(str == "in")
  1555. return typeof(int);
  1556. if(str == "li")
  1557. return typeof(LSL_List);
  1558. if(str == "ob")
  1559. return typeof(object);
  1560. if(str == "ro")
  1561. return typeof(LSL_Rotation);
  1562. if(str == "sc")
  1563. return typeof(XMRSDTypeClObj);
  1564. if(str == "st")
  1565. return typeof(string);
  1566. if(str == "ve")
  1567. return typeof(LSL_Vector);
  1568. if(str == "xa")
  1569. return typeof(XMR_Array);
  1570. return Type.GetType(str, true);
  1571. }
  1572. /**
  1573. * @brief Read state in from a stream.
  1574. */
  1575. public void MigrateIn(BinaryReader mir)
  1576. {
  1577. try
  1578. {
  1579. this.migrateInReader = mir;
  1580. this.migrateInObjects = new Dictionary<int, object>();
  1581. this.ehArgs = (object[])this.RecvObjValue();
  1582. this.doGblInit = mir.ReadBoolean();
  1583. this.stateCode = mir.ReadInt32();
  1584. this.eventCode = (ScriptEventCode)mir.ReadInt32();
  1585. this.newStateCode = -1;
  1586. this.glblVars.RecvArrays(this.RecvObjValue);
  1587. XMRStackFrame lastSF = null;
  1588. string funcName;
  1589. while((funcName = mir.ReadString()) != "")
  1590. {
  1591. if(funcName == "**newStateCode**")
  1592. {
  1593. this.newStateCode = mir.ReadInt32();
  1594. continue;
  1595. }
  1596. XMRStackFrame thisSF = new XMRStackFrame();
  1597. thisSF.funcName = funcName;
  1598. thisSF.callNo = mir.ReadInt32();
  1599. thisSF.objArray = (object[])this.RecvObjValue();
  1600. if(lastSF == null)
  1601. this.stackFrames = thisSF;
  1602. else
  1603. lastSF.nextSF = thisSF;
  1604. lastSF = thisSF;
  1605. }
  1606. }
  1607. finally
  1608. {
  1609. this.migrateInReader = null;
  1610. this.migrateInObjects = null;
  1611. }
  1612. }
  1613. /**
  1614. * @brief Read a single value from the stream.
  1615. * @returns value (boxed as needed)
  1616. */
  1617. private BinaryReader migrateInReader;
  1618. private Dictionary<int, object> migrateInObjects;
  1619. public object RecvObjValue()
  1620. {
  1621. BinaryReader mir = this.migrateInReader;
  1622. int ident = this.migrateInObjects.Count;
  1623. Ser code = (Ser)mir.ReadByte();
  1624. switch(code)
  1625. {
  1626. case Ser.NULL:
  1627. return null;
  1628. case Ser.EVENTCODE:
  1629. return (ScriptEventCode)mir.ReadInt32();
  1630. case Ser.LSLFLOAT:
  1631. return new LSL_Float(mir.ReadDouble());
  1632. case Ser.LSLINT:
  1633. return new LSL_Integer(mir.ReadInt32());
  1634. case Ser.LSLKEY:
  1635. return new LSL_Key((string)RecvObjValue());
  1636. case Ser.LSLLIST:
  1637. {
  1638. this.migrateInObjects.Add(ident, null); // placeholder
  1639. object[] data = (object[])RecvObjValue(); // read data, maybe using another index
  1640. LSL_List list = new LSL_List(data); // make LSL-level list
  1641. this.migrateInObjects[ident] = list; // fill in slot
  1642. return list;
  1643. }
  1644. case Ser.LSLROT:
  1645. {
  1646. double x = mir.ReadDouble();
  1647. double y = mir.ReadDouble();
  1648. double z = mir.ReadDouble();
  1649. double w = mir.ReadDouble();
  1650. return new LSL_Rotation(x, y, z, w);
  1651. }
  1652. case Ser.LSLSTR:
  1653. return new LSL_String((string)RecvObjValue());
  1654. case Ser.LSLVEC:
  1655. {
  1656. double x = mir.ReadDouble();
  1657. double y = mir.ReadDouble();
  1658. double z = mir.ReadDouble();
  1659. return new LSL_Vector(x, y, z);
  1660. }
  1661. case Ser.SYSARRAY:
  1662. {
  1663. Type eletype = String2SysType(mir.ReadString());
  1664. int length = mir.ReadInt32();
  1665. Array array = Array.CreateInstance(eletype, length);
  1666. this.migrateInObjects.Add(ident, array);
  1667. for(int i = 0; i < length; i++)
  1668. array.SetValue(RecvObjValue(), i);
  1669. return array;
  1670. }
  1671. case Ser.SYSBOOL:
  1672. return mir.ReadBoolean();
  1673. case Ser.SYSDOUB:
  1674. return mir.ReadDouble();
  1675. case Ser.SYSFLOAT:
  1676. return mir.ReadSingle();
  1677. case Ser.SYSINT:
  1678. return mir.ReadInt32();
  1679. case Ser.SYSCHAR:
  1680. return mir.ReadChar();
  1681. case Ser.SYSSTR:
  1682. string s = mir.ReadString();
  1683. this.migrateInObjects.Add(ident, s);
  1684. return s;
  1685. case Ser.XMRARRAY:
  1686. {
  1687. XMR_Array array = new XMR_Array(this);
  1688. this.migrateInObjects.Add(ident, array);
  1689. array.RecvArrayObj(this.RecvObjValue);
  1690. return array;
  1691. }
  1692. case Ser.DUPREF:
  1693. {
  1694. ident = mir.ReadInt32();
  1695. object obj = this.migrateInObjects[ident];
  1696. if(obj is ObjLslList)
  1697. obj = new LSL_List(((ObjLslList)obj).objarray);
  1698. return obj;
  1699. }
  1700. case Ser.XMRINST:
  1701. return this;
  1702. case Ser.DELEGATE:
  1703. this.migrateInObjects.Add(ident, null); // placeholder
  1704. string name = mir.ReadString(); // function name
  1705. string sig = mir.ReadString(); // delegate type
  1706. object targ = this.RecvObjValue(); // 'this' object
  1707. Delegate del = this.GetScriptMethodDelegate(name, sig, targ);
  1708. this.migrateInObjects[ident] = del; // actual value
  1709. return del;
  1710. case Ser.SDTCLOBJ:
  1711. XMRSDTypeClObj clobj = new XMRSDTypeClObj();
  1712. this.migrateInObjects.Add(ident, clobj);
  1713. clobj.Restore(this, this.RecvObjValue);
  1714. return clobj;
  1715. case Ser.SYSERIAL:
  1716. {
  1717. int rawLength = mir.ReadInt32();
  1718. byte[] rawBytes = mir.ReadBytes(rawLength);
  1719. MemoryStream memoryStream = new MemoryStream(rawBytes);
  1720. System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bformatter =
  1721. new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
  1722. object graph = bformatter.Deserialize(memoryStream);
  1723. this.migrateInObjects.Add(ident, graph);
  1724. return graph;
  1725. }
  1726. case Ser.THROWNEX:
  1727. {
  1728. int rawLength = mir.ReadInt32();
  1729. byte[] rawBytes = mir.ReadBytes(rawLength);
  1730. MemoryStream memoryStream = new MemoryStream(rawBytes);
  1731. System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bformatter =
  1732. new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
  1733. object graph = bformatter.Deserialize(memoryStream);
  1734. this.migrateInObjects.Add(ident, graph);
  1735. ((ScriptThrownException)graph).thrown = RecvObjValue();
  1736. return graph;
  1737. }
  1738. default:
  1739. throw new Exception("bad stream code " + code.ToString());
  1740. }
  1741. }
  1742. // wrapper around list object arrays to make sure they are always object types for migration purposes
  1743. private class ObjLslList
  1744. {
  1745. public object[] objarray;
  1746. }
  1747. }
  1748. // Any xmr...() methods that call CheckRun() must be tagged with this attribute
  1749. // so the ScriptCodeGen will know the method is non-trivial.
  1750. public class xmrMethodCallsCheckRunAttribute: Attribute
  1751. {
  1752. }
  1753. // Any xmr...() methods in xmrengtest that call Stub<somethingorother>() must be
  1754. // tagged with this attribute so the -builtins option will tell the user that
  1755. // they are a stub function.
  1756. public class xmrMethodIsNoisyAttribute: Attribute
  1757. {
  1758. }
  1759. // Any script callable methods that really return a key not a string should be
  1760. // tagged with this attribute so the compiler will know they return type key and
  1761. // not type string.
  1762. public class xmrMethodReturnsKeyAttribute: Attribute
  1763. {
  1764. }
  1765. [SerializableAttribute]
  1766. public class OutOfHeapException: Exception
  1767. {
  1768. public OutOfHeapException(int oldtotal, int newtotal, int limit)
  1769. : base("oldtotal=" + oldtotal + ", newtotal=" + newtotal + ", limit=" + limit)
  1770. {
  1771. }
  1772. }
  1773. [SerializableAttribute]
  1774. public class OutOfStackException: Exception
  1775. {
  1776. }
  1777. }