doubango/tinySIGCOMP/src/tcomp_udvm.c
c732d49e
 #if HAVE_CRT
 #define _CRTDBG_MAP_ALLOC 
 #include <stdlib.h> 
 #include <crtdbg.h>
 #endif //HAVE_CRT
 /*
 * Copyright (C) 2010-2011 Mamadou Diop
 * Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org>
 *	
 * This file is part of Open Source Doubango Framework.
 *
 * DOUBANGO is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *	
 * DOUBANGO is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *	
 * You should have received a copy of the GNU General Public License
 * along with DOUBANGO.
 *
 */
 
 /**@file tcomp_udvm.c
  * @brief  SigComp UDVM machine.
  */
 #include "tcomp_udvm.h"
 
 #include "tsk_memory.h"
 #include "tsk_debug.h"
 
 #include <string.h>
 
 #define TCOMP_UDVM_HEADER_RESERVED_SIZE 22
 
 tcomp_udvm_t* tcomp_udvm_create(tcomp_message_t* _sigCompMessage, tcomp_statehandler_t*  stateHandler, tcomp_result_t* lpResult)
 {
 	tcomp_udvm_t *udvm;
 	if((udvm = tsk_object_new(tcomp_udvm_def_t))){
 		/* RFC 3320 - 7.  SigComp Message Format */
 		udvm->sigCompMessage = tsk_object_ref(_sigCompMessage);
 		udvm->stateHandler = tsk_object_ref(stateHandler);
 		udvm->lpResult = tsk_object_ref(lpResult);
 		
 		udvm->isOK = tsk_true;
 		udvm->maximum_UDVM_cycles = 0; /* RFC 3320 subclause 8.6 */
 		udvm->consumed_cycles = 0;
 		udvm->memory = tcomp_buffer_create_null();
 
 		/* Alloc UDVM memory */
 		if(udvm->sigCompMessage->stream_based){
 			/*
 			* If the transport is stream-based however, then a fixed-size input buffer is required to accommodate the stream, independently of the
 			* size of each SigComp message. So, for simplicity, the UDVM memory size is set to (decompression_memory_size / 2).
 			*/
 
 			tcomp_buffer_allocBuff(udvm->memory, udvm->stateHandler->sigcomp_parameters->dmsValue/2);
 		}
 		else{
 			/*
 			* If the transport is message-based then sufficient memory must be available
 			* to buffer the entire SigComp message before it is passed to the UDVM. So if the message is n bytes long, then the UDVM memory size is set
 			* to (decompression_memory_size - n), up to a maximum of 65536 bytes.
 			*/
 			tcomp_buffer_allocBuff(udvm->memory, (udvm->stateHandler->sigcomp_parameters->dmsValue-udvm->sigCompMessage->totalSize));
 		}
 
 		/*
 		* Has feedback with my state id?
 		*/
 		if(tcomp_buffer_getSize(udvm->sigCompMessage->ret_feedback_buffer)){
 			tsk_size_t size = tcomp_buffer_getSize(udvm->sigCompMessage->ret_feedback_buffer);
 			tcomp_buffer_allocBuff(udvm->lpResult->ret_feedback, size);
 			memcpy(tcomp_buffer_getBuffer(udvm->lpResult->ret_feedback), tcomp_buffer_getBuffer(udvm->sigCompMessage->ret_feedback_buffer), size);
 		}
 		
 		/*
 		*	Has state?
 		*/
 		if(tcomp_buffer_getSize(udvm->sigCompMessage->stateId)){
 			/* Find the provided state */
 			tcomp_state_t* lpState = NULL;
 			uint32_t match_count = tcomp_statehandler_findState(udvm->stateHandler, udvm->sigCompMessage->stateId, &lpState);
 			if( (match_count != 1 || !lpState)
 				|| (lpState->minimum_access_length > tcomp_buffer_getSize(udvm->sigCompMessage->stateId))
 				|| ((tsk_size_t)(lpState->address + lpState->length) > TCOMP_UDVM_GET_SIZE()) )
 			{
 				TSK_DEBUG_ERROR("NACK_STATE_NOT_FOUND for id = ");
 				tcomp_buffer_print(udvm->sigCompMessage->stateId);
 				tcomp_udvm_createNackInfo(udvm, NACK_STATE_NOT_FOUND, udvm->sigCompMessage->stateId, 0);
 				udvm->isOK = tsk_false;
 				goto bail;
 			}
 			/*
 			* Copy bytecodes to UDVM memory
 			*/
 			if( (tsk_size_t)(lpState->address + lpState->length) >= TCOMP_UDVM_GET_SIZE() ){
 				tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT);
 				udvm->isOK = tsk_false;
 				goto bail;
 			}
 			memcpy( TCOMP_UDVM_GET_BUFFER_AT(lpState->address), 
 				tcomp_buffer_getBuffer(lpState->value), 
 				tcomp_buffer_getSize(lpState->value) );
 			
 			//RFC 3320 - 7.2.  Accessing Stored State (Useful values)
 			TCOMP_UDVM_SET_2BYTES_VAL(TCOMP_UDVM_HEADER_PARTIAL_STATE_ID_LENGTH_INDEX, (uint16_t)tcomp_buffer_getSize(udvm->sigCompMessage->stateId));
 			TCOMP_UDVM_SET_2BYTES_VAL(TCOMP_UDVM_HEADER_STATE_LENGTH_INDEX, (uint16_t)tcomp_buffer_getSize(lpState->value));
 			
 			udvm->executionPointer = lpState->instruction;
 		}
 		else // DON'T HAVE STATE
 		{
 			/*
 			* Copy bytecodes to UDVM memory
 			*/
 			tsk_size_t bytecodes_destination = udvm->sigCompMessage->bytecodes_destination;
 			if( (bytecodes_destination + tcomp_buffer_getSize(udvm->sigCompMessage->uploaded_UDVM_buffer)) >= TCOMP_UDVM_GET_SIZE() ){
 				tcomp_udvm_createNackInfo2(udvm, NACK_BYTECODES_TOO_LARGE);
 				udvm->isOK = tsk_false;
 				goto bail;
 			}
 			memcpy( TCOMP_UDVM_GET_BUFFER_AT(bytecodes_destination),
 				tcomp_buffer_getBuffer(udvm->sigCompMessage->uploaded_UDVM_buffer),
 				tcomp_buffer_getSize(udvm->sigCompMessage->uploaded_UDVM_buffer));
 
 			// Set pointer indicating execution index
 			udvm->executionPointer = bytecodes_destination;
 		}
 
 		/* RFC 3320-Section_8.6.  UDVM Cycles
 		*
 		* the maximum number of UDVM cycles available for processing an n-byte SigComp message is given by the formula
 		* maximum_UDVM_cycles = (8 * n + 1000) * cycles_per_bit
 		*/
 		udvm->maximum_UDVM_cycles = ( (8 * udvm->sigCompMessage->header_size + 1000) * udvm->stateHandler->sigcomp_parameters->cpbValue );
 		
 		//
 		//	RFC 3320 - 7.2.  Useful values
 		//
 		TCOMP_UDVM_SET_2BYTES_VAL(TCOMP_UDVM_HEADER_UDVM_MEMORY_SIZE_INDEX, (uint16_t)TCOMP_UDVM_GET_SIZE());
 		TCOMP_UDVM_SET_2BYTES_VAL(TCOMP_UDVM_HEADER_CYCLES_PER_BIT_INDEX, udvm->stateHandler->sigcomp_parameters->cpbValue);
 		TCOMP_UDVM_SET_2BYTES_VAL(TCOMP_UDVM_HEADER_SIGCOMP_VERSION_INDEX, udvm->stateHandler->sigcomp_parameters->SigComp_version);
 		memset(TCOMP_UDVM_GET_BUFFER_AT(TCOMP_UDVM_HEADER_RESERVED_INDEX), 0, TCOMP_UDVM_HEADER_RESERVED_SIZE);
 	}
 	else{
 		TSK_DEBUG_ERROR("Failed to create new udvm machine.");
 	}
 
 bail:
 	return udvm;
 }
 
 /**Executes the bytecode.
 */
 static tsk_bool_t tcomp_udvm_runByteCode(tcomp_udvm_t *udvm)
 {
 	uint32_t operand_1, operand_2, operand_3, operand_4, operand_5, operand_6, operand_7;
 	tsk_bool_t excution_failed = tsk_false, end_message = tsk_false;
 	if(!udvm->isOK) {
 		TSK_DEBUG_ERROR("Cannot run()/execute() invalid bytecode");
 		return tsk_false;
 	}
 
 	// LOOP - EXCUTE all bytecode
 	while( !excution_failed && !end_message )
 	{
 		uint8_t udvm_instruction = * (TCOMP_UDVM_GET_BUFFER_AT(udvm->executionPointer));
 		udvm->last_memory_address_of_instruction = udvm->executionPointer;
 		udvm->executionPointer++; /* Skip the 1-byte [INSTRUCTION]. */
 
 		switch(udvm_instruction)
 		{
 		case TCOMP_UDVM_INST__DECOMPRESSION_FAILURE:
 			{
 				TCOMP_UDVM_EXEC_INST__DECOMPRESSION_FAILURE(udvm);
 				excution_failed = tsk_true;
 				break;
 			}
 
 		case TCOMP_UDVM_INST__AND:
 			{
 				operand_1 = tcomp_udvm_opget_reference_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__AND(udvm, operand_1, operand_2);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__OR:
 			{
 				operand_1 = tcomp_udvm_opget_reference_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__OR(udvm, operand_1, operand_2);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__NOT:
 			{
 				operand_1 = tcomp_udvm_opget_reference_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__NOT(udvm, operand_1);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__LSHIFT:
 			{
 				operand_1 = tcomp_udvm_opget_reference_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__LSHIFT(udvm, operand_1, operand_2);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__RSHIFT:
 			{
 				operand_1 = tcomp_udvm_opget_reference_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__RSHIFT(udvm, operand_1, operand_2);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__ADD:
 			{
 				operand_1 = tcomp_udvm_opget_reference_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__ADD(udvm, operand_1, operand_2);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__SUBTRACT:
 			{
 				operand_1 = tcomp_udvm_opget_reference_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__SUBTRACT(udvm, operand_1, operand_2);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__MULTIPLY:
 			{
 				operand_1 = tcomp_udvm_opget_reference_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__MULTIPLY(udvm, operand_1, operand_2);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__DIVIDE:
 			{
 				operand_1 = tcomp_udvm_opget_reference_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__DIVIDE(udvm, operand_1, operand_2);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__REMAINDER:
 			{
 				operand_1 = tcomp_udvm_opget_reference_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__REMAINDER(udvm, operand_1, operand_2);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__SORT_ASCENDING:
 			{
 				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_3 = tcomp_udvm_opget_multitype_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__SORT_ASCENDING(udvm, operand_1, operand_2, operand_3);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__SORT_DESCENDING:
 			{
 				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_3 = tcomp_udvm_opget_multitype_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__SORT_DESCENDING(udvm, operand_1, operand_2, operand_3);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__SHA_1:
 			{
 				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_3 = tcomp_udvm_opget_multitype_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__SHA_1(udvm, operand_1, operand_2, operand_3);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__LOAD:
 			{
 				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__LOAD(udvm, operand_1, operand_2);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__MULTILOAD:
 			{
 				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_2 = tcomp_udvm_opget_literal_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__MULTILOAD(udvm, operand_1, operand_2);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__PUSH:
 			{
 				excution_failed = !TCOMP_UDVM_EXEC_INST__PUSH2(udvm);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__POP:
 			{
 				excution_failed = !TCOMP_UDVM_EXEC_INST__POP2(udvm);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__COPY:
 			{
 				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_3 = tcomp_udvm_opget_multitype_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__COPY(udvm, operand_1, operand_2, operand_3);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__COPY_LITERAL:
 			{
 				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_3 = tcomp_udvm_opget_reference_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__COPY_LITERAL(udvm, operand_1, operand_2, operand_3);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__COPY_OFFSET:
 			{
 				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_3 = tcomp_udvm_opget_reference_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__COPY_OFFSET(udvm, operand_1, operand_2, operand_3);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__MEMSET:
 			{
 				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_3 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_4 = tcomp_udvm_opget_multitype_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__MEMSET(udvm, operand_1, operand_2, operand_3, operand_4);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__JUMP:
 			{
 				excution_failed = !TCOMP_UDVM_EXEC_INST__JUMP2(udvm);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__COMPARE:
 			{
 				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_3 = tcomp_udvm_opget_address_param(udvm, udvm->last_memory_address_of_instruction);
 				operand_4 = tcomp_udvm_opget_address_param(udvm, udvm->last_memory_address_of_instruction);
 				operand_5 = tcomp_udvm_opget_address_param(udvm, udvm->last_memory_address_of_instruction);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__COMPARE(udvm, operand_1, operand_2, operand_3, operand_4, operand_5);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__CALL:
 			{
 				operand_1 = tcomp_udvm_opget_address_param(udvm, udvm->last_memory_address_of_instruction);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__CALL(udvm, operand_1);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__RETURN:
 			{
 				excution_failed = !TCOMP_UDVM_EXEC_INST__RETURN(udvm);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__SWITCH:
 			{
 				operand_1 = tcomp_udvm_opget_literal_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__SWITCH(udvm, operand_1, operand_2);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__CRC:
 			{
 				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_3 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_4 = tcomp_udvm_opget_reference_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__CRC(udvm, operand_1, operand_2, operand_3, operand_4);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__INPUT_BYTES:
 			{
 				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_3 = tcomp_udvm_opget_address_param(udvm, udvm->last_memory_address_of_instruction);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__INPUT_BYTES(udvm, operand_1, operand_2, operand_3);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__INPUT_BITS:
 			{	
 				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_3 = tcomp_udvm_opget_address_param(udvm, udvm->last_memory_address_of_instruction);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__INPUT_BITS(udvm, operand_1, operand_2, operand_3);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__INPUT_HUFFMAN:
 			{
 				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_2 = tcomp_udvm_opget_address_param(udvm, udvm->last_memory_address_of_instruction);
 				operand_3 = tcomp_udvm_opget_literal_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__INPUT_HUFFMAN(udvm, operand_1, operand_2, operand_3);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__STATE_ACCESS:
 			{
 				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_3 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_4 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_5 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_6 = tcomp_udvm_opget_multitype_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__STATE_ACCESS(udvm, operand_1, operand_2, operand_3, operand_4, operand_5, operand_6);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__STATE_CREATE:
 			{
 				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_3 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_4 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_5 = tcomp_udvm_opget_multitype_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__STATE_CREATE(udvm, operand_1, operand_2, operand_3, operand_4, operand_5);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__STATE_FREE:
 			{
 				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__STATE_FREE(udvm, operand_1, operand_2);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__OUTPUT:
 			{
 				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__OUTPUT(udvm, operand_1, operand_2);
 				break;
 			}
 
 		case TCOMP_UDVM_INST__END_MESSAGE:
 			{
 				operand_1 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_2 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_3 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_4 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_5 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_6 = tcomp_udvm_opget_multitype_param(udvm);
 				operand_7 = tcomp_udvm_opget_multitype_param(udvm);
 				excution_failed = !TCOMP_UDVM_EXEC_INST__END_MESSAGE(udvm, operand_1, operand_2, operand_3, operand_4, operand_5, operand_6, operand_7);
 				end_message = 1;
 				break;
 			}
 
 		default:
 			tcomp_udvm_createNackInfo2(udvm, NACK_INVALID_OPCODE);
 			goto bail;
 		}
 
 		if(excution_failed){
 			TSK_DEBUG_ERROR("Execution failed for instruction = %s", TCOMP_INST_DESCRIPTIONS[udvm_instruction].desc);
 		}
 		//TCOMP_UDVM_DEBUG_PRINT(200);
 	}
 
 bail:
 	udvm->lpResult->consumed_cycles = udvm->consumed_cycles;
 	return (!excution_failed);
 }
 
 /**Decompress the bytecode.
 */
 tsk_bool_t tcomp_udvm_decompress(tcomp_udvm_t *udvm)
 {
 	return tcomp_udvm_runByteCode(udvm);
 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 //========================================================
 //	UDVM machine definition
 //
 static tsk_object_t* tcomp_udvm_ctor(tsk_object_t * self, va_list * app)
 {
 	tcomp_udvm_t *udvm = self;
 	if(udvm){
 
 	}
 	return self;
 }
 
 static tsk_object_t* tcomp_udvm_dtor(tsk_object_t *self)
 {
 	tcomp_udvm_t *udvm = self;
 	if(udvm){
 		TSK_OBJECT_SAFE_FREE(udvm->memory);
 		TSK_OBJECT_SAFE_FREE(udvm->sigCompMessage);
 		TSK_OBJECT_SAFE_FREE(udvm->stateHandler);
 		TSK_OBJECT_SAFE_FREE(udvm->lpResult);
 
 		TSK_FREE(udvm->tmp_buff.ptr);
 	}
 	else{
 		TSK_DEBUG_ERROR("Null udvm machine.");
 	}
 
 	return self;
 }
 
 static const tsk_object_def_t tcomp_udvm_def_s = 
 {
 	sizeof(tcomp_udvm_t),
 	tcomp_udvm_ctor,
 	tcomp_udvm_dtor,
 	tsk_null
 };
 const tsk_object_def_t *tcomp_udvm_def_t = &tcomp_udvm_def_s;