aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/lscript/lscript_alloc.h
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/lscript/lscript_alloc.h
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/lscript/lscript_alloc.h')
-rw-r--r--linden/indra/lscript/lscript_alloc.h363
1 files changed, 363 insertions, 0 deletions
diff --git a/linden/indra/lscript/lscript_alloc.h b/linden/indra/lscript/lscript_alloc.h
new file mode 100644
index 0000000..67e3dc0
--- /dev/null
+++ b/linden/indra/lscript/lscript_alloc.h
@@ -0,0 +1,363 @@
1/**
2 * @file lscript_alloc.h
3 * @brief General heap management for scripting system
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifndef LL_LSCRIPT_ALLOC_H
29#define LL_LSCRIPT_ALLOC_H
30// #define at top of file accelerates gcc compiles
31// Under gcc 2.9, the manual is unclear if comments can appear above #ifndef
32// Under gcc 3, the manual explicitly states comments can appear above the #ifndef
33
34#include "stdtypes.h"
35#include "lscript_byteconvert.h"
36#include "lscript_library.h"
37#include "llrand.h"
38#include <stdio.h>
39
40void reset_hp_to_safe_spot(const U8 *buffer);
41
42
43// supported data types
44
45// basic types
46// integer 4 bytes of integer data
47// float 4 bytes of float data
48// string data null terminated 1 byte string
49// key data null terminated 1 byte string
50// vector data 12 bytes of 3 floats
51// quaternion data 16 bytes of 4 floats
52
53// list type
54// list data 4 bytes of number of entries followed by followed by pointer
55
56// string pointer 4 bytes of address of string data on the heap (only used in list data)
57// key pointer 4 bytes of address of key data on the heap (only used in list data)
58
59// heap format
60//
61// 4 byte offset to next block (in bytes)
62// 1 byte of type of variable or empty
63// 2 bytes of reference count
64// nn bytes of data
65
66const S32 MAX_HEAP_SIZE = TOP_OF_MEMORY;
67
68class LLScriptAllocEntry
69{
70public:
71 LLScriptAllocEntry() : mSize(0), mType(LST_NULL), mReferenceCount(0) {}
72 LLScriptAllocEntry(S32 offset, U8 type) : mSize(offset), mType(type), mReferenceCount(1) {}
73 friend std::ostream& operator<<(std::ostream& s, const LLScriptAllocEntry &a)
74 {
75 s << "Size: " << a.mSize << " Type: " << LSCRIPTTypeNames[a.mType] << " Count: " << a.mReferenceCount;
76 return s;
77 }
78
79 S32 mSize;
80 U8 mType;
81 S16 mReferenceCount;
82};
83
84// this is only OK because we only load/save via accessors below
85const S32 SIZEOF_SCRIPT_ALLOC_ENTRY = 7;
86
87inline void alloc_entry2bytestream(U8 *buffer, S32 &offset, const LLScriptAllocEntry &entry)
88{
89 if ( (offset < 0)
90 ||(offset > MAX_HEAP_SIZE))
91 {
92 set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
93 }
94 else
95 {
96 integer2bytestream(buffer, offset, entry.mSize);
97 byte2bytestream(buffer, offset, entry.mType);
98 s162bytestream(buffer, offset, entry.mReferenceCount);
99 }
100}
101
102inline void bytestream2alloc_entry(LLScriptAllocEntry &entry, U8 *buffer, S32 &offset)
103{
104 if ( (offset < 0)
105 ||(offset > MAX_HEAP_SIZE))
106 {
107 set_fault(buffer, LSRF_BOUND_CHECK_ERROR);
108 reset_hp_to_safe_spot(buffer);
109 }
110 else
111 {
112 entry.mSize = bytestream2integer(buffer, offset);
113 entry.mType = bytestream2byte(buffer, offset);
114 entry.mReferenceCount = bytestream2s16(buffer, offset);
115 }
116}
117
118// create a heap from the HR to TM
119BOOL lsa_create_heap(U8 *heap_start, S32 size);
120void lsa_fprint_heap(U8 *buffer, FILE *fp);
121
122void lsa_print_heap(U8 *buffer);
123
124// adding to heap
125// if block is empty
126// if block is at least block size + 4 larger than data
127// split block
128// insert data into first part
129// return address
130// else
131// insert data into block
132// return address
133// else
134// if next block is >= SP
135// set Stack-Heap collision
136// return NULL
137// if next block is empty
138// merge next block with current block
139// go to start of algorithm
140// else
141// move to next block
142// go to start of algorithm
143
144S32 lsa_heap_add_data(U8 *buffer, LLScriptLibData *data, S32 heapsize, BOOL b_delete);
145
146S32 lsa_heap_top(U8 *heap_start, S32 maxsize);
147
148// split block
149// set offset to point to new block
150// set offset of new block to point to original offset - block size - data size
151// set new block to empty
152// set new block reference count to 0
153void lsa_split_block(U8 *buffer, S32 &offset, S32 size, LLScriptAllocEntry &entry);
154
155// insert data
156// if data is non-list type
157// set type to basic type, set reference count to 1, copy data, return address
158// else
159// set type to list data type, set reference count to 1
160// for each list entry
161// insert data
162// return address
163
164void lsa_insert_data(U8 *buffer, S32 &offset, LLScriptLibData *data, LLScriptAllocEntry &entry, S32 heapsize);
165
166S32 lsa_create_data_block(U8 **buffer, LLScriptLibData *data, S32 base_offset);
167
168// increase reference count
169// increase reference count by 1
170
171void lsa_increase_ref_count(U8 *buffer, S32 offset);
172
173// decrease reference count
174// decrease reference count by 1
175// if reference count == 0
176// set type to empty
177
178void lsa_decrease_ref_count(U8 *buffer, S32 offset);
179
180inline S32 get_max_heap_size(U8 *buffer)
181{
182 return get_register(buffer, LREG_SP) - get_register(buffer, LREG_HR);
183}
184
185
186LLScriptLibData *lsa_get_data(U8 *buffer, S32 &offset, BOOL b_dec_ref);
187LLScriptLibData *lsa_get_list_ptr(U8 *buffer, S32 &offset, BOOL b_dec_ref);
188
189S32 lsa_cat_strings(U8 *buffer, S32 offset1, S32 offset2, S32 heapsize);
190S32 lsa_cmp_strings(U8 *buffer, S32 offset1, S32 offset2);
191
192S32 lsa_cat_lists(U8 *buffer, S32 offset1, S32 offset2, S32 heapsize);
193S32 lsa_cmp_lists(U8 *buffer, S32 offset1, S32 offset2);
194S32 lsa_preadd_lists(U8 *buffer, LLScriptLibData *data, S32 offset2, S32 heapsize);
195S32 lsa_postadd_lists(U8 *buffer, S32 offset1, LLScriptLibData *data, S32 heapsize);
196
197// modifying a list
198// insert new list that is modified
199// store returned address in original list's variable
200// decrease reference count on old list
201
202// list l1 = [10];
203// list l2 = l1;
204// l1 = [11];
205
206// we want l2 == [10];
207
208// more complicated example:
209// list l1 = [10, 11];
210// list l2 = l1;
211// l1[0] = 12
212
213// I think that we want l2 = [10, 11];
214
215// one option would be to use syntax like:
216// l1 = llSetList(l1, 0, 12);
217// but this would require variable argument list matching
218// which maybe is ok, but would be work
219// the other option would be changes to lists that have multiple references causes a copy to occur
220
221// popl @l1, 0, integer, 12
222//
223// would cause l1 to be copied, 12 to replace the 0th entry, and the address of the new list to be saved in l1
224//
225
226inline LLScriptLibData *lsa_bubble_sort(LLScriptLibData *src, S32 stride, S32 ascending)
227{
228 S32 number = src->getListLength();
229
230 if (number <= 0)
231 {
232 return NULL;
233 }
234
235 if (stride <= 0)
236 {
237 stride = 1;
238 }
239
240 S32 i = 0;
241
242 if (number % stride)
243 {
244 LLScriptLibData *retval = src->mListp;
245 src->mListp = NULL;
246 return retval;
247 }
248
249 LLScriptLibData **sortarray = (LLScriptLibData **)new U32[number];
250
251 LLScriptLibData *temp = src->mListp;
252 while (temp)
253 {
254 sortarray[i] = temp;
255 i++;
256 temp = temp->mListp;
257 }
258
259 S32 j, s;
260
261 for (i = 0; i < number; i += stride)
262 {
263 for (j = i; j < number; j += stride)
264 {
265 if ( ((*sortarray[i]) <= (*sortarray[j]))
266 != (ascending == TRUE))
267 {
268 for (s = 0; s < stride; s++)
269 {
270 temp = sortarray[i + s];
271 sortarray[i + s] = sortarray[j + s];
272 sortarray[j + s] = temp;
273 }
274 }
275 }
276 }
277
278 i = 1;
279 temp = sortarray[0];
280 while (i < number)
281 {
282 temp->mListp = sortarray[i++];
283 temp = temp->mListp;
284 }
285 temp->mListp = NULL;
286
287 src->mListp = NULL;
288
289 return sortarray[0];
290}
291
292
293inline LLScriptLibData *lsa_randomize(LLScriptLibData *src, S32 stride)
294{
295 S32 number = src->getListLength();
296
297 if (number <= 0)
298 {
299 return NULL;
300 }
301
302 if (stride <= 0)
303 {
304 stride = 1;
305 }
306
307 if (number % stride)
308 {
309 LLScriptLibData *retval = src->mListp;
310 src->mListp = NULL;
311 return retval;
312 }
313
314 LLScriptLibData **sortarray = (LLScriptLibData **)new U32[number];
315
316 LLScriptLibData *temp = src->mListp;
317 S32 i = 0;
318 while (temp)
319 {
320 sortarray[i] = temp;
321 i++;
322 temp = temp->mListp;
323 }
324
325 S32 k, j, s;
326
327 for (k = 0; k < 20; k++)
328 {
329 for (i = 0; i < number; i += stride)
330 {
331 for (j = i; j < number; j += stride)
332 {
333 if (frand(1.f) > 0.5)
334 {
335 for (s = 0; s < stride; s++)
336 {
337 temp = sortarray[i + s];
338 sortarray[i + s] = sortarray[j + s];
339 sortarray[j + s] = temp;
340 }
341 }
342 }
343 }
344 }
345
346 i = 1;
347 temp = sortarray[0];
348 while (i < number)
349 {
350 temp->mListp = sortarray[i++];
351 temp = temp->mListp;
352 }
353 temp->mListp = NULL;
354
355 src->mListp = NULL;
356
357 LLScriptLibData *ret_value = sortarray[0];
358 delete [] sortarray;
359
360 return ret_value;
361}
362
363#endif