⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 si_instr.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * Copyright (C) Ericsson Mobile Communications AB, 2000.
 * Licensed to AU-System AB.
 * All rights reserved.
 *
 * This software is covered by the license agreement between
 * the end user and AU-System AB, and may be used and copied
 * only in accordance with the terms of the said agreement.
 *
 * Neither Ericsson Mobile Communications AB nor AU-System AB
 * assumes any responsibility or liability for any errors or inaccuracies in
 * this software, or any consequential, incidental or indirect damage arising
 * out of the use of the Generic WAP Client software.
 */
#include "si_instr.h"

#include "si_frame.h"
#include "si_libs.h"
#include "url.h"


typedef struct {
	enumErrorCode		(*func)( BYTE, pstructSI ); /* pointer to a function */
	UINT16			timeCost;
} structInstr_S;

typedef struct {
	enumErrorCode		(*func)( pstructSI );
	UINT16			timeCost;
} structInstr;


/* Global instruction arrays */


const structInstr_S			array1XXPPPPP[4] = 
{
	{	Exec_JUMP_FW_S, 1},
	{	Exec_JUMP_BW_S, 1},
	{	Exec_TJUMP_FW_S, 1},
	{	Exec_LOAD_VAR_S, 1}
};

 
const structInstr_S			array010XPPPP[2] =
{
	{	Exec_STORE_VAR_S, 1},
	{	Exec_LOAD_CONST_S, 1}
};


const structInstr_S			array011XXPPP[4] =
{
	{	Exec_CALL_S, 1},
	{	Exec_CALL_LIB_S, 1},
	{	Exec_INCR_VAR_S, 1},
	{ NULL, 0}
};


const structInstr				array00XXXXXX[64] =
{
	{ NULL, 0},		
	{	Exec_JUMP_FW, 1},			{ Exec_JUMP_FW_W, 1},			{	Exec_JUMP_BW, 1},
	{	Exec_JUMP_BW_W, 1},		{ Exec_TJUMP_FW, 1},			{ Exec_TJUMP_FW_W, 1},			
	{	Exec_TJUMP_BW, 1},		{ Exec_TJUMP_BW_W, 1},		{ Exec_CALL, 1},					
	{	Exec_CALL_LIB, 1},		{ Exec_CALL_LIB_W, 1},		{ Exec_CALL_URL, 1},			
	{	Exec_CALL_URL_W, 1},	{ Exec_LOAD_VAR, 1},			{ Exec_STORE_VAR, 1},			
	{	Exec_INCR_VAR, 1},		{ Exec_DECR_VAR, 1},			{ Exec_LOAD_CONST, 1},		
	{	Exec_LOAD_CONST_W, 1},{ Exec_CONST_0, 1},				{ Exec_CONST_1, 1},				
	{	Exec_CONST_M1, 1},		{ Exec_CONST_ES, 1},			{ Exec_CONST_INVALID, 1},	
	{	Exec_CONST_TRUE, 1},	{ Exec_CONST_FALSE, 1},		{ Exec_INCR, 1},					
	{	Exec_DECR, 1},				{ Exec_ADD_ASG, 1},				{ Exec_SUB_ASG, 1},				
	{	Exec_UMINUS, 1},			{ Exec_ADD, 1},						{ Exec_SUB, 1},						
	{	Exec_MUL, 1},					{ Exec_DIV, 1},						{ Exec_IDIV, 1},					
	{	Exec_REM, 1},					{ Exec_B_AND, 1},					{ Exec_B_OR, 1},					
	{	Exec_B_XOR, 1},				{ Exec_B_NOT, 1},					{ Exec_B_LSHIFT, 1},			
	{	Exec_B_RSSHIFT, 1},		{ Exec_B_RSZSHIFT, 1},		{ Exec_EQ, 1},						
	{	Exec_LE, 1},					{ Exec_LT, 1},						{ Exec_GE, 1},						
	{	Exec_GT, 1},					{ Exec_NE, 1},						{ Exec_NOT, 1},						
	{	Exec_SCAND, 1},				{ Exec_SCOR, 1},					{ Exec_TOBOOL, 1},				
	{	Exec_POP, 1},					{ Exec_TYPEOF, 1},				{ Exec_ISVALID, 1},				
	{	Exec_RETURN, 1},			{ Exec_RETURN_ES, 1},			{ Exec_DEBUG, 1},
	{ NULL, 0},							{ NULL, 0},								{ NULL, 0}
};



