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