NSEEL_CODEHANDLE AVS_EEL_IF_Compile(void *context, char *code) { NSEEL_CODEHANDLE ret; EnterCriticalSection(&g_eval_cs); ret=NSEEL_code_compile((NSEEL_VMCTX)context,code,0); if (!ret) { if (g_log_errors) { char *expr = NSEEL_code_getcodeerror((NSEEL_VMCTX)context); if (expr) { 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'; } } } LeaveCriticalSection(&g_eval_cs); return ret; }
//------------------------------------------------------------------------------ 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; }