enumErrorCode ExecBytecodeInstr( BYTE instr, pstructSI si )
{
	UINT8		arrayIndex;

	if ((instr != 0) && (si != NULL)) 
	{
		if ( (instr & 0x80) == 0x80 ) 
		{
			arrayIndex = (instr & 0x60) >> 5;
			si->currTime += array1XXPPPPP[ arrayIndex ].timeCost;
			if (array1XXPPPPP[ arrayIndex ].func != NULL)
			{
				return (array1XXPPPPP[ arrayIndex ].func)( instr, si );
			}
			else
			{
				return ERR_WAE_WMLS_VERIFICATION;
			}
		}
		else if ( (instr & 0xE0) == 0x40 ) 
		{
			arrayIndex = (instr & 0x10) >> 4;
			si->currTime += array010XPPPP[ arrayIndex ].timeCost;
			if (array010XPPPP[ arrayIndex ].func != NULL)
			{
				return (array010XPPPP[ arrayIndex ].func)( instr, si );
			}
			else
			{
				return ERR_WAE_WMLS_VERIFICATION;
			}
		}
		else if ( (instr & 0xE0) == 0x60 ) 
		{
			arrayIndex = (instr & 0x18) >> 3;
			si->currTime += array011XXPPP[ arrayIndex ].timeCost;
			if (array011XXPPP[ arrayIndex ].func != NULL)
			{
				return (array011XXPPP[ arrayIndex ].func)( instr, si );
			}
			else
			{
				return ERR_WAE_WMLS_VERIFICATION;
			}
		}
		else if ( (instr & 0xC0) == 0x00 ) 
		{
			arrayIndex = instr & 0x3F;
			si->currTime += array00XXXXXX[ arrayIndex ].timeCost;
			if (array00XXXXXX[ arrayIndex ].func != NULL)
			{
				return (array00XXXXXX[ arrayIndex ].func)( si );
			}
			else
			{
				return ERR_WAE_WMLS_VERIFICATION;
			}
		}
		else
		{
				return ERR_WAE_WMLS_VERIFICATION;
		}
	}
	return ERR_WAE_WMLS_NULL;
}



/* Control flow instructions ***********************************************************/

enumErrorCode Exec_JUMP_FW_S( BYTE instr, pstructSI si )
{
	UINT8			offset;

	offset = Read5bFrom8b( instr );

	if ( RE_Jump( si->RE, offset ) ) {	
		/* at the given offset from the address of the 
		first byte following this instruction */
		return ERR_WAE_WMLS_NONE;
	}
	else {
		return ERR_WAE_WMLS_VERIFICATION;
	}
}


enumErrorCode Exec_JUMP_FW( pstructSI si ) 
{
	UINT8			offset;

	if (	RE_Read8bOperand( si->RE, &offset ) && 
				RE_Jump( si->RE, offset ) ) {
		/* at the given offset from the address of the 
		first byte following this instruction */
		return ERR_WAE_WMLS_NONE;
	}

	return ERR_WAE_WMLS_VERIFICATION;
}


enumErrorCode Exec_JUMP_FW_W( pstructSI si ) 
{
	UINT16			offset;

	if (	RE_Read16bOperand( si->RE, &offset ) && 
				RE_Jump( si->RE, offset ) ) {
		/* at the given offset from the address of the 
		first byte following this instruction */
		return ERR_WAE_WMLS_NONE;
	}

	return ERR_WAE_WMLS_VERIFICATION;
}


enumErrorCode Exec_JUMP_BW_S( BYTE instr, pstructSI si ) 
{
	UINT8			offset;

	offset = Read5bFrom8b( instr );

	if ( RE_Jump( si->RE, -((INT32)offset)-1 ) ) {	
		/* at the given offset from the address of this instruction */
		return ERR_WAE_WMLS_NONE;
	}
	else {
		return ERR_WAE_WMLS_VERIFICATION;
	}
}


enumErrorCode Exec_JUMP_BW( pstructSI si ) 
{
	UINT8			offset;

	if (	RE_Read8bOperand( si->RE, &offset ) && 
				RE_Jump( si->RE, -((INT32)offset)-2 ) ) {
		/* at the given offset from the address of this instruction */
		return ERR_WAE_WMLS_NONE;
	}

	return ERR_WAE_WMLS_VERIFICATION;
}


