123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747 |
- #include <windows.h>
- #include <stdio.h>
- #include <math.h>
- #include "Compiler.h"
- #include "eval.h"
- // defining this allows code to run in different threads at the same time
- // it tends however, to be slower. We leave this OFF for AVS, since most of our shit runs in one thread
- // anyhow.
- //#define NSEEL_REENTRANT_EXECUTION
- #ifdef NSEEL_REENTRANT_EXECUTION
- #include <malloc.h>
- #endif
- #define NSEEL_USE_CRITICAL_SECTION g_eval_cs
- // note that compiling can only happen in one thread at a time, always.
- int g_evallib_stats[5]; // source bytes, static code bytes, call code bytes, data bytes, segments
- #ifdef NSEEL_USE_CRITICAL_SECTION
- CRITICAL_SECTION NSEEL_USE_CRITICAL_SECTION;
- #endif
- #define LLB_DSIZE (65536-64)
- typedef struct _llBlock {
- struct _llBlock *next;
- int sizeused;
- char block[LLB_DSIZE];
- } llBlock;
- typedef struct _startPtr {
- struct _startPtr *next;
- void *startptr;
- } startPtr;
- typedef struct {
- int workTablePtr_size;
- llBlock *blocks;
- void *code;
- int code_stats[4];
- } codeHandleType;
- static llBlock *blocks_head = NULL;
- static llBlock *tmpblocks_head = NULL; // used only during compile
- #define NSEEL_MAX_TEMPSPACE_ENTRIES 8192
- static int g_evallib_computTableTop; // make it abort on potential overflow =)
- static int l_stats[4]; // source bytes, static code bytes, call code bytes, data bytes
- static void *__newBlock(llBlock **start,int size);
- #define newTmpBlock(x) __newBlock(&tmpblocks_head,x)
- #define newBlock(x) __newBlock(&blocks_head,x)
- static void freeBlocks(llBlock *start);
- char *g_evallib_visdata;
- #define DECL_ASMFUNC(x) \
- void _asm_##x##(void); \
- void _asm_##x##_end(void); \
- DECL_ASMFUNC(sin)
- DECL_ASMFUNC(cos)
- DECL_ASMFUNC(tan)
- DECL_ASMFUNC(asin)
- DECL_ASMFUNC(acos)
- DECL_ASMFUNC(atan)
- DECL_ASMFUNC(atan2)
- DECL_ASMFUNC(sqr)
- DECL_ASMFUNC(sqrt)
- DECL_ASMFUNC(pow)
- DECL_ASMFUNC(exp)
- DECL_ASMFUNC(log)
- DECL_ASMFUNC(log10)
- DECL_ASMFUNC(abs)
- DECL_ASMFUNC(min)
- DECL_ASMFUNC(min)
- DECL_ASMFUNC(max)
- DECL_ASMFUNC(sig)
- DECL_ASMFUNC(sign)
- DECL_ASMFUNC(rand)
- DECL_ASMFUNC(band)
- DECL_ASMFUNC(bor)
- DECL_ASMFUNC(bnot)
- DECL_ASMFUNC(if)
- DECL_ASMFUNC(equal)
- DECL_ASMFUNC(below)
- DECL_ASMFUNC(above)
- DECL_ASMFUNC(assign)
- DECL_ASMFUNC(add)
- DECL_ASMFUNC(sub)
- DECL_ASMFUNC(mul)
- DECL_ASMFUNC(div)
- DECL_ASMFUNC(mod)
- DECL_ASMFUNC(or)
- DECL_ASMFUNC(and)
- DECL_ASMFUNC(uplus)
- DECL_ASMFUNC(uminus)
- DECL_ASMFUNC(floor)
- DECL_ASMFUNC(ceil)
- DECL_ASMFUNC(invsqrt)
- DECL_ASMFUNC(exec2)
- DECL_ASMFUNC(getosc)
- DECL_ASMFUNC(getspec)
- DECL_ASMFUNC(gettime)
- DECL_ASMFUNC(getmouse)
- DECL_ASMFUNC(setmousepos)
- static functionType fnTable1[36] = {
- { "if", _asm_if,_asm_if_end, 3 },
- { "sin", _asm_sin,_asm_sin_end, 1 },
- { "cos", _asm_cos,_asm_cos_end, 1 },
- { "tan", _asm_tan,_asm_tan_end, 1 },
- { "asin", _asm_asin,_asm_asin_end, 1 },
- { "acos", _asm_acos,_asm_acos_end, 1 },
- { "atan", _asm_atan,_asm_atan_end, 1 },
- { "atan2", _asm_atan2,_asm_atan2_end, 2 },
- { "sqr", _asm_sqr,_asm_sqr_end, 1 },
- { "sqrt", _asm_sqrt,_asm_sqrt_end, 1 },
- { "pow", _asm_pow,_asm_pow_end, 2 },
- { "exp", _asm_exp,_asm_exp_end, 1 },
- { "log", _asm_log,_asm_log_end, 1 },
- { "log10", _asm_log10,_asm_log10_end, 1 },
- { "abs", _asm_abs,_asm_abs_end, 1 },
- { "min", _asm_min,_asm_min_end, 2 },
- { "max", _asm_max,_asm_max_end, 2 },
- { "sigmoid",_asm_sig,_asm_sig_end, 2 } ,
- { "sign", _asm_sign,_asm_sign_end, 1 } ,
- { "rand", _asm_rand,_asm_rand_end, 1 } ,
- { "band", _asm_band,_asm_band_end, 2 } ,
- { "bor", _asm_bor,_asm_bor_end, 2 } ,
- { "bnot", _asm_bnot,_asm_bnot_end, 1 } ,
- { "equal", _asm_equal,_asm_equal_end, 2 },
- { "below", _asm_below,_asm_below_end, 2 },
- { "above", _asm_above,_asm_above_end, 2 },
- { "floor", _asm_floor,_asm_floor_end, 1 },
- { "ceil", _asm_ceil,_asm_ceil_end, 1 },
- { "invsqrt", _asm_invsqrt,_asm_invsqrt_end, 1 },
- { "assign",_asm_assign,_asm_assign_end,2},
- { "exec2",_asm_exec2,_asm_exec2_end,2},
- // these will be seperated since they are AVS specific
- { "getosc", _asm_getosc,_asm_getosc_end,3 },
- { "getspec",_asm_getspec,_asm_getspec_end,3 },
- { "gettime", _asm_gettime,_asm_gettime_end,1},
- { "getkbmouse",_asm_getmouse,_asm_getmouse_end,1},
- { "setmousepos",_asm_setmousepos,_asm_setmousepos_end,2},
- };
- functionType *getFunctionFromTable(int idx)
- {
- // todo: add API for adding functions to a seperate table :)
- if (idx<0 || idx>=sizeof(fnTable1)/sizeof(fnTable1[0])) return 0;
- return fnTable1+idx;
- }
- //---------------------------------------------------------------------------------------------------------------
- static void *realAddress(void *fn, void *fn_e, int *size)
- {
- #ifdef _DEBUG
- // Debug Mode
- *siiiize=0; // fucko, need to figure this out
- char *ptr = (char *)fn;
- return ptr + (*(int *)(ptr+1))+5;
- #else
- // Release Mode
- *size = (int)fn_e - (int) fn;
- return fn;
- #endif
- }
- //---------------------------------------------------------------------------------------------------------------
- static void freeBlocks(llBlock *start)
- {
- while (start)
- {
- llBlock *llB = start->next;
- GlobalFree(start);
- start=llB;
- }
- }
- //---------------------------------------------------------------------------------------------------------------
- static void *__newBlock(llBlock **start, int size)
- {
- llBlock *llb;
- int alloc_size;
- if (*start && (LLB_DSIZE - (*start)->sizeused) >= size)
- {
- void *t=(*start)->block+(*start)->sizeused;
- (*start)->sizeused+=size;
- return t;
- }
- alloc_size=sizeof(llBlock);
- if ((int)size > LLB_DSIZE) alloc_size += size - LLB_DSIZE;
- llb = (llBlock *)VirtualAlloc(NULL, alloc_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
- // benski> CUT: llb = (llBlock *)GlobalAlloc(GMEM_FIXED,alloc_size); // grab bigger block if absolutely necessary (heh)
- llb->sizeused=size;
- llb->next = *start;
- *start = llb;
- return llb->block;
- }
- #define X86_MOV_EAX_DIRECTVALUE 0xB8
- #define X86_MOV_ESI_DIRECTVALUE 0xBE
- #define X86_MOV_ESI_DIRECTMEMVALUE 0x358B
- #define X86_PUSH_EAX 0x50
- #define X86_POP_EBX 0x5B
- #define X86_POP_ECX 0x59
- #define X86_MOV_ESI_EDI 0xF78B
- #define X86_PUSH_ESI 0x56
- #define X86_POP_ESI 0x5E
- #define X86_RET 0xC3
- //---------------------------------------------------------------------------------------------------------------
- static int *findFBlock(char *p)
- {
- while (*(int *)p != 0xFFFFFFFF) p++;
- return (int*)p;
- }
- //---------------------------------------------------------------------------------------------------------------
- int createCompiledValue(double value, double *addrValue)
- {
- unsigned char *block;
- double *dupValue;
- block=(unsigned char *)newTmpBlock(4+5);
- if (addrValue == NULL)
- {
- l_stats[3]+=sizeof(double);
- *(dupValue = (double *)newBlock(sizeof(double))) = value;
- }
- else
- dupValue = addrValue;
- ((int*)block)[0]=5;
- block[4]=X86_MOV_EAX_DIRECTVALUE; // mov eax, <value>
- *(int *)(block+5) = (int)dupValue;
- return ((int)(block));
- }
- //---------------------------------------------------------------------------------------------------------------
- int getFunctionAddress(int fntype, int fn, int *size)
- {
- switch (fntype)
- {
- case MATH_SIMPLE:
- switch (fn)
- {
- case FN_ASSIGN:
- return (int)realAddress(_asm_assign,_asm_assign_end,size);
- case FN_ADD:
- return (int)realAddress(_asm_add,_asm_add_end,size);
- case FN_SUB:
- return (int)realAddress(_asm_sub,_asm_sub_end,size);
- case FN_MULTIPLY:
- return (int)realAddress(_asm_mul,_asm_mul_end,size);
- case FN_DIVIDE:
- return (int)realAddress(_asm_div,_asm_div_end,size);
- case FN_MODULO:
- return (int)realAddress(_asm_mod,_asm_mod_end,size);
- case FN_AND:
- return (int)realAddress(_asm_and,_asm_and_end,size);
- case FN_OR:
- return (int)realAddress(_asm_or,_asm_or_end,size);
- case FN_UPLUS:
- return (int)realAddress(_asm_uplus,_asm_uplus_end,size);
- case FN_UMINUS:
- return (int)realAddress(_asm_uminus,_asm_uminus_end,size);
- }
- case MATH_FN:
- {
- functionType *p=getFunctionFromTable(fn);
- if (!p)
- {
- if (size) *size=0;
- return 0;
- }
- return (int)realAddress(p->afunc,p->func_e,size);
- }
- }
- return 0;
- }
- //---------------------------------------------------------------------------------------------------------------
- int createCompiledFunction3(int fntype, int fn, int code1, int code2, int code3)
- {
- int sizes1=((int *)code1)[0];
- int sizes2=((int *)code2)[0];
- int sizes3=((int *)code3)[0];
- if (fntype == MATH_FN && fn == 0) // special case: IF
- {
- void *func3;
- int size;
- int *ptr;
- char *block;
- unsigned char *newblock2,*newblock3;
- newblock2=newBlock(sizes2+1);
- memcpy(newblock2,(char*)code2+4,sizes2);
- newblock2[sizes2]=X86_RET;
- newblock3=newBlock(sizes3+1);
- memcpy(newblock3,(char*)code3+4,sizes3);
- newblock3[sizes3]=X86_RET;
- l_stats[2]+=sizes2+sizes3+2;
-
- func3 = realAddress(_asm_if,_asm_if_end,&size);
- block=(char *)newTmpBlock(4+sizes1+size);
- ((int*)block)[0]=sizes1+size;
- memcpy(block+4,(char*)code1+4,sizes1);
- ptr=(int *)(block+4+sizes1);
- memcpy(ptr,func3,size);
- ptr=findFBlock((char*)ptr); *ptr++=(int)newblock2;
- ptr=findFBlock((char*)ptr); *ptr=(int)newblock3;
- return (int)block;
- }
- else
- {
- int size2;
- unsigned char *block;
- unsigned char *outp;
- int myfunc;
-
- myfunc = getFunctionAddress(fntype, fn, &size2);
- block=(unsigned char *)newTmpBlock(4+size2+sizes1+sizes2+sizes3+4);
- ((int*)block)[0]=4+size2+sizes1+sizes2+sizes3;
- outp=block+4;
- memcpy(outp,(char*)code1+4,sizes1);
- outp+=sizes1;
- *outp++ = X86_PUSH_EAX;
- memcpy(outp,(char*)code2+4,sizes2);
- outp+=sizes2;
- *outp++ = X86_PUSH_EAX;
- memcpy(outp,(char*)code3+4,sizes3);
- outp+=sizes3;
- *outp++ = X86_POP_EBX;
- *outp++ = X86_POP_ECX;
- memcpy(block+4+4+sizes1+sizes2+sizes3,(void*)myfunc,size2);
- g_evallib_computTableTop++;
- return ((int)(block));
- }
- }
- //---------------------------------------------------------------------------------------------------------------
- int createCompiledFunction2(int fntype, int fn, int code1, int code2)
- {
- int size2;
- unsigned char *block;
- unsigned char *outp;
- int myfunc;
- int sizes1=((int *)code1)[0];
- int sizes2=((int *)code2)[0];
- myfunc = getFunctionAddress(fntype, fn, &size2);
- block=(unsigned char *)newTmpBlock(2+size2+sizes1+sizes2+4);
- ((int*)block)[0]=2+size2+sizes1+sizes2;
- outp=block+4;
- memcpy(outp,(char*)code1+4,sizes1);
- outp+=sizes1;
- *outp++ = X86_PUSH_EAX;
- memcpy(outp,(char*)code2+4,sizes2);
- outp+=sizes2;
- *outp++ = X86_POP_EBX;
- memcpy(block+4+2+sizes1+sizes2,(void*)myfunc,size2);
- g_evallib_computTableTop++;
- return ((int)(block));
- }
- //---------------------------------------------------------------------------------------------------------------
- int createCompiledFunction1(int fntype, int fn, int code)
- {
- int size,size2;
- char *block;
- int myfunc;
- void *func1;
-
- size =((int *)code)[0];
- func1 = (void *)(code+4);
- myfunc = getFunctionAddress(fntype, fn, &size2);
- block=(char *)newTmpBlock(4+size+size2);
- ((int*)block)[0]=size+size2;
- memcpy(block+4, func1, size);
- memcpy(block+size+4,(void*)myfunc,size2);
- g_evallib_computTableTop++;
- return ((int)(block));
- }
- static char *preprocessCode(char *expression)
- {
- int len=0;
- int alloc_len=strlen(expression)+1+64;
- char *buf=(char *)malloc(alloc_len);
- while (*expression)
- {
- if (len > alloc_len-32)
- {
- alloc_len = len+128;
- buf=(char*)realloc(buf,alloc_len);
- }
- if (expression[0] == '/')
- {
- if (expression[1] == '/')
- {
- expression+=2;
- while (expression[0] && expression[0] != '\r' && expression[0] != '\n') expression++;
- }
- else if (expression[1] == '*')
- {
- expression+=2;
- while (expression[0] && (expression[0] != '*' || expression[1] != '/')) expression++;
- if (expression[0]) expression+=2; // at this point we KNOW expression[0]=* and expression[1]=/
- }
- else
- {
- char c=buf[len++]=*expression++;
- if (c != ' ' && c != '\t' && c != '\r' && c != '\n') l_stats[0]++;
- }
- }
- else if (expression[0] == '$')
- {
- if (toupper(expression[1]) == 'P' && toupper(expression[2]) == 'I')
- {
- static char *str="3.141592653589793";
- expression+=3;
- memcpy(buf+len,str,17);
- len+=17; //strlen(str);
- l_stats[0]+=17;
- }
- else if (toupper(expression[1]) == 'E')
- {
- static char *str="2.71828183";
- expression+=2;
- memcpy(buf+len,str,10);
- len+=10; //strlen(str);
- l_stats[0]+=10;
- }
- if (toupper(expression[1]) == 'P' && toupper(expression[2]) == 'H' && toupper(expression[3]) == 'I')
- {
- static char *str="1.61803399";
- expression+=4;
- memcpy(buf+len,str,10);
- len+=10; //strlen(str);
- l_stats[0]+=10;
- }
- else
- {
- char c = buf[len++]=*expression++;
- if (c != ' ' && c != '\t' && c != '\r' && c != '\n') l_stats[0]++;
- }
- }
- else
- {
- char c=*expression++;
- if (c == '\r' || c == '\n' || c == '\t') c=' ';
- buf[len++]=c;
- if (c != ' ') l_stats[0]++;
- }
- }
- buf[len]=0;
- return buf;
- }
- int g_log_errors;
- static void movestringover(char *str, int amount)
- {
- char tmp[1024+8];
- int l=(int)strlen(str);
- l=min(1024-amount-1,l);
- memcpy(tmp,str,l+1);
- while (l >= 0 && tmp[l]!='\n') l--;
- l++;
- tmp[l]=0;//ensure we null terminate
- memcpy(str+amount,tmp,l+1);
- }
- //------------------------------------------------------------------------------
- int compileCode(char *_expression)
- {
- char *expression,*expression_start;
- int computable_size=0;
- codeHandleType *handle;
- startPtr *scode=NULL;
- startPtr *startpts=NULL;
- if (!_expression || !*_expression) return 0;
- if (!varTable) return 0;
- #ifdef NSEEL_USE_CRITICAL_SECTION
- EnterCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
- #endif
- blocks_head=0;
- tmpblocks_head=0;
- memset(l_stats,0,sizeof(l_stats));
- handle = (codeHandleType*)newBlock(sizeof(codeHandleType));
- if (!handle)
- {
- #ifdef NSEEL_USE_CRITICAL_SECTION
- LeaveCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
- #endif
- return 0;
- }
-
- memset(handle,0,sizeof(codeHandleType));
- expression_start=expression=preprocessCode(_expression);
- while (*expression)
- {
- startPtr *tmp;
- char *expr;
- colCount=0;
- // single out segment
- while (*expression == ';' || *expression == ' ') expression++;
- if (!*expression) break;
- expr=expression;
- while (*expression && *expression != ';') expression++;
- if (*expression) *expression++ = 0;
- // parse
- tmp=(startPtr*) newTmpBlock(sizeof(startPtr));
- if (!tmp) break;
- g_evallib_computTableTop=0;
- tmp->startptr=compileExpression(expr);
- if (computable_size < g_evallib_computTableTop)
- {
- computable_size=g_evallib_computTableTop;
- }
- if (g_evallib_computTableTop > NSEEL_MAX_TEMPSPACE_ENTRIES-32)
- {
- tmp->startptr=0; // overflow in this mode
- }
- if (!tmp->startptr)
- {
- if (g_log_errors)
- {
- int l=strlen(expr);
- if (l > 512) l=512;
- movestringover(last_error_string,l+2);
- memcpy(last_error_string,expr,l);
- last_error_string[l]='\r';
- last_error_string[l+1]='\n';
- }
- scode=NULL;
- break;
- }
- tmp->next=NULL;
- if (!scode) scode=startpts=tmp;
- else
- {
- scode->next=tmp;
- scode=tmp;
- }
- }
- // check to see if failed on the first startingCode
- if (!scode)
- {
- freeBlocks(blocks_head); // free blocks
- handle=NULL; // return NULL (after resetting blocks_head)
- }
- else
- {
- // now we build one big code segment out of our list of them, inserting a mov esi, computable before each item
- unsigned char *writeptr;
- int size=1; // for ret at end :)
- startPtr *p;
- p=startpts;
- while (p)
- {
- size+=2; // mov esi, edi
- size+=*(int *)p->startptr;
- p=p->next;
- }
- handle->code = newBlock(size);
- if (handle->code)
- {
- writeptr=(unsigned char *)handle->code;
- p=startpts;
- while (p)
- {
- int thissize=*(int *)p->startptr;
- *(unsigned short *)writeptr= X86_MOV_ESI_EDI;
- writeptr+=2;
- memcpy(writeptr,(char*)p->startptr + 4,thissize);
- writeptr += thissize;
-
- p=p->next;
- }
- *writeptr=X86_RET; // ret
- l_stats[1]=size;
- }
- handle->blocks = blocks_head;
- handle->workTablePtr_size=(computable_size+4) * sizeof(double);
- }
- freeBlocks(tmpblocks_head); // free blocks
- tmpblocks_head=0;
- blocks_head=0;
- if (handle)
- {
- memcpy(handle->code_stats,l_stats,sizeof(l_stats));
- g_evallib_stats[0]+=l_stats[0];
- g_evallib_stats[1]+=l_stats[1];
- g_evallib_stats[2]+=l_stats[2];
- g_evallib_stats[3]+=l_stats[3];
- g_evallib_stats[4]++;
- }
- memset(l_stats,0,sizeof(l_stats));
- #ifdef NSEEL_USE_CRITICAL_SECTION
- LeaveCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
- #endif
- free(expression_start);
- return (int)handle;
- }
- //------------------------------------------------------------------------------
- void executeCode(int handle, char visdata[2][2][576])
- {
- #ifdef NSEEL_REENTRANT_EXECUTION
- int baseptr;
- #else
- static double _tab[NSEEL_MAX_TEMPSPACE_ENTRIES];
- int baseptr = (int) _tab;
- #endif
- codeHandleType *h = (codeHandleType *)handle;
- if (!h || !h->code) return;
- #ifdef NSEEL_USE_CRITICAL_SECTION
- EnterCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
- #endif
- g_evallib_visdata=(char*)visdata;
- #ifdef NSEEL_REENTRANT_EXECUTION
- baseptr = (int) alloca(h->workTablePtr_size);
- if (!baseptr) return;
- #endif
- {
- int startPoint=(int)h->code;
- __asm
- {
- mov ebx, baseptr
- mov eax, startPoint
- pushad // Lets cover our ass
- mov edi, ebx
- call eax
- popad
- }
- }
- g_evallib_visdata=NULL;
- #ifdef NSEEL_USE_CRITICAL_SECTION
- LeaveCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
- #endif
- }
- //------------------------------------------------------------------------------
- void freeCode(int handle)
- {
- codeHandleType *h = (codeHandleType *)handle;
- if (h != NULL)
- {
- g_evallib_stats[0]-=h->code_stats[0];
- g_evallib_stats[1]-=h->code_stats[1];
- g_evallib_stats[2]-=h->code_stats[2];
- g_evallib_stats[3]-=h->code_stats[3];
- g_evallib_stats[4]--;
- freeBlocks(h->blocks);
- }
- }
- //------------------------------------------------------------------------------
- void resetVars(varType *vars)
- {
- #ifdef NSEEL_USE_CRITICAL_SECTION
- if (vars) EnterCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
- #endif
- varTable=vars;
- #ifdef NSEEL_USE_CRITICAL_SECTION
- if (!vars) LeaveCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
- #endif
- }
|