42 #if defined(__APPLE__)
43 #include <crt_externs.h>
48 #if defined(WITH_GPSEE)
50 #define JS_THREADSAFE 1
55 typedef gpsee_interpreter_t *
JSI_t;
56 #define _RPMJS_OPTIONS \
57 (JSOPTION_STRICT | JSOPTION_RELIMIT | JSOPTION_ANONFUNFIX | JSOPTION_JIT)
62 #define _RPMJS_OPTIONS 0
66 #define _RPMJS_INTERNAL
71 #define F_ISSET(_flags, _FLAG) ((_flags) & RPMJS_FLAGS_##_FLAG)
76 #define RPMJSDBG(_t, _l) \
77 if ((_t) || _rpmjs_debug) fprintf _l
91 {
"allow",
'a', POPT_BIT_SET, &
_rpmjs.flags, RPMJS_FLAGS_ALLOW,
92 N_(
"Allow (read-only) access to caller's environmen"), NULL },
93 {
"nocache",
'C', POPT_BIT_SET, &
_rpmjs.flags, RPMJS_FLAGS_NOCACHE,
94 N_(
"Disables compiler caching via JSScript XDR serialization"), NULL },
95 {
"loadrc",
'R', POPT_BIT_SET, &
_rpmjs.flags, RPMJS_FLAGS_LOADRC,
96 N_(
"Load RC file for interpreter based on script filename."), NULL },
97 {
"nowarn",
'W', POPT_BIT_SET, &
_rpmjs.flags, RPMJS_FLAGS_NOWARN,
98 N_(
"Do not report warnings"), NULL },
100 {
"norelimit",
'e', POPT_BIT_CLR, &
_rpmjs.flags, RPMJS_FLAGS_RELIMIT,
101 N_(
"Do not limit regexps to n^3 levels of backtracking"), NULL },
102 {
"nojit",
'J', POPT_BIT_CLR, &
_rpmjs.flags, RPMJS_FLAGS_JIT,
103 N_(
"Disable nanojit"), NULL },
104 {
"nostrict",
'S', POPT_BIT_CLR, &
_rpmjs.flags, RPMJS_FLAGS_STRICT,
105 N_(
"Disable Strict mode"), NULL },
106 {
"noutf8",
'U', POPT_BIT_SET, &
_rpmjs.flags, RPMJS_FLAGS_NOUTF8,
107 N_(
"Disable UTF-8 C string processing"), NULL },
108 {
"xml",
'x', POPT_BIT_SET, &
_rpmjs.flags, RPMJS_FLAGS_XML,
109 N_(
"Parse <!-- comments --> as E4X tokens"), NULL },
111 {
"anonfunfix",
'\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN, &
_rpmjs.flags, RPMJS_FLAGS_ANONFUNFIX,
112 N_(
"Parse //@line number [\"filename\"] for XUL"), NULL },
113 {
"atline",
'A', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN, &
_rpmjs.flags, RPMJS_FLAGS_ATLINE,
114 N_(
"Parse //@line number [\"filename\"] for XUL"), NULL },
115 {
"werror",
'w', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN, &
_rpmjs.flags, RPMJS_FLAGS_WERROR,
116 N_(
"Convert warnings to errors"), NULL },
127 RPMJSDBG(0, (stderr,
"==> %s(%p) I %p\n", __FUNCTION__, js, js->I));
129 #if defined(WITH_GPSEE)
130 #if defined(XXX_GPSEE_DEBUGGER)
131 gpsee_finiDebugger(js->jsdc);
134 (void) gpsee_destroyInterpreter(js->I);
148 if (_rpmjsPool == NULL) {
161 #if defined(WITH_GPSEE)
175 (flags & 0x80000000) ?
rpmjsI() :
180 #if defined(WITH_GPSEE)
182 #if defined(XXX_GPSEE_DEBUGGER)
189 if (
F_ISSET(flags, NOUTF8) ||
getenv(
"GPSEE_NO_UTF8_C_STRINGS")) {
190 JS_DestroyRuntime(JS_NewRuntime(1024));
191 putenv((
char *)
"GPSEE_NO_UTF8_C_STRINGS=1");
195 I = gpsee_createInterpreter();
196 #if defined(XXX_GPSEE_DEBUGGER)
197 js->jsdc = gpsee_initDebugger(I->cx, I->realm, DEBUGGER_JS);
202 I->useCompilerCache = 0;
205 gpsee_runtime_t * grt = JS_GetRuntimePrivate(JS_GetRuntime(I->cx));
206 grt->errorReport |= er_noWarnings;
209 JS_SetOptions(I->cx, (flags & 0xffff));
210 #if defined(JS_GC_ZEAL)
221 #if defined(WITH_GPSEE)
222 static FILE * rpmjsOpenFile(
rpmjs js,
const char * fn,
const char ** msgp)
228 if (fp == NULL || ferror(fp)) {
236 *msgp =
xstrdup(
"unknown error");
241 gpsee_flock(fileno(fp), GPSEE_LOCK_SH);
243 if (
F_ISSET(js->flags, SKIPSHEBANG)) {
246 if (fgets(buf,
sizeof(buf), fp)) {
247 if (!(buf[0] ==
'#' && buf[1] ==
'!')) {
254 gpsee_interpreter_t * I = js->I;
255 I->linenoOffset += 1;
258 if (strchr(buf,
'\n'))
260 }
while (fgets(buf,
sizeof(buf), fp));
272 RPMJSDBG(0, (stderr,
"<== %s(%p,%s,%p) fp %p\n", __FUNCTION__, js, fn, msgp, fp));
278 static void processInlineFlags(
rpmjs js, FILE * fp,
signed int *verbosity_p)
285 while (fgets(buf,
sizeof(buf), fp)) {
288 if ((buf[0] !=
'/') || (buf[1] !=
'/'))
291 for (s = buf + 2; *s ==
' ' || *s ==
'\t'; s++);
292 if (strncmp(s,
"gpsee:", 6) != 0)
295 for (s = s + 6; *s ==
' ' || *s ==
'\t'; s++);
297 for (e = s; *e; e++) {
309 processFlags(gsr, s, verbosity_p);
319 const char ** resultp)
323 if (js == NULL) js =
rpmjsI();
326 #if defined(WITH_GPSEE)
327 gpsee_interpreter_t * I = js->I;
328 FILE * fp = rpmjsOpenFile(js, fn, resultp);
331 I->grt->exitType = et_execFailure;
337 processInlineFlags(js, fp, &verbosity);
338 gpsee_setVerbosity(verbosity);
342 if (
F_ISSET(js->flags, NOEXEC)) {
343 JSScript *script = NULL;
344 JSObject *scrobj = NULL;
346 if (!gpsee_compileScript(I->cx, fn,
347 fp, NULL, &script, I->realm->globalObject, &scrobj))
349 I->grt->exitType = et_exception;
351 gpsee_reportUncaughtException(I->cx, JSVAL_NULL,
352 (gpsee_verbosity(0) >= GSR_FORCE_STACK_DUMP_VERBOSITY)
354 ((gpsee_verbosity(0) >= GPSEE_ERROR_OUTPUT_VERBOSITY)
355 && isatty(STDERR_FILENO)));
357 I->grt->exitType = et_finished;
361 char *
const * Ienviron = NULL;
363 if (
F_ISSET(js->flags, ALLOW)) {
364 #if defined(__APPLE__)
365 Ienviron = (
char *
const *) _NSGetEnviron();
371 I->grt->exitType = et_execFailure;
372 if (gpsee_runProgramModule(I->cx, fn,
373 NULL, fp, Iargv, Ienviron) == JS_FALSE)
375 int code = gpsee_getExceptionExitCode(I->cx);
377 I->grt->exitType = et_requested;
378 I->grt->exitCode =
code;
383 if (JS_IsExceptionPending(I->cx)) {
385 gpsee_reportUncaughtException(I->cx, JSVAL_NULL,
386 (gpsee_verbosity(0) >= GSR_FORCE_STACK_DUMP_VERBOSITY)
388 ((gpsee_verbosity(0) >= GPSEE_ERROR_OUTPUT_VERBOSITY)
389 && isatty(STDERR_FILENO)));
392 I->grt->exitType = et_finished;
401 #if defined(WITH_GPSEE)
405 RPMJSDBG(0, (stderr,
"<== %s(%p,%s) rc %d |%s|\n", __FUNCTION__, js, fn, rc, (resultp ? *resultp :
"")));
417 if (js == NULL) js =
rpmjsI();
419 #if defined(WITH_GPSEE)
420 { gpsee_interpreter_t * I = js->I;
421 jsval
v = JSVAL_VOID;
422 JSBool ok = JS_EvaluateScript(I->cx, I->realm->globalObject,
423 str, strlen(str), __FILE__, __LINE__, &v);
427 if (resultp && JSVAL_IS_STRING(v)) {
428 JSString * rstr = JSVAL_TO_STRING(v);
429 size_t ns = JS_GetStringEncodingLength(I->cx, rstr);
431 ns = JS_EncodeStringToBuffer(rstr, s, ns);
439 RPMJSDBG(0, (stderr,
"<== %s(%p,%p[%u]) rc %d\n", __FUNCTION__, js, str, (
unsigned)(str ? strlen(str) : 0), rc));
rpmjs rpmjsLink(rpmjs js)
Reference a js interpreter instance.
char * getenv(const char *name)
struct poptOption rpmjsIPoptTable[]
char * xstrdup(const char *str)
static rpmjs rpmjsI(void)
static void rpmlog(int code, const char *fmt,...)
const char const bson_bool_t v
rpmioItem rpmioGetPool(rpmioPool pool, size_t size)
Get unused item from pool, or alloc a new item.
rpmjs rpmjsNew(char **av, uint32_t flags)
Create and load a js interpreter.
rpmRC rpmjsRunFile(rpmjs js, const char *fn, char *const *Iargv, const char **resultp)
Execute js from a file.
static void rpmjsFini(void *_js)
const char const bson int mongo_write_concern int flags
enum rpmRC_e rpmRC
RPM return codes.
rpmioPool rpmioNewPool(const char *name, size_t size, int limit, int flags, char *(*dbg)(void *item), void(*init)(void *item), void(*fini)(void *item))
Create a memory pool.
static rpmjs rpmjsGetPool(rpmioPool pool)
const char const char * code
rpmRC rpmjsRun(rpmjs js, const char *str, const char **resultp)
Execute js string.
#define F_ISSET(_flags, _FLAG)