Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/mujs/jsstate.c @ 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 #include "jsi.h" | |
| 2 | |
| 3 #include <assert.h> | |
| 4 #include <errno.h> | |
| 5 | |
| 6 static int js_ptry(js_State *J) { | |
| 7 if (J->trytop == JS_TRYLIMIT) { | |
| 8 J->stack[J->top].t.type = JS_TLITSTR; | |
| 9 J->stack[J->top].u.litstr = "exception stack overflow"; | |
| 10 ++J->top; | |
| 11 return 1; | |
| 12 } | |
| 13 return 0; | |
| 14 } | |
| 15 | |
| 16 static void *js_defaultalloc(void *actx, void *ptr, int size) | |
| 17 { | |
| 18 if (size == 0) { | |
| 19 free(ptr); | |
| 20 return NULL; | |
| 21 } | |
| 22 return realloc(ptr, (size_t)size); | |
| 23 } | |
| 24 | |
| 25 static void js_defaultreport(js_State *J, const char *message) | |
| 26 { | |
| 27 fputs(message, stderr); | |
| 28 fputc('\n', stderr); | |
| 29 } | |
| 30 | |
| 31 static void js_defaultpanic(js_State *J) | |
| 32 { | |
| 33 js_report(J, "uncaught exception"); | |
| 34 /* return to javascript to abort */ | |
| 35 } | |
| 36 | |
| 37 int js_ploadstring(js_State *J, const char *filename, const char *source) | |
| 38 { | |
| 39 if (js_ptry(J)) | |
| 40 return 1; | |
| 41 if (js_try(J)) | |
| 42 return 1; | |
| 43 js_loadstring(J, filename, source); | |
| 44 js_endtry(J); | |
| 45 return 0; | |
| 46 } | |
| 47 | |
| 48 int js_ploadfile(js_State *J, const char *filename) | |
| 49 { | |
| 50 if (js_ptry(J)) | |
| 51 return 1; | |
| 52 if (js_try(J)) | |
| 53 return 1; | |
| 54 js_loadfile(J, filename); | |
| 55 js_endtry(J); | |
| 56 return 0; | |
| 57 } | |
| 58 | |
| 59 const char *js_trystring(js_State *J, int idx, const char *error) | |
| 60 { | |
| 61 const char *s; | |
| 62 if (js_ptry(J)) { | |
| 63 js_pop(J, 1); | |
| 64 return error; | |
| 65 } | |
| 66 if (js_try(J)) { | |
| 67 js_pop(J, 1); | |
| 68 return error; | |
| 69 } | |
| 70 s = js_tostring(J, idx); | |
| 71 js_endtry(J); | |
| 72 return s; | |
| 73 } | |
| 74 | |
| 75 double js_trynumber(js_State *J, int idx, double error) | |
| 76 { | |
| 77 double v; | |
| 78 if (js_ptry(J)) { | |
| 79 js_pop(J, 1); | |
| 80 return error; | |
| 81 } | |
| 82 if (js_try(J)) { | |
| 83 js_pop(J, 1); | |
| 84 return error; | |
| 85 } | |
| 86 v = js_tonumber(J, idx); | |
| 87 js_endtry(J); | |
| 88 return v; | |
| 89 } | |
| 90 | |
| 91 int js_tryinteger(js_State *J, int idx, int error) | |
| 92 { | |
| 93 int v; | |
| 94 if (js_ptry(J)) { | |
| 95 js_pop(J, 1); | |
| 96 return error; | |
| 97 } | |
| 98 if (js_try(J)) { | |
| 99 js_pop(J, 1); | |
| 100 return error; | |
| 101 } | |
| 102 v = js_tointeger(J, idx); | |
| 103 js_endtry(J); | |
| 104 return v; | |
| 105 } | |
| 106 | |
| 107 int js_tryboolean(js_State *J, int idx, int error) | |
| 108 { | |
| 109 int v; | |
| 110 if (js_ptry(J)) { | |
| 111 js_pop(J, 1); | |
| 112 return error; | |
| 113 } | |
| 114 if (js_try(J)) { | |
| 115 js_pop(J, 1); | |
| 116 return error; | |
| 117 } | |
| 118 v = js_toboolean(J, idx); | |
| 119 js_endtry(J); | |
| 120 return v; | |
| 121 } | |
| 122 | |
| 123 static void js_loadstringx(js_State *J, const char *filename, const char *source, int iseval) | |
| 124 { | |
| 125 js_Ast *P; | |
| 126 js_Function *F; | |
| 127 | |
| 128 if (js_try(J)) { | |
| 129 jsP_freeparse(J); | |
| 130 js_throw(J); | |
| 131 } | |
| 132 | |
| 133 P = jsP_parse(J, filename, source); | |
| 134 F = jsC_compilescript(J, P, iseval ? J->strict : J->default_strict); | |
| 135 jsP_freeparse(J); | |
| 136 js_newscript(J, F, iseval ? (J->strict ? J->E : NULL) : J->GE); | |
| 137 | |
| 138 js_endtry(J); | |
| 139 } | |
| 140 | |
| 141 void js_loadeval(js_State *J, const char *filename, const char *source) | |
| 142 { | |
| 143 js_loadstringx(J, filename, source, 1); | |
| 144 } | |
| 145 | |
| 146 void js_loadstring(js_State *J, const char *filename, const char *source) | |
| 147 { | |
| 148 js_loadstringx(J, filename, source, 0); | |
| 149 } | |
| 150 | |
| 151 void js_loadfile(js_State *J, const char *filename) | |
| 152 { | |
| 153 FILE *f; | |
| 154 char *s, *p; | |
| 155 int n, t; | |
| 156 | |
| 157 f = fopen(filename, "rb"); | |
| 158 if (!f) { | |
| 159 js_error(J, "cannot open file '%s': %s", filename, strerror(errno)); | |
| 160 } | |
| 161 | |
| 162 if (fseek(f, 0, SEEK_END) < 0) { | |
| 163 fclose(f); | |
| 164 js_error(J, "cannot seek in file '%s': %s", filename, strerror(errno)); | |
| 165 } | |
| 166 | |
| 167 n = ftell(f); | |
| 168 if (n < 0) { | |
| 169 fclose(f); | |
| 170 js_error(J, "cannot tell in file '%s': %s", filename, strerror(errno)); | |
| 171 } | |
| 172 | |
| 173 if (fseek(f, 0, SEEK_SET) < 0) { | |
| 174 fclose(f); | |
| 175 js_error(J, "cannot seek in file '%s': %s", filename, strerror(errno)); | |
| 176 } | |
| 177 | |
| 178 if (js_try(J)) { | |
| 179 fclose(f); | |
| 180 js_throw(J); | |
| 181 } | |
| 182 s = js_malloc(J, n + 1); /* add space for string terminator */ | |
| 183 js_endtry(J); | |
| 184 | |
| 185 t = fread(s, 1, (size_t)n, f); | |
| 186 if (t != n) { | |
| 187 js_free(J, s); | |
| 188 fclose(f); | |
| 189 js_error(J, "cannot read data from file '%s': %s", filename, strerror(errno)); | |
| 190 } | |
| 191 | |
| 192 s[n] = 0; /* zero-terminate string containing file data */ | |
| 193 | |
| 194 if (js_try(J)) { | |
| 195 js_free(J, s); | |
| 196 fclose(f); | |
| 197 js_throw(J); | |
| 198 } | |
| 199 | |
| 200 /* skip first line if it starts with "#!" */ | |
| 201 p = s; | |
| 202 if (p[0] == '#' && p[1] == '!') { | |
| 203 p += 2; | |
| 204 while (*p && *p != '\n') | |
| 205 ++p; | |
| 206 } | |
| 207 | |
| 208 js_loadstring(J, filename, p); | |
| 209 | |
| 210 js_free(J, s); | |
| 211 fclose(f); | |
| 212 js_endtry(J); | |
| 213 } | |
| 214 | |
| 215 int js_dostring(js_State *J, const char *source) | |
| 216 { | |
| 217 if (js_ptry(J)) { | |
| 218 js_report(J, "exception stack overflow"); | |
| 219 js_pop(J, 1); | |
| 220 return 1; | |
| 221 } | |
| 222 if (js_try(J)) { | |
| 223 js_report(J, js_trystring(J, -1, "Error")); | |
| 224 js_pop(J, 1); | |
| 225 return 1; | |
| 226 } | |
| 227 js_loadstring(J, "[string]", source); | |
| 228 js_pushundefined(J); | |
| 229 js_call(J, 0); | |
| 230 js_pop(J, 1); | |
| 231 js_endtry(J); | |
| 232 return 0; | |
| 233 } | |
| 234 | |
| 235 int js_dofile(js_State *J, const char *filename) | |
| 236 { | |
| 237 if (js_ptry(J)) { | |
| 238 js_report(J, "exception stack overflow"); | |
| 239 js_pop(J, 1); | |
| 240 return 1; | |
| 241 } | |
| 242 if (js_try(J)) { | |
| 243 js_report(J, js_trystring(J, -1, "Error")); | |
| 244 js_pop(J, 1); | |
| 245 return 1; | |
| 246 } | |
| 247 js_loadfile(J, filename); | |
| 248 js_pushundefined(J); | |
| 249 js_call(J, 0); | |
| 250 js_pop(J, 1); | |
| 251 js_endtry(J); | |
| 252 return 0; | |
| 253 } | |
| 254 | |
| 255 js_Panic js_atpanic(js_State *J, js_Panic panic) | |
| 256 { | |
| 257 js_Panic old = J->panic; | |
| 258 J->panic = panic; | |
| 259 return old; | |
| 260 } | |
| 261 | |
| 262 void js_report(js_State *J, const char *message) | |
| 263 { | |
| 264 if (J->report) | |
| 265 J->report(J, message); | |
| 266 } | |
| 267 | |
| 268 void js_setreport(js_State *J, js_Report report) | |
| 269 { | |
| 270 J->report = report; | |
| 271 } | |
| 272 | |
| 273 void js_setcontext(js_State *J, void *uctx) | |
| 274 { | |
| 275 J->uctx = uctx; | |
| 276 } | |
| 277 | |
| 278 void *js_getcontext(js_State *J) | |
| 279 { | |
| 280 return J->uctx; | |
| 281 } | |
| 282 | |
| 283 js_State *js_newstate(js_Alloc alloc, void *actx, int flags) | |
| 284 { | |
| 285 js_State *J; | |
| 286 | |
| 287 assert(sizeof(js_Value) == 16); | |
| 288 assert(soffsetof(js_Value, t.type) == 15); | |
| 289 | |
| 290 if (!alloc) | |
| 291 alloc = js_defaultalloc; | |
| 292 | |
| 293 J = alloc(actx, NULL, sizeof *J); | |
| 294 if (!J) | |
| 295 return NULL; | |
| 296 memset(J, 0, sizeof(*J)); | |
| 297 J->actx = actx; | |
| 298 J->alloc = alloc; | |
| 299 | |
| 300 if (flags & JS_STRICT) | |
| 301 J->strict = J->default_strict = 1; | |
| 302 | |
| 303 J->trace[0].name = "-top-"; | |
| 304 J->trace[0].file = "native"; | |
| 305 J->trace[0].line = 0; | |
| 306 | |
| 307 J->report = js_defaultreport; | |
| 308 J->panic = js_defaultpanic; | |
| 309 | |
| 310 J->stack = alloc(actx, NULL, JS_STACKSIZE * sizeof *J->stack); | |
| 311 if (!J->stack) { | |
| 312 alloc(actx, J, 0); | |
| 313 return NULL; | |
| 314 } | |
| 315 | |
| 316 J->gcmark = 1; | |
| 317 J->nextref = 0; | |
| 318 J->gcthresh = 0; /* reaches stability within ~ 2-5 GC cycles */ | |
| 319 | |
| 320 if (js_try(J)) { | |
| 321 js_freestate(J); | |
| 322 return NULL; | |
| 323 } | |
| 324 | |
| 325 J->R = jsV_newobject(J, JS_COBJECT, NULL); | |
| 326 J->G = jsV_newobject(J, JS_COBJECT, NULL); | |
| 327 J->E = jsR_newenvironment(J, J->G, NULL); | |
| 328 J->GE = J->E; | |
| 329 | |
| 330 jsB_init(J); | |
| 331 | |
| 332 js_endtry(J); | |
| 333 return J; | |
| 334 } |