enumErrorCode Exec_JUMP_BW_W( pstructSI si ) 
{
	UINT16			offset;

	if (	RE_Read16bOperand( si->RE, &offset ) && 
				RE_Jump( si->RE, -((INT32)offset)-3 ) ) {
		/* at the given offset from the address of this instruction */
		return ERR_WAE_WMLS_NONE;
	}

	return ERR_WAE_WMLS_VERIFICATION;
}


enumErrorCode Exec_TJUMP_FW_S( BYTE instr, pstructSI si ) 
{
	UINT8				offset;
	BOOL				makeJump = TRUE;
	pstructVar	op1;


	offset = Read5bFrom8b( instr );
	op1 = RE_Pop( si->RE );

	if (op1 == NULL)
		return ERR_WAE_WMLS_STACK_UNDERFLOW;

	if (Var_ConvertMethod( CONVERT_BOOLS, op1, NULL )) {
			makeJump = ! (op1->val.theInt);	/* theInt is also the placeholder of the bool value */
			/* only jump on false or invalid */
	}
	/* if convert failed it is treated as invalid which leads to a jump */

	Var_Delete( &op1 );	/* op1 is no longer needed */

	if (makeJump) {

		if ( RE_Jump( si->RE, offset ) ) {	
		/* at the given offset from the address of the 
		first byte following this instruction */
			return ERR_WAE_WMLS_NONE;
		}
		else {
			return ERR_WAE_WMLS_VERIFICATION;
		}

	}
	else {
		return ERR_WAE_WMLS_NONE;
	}
}


enumErrorCode Exec_TJUMP_FW( pstructSI si ) 
{
	UINT8				offset;
	BOOL				makeJump = TRUE;
	pstructVar	op1;


	if ( ! RE_Read8bOperand( si->RE, &offset )) {
		return ERR_WAE_WMLS_VERIFICATION;
	}

	op1 = RE_Pop( si->RE );
	if (op1 == NULL)
		return ERR_WAE_WMLS_STACK_UNDERFLOW;

	if (Var_ConvertMethod( CONVERT_BOOLS, op1, NULL )) {
			makeJump = ! (op1->val.theInt);	/* theInt is also the placeholder of the bool value */
			/* only jump on false or invalid */
	}
	/* if convert failed it is treated as invalid which leads to a jump */

	Var_Delete( &op1 );	/* op1 is no longer needed */

	if (makeJump) {

		if ( RE_Jump( si->RE, offset ) ) {	
		/* at the given offset from the address of the 
		first byte following this instruction */
			return ERR_WAE_WMLS_NONE;
		}
		else {
			return ERR_WAE_WMLS_VERIFICATION;
		}

	}
	else {
		return ERR_WAE_WMLS_NONE;
	}
}


enumErrorCode Exec_TJUMP_FW_W( pstructSI si ) 
{
	UINT16				offset;
	BOOL				makeJump = TRUE;
	pstructVar	op1;


	if ( ! RE_Read16bOperand( si->RE, &offset )) {
		return ERR_WAE_WMLS_VERIFICATION;
	}

	op1 = RE_Pop( si->RE );
	if (op1 == NULL)
		return ERR_WAE_WMLS_STACK_UNDERFLOW;

	if (Var_ConvertMethod( CONVERT_BOOLS, op1, NULL )) {
			makeJump = ! (op1->val.theInt);	/* theInt is also the placeholder of the bool value */
			/* only jump on false or invalid */
	}
	/* if convert failed it is treated as invalid which leads to a jump */

	Var_Delete( &op1 );	/* op1 is no longer needed */

	if (makeJump) {

		if ( RE_Jump( si->RE, offset ) ) {	
		/* at the given offset from the address of the 
		first byte following this instruction */
			return ERR_WAE_WMLS_NONE;
		}
		else {
			return ERR_WAE_WMLS_VERIFICATION;
		}

	}
	else {
		return ERR_WAE_WMLS_NONE;
	}
}


