1
0

ns-eel-int.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. /*
  2. Nullsoft Expression Evaluator Library (NS-EEL)
  3. Copyright (C) 1999-2003 Nullsoft, Inc.
  4. ns-eel-int.h: internal code definition header.
  5. This software is provided 'as-is', without any express or implied
  6. warranty. In no event will the authors be held liable for any damages
  7. arising from the use of this software.
  8. Permission is granted to anyone to use this software for any purpose,
  9. including commercial applications, and to alter it and redistribute it
  10. freely, subject to the following restrictions:
  11. 1. The origin of this software must not be misrepresented; you must not
  12. claim that you wrote the original software. If you use this software
  13. in a product, an acknowledgment in the product documentation would be
  14. appreciated but is not required.
  15. 2. Altered source versions must be plainly marked as such, and must not be
  16. misrepresented as being the original software.
  17. 3. This notice may not be removed or altered from any source distribution.
  18. */
  19. #ifndef __NS_EELINT_H__
  20. #define __NS_EELINT_H__
  21. #ifdef _WIN32
  22. #include <windows.h>
  23. #else
  24. #include "../wdltypes.h"
  25. #endif
  26. #include "ns-eel.h"
  27. #include "ns-eel-addfuncs.h"
  28. #ifdef __cplusplus
  29. extern "C" {
  30. #endif
  31. enum {
  32. // these ignore fn in opcodes, just use fntype to determine function
  33. FN_MULTIPLY=0,
  34. FN_DIVIDE,
  35. FN_JOIN_STATEMENTS,
  36. FN_DENORMAL_LIKELY,
  37. FN_DENORMAL_UNLIKELY,
  38. FN_ADD,
  39. FN_SUB,
  40. FN_AND,
  41. FN_OR,
  42. FN_UMINUS,
  43. FN_NOT,
  44. FN_NOTNOT,
  45. FN_XOR,
  46. FN_SHL,
  47. FN_SHR,
  48. FN_MOD,
  49. FN_POW,
  50. FN_LT,
  51. FN_GT,
  52. FN_LTE,
  53. FN_GTE,
  54. FN_EQ,
  55. FN_EQ_EXACT,
  56. FN_NE,
  57. FN_NE_EXACT,
  58. FN_LOGICAL_AND,
  59. FN_LOGICAL_OR,
  60. FN_IF_ELSE,
  61. FN_MEMORY,
  62. FN_GMEMORY,
  63. FN_NONCONST_BEGIN,
  64. FN_ASSIGN=FN_NONCONST_BEGIN,
  65. FN_ADD_OP,
  66. FN_SUB_OP,
  67. FN_MOD_OP,
  68. FN_OR_OP,
  69. FN_AND_OP,
  70. FN_XOR_OP,
  71. FN_DIV_OP,
  72. FN_MUL_OP,
  73. FN_POW_OP,
  74. FN_WHILE,
  75. FN_LOOP,
  76. FUNCTYPE_SIMPLEMAX,
  77. FUNCTYPE_FUNCTIONTYPEREC=1000, // fn is a functionType *
  78. FUNCTYPE_EELFUNC, // fn is a _codeHandleFunctionRec *
  79. };
  80. #define YYSTYPE opcodeRec *
  81. #define NSEEL_CLOSEFACTOR 0.00001
  82. typedef struct opcodeRec opcodeRec;
  83. typedef struct _codeHandleFunctionRec
  84. {
  85. struct _codeHandleFunctionRec *next; // main linked list (only used for high level functions)
  86. struct _codeHandleFunctionRec *derivedCopies; // separate linked list, _head being the main function, other copies being derived versions
  87. void *startptr; // compiled code (may be cleared + recompiled when shared)
  88. opcodeRec *opcodes;
  89. int startptr_size; // 0=no code. -1 = needs calculation. >0 = size.
  90. int tmpspace_req;
  91. int num_params;
  92. int rvMode; // RETURNVALUE_*
  93. int fpStackUsage; // 0-8, usually
  94. int canHaveDenormalOutput;
  95. // local storage's first items are the parameters, then locals. Note that the opcodes will reference localstorage[] via VARPTRPTR, but
  96. // the values localstorage[x] points are reallocated from context-to-context, if it is a common function.
  97. // separately allocated list of pointers, the contents of the list should be zeroed on context changes if a common function
  98. // note that when making variations on a function (context), it is shared, but since it is zeroed on context changes, it is context-local
  99. int localstorage_size;
  100. EEL_F **localstorage;
  101. int isCommonFunction;
  102. int usesNamespaces;
  103. unsigned int parameterAsNamespaceMask;
  104. char fname[NSEEL_MAX_FUNCSIG_NAME+1];
  105. } _codeHandleFunctionRec;
  106. #define LLB_DSIZE (65536-64)
  107. typedef struct _llBlock {
  108. struct _llBlock *next;
  109. int sizeused;
  110. char block[LLB_DSIZE];
  111. } llBlock;
  112. typedef struct {
  113. llBlock *blocks,
  114. *blocks_data;
  115. void *workTable; // references a chunk in blocks_data
  116. void *code;
  117. int code_size; // in case the caller wants to write it out
  118. int code_stats[4];
  119. int want_stack;
  120. void *stack; // references a chunk in blocks_data, somewhere within the complete NSEEL_STACK_SIZE aligned at NSEEL_STACK_SIZE
  121. void *ramPtr;
  122. int workTable_size; // size (minus padding/extra space) of workTable -- only used if EEL_VALIDATE_WORKTABLE_USE set, but might be handy to have around too
  123. int compile_flags;
  124. } codeHandleType;
  125. typedef struct
  126. {
  127. EEL_F *value;
  128. int refcnt;
  129. char isreg;
  130. char str[1];
  131. } varNameRec;
  132. typedef struct
  133. {
  134. void *ptr;
  135. int size, alloc;
  136. } eel_growbuf;
  137. #define EEL_GROWBUF(type) union { eel_growbuf _growbuf; type *_tval; }
  138. #define EEL_GROWBUF_RESIZE(gb, newsz) __growbuf_resize(&(gb)->_growbuf, (newsz)*(int)sizeof((gb)->_tval[0])) // <0 to free, does not realloc down otherwise
  139. #define EEL_GROWBUF_GET(gb) ((gb)->_tval)
  140. #define EEL_GROWBUF_GET_SIZE(gb) ((gb)->_growbuf.size/(int)sizeof((gb)->_tval[0]))
  141. typedef struct _compileContext
  142. {
  143. eel_function_table *registered_func_tab;
  144. const char *(*func_check)(const char *fn_name, void *user); // return error message if not permitted
  145. void *func_check_user;
  146. EEL_GROWBUF(varNameRec *) varNameList;
  147. EEL_F *varValueStore;
  148. int varValueStore_left;
  149. int errVar,gotEndOfInput;
  150. opcodeRec *result;
  151. char last_error_string[256];
  152. void *scanner;
  153. const char *rdbuf_start, *rdbuf, *rdbuf_end;
  154. llBlock *tmpblocks_head, // used while compiling, and freed after compiling
  155. *blocks_head, // used while compiling, transferred to code context (these are pages marked as executable)
  156. *blocks_head_data, // used while compiling, transferred to code context
  157. *pblocks; // persistent blocks, stores data used by varTable_Names, varTable_Values, etc.
  158. int l_stats[4]; // source bytes, static code bytes, call code bytes, data bytes
  159. int has_used_global_vars;
  160. _codeHandleFunctionRec *functions_local, *functions_common;
  161. // state used while generating functions
  162. int optimizeDisableFlags;
  163. int current_compile_flags;
  164. struct opcodeRec *directValueCache; // linked list using fn as next
  165. int isSharedFunctions;
  166. int isGeneratingCommonFunction;
  167. int function_usesNamespaces;
  168. int function_globalFlag; // set if restrict globals to function_localTable_Names[2]
  169. // [0] is parameter+local symbols (combined space)
  170. // [1] is symbols which get implied "this." if used
  171. // [2] is globals permitted
  172. int function_localTable_Size[3]; // for parameters only
  173. char **function_localTable_Names[3]; // lists of pointers
  174. EEL_F **function_localTable_ValuePtrs;
  175. const char *function_curName; // name of current function
  176. EEL_F (*onString)(void *caller_this, struct eelStringSegmentRec *list);
  177. EEL_F (*onNamedString)(void *caller_this, const char *name);
  178. EEL_F *(*getVariable)(void *userctx, const char *name);
  179. void *getVariable_userctx;
  180. codeHandleType *tmpCodeHandle;
  181. struct
  182. {
  183. int needfree;
  184. int maxblocks;
  185. double closefact;
  186. EEL_F *blocks[NSEEL_RAM_BLOCKS];
  187. } ram_state
  188. #ifdef __GNUC__
  189. __attribute__ ((aligned (8)))
  190. #endif
  191. ;
  192. void *gram_blocks;
  193. void *caller_this;
  194. }
  195. compileContext;
  196. #define NSEEL_NPARAMS_FLAG_CONST 0x80000
  197. typedef struct functionType {
  198. const char *name;
  199. void *afunc;
  200. void *func_e;
  201. int nParams;
  202. void *replptrs[4];
  203. NSEEL_PPPROC pProc;
  204. } functionType;
  205. functionType *nseel_getFunctionByName(compileContext *ctx, const char *name, int *mchk); // sets mchk (if non-NULL) to how far allowed to scan forward for duplicate names
  206. opcodeRec *nseel_createCompiledValue(compileContext *ctx, EEL_F value);
  207. opcodeRec *nseel_createCompiledValuePtr(compileContext *ctx, EEL_F *addrValue, const char *namestr);
  208. opcodeRec *nseel_createMoreParametersOpcode(compileContext *ctx, opcodeRec *code1, opcodeRec *code2);
  209. opcodeRec *nseel_createSimpleCompiledFunction(compileContext *ctx, int fn, int np, opcodeRec *code1, opcodeRec *code2);
  210. opcodeRec *nseel_createMemoryAccess(compileContext *ctx, opcodeRec *code1, opcodeRec *code2);
  211. opcodeRec *nseel_createIfElse(compileContext *ctx, opcodeRec *code1, opcodeRec *code2, opcodeRec *code3);
  212. opcodeRec *nseel_createFunctionByName(compileContext *ctx, const char *name, int np, opcodeRec *code1, opcodeRec *code2, opcodeRec *code3);
  213. // converts a generic identifier (VARPTR) opcode into either an actual variable reference (parmcnt = -1),
  214. // or if parmcnt >= 0, to a function call (see nseel_setCompiledFunctionCallParameters())
  215. opcodeRec *nseel_resolve_named_symbol(compileContext *ctx, opcodeRec *rec, int parmcnt, int *errOut);
  216. // sets parameters and calculates parameter count for opcode, and calls nseel_resolve_named_symbol() with the right
  217. // parameter count
  218. opcodeRec *nseel_setCompiledFunctionCallParameters(compileContext *ctx, opcodeRec *fn, opcodeRec *code1, opcodeRec *code2, opcodeRec *code3, opcodeRec *postCode, int *errOut);
  219. // errOut will be set if return NULL:
  220. // -1 if postCode set when not wanted (i.e. not while())
  221. // 0 if func not found,
  222. // 1 if function requires 2+ parameters but was given more
  223. // 2 if function needs more parameters
  224. // 4 if function requires 1 parameter but was given more
  225. struct eelStringSegmentRec *nseel_createStringSegmentRec(compileContext *ctx, const char *str, int len);
  226. opcodeRec *nseel_eelMakeOpcodeFromStringSegments(compileContext *ctx, struct eelStringSegmentRec *rec);
  227. EEL_F *nseel_int_register_var(compileContext *ctx, const char *name, int isReg, const char **namePtrOut);
  228. _codeHandleFunctionRec *eel_createFunctionNamespacedInstance(compileContext *ctx, _codeHandleFunctionRec *fr, const char *nameptr);
  229. typedef struct nseel_globalVarItem
  230. {
  231. EEL_F data;
  232. struct nseel_globalVarItem *_next;
  233. char name[1]; // varlen, does not include _global. prefix
  234. } nseel_globalVarItem;
  235. extern nseel_globalVarItem *nseel_globalreg_list; // if NSEEL_EEL1_COMPAT_MODE, must use NSEEL_getglobalregs() for regxx values
  236. #include "y.tab.h"
  237. // nseel_simple_tokenizer will return comments as tokens if state is non-NULL
  238. const char *nseel_simple_tokenizer(const char **ptr, const char *endptr, int *lenOut, int *state);
  239. int nseel_filter_escaped_string(char *outbuf, int outbuf_sz, const char *rdptr, size_t rdptr_size, char delim_char); // returns length used, minus NUL char
  240. opcodeRec *nseel_translate(compileContext *ctx, const char *tmp, size_t tmplen); // tmplen=0 for nul-term
  241. int nseel_lookup(compileContext *ctx, opcodeRec **opOut, const char *sname);
  242. EEL_F * NSEEL_CGEN_CALL __NSEEL_RAMAlloc(EEL_F **blocks, unsigned int w);
  243. EEL_F * NSEEL_CGEN_CALL __NSEEL_RAMAllocGMEM(EEL_F ***blocks, unsigned int w);
  244. EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemSet(EEL_F **blocks,EEL_F *dest, EEL_F *v, EEL_F *lenptr);
  245. EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemFree(void *blocks, EEL_F *which);
  246. EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemTop(void *blocks, EEL_F *which);
  247. EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemCpy(EEL_F **blocks,EEL_F *dest, EEL_F *src, EEL_F *lenptr);
  248. EEL_F NSEEL_CGEN_CALL __NSEEL_RAM_Mem_SetValues(EEL_F **blocks, INT_PTR np, EEL_F **parms);
  249. EEL_F NSEEL_CGEN_CALL __NSEEL_RAM_Mem_GetValues(EEL_F **blocks, INT_PTR np, EEL_F **parms);
  250. extern EEL_F nseel_ramalloc_onfail; // address returned by __NSEEL_RAMAlloc et al on failure
  251. extern EEL_F * volatile nseel_gmembuf_default; // can free/zero this on DLL unload if needed
  252. #ifdef __cplusplus
  253. }
  254. #endif
  255. #endif//__NS_EELINT_H__