📄 decomp_action.c
字号:
#include <stdio.h>#include <sys/types.h>#include "decomp_action.h"static unsigned char * action_block;static ssize_t action_len=0;static size_t ptr_offset=0;static char *false_str="false";static char *true_str="true";static char *null_str="NULL";static char *undef_str="undefined";static struct mem_chain *mem_head=NULL;static sigjmp_buf jmpbuf;static signed int this_errno=0;static int print_code=0;static print_buffer my_buffer;static int gIndent = 0;char indentBuf[256];int byteorder;my_dictionary *dictionary;static reg_array *reg_global=NULL;static reg_array *reg_current=NULL;static struct ActionRecord *action_save=NULL;static Stack stack = NULL;static uint32_t dictionary_count=0;/*funciton2的6个自动寄存器预定义值*/char *arNames[] = {"this", "arguments", "super", "_root", "_parent", "_global"};/*6个自动寄存器true测试位*/unsigned int arFlags[] = {0x0001, 0x0004, 0x0010, 0x0040, 0x0080, 0x0100};/*6个自动寄存器false测试位*/unsigned int arNotFlags[] = {0x0002, 0x0008, 0x0020, 0x0000, 0x0000, 0x0000};/*--------------------add_mem_chain--------------------------*///////////////////////////////////////////////////////////////////// add_mem_chain函数 //// //// 用于将calloc系统调用分配的内存挂接到临时链表中,待退出时释放 //// ptr指向分配的内存区域,type指定类型,类型值将用来标示这个内存 //// 的释放方式,size可以用来表示长度,该长度的意义根据type的不同 //// 而不同,add_mem_chain只是简单的0将size保存在链表节点的size成员//// 中 ////////////////////////////////////////////////////////////////////void * add_mem_chain(void *ptr,int type,ssize_t size) { struct mem_chain *tmp_node; tmp_node=Malloc(sizeof(struct mem_chain)); memset(tmp_node,0,sizeof(struct mem_chain)); tmp_node->ptr=ptr; tmp_node->size=size; tmp_node->type=type; tmp_node->next=mem_head; mem_head=tmp_node; return(tmp_node);}/*--------------------del_mem_chain----------------------------*//////////////////////////////////////////////////////////////////////// 从临时内存链表中取下内存节点 //// 该函数负责释放内存链表节点,而不释放节点上挂接的内存区域 //// ptr指针标示要取下哪个内存区域,如果在链表中不能找到该区域 //// 则返回NULL表示错误,部分函数会将函数内部动态分配和使用的内存 //// 挂接到临时链表中,以防备函数中途失败导致不能释放内存 //// 这些函数会在成功返回前将内存从链表中取下 ///////////////////////////////////////////////////////////////////////void * del_mem_chain(void *ptr) { struct mem_chain **tmp_node=&mem_head,*free_node=NULL; void * str=NULL; while(*tmp_node) { if(ptr==(*tmp_node)->ptr) { str=ptr; free_node=(*tmp_node); (*tmp_node)=(*tmp_node)->next; break; } tmp_node=&((*tmp_node)->next); } if(free_node) free(free_node); return(str);}/*------------------------my_readBit------------------------*///////////////////////////////////////////////////////////////////////// 读bit位函数 //// 从一个字节数据中读指定连续bit位,如读(char)val的第2和第3bit的值 //// 要读如的bit的位置必须是连续的,mask为位掩码 //// example: //// result=my_readBit(val,"01100000"); ////////////////////////////////////////////////////////////////////////uint8_t my_readBit(uint8_t val,const char *mask) { uint32_t n=0,ck=0; uint8_t v=0,last='0'; int fir_local=IMPOSSIBLE_BIT_LOCAL,i=0; if(!mask||(n=strlen(mask))!=8) err_debug(ERR_ARGUMENT,"my_readBit:invalid argument!"); for(i=(n-1);i>=0;i--) { if(last!=mask[i]) { if(++ck>2) err_debug(ERR_ARGUMENT,"my_readBit:Invalid mask argument:\"%s\"",mask); last=mask[i]; } if(mask[i]=='1') { if(fir_local==IMPOSSIBLE_BIT_LOCAL) fir_local=(n-i-1); if((1<<(n-i-1)) & val) v|=1<<(n-i-1-fir_local); } else if(mask[i]=='0') {} else err_debug(ERR_ARGUMENT,"my_readBit:Invalid mask argument:\"%s\"",mask); } if(ck>2) err_debug(ERR_ARGUMENT,"my_readBit:Invalid mask argument:\"%s\"",mask); return (v);}//////////////////////////////////////////////////////////// Malloc内存动态分配函数 //// //// 加入了错误处理的malloc函数 //// /////////////////////////////////////////////////////////////*------------------------Malloc------------------------*/void * Malloc(size_t thislen) { void *ptr; if(thislen<=0) { err_debug(ERR_ARGUMENT,"Malloc:wrong argument!"); } if(thislen>BUFFER_MAX_SIZE) { err_debug(ERR_ARGUMENT,"Malloc:wrong argument!"); }RE_MALLOC: if((ptr=malloc(thislen))==NULL) { if(errno==EINTR) goto RE_MALLOC; else err_debug(ERR_MEMORY,"Malloc:Cannot allocate memory!"); } memset(ptr,0,thislen); return(ptr);}/*----------------------Realloc------------------------*//////////////////////////////////////////////////////////// Realloc重新内存分配函数 //// //// 加入了错误处理 //// //// ///////////////////////////////////////////////////////////void *Realloc(void *oldptr,size_t thislen) { void *ptr; if(thislen<=0||oldptr==NULL) { err_debug(ERR_ARGUMENT,"Realloc:wrong argument!"); } if(thislen>BUFFER_MAX_SIZE) { err_debug(ERR_ARGUMENT,"Realloc:wrong argument!"); }RE_ALLOC: if((ptr=realloc(oldptr,thislen))==NULL) { if(errno==EINTR) goto RE_ALLOC; else err_debug(ERR_MEMORY,"Realloc:Cannot allocate memory!"); } return(ptr);}/*--------------------re_allocate_buffer-----------------*//////////////////////////////////////////////////////////////// re_allocate_buffer //// //// 用于输出缓冲在空间不足时区重新分配内存 //// 并拷贝已有数据 //// thislen参数指明要重新分配的空间的大小 //// 返回值为分配到的空间size ///////////////////////////////////////////////////////////////size_t re_allocate_buffer(size_t thislen) { char *ptr=NULL; uint32_t old_cur=0; if(thislen<0||thislen>=BUFFER_MAX_SIZE) { err_debug(ERR_ARGUMENT,"re_allocate_buffer:wrong argument!"); } /*如果分配过内存,并且要重新分配的长度等于0则释放已有内存*/ if(thislen==0) { if(my_flags!=BUFFER_UN_INIT && my_ptr) free(my_ptr); INIT_BUFFER; return(0); } /*如果没有分配过内存,则调用Malloc分配内存*/ if(my_flags==BUFFER_UN_INIT) { old_cur=0; ptr=(char *)Malloc(thislen); } else { /*否则调用Realloc重新分配内存*/ old_cur=my_cur; ptr=(char *)Realloc(my_ptr,thislen); } /*清零比原有内存区多出来的分配的空间*/ if(thislen>old_cur) memset((ptr+old_cur),0,thislen-old_cur); my_ptr=ptr; my_len=thislen; my_cur=old_cur; my_flags=BUFFER_INIT; return (thislen);}/*---------------------my_printf-------------------------*////////////////////////////////////////////////////////////// 打印输出到内存缓冲区函数 //// //// 完全兼容printf函数调用方式 //// 该函数发现缓冲区空间不足时重新分配缓冲区 //// 并且复制已有数据到新的缓冲区中 //// 复制工作是靠realloc函数实现的 //// 该函数调用方式和printf函数相同, //// 返回值是打印的字节数 //// /////////////////////////////////////////////////////////////int my_printf(const char *fmt,...) { va_list ap; int i; size_t tmp_len; /*如果没有初始化过内存缓冲区则分配基本大小(BUFFER_DEF_SIZE)的缓冲区*/ if(my_flags==BUFFER_UN_INIT) { if(re_allocate_buffer(BUFFER_DEF_SIZE)!=BUFFER_DEF_SIZE) err_debug(ERR_CALL,"my_printf:re_allocate call failure!"); } /*如果调用BUFFER_WILL_FULL宏发现缓冲区空间不足则增加BUFFER_STEP_SIZE字节*/ while(BUFFER_WILL_FULL) { tmp_len=my_len+BUFFER_STEP_SIZE; if(re_allocate_buffer(tmp_len)!=tmp_len) err_debug(ERR_CALL,"my_printf:re_allocate call failure!"); } /*打印内存函数vsnprintf会保证不会写多于剩余缓冲区大小的字节*/RE_PRINT: va_start(ap,fmt); i=vsnprintf(my_cur_ptr,my_remain_len,fmt,ap); va_end(ap); /*如果vsnprintf返回值大于或者等于剩余的空间数则说明还有剩余内容未打印*/ /*则重新多分配buffer_step_size的内存再次调用vsnprintf语句,直至*/ /*起始地址加上vsnprintf的返回值小于当前剩余的内存数为止*/ if((my_cur+i)>=my_len-2) { tmp_len=my_len+(BUFFER_STEP_SIZE>i?BUFFER_STEP_SIZE:(i+BUFFER_STEP_SIZE)); if(re_allocate_buffer(tmp_len)!=tmp_len) err_debug(ERR_CALL,"my_printf:re_allocate call failure!"); goto RE_PRINT; } /*更新当前缓冲区空闲区域的起始位置*/ my_cur+=i; return(i);}/*-----------------------My_readDouble--------------------------*///////////////////////////////////////////////////////////////////// 从输入的p-code内存中读一个double(8byte) //// 因为字节序的原因要重新更新位置 //// ////////////////////////////////////////////////////////////////////double My_readDouble() { char data[8]; if(!TEST_SPACE(sizeof(double))) { err_debug(ERR_INPUT,"My_readDouble:no enough input"); } data[4] = My_readUInt8(); data[5] = My_readUInt8(); data[6] = My_readUInt8(); data[7] = My_readUInt8(); data[0] = My_readUInt8(); data[1] = My_readUInt8(); data[2] = My_readUInt8(); data[3] = My_readUInt8(); return *((double *)data);}/*--------------------My_readString------------------------------*////////////////////////////////////////////////////////////////////// 从输入P-code的内存中读一个字符串 //// 如果字符串中包含制表符,回车,换行则转换成 //// 转义子符\t,\n或\r /////////////////////////////////////////////////////////////////////char *My_readString() { int len = 0, buflen = 256; char c, *buf, *p; buf = (char *)Malloc(sizeof(char)*256); p = buf; while((c=(char)My_readUInt8()) != '\0'&& !block_eof()) { if(len >= buflen-2) { buf = (char *)Realloc(buf, sizeof(char)*(buflen+256)); buflen += 256; p = buf+len; } switch(c) { case '\n': *(p++) = '\\'; *(p++) = 'n'; ++len; break; case '\t': *(p++) = '\\'; *(p++) = 't'; ++len; break; case '\r':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -