XMRInstAbstract.cs 77 KB

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