1
0

Compiler.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747
  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <math.h>
  4. #include "Compiler.h"
  5. #include "eval.h"
  6. // defining this allows code to run in different threads at the same time
  7. // it tends however, to be slower. We leave this OFF for AVS, since most of our shit runs in one thread
  8. // anyhow.
  9. //#define NSEEL_REENTRANT_EXECUTION
  10. #ifdef NSEEL_REENTRANT_EXECUTION
  11. #include <malloc.h>
  12. #endif
  13. #define NSEEL_USE_CRITICAL_SECTION g_eval_cs
  14. // note that compiling can only happen in one thread at a time, always.
  15. int g_evallib_stats[5]; // source bytes, static code bytes, call code bytes, data bytes, segments
  16. #ifdef NSEEL_USE_CRITICAL_SECTION
  17. CRITICAL_SECTION NSEEL_USE_CRITICAL_SECTION;
  18. #endif
  19. #define LLB_DSIZE (65536-64)
  20. typedef struct _llBlock {
  21. struct _llBlock *next;
  22. int sizeused;
  23. char block[LLB_DSIZE];
  24. } llBlock;
  25. typedef struct _startPtr {
  26. struct _startPtr *next;
  27. void *startptr;
  28. } startPtr;
  29. typedef struct {
  30. int workTablePtr_size;
  31. llBlock *blocks;
  32. void *code;
  33. int code_stats[4];
  34. } codeHandleType;
  35. static llBlock *blocks_head = NULL;
  36. static llBlock *tmpblocks_head = NULL; // used only during compile
  37. #define NSEEL_MAX_TEMPSPACE_ENTRIES 8192
  38. static int g_evallib_computTableTop; // make it abort on potential overflow =)
  39. static int l_stats[4]; // source bytes, static code bytes, call code bytes, data bytes
  40. static void *__newBlock(llBlock **start,int size);
  41. #define newTmpBlock(x) __newBlock(&tmpblocks_head,x)
  42. #define newBlock(x) __newBlock(&blocks_head,x)
  43. static void freeBlocks(llBlock *start);
  44. char *g_evallib_visdata;
  45. #define DECL_ASMFUNC(x) \
  46. void _asm_##x##(void); \
  47. void _asm_##x##_end(void); \
  48. DECL_ASMFUNC(sin)
  49. DECL_ASMFUNC(cos)
  50. DECL_ASMFUNC(tan)
  51. DECL_ASMFUNC(asin)
  52. DECL_ASMFUNC(acos)
  53. DECL_ASMFUNC(atan)
  54. DECL_ASMFUNC(atan2)
  55. DECL_ASMFUNC(sqr)
  56. DECL_ASMFUNC(sqrt)
  57. DECL_ASMFUNC(pow)
  58. DECL_ASMFUNC(exp)
  59. DECL_ASMFUNC(log)
  60. DECL_ASMFUNC(log10)
  61. DECL_ASMFUNC(abs)
  62. DECL_ASMFUNC(min)
  63. DECL_ASMFUNC(min)
  64. DECL_ASMFUNC(max)
  65. DECL_ASMFUNC(sig)
  66. DECL_ASMFUNC(sign)
  67. DECL_ASMFUNC(rand)
  68. DECL_ASMFUNC(band)
  69. DECL_ASMFUNC(bor)
  70. DECL_ASMFUNC(bnot)
  71. DECL_ASMFUNC(if)
  72. DECL_ASMFUNC(equal)
  73. DECL_ASMFUNC(below)
  74. DECL_ASMFUNC(above)
  75. DECL_ASMFUNC(assign)
  76. DECL_ASMFUNC(add)
  77. DECL_ASMFUNC(sub)
  78. DECL_ASMFUNC(mul)
  79. DECL_ASMFUNC(div)
  80. DECL_ASMFUNC(mod)
  81. DECL_ASMFUNC(or)
  82. DECL_ASMFUNC(and)
  83. DECL_ASMFUNC(uplus)
  84. DECL_ASMFUNC(uminus)
  85. DECL_ASMFUNC(floor)
  86. DECL_ASMFUNC(ceil)
  87. DECL_ASMFUNC(invsqrt)
  88. DECL_ASMFUNC(exec2)
  89. DECL_ASMFUNC(getosc)
  90. DECL_ASMFUNC(getspec)
  91. DECL_ASMFUNC(gettime)
  92. DECL_ASMFUNC(getmouse)
  93. DECL_ASMFUNC(setmousepos)
  94. static functionType fnTable1[36] = {
  95. { "if", _asm_if,_asm_if_end, 3 },
  96. { "sin", _asm_sin,_asm_sin_end, 1 },
  97. { "cos", _asm_cos,_asm_cos_end, 1 },
  98. { "tan", _asm_tan,_asm_tan_end, 1 },
  99. { "asin", _asm_asin,_asm_asin_end, 1 },
  100. { "acos", _asm_acos,_asm_acos_end, 1 },
  101. { "atan", _asm_atan,_asm_atan_end, 1 },
  102. { "atan2", _asm_atan2,_asm_atan2_end, 2 },
  103. { "sqr", _asm_sqr,_asm_sqr_end, 1 },
  104. { "sqrt", _asm_sqrt,_asm_sqrt_end, 1 },
  105. { "pow", _asm_pow,_asm_pow_end, 2 },
  106. { "exp", _asm_exp,_asm_exp_end, 1 },
  107. { "log", _asm_log,_asm_log_end, 1 },
  108. { "log10", _asm_log10,_asm_log10_end, 1 },
  109. { "abs", _asm_abs,_asm_abs_end, 1 },
  110. { "min", _asm_min,_asm_min_end, 2 },
  111. { "max", _asm_max,_asm_max_end, 2 },
  112. { "sigmoid",_asm_sig,_asm_sig_end, 2 } ,
  113. { "sign", _asm_sign,_asm_sign_end, 1 } ,
  114. { "rand", _asm_rand,_asm_rand_end, 1 } ,
  115. { "band", _asm_band,_asm_band_end, 2 } ,
  116. { "bor", _asm_bor,_asm_bor_end, 2 } ,
  117. { "bnot", _asm_bnot,_asm_bnot_end, 1 } ,
  118. { "equal", _asm_equal,_asm_equal_end, 2 },
  119. { "below", _asm_below,_asm_below_end, 2 },
  120. { "above", _asm_above,_asm_above_end, 2 },
  121. { "floor", _asm_floor,_asm_floor_end, 1 },
  122. { "ceil", _asm_ceil,_asm_ceil_end, 1 },
  123. { "invsqrt", _asm_invsqrt,_asm_invsqrt_end, 1 },
  124. { "assign",_asm_assign,_asm_assign_end,2},
  125. { "exec2",_asm_exec2,_asm_exec2_end,2},
  126. // these will be seperated since they are AVS specific
  127. { "getosc", _asm_getosc,_asm_getosc_end,3 },
  128. { "getspec",_asm_getspec,_asm_getspec_end,3 },
  129. { "gettime", _asm_gettime,_asm_gettime_end,1},
  130. { "getkbmouse",_asm_getmouse,_asm_getmouse_end,1},
  131. { "setmousepos",_asm_setmousepos,_asm_setmousepos_end,2},
  132. };
  133. functionType *getFunctionFromTable(int idx)
  134. {
  135. // todo: add API for adding functions to a seperate table :)
  136. if (idx<0 || idx>=sizeof(fnTable1)/sizeof(fnTable1[0])) return 0;
  137. return fnTable1+idx;
  138. }
  139. //---------------------------------------------------------------------------------------------------------------
  140. static void *realAddress(void *fn, void *fn_e, int *size)
  141. {
  142. #ifdef _DEBUG
  143. // Debug Mode
  144. *siiiize=0; // fucko, need to figure this out
  145. char *ptr = (char *)fn;
  146. return ptr + (*(int *)(ptr+1))+5;
  147. #else
  148. // Release Mode
  149. *size = (int)fn_e - (int) fn;
  150. return fn;
  151. #endif
  152. }
  153. //---------------------------------------------------------------------------------------------------------------
  154. static void freeBlocks(llBlock *start)
  155. {
  156. while (start)
  157. {
  158. llBlock *llB = start->next;
  159. GlobalFree(start);
  160. start=llB;
  161. }
  162. }
  163. //---------------------------------------------------------------------------------------------------------------
  164. static void *__newBlock(llBlock **start, int size)
  165. {
  166. llBlock *llb;
  167. int alloc_size;
  168. if (*start && (LLB_DSIZE - (*start)->sizeused) >= size)
  169. {
  170. void *t=(*start)->block+(*start)->sizeused;
  171. (*start)->sizeused+=size;
  172. return t;
  173. }
  174. alloc_size=sizeof(llBlock);
  175. if ((int)size > LLB_DSIZE) alloc_size += size - LLB_DSIZE;
  176. llb = (llBlock *)VirtualAlloc(NULL, alloc_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  177. // benski> CUT: llb = (llBlock *)GlobalAlloc(GMEM_FIXED,alloc_size); // grab bigger block if absolutely necessary (heh)
  178. llb->sizeused=size;
  179. llb->next = *start;
  180. *start = llb;
  181. return llb->block;
  182. }
  183. #define X86_MOV_EAX_DIRECTVALUE 0xB8
  184. #define X86_MOV_ESI_DIRECTVALUE 0xBE
  185. #define X86_MOV_ESI_DIRECTMEMVALUE 0x358B
  186. #define X86_PUSH_EAX 0x50
  187. #define X86_POP_EBX 0x5B
  188. #define X86_POP_ECX 0x59
  189. #define X86_MOV_ESI_EDI 0xF78B
  190. #define X86_PUSH_ESI 0x56
  191. #define X86_POP_ESI 0x5E
  192. #define X86_RET 0xC3
  193. //---------------------------------------------------------------------------------------------------------------
  194. static int *findFBlock(char *p)
  195. {
  196. while (*(int *)p != 0xFFFFFFFF) p++;
  197. return (int*)p;
  198. }
  199. //---------------------------------------------------------------------------------------------------------------
  200. int createCompiledValue(double value, double *addrValue)
  201. {
  202. unsigned char *block;
  203. double *dupValue;
  204. block=(unsigned char *)newTmpBlock(4+5);
  205. if (addrValue == NULL)
  206. {
  207. l_stats[3]+=sizeof(double);
  208. *(dupValue = (double *)newBlock(sizeof(double))) = value;
  209. }
  210. else
  211. dupValue = addrValue;
  212. ((int*)block)[0]=5;
  213. block[4]=X86_MOV_EAX_DIRECTVALUE; // mov eax, <value>
  214. *(int *)(block+5) = (int)dupValue;
  215. return ((int)(block));
  216. }
  217. //---------------------------------------------------------------------------------------------------------------
  218. int getFunctionAddress(int fntype, int fn, int *size)
  219. {
  220. switch (fntype)
  221. {
  222. case MATH_SIMPLE:
  223. switch (fn)
  224. {
  225. case FN_ASSIGN:
  226. return (int)realAddress(_asm_assign,_asm_assign_end,size);
  227. case FN_ADD:
  228. return (int)realAddress(_asm_add,_asm_add_end,size);
  229. case FN_SUB:
  230. return (int)realAddress(_asm_sub,_asm_sub_end,size);
  231. case FN_MULTIPLY:
  232. return (int)realAddress(_asm_mul,_asm_mul_end,size);
  233. case FN_DIVIDE:
  234. return (int)realAddress(_asm_div,_asm_div_end,size);
  235. case FN_MODULO:
  236. return (int)realAddress(_asm_mod,_asm_mod_end,size);
  237. case FN_AND:
  238. return (int)realAddress(_asm_and,_asm_and_end,size);
  239. case FN_OR:
  240. return (int)realAddress(_asm_or,_asm_or_end,size);
  241. case FN_UPLUS:
  242. return (int)realAddress(_asm_uplus,_asm_uplus_end,size);
  243. case FN_UMINUS:
  244. return (int)realAddress(_asm_uminus,_asm_uminus_end,size);
  245. }
  246. case MATH_FN:
  247. {
  248. functionType *p=getFunctionFromTable(fn);
  249. if (!p)
  250. {
  251. if (size) *size=0;
  252. return 0;
  253. }
  254. return (int)realAddress(p->afunc,p->func_e,size);
  255. }
  256. }
  257. return 0;
  258. }
  259. //---------------------------------------------------------------------------------------------------------------
  260. int createCompiledFunction3(int fntype, int fn, int code1, int code2, int code3)
  261. {
  262. int sizes1=((int *)code1)[0];
  263. int sizes2=((int *)code2)[0];
  264. int sizes3=((int *)code3)[0];
  265. if (fntype == MATH_FN && fn == 0) // special case: IF
  266. {
  267. void *func3;
  268. int size;
  269. int *ptr;
  270. char *block;
  271. unsigned char *newblock2,*newblock3;
  272. newblock2=newBlock(sizes2+1);
  273. memcpy(newblock2,(char*)code2+4,sizes2);
  274. newblock2[sizes2]=X86_RET;
  275. newblock3=newBlock(sizes3+1);
  276. memcpy(newblock3,(char*)code3+4,sizes3);
  277. newblock3[sizes3]=X86_RET;
  278. l_stats[2]+=sizes2+sizes3+2;
  279. func3 = realAddress(_asm_if,_asm_if_end,&size);
  280. block=(char *)newTmpBlock(4+sizes1+size);
  281. ((int*)block)[0]=sizes1+size;
  282. memcpy(block+4,(char*)code1+4,sizes1);
  283. ptr=(int *)(block+4+sizes1);
  284. memcpy(ptr,func3,size);
  285. ptr=findFBlock((char*)ptr); *ptr++=(int)newblock2;
  286. ptr=findFBlock((char*)ptr); *ptr=(int)newblock3;
  287. return (int)block;
  288. }
  289. else
  290. {
  291. int size2;
  292. unsigned char *block;
  293. unsigned char *outp;
  294. int myfunc;
  295. myfunc = getFunctionAddress(fntype, fn, &size2);
  296. block=(unsigned char *)newTmpBlock(4+size2+sizes1+sizes2+sizes3+4);
  297. ((int*)block)[0]=4+size2+sizes1+sizes2+sizes3;
  298. outp=block+4;
  299. memcpy(outp,(char*)code1+4,sizes1);
  300. outp+=sizes1;
  301. *outp++ = X86_PUSH_EAX;
  302. memcpy(outp,(char*)code2+4,sizes2);
  303. outp+=sizes2;
  304. *outp++ = X86_PUSH_EAX;
  305. memcpy(outp,(char*)code3+4,sizes3);
  306. outp+=sizes3;
  307. *outp++ = X86_POP_EBX;
  308. *outp++ = X86_POP_ECX;
  309. memcpy(block+4+4+sizes1+sizes2+sizes3,(void*)myfunc,size2);
  310. g_evallib_computTableTop++;
  311. return ((int)(block));
  312. }
  313. }
  314. //---------------------------------------------------------------------------------------------------------------
  315. int createCompiledFunction2(int fntype, int fn, int code1, int code2)
  316. {
  317. int size2;
  318. unsigned char *block;
  319. unsigned char *outp;
  320. int myfunc;
  321. int sizes1=((int *)code1)[0];
  322. int sizes2=((int *)code2)[0];
  323. myfunc = getFunctionAddress(fntype, fn, &size2);
  324. block=(unsigned char *)newTmpBlock(2+size2+sizes1+sizes2+4);
  325. ((int*)block)[0]=2+size2+sizes1+sizes2;
  326. outp=block+4;
  327. memcpy(outp,(char*)code1+4,sizes1);
  328. outp+=sizes1;
  329. *outp++ = X86_PUSH_EAX;
  330. memcpy(outp,(char*)code2+4,sizes2);
  331. outp+=sizes2;
  332. *outp++ = X86_POP_EBX;
  333. memcpy(block+4+2+sizes1+sizes2,(void*)myfunc,size2);
  334. g_evallib_computTableTop++;
  335. return ((int)(block));
  336. }
  337. //---------------------------------------------------------------------------------------------------------------
  338. int createCompiledFunction1(int fntype, int fn, int code)
  339. {
  340. int size,size2;
  341. char *block;
  342. int myfunc;
  343. void *func1;
  344. size =((int *)code)[0];
  345. func1 = (void *)(code+4);
  346. myfunc = getFunctionAddress(fntype, fn, &size2);
  347. block=(char *)newTmpBlock(4+size+size2);
  348. ((int*)block)[0]=size+size2;
  349. memcpy(block+4, func1, size);
  350. memcpy(block+size+4,(void*)myfunc,size2);
  351. g_evallib_computTableTop++;
  352. return ((int)(block));
  353. }
  354. static char *preprocessCode(char *expression)
  355. {
  356. int len=0;
  357. int alloc_len=strlen(expression)+1+64;
  358. char *buf=(char *)malloc(alloc_len);
  359. while (*expression)
  360. {
  361. if (len > alloc_len-32)
  362. {
  363. alloc_len = len+128;
  364. buf=(char*)realloc(buf,alloc_len);
  365. }
  366. if (expression[0] == '/')
  367. {
  368. if (expression[1] == '/')
  369. {
  370. expression+=2;
  371. while (expression[0] && expression[0] != '\r' && expression[0] != '\n') expression++;
  372. }
  373. else if (expression[1] == '*')
  374. {
  375. expression+=2;
  376. while (expression[0] && (expression[0] != '*' || expression[1] != '/')) expression++;
  377. if (expression[0]) expression+=2; // at this point we KNOW expression[0]=* and expression[1]=/
  378. }
  379. else
  380. {
  381. char c=buf[len++]=*expression++;
  382. if (c != ' ' && c != '\t' && c != '\r' && c != '\n') l_stats[0]++;
  383. }
  384. }
  385. else if (expression[0] == '$')
  386. {
  387. if (toupper(expression[1]) == 'P' && toupper(expression[2]) == 'I')
  388. {
  389. static char *str="3.141592653589793";
  390. expression+=3;
  391. memcpy(buf+len,str,17);
  392. len+=17; //strlen(str);
  393. l_stats[0]+=17;
  394. }
  395. else if (toupper(expression[1]) == 'E')
  396. {
  397. static char *str="2.71828183";
  398. expression+=2;
  399. memcpy(buf+len,str,10);
  400. len+=10; //strlen(str);
  401. l_stats[0]+=10;
  402. }
  403. if (toupper(expression[1]) == 'P' && toupper(expression[2]) == 'H' && toupper(expression[3]) == 'I')
  404. {
  405. static char *str="1.61803399";
  406. expression+=4;
  407. memcpy(buf+len,str,10);
  408. len+=10; //strlen(str);
  409. l_stats[0]+=10;
  410. }
  411. else
  412. {
  413. char c = buf[len++]=*expression++;
  414. if (c != ' ' && c != '\t' && c != '\r' && c != '\n') l_stats[0]++;
  415. }
  416. }
  417. else
  418. {
  419. char c=*expression++;
  420. if (c == '\r' || c == '\n' || c == '\t') c=' ';
  421. buf[len++]=c;
  422. if (c != ' ') l_stats[0]++;
  423. }
  424. }
  425. buf[len]=0;
  426. return buf;
  427. }
  428. int g_log_errors;
  429. static void movestringover(char *str, int amount)
  430. {
  431. char tmp[1024+8];
  432. int l=(int)strlen(str);
  433. l=min(1024-amount-1,l);
  434. memcpy(tmp,str,l+1);
  435. while (l >= 0 && tmp[l]!='\n') l--;
  436. l++;
  437. tmp[l]=0;//ensure we null terminate
  438. memcpy(str+amount,tmp,l+1);
  439. }
  440. //------------------------------------------------------------------------------
  441. int compileCode(char *_expression)
  442. {
  443. char *expression,*expression_start;
  444. int computable_size=0;
  445. codeHandleType *handle;
  446. startPtr *scode=NULL;
  447. startPtr *startpts=NULL;
  448. if (!_expression || !*_expression) return 0;
  449. if (!varTable) return 0;
  450. #ifdef NSEEL_USE_CRITICAL_SECTION
  451. EnterCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
  452. #endif
  453. blocks_head=0;
  454. tmpblocks_head=0;
  455. memset(l_stats,0,sizeof(l_stats));
  456. handle = (codeHandleType*)newBlock(sizeof(codeHandleType));
  457. if (!handle)
  458. {
  459. #ifdef NSEEL_USE_CRITICAL_SECTION
  460. LeaveCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
  461. #endif
  462. return 0;
  463. }
  464. memset(handle,0,sizeof(codeHandleType));
  465. expression_start=expression=preprocessCode(_expression);
  466. while (*expression)
  467. {
  468. startPtr *tmp;
  469. char *expr;
  470. colCount=0;
  471. // single out segment
  472. while (*expression == ';' || *expression == ' ') expression++;
  473. if (!*expression) break;
  474. expr=expression;
  475. while (*expression && *expression != ';') expression++;
  476. if (*expression) *expression++ = 0;
  477. // parse
  478. tmp=(startPtr*) newTmpBlock(sizeof(startPtr));
  479. if (!tmp) break;
  480. g_evallib_computTableTop=0;
  481. tmp->startptr=compileExpression(expr);
  482. if (computable_size < g_evallib_computTableTop)
  483. {
  484. computable_size=g_evallib_computTableTop;
  485. }
  486. if (g_evallib_computTableTop > NSEEL_MAX_TEMPSPACE_ENTRIES-32)
  487. {
  488. tmp->startptr=0; // overflow in this mode
  489. }
  490. if (!tmp->startptr)
  491. {
  492. if (g_log_errors)
  493. {
  494. int l=strlen(expr);
  495. if (l > 512) l=512;
  496. movestringover(last_error_string,l+2);
  497. memcpy(last_error_string,expr,l);
  498. last_error_string[l]='\r';
  499. last_error_string[l+1]='\n';
  500. }
  501. scode=NULL;
  502. break;
  503. }
  504. tmp->next=NULL;
  505. if (!scode) scode=startpts=tmp;
  506. else
  507. {
  508. scode->next=tmp;
  509. scode=tmp;
  510. }
  511. }
  512. // check to see if failed on the first startingCode
  513. if (!scode)
  514. {
  515. freeBlocks(blocks_head); // free blocks
  516. handle=NULL; // return NULL (after resetting blocks_head)
  517. }
  518. else
  519. {
  520. // now we build one big code segment out of our list of them, inserting a mov esi, computable before each item
  521. unsigned char *writeptr;
  522. int size=1; // for ret at end :)
  523. startPtr *p;
  524. p=startpts;
  525. while (p)
  526. {
  527. size+=2; // mov esi, edi
  528. size+=*(int *)p->startptr;
  529. p=p->next;
  530. }
  531. handle->code = newBlock(size);
  532. if (handle->code)
  533. {
  534. writeptr=(unsigned char *)handle->code;
  535. p=startpts;
  536. while (p)
  537. {
  538. int thissize=*(int *)p->startptr;
  539. *(unsigned short *)writeptr= X86_MOV_ESI_EDI;
  540. writeptr+=2;
  541. memcpy(writeptr,(char*)p->startptr + 4,thissize);
  542. writeptr += thissize;
  543. p=p->next;
  544. }
  545. *writeptr=X86_RET; // ret
  546. l_stats[1]=size;
  547. }
  548. handle->blocks = blocks_head;
  549. handle->workTablePtr_size=(computable_size+4) * sizeof(double);
  550. }
  551. freeBlocks(tmpblocks_head); // free blocks
  552. tmpblocks_head=0;
  553. blocks_head=0;
  554. if (handle)
  555. {
  556. memcpy(handle->code_stats,l_stats,sizeof(l_stats));
  557. g_evallib_stats[0]+=l_stats[0];
  558. g_evallib_stats[1]+=l_stats[1];
  559. g_evallib_stats[2]+=l_stats[2];
  560. g_evallib_stats[3]+=l_stats[3];
  561. g_evallib_stats[4]++;
  562. }
  563. memset(l_stats,0,sizeof(l_stats));
  564. #ifdef NSEEL_USE_CRITICAL_SECTION
  565. LeaveCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
  566. #endif
  567. free(expression_start);
  568. return (int)handle;
  569. }
  570. //------------------------------------------------------------------------------
  571. void executeCode(int handle, char visdata[2][2][576])
  572. {
  573. #ifdef NSEEL_REENTRANT_EXECUTION
  574. int baseptr;
  575. #else
  576. static double _tab[NSEEL_MAX_TEMPSPACE_ENTRIES];
  577. int baseptr = (int) _tab;
  578. #endif
  579. codeHandleType *h = (codeHandleType *)handle;
  580. if (!h || !h->code) return;
  581. #ifdef NSEEL_USE_CRITICAL_SECTION
  582. EnterCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
  583. #endif
  584. g_evallib_visdata=(char*)visdata;
  585. #ifdef NSEEL_REENTRANT_EXECUTION
  586. baseptr = (int) alloca(h->workTablePtr_size);
  587. if (!baseptr) return;
  588. #endif
  589. {
  590. int startPoint=(int)h->code;
  591. __asm
  592. {
  593. mov ebx, baseptr
  594. mov eax, startPoint
  595. pushad // Lets cover our ass
  596. mov edi, ebx
  597. call eax
  598. popad
  599. }
  600. }
  601. g_evallib_visdata=NULL;
  602. #ifdef NSEEL_USE_CRITICAL_SECTION
  603. LeaveCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
  604. #endif
  605. }
  606. //------------------------------------------------------------------------------
  607. void freeCode(int handle)
  608. {
  609. codeHandleType *h = (codeHandleType *)handle;
  610. if (h != NULL)
  611. {
  612. g_evallib_stats[0]-=h->code_stats[0];
  613. g_evallib_stats[1]-=h->code_stats[1];
  614. g_evallib_stats[2]-=h->code_stats[2];
  615. g_evallib_stats[3]-=h->code_stats[3];
  616. g_evallib_stats[4]--;
  617. freeBlocks(h->blocks);
  618. }
  619. }
  620. //------------------------------------------------------------------------------
  621. void resetVars(varType *vars)
  622. {
  623. #ifdef NSEEL_USE_CRITICAL_SECTION
  624. if (vars) EnterCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
  625. #endif
  626. varTable=vars;
  627. #ifdef NSEEL_USE_CRITICAL_SECTION
  628. if (!vars) LeaveCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
  629. #endif
  630. }