lscript_alloc.h
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:8k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file lscript_alloc.h
  3.  * @brief General heap management for scripting system
  4.  *
  5.  * $LicenseInfo:firstyear=2002&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2002-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #ifndef LL_LSCRIPT_ALLOC_H
  33. #define LL_LSCRIPT_ALLOC_H
  34. // #define at top of file accelerates gcc compiles
  35. // Under gcc 2.9, the manual is unclear if comments can appear above #ifndef
  36. // Under gcc 3, the manual explicitly states comments can appear above the #ifndef
  37. #include "lscript_byteconvert.h"
  38. #include "lscript_library.h"
  39. void reset_hp_to_safe_spot(const U8 *buffer);
  40. // supported data types
  41. // basic types
  42. // integer 4 bytes of integer data
  43. // float 4 bytes of float data
  44. // string data null terminated 1 byte string
  45. // key data null terminated 1 byte string
  46. // vector data 12 bytes of 3 floats
  47. // quaternion data 16 bytes of 4 floats
  48. // list type
  49. // list data 4 bytes of number of entries followed by followed by pointer
  50. // string pointer 4 bytes of address of string data on the heap (only used in list data)
  51. //  key pointer 4 bytes of address of key data on the heap (only used in list data)
  52. // heap format
  53. // 
  54. // 4 byte offset to next block (in bytes)
  55. // 1 byte of type of variable or empty
  56. // 2 bytes of reference count
  57. // nn bytes of data
  58. const S32 MAX_HEAP_SIZE = TOP_OF_MEMORY;
  59. class LLScriptAllocEntry
  60. {
  61. public:
  62. LLScriptAllocEntry() : mSize(0), mType(LST_NULL), mReferenceCount(0) {}
  63. LLScriptAllocEntry(S32 offset, U8 type) : mSize(offset), mType(type), mReferenceCount(1) {}
  64. friend std::ostream&  operator<<(std::ostream& s, const LLScriptAllocEntry &a)
  65. {
  66. s << "Size: " << a.mSize << " Type: " << LSCRIPTTypeNames[a.mType] << " Count: " << a.mReferenceCount;
  67. return s;
  68. }
  69. S32 mSize;
  70. U8 mType;
  71. S16 mReferenceCount;
  72. };
  73. // this is only OK because we only load/save via accessors below
  74. const S32 SIZEOF_SCRIPT_ALLOC_ENTRY = 7;
  75. inline void alloc_entry2bytestream(U8 *buffer, S32 &offset, const LLScriptAllocEntry &entry)
  76. {
  77. if (  (offset < 0)
  78. ||(offset > MAX_HEAP_SIZE))
  79. {
  80. set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
  81. }
  82. else
  83. {
  84. integer2bytestream(buffer, offset, entry.mSize);
  85. byte2bytestream(buffer, offset, entry.mType);
  86. s162bytestream(buffer, offset, entry.mReferenceCount);
  87. }
  88. }
  89. inline void bytestream2alloc_entry(LLScriptAllocEntry &entry, U8 *buffer, S32 &offset)
  90. {
  91. if (  (offset < 0)
  92. ||(offset > MAX_HEAP_SIZE))
  93. {
  94. set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
  95. reset_hp_to_safe_spot(buffer);
  96. }
  97. else
  98. {
  99. entry.mSize = bytestream2integer(buffer, offset);
  100. entry.mType = bytestream2byte(buffer, offset);
  101. entry.mReferenceCount = bytestream2s16(buffer, offset);
  102. }
  103. }
  104. // create a heap from the HR to TM
  105. BOOL lsa_create_heap(U8 *heap_start, S32 size);
  106. void lsa_fprint_heap(U8 *buffer, LLFILE *fp);
  107. void lsa_print_heap(U8 *buffer);
  108. // adding to heap
  109. // if block is empty
  110. // if block is at least block size + 4 larger than data
  111. // split block
  112. // insert data into first part
  113. // return address
  114. // else
  115. // insert data into block
  116. // return address
  117. // else
  118. // if next block is >= SP 
  119. // set Stack-Heap collision
  120. // return NULL
  121. // if next block is empty
  122. // merge next block with current block
  123. // go to start of algorithm
  124. // else
  125. // move to next block
  126. // go to start of algorithm
  127. S32 lsa_heap_add_data(U8 *buffer, LLScriptLibData *data, S32 heapsize, BOOL b_delete);
  128. S32 lsa_heap_top(U8 *heap_start, S32 maxsize);
  129. // split block
  130. // set offset to point to new block
  131. // set offset of new block to point to original offset - block size - data size
  132. // set new block to empty
  133. // set new block reference count to 0
  134. void lsa_split_block(U8 *buffer, S32 &offset, S32 size, LLScriptAllocEntry &entry);
  135. // insert data
  136. // if data is non-list type
  137. // set type to basic type, set reference count to 1, copy data, return address
  138. // else
  139. // set type to list data type, set reference count to 1
  140. // for each list entry
  141. // insert data
  142. // return address
  143. void lsa_insert_data(U8 *buffer, S32 &offset, LLScriptLibData *data, LLScriptAllocEntry &entry, S32 heapsize);
  144. S32 lsa_create_data_block(U8 **buffer, LLScriptLibData *data, S32 base_offset);
  145. // increase reference count
  146. // increase reference count by 1
  147. void lsa_increase_ref_count(U8 *buffer, S32 offset);
  148. // decrease reference count
  149. // decrease reference count by 1
  150. // if reference count == 0
  151. // set type to empty
  152. void lsa_decrease_ref_count(U8 *buffer, S32 offset);
  153. inline S32 get_max_heap_size(U8 *buffer)
  154. {
  155. return get_register(buffer, LREG_SP) - get_register(buffer, LREG_HR);
  156. }
  157. LLScriptLibData *lsa_get_data(U8 *buffer, S32 &offset, BOOL b_dec_ref);
  158. LLScriptLibData *lsa_get_list_ptr(U8 *buffer, S32 &offset, BOOL b_dec_ref);
  159. S32 lsa_cat_strings(U8 *buffer, S32 offset1, S32 offset2, S32 heapsize);
  160. S32 lsa_cmp_strings(U8 *buffer, S32 offset1, S32 offset2);
  161. S32 lsa_cat_lists(U8 *buffer, S32 offset1, S32 offset2, S32 heapsize);
  162. S32 lsa_cmp_lists(U8 *buffer, S32 offset1, S32 offset2);
  163. S32 lsa_preadd_lists(U8 *buffer, LLScriptLibData *data, S32 offset2, S32 heapsize);
  164. S32 lsa_postadd_lists(U8 *buffer, S32 offset1, LLScriptLibData *data, S32 heapsize);
  165. // modifying a list
  166. // insert new list that is modified
  167. // store returned address in original list's variable
  168. // decrease reference count on old list
  169. // list l1 = [10];
  170. // list l2 = l1;
  171. // l1 = [11];
  172. // we want l2 == [10];
  173. // more complicated example:
  174. // list l1 = [10, 11];
  175. // list l2 = l1;
  176. // l1[0] = 12
  177. // I think that we want l2 = [10, 11];
  178. // one option would be to use syntax like:
  179. // l1 = llSetList(l1, 0, 12);
  180. // but this would require variable argument list matching
  181. // which maybe is ok, but would be work
  182. // the other option would be changes to lists that have multiple references causes a copy to occur
  183. // popl @l1, 0, integer, 12
  184. //
  185. // would cause l1 to be copied, 12 to replace the 0th entry, and the address of the new list to be saved in l1
  186. //
  187. inline LLScriptLibData *lsa_bubble_sort(LLScriptLibData *src, S32 stride, S32 ascending)
  188. {
  189. S32 number = src->getListLength();
  190. if (number <= 0)
  191. {
  192. return NULL;
  193. }
  194. if (stride <= 0)
  195. {
  196. stride = 1;
  197. }
  198. S32 i = 0;
  199. if (number % stride)
  200. {
  201. LLScriptLibData *retval = src->mListp;
  202. src->mListp = NULL;
  203. return retval;
  204. }
  205. LLScriptLibData **sortarray = new LLScriptLibData*[number];
  206. LLScriptLibData *temp = src->mListp;
  207. while (temp)
  208. {
  209. sortarray[i] = temp;
  210. i++;
  211. temp = temp->mListp;
  212. }
  213. S32 j, s;
  214. for (i = 0; i < number; i += stride)
  215. {
  216. for (j = i; j < number; j += stride)
  217. {
  218. if (  ((*sortarray[i]) <= (*sortarray[j]))
  219. != (ascending == TRUE))
  220. {
  221. for (s = 0; s < stride; s++)
  222. {
  223. temp = sortarray[i + s];
  224. sortarray[i + s] = sortarray[j + s];
  225. sortarray[j + s] = temp;
  226. }
  227. }
  228. }
  229. }
  230. i = 1;
  231. temp = sortarray[0];
  232. while (i < number)
  233. {
  234. temp->mListp = sortarray[i++];
  235. temp = temp->mListp;
  236. }
  237. temp->mListp = NULL;
  238. src->mListp = NULL;
  239. temp = sortarray[0];
  240. delete[] sortarray;
  241. return temp;
  242. }
  243. LLScriptLibData* lsa_randomize(LLScriptLibData* src, S32 stride);
  244. #endif