enumErrorCode Exec_TJUMP_BW( pstructSI si ) 
{
	UINT8				offset;
	BOOL				makeJump = TRUE;
	pstructVar	op1;


	if ( ! RE_Read8bOperand( si->RE, &offset )) {
		return ERR_WAE_WMLS_VERIFICATION;
	}

	op1 = RE_Pop( si->RE );
	if (op1 == NULL)
		return ERR_WAE_WMLS_STACK_UNDERFLOW;

	if (Var_ConvertMethod( CONVERT_BOOLS, op1, NULL )) {
			makeJump = ! (op1->val.theInt);	/* theInt is also the placeholder of the bool value */
			/* only jump on false or invalid */
	}
	/* if convert failed it is treated as invalid which leads to a jump */

	Var_Delete( &op1 );	/* op1 is no longer needed */

	if (makeJump) {

		if ( RE_Jump( si->RE, -((INT32)offset)-2 ) ) {	
		/* at the given offset from the address of the 
		first byte following this instruction */
			return ERR_WAE_WMLS_NONE;
		}
		else {
			return ERR_WAE_WMLS_VERIFICATION;
		}

	}
	else {
		return ERR_WAE_WMLS_NONE;
	}
}


enumErrorCode Exec_TJUMP_BW_W( pstructSI si ) 
{
	UINT16			offset;
	BOOL				makeJump = TRUE;
	pstructVar	op1;


	if ( ! RE_Read16bOperand( si->RE, &offset )) {
		return ERR_WAE_WMLS_VERIFICATION;
	}

	op1 = RE_Pop( si->RE );
	if (op1 == NULL) {
		Var_Delete( &op1 );
		return ERR_WAE_WMLS_STACK_UNDERFLOW;
	}

	if (Var_ConvertMethod( CONVERT_BOOLS, op1, NULL )) {
			makeJump = ! (op1->val.theInt);	/* theInt is also the placeholder of the bool value */
			/* only jump on false or invalid */
	}
	/* if convert failed it is treated as invalid which leads to a jump */

	Var_Delete( &op1 );	/* op1 is no longer needed */

	if (makeJump) {

		if ( RE_Jump( si->RE, -((INT32)offset)-3 ) ) {	
		/* at the given offset from the address of the 
		first byte following this instruction */
			return ERR_WAE_WMLS_NONE;
		}
		else {
			return ERR_WAE_WMLS_VERIFICATION;
		}

	}
	else {
		return ERR_WAE_WMLS_NONE;
	}
}



/* Function call instructions ******************************************************************/
enumErrorCode Exec_CALL_S( BYTE instr, pstructSI si )
/*
CORRECTION 990226 (KHN)
=======================
Added so that a local function call makes sure to
report the stack underflow error. This happens if
there are less operands on the stack than the function
has as number of arguments.
*/
{
	UINT8				findex = 0;

	findex = Read3bFrom8b( instr );

	if (findex < si->RE->BPI->nbrOfFunctions) {
		/* valid function index */

		/* set the return IP*/

		FS_Push( si->RE->FS, &(si->RE->currF), si->RE->IP );
		si->RE->currF = Frame_New( findex, si->RE->BPI, si->RE->OpS );

    if (si->RE->currF == NULL)
    {	/* not enough operands on the OpS to match number of function arguments */
    	return ERR_WAE_WMLS_STACK_UNDERFLOW;
    }

		/* set the IP so the next instruction to be executed will be in the new function */
		si->RE->IP = si->RE->BPI->functions[ findex ].startPos;

		return ERR_WAE_WMLS_NONE;
	}
	else {
		return ERR_WAE_WMLS_VERIFICATION;
	}
}


enumErrorCode Exec_CALL( pstructSI si )
/*
CORRECTION 990226 (KHN)
=======================
Added so that a local function call makes sure to
report the stack underflow error. This happens if
there are less operands on the stack than the function
has as number of arguments.
*/
{
	UINT8				findex = 0;

	if ( ! RE_Read8bOperand( si->RE, &findex )) {
		return ERR_WAE_WMLS_VERIFICATION;
	}

	if (findex < si->RE->BPI->nbrOfFunctions) {
		/* valid function index */
		FS_Push( si->RE->FS, &(si->RE->currF), si->RE->IP );
		si->RE->currF = Frame_New( findex, si->RE->BPI, si->RE->OpS );

		/* set the IP so the next instruction to be executed will be in the new function */
		si->RE->IP = si->RE->BPI->functions[ findex ].startPos;

    if (si->RE->currF == NULL)
    {	/* not enough operands on the OpS to match number of function arguments */
    	return ERR_WAE_WMLS_STACK_UNDERFLOW;
    }

		return ERR_WAE_WMLS_NONE;
	}
	else {
		return ERR_WAE_WMLS_VERIFICATION;
	}
}


