1 #ifndef jsi_h
2 #define jsi_h
3
4 #include "mujs.h"
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <stddef.h>
9 #include <stdarg.h>
10 #include <string.h>
11 #include <setjmp.h>
12 #include <math.h>
13 #include <float.h>
14 #include <limits.h>
15
16 /* Microsoft Visual C */
17 #ifdef _MSC_VER
18 #pragma warning(disable:4996) /* _CRT_SECURE_NO_WARNINGS */
19 #pragma warning(disable:4244) /* implicit conversion from double to int */
20 #pragma warning(disable:4267) /* implicit conversion of int to smaller int */
21 #define inline __inline
22 #if _MSC_VER < 1900 /* MSVC 2015 */
23 #define snprintf jsW_snprintf
24 #define vsnprintf jsW_vsnprintf
jsW_vsnprintf(char * str,size_t size,const char * fmt,va_list ap)25 static int jsW_vsnprintf(char *str, size_t size, const char *fmt, va_list ap)
26 {
27 int n;
28 n = _vsnprintf(str, size, fmt, ap);
29 str[size-1] = 0;
30 return n;
31 }
jsW_snprintf(char * str,size_t size,const char * fmt,...)32 static int jsW_snprintf(char *str, size_t size, const char *fmt, ...)
33 {
34 int n;
35 va_list ap;
36 va_start(ap, fmt);
37 n = jsW_vsnprintf(str, size, fmt, ap);
38 va_end(ap);
39 return n;
40 }
41 #endif
42 #if _MSC_VER <= 1700 /* <= MSVC 2012 */
43 #define isnan(x) _isnan(x)
44 #define isinf(x) (!_finite(x))
45 #define isfinite(x) _finite(x)
signbit(double x)46 static __inline int signbit(double x) { __int64 i; memcpy(&i, &x, 8); return i>>63; }
47 #define INFINITY (DBL_MAX+DBL_MAX)
48 #define NAN (INFINITY-INFINITY)
49 #endif
50 #endif
51
52 #define soffsetof(x,y) ((int)offsetof(x,y))
53 #define nelem(a) (int)(sizeof (a) / sizeof (a)[0])
54
55 void *js_malloc(js_State *J, int size);
56 void *js_realloc(js_State *J, void *ptr, int size);
57 void js_free(js_State *J, void *ptr);
58
59 typedef struct js_Regexp js_Regexp;
60 typedef struct js_Value js_Value;
61 typedef struct js_Object js_Object;
62 typedef struct js_String js_String;
63 typedef struct js_Ast js_Ast;
64 typedef struct js_Function js_Function;
65 typedef struct js_Environment js_Environment;
66 typedef struct js_StringNode js_StringNode;
67 typedef struct js_Jumpbuf js_Jumpbuf;
68 typedef struct js_StackTrace js_StackTrace;
69
70 /* Limits */
71
72 #ifndef JS_STACKSIZE
73 #define JS_STACKSIZE 256 /* value stack size */
74 #endif
75 #ifndef JS_ENVLIMIT
76 #define JS_ENVLIMIT 128 /* environment stack size */
77 #endif
78 #ifndef JS_TRYLIMIT
79 #define JS_TRYLIMIT 64 /* exception stack size */
80 #endif
81 #ifndef JS_GCFACTOR
82 /*
83 * GC will try to trigger when memory usage is this value times the minimum
84 * needed memory. E.g. if there are 100 remaining objects after GC and this
85 * value is 5.0, then the next GC will trigger when the overall number is 500.
86 * I.e. a value of 5.0 aims at 80% garbage, 20% remain-used on each GC.
87 * The bigger the value the less impact GC has on overall performance, but more
88 * memory is used and individual GC pauses are longer (but fewer).
89 */
90 #define JS_GCFACTOR 5.0 /* memory overhead factor >= 1.0 */
91 #endif
92 #ifndef JS_ASTLIMIT
93 #define JS_ASTLIMIT 100 /* max nested expressions */
94 #endif
95
96 /* instruction size -- change to int if you get integer overflow syntax errors */
97
98 #ifdef JS_INSTRUCTION
99 typedef JS_INSTRUCTION js_Instruction;
100 #else
101 typedef unsigned short js_Instruction;
102 #endif
103
104 /* String interning */
105
106 char *js_strdup(js_State *J, const char *s);
107 const char *js_intern(js_State *J, const char *s);
108 void jsS_dumpstrings(js_State *J);
109 void jsS_freestrings(js_State *J);
110
111 /* Portable strtod and printf float formatting */
112
113 void js_fmtexp(char *p, int e);
114 int js_grisu2(double v, char *buffer, int *K);
115 double js_strtod(const char *as, char **aas);
116
117 /* Private stack functions */
118
119 void js_newarguments(js_State *J);
120 void js_newfunction(js_State *J, js_Function *function, js_Environment *scope);
121 void js_newscript(js_State *J, js_Function *fun, js_Environment *scope, int type);
122 void js_loadeval(js_State *J, const char *filename, const char *source);
123
124 js_Regexp *js_toregexp(js_State *J, int idx);
125 int js_isarrayindex(js_State *J, const char *str, int *idx);
126 int js_runeat(js_State *J, const char *s, int i);
127 int js_utfptrtoidx(const char *s, const char *p);
128 const char *js_utfidxtoptr(const char *s, int i);
129
130 void js_dup(js_State *J);
131 void js_dup2(js_State *J);
132 void js_rot2(js_State *J);
133 void js_rot3(js_State *J);
134 void js_rot4(js_State *J);
135 void js_rot2pop1(js_State *J);
136 void js_rot3pop2(js_State *J);
137 void js_dup1rot3(js_State *J);
138 void js_dup1rot4(js_State *J);
139
140 void js_RegExp_prototype_exec(js_State *J, js_Regexp *re, const char *text);
141
142 void js_trap(js_State *J, int pc); /* dump stack and environment to stdout */
143
144 struct js_StackTrace
145 {
146 const char *name;
147 const char *file;
148 int line;
149 };
150
151 /* Exception handling */
152
153 struct js_Jumpbuf
154 {
155 jmp_buf buf;
156 js_Environment *E;
157 int envtop;
158 int tracetop;
159 int top, bot;
160 int strict;
161 js_Instruction *pc;
162 };
163
164 void *js_savetrypc(js_State *J, js_Instruction *pc);
165
166 #define js_trypc(J, PC) \
167 setjmp(js_savetrypc(J, PC))
168
169 /* String buffer */
170
171 typedef struct js_Buffer { int n, m; char s[64]; } js_Buffer;
172
173 void js_putc(js_State *J, js_Buffer **sbp, int c);
174 void js_puts(js_State *J, js_Buffer **sb, const char *s);
175 void js_putm(js_State *J, js_Buffer **sb, const char *s, const char *e);
176
177 /* State struct */
178
179 struct js_State
180 {
181 void *actx;
182 void *uctx;
183 js_Alloc alloc;
184 js_Report report;
185 js_Panic panic;
186
187 js_StringNode *strings;
188
189 int default_strict;
190 int strict;
191
192 /* parser input source */
193 const char *filename;
194 const char *source;
195 int line;
196
197 /* lexer state */
198 struct { char *text; int len, cap; } lexbuf;
199 int lexline;
200 int lexchar;
201 int lasttoken;
202 int newline;
203
204 /* parser state */
205 int astdepth;
206 int lookahead;
207 const char *text;
208 double number;
209 js_Ast *gcast; /* list of allocated nodes to free after parsing */
210
211 /* runtime environment */
212 js_Object *Object_prototype;
213 js_Object *Array_prototype;
214 js_Object *Function_prototype;
215 js_Object *Boolean_prototype;
216 js_Object *Number_prototype;
217 js_Object *String_prototype;
218 js_Object *RegExp_prototype;
219 js_Object *Date_prototype;
220
221 js_Object *Error_prototype;
222 js_Object *EvalError_prototype;
223 js_Object *RangeError_prototype;
224 js_Object *ReferenceError_prototype;
225 js_Object *SyntaxError_prototype;
226 js_Object *TypeError_prototype;
227 js_Object *URIError_prototype;
228
229 unsigned int seed; /* Math.random seed */
230
231 int nextref; /* for js_ref use */
232 js_Object *R; /* registry of hidden values */
233 js_Object *G; /* the global object */
234 js_Environment *E; /* current environment scope */
235 js_Environment *GE; /* global environment scope (at the root) */
236
237 /* execution stack */
238 int top, bot;
239 js_Value *stack;
240
241 /* garbage collector list */
242 int gcpause;
243 int gcmark;
244 unsigned int gccounter, gcthresh;
245 js_Environment *gcenv;
246 js_Function *gcfun;
247 js_Object *gcobj;
248 js_String *gcstr;
249
250 js_Object *gcroot; /* gc scan list */
251
252 /* environments on the call stack but currently not in scope */
253 int envtop;
254 js_Environment *envstack[JS_ENVLIMIT];
255
256 /* debug info stack trace */
257 int tracetop;
258 js_StackTrace trace[JS_ENVLIMIT];
259
260 /* exception stack */
261 int trytop;
262 js_Jumpbuf trybuf[JS_TRYLIMIT];
263 };
264
265 #endif
266