ns-eel.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /*
  2. Nullsoft Expression Evaluator Library (NS-EEL)
  3. Copyright (C) 1999-2003 Nullsoft, Inc.
  4. ns-eel.h: main application interface 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_EEL_H__
  20. #define __NS_EEL_H__
  21. // put standard includes here
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #ifndef EEL_F_SIZE
  25. #define EEL_F_SIZE 8
  26. #endif
  27. #define NSEEL_EEL1_COMPAT_MODE
  28. #include "wdltypes.h"
  29. #if EEL_F_SIZE == 4
  30. typedef float EEL_F;
  31. typedef float *EEL_F_PTR;
  32. #else
  33. typedef double EEL_F WDL_FIXALIGN;
  34. typedef double *EEL_F_PTR;
  35. #endif
  36. #ifdef _MSC_VER
  37. #define NSEEL_CGEN_CALL __cdecl
  38. #else
  39. #define NSEEL_CGEN_CALL
  40. #endif
  41. #ifdef __cplusplus
  42. extern "C" {
  43. #endif
  44. // host should implement these (can be empty stub functions if no VM will execute code in multiple threads at once)
  45. // implement if you will be running the code in same VM from multiple threads,
  46. // or VMs that have the same GRAM pointer from different threads, or multiple
  47. // VMs that have a NULL GRAM pointer from multiple threads.
  48. // if you give each VM it's own unique GRAM and only run each VM in one thread, then you can leave it blank.
  49. // or if you're daring....
  50. void NSEEL_HOSTSTUB_EnterMutex();
  51. void NSEEL_HOSTSTUB_LeaveMutex();
  52. int NSEEL_init(); // returns nonzero on failure (only if EEL_VALIDATE_FSTUBS defined), otherwise the same as NSEEL_quit(), and completely optional
  53. void NSEEL_quit(); // clears any added functions
  54. // adds a function that returns a value (EEL_F)
  55. #define NSEEL_addfunc_retval(name,np,pproc,fptr) \
  56. NSEEL_addfunc_ret_type(name,np,1,pproc,(void *)(fptr),NSEEL_ADDFUNC_DESTINATION)
  57. // adds a function that returns a pointer (EEL_F*)
  58. #define NSEEL_addfunc_retptr(name,np,pproc,fptr) \
  59. NSEEL_addfunc_ret_type(name,np,0,pproc,(void *)(fptr),NSEEL_ADDFUNC_DESTINATION)
  60. // adds a void or bool function
  61. #define NSEEL_addfunc_retbool(name,np,pproc,fptr) \
  62. NSEEL_addfunc_ret_type(name,np,-1,pproc,(void *)(fptr),NSEEL_ADDFUNC_DESTINATION)
  63. // adds a function that takes min_np or more parameters (func sig needs to be EEL_F func(void *ctx, INT_PTR np, EEL_F **parms)
  64. #define NSEEL_addfunc_varparm(name, min_np, pproc, fptr) \
  65. NSEEL_addfunc_varparm_ex(name,min_np,0,pproc,fptr,NSEEL_ADDFUNC_DESTINATION)
  66. // adds a function that takes np parameters via func: sig needs to be EEL_F func(void *ctx, INT_PTR np, EEL_F **parms)
  67. #define NSEEL_addfunc_exparms(name, np, pproc, fptr) \
  68. NSEEL_addfunc_varparm_ex(name,np,1,pproc,fptr,NSEEL_ADDFUNC_DESTINATION)
  69. // deprecated
  70. #define NSEEL_addfunction(name,nparms,code,len) NSEEL_addfunctionex((name),(nparms),(code),(len),0,0)
  71. #define NSEEL_addfunctionex(name,nparms,code,len,pproc,fptr) NSEEL_addfunctionex2((name),(nparms),(code),(len),(pproc),(fptr),0, NSEEL_ADDFUNC_DESTINATION)
  72. #ifndef NSEEL_ADDFUNC_DESTINATION
  73. #define NSEEL_ADDFUNC_DESTINATION (NULL)
  74. #endif
  75. struct functionType;
  76. typedef struct
  77. {
  78. struct functionType *list;
  79. int list_size;
  80. } eel_function_table;
  81. struct _compileContext;
  82. typedef void *(*NSEEL_PPPROC)(void *data, int data_size, struct _compileContext *userfunc_data);
  83. void NSEEL_addfunctionex2(const char *name, int nparms, char *code_startaddr, int code_len, NSEEL_PPPROC pproc, void *fptr, void *fptr2, eel_function_table *destination);
  84. void NSEEL_addfunc_ret_type(const char *name, int np, int ret_type, NSEEL_PPPROC pproc, void *fptr, eel_function_table *destination); // ret_type=-1 for bool, 1 for value, 0 for ptr
  85. void NSEEL_addfunc_varparm_ex(const char *name, int min_np, int want_exact, NSEEL_PPPROC pproc, EEL_F (NSEEL_CGEN_CALL *fptr)(void *, INT_PTR, EEL_F **), eel_function_table *destination);
  86. int *NSEEL_getstats(); // returns a pointer to 5 ints... source bytes, static code bytes, call code bytes, data bytes, number of code handles
  87. typedef void *NSEEL_VMCTX;
  88. typedef void *NSEEL_CODEHANDLE;
  89. NSEEL_VMCTX NSEEL_VM_alloc(); // return a handle
  90. void NSEEL_VM_free(NSEEL_VMCTX ctx); // free when done with a VM and ALL of its code have been freed, as well
  91. void NSEEL_VM_SetFunctionTable(NSEEL_VMCTX, eel_function_table *tab); // use NULL to use default (global) table
  92. // validateFunc can return error message if not permitted
  93. void NSEEL_VM_SetFunctionValidator(NSEEL_VMCTX, const char * (*validateFunc)(const char *fn_name, void *user), void *user);
  94. void NSEEL_VM_remove_unused_vars(NSEEL_VMCTX _ctx);
  95. void NSEEL_VM_clear_var_refcnts(NSEEL_VMCTX _ctx);
  96. void NSEEL_VM_remove_all_nonreg_vars(NSEEL_VMCTX _ctx);
  97. void NSEEL_VM_enumallvars(NSEEL_VMCTX ctx, int (*func)(const char *name, EEL_F *val, void *ctx), void *userctx); // return false from func to stop
  98. EEL_F *NSEEL_VM_regvar(NSEEL_VMCTX ctx, const char *name); // register a variable (before compilation)
  99. EEL_F *NSEEL_VM_getvar(NSEEL_VMCTX ctx, const char *name); // get a variable (if registered or created by code)
  100. int NSEEL_VM_get_var_refcnt(NSEEL_VMCTX _ctx, const char *name); // returns -1 if not registered, or >=0
  101. void NSEEL_VM_set_var_resolver(NSEEL_VMCTX ctx, EEL_F *(*res)(void *userctx, const char *name), void *userctx);
  102. void NSEEL_VM_freeRAM(NSEEL_VMCTX ctx); // clears and frees all (VM) RAM used
  103. void NSEEL_VM_freeRAMIfCodeRequested(NSEEL_VMCTX); // call after code to free the script-requested memory
  104. int NSEEL_VM_wantfreeRAM(NSEEL_VMCTX ctx); // want NSEEL_VM_freeRAMIfCodeRequested?
  105. // if you set this, it uses a local GMEM context.
  106. // Must be set before compilation.
  107. // void *p=NULL;
  108. // NSEEL_VM_SetGRAM(ctx,&p);
  109. // .. do stuff
  110. // NSEEL_VM_FreeGRAM(&p);
  111. void NSEEL_VM_SetGRAM(NSEEL_VMCTX ctx, void **gram);
  112. void NSEEL_VM_FreeGRAM(void **ufd); // frees a gmem context.
  113. void NSEEL_VM_SetCustomFuncThis(NSEEL_VMCTX ctx, void *thisptr);
  114. EEL_F *NSEEL_VM_getramptr(NSEEL_VMCTX ctx, unsigned int offs, int *validCount);
  115. EEL_F *NSEEL_VM_getramptr_noalloc(NSEEL_VMCTX ctx, unsigned int offs, int *validCount);
  116. // set 0 to query. returns actual value used (limits, granularity apply -- see NSEEL_RAM_BLOCKS)
  117. int NSEEL_VM_setramsize(NSEEL_VMCTX ctx, int maxent);
  118. struct eelStringSegmentRec {
  119. struct eelStringSegmentRec *_next;
  120. const char *str_start; // escaped characters, including opening/trailing characters
  121. int str_len;
  122. };
  123. void NSEEL_VM_SetStringFunc(NSEEL_VMCTX ctx,
  124. EEL_F (*onString)(void *caller_this, struct eelStringSegmentRec *list),
  125. EEL_F (*onNamedString)(void *caller_this, const char *name));
  126. // call with NULL to calculate size, or non-null to generate to buffer (returning size used -- will not null terminate, caller responsibility)
  127. int nseel_stringsegments_tobuf(char *bufOut, int bufout_sz, struct eelStringSegmentRec *list);
  128. NSEEL_CODEHANDLE NSEEL_code_compile(NSEEL_VMCTX ctx, const char *code, int lineoffs);
  129. #define NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS 1 // allows that code's functions to be used in other code (note you shouldn't destroy that codehandle without destroying others first if used)
  130. #define NSEEL_CODE_COMPILE_FLAG_COMMONFUNCS_RESET 2 // resets common code functions
  131. #define NSEEL_CODE_COMPILE_FLAG_NOFPSTATE 4 // hint that the FPU/SSE state should be good-to-go
  132. #define NSEEL_CODE_COMPILE_FLAG_ONLY_BUILTIN_FUNCTIONS 8 // very restrictive mode (only math functions really)
  133. NSEEL_CODEHANDLE NSEEL_code_compile_ex(NSEEL_VMCTX ctx, const char *code, int lineoffs, int flags);
  134. char *NSEEL_code_getcodeerror(NSEEL_VMCTX ctx);
  135. int NSEEL_code_geterror_flag(NSEEL_VMCTX ctx);
  136. void NSEEL_code_execute(NSEEL_CODEHANDLE code);
  137. void NSEEL_code_free(NSEEL_CODEHANDLE code);
  138. int *NSEEL_code_getstats(NSEEL_CODEHANDLE code); // 4 ints...source bytes, static code bytes, call code bytes, data bytes
  139. // global memory control/view
  140. extern unsigned int NSEEL_RAM_limitmem; // if nonzero, memory limit for user data, in bytes
  141. extern unsigned int NSEEL_RAM_memused;
  142. extern int NSEEL_RAM_memused_errors;
  143. // configuration:
  144. // use the handwritten lexer -- the flex (eel2.l generated) lexer mostly works, but doesn't support string parsing at the moment
  145. // this mode is faster and uses less ram than eel2.l anyway, so leave it on
  146. #define NSEEL_SUPER_MINIMAL_LEXER
  147. // #define NSEEL_EEL1_COMPAT_MODE // supports old behaviors (continue after failed compile), old functions _bnot etc. disables string support (strings were used as comments in eel1 etc)
  148. #define NSEEL_MAX_VARIABLE_NAMELEN 128 // define this to override the max variable length
  149. #define NSEEL_MAX_EELFUNC_PARAMETERS 40
  150. #define NSEEL_MAX_FUNCSIG_NAME 2048 // longer than variable maxlen, due to multiple namespaces
  151. // maximum loop length (0 for unlimited)
  152. #ifndef NSEEL_LOOPFUNC_SUPPORT_MAXLEN
  153. #define NSEEL_LOOPFUNC_SUPPORT_MAXLEN 1048576
  154. #endif
  155. #define NSEEL_MAX_FUNCTION_SIZE_FOR_INLINE 2048
  156. // when a VM ctx doesn't have a GRAM context set, make the global one this big
  157. #define NSEEL_SHARED_GRAM_SIZE (1<<20)
  158. //#define EEL_DUMP_OPS // used for testing frontend parser/logic changes
  159. // note: if you wish to change NSEEL_RAM_*, and your target is x86-64, you will need to regenerate things.
  160. // on osx:
  161. // php a2x64.php win64x
  162. // php a2x64.php macho64
  163. // or on win32:
  164. // php a2x64.php
  165. // php a2x64.php macho64x
  166. // this will regenerate the .asm files and object files
  167. // 512 * 65536 = 32 million entries maximum (256MB RAM)
  168. // default is limited to 128 * 65536 = 8 million entries (64MB RAM)
  169. // default to 8 million entries, use NSEEL_VM_setramsize() to change at runtime
  170. #define NSEEL_RAM_BLOCKS_DEFAULTMAX 128
  171. // 512 entry block table maximum (2k/4k per VM)
  172. #define NSEEL_RAM_BLOCKS_LOG2 9
  173. // 65536 items per block (512KB)
  174. #define NSEEL_RAM_ITEMSPERBLOCK_LOG2 16
  175. #define NSEEL_RAM_BLOCKS (1 << NSEEL_RAM_BLOCKS_LOG2)
  176. #define NSEEL_RAM_ITEMSPERBLOCK (1<<NSEEL_RAM_ITEMSPERBLOCK_LOG2)
  177. #define NSEEL_STACK_SIZE 4096 // about 64k overhead if the stack functions are used in a given code handle
  178. // arch neutral mode, runs about 1/8th speed or so
  179. //#define EEL_TARGET_PORTABLE
  180. #ifdef EEL_TARGET_PORTABLE
  181. #define EEL_BC_TYPE int
  182. #endif
  183. #ifdef NSEEL_EEL1_COMPAT_MODE
  184. double *NSEEL_getglobalregs();
  185. #endif
  186. void eel_setfp_round(); // use to set fp to rounding mode (normal) -- only really use this when being called from EEL
  187. void eel_setfp_trunc(); // use to restore fp to trunc mode -- only really use this when being called from EEL
  188. void eel_enterfp(int s[2]);
  189. void eel_leavefp(int s[2]);
  190. extern void *(*nseel_gmem_calloc)(size_t,size_t); // set this to the calloc() implementation used by the context that will call NSEEL_VM_FreeGRAM()
  191. #ifdef __cplusplus
  192. }
  193. #endif
  194. #endif//__NS_EEL_H__