4 Copyright 2005 Nullsoft, Inc.
\r
7 Redistribution and use in source and binary forms, with or without modification,
\r
8 are permitted provided that the following conditions are met:
\r
10 * Redistributions of source code must retain the above copyright notice,
\r
11 this list of conditions and the following disclaimer.
\r
13 * Redistributions in binary form must reproduce the above copyright notice,
\r
14 this list of conditions and the following disclaimer in the documentation
\r
15 and/or other materials provided with the distribution.
\r
17 * Neither the name of Nullsoft nor the names of its contributors may be used to
\r
18 endorse or promote products derived from this software without specific prior written permission.
\r
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
\r
21 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
\r
22 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
\r
23 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
\r
24 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
\r
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
\r
26 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
\r
27 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
30 #include <windows.h>
\r
34 #include "Compiler.h"
\r
37 #define LLB_DSIZE (65536-64)
\r
38 typedef struct _llBlock {
\r
39 struct _llBlock *next;
\r
41 char block[LLB_DSIZE];
\r
44 typedef struct _startPtr {
\r
45 struct _startPtr *next;
\r
54 static llBlock *blocks_head = NULL;
\r
56 double computTable[16384];
\r
57 double *nextBlock=computTable;
\r
59 extern CRITICAL_SECTION g_eval_cs;
\r
61 static void *newBlock(int size);
\r
62 static void freeBlocks(llBlock *start);
\r
65 void _asm_sin(void);
\r
66 void _asm_cos(void);
\r
67 void _asm_tan(void);
\r
68 void _asm_int(void);
\r
69 void _asm_asin(void);
\r
70 void _asm_acos(void);
\r
71 void _asm_atan(void);
\r
72 void _asm_atan2(void);
\r
73 void _asm_sqr(void);
\r
74 void _asm_sqrt(void);
\r
75 void _asm_pow(void);
\r
76 void _asm_exp(void);
\r
77 void _asm_log(void);
\r
78 void _asm_log10(void);
\r
79 void _asm_abs(void);
\r
80 void _asm_min(void);
\r
81 void _asm_max(void);
\r
82 void _asm_sig(void);
\r
83 void _asm_sign(void);
\r
84 void _asm_rand(void);
\r
85 void _asm_band(void);
\r
86 void _asm_bor(void);
\r
87 void _asm_bnot(void);
\r
89 void _asm_equal(void);
\r
90 void _asm_below(void);
\r
91 void _asm_above(void);
\r
92 void _asm_assign(void);
\r
93 void _asm_add(void);
\r
94 void _asm_sub(void);
\r
95 void _asm_mul(void);
\r
96 void _asm_div(void);
\r
97 void _asm_mod(void);
\r
99 void _asm_and(void);
\r
100 void _asm_uplus(void);
\r
101 void _asm_uminus(void);
\r
102 void _asm_function3(void);
\r
103 void _asm_function3_end(void);
\r
104 void _asm_function2(void);
\r
105 void _asm_function2_end(void);
\r
106 void _asm_function1(void);
\r
107 void _asm_function1_end(void);
\r
108 void _asm_simpleValue(void);
\r
109 void _asm_simpleValue_end(void);
\r
111 functionType fnTable[27] = {{ "sin", _asm_sin, 1 },
\r
112 { "cos", _asm_cos, 1 },
\r
113 { "tan", _asm_tan, 1 },
\r
114 { "int", _asm_int, 1 },
\r
115 { "asin", _asm_asin, 1 },
\r
116 { "acos", _asm_acos, 1 },
\r
117 { "atan", _asm_atan, 1 },
\r
118 { "atan2", _asm_atan2, 2 },
\r
119 { "sqr", _asm_sqr, 1 },
\r
120 { "sqrt", _asm_sqrt, 1 },
\r
121 { "pow", _asm_pow, 2 },
\r
122 { "exp", _asm_exp, 1 },
\r
123 { "log", _asm_log, 1 },
\r
124 { "log10", _asm_log10, 1 },
\r
125 { "abs", _asm_abs, 1 },
\r
126 { "min", _asm_min, 2 },
\r
127 { "max", _asm_max, 2 },
\r
128 { "sigmoid",_asm_sig, 2 } ,
\r
129 { "sign", _asm_sign, 1 } ,
\r
130 { "rand", _asm_rand, 1 } ,
\r
131 { "band", _asm_band, 2 } ,
\r
132 { "bor", _asm_bor, 2 } ,
\r
133 { "bnot", _asm_bnot, 1 } ,
\r
134 { "if", _asm_if, 3 },
\r
135 { "equal", _asm_equal, 2 },
\r
136 { "below", _asm_below, 2 },
\r
137 { "above", _asm_above, 2 },
\r
141 //---------------------------------------------------------------------------------------------------------------
\r
142 void *realAddress(void *fn)
\r
144 #if defined(_DEBUG) && 0
\r
145 // if this ever is needed, it should check that, the the data
\r
146 // is of the expected jump format before assuming it is so
\r
148 char *ptr = (char *)fn;
\r
149 ptr += (*(int *)((ptr+1))+5);
\r
157 //#define realAddress(a) a
\r
159 //---------------------------------------------------------------------------------------------------------------
\r
160 static void freeBlocks(llBlock *start)
\r
164 llBlock *llB = start->next;
\r
170 //---------------------------------------------------------------------------------------------------------------
\r
171 static void *newBlock(int size)
\r
175 if (blocks_head && (LLB_DSIZE - blocks_head->sizeused) >= size)
\r
177 void *t=blocks_head->block+blocks_head->sizeused;
\r
178 blocks_head->sizeused+=size;
\r
181 alloc_size=sizeof(llBlock);
\r
182 if ((int)size > LLB_DSIZE) alloc_size += size - LLB_DSIZE;
\r
183 llb = (llBlock *)GlobalAlloc(GMEM_FIXED,alloc_size); // grab bigger block if absolutely necessary (heh)
\r
184 llb->sizeused=size;
\r
185 llb->next = blocks_head;
\r
190 //---------------------------------------------------------------------------------------------------------------
\r
191 static int *findFBlock(char *p)
\r
193 while (*(int *)p != 0xFFFFFFFF) p++;
\r
198 //---------------------------------------------------------------------------------------------------------------
\r
199 int createCompiledValue(double value, double *addrValue)
\r
208 //size=(int)_asm_simpleValue_end-(int)_asm_simpleValue;
\r
210 block=(char *)newBlock(size);
\r
212 if (addrValue == NULL)
\r
213 *(dupValue = (double *)newBlock(sizeof(double))) = value;
\r
215 dupValue = addrValue;
\r
217 memcpy(block, realAddress(_asm_simpleValue), size);
\r
220 while (*(int *)p != 0xFFFFFFFF)
\r
227 *findFBlock(block)=(int)dupValue;
\r
229 return ((int)(block));
\r
233 //---------------------------------------------------------------------------------------------------------------
\r
234 int getFunctionAddress(int fntype, int fn)
\r
242 return (int)realAddress(_asm_assign);
\r
244 return (int)realAddress(_asm_add);
\r
246 return (int)realAddress(_asm_sub);
\r
248 return (int)realAddress(_asm_mul);
\r
250 return (int)realAddress(_asm_div);
\r
252 return (int)realAddress(_asm_mod);
\r
254 return (int)realAddress(_asm_and);
\r
256 return (int)realAddress(_asm_or);
\r
258 return (int)realAddress(_asm_uplus);
\r
260 return (int)realAddress(_asm_uminus);
\r
263 return (int)realAddress(fnTable[fn].afunc);
\r
269 //---------------------------------------------------------------------------------------------------------------
\r
270 int createCompiledFunction3(int fntype, int fn, int code1, int code2, int code3)
\r
276 // size=(int)_asm_function3_end-(int)_asm_function3;
\r
278 block=(char *)newBlock(size);
\r
280 memcpy(block, realAddress(_asm_function3), size);
\r
282 p=findFBlock(block); *p++=code1;
\r
283 p=findFBlock((char*)p); *p++=code2;
\r
284 p=findFBlock((char*)p); *p++=code3;
\r
285 p=findFBlock((char*)p); *p++=getFunctionAddress(fntype, fn);
\r
287 return ((int)(block));
\r
290 //---------------------------------------------------------------------------------------------------------------
\r
291 int createCompiledFunction2(int fntype, int fn, int code1, int code2)
\r
297 // size=(int)_asm_function2_end-(int)_asm_function2;
\r
299 block=(char *)newBlock(size);
\r
301 memcpy(block, realAddress(_asm_function2), size);
\r
303 p=findFBlock(block); *p++=code1;
\r
304 p=findFBlock((char*)p); *p++=code2;
\r
305 p=findFBlock((char*)p); *p++=getFunctionAddress(fntype, fn);
\r
307 return ((int)(block));
\r
311 //---------------------------------------------------------------------------------------------------------------
\r
312 int createCompiledFunction1(int fntype, int fn, int code)
\r
318 // size=(int)_asm_function1_end-(int)_asm_function1;
\r
320 block=(char *)newBlock(size);
\r
322 memcpy(block, realAddress(_asm_function1), size);
\r
324 p=findFBlock(block); *p++=code;
\r
325 p=findFBlock((char*)p); *p++=getFunctionAddress(fntype, fn);
\r
327 return ((int)(block));
\r
330 //------------------------------------------------------------------------------
\r
331 int compileCode(char *expression)
\r
334 codeHandleType *handle;
\r
335 startPtr *scode=NULL;
\r
338 if (!expression || !*expression) return 0;
\r
339 if (!varTable) return 0;
\r
341 handle = (codeHandleType*)newBlock(sizeof(codeHandleType));
\r
343 if (!handle) return 0;
\r
345 memset(handle,0,sizeof(codeHandleType));
\r
347 while (*expression)
\r
354 // single out segment
\r
355 while (*expression == ';' || *expression == ' ' || *expression == '\n' ||
\r
356 *expression == '\r' || *expression == '\t') expression++;
\r
357 if (!*expression) break;
\r
362 if (a) expression++;
\r
363 if (!a || a == ';') break;
\r
364 if (a == '\n' || a=='\r' || a=='\t') a=' ';
\r
370 tmp=(startPtr*) newBlock(sizeof(startPtr));
\r
372 tmp->startptr=compileExpression(expr);
\r
373 if (!tmp->startptr) { scode=NULL; break; }
\r
375 if (!scode) scode=handle->startpts=tmp;
\r
383 // check to see if failed on the first startingCode
\r
386 freeBlocks(blocks_head); // free blocks
\r
387 handle=NULL; // return NULL (after resetting blocks_head)
\r
389 else handle->blocks = blocks_head;
\r
393 return (int)handle;
\r
396 //------------------------------------------------------------------------------
\r
397 void executeCode(int handle)
\r
399 codeHandleType *h = (codeHandleType *)handle;
\r
402 // EnterCriticalSection(&g_eval_cs);
\r
406 void *startPoint=p->startptr;
\r
407 if (!startPoint) break;
\r
409 nextBlock=computTable;
\r
410 __asm pusha // Lets cover our ass
\r
411 __asm call startPoint
\r
414 // LeaveCriticalSection(&g_eval_cs);
\r
417 //------------------------------------------------------------------------------
\r
418 void freeCode(int handle)
\r
420 codeHandleType *h = (codeHandleType *)handle;
\r
423 freeBlocks(h->blocks);
\r