lscript_alloc.h

Go to the documentation of this file.
00001 
00032 #ifndef LL_LSCRIPT_ALLOC_H
00033 #define LL_LSCRIPT_ALLOC_H
00034 // #define at top of file accelerates gcc compiles
00035 // Under gcc 2.9, the manual is unclear if comments can appear above #ifndef
00036 // Under gcc 3, the manual explicitly states comments can appear above the #ifndef
00037 
00038 #include "lscript_byteconvert.h"
00039 #include "lscript_library.h"
00040 
00041 void reset_hp_to_safe_spot(const U8 *buffer);
00042 
00043 
00044 // supported data types
00045 
00046 //      basic types
00047 //      integer                 4 bytes of integer data
00048 //      float                   4 bytes of float data
00049 //      string data             null terminated 1 byte string
00050 //      key data                null terminated 1 byte string
00051 //      vector data             12 bytes of 3 floats
00052 //      quaternion data 16 bytes of 4 floats
00053 
00054 //      list type
00055 //      list data               4 bytes of number of entries followed by followed by pointer
00056 
00057 //      string pointer          4 bytes of address of string data on the heap (only used in list data)
00058 //  key pointer                 4 bytes of address of key data on the heap (only used in list data)
00059 
00060 // heap format
00061 // 
00062 // 4 byte offset to next block (in bytes)
00063 // 1 byte of type of variable or empty
00064 // 2 bytes of reference count
00065 // nn bytes of data
00066 
00067 const S32 MAX_HEAP_SIZE = TOP_OF_MEMORY;
00068 
00069 class LLScriptAllocEntry
00070 {
00071 public:
00072         LLScriptAllocEntry() : mSize(0), mType(LST_NULL), mReferenceCount(0) {}
00073         LLScriptAllocEntry(S32 offset, U8 type) : mSize(offset), mType(type), mReferenceCount(1) {}
00074         friend std::ostream&     operator<<(std::ostream& s, const LLScriptAllocEntry &a)
00075         {
00076                 s << "Size: " << a.mSize << " Type: " << LSCRIPTTypeNames[a.mType] << " Count: " << a.mReferenceCount;
00077                 return s;
00078         }
00079 
00080         S32 mSize;
00081         U8      mType;
00082         S16 mReferenceCount;
00083 };
00084 
00085 // this is only OK because we only load/save via accessors below
00086 const S32 SIZEOF_SCRIPT_ALLOC_ENTRY = 7;
00087 
00088 inline void alloc_entry2bytestream(U8 *buffer, S32 &offset, const LLScriptAllocEntry &entry)
00089 {
00090         if (  (offset < 0)
00091                 ||(offset > MAX_HEAP_SIZE))
00092         {
00093                 set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
00094         }
00095         else
00096         {
00097                 integer2bytestream(buffer, offset, entry.mSize);
00098                 byte2bytestream(buffer, offset, entry.mType);
00099                 s162bytestream(buffer, offset, entry.mReferenceCount);
00100         }
00101 }
00102 
00103 inline void bytestream2alloc_entry(LLScriptAllocEntry &entry, U8 *buffer, S32 &offset)
00104 {
00105         if (  (offset < 0)
00106                 ||(offset > MAX_HEAP_SIZE))
00107         {
00108                 set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
00109                 reset_hp_to_safe_spot(buffer);
00110         }
00111         else
00112         {
00113                 entry.mSize = bytestream2integer(buffer, offset);
00114                 entry.mType = bytestream2byte(buffer, offset);
00115                 entry.mReferenceCount = bytestream2s16(buffer, offset);
00116         }
00117 }
00118 
00119 // create a heap from the HR to TM
00120 BOOL lsa_create_heap(U8 *heap_start, S32 size);
00121 void lsa_fprint_heap(U8 *buffer, FILE *fp);
00122 
00123 void lsa_print_heap(U8 *buffer);
00124 
00125 // adding to heap
00126 //      if block is empty
00127 //              if block is at least block size + 4 larger than data
00128 //                      split block
00129 //                      insert data into first part
00130 //                      return address
00131 //              else
00132 //                      insert data into block
00133 //                      return address
00134 //      else
00135 //              if next block is >= SP 
00136 //                      set Stack-Heap collision
00137 //                      return NULL
00138 //              if next block is empty
00139 //                      merge next block with current block
00140 //                      go to start of algorithm
00141 //              else
00142 //                      move to next block
00143 //                      go to start of algorithm
00144 
00145 S32 lsa_heap_add_data(U8 *buffer, LLScriptLibData *data, S32 heapsize, BOOL b_delete);
00146 
00147 S32 lsa_heap_top(U8 *heap_start, S32 maxsize);
00148 
00149 // split block
00150 //      set offset to point to new block
00151 //      set offset of new block to point to original offset - block size - data size
00152 //      set new block to empty
00153 //      set new block reference count to 0
00154 void lsa_split_block(U8 *buffer, S32 &offset, S32 size, LLScriptAllocEntry &entry);
00155 
00156 // insert data
00157 //      if data is non-list type
00158 //              set type to basic type, set reference count to 1, copy data, return address
00159 //      else
00160 //              set type to list data type, set reference count to 1
00161 //              for each list entry
00162 //                      insert data
00163 //                      return address
00164 
00165 void lsa_insert_data(U8 *buffer, S32 &offset, LLScriptLibData *data, LLScriptAllocEntry &entry, S32 heapsize);
00166 
00167 S32 lsa_create_data_block(U8 **buffer, LLScriptLibData *data, S32 base_offset);
00168 
00169 // increase reference count
00170 //              increase reference count by 1
00171 
00172 void lsa_increase_ref_count(U8 *buffer, S32 offset);
00173 
00174 // decrease reference count
00175 //              decrease reference count by 1
00176 //              if reference count == 0
00177 //                      set type to empty
00178 
00179 void lsa_decrease_ref_count(U8 *buffer, S32 offset);
00180 
00181 inline S32 get_max_heap_size(U8 *buffer)
00182 {
00183         return get_register(buffer, LREG_SP) - get_register(buffer, LREG_HR);
00184 }
00185 
00186 
00187 LLScriptLibData *lsa_get_data(U8 *buffer, S32 &offset, BOOL b_dec_ref);
00188 LLScriptLibData *lsa_get_list_ptr(U8 *buffer, S32 &offset, BOOL b_dec_ref);
00189 
00190 S32 lsa_cat_strings(U8 *buffer, S32 offset1, S32 offset2, S32 heapsize);
00191 S32 lsa_cmp_strings(U8 *buffer, S32 offset1, S32 offset2);
00192 
00193 S32 lsa_cat_lists(U8 *buffer, S32 offset1, S32 offset2, S32 heapsize);
00194 S32 lsa_cmp_lists(U8 *buffer, S32 offset1, S32 offset2);
00195 S32 lsa_preadd_lists(U8 *buffer, LLScriptLibData *data, S32 offset2, S32 heapsize);
00196 S32 lsa_postadd_lists(U8 *buffer, S32 offset1, LLScriptLibData *data, S32 heapsize);
00197 
00198 // modifying a list
00199 //      insert new list that is modified
00200 //      store returned address in original list's variable
00201 //      decrease reference count on old list
00202 
00203 //      list l1 = [10];
00204 //      list l2 = l1;
00205 //      l1 = [11];
00206 
00207 //      we want l2 == [10];
00208 
00209 // more complicated example:
00210 //      list l1 = [10, 11];
00211 //      list l2 = l1;
00212 //      l1[0] = 12
00213 
00214 // I think that we want l2 = [10, 11];
00215 
00216 // one option would be to use syntax like:
00217 //      l1 = llSetList(l1, 0, 12);
00218 // but this would require variable argument list matching
00219 // which maybe is ok, but would be work
00220 // the other option would be changes to lists that have multiple references causes a copy to occur
00221 
00222 // popl @l1, 0, integer, 12
00223 //
00224 // would cause l1 to be copied, 12 to replace the 0th entry, and the address of the new list to be saved in l1
00225 //
00226 
00227 inline LLScriptLibData *lsa_bubble_sort(LLScriptLibData *src, S32 stride, S32 ascending)
00228 {
00229         S32 number = src->getListLength();
00230 
00231         if (number <= 0)
00232         {
00233                 return NULL;
00234         }
00235 
00236         if (stride <= 0)
00237         {
00238                 stride = 1;
00239         }
00240 
00241         S32 i = 0;
00242 
00243         if (number % stride)
00244         {
00245                 LLScriptLibData *retval = src->mListp;
00246                 src->mListp = NULL;
00247                 return retval;
00248         }
00249 
00250         LLScriptLibData **sortarray = new LLScriptLibData*[number];
00251 
00252         LLScriptLibData *temp = src->mListp;
00253         while (temp)
00254         {
00255                 sortarray[i] = temp;
00256                 i++;
00257                 temp = temp->mListp;
00258         }
00259 
00260         S32 j, s;
00261 
00262         for (i = 0; i < number; i += stride)
00263         {
00264                 for (j = i; j < number; j += stride)
00265                 {
00266                         if (  ((*sortarray[i]) <= (*sortarray[j]))
00267                                 != (ascending == TRUE))
00268                         {
00269                                 for (s = 0; s < stride; s++)
00270                                 {
00271                                         temp = sortarray[i + s];
00272                                         sortarray[i + s] = sortarray[j + s];
00273                                         sortarray[j + s] = temp;
00274                                 }
00275                         }
00276                 }
00277         }
00278 
00279         i = 1;
00280         temp = sortarray[0];
00281         while (i < number)
00282         {
00283                 temp->mListp = sortarray[i++];
00284                 temp = temp->mListp;
00285         }
00286         temp->mListp = NULL;
00287 
00288         src->mListp = NULL;
00289 
00290         temp = sortarray[0];
00291         delete[] sortarray;
00292         return temp;
00293 }
00294 
00295 
00296 LLScriptLibData* lsa_randomize(LLScriptLibData* src, S32 stride);
00297 
00298 #endif

Generated on Thu Jul 1 06:09:49 2010 for Second Life Viewer by  doxygen 1.4.7