XMRInstAbstract.cs 76 KB

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