enumErrorCode Exec_CALL_LIB_S( BYTE instr, pstructSI si ) 
{
	UINT8				findex = 0,
							lindex = 0;

	findex = Read3bFrom8b( instr );

	if ( ! RE_Read8bOperand( si->RE, &lindex )) {
		return ERR_WAE_WMLS_VERIFICATION;
	}
	return CallLibraryFunction( si, lindex, findex );
}


enumErrorCode Exec_CALL_LIB( pstructSI si ) 
{
	UINT8				findex = 0;
	UINT8				lindex = 0;

	if ( ! RE_Read8bOperand( si->RE, &findex )) {
		return ERR_WAE_WMLS_VERIFICATION;
	}
	if ( ! RE_Read8bOperand( si->RE, &lindex )) {
		return ERR_WAE_WMLS_VERIFICATION;
	}
	return CallLibraryFunction( si, lindex, findex );
}


enumErrorCode Exec_CALL_LIB_W( pstructSI si ) 
{
	UINT8				findex = 0;
	UINT16			lindex = 0;

	if ( ! RE_Read8bOperand( si->RE, &findex )) {
		return ERR_WAE_WMLS_VERIFICATION;
	}
	if ( ! RE_Read16bOperand( si->RE, &lindex )) {
		return ERR_WAE_WMLS_VERIFICATION;
	}
	return CallLibraryFunction( si, lindex, findex );
}


enumErrorCode Exec_CALL_URL( pstructSI si )
{
	UINT8						cindexURL		= 0;
	UINT8						cindexFUNC	= 0;
	UINT8						nbrOfArgs		= 0;
	pstructVar			url = NULL;
	WCHAR*					resolvedUrl = NULL;
	BYTE*						utf8_funcName = NULL;
	enumConstType		constType;
	enumErrorCode		error = ERR_WAE_WMLS_VERIFICATION;

	if ( ! RE_Read8bOperand( si->RE, &cindexURL )) {
		return ERR_WAE_WMLS_VERIFICATION;
	}
	if ( ! RE_Read8bOperand( si->RE, &cindexFUNC )) {
		return ERR_WAE_WMLS_VERIFICATION;
	}
	if ( ! RE_Read8bOperand( si->RE, &nbrOfArgs )) {
		return ERR_WAE_WMLS_VERIFICATION;
	}

	if (BPI_GetConstantType( si->RE->BPI, cindexURL, &constType ))
	{
		utf8_funcName = BPI_GetRawUTF8Constant( si->RE->BPI, si->RE->BP, si->RE->BPend, cindexFUNC );
		if ((constType >= CONST_TYPE_UTF8) && (constType <= CONST_TYPE_EXT_CHARSET) && (utf8_funcName != NULL) )
		{
			url = BPI_GetConstant( si->RE->BPI, si->RE->BP, si->RE->BPend, cindexURL );
			if (url != NULL)
			{
				if (w_Resolve (si->baseURL, url->val.theString, &resolvedUrl))
				{
					si->returnInfo = SI_RETURN_EXTERNAL;

					if ( SI_NewReturnParams( si ) )
					{
						/* the SIs returnparams struct is to be filled in */
						si->returnParams->islibCall = FALSE;

						si->returnParams->bpUrl = resolvedUrl;
						resolvedUrl = NULL;

						si->returnParams->funcName = utf8_funcName;
						utf8_funcName = NULL;

           	si->returnParams->argOpS = OpS_NewFromOpS( si->RE->OpS, nbrOfArgs );
						if (si->returnParams->argOpS != NULL)
						{
							error = ERR_WAE_WMLS_NONE;
						}
						else
						{
							error = ERR_WAE_WMLS_STACK_UNDERFLOW;
						}
					}
				}
				/* else ERR_WAE_WMLS_VERIFICATION (the init value of error) */
			}
		}
	}

	DEALLOC( &resolvedUrl );
	Var_Delete( &url );
	DEALLOC( &utf8_funcName );

	return error;
}


enumErrorCode Exec_CALL_URL_W( pstructSI si )
{
	UINT16					cindexURL		= 0;
	UINT16					cindexFUNC	= 0;
	UINT8						nbrOfArgs		= 0;
	pstructVar			url = NULL;
	WCHAR*					resolvedUrl = NULL;
	BYTE*						utf8_funcName = NULL;
	enumConstType		constType;
	enumErrorCode				error = ERR_WAE_WMLS_VERIFICATION;

	if ( ! RE_Read16bOperand( si->RE, &cindexURL )) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -