S32 LLScriptHeapRunTime::addData(char *string)
{
	if (!mBuffer)
		return 0;

	S32 size = strlen(string) + 1;
	S32 block_offset = findOpenBlock(size + HEAP_BLOCK_HEADER_SIZE);

	if (mCurrentPosition)
	{
		S32 offset = mCurrentPosition;
		if (offset + block_offset + HEAP_BLOCK_HEADER_SIZE + LSCRIPTDataSize[LST_INTEGER] >= mStackPointer)
		{
			set_fault(mBuffer, LSRF_STACK_HEAP_COLLISION);
			return 0;
		}
		// cool, we've found a spot!
		// set offset
		integer2bytestream(mBuffer, offset, block_offset);
		// set reference count
		integer2bytestream(mBuffer, offset, 1);
		// set type
		*(mBuffer + offset++) = LSCRIPTTypeByte[LST_STRING];
		// plug in data
		char2bytestream(mBuffer, offset, string);
		if (mbPrint)
			printf("0x%X created ref count %d\n", mCurrentPosition - mHeapRegister, 1);

		// now, zero out next offset to prevent "trouble"
	//	offset = mCurrentPosition + size + HEAP_BLOCK_HEADER_SIZE;
	//	integer2bytestream(mBuffer, offset, 0);
	}
	return mCurrentPosition;
}
Beispiel #2
0
void lsa_insert_data(U8 *buffer, S32 &offset, LLScriptLibData *data, LLScriptAllocEntry &entry, S32 heapsize)
{
	if (get_register(buffer, LREG_FR))
		return;
	if (data->mType != LST_LIST)
	{
		switch(data->mType)
		{
		case LST_INTEGER:
			integer2bytestream(buffer, offset, data->mInteger);
			break;
		case LST_FLOATINGPOINT:
			float2bytestream(buffer, offset, data->mFP);
			break;
		case LST_KEY:
		        char2bytestream(buffer, offset, data->mKey ? data->mKey : "");
			break;
		case LST_STRING:
		        char2bytestream(buffer, offset, data->mString ? data->mString : "");
			break;
		case LST_VECTOR:
			vector2bytestream(buffer, offset, data->mVec);
			break;
		case LST_QUATERNION:
			quaternion2bytestream(buffer, offset, data->mQuat);
			break;
		default:
			break;
		}
	}
	else
	{
		// store length of list
		integer2bytestream(buffer, offset, data->getListLength());
		data = data->mListp;
		while(data)
		{
			// store entry and then store address if valid
			S32 address = lsa_heap_add_data(buffer, data, heapsize, FALSE);
			integer2bytestream(buffer, offset, address);
			data = data->mListp;
		}
	}
}
Beispiel #3
0
S32 lsa_create_data_block(U8 **buffer, LLScriptLibData *data, S32 base_offset)
{
	S32 offset = 0;
	S32 size = 0;

	LLScriptAllocEntry entry;

	if (!data)
	{
		entry.mType = LST_NULL;
		entry.mReferenceCount = 0;
		entry.mSize = MAX_HEAP_SIZE;
		size = SIZEOF_SCRIPT_ALLOC_ENTRY;
		*buffer = new U8[size];
		alloc_entry2bytestream(*buffer, offset, entry);
		return size;
	}

	entry.mType = data->mType;
	entry.mReferenceCount = 1;

	if (data->mType != LST_LIST)
	{
		if (  (data->mType != LST_STRING)
			&&(data->mType != LST_KEY))
		{
			size = LSCRIPTDataSize[data->mType];
		}
		else
		{
			if (data->mType == LST_STRING)
			{
				if (data->mString)
				{
					size = (S32)strlen(data->mString) + 1;		/*Flawfinder: ignore*/
				}
				else
				{
					size = 1;
				}
			}
			if (data->mType == LST_KEY)
			{
				if (data->mKey)
				{
					size = (S32)strlen(data->mKey) + 1;		/*Flawfinder: ignore*/
				}
				else
				{
					size = 1;
				}
			}
		}
		entry.mSize = size;
		size += SIZEOF_SCRIPT_ALLOC_ENTRY;
		*buffer = new U8[size];
		alloc_entry2bytestream(*buffer, offset, entry);

		switch(data->mType)
		{
		case LST_INTEGER:
			integer2bytestream(*buffer, offset, data->mInteger);
			break;
		case LST_FLOATINGPOINT:
			float2bytestream(*buffer, offset, data->mFP);
			break;
		case LST_KEY:
			if (data->mKey)
				char2bytestream(*buffer, offset, data->mKey);
			else
				byte2bytestream(*buffer, offset, 0);
			break;
		case LST_STRING:
			if (data->mString)
				char2bytestream(*buffer, offset, data->mString);
			else
				byte2bytestream(*buffer, offset, 0);
			break;
		case LST_VECTOR:
			vector2bytestream(*buffer, offset, data->mVec);
			break;
		case LST_QUATERNION:
			quaternion2bytestream(*buffer, offset, data->mQuat);
			break;
		default:
			break;
		}
	}
	else
	{
		U8 *listbuf;
		S32 length = data->getListLength();
		size = 4 * length + 4;
		entry.mSize = size;

		size += SIZEOF_SCRIPT_ALLOC_ENTRY;
		*buffer = new U8[size];

		alloc_entry2bytestream(*buffer, offset, entry);
		// store length of list
		integer2bytestream(*buffer, offset, length);
		data = data->mListp;
		while(data)
		{
	// this bit of nastiness is to get around that code paths to local variables can result in lack of initialization
	// and function clean up of ref counts isn't based on scope (a mistake, I know)
			integer2bytestream(*buffer, offset, size + base_offset + 1);

			S32 listsize = lsa_create_data_block(&listbuf, data, base_offset + size);
			if (listsize)
			{
				U8 *tbuff = new U8[size + listsize];
				if (tbuff == NULL)
				{
					llerrs << "Memory Allocation Failed" << llendl;
				}
				memcpy(tbuff, *buffer, size);	/*Flawfinder: ignore*/
				memcpy(tbuff + size, listbuf, listsize);		/*Flawfinder: ignore*/
				size += listsize;
				delete [] *buffer;
				delete [] listbuf;
				*buffer = tbuff;
			}
			data = data->mListp;
		}
	}
	return size;
}