00001
00032 #if 0
00033
00034 #include "linden_common.h"
00035
00036 #include "lscript_heapruntime.h"
00037 #include "lscript_execute.h"
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 LLScriptHeapRunTime::LLScriptHeapRunTime()
00107 : mLastEmpty(0), mBuffer(NULL), mCurrentPosition(0), mStackPointer(0), mHeapRegister(0), mbPrint(FALSE)
00108 {
00109 }
00110
00111 LLScriptHeapRunTime::~LLScriptHeapRunTime()
00112 {
00113 }
00114
00115 S32 LLScriptHeapRunTime::addData(char *string)
00116 {
00117 if (!mBuffer)
00118 return 0;
00119
00120 S32 size = strlen(string) + 1;
00121 S32 block_offset = findOpenBlock(size + HEAP_BLOCK_HEADER_SIZE);
00122
00123 if (mCurrentPosition)
00124 {
00125 S32 offset = mCurrentPosition;
00126 if (offset + block_offset + HEAP_BLOCK_HEADER_SIZE + LSCRIPTDataSize[LST_INTEGER] >= mStackPointer)
00127 {
00128 set_fault(mBuffer, LSRF_STACK_HEAP_COLLISION);
00129 return 0;
00130 }
00131
00132
00133 integer2bytestream(mBuffer, offset, block_offset);
00134
00135 integer2bytestream(mBuffer, offset, 1);
00136
00137 *(mBuffer + offset++) = LSCRIPTTypeByte[LST_STRING];
00138
00139 char2bytestream(mBuffer, offset, string);
00140 if (mbPrint)
00141 printf("0x%X created ref count %d\n", mCurrentPosition - mHeapRegister, 1);
00142
00143
00144
00145
00146 }
00147 return mCurrentPosition;
00148 }
00149
00150 S32 LLScriptHeapRunTime::addData(U8 *list)
00151 {
00152 if (!mBuffer)
00153 return 0;
00154 return 0;
00155 }
00156
00157 S32 LLScriptHeapRunTime::catStrings(S32 address1, S32 address2)
00158 {
00159 if (!mBuffer)
00160 return 0;
00161
00162 S32 dataaddress1 = address1 + 2*LSCRIPTDataSize[LST_INTEGER] + 1;
00163 S32 dataaddress2 = address2 + 2*LSCRIPTDataSize[LST_INTEGER] + 1;
00164
00165 S32 toffset1 = dataaddress1;
00166 safe_heap_bytestream_count_char(mBuffer, toffset1);
00167
00168 S32 toffset2 = dataaddress2;
00169 safe_heap_bytestream_count_char(mBuffer, toffset2);
00170
00171
00172 S32 size1 = toffset1 - dataaddress1;
00173 S32 size2 = toffset2 - dataaddress2;
00174 S32 newbuffer = size1 + size2 - 1;
00175
00176 char *temp = new char[newbuffer];
00177
00178
00179 bytestream2char(temp, mBuffer, dataaddress1);
00180 bytestream2char(temp + size1 - 1, mBuffer, dataaddress2);
00181
00182 decreaseRefCount(address1);
00183 decreaseRefCount(address2);
00184
00185 S32 retaddress = addData(temp);
00186
00187 return retaddress;
00188 }
00189
00190 S32 LLScriptHeapRunTime::cmpStrings(S32 address1, S32 address2)
00191 {
00192 if (!mBuffer)
00193 return 0;
00194
00195 S32 dataaddress1 = address1 + 2*LSCRIPTDataSize[LST_INTEGER] + 1;
00196 S32 dataaddress2 = address2 + 2*LSCRIPTDataSize[LST_INTEGER] + 1;
00197
00198 S32 toffset1 = dataaddress1;
00199 safe_heap_bytestream_count_char(mBuffer, toffset1);
00200
00201 S32 toffset2 = dataaddress2;
00202 safe_heap_bytestream_count_char(mBuffer, toffset2);
00203
00204
00205 S32 size1 = toffset1 - dataaddress1;
00206 S32 size2 = toffset2 - dataaddress2;
00207
00208 if (size1 != size2)
00209 {
00210 return llmin(size1, size2);
00211 }
00212 else
00213 {
00214 return strncmp((char *)(mBuffer + dataaddress1), (char *)(mBuffer + dataaddress2), size1);
00215 }
00216 }
00217
00218 void LLScriptHeapRunTime::removeData(S32 address)
00219 {
00220 if (!mBuffer)
00221 return;
00222
00223 S32 toffset = address;
00224
00225 bytestream2integer(mBuffer, toffset);
00226
00227
00228 integer2bytestream(mBuffer, toffset, 0);
00229
00230 *(mBuffer + toffset) = 0;
00231
00232
00233 S32 clean = mHeapRegister;
00234 S32 tclean;
00235 S32 clean_offset;
00236
00237 S32 nclean;
00238 S32 tnclean;
00239 S32 next_offset;
00240
00241 U8 type;
00242 U8 ntype;
00243
00244 for(;;)
00245 {
00246 tclean = clean;
00247 clean_offset = bytestream2integer(mBuffer, tclean);
00248
00249 tclean += LSCRIPTDataSize[LST_INTEGER];
00250 type = *(mBuffer + tclean);
00251
00252 if (!clean_offset)
00253 {
00254 if (!type)
00255 {
00256
00257 set_register(mBuffer, LREG_HP, clean);
00258 }
00259 return;
00260 }
00261
00262
00263 if (!type)
00264 {
00265
00266 nclean = clean + clean_offset;
00267 tnclean = nclean;
00268 next_offset = bytestream2integer(mBuffer, tnclean);
00269 tnclean += LSCRIPTDataSize[LST_INTEGER];
00270 ntype = *(mBuffer + tnclean);
00271
00272 if (!next_offset)
00273 {
00274
00275 tclean = clean;
00276 integer2bytestream(mBuffer, tclean, 0);
00277 set_register(mBuffer, LREG_HP, clean);
00278 return;
00279 }
00280
00281 if (!ntype)
00282 {
00283
00284 tclean = clean;
00285 integer2bytestream(mBuffer, tclean, clean_offset + next_offset);
00286
00287 }
00288 else
00289 {
00290 clean += clean_offset;
00291 }
00292 }
00293 else
00294 {
00295
00296 clean += clean_offset;
00297 }
00298 }
00299 }
00300
00301 void LLScriptHeapRunTime::coalesce(S32 address1, S32 address2)
00302 {
00303
00304 S32 toffset = address1;
00305 S32 offset1 = bytestream2integer(mBuffer, toffset);
00306 offset1 += bytestream2integer(mBuffer, address2);
00307
00308 integer2bytestream(mBuffer, address1, offset1);
00309 }
00310
00311 void LLScriptHeapRunTime::split(S32 address1, S32 size)
00312 {
00313 S32 toffset = address1;
00314 S32 oldoffset = bytestream2integer(mBuffer, toffset);
00315
00316
00317 S32 newoffset = oldoffset - size;
00318 S32 newblockpos = address1 + size;
00319
00320
00321 integer2bytestream(mBuffer, newblockpos, newoffset);
00322
00323 integer2bytestream(mBuffer, newblockpos, 0);
00324
00325 *(mBuffer + newblockpos) = 0;
00326
00327
00328 integer2bytestream(mBuffer, address1, size + HEAP_BLOCK_HEADER_SIZE);
00329 }
00330
00331
00332
00333
00334
00335
00336
00337
00338 void LLScriptHeapRunTime::increaseRefCount(S32 address)
00339 {
00340 if (!mBuffer)
00341 return;
00342
00343 if (!address)
00344 {
00345
00346 return;
00347 }
00348
00349
00350 S32 toffset = address + 4;
00351 S32 count = bytestream2integer(mBuffer, toffset);
00352
00353 count++;
00354
00355 if (mbPrint)
00356 printf("0x%X inc ref count %d\n", address - mHeapRegister, count);
00357
00358
00359 U8 type = *(mBuffer + toffset);
00360
00361 if (type == LSCRIPTTypeByte[LST_STRING])
00362 {
00363 toffset = address + 4;
00364 integer2bytestream(mBuffer, toffset, count);
00365 }
00366
00367 else
00368 {
00369 set_fault(mBuffer, LSRF_HEAP_ERROR);
00370 }
00371 }
00372
00373 void LLScriptHeapRunTime::decreaseRefCount(S32 address)
00374 {
00375 if (!mBuffer)
00376 return;
00377
00378 if (!address)
00379 {
00380
00381 return;
00382 }
00383
00384
00385 S32 toffset = address;
00386
00387 bytestream2integer(mBuffer, toffset);
00388
00389
00390 S32 count = bytestream2integer(mBuffer, toffset);
00391
00392
00393 U8 type = *(mBuffer + toffset);
00394
00395 if (type == LSCRIPTTypeByte[LST_STRING])
00396 {
00397 count--;
00398
00399 if (mbPrint)
00400 printf("0x%X dec ref count %d\n", address - mHeapRegister, count);
00401
00402 toffset = address + 4;
00403 integer2bytestream(mBuffer, toffset, count);
00404 if (!count)
00405 {
00406
00407 removeData(address);
00408 }
00409 }
00410
00411 else
00412 {
00413 set_fault(mBuffer, LSRF_HEAP_ERROR);
00414 }
00415 }
00416
00417
00418 void LLScriptHeapRunTime::releaseLocal(S32 address)
00419 {
00420 S32 hr = get_register(mBuffer, LREG_HR);
00421 address = lscript_local_get(mBuffer, address);
00422 if ( (address >= hr)
00423 &&(address < hr + get_register(mBuffer, LREG_HP)))
00424 {
00425 decreaseRefCount(address);
00426 }
00427 }
00428
00429 void LLScriptHeapRunTime::releaseGlobal(S32 address)
00430 {
00431
00432 S32 hr = get_register(mBuffer, LREG_HR);
00433 address = lscript_global_get(mBuffer, address) + hr;
00434 if ( (address >= hr)
00435 &&(address < hr + get_register(mBuffer, LREG_HP)))
00436 {
00437 decreaseRefCount(address);
00438 }
00439 }
00440
00441
00442
00443
00444
00445 #if defined(_MSC_VER)
00446 # pragma warning(disable: 4702) // unreachable code
00447 #endif
00448
00449 S32 LLScriptHeapRunTime::findOpenBlock(S32 size)
00450 {
00451 S32 offset;
00452 S32 toffset;
00453 U8 blocktype;
00454
00455 while(1)
00456 {
00457 if (mCurrentPosition + size >= mStackPointer)
00458 {
00459 set_fault(mBuffer, LSRF_STACK_HEAP_COLLISION);
00460 mCurrentPosition = 0;
00461 }
00462
00463 toffset = mCurrentPosition;
00464 offset = bytestream2integer(mBuffer, toffset);
00465 if (!offset)
00466 {
00467
00468
00469 if (mLastEmpty)
00470 {
00471
00472
00473 mCurrentPosition = mLastEmpty;
00474 integer2bytestream(mBuffer, mLastEmpty, 0);
00475 mLastEmpty = 0;
00476 }
00477
00478 offset = mCurrentPosition + size;
00479 integer2bytestream(mBuffer, offset, 0);
00480
00481
00482 set_register(mBuffer, LREG_HP, mCurrentPosition + size);
00483 return size;
00484 }
00485
00486
00487 toffset += LSCRIPTDataSize[LST_INTEGER];
00488
00489 blocktype = *(mBuffer + toffset++);
00490
00491 if (!blocktype)
00492 {
00493
00494 if (mLastEmpty)
00495 {
00496 coalesce(mLastEmpty, mCurrentPosition);
00497 mCurrentPosition = mLastEmpty;
00498 toffset = mCurrentPosition;
00499 offset = bytestream2integer(mBuffer, toffset);
00500 }
00501
00502
00503 if (offset >= size)
00504 {
00505
00506 if (offset - HEAP_BLOCK_SPLIT_THRESHOLD >= size)
00507 {
00508 split(mCurrentPosition, size);
00509 return size;
00510 }
00511 else
00512 return offset;
00513 }
00514 }
00515
00516 mCurrentPosition += offset;
00517 }
00518
00519 mCurrentPosition = 0;
00520 return 0;
00521 }
00522
00523 LLScriptHeapRunTime gRunTime;
00524 #endif