?? 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 + -