Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/mujs/jsi.h @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 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 | |
| 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 } | |
| 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) | |
| 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 union js_Value js_Value; | |
| 68 typedef struct js_Regexp js_Regexp; | |
| 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 4096 /* value stack size */ | |
| 82 #endif | |
| 83 #ifndef JS_ENVLIMIT | |
| 84 #define JS_ENVLIMIT 1024 /* environment stack size */ | |
| 85 #endif | |
| 86 #ifndef JS_TRYLIMIT | |
| 87 #define JS_TRYLIMIT 64 /* exception stack size */ | |
| 88 #endif | |
| 89 | |
| 90 #ifndef JS_ARRAYLIMIT | |
| 91 #define JS_ARRAYLIMIT (1<<26) /* limit arrays to 64M entries (1G of flat array data) */ | |
| 92 #endif | |
| 93 | |
| 94 #ifndef JS_GCFACTOR | |
| 95 /* | |
| 96 * GC will try to trigger when memory usage is this value times the minimum | |
| 97 * needed memory. E.g. if there are 100 remaining objects after GC and this | |
| 98 * value is 5.0, then the next GC will trigger when the overall number is 500. | |
| 99 * I.e. a value of 5.0 aims at 80% garbage, 20% remain-used on each GC. | |
| 100 * The bigger the value the less impact GC has on overall performance, but more | |
| 101 * memory is used and individual GC pauses are longer (but fewer). | |
| 102 */ | |
| 103 #define JS_GCFACTOR 5.0 /* memory overhead factor >= 1.0 */ | |
| 104 #endif | |
| 105 | |
| 106 #ifndef JS_ASTLIMIT | |
| 107 #define JS_ASTLIMIT 400 /* max nested expressions */ | |
| 108 #endif | |
| 109 | |
| 110 #ifndef JS_STRLIMIT | |
| 111 #define JS_STRLIMIT (1<<28) /* max string length */ | |
| 112 #endif | |
| 113 | |
| 114 /* instruction size -- change to int if you get integer overflow syntax errors */ | |
| 115 | |
| 116 #ifdef JS_INSTRUCTION | |
| 117 typedef JS_INSTRUCTION js_Instruction; | |
| 118 #else | |
| 119 typedef unsigned short js_Instruction; | |
| 120 #endif | |
| 121 | |
| 122 /* String interning */ | |
| 123 | |
| 124 char *js_strdup(js_State *J, const char *s); | |
| 125 const char *js_intern(js_State *J, const char *s); | |
| 126 void jsS_dumpstrings(js_State *J); | |
| 127 void jsS_freestrings(js_State *J); | |
| 128 | |
| 129 /* Portable strtod and printf float formatting */ | |
| 130 | |
| 131 void js_fmtexp(char *p, int e); | |
| 132 int js_grisu2(double v, char *buffer, int *K); | |
| 133 double js_strtod(const char *as, char **aas); | |
| 134 | |
| 135 double js_strtol(const char *s, char **ep, int radix); | |
| 136 | |
| 137 /* Private stack functions */ | |
| 138 | |
| 139 void js_newarguments(js_State *J); | |
| 140 void js_newfunction(js_State *J, js_Function *function, js_Environment *scope); | |
| 141 void js_newscript(js_State *J, js_Function *function, js_Environment *scope); | |
| 142 void js_loadeval(js_State *J, const char *filename, const char *source); | |
| 143 | |
| 144 js_Regexp *js_toregexp(js_State *J, int idx); | |
| 145 int js_isarrayindex(js_State *J, const char *str, int *idx); | |
| 146 int js_runeat(js_State *J, const char *s, int i); | |
| 147 int js_utflen(const char *s); | |
| 148 int js_utfptrtoidx(const char *s, const char *p); | |
| 149 | |
| 150 void js_dup(js_State *J); | |
| 151 void js_dup2(js_State *J); | |
| 152 void js_rot2(js_State *J); | |
| 153 void js_rot3(js_State *J); | |
| 154 void js_rot4(js_State *J); | |
| 155 void js_rot2pop1(js_State *J); | |
| 156 void js_rot3pop2(js_State *J); | |
| 157 void js_dup1rot3(js_State *J); | |
| 158 void js_dup1rot4(js_State *J); | |
| 159 | |
| 160 void js_RegExp_prototype_exec(js_State *J, js_Regexp *re, const char *text); | |
| 161 | |
| 162 void js_trap(js_State *J, int pc); /* dump stack and environment to stdout */ | |
| 163 | |
| 164 struct js_StackTrace | |
| 165 { | |
| 166 const char *name; | |
| 167 const char *file; | |
| 168 int line; | |
| 169 }; | |
| 170 | |
| 171 /* Exception handling */ | |
| 172 | |
| 173 struct js_Jumpbuf | |
| 174 { | |
| 175 jmp_buf buf; | |
| 176 js_Environment *E; | |
| 177 int envtop; | |
| 178 int tracetop; | |
| 179 int top, bot; | |
| 180 int strict; | |
| 181 js_Instruction *pc; | |
| 182 }; | |
| 183 | |
| 184 void *js_savetrypc(js_State *J, js_Instruction *pc); | |
| 185 | |
| 186 #define js_trypc(J, PC) \ | |
| 187 setjmp(js_savetrypc(J, PC)) | |
| 188 | |
| 189 /* String buffer */ | |
| 190 | |
| 191 typedef struct js_Buffer { int n, m; char s[64]; } js_Buffer; | |
| 192 | |
| 193 void js_putc(js_State *J, js_Buffer **sbp, int c); | |
| 194 void js_puts(js_State *J, js_Buffer **sb, const char *s); | |
| 195 void js_putm(js_State *J, js_Buffer **sb, const char *s, const char *e); | |
| 196 | |
| 197 /* State struct */ | |
| 198 | |
| 199 struct js_State | |
| 200 { | |
| 201 void *actx; | |
| 202 void *uctx; | |
| 203 js_Alloc alloc; | |
| 204 js_Report report; | |
| 205 js_Panic panic; | |
| 206 | |
| 207 js_StringNode *strings; | |
| 208 | |
| 209 int default_strict; | |
| 210 int strict; | |
| 211 | |
| 212 /* parser input source */ | |
| 213 const char *filename; | |
| 214 const char *source; | |
| 215 int line; | |
| 216 | |
| 217 /* lexer state */ | |
| 218 struct { char *text; int len, cap; } lexbuf; | |
| 219 int lexline; | |
| 220 int lexchar; | |
| 221 int lasttoken; | |
| 222 int newline; | |
| 223 | |
| 224 /* parser state */ | |
| 225 int astdepth; | |
| 226 int lookahead; | |
| 227 const char *text; | |
| 228 double number; | |
| 229 js_Ast *gcast; /* list of allocated nodes to free after parsing */ | |
| 230 | |
| 231 /* runtime environment */ | |
| 232 js_Object *Object_prototype; | |
| 233 js_Object *Array_prototype; | |
| 234 js_Object *Function_prototype; | |
| 235 js_Object *Boolean_prototype; | |
| 236 js_Object *Number_prototype; | |
| 237 js_Object *String_prototype; | |
| 238 js_Object *RegExp_prototype; | |
| 239 js_Object *Date_prototype; | |
| 240 | |
| 241 js_Object *Error_prototype; | |
| 242 js_Object *EvalError_prototype; | |
| 243 js_Object *RangeError_prototype; | |
| 244 js_Object *ReferenceError_prototype; | |
| 245 js_Object *SyntaxError_prototype; | |
| 246 js_Object *TypeError_prototype; | |
| 247 js_Object *URIError_prototype; | |
| 248 | |
| 249 unsigned int seed; /* Math.random seed */ | |
| 250 | |
| 251 char scratch[12]; /* scratch buffer for iterating over array indices */ | |
| 252 | |
| 253 int nextref; /* for js_ref use */ | |
| 254 js_Object *R; /* registry of hidden values */ | |
| 255 js_Object *G; /* the global object */ | |
| 256 js_Environment *E; /* current environment scope */ | |
| 257 js_Environment *GE; /* global environment scope (at the root) */ | |
| 258 | |
| 259 /* execution stack */ | |
| 260 int top, bot; | |
| 261 js_Value *stack; | |
| 262 | |
| 263 /* garbage collector list */ | |
| 264 int gcpause; | |
| 265 int gcmark; | |
| 266 unsigned int gccounter, gcthresh; | |
| 267 js_Environment *gcenv; | |
| 268 js_Function *gcfun; | |
| 269 js_Object *gcobj; | |
| 270 js_String *gcstr; | |
| 271 | |
| 272 js_Object *gcroot; /* gc scan list */ | |
| 273 | |
| 274 /* environments on the call stack but currently not in scope */ | |
| 275 int envtop; | |
| 276 js_Environment *envstack[JS_ENVLIMIT]; | |
| 277 | |
| 278 /* debug info stack trace */ | |
| 279 int tracetop; | |
| 280 js_StackTrace trace[JS_ENVLIMIT]; | |
| 281 | |
| 282 /* exception stack */ | |
| 283 int trytop; | |
| 284 js_Jumpbuf trybuf[JS_TRYLIMIT]; | |
| 285 }; | |
| 286 | |
| 287 /* Values */ | |
| 288 | |
| 289 typedef struct js_Property js_Property; | |
| 290 typedef struct js_Iterator js_Iterator; | |
| 291 | |
| 292 /* Hint to ToPrimitive() */ | |
| 293 enum { | |
| 294 JS_HNONE, | |
| 295 JS_HNUMBER, | |
| 296 JS_HSTRING | |
| 297 }; | |
| 298 | |
| 299 enum js_Type { | |
| 300 JS_TSHRSTR, /* type tag doubles as string zero-terminator */ | |
| 301 JS_TUNDEFINED, | |
| 302 JS_TNULL, | |
| 303 JS_TBOOLEAN, | |
| 304 JS_TNUMBER, | |
| 305 JS_TLITSTR, | |
| 306 JS_TMEMSTR, | |
| 307 JS_TOBJECT, | |
| 308 }; | |
| 309 | |
| 310 enum js_Class { | |
| 311 JS_COBJECT, | |
| 312 JS_CARRAY, | |
| 313 JS_CFUNCTION, | |
| 314 JS_CSCRIPT, /* function created from global/eval code */ | |
| 315 JS_CCFUNCTION, /* built-in function */ | |
| 316 JS_CERROR, | |
| 317 JS_CBOOLEAN, | |
| 318 JS_CNUMBER, | |
| 319 JS_CSTRING, | |
| 320 JS_CREGEXP, | |
| 321 JS_CDATE, | |
| 322 JS_CMATH, | |
| 323 JS_CJSON, | |
| 324 JS_CARGUMENTS, | |
| 325 JS_CITERATOR, | |
| 326 JS_CUSERDATA, | |
| 327 }; | |
| 328 | |
| 329 /* | |
| 330 Short strings abuse the js_Value struct. By putting the type tag in the | |
| 331 last byte, and using 0 as the tag for short strings, we can use the | |
| 332 entire js_Value as string storage by letting the type tag serve double | |
| 333 purpose as the string zero terminator. | |
| 334 */ | |
| 335 | |
| 336 union js_Value | |
| 337 { | |
| 338 struct { | |
| 339 char pad[15]; | |
| 340 char type; /* type tag overlaps with final byte of shrstr */ | |
| 341 } t; | |
| 342 union { | |
| 343 char shrstr[16]; | |
| 344 int boolean; | |
| 345 double number; | |
| 346 const char *litstr; | |
| 347 js_String *memstr; | |
| 348 js_Object *object; | |
| 349 } u; | |
| 350 }; | |
| 351 | |
| 352 struct js_String | |
| 353 { | |
| 354 js_String *gcnext; | |
| 355 char gcmark; | |
| 356 char p[1]; | |
| 357 }; | |
| 358 | |
| 359 struct js_Regexp | |
| 360 { | |
| 361 void *prog; | |
| 362 char *source; | |
| 363 unsigned short flags; | |
| 364 unsigned short last; | |
| 365 }; | |
| 366 | |
| 367 struct js_Object | |
| 368 { | |
| 369 enum js_Class type; | |
| 370 int extensible; | |
| 371 js_Property *properties; | |
| 372 int count; /* number of properties, for array sparseness check */ | |
| 373 js_Object *prototype; | |
| 374 union { | |
| 375 int boolean; | |
| 376 double number; | |
| 377 struct { | |
| 378 int length; | |
| 379 char *string; | |
| 380 char shrstr[16]; | |
| 381 } s; | |
| 382 struct { | |
| 383 int length; /* actual length */ | |
| 384 int simple; /* true if array has only non-sparse array properties */ | |
| 385 int flat_length; /* used length of simple array part */ | |
| 386 int flat_capacity; /* allocated length of simple array part */ | |
| 387 js_Value *array; | |
| 388 } a; | |
| 389 struct { | |
| 390 js_Function *function; | |
| 391 js_Environment *scope; | |
| 392 } f; | |
| 393 struct { | |
| 394 const char *name; | |
| 395 js_CFunction function; | |
| 396 js_CFunction constructor; | |
| 397 int length; | |
| 398 void *data; | |
| 399 js_Finalize finalize; | |
| 400 } c; | |
| 401 js_Regexp r; | |
| 402 struct { | |
| 403 js_Object *target; | |
| 404 int i, n; /* for array part */ | |
| 405 js_Iterator *head, *current; /* for object part */ | |
| 406 } iter; | |
| 407 struct { | |
| 408 const char *tag; | |
| 409 void *data; | |
| 410 js_HasProperty has; | |
| 411 js_Put put; | |
| 412 js_Delete delete; | |
| 413 js_Finalize finalize; | |
| 414 } user; | |
| 415 } u; | |
| 416 js_Object *gcnext; /* allocation list */ | |
| 417 js_Object *gcroot; /* scan list */ | |
| 418 int gcmark; | |
| 419 }; | |
| 420 | |
| 421 struct js_Property | |
| 422 { | |
| 423 js_Property *left, *right; | |
| 424 int level; | |
| 425 int atts; | |
| 426 js_Value value; | |
| 427 js_Object *getter; | |
| 428 js_Object *setter; | |
| 429 char name[1]; | |
| 430 }; | |
| 431 | |
| 432 struct js_Iterator | |
| 433 { | |
| 434 js_Iterator *next; | |
| 435 char name[1]; | |
| 436 }; | |
| 437 | |
| 438 struct js_Environment | |
| 439 { | |
| 440 js_Environment *outer; | |
| 441 js_Object *variables; | |
| 442 | |
| 443 js_Environment *gcnext; | |
| 444 int gcmark; | |
| 445 }; | |
| 446 | |
| 447 /* jsrun.c */ | |
| 448 js_Environment *jsR_newenvironment(js_State *J, js_Object *variables, js_Environment *outer); | |
| 449 js_String *jsV_newmemstring(js_State *J, const char *s, int n); | |
| 450 js_Value *js_tovalue(js_State *J, int idx); | |
| 451 void js_toprimitive(js_State *J, int idx, int hint); | |
| 452 js_Object *js_toobject(js_State *J, int idx); | |
| 453 void js_pushvalue(js_State *J, js_Value v); | |
| 454 void js_pushobject(js_State *J, js_Object *v); | |
| 455 void jsR_unflattenarray(js_State *J, js_Object *obj); | |
| 456 | |
| 457 /* jsvalue.c */ | |
| 458 int jsV_toboolean(js_State *J, js_Value *v); | |
| 459 double jsV_tonumber(js_State *J, js_Value *v); | |
| 460 double jsV_tointeger(js_State *J, js_Value *v); | |
| 461 const char *jsV_tostring(js_State *J, js_Value *v); | |
| 462 js_Object *jsV_toobject(js_State *J, js_Value *v); | |
| 463 void jsV_toprimitive(js_State *J, js_Value *v, int preferred); | |
| 464 | |
| 465 const char *js_itoa(char *buf, int a); | |
| 466 double js_stringtofloat(const char *s, char **ep); | |
| 467 int jsV_numbertointeger(double n); | |
| 468 int jsV_numbertoint32(double n); | |
| 469 unsigned int jsV_numbertouint32(double n); | |
| 470 short jsV_numbertoint16(double n); | |
| 471 unsigned short jsV_numbertouint16(double n); | |
| 472 const char *jsV_numbertostring(js_State *J, char buf[32], double number); | |
| 473 double jsV_stringtonumber(js_State *J, const char *string); | |
| 474 | |
| 475 /* jsproperty.c */ | |
| 476 js_Object *jsV_newobject(js_State *J, enum js_Class type, js_Object *prototype); | |
| 477 js_Property *jsV_getownproperty(js_State *J, js_Object *obj, const char *name); | |
| 478 js_Property *jsV_getpropertyx(js_State *J, js_Object *obj, const char *name, int *own); | |
| 479 js_Property *jsV_getproperty(js_State *J, js_Object *obj, const char *name); | |
| 480 js_Property *jsV_setproperty(js_State *J, js_Object *obj, const char *name); | |
| 481 js_Property *jsV_nextproperty(js_State *J, js_Object *obj, const char *name); | |
| 482 void jsV_delproperty(js_State *J, js_Object *obj, const char *name); | |
| 483 | |
| 484 js_Object *jsV_newiterator(js_State *J, js_Object *obj, int own); | |
| 485 const char *jsV_nextiterator(js_State *J, js_Object *iter); | |
| 486 | |
| 487 void jsV_resizearray(js_State *J, js_Object *obj, int newlen); | |
| 488 | |
| 489 void jsV_unflattenarray(js_State *J, js_Object *obj); | |
| 490 void jsV_growarray(js_State *J, js_Object *obj); | |
| 491 | |
| 492 /* Lexer */ | |
| 493 | |
| 494 enum | |
| 495 { | |
| 496 TK_IDENTIFIER = 256, | |
| 497 TK_NUMBER, | |
| 498 TK_STRING, | |
| 499 TK_REGEXP, | |
| 500 | |
| 501 /* multi-character punctuators */ | |
| 502 TK_LE, | |
| 503 TK_GE, | |
| 504 TK_EQ, | |
| 505 TK_NE, | |
| 506 TK_STRICTEQ, | |
| 507 TK_STRICTNE, | |
| 508 TK_SHL, | |
| 509 TK_SHR, | |
| 510 TK_USHR, | |
| 511 TK_AND, | |
| 512 TK_OR, | |
| 513 TK_ADD_ASS, | |
| 514 TK_SUB_ASS, | |
| 515 TK_MUL_ASS, | |
| 516 TK_DIV_ASS, | |
| 517 TK_MOD_ASS, | |
| 518 TK_SHL_ASS, | |
| 519 TK_SHR_ASS, | |
| 520 TK_USHR_ASS, | |
| 521 TK_AND_ASS, | |
| 522 TK_OR_ASS, | |
| 523 TK_XOR_ASS, | |
| 524 TK_INC, | |
| 525 TK_DEC, | |
| 526 | |
| 527 /* keywords */ | |
| 528 TK_BREAK, | |
| 529 TK_CASE, | |
| 530 TK_CATCH, | |
| 531 TK_CONTINUE, | |
| 532 TK_DEBUGGER, | |
| 533 TK_DEFAULT, | |
| 534 TK_DELETE, | |
| 535 TK_DO, | |
| 536 TK_ELSE, | |
| 537 TK_FALSE, | |
| 538 TK_FINALLY, | |
| 539 TK_FOR, | |
| 540 TK_FUNCTION, | |
| 541 TK_IF, | |
| 542 TK_IN, | |
| 543 TK_INSTANCEOF, | |
| 544 TK_NEW, | |
| 545 TK_NULL, | |
| 546 TK_RETURN, | |
| 547 TK_SWITCH, | |
| 548 TK_THIS, | |
| 549 TK_THROW, | |
| 550 TK_TRUE, | |
| 551 TK_TRY, | |
| 552 TK_TYPEOF, | |
| 553 TK_VAR, | |
| 554 TK_VOID, | |
| 555 TK_WHILE, | |
| 556 TK_WITH, | |
| 557 }; | |
| 558 | |
| 559 int jsY_iswhite(int c); | |
| 560 int jsY_isnewline(int c); | |
| 561 int jsY_ishex(int c); | |
| 562 int jsY_tohex(int c); | |
| 563 | |
| 564 const char *jsY_tokenstring(int token); | |
| 565 int jsY_findword(const char *s, const char **list, int num); | |
| 566 | |
| 567 void jsY_initlex(js_State *J, const char *filename, const char *source); | |
| 568 int jsY_lex(js_State *J); | |
| 569 int jsY_lexjson(js_State *J); | |
| 570 | |
| 571 /* Parser */ | |
| 572 | |
| 573 enum js_AstType | |
| 574 { | |
| 575 AST_LIST, | |
| 576 AST_FUNDEC, | |
| 577 AST_IDENTIFIER, | |
| 578 | |
| 579 EXP_IDENTIFIER, | |
| 580 EXP_NUMBER, | |
| 581 EXP_STRING, | |
| 582 EXP_REGEXP, | |
| 583 | |
| 584 /* literals */ | |
| 585 EXP_ELISION, /* for array elisions */ | |
| 586 EXP_NULL, | |
| 587 EXP_TRUE, | |
| 588 EXP_FALSE, | |
| 589 EXP_THIS, | |
| 590 | |
| 591 EXP_ARRAY, | |
| 592 EXP_OBJECT, | |
| 593 EXP_PROP_VAL, | |
| 594 EXP_PROP_GET, | |
| 595 EXP_PROP_SET, | |
| 596 | |
| 597 EXP_FUN, | |
| 598 | |
| 599 /* expressions */ | |
| 600 EXP_INDEX, | |
| 601 EXP_MEMBER, | |
| 602 EXP_CALL, | |
| 603 EXP_NEW, | |
| 604 | |
| 605 EXP_POSTINC, | |
| 606 EXP_POSTDEC, | |
| 607 | |
| 608 EXP_DELETE, | |
| 609 EXP_VOID, | |
| 610 EXP_TYPEOF, | |
| 611 EXP_PREINC, | |
| 612 EXP_PREDEC, | |
| 613 EXP_POS, | |
| 614 EXP_NEG, | |
| 615 EXP_BITNOT, | |
| 616 EXP_LOGNOT, | |
| 617 | |
| 618 EXP_MOD, | |
| 619 EXP_DIV, | |
| 620 EXP_MUL, | |
| 621 EXP_SUB, | |
| 622 EXP_ADD, | |
| 623 EXP_USHR, | |
| 624 EXP_SHR, | |
| 625 EXP_SHL, | |
| 626 EXP_IN, | |
| 627 EXP_INSTANCEOF, | |
| 628 EXP_GE, | |
| 629 EXP_LE, | |
| 630 EXP_GT, | |
| 631 EXP_LT, | |
| 632 EXP_STRICTNE, | |
| 633 EXP_STRICTEQ, | |
| 634 EXP_NE, | |
| 635 EXP_EQ, | |
| 636 EXP_BITAND, | |
| 637 EXP_BITXOR, | |
| 638 EXP_BITOR, | |
| 639 EXP_LOGAND, | |
| 640 EXP_LOGOR, | |
| 641 | |
| 642 EXP_COND, | |
| 643 | |
| 644 EXP_ASS, | |
| 645 EXP_ASS_MUL, | |
| 646 EXP_ASS_DIV, | |
| 647 EXP_ASS_MOD, | |
| 648 EXP_ASS_ADD, | |
| 649 EXP_ASS_SUB, | |
| 650 EXP_ASS_SHL, | |
| 651 EXP_ASS_SHR, | |
| 652 EXP_ASS_USHR, | |
| 653 EXP_ASS_BITAND, | |
| 654 EXP_ASS_BITXOR, | |
| 655 EXP_ASS_BITOR, | |
| 656 | |
| 657 EXP_COMMA, | |
| 658 | |
| 659 EXP_VAR, /* var initializer */ | |
| 660 | |
| 661 /* statements */ | |
| 662 STM_BLOCK, | |
| 663 STM_EMPTY, | |
| 664 STM_VAR, | |
| 665 STM_IF, | |
| 666 STM_DO, | |
| 667 STM_WHILE, | |
| 668 STM_FOR, | |
| 669 STM_FOR_VAR, | |
| 670 STM_FOR_IN, | |
| 671 STM_FOR_IN_VAR, | |
| 672 STM_CONTINUE, | |
| 673 STM_BREAK, | |
| 674 STM_RETURN, | |
| 675 STM_WITH, | |
| 676 STM_SWITCH, | |
| 677 STM_THROW, | |
| 678 STM_TRY, | |
| 679 STM_DEBUGGER, | |
| 680 | |
| 681 STM_LABEL, | |
| 682 STM_CASE, | |
| 683 STM_DEFAULT, | |
| 684 }; | |
| 685 | |
| 686 typedef struct js_JumpList js_JumpList; | |
| 687 | |
| 688 struct js_JumpList | |
| 689 { | |
| 690 enum js_AstType type; | |
| 691 int inst; | |
| 692 js_JumpList *next; | |
| 693 }; | |
| 694 | |
| 695 struct js_Ast | |
| 696 { | |
| 697 enum js_AstType type; | |
| 698 int line; | |
| 699 js_Ast *parent, *a, *b, *c, *d; | |
| 700 double number; | |
| 701 const char *string; | |
| 702 js_JumpList *jumps; /* list of break/continue jumps to patch */ | |
| 703 int casejump; /* for switch case clauses */ | |
| 704 js_Ast *gcnext; /* next in alloc list */ | |
| 705 }; | |
| 706 | |
| 707 js_Ast *jsP_parsefunction(js_State *J, const char *filename, const char *params, const char *body); | |
| 708 js_Ast *jsP_parse(js_State *J, const char *filename, const char *source); | |
| 709 void jsP_freeparse(js_State *J); | |
| 710 | |
| 711 /* Compiler */ | |
| 712 | |
| 713 enum js_OpCode | |
| 714 { | |
| 715 OP_POP, /* A -- */ | |
| 716 OP_DUP, /* A -- A A */ | |
| 717 OP_DUP2, /* A B -- A B A B */ | |
| 718 OP_ROT2, /* A B -- B A */ | |
| 719 OP_ROT3, /* A B C -- C A B */ | |
| 720 OP_ROT4, /* A B C D -- D A B C */ | |
| 721 | |
| 722 OP_INTEGER, /* -K- (number-32768) */ | |
| 723 OP_NUMBER, /* -N- <number> */ | |
| 724 OP_STRING, /* -S- <string> */ | |
| 725 OP_CLOSURE, /* -F- <closure> */ | |
| 726 | |
| 727 OP_NEWARRAY, | |
| 728 OP_NEWOBJECT, | |
| 729 OP_NEWREGEXP, /* -S,opts- <regexp> */ | |
| 730 | |
| 731 OP_UNDEF, | |
| 732 OP_NULL, | |
| 733 OP_TRUE, | |
| 734 OP_FALSE, | |
| 735 | |
| 736 OP_THIS, | |
| 737 OP_CURRENT, /* currently executing function object */ | |
| 738 | |
| 739 OP_GETLOCAL, /* -K- <value> */ | |
| 740 OP_SETLOCAL, /* <value> -K- <value> */ | |
| 741 OP_DELLOCAL, /* -K- false */ | |
| 742 | |
| 743 OP_HASVAR, /* -S- ( <value> | undefined ) */ | |
| 744 OP_GETVAR, /* -S- <value> */ | |
| 745 OP_SETVAR, /* <value> -S- <value> */ | |
| 746 OP_DELVAR, /* -S- <success> */ | |
| 747 | |
| 748 OP_IN, /* <name> <obj> -- <exists?> */ | |
| 749 | |
| 750 OP_SKIPARRAY, /* <obj> -- <obj> */ | |
| 751 OP_INITARRAY, /* <obj> <val> -- <obj> */ | |
| 752 OP_INITPROP, /* <obj> <key> <val> -- <obj> */ | |
| 753 OP_INITGETTER, /* <obj> <key> <closure> -- <obj> */ | |
| 754 OP_INITSETTER, /* <obj> <key> <closure> -- <obj> */ | |
| 755 | |
| 756 OP_GETPROP, /* <obj> <name> -- <value> */ | |
| 757 OP_GETPROP_S, /* <obj> -S- <value> */ | |
| 758 OP_SETPROP, /* <obj> <name> <value> -- <value> */ | |
| 759 OP_SETPROP_S, /* <obj> <value> -S- <value> */ | |
| 760 OP_DELPROP, /* <obj> <name> -- <success> */ | |
| 761 OP_DELPROP_S, /* <obj> -S- <success> */ | |
| 762 | |
| 763 OP_ITERATOR, /* <obj> -- <iobj> */ | |
| 764 OP_NEXTITER, /* <iobj> -- ( <iobj> <name> true | false ) */ | |
| 765 | |
| 766 OP_EVAL, /* <args...> -(numargs)- <returnvalue> */ | |
| 767 OP_CALL, /* <closure> <this> <args...> -(numargs)- <returnvalue> */ | |
| 768 OP_NEW, /* <closure> <args...> -(numargs)- <returnvalue> */ | |
| 769 | |
| 770 OP_TYPEOF, | |
| 771 OP_POS, | |
| 772 OP_NEG, | |
| 773 OP_BITNOT, | |
| 774 OP_LOGNOT, | |
| 775 OP_INC, /* <x> -- ToNumber(x)+1 */ | |
| 776 OP_DEC, /* <x> -- ToNumber(x)-1 */ | |
| 777 OP_POSTINC, /* <x> -- ToNumber(x)+1 ToNumber(x) */ | |
| 778 OP_POSTDEC, /* <x> -- ToNumber(x)-1 ToNumber(x) */ | |
| 779 | |
| 780 OP_MUL, | |
| 781 OP_DIV, | |
| 782 OP_MOD, | |
| 783 OP_ADD, | |
| 784 OP_SUB, | |
| 785 OP_SHL, | |
| 786 OP_SHR, | |
| 787 OP_USHR, | |
| 788 OP_LT, | |
| 789 OP_GT, | |
| 790 OP_LE, | |
| 791 OP_GE, | |
| 792 OP_EQ, | |
| 793 OP_NE, | |
| 794 OP_STRICTEQ, | |
| 795 OP_STRICTNE, | |
| 796 OP_JCASE, | |
| 797 OP_BITAND, | |
| 798 OP_BITXOR, | |
| 799 OP_BITOR, | |
| 800 | |
| 801 OP_INSTANCEOF, | |
| 802 | |
| 803 OP_THROW, | |
| 804 | |
| 805 OP_TRY, /* -ADDR- /jump/ or -ADDR- <exception> */ | |
| 806 OP_ENDTRY, | |
| 807 | |
| 808 OP_CATCH, /* push scope chain with exception variable */ | |
| 809 OP_ENDCATCH, | |
| 810 | |
| 811 OP_WITH, | |
| 812 OP_ENDWITH, | |
| 813 | |
| 814 OP_DEBUGGER, | |
| 815 OP_JUMP, | |
| 816 OP_JTRUE, | |
| 817 OP_JFALSE, | |
| 818 OP_RETURN, | |
| 819 }; | |
| 820 | |
| 821 struct js_Function | |
| 822 { | |
| 823 const char *name; | |
| 824 int script; | |
| 825 int lightweight; | |
| 826 int strict; | |
| 827 int arguments; | |
| 828 int numparams; | |
| 829 | |
| 830 js_Instruction *code; | |
| 831 int codecap, codelen; | |
| 832 | |
| 833 js_Function **funtab; | |
| 834 int funcap, funlen; | |
| 835 | |
| 836 const char **vartab; | |
| 837 int varcap, varlen; | |
| 838 | |
| 839 const char *filename; | |
| 840 int line, lastline; | |
| 841 | |
| 842 js_Function *gcnext; | |
| 843 int gcmark; | |
| 844 }; | |
| 845 | |
| 846 js_Function *jsC_compilefunction(js_State *J, js_Ast *prog); | |
| 847 js_Function *jsC_compilescript(js_State *J, js_Ast *prog, int default_strict); | |
| 848 | |
| 849 /* Builtins */ | |
| 850 | |
| 851 void jsB_init(js_State *J); | |
| 852 void jsB_initobject(js_State *J); | |
| 853 void jsB_initarray(js_State *J); | |
| 854 void jsB_initfunction(js_State *J); | |
| 855 void jsB_initboolean(js_State *J); | |
| 856 void jsB_initnumber(js_State *J); | |
| 857 void jsB_initstring(js_State *J); | |
| 858 void jsB_initregexp(js_State *J); | |
| 859 void jsB_initerror(js_State *J); | |
| 860 void jsB_initmath(js_State *J); | |
| 861 void jsB_initjson(js_State *J); | |
| 862 void jsB_initdate(js_State *J); | |
| 863 | |
| 864 void jsB_propf(js_State *J, const char *name, js_CFunction cfun, int n); | |
| 865 void jsB_propn(js_State *J, const char *name, double number); | |
| 866 void jsB_props(js_State *J, const char *name, const char *string); | |
| 867 | |
| 868 #endif |
