RPM Package Manager, CVS Repository
  http://rpm5.org/cvs/
  ____________________________________________________________________________

  Server: rpm5.org                         Name:   Jeff Johnson
  Root:   /v/rpm/cvs                       Email:  j...@rpm5.org
  Module: rpm                              Date:   23-Jun-2017 05:39:44
  Branch: rpm-5_4                          Handle: 2017062303394301

  Added files:              (Branch: rpm-5_4)
    rpm/rpmio               rpmjss.h
  Modified files:           (Branch: rpm-5_4)
    rpm/rpmio               Makefile.am rpmjs17.cpp rpmjs185.cpp rpmjs24.cpp
                            rpmjs31.cpp rpmjs38.cpp rpmjs45.cpp

  Log:
    - rpmjss: avoid "namesapce js" collision.

  Summary:
    Revision    Changes     Path
    1.293.2.98  +7  -7      rpm/rpmio/Makefile.am
    1.1.2.4     +419 -43    rpm/rpmio/rpmjs17.cpp
    1.1.2.4     +389 -32    rpm/rpmio/rpmjs185.cpp
    1.1.2.5     +38 -28     rpm/rpmio/rpmjs24.cpp
    1.1.2.5     +33 -28     rpm/rpmio/rpmjs31.cpp
    1.1.2.5     +33 -28     rpm/rpmio/rpmjs38.cpp
    1.1.2.6     +679 -61    rpm/rpmio/rpmjs45.cpp
    1.1.2.1     +141 -0     rpm/rpmio/rpmjss.h
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: rpm/rpmio/Makefile.am
  ============================================================================
  $ cvs diff -u -r1.293.2.97 -r1.293.2.98 Makefile.am
  --- rpm/rpmio/Makefile.am     23 Jun 2017 00:43:55 -0000      1.293.2.97
  +++ rpm/rpmio/Makefile.am     23 Jun 2017 03:39:43 -0000      1.293.2.98
  @@ -551,27 +551,27 @@
   rpmgpg_LDADD = $(RPMIO_LDADD_COMMON)
   
   rpmjs185_SOURCES = rpmjs185.cpp
  -rpmjs185_CPPFLAGS = -DXP_UNIX=1 -DJS_THREADSAFE=1 -I/usr/include/js -fPIC 
-DRPMJS_SELF_TEST
  +rpmjs185_CPPFLAGS = -DXP_UNIX=1 -DJS_THREADSAFE=1 -I/usr/include/js -fPIC 
-DRPMJSS_SELF_TEST
   rpmjs185_LDADD = -L/usr/lib64 -ljs
   
   rpmjs17_SOURCES = rpmjs17.cpp
  -rpmjs17_CPPFLAGS = -include /usr/include/js-17.0/js/RequiredDefines.h 
-I/usr/include/js-17.0 -fPIC -DRPMJS_SELF_TEST
  +rpmjs17_CPPFLAGS = -include /usr/include/js-17.0/js/RequiredDefines.h 
-I/usr/include/js-17.0 -fPIC -DRPMJSS_SELF_TEST
   rpmjs17_LDADD = -L/usr/lib64 -lmozjs-17.0
   
   rpmjs24_SOURCES = rpmjs24.cpp
  -rpmjs24_CPPFLAGS = -include /usr/include/mozjs-24/js/RequiredDefines.h 
-I/usr/include/mozjs-24 -fPIC -DRPMJS_SELF_TEST
  +rpmjs24_CPPFLAGS = -include /usr/include/mozjs-24/js/RequiredDefines.h 
-I/usr/include/mozjs-24 -fPIC -DRPMJSS_SELF_TEST
   rpmjs24_LDADD = -L/usr/lib64 -lmozjs-24
   
   rpmjs31_SOURCES = rpmjs31.cpp
  -rpmjs31_CPPFLAGS = -include /usr/include/mozjs-31/js/RequiredDefines.h 
-I/usr/include/mozjs-31 -fPIC -DRPMJS_SELF_TEST
  +rpmjs31_CPPFLAGS = -include /usr/include/mozjs-31/js/RequiredDefines.h 
-I/usr/include/mozjs-31 -fPIC -DRPMJSS_SELF_TEST
   rpmjs31_LDADD = -L/usr/lib64 -lmozjs-31
   
   rpmjs38_SOURCES = rpmjs38.cpp
  -rpmjs38_CPPFLAGS = -include /usr/include/mozjs-38/js/RequiredDefines.h 
-I/usr/include/mozjs-38 -fPIC -DRPMJS_SELF_TEST
  +rpmjs38_CPPFLAGS = -include /usr/include/mozjs-38/js/RequiredDefines.h 
-I/usr/include/mozjs-38 -fPIC -DRPMJSS_SELF_TEST
   rpmjs38_LDADD = -L/usr/lib64 -lmozjs-38
   
   rpmjs45_SOURCES = rpmjs45.cpp
  -rpmjs45_CPPFLAGS = -include /usr/include/mozjs-45/js/RequiredDefines.h 
-I/usr/include/mozjs-45 -fPIC -DRPMJS_SELF_TEST
  +rpmjs45_CPPFLAGS = -include /usr/include/mozjs-45/js/RequiredDefines.h 
-I/usr/include/mozjs-45 -fPIC -DRPMJSS_SELF_TEST
   rpmjs45_LDADD = -L/usr/lib64 -lmozjs-45
   
   mozjs:       rpmjs185 rpmjs17 rpmjs24 rpmjs31 rpmjs38 rpmjs45
  @@ -582,7 +582,7 @@
        -./rpmjs38
        -./rpmjs45
   
  -mozjs45: rpmjs45
  +moz45:       rpmjs45
        @-env ASAN_OPTIONS=detect_leaks=0 ./rpmjs45
   
   rpmpbzip2_SOURCES = rpmpbzip2.c
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/rpmjs17.cpp
  ============================================================================
  $ cvs diff -u -r1.1.2.3 -r1.1.2.4 rpmjs17.cpp
  --- rpm/rpmio/rpmjs17.cpp     22 Jun 2017 17:35:24 -0000      1.1.2.3
  +++ rpm/rpmio/rpmjs17.cpp     23 Jun 2017 03:39:43 -0000      1.1.2.4
  @@ -2,14 +2,14 @@
   // #define __STDC_LIMIT_MACROS
   // #include <stdint.h>
   
  +#pragma GCC diagnostic ignored "-Winvalid-offsetof"
  +
   #include "system.h"
   
  -#define      js      jsns
   #include "jsapi.h"
  -#undef       js
   
  -#define      _RPMJS_INTERNAL
  -#include <rpmjs.h>
  +#define      _RPMJSS_INTERNAL
  +#include <rpmjss.h>
   
   #include "debug.h"
   
  @@ -26,8 +26,12 @@
       JS_ConvertStub,
   };
   
  -struct rpmjs_s _js;
  -rpmjs js = &_js;
  +static int rpmjss_nopens;
  +
  +static int _rpmjss17_debug;
  +#define SPEW(_fmt, ...) \
  +    if (_rpmjss17_debug) \
  +     fprintf(stderr, _fmt, __VA_ARGS__)
   
   /*==============================================================*/
   typedef struct JSI_s * JSI_t;
  @@ -38,7 +42,7 @@
   };
   
   static void
  -rpmjsReportError(JSContext *cx, const char *message, JSErrorReport *report)
  +rpmjssReportError(JSContext *cx, const char *message, JSErrorReport *report)
   {
       fprintf(stderr, "%s:%u:%s\n",
        report->filename ? report->filename : "<no filename=\"filename\">",
  @@ -46,11 +50,371 @@
   }
   
   /*==============================================================*/
  -static int rpmjs_nopens;
  +static JSBool compileOnly = JS_FALSE;
   
  -static void mozFini(rpmjs js)
  +static JSBool
  +Version(JSContext *cx, unsigned argc, jsval *vp)
   {
  -    JSI_t I = (JSI_t) js->I;
  +    jsval *argv = JS_ARGV(cx, vp);
  +    if (argc > 0 && JSVAL_IS_INT(argv[0]))
  +        *vp = INT_TO_JSVAL(JS_SetVersion(cx, (JSVersion) 
JSVAL_TO_INT(argv[0])));
  +    else
  +        *vp = INT_TO_JSVAL(JS_GetVersion(cx));
  +    return JS_TRUE;
  +}
  +
  +static JSBool
  +Load(JSContext *cx, unsigned argc, jsval *vp)
  +{
  +#ifdef       FIXME
  +    jsval *argv = JS_ARGV(cx, vp);
  +    JSObject *thisobj = JS_THIS_OBJECT(cx, vp);
  +    if (!thisobj)
  +        return JS_FALSE;
  +
  +    for (unsigned i = 0; i < argc; i++) {
  +        JSString *str = JS_ValueToString(cx, argv[i]);
  +        if (!str)
  +            return false;
  +        argv[i] = STRING_TO_JSVAL(str);
  +        JSAutoByteString filename(cx, str);
  +        if (!filename)
  +            return JS_FALSE;
  +        errno = 0;
  +        uint32_t oldopts = JS_GetOptions(cx);
  +        JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | 
JSOPTION_NO_SCRIPT_RVAL);
  +        JSObject *scriptObj = JS_CompileFile(cx, thisobj, filename.ptr());
  +        JS_SetOptions(cx, oldopts);
  +        if (!scriptObj)
  +            return false;
  +
  +        if (!compileOnly && !JS_ExecuteScript(cx, thisobj, scriptObj, NULL))
  +            return false;
  +    }
  +
  +    return true;
  +#else
  +    return false;
  +#endif
  +}
  +
  +static JSBool
  +Evaluate(JSContext *cx, unsigned argc, jsval *vp)
  +{
  +#ifdef       FIXME
  +    if (argc != 1 || !JSVAL_IS_STRING(JS_ARGV(cx, vp)[0])) {
  +#ifdef       FIXME
  +        JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
  +                             (argc != 1) ? JSSMSG_NOT_ENOUGH_ARGS : 
JSSMSG_INVALID_ARGS,
  +                             "evaluate");
  +#endif       /* FIXME */
  +        return false;
  +    }
  +
  +    JSString *code = JSVAL_TO_STRING(JS_ARGV(cx, vp)[0]);
  +
  +    size_t codeLength;
  +    const jschar *codeChars = JS_GetStringCharsAndLength(cx, code, 
&codeLength);
  +    if (!codeChars)
  +        return false;
  +
  +    JSObject *thisobj = JS_THIS_OBJECT(cx, vp);
  +    if (!thisobj)
  +        return false;
  +
  +    if ((JS_GET_CLASS(cx, thisobj)->flags & JSCLASS_IS_GLOBAL) != 
JSCLASS_IS_GLOBAL) {
  +#ifdef       FIXME
  +        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, 
JSMSG_UNEXPECTED_TYPE,
  +                             "this-value passed to evaluate()", "not a 
global object");
  +#endif       /* FIXME */
  +        return false;
  +    }
  +
  +    JS_SET_RVAL(cx, vp, JSVAL_VOID);
  +    return JS_EvaluateUCScript(cx, thisobj, codeChars, codeLength, 
"@evaluate", 0, NULL);
  +#else        /* FIXME */
  +    return false;
  +#endif       /* FIXME */
  +}
  +
  +static JSString *
  +FileAsString(JSContext *cx, const char *pathname)
  +{
  +    FILE *file;
  +    JSString *str = NULL;
  +    size_t len, cc;
  +    char *buf;
  +
  +    file = fopen(pathname, "rb");
  +    if (!file) {
  +        JS_ReportError(cx, "can't open %s: %s", pathname, strerror(errno));
  +        return NULL;
  +    }
  +
  +    if (fseek(file, 0, SEEK_END) == EOF) {
  +        JS_ReportError(cx, "can't seek end of %s", pathname);
  +    } else {
  +        len = ftell(file);
  +        if (fseek(file, 0, SEEK_SET) == EOF) {
  +            JS_ReportError(cx, "can't seek start of %s", pathname);
  +        } else {
  +            buf = (char*) JS_malloc(cx, len + 1);
  +            if (buf) {
  +                cc = fread(buf, 1, len, file);
  +                if (cc != len) {
  +                    JS_ReportError(cx, "can't read %s: %s", pathname,
  +                                   (ptrdiff_t(cc) < 0) ? strerror(errno) : 
"short read");
  +                } else {
  +                    len = (size_t)cc;
  +                    str = JS_NewStringCopyN(cx, buf, len);
  +                }
  +                JS_free(cx, buf);
  +            }
  +        }
  +    }
  +    fclose(file);
  +
  +    return str;
  +}
  +
  +/*
  + * Function to run scripts and return compilation + execution time. Semantics
  + * are closely modelled after the equivalent function in WebKit, as this is 
used
  + * to produce benchmark timings by SunSpider.
  + */
  +static JSBool
  +Run(JSContext *cx, unsigned argc, jsval *vp)
  +{
  +#ifdef       FIXME
  +    if (argc != 1) {
  +#ifdef       FIXME
  +        JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, 
JSSMSG_INVALID_ARGS, "run");
  +#endif       /* FIXME */
  +        return false;
  +    }
  +
  +    JSObject *thisobj = JS_THIS_OBJECT(cx, vp);
  +    if (!thisobj)
  +        return false;
  +
  +    jsval *argv = JS_ARGV(cx, vp);
  +    JSString *str = JS_ValueToString(cx, argv[0]);
  +    if (!str)
  +        return false;
  +    argv[0] = STRING_TO_JSVAL(str);
  +    JSAutoByteString filename(cx, str);
  +    if (!filename)
  +        return false;
  +
  +    const jschar *ucbuf = NULL;
  +    size_t buflen;
  +    str = FileAsString(cx, filename.ptr());
  +    if (str)
  +        ucbuf = JS_GetStringCharsAndLength(cx, str, &buflen);
  +    if (!ucbuf)
  +        return false;
  +
  +    JS::Anchor<JSString *> a_str(str);
  +    uint32_t oldopts = JS_GetOptions(cx);
  +    JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | 
JSOPTION_NO_SCRIPT_RVAL);
  +
  +#ifdef       FIXME
  +    int64 startClock = PRMJ_Now();
  +#endif       /* FIXME */
  +    JSObject *scriptObj = JS_CompileUCScript(cx, thisobj, ucbuf, buflen, 
filename.ptr(), 1);
  +    JS_SetOptions(cx, oldopts);
  +    if (!scriptObj || !JS_ExecuteScript(cx, thisobj, scriptObj, NULL))
  +        return false;
  +
  +#ifdef       FIXME
  +    int64 endClock = PRMJ_Now();
  +    JS_SET_RVAL(cx, vp, DOUBLE_TO_JSVAL((endClock - startClock) / 
double(PRMJ_USEC_PER_MSEC)));
  +#endif       /* FIXME */
  +    return true;
  +#else        /* FIXME */
  +    return false;
  +#endif       /* FIXME */
  +}
  +
  +#ifdef       NOTYET
  +/*
  + * function readline()
  + * Provides a hook for scripts to read a line from stdin.
  + */
  +static JSBool
  +ReadLine(JSContext *cx, unsigned argc, jsval *vp)
  +{
  +#define BUFSIZE 256
  +    FILE *from;
  +    char *buf, *tmp;
  +    size_t bufsize, buflength, gotlength;
  +    JSBool sawNewline;
  +    JSString *str;
  +
  +    from = stdin;
  +    buflength = 0;
  +    bufsize = BUFSIZE;
  +    buf = (char *) JS_malloc(cx, bufsize);
  +    if (!buf)
  +        return JS_FALSE;
  +
  +    sawNewline = JS_FALSE;
  +    while ((gotlength =
  +            js_fgets(buf + buflength, bufsize - buflength, from)) > 0) {
  +        buflength += gotlength;
  +
  +        /* Are we done? */
  +        if (buf[buflength - 1] == '\n') {
  +            buf[buflength - 1] = '\0';
  +            sawNewline = JS_TRUE;
  +            break;
  +        } else if (buflength < bufsize - 1) {
  +            break;
  +        }
  +
  +        /* Else, grow our buffer for another pass. */
  +        bufsize *= 2;
  +        if (bufsize > buflength) {
  +            tmp = (char *) JS_realloc(cx, buf, bufsize);
  +        } else {
  +            JS_ReportOutOfMemory(cx);
  +            tmp = NULL;
  +        }
  +
  +        if (!tmp) {
  +            JS_free(cx, buf);
  +            return JS_FALSE;
  +        }
  +
  +        buf = tmp;
  +    }
  +
  +    /* Treat the empty string specially. */
  +    if (buflength == 0) {
  +        *vp = feof(from) ? JSVAL_NULL : JS_GetEmptyStringValue(cx);
  +        JS_free(cx, buf);
  +        return JS_TRUE;
  +    }
  +
  +    /* Shrink the buffer to the real size. */
  +    tmp = (char *) JS_realloc(cx, buf, buflength);
  +    if (!tmp) {
  +        JS_free(cx, buf);
  +        return JS_FALSE;
  +    }
  +
  +    buf = tmp;
  +
  +    /*
  +     * Turn buf into a JSString. Note that buflength includes the trailing 
null
  +     * character.
  +     */
  +    str = JS_NewStringCopyN(cx, buf, sawNewline ? buflength - 1 : buflength);
  +    JS_free(cx, buf);
  +    if (!str)
  +        return JS_FALSE;
  +
  +    *vp = STRING_TO_JSVAL(str);
  +    return JS_TRUE;
  +}
  +#endif
  +
  +static JSBool
  +PutStr(JSContext *cx, unsigned argc, jsval *vp)
  +{
  +    FILE * gOutFile = stdout;
  +    jsval * argv = JS_ARGV(cx, vp);
  +    JSString *str;
  +    char *bytes;
  +
  +    if (argc != 0) {
  +        str = JS_ValueToString(cx, argv[0]);
  +        if (!str)
  +            return JS_FALSE;
  +        bytes = JS_EncodeString(cx, str);
  +        if (!bytes)
  +            return JS_FALSE;
  +        fputs(bytes, gOutFile);
  +        JS_free(cx, bytes);
  +        fflush(gOutFile);
  +    }
  +
  +    JS_SET_RVAL(cx, vp, JSVAL_VOID);
  +    return JS_TRUE;
  +}
  +
  +static JSBool
  +Now(JSContext *cx, unsigned argc, jsval *vp)
  +{
  +#ifdef       FIXME
  +#ifdef       FIXME
  +    jsdouble now = PRMJ_Now() / double(PRMJ_USEC_PER_MSEC);
  +#else
  +    jsdouble now = time(NULL) * 1000;
  +#endif
  +    JS_SET_RVAL(cx, vp, DOUBLE_TO_JSVAL(now));
  +    return true;
  +#else
  +    return false;
  +#endif
  +}
  +
  +static JSBool
  +Print(JSContext *cx, unsigned argc, jsval *vp)
  +{
  +    FILE * gOutFile = stdout;
  +    jsval * argv = JS_ARGV(cx, vp);
  +    unsigned i;
  +    JSString *str;
  +    char *bytes;
  +
  +    for (i = 0; i < argc; i++) {
  +        str = JS_ValueToString(cx, argv[i]);
  +        if (!str)
  +            return JS_FALSE;
  +        bytes = JS_EncodeString(cx, str);
  +        if (!bytes)
  +            return JS_FALSE;
  +        fprintf(gOutFile, "%s%s", i ? " " : "", bytes);
  +        JS_free(cx, bytes);
  +    }
  +
  +    fputc('\n', gOutFile);
  +    fflush(gOutFile);
  +
  +    JS_SET_RVAL(cx, vp, JSVAL_VOID);
  +    return JS_TRUE;
  +}
  +
  +static JSBool
  +Require(JSContext *cx, unsigned argc, jsval *vp)
  +{
  +    jsval * argv = JS_ARGV(cx, vp);
  +SPEW("==> %s(%p,%p[%u],%p)\n", __FUNCTION__, cx, argv, (unsigned)argc, vp);
  +
  +    JS_SET_RVAL(cx, vp, JSVAL_VOID);
  +    return JS_TRUE;
  +}
  +
  +static JSFunctionSpec global_functions[] = {
  +    JS_FN("version", Version,        0,0),
  +    JS_FN("load",    Load,           1,0),
  +    JS_FN("evaluate",        Evaluate,       1,0),
  +    JS_FN("run",     Run,            1,0),
  +#ifdef       NOTYET
  +    JS_FN("readline",        ReadLine,       0,0),
  +#endif
  +    JS_FN("print",   Print,          0,0),
  +    JS_FN("putstr",  PutStr,         0,0),
  +    JS_FN("dateNow", Now,            0,0),
  +    JS_FS("require", Require,        0,0),
  +    JS_FS_END
  +};
  +
  +/*==============================================================*/
  +static void mozFini(rpmjss jss)
  +{
  +    JSI_t I = (JSI_t) jss->I;
   
       if (I->cx)
        JS_DestroyContext(I->cx);
  @@ -60,22 +424,26 @@
        JS_DestroyRuntime(I->rt);
       I->rt = NULL;
   
  -    if (--rpmjs_nopens <= 0)  {
  +    if (--rpmjss_nopens <= 0)  {
        JS_ShutDown();
  -     rpmjs_nopens = 0; 
  +     rpmjss_nopens = 0; 
       }   
       free(I);
   }
   
  -static void * mozInit(rpmjs js)
  +static void * mozInit(rpmjss jss)
   {   
       JSI_t I = NULL;
  -    uint32_t flags = js->flags;
  +    uint32_t flags = jss->flags;
   
       static uint32_t _maxbytes = 8L * 1024L * 1024L;
       static size_t _stackChunkSize = 8192;
  +    JSClass * _clasp = (JSClass *)&global_class;
  +    JSFunctionSpec * _functions = global_functions;
  +    JSPrincipals * _principals = NULL;
  +    JSBool ok;
   
  -    if (rpmjs_nopens++ == 0) {
  +    if (rpmjss_nopens++ == 0) {
   #ifdef       NOTYET          /* XXX collides with ancient JS_NewRuntime */
        JS_Init();
   #endif
  @@ -86,45 +454,52 @@
   
       I->rt = JS_NewRuntime(_maxbytes);
   assert(I->rt);
  -    JS_SetRuntimePrivate(I->rt, (void *)js);
  +    JS_SetRuntimePrivate(I->rt, (void *)jss);
   
       I->cx = JS_NewContext(I->rt, _stackChunkSize);
   assert(I->cx);
  -    JS_SetContextPrivate(I->cx, (void *)js);
  +    JS_SetContextPrivate(I->cx, (void *)jss);
  +
  +    JS_SetOptions(I->cx,
  +             JSOPTION_VAROBJFIX | JSOPTION_METHODJIT);
  +    JS_SetVersion(I->cx, JSVERSION_LATEST);
  +    JS_SetErrorReporter(I->cx, rpmjssReportError);
  +
  +    JS::RootedObject global(I->cx,
  +             JS_NewGlobalObject(I->cx, _clasp, _principals));
  +    I->global = global;
  +assert(I->global);
  +    JS_SetGlobalObject(I->cx, I->global);
  +
  +    ok = JS_InitStandardClasses(I->cx, global);
  +assert(ok);
  +#ifdef  JS_HAS_CTYPES
  +    ok = JS_InitCTypesClass(I->cx, I->global);
  +assert(ok);
  +#endif
  +
  +    ok = JS_DefineFunctions(I->cx, I->global, _functions);
  +assert(ok);
   
       return I;
   }
   
  -static int mozRun(rpmjs js,
  +static int mozRun(rpmjss jss,
                const char * script, const char * filename, int lineno)
   {
  -    JSI_t I = (JSI_t) js->I;
  +    JSI_t I = (JSI_t) jss->I;
   
  -    JSClass * _clasp = (JSClass *)&global_class;
  -#ifdef       NOTYET
  -    JSFunctionSpec * _functions = global_functions;
  -#endif
  -    JSPrincipals * _principals = NULL;
       JSBool ok;
   
       // In practice, you would want to exit this any
       // time you're spinning the event loop
       JSAutoRequest ar(I->cx);
   
  -    JS::RootedObject global(I->cx,
  -             JS_NewGlobalObject(I->cx, _clasp, _principals));
  -    if (!global)
  -     return 1;
  -    I->global = global;
  -assert(I->global);
  -    JS_SetGlobalObject(I->cx, I->global);
  -
       JS::RootedValue rval(I->cx);
       {        // Scope for JSAutoCompartment
  -     JSAutoCompartment ac(I->cx, global);
  -     JS_InitStandardClasses(I->cx, global);
  +     JSAutoCompartment ac(I->cx, I->global);
   
  -     ok = JS_EvaluateScript(I->cx, global,
  +     ok = JS_EvaluateScript(I->cx, I->global,
                        script, strlen(script), filename, lineno,
                        rval.address());
        if (!ok)
  @@ -139,24 +514,25 @@
   static struct JSIO_s _mozjs17 = { mozFini, mozInit, mozRun };
   JSIO_t mozjs17 = &_mozjs17;
   
  -#if defined(RPMJS_SELF_TEST)
  +#if defined(RPMJSS_SELF_TEST)
  +struct rpmjss_s _jss;
  +rpmjss jss = &_jss;
  +
   /*==============================================================*/
   int main(int argc, const char *argv[])
   {
       int rc = 0;
   
  -    JSI_t I = (JSI_t) mozInit(js);
  -    js->I = I;
  +    JSI_t I = (JSI_t) mozInit(jss);
  +    jss->I = I;
   
       {
        const char *script = "'hello'+'world, it is '+new Date()";
  -     const char *filename = "noname";
  -     int lineno = 1;
  -     rc = mozRun(js, script, filename, lineno);
  +     rc = mozRun(jss, script, __FILE__, __LINE__);
       }
   
  -    mozFini(js);
  +    mozFini(jss);
   
       return rc;
   }
  -#endif       /* RPMJS_SELF_TEST */
  +#endif       /* RPMJSS_SELF_TEST */
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/rpmjs185.cpp
  ============================================================================
  $ cvs diff -u -r1.1.2.3 -r1.1.2.4 rpmjs185.cpp
  --- rpm/rpmio/rpmjs185.cpp    22 Jun 2017 17:35:24 -0000      1.1.2.3
  +++ rpm/rpmio/rpmjs185.cpp    23 Jun 2017 03:39:43 -0000      1.1.2.4
  @@ -2,14 +2,14 @@
   // #define __STDC_LIMIT_MACROS
   // #include <stdint.h>
   
  +#pragma GCC diagnostic ignored "-Winvalid-offsetof"
  +
   #include "system.h"
   
  -#define      js      jsns
   #include "jsapi.h"
  -#undef       js
   
  -#define      _RPMJS_INTERNAL
  -#include <rpmjs.h>
  +#define      _RPMJSS_INTERNAL
  +#include <rpmjss.h>
   
   #include "debug.h"
   
  @@ -26,8 +26,12 @@
       JS_ConvertStub,
   };
   
  -struct rpmjs_s _js;
  -rpmjs js = &_js;
  +static int rpmjss_nopens;
  +
  +static int _rpmjss185_debug;
  +#define SPEW(_fmt, ...) \
  +    if (_rpmjss185_debug) \
  +     fprintf(stderr, _fmt, __VA_ARGS__)
   
   /*==============================================================*/
   typedef struct JSI_s * JSI_t;
  @@ -38,7 +42,7 @@
   };
   
   static void
  -rpmjsReportError(JSContext *cx, const char *message, JSErrorReport *report)
  +rpmjssReportError(JSContext *cx, const char *message, JSErrorReport *report)
   {
       fprintf(stderr, "%s:%u:%s\n",
        report->filename ? report->filename : "<no filename=\"filename\">",
  @@ -46,11 +50,355 @@
   }
   
   /*==============================================================*/
  -static int rpmjs_nopens;
  +static JSBool compileOnly = JS_FALSE;
  +
  +static JSBool
  +Version(JSContext *cx, uintN argc, jsval *vp)
  +{
  +    jsval *argv = JS_ARGV(cx, vp);
  +    if (argc > 0 && JSVAL_IS_INT(argv[0]))
  +        *vp = INT_TO_JSVAL(JS_SetVersion(cx, (JSVersion) 
JSVAL_TO_INT(argv[0])));
  +    else
  +        *vp = INT_TO_JSVAL(JS_GetVersion(cx));
  +    return JS_TRUE;
  +}
  +
  +static JSBool
  +Load(JSContext *cx, uintN argc, jsval *vp)
  +{
  +    jsval *argv = JS_ARGV(cx, vp);
  +    JSObject *thisobj = JS_THIS_OBJECT(cx, vp);
  +    if (!thisobj)
  +        return JS_FALSE;
  +
  +    for (uintN i = 0; i < argc; i++) {
  +        JSString *str = JS_ValueToString(cx, argv[i]);
  +        if (!str)
  +            return false;
  +        argv[i] = STRING_TO_JSVAL(str);
  +        JSAutoByteString filename(cx, str);
  +        if (!filename)
  +            return JS_FALSE;
  +        errno = 0;
  +        uint32 oldopts = JS_GetOptions(cx);
  +        JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | 
JSOPTION_NO_SCRIPT_RVAL);
  +        JSObject *scriptObj = JS_CompileFile(cx, thisobj, filename.ptr());
  +        JS_SetOptions(cx, oldopts);
  +        if (!scriptObj)
  +            return false;
  +
  +        if (!compileOnly && !JS_ExecuteScript(cx, thisobj, scriptObj, NULL))
  +            return false;
  +    }
  +
  +    return true;
  +}
  +
  +static JSBool
  +Evaluate(JSContext *cx, uintN argc, jsval *vp)
  +{
  +    if (argc != 1 || !JSVAL_IS_STRING(JS_ARGV(cx, vp)[0])) {
  +#ifdef       FIXME
  +        JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
  +                             (argc != 1) ? JSSMSG_NOT_ENOUGH_ARGS : 
JSSMSG_INVALID_ARGS,
  +                             "evaluate");
  +#endif
  +        return false;
  +    }
  +
  +    JSString *code = JSVAL_TO_STRING(JS_ARGV(cx, vp)[0]);
  +
  +    size_t codeLength;
  +    const jschar *codeChars = JS_GetStringCharsAndLength(cx, code, 
&codeLength);
  +    if (!codeChars)
  +        return false;
  +
  +    JSObject *thisobj = JS_THIS_OBJECT(cx, vp);
  +    if (!thisobj)
  +        return false;
  +
  +    if ((JS_GET_CLASS(cx, thisobj)->flags & JSCLASS_IS_GLOBAL) != 
JSCLASS_IS_GLOBAL) {
  +#ifdef       FIXME
  +        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, 
JSMSG_UNEXPECTED_TYPE,
  +                             "this-value passed to evaluate()", "not a 
global object");
  +#endif
  +        return false;
  +    }
  +
  +    JS_SET_RVAL(cx, vp, JSVAL_VOID);
  +    return JS_EvaluateUCScript(cx, thisobj, codeChars, codeLength, 
"@evaluate", 0, NULL);
  +}
  +
  +static JSString *
  +FileAsString(JSContext *cx, const char *pathname)
  +{
  +    FILE *file;
  +    JSString *str = NULL;
  +    size_t len, cc;
  +    char *buf;
  +
  +    file = fopen(pathname, "rb");
  +    if (!file) {
  +        JS_ReportError(cx, "can't open %s: %s", pathname, strerror(errno));
  +        return NULL;
  +    }
  +
  +    if (fseek(file, 0, SEEK_END) == EOF) {
  +        JS_ReportError(cx, "can't seek end of %s", pathname);
  +    } else {
  +        len = ftell(file);
  +        if (fseek(file, 0, SEEK_SET) == EOF) {
  +            JS_ReportError(cx, "can't seek start of %s", pathname);
  +        } else {
  +            buf = (char*) JS_malloc(cx, len + 1);
  +            if (buf) {
  +                cc = fread(buf, 1, len, file);
  +                if (cc != len) {
  +                    JS_ReportError(cx, "can't read %s: %s", pathname,
  +                                   (ptrdiff_t(cc) < 0) ? strerror(errno) : 
"short read");
  +                } else {
  +                    len = (size_t)cc;
  +                    str = JS_NewStringCopyN(cx, buf, len);
  +                }
  +                JS_free(cx, buf);
  +            }
  +        }
  +    }
  +    fclose(file);
  +
  +    return str;
  +}
  +
  +/*
  + * Function to run scripts and return compilation + execution time. Semantics
  + * are closely modelled after the equivalent function in WebKit, as this is 
used
  + * to produce benchmark timings by SunSpider.
  + */
  +static JSBool
  +Run(JSContext *cx, uintN argc, jsval *vp)
  +{
  +    if (argc != 1) {
  +#ifdef       FIXME
  +        JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, 
JSSMSG_INVALID_ARGS, "run");
  +#endif
  +        return false;
  +    }
  +
  +    JSObject *thisobj = JS_THIS_OBJECT(cx, vp);
  +    if (!thisobj)
  +        return false;
  +
  +    jsval *argv = JS_ARGV(cx, vp);
  +    JSString *str = JS_ValueToString(cx, argv[0]);
  +    if (!str)
  +        return false;
  +    argv[0] = STRING_TO_JSVAL(str);
  +    JSAutoByteString filename(cx, str);
  +    if (!filename)
  +        return false;
  +
  +    const jschar *ucbuf = NULL;
  +    size_t buflen;
  +    str = FileAsString(cx, filename.ptr());
  +    if (str)
  +        ucbuf = JS_GetStringCharsAndLength(cx, str, &buflen);
  +    if (!ucbuf)
  +        return false;
  +
  +    JS::Anchor<JSString *> a_str(str);
  +    uint32 oldopts = JS_GetOptions(cx);
  +    JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | 
JSOPTION_NO_SCRIPT_RVAL);
  +
  +#ifdef       FIXME
  +    int64 startClock = PRMJ_Now();
  +#endif
  +    JSObject *scriptObj = JS_CompileUCScript(cx, thisobj, ucbuf, buflen, 
filename.ptr(), 1);
  +    JS_SetOptions(cx, oldopts);
  +    if (!scriptObj || !JS_ExecuteScript(cx, thisobj, scriptObj, NULL))
  +        return false;
  +
  +#ifdef       FIXME
  +    int64 endClock = PRMJ_Now();
  +    JS_SET_RVAL(cx, vp, DOUBLE_TO_JSVAL((endClock - startClock) / 
double(PRMJ_USEC_PER_MSEC)));
  +#endif
  +    return true;
  +}
  +
  +#ifdef       NOTYET
  +/*
  + * function readline()
  + * Provides a hook for scripts to read a line from stdin.
  + */
  +static JSBool
  +ReadLine(JSContext *cx, uintN argc, jsval *vp)
  +{
  +#define BUFSIZE 256
  +    FILE *from;
  +    char *buf, *tmp;
  +    size_t bufsize, buflength, gotlength;
  +    JSBool sawNewline;
  +    JSString *str;
  +
  +    from = stdin;
  +    buflength = 0;
  +    bufsize = BUFSIZE;
  +    buf = (char *) JS_malloc(cx, bufsize);
  +    if (!buf)
  +        return JS_FALSE;
  +
  +    sawNewline = JS_FALSE;
  +    while ((gotlength =
  +            js_fgets(buf + buflength, bufsize - buflength, from)) > 0) {
  +        buflength += gotlength;
  +
  +        /* Are we done? */
  +        if (buf[buflength - 1] == '\n') {
  +            buf[buflength - 1] = '\0';
  +            sawNewline = JS_TRUE;
  +            break;
  +        } else if (buflength < bufsize - 1) {
  +            break;
  +        }
  +
  +        /* Else, grow our buffer for another pass. */
  +        bufsize *= 2;
  +        if (bufsize > buflength) {
  +            tmp = (char *) JS_realloc(cx, buf, bufsize);
  +        } else {
  +            JS_ReportOutOfMemory(cx);
  +            tmp = NULL;
  +        }
  +
  +        if (!tmp) {
  +            JS_free(cx, buf);
  +            return JS_FALSE;
  +        }
  +
  +        buf = tmp;
  +    }
  +
  +    /* Treat the empty string specially. */
  +    if (buflength == 0) {
  +        *vp = feof(from) ? JSVAL_NULL : JS_GetEmptyStringValue(cx);
  +        JS_free(cx, buf);
  +        return JS_TRUE;
  +    }
  +
  +    /* Shrink the buffer to the real size. */
  +    tmp = (char *) JS_realloc(cx, buf, buflength);
  +    if (!tmp) {
  +        JS_free(cx, buf);
  +        return JS_FALSE;
  +    }
  +
  +    buf = tmp;
   
  -static void mozFini(rpmjs js)
  +    /*
  +     * Turn buf into a JSString. Note that buflength includes the trailing 
null
  +     * character.
  +     */
  +    str = JS_NewStringCopyN(cx, buf, sawNewline ? buflength - 1 : buflength);
  +    JS_free(cx, buf);
  +    if (!str)
  +        return JS_FALSE;
  +
  +    *vp = STRING_TO_JSVAL(str);
  +    return JS_TRUE;
  +}
  +#endif
  +
  +static JSBool
  +PutStr(JSContext *cx, uintN argc, jsval *vp)
   {
  -    JSI_t I = (JSI_t) js->I;
  +    FILE * gOutFile = stdout;
  +    jsval * argv = JS_ARGV(cx, vp);
  +    JSString *str;
  +    char *bytes;
  +
  +    if (argc != 0) {
  +        str = JS_ValueToString(cx, argv[0]);
  +        if (!str)
  +            return JS_FALSE;
  +        bytes = JS_EncodeString(cx, str);
  +        if (!bytes)
  +            return JS_FALSE;
  +        fputs(bytes, gOutFile);
  +        JS_free(cx, bytes);
  +        fflush(gOutFile);
  +    }
  +
  +    JS_SET_RVAL(cx, vp, JSVAL_VOID);
  +    return JS_TRUE;
  +}
  +
  +static JSBool
  +Now(JSContext *cx, uintN argc, jsval *vp)
  +{
  +#ifdef       FIXME
  +    jsdouble now = PRMJ_Now() / double(PRMJ_USEC_PER_MSEC);
  +#else
  +    jsdouble now = time(NULL) * 1000;
  +#endif
  +    JS_SET_RVAL(cx, vp, DOUBLE_TO_JSVAL(now));
  +    return true;
  +}
  +
  +static JSBool
  +Print(JSContext *cx, uintN argc, jsval *vp)
  +{
  +    FILE * gOutFile = stdout;
  +    jsval * argv = JS_ARGV(cx, vp);
  +    uintN i;
  +    JSString *str;
  +    char *bytes;
  +
  +    for (i = 0; i < argc; i++) {
  +        str = JS_ValueToString(cx, argv[i]);
  +        if (!str)
  +            return JS_FALSE;
  +        bytes = JS_EncodeString(cx, str);
  +        if (!bytes)
  +            return JS_FALSE;
  +        fprintf(gOutFile, "%s%s", i ? " " : "", bytes);
  +        JS_free(cx, bytes);
  +    }
  +
  +    fputc('\n', gOutFile);
  +    fflush(gOutFile);
  +
  +    JS_SET_RVAL(cx, vp, JSVAL_VOID);
  +    return JS_TRUE;
  +}
  +
  +static JSBool
  +Require(JSContext *cx, uintN argc, jsval *vp)
  +{
  +    jsval * argv = JS_ARGV(cx, vp);
  +SPEW("==> %s(%p,%p[%u],%p)\n", __FUNCTION__, cx, argv, (unsigned)argc, vp);
  +
  +    JS_SET_RVAL(cx, vp, JSVAL_VOID);
  +    return JS_TRUE;
  +}
  +
  +static JSFunctionSpec global_functions[] = {
  +    JS_FN("version", Version,        0,0),
  +    JS_FN("load",    Load,           1,0),
  +    JS_FN("evaluate",        Evaluate,       1,0),
  +    JS_FN("run",     Run,            1,0),
  +#ifdef       NOTYET
  +    JS_FN("readline",        ReadLine,       0,0),
  +#endif
  +    JS_FN("print",   Print,          0,0),
  +    JS_FN("putstr",  PutStr,         0,0),
  +    JS_FN("dateNow", Now,            0,0),
  +    JS_FS("require", Require,        0,0),
  +    JS_FS_END
  +};
  +
  +/*==============================================================*/
  +static void mozFini(rpmjss jss)
  +{
  +    JSI_t I = (JSI_t) jss->I;
   
       if (I->cx)
        JS_DestroyContext(I->cx);
  @@ -60,27 +408,26 @@
        JS_DestroyRuntime(I->rt);
       I->rt = NULL;
   
  -    if (--rpmjs_nopens <= 0)  {
  +    if (--rpmjss_nopens <= 0)  {
        JS_ShutDown();
  -     rpmjs_nopens = 0; 
  +     rpmjss_nopens = 0; 
       }   
       free(I);
   }
   
  -static void * mozInit(rpmjs js)
  +static void * mozInit(rpmjss jss)
   {   
       JSI_t I = NULL;
  -    uint32_t flags = js->flags;
  +    uint32_t flags = jss->flags;
   
       static uint32 _maxbytes = 8L * 1024L * 1024L;
       static size_t _stackChunkSize = 8192;
       JSClass * _clasp = (JSClass *)&global_class;
  -#ifdef       NOTYET
       JSFunctionSpec * _functions = global_functions;
  -#endif
       JSPrincipals * _principals = NULL;
  +    JSBool ok;
   
  -    if (rpmjs_nopens++ == 0) {
  +    if (rpmjss_nopens++ == 0) {
   #ifdef       NOTYET          /* XXX collides with ancient JS_NewRuntime */
        JS_Init();
   #endif
  @@ -91,27 +438,38 @@
   
       I->rt = JS_NewRuntime(_maxbytes);
   assert(I->rt);
  -    JS_SetRuntimePrivate(I->rt, (void *)js);
  +    JS_SetRuntimePrivate(I->rt, (void *)jss);
   
       I->cx = JS_NewContext(I->rt, _stackChunkSize);
   assert(I->cx);
  -    JS_SetContextPrivate(I->cx, (void *)js);
  +    JS_SetContextPrivate(I->cx, (void *)jss);
   
       JS_SetOptions(I->cx,
                JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT);
       JS_SetVersion(I->cx, JSVERSION_LATEST);
  -    JS_SetErrorReporter(I->cx, rpmjsReportError);
  +    JS_SetErrorReporter(I->cx, rpmjssReportError);
   
       I->global = JS_NewCompartmentAndGlobalObject(I->cx,
                        _clasp, _principals);
  +assert(I->global);
  +
  +    ok = JS_InitStandardClasses(I->cx, I->global);
  +assert(ok);
  +#ifdef  JS_HAS_CTYPES
  +    ok = JS_InitCTypesClass(I->cx, I->global);
  +assert(ok);
  +#endif
  +
  +    ok = JS_DefineFunctions(I->cx, I->global, _functions);
  +assert(ok);
   
       return I;
   }
   
  -static int mozRun(rpmjs js,
  +static int mozRun(rpmjss jss,
                const char * script, const char * filename, int lineno)
   {
  -    JSI_t I = (JSI_t) js->I;
  +    JSI_t I = (JSI_t) jss->I;
   
       JSClass * _clasp = (JSClass *)&global_class;
   #ifdef       NOTYET
  @@ -128,8 +486,6 @@
           if (!ac.enter(I->cx, I->global))
            return 1;
   #endif
  -     
  -     JS_InitStandardClasses(I->cx, I->global);
   
        ok = JS_EvaluateScript(I->cx, I->global,
                        script, strlen(script), filename, lineno,
  @@ -146,24 +502,25 @@
   static struct JSIO_s _mozjs185 = { mozFini, mozInit, mozRun };
   JSIO_t mozjs185 = &_mozjs185;
   
  -#if defined(RPMJS_SELF_TEST)
  +#if defined(RPMJSS_SELF_TEST)
  +struct rpmjss_s _jss;
  +rpmjss jss = &_jss;
  +
   /*==============================================================*/
   int main(int argc, const char *argv[])
   {
       int rc = 0;
   
  -    JSI_t I = (JSI_t) mozInit(js);
  -    js->I = I;
  +    JSI_t I = (JSI_t) mozInit(jss);
  +    jss->I = I;
   
       {
        const char *script = "'hello'+'world, it is '+new Date()";
  -     const char *filename = "noname";
  -     int lineno = 1;
  -     rc = mozRun(js, script, filename, lineno);
  +     rc = mozRun(jss, script, __FILE__, __LINE__);
       }
   
  -    mozFini(js);
  +    mozFini(jss);
   
       return rc;
   }
  -#endif       /* RPMJS_SELF_TEST */
  +#endif       /* RPMJSS_SELF_TEST */
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/rpmjs24.cpp
  ============================================================================
  $ cvs diff -u -r1.1.2.4 -r1.1.2.5 rpmjs24.cpp
  --- rpm/rpmio/rpmjs24.cpp     22 Jun 2017 17:35:24 -0000      1.1.2.4
  +++ rpm/rpmio/rpmjs24.cpp     23 Jun 2017 03:39:43 -0000      1.1.2.5
  @@ -2,14 +2,14 @@
   // #define __STDC_LIMIT_MACROS
   // #include <stdint.h>
   
  +#pragma GCC diagnostic ignored "-Winvalid-offsetof"
  +
   #include "system.h"
   
  -#define      js      jsns
   #include "jsapi.h"
  -#undef       js
   
  -#define      _RPMJS_INTERNAL
  -#include <rpmjs.h>
  +#define      _RPMJSS_INTERNAL
  +#include <rpmjss.h>
   
   #include "debug.h"
   
  @@ -28,8 +28,12 @@
   
   #define      JS_Init()
   
  -struct rpmjs_s _js;
  -rpmjs js = &_js;
  +static int rpmjss_nopens;
  +
  +static int _rpmjss24_debug;
  +#define SPEW(_fmt, ...) \
  +    if (_rpmjss24_debug) \
  +     fprintf(stderr, _fmt, __VA_ARGS__)
   
   /*==============================================================*/
   typedef struct JSI_s * JSI_t;
  @@ -40,7 +44,7 @@
   };
   
   static void
  -rpmjsReportError(JSContext *cx, const char *message, JSErrorReport *report)
  +rpmjssReportError(JSContext *cx, const char *message, JSErrorReport *report)
   {
       fprintf(stderr, "%s:%u:%s\n",
        report->filename ? report->filename : "<no filename=\"filename\">",
  @@ -48,11 +52,9 @@
   }
   
   /*==============================================================*/
  -static int rpmjs_nopens;
  -
  -static void mozFini(rpmjs js)
  +static void mozFini(rpmjss jss)
   {
  -    JSI_t I = (JSI_t) js->I;
  +    JSI_t I = (JSI_t) jss->I;
   
       if (I->cx)
        JS_DestroyContext(I->cx);
  @@ -62,22 +64,22 @@
        JS_DestroyRuntime(I->rt);
       I->rt = NULL;
   
  -    if (--rpmjs_nopens <= 0)  {
  +    if (--rpmjss_nopens <= 0)  {
        JS_ShutDown();
  -     rpmjs_nopens = 0; 
  +     rpmjss_nopens = 0; 
       }   
       free(I);
   }
   
  -static void * mozInit(rpmjs js)
  +static void * mozInit(rpmjss jss)
   {   
       JSI_t I = NULL;
  -    uint32_t flags = js->flags;
  +    uint32_t flags = jss->flags;
   
       static uint32_t _maxbytes = 8L * 1024L * 1024L;
       static size_t _stackChunkSize = 8192;
   
  -    if (rpmjs_nopens++ == 0)
  +    if (rpmjss_nopens++ == 0)
        JS_Init();
   
       I = (JSI_t) calloc(1, sizeof(*I));
  @@ -85,19 +87,26 @@
   
       I->rt = JS_NewRuntime(_maxbytes, JS_USE_HELPER_THREADS);
   assert(I->rt);
  -    JS_SetRuntimePrivate(I->rt, (void *)js);
  +    JS_SetRuntimePrivate(I->rt, (void *)jss);
   
       I->cx = JS_NewContext(I->rt, _stackChunkSize);
   assert(I->cx);
  -    JS_SetContextPrivate(I->cx, (void *)js);
  +    JS_SetContextPrivate(I->cx, (void *)jss);
  +
  +    JS_SetOptions(I->cx,
  +             JSOPTION_VAROBJFIX);
  +#ifdef       NOTYET
  +    JS_SetVersion(I->cx, JSVERSION_LATEST);
  +#endif
  +    JS_SetErrorReporter(I->cx, rpmjssReportError);
   
       return I;
   }
   
  -static int mozRun(rpmjs js,
  +static int mozRun(rpmjss jss,
                const char * script, const char * filename, int lineno)
   {
  -    JSI_t I = (JSI_t) js->I;
  +    JSI_t I = (JSI_t) jss->I;
   
       JSClass * _clasp = (JSClass *)&global_class;
   #ifdef       NOTYET
  @@ -138,24 +147,25 @@
   static struct JSIO_s _mozjs24 = { mozFini, mozInit, mozRun };
   JSIO_t mozjs24 = &_mozjs24;
   
  -#if defined(RPMJS_SELF_TEST)
  +#if defined(RPMJSS_SELF_TEST)
  +struct rpmjss_s _jss;
  +rpmjss jss = &_jss;
  +
   /*==============================================================*/
   int main(int argc, const char *argv[])
   {
       int rc = 0;
   
  -    JSI_t I = (JSI_t) mozInit(js);
  -    js->I = I;
  +    JSI_t I = (JSI_t) mozInit(jss);
  +    jss->I = I;
   
       {
        const char *script = "'hello'+'world, it is '+new Date()";
  -     const char *filename = "noname";
  -     int lineno = 1;
  -     rc = mozRun(js, script, filename, lineno);
  +     rc = mozRun(jss, script, __FILE__, __LINE__);
       }
   
  -    mozFini(js);
  +    mozFini(jss);
   
       return rc;
   }
  -#endif       /* RPMJS_SELF_TEST */
  +#endif       /* RPMJSS_SELF_TEST */
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/rpmjs31.cpp
  ============================================================================
  $ cvs diff -u -r1.1.2.4 -r1.1.2.5 rpmjs31.cpp
  --- rpm/rpmio/rpmjs31.cpp     22 Jun 2017 17:35:24 -0000      1.1.2.4
  +++ rpm/rpmio/rpmjs31.cpp     23 Jun 2017 03:39:43 -0000      1.1.2.5
  @@ -2,14 +2,14 @@
   // #define __STDC_LIMIT_MACROS
   // #include <stdint.h>
   
  +#pragma GCC diagnostic ignored "-Winvalid-offsetof"
  +
   #include "system.h"
   
  -#define      js      jsns
   #include "jsapi.h"
  -#undef       js
   
  -#define      _RPMJS_INTERNAL
  -#include <rpmjs.h>
  +#define      _RPMJSS_INTERNAL
  +#include <rpmjss.h>
   
   #include "debug.h"
   
  @@ -31,8 +31,12 @@
       JS_GlobalObjectTraceHook
   };
   
  -struct rpmjs_s _js;
  -rpmjs js = &_js;
  +static int rpmjss_nopens;
  +
  +static int _rpmjs31_debug;
  +#define SPEW(_fmt, ...) \
  +    if (_rpmjss31_debug) \
  +     fprintf(stderr, _fmt, __VA_ARGS__)
   
   /*==============================================================*/
   typedef struct JSI_s * JSI_t;
  @@ -43,7 +47,7 @@
   };
   
   static void
  -rpmjsReportError(JSContext *cx, const char *message, JSErrorReport *report)
  +rpmjssReportError(JSContext *cx, const char *message, JSErrorReport *report)
   {
       fprintf(stderr, "%s:%u:%s\n",
        report->filename ? report->filename : "<no filename=\"filename\">",
  @@ -51,11 +55,9 @@
   }
   
   /*==============================================================*/
  -static int rpmjs_nopens;
  -
  -static void mozFini(rpmjs js)
  +static void mozFini(rpmjss jss)
   {
  -    JSI_t I = (JSI_t) js->I;
  +    JSI_t I = (JSI_t) jss->I;
   
       if (I->cx)
        JS_DestroyContext(I->cx);
  @@ -65,22 +67,22 @@
        JS_DestroyRuntime(I->rt);
       I->rt = NULL;
   
  -    if (--rpmjs_nopens <= 0)  {
  +    if (--rpmjss_nopens <= 0)  {
        JS_ShutDown();
  -     rpmjs_nopens = 0; 
  +     rpmjss_nopens = 0; 
       }   
       free(I);
   }
   
  -static void * mozInit(rpmjs js)
  +static void * mozInit(rpmjss jss)
   {   
       JSI_t I = NULL;
  -    uint32_t flags = js->flags;
  +    uint32_t flags = jss->flags;
   
       static uint32_t _maxbytes = 8L * 1024L * 1024L;
       static size_t _stackChunkSize = 8192;
   
  -    if (rpmjs_nopens++ == 0)
  +    if (rpmjss_nopens++ == 0)
        JS_Init();
   
       I = (JSI_t) calloc(1, sizeof(*I));
  @@ -88,19 +90,21 @@
   
       I->rt = JS_NewRuntime(_maxbytes, JS_USE_HELPER_THREADS);
   assert(I->rt);
  -    JS_SetRuntimePrivate(I->rt, (void *)js);
  +    JS_SetRuntimePrivate(I->rt, (void *)jss);
   
       I->cx = JS_NewContext(I->rt, _stackChunkSize);
   assert(I->cx);
  -    JS_SetContextPrivate(I->cx, (void *)js);
  +    JS_SetContextPrivate(I->cx, (void *)jss);
  +
  +    JS_SetErrorReporter(I->cx, rpmjssReportError);
   
       return I;
   }
   
  -static int mozRun(rpmjs js,
  +static int mozRun(rpmjss jss,
                const char * script, const char * filename, int lineno)
   {
  -    JSI_t I = (JSI_t) js->I;
  +    JSI_t I = (JSI_t) jss->I;
   
       JSClass * _clasp = (JSClass *)&global_class;
   #ifdef       NOTYET
  @@ -140,24 +144,25 @@
   static struct JSIO_s _mozjs31 = { mozFini, mozInit, mozRun };
   JSIO_t mozjs31 = &_mozjs31;
   
  -#if defined(RPMJS_SELF_TEST)
  +#if defined(RPMJSS_SELF_TEST)
  +struct rpmjss_s _jss;
  +rpmjss jss = &_jss;
  +
   /*==============================================================*/
   int main(int argc, const char *argv[])
   {
       int rc = 0;
   
  -    JSI_t I = (JSI_t) mozInit(js);
  -    js->I = I;
  +    JSI_t I = (JSI_t) mozInit(jss);
  +    jss->I = I;
   
       {
        const char *script = "'hello'+'world, it is '+new Date()";
  -     const char *filename = "noname";
  -     int lineno = 1;
  -     rc = mozRun(js, script, filename, lineno);
  +     rc = mozRun(jss, script, __FILE__, __LINE__);
       }
   
  -    mozFini(js);
  +    mozFini(jss);
   
       return rc;
   }
  -#endif       /* RPMJS_SELF_TEST */
  +#endif       /* RPMJSS_SELF_TEST */
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/rpmjs38.cpp
  ============================================================================
  $ cvs diff -u -r1.1.2.4 -r1.1.2.5 rpmjs38.cpp
  --- rpm/rpmio/rpmjs38.cpp     22 Jun 2017 17:35:24 -0000      1.1.2.4
  +++ rpm/rpmio/rpmjs38.cpp     23 Jun 2017 03:39:43 -0000      1.1.2.5
  @@ -2,14 +2,14 @@
   // #define __STDC_LIMIT_MACROS
   // #include <stdint.h>
   
  +#pragma GCC diagnostic ignored "-Winvalid-offsetof"
  +
   #include "system.h"
   
  -#define      js      jsns
   #include "jsapi.h"
  -#undef       js
   
  -#define      _RPMJS_INTERNAL
  -#include <rpmjs.h>
  +#define      _RPMJSS_INTERNAL
  +#include <rpmjss.h>
   
   #include "debug.h"
   
  @@ -31,8 +31,12 @@
       JS_GlobalObjectTraceHook
   };
   
  -struct rpmjs_s _js;
  -rpmjs js = &_js;
  +static int rpmjss_nopens;
  +
  +static int _rpmjss38_debug;
  +#define SPEW(_fmt, ...) \
  +    if (_rpmjss38_debug) \
  +     fprintf(stderr, _fmt, __VA_ARGS__)
   
   /*==============================================================*/
   typedef struct JSI_s * JSI_t;
  @@ -43,7 +47,7 @@
   };
   
   static void
  -rpmjsReportError(JSContext *cx, const char *message, JSErrorReport *report)
  +rpmjssReportError(JSContext *cx, const char *message, JSErrorReport *report)
   {
       fprintf(stderr, "%s:%u:%s\n",
        report->filename ? report->filename : "<no filename=\"filename\">",
  @@ -51,11 +55,9 @@
   }
   
   /*==============================================================*/
  -static int rpmjs_nopens;
  -
  -static void mozFini(rpmjs js)
  +static void mozFini(rpmjss jss)
   {
  -    JSI_t I = (JSI_t) js->I;
  +    JSI_t I = (JSI_t) jss->I;
   
       if (I->cx)
        JS_DestroyContext(I->cx);
  @@ -65,22 +67,22 @@
        JS_DestroyRuntime(I->rt);
       I->rt = NULL;
   
  -    if (--rpmjs_nopens <= 0)  {
  +    if (--rpmjss_nopens <= 0)  {
        JS_ShutDown();
  -     rpmjs_nopens = 0; 
  +     rpmjss_nopens = 0; 
       }   
       free(I);
   }
   
  -static void * mozInit(rpmjs js)
  +static void * mozInit(rpmjss jss)
   {   
       JSI_t I = NULL;
  -    uint32_t flags = js->flags;
  +    uint32_t flags = jss->flags;
   
       static uint32_t _maxbytes = 8L * 1024L * 1024L;
       static size_t _stackChunkSize = 8192;
   
  -    if (rpmjs_nopens++ == 0)
  +    if (rpmjss_nopens++ == 0)
        JS_Init();
   
       I = (JSI_t) calloc(1, sizeof(*I));
  @@ -88,19 +90,21 @@
   
       I->rt = JS_NewRuntime(_maxbytes);
   assert(I->rt);
  -    JS_SetRuntimePrivate(I->rt, (void *)js);
  +    JS_SetRuntimePrivate(I->rt, (void *)jss);
   
       I->cx = JS_NewContext(I->rt, _stackChunkSize);
   assert(I->cx);
  -    JS_SetContextPrivate(I->cx, (void *)js);
  +    JS_SetContextPrivate(I->cx, (void *)jss);
  +
  +    JS_SetErrorReporter(I->rt, rpmjssReportError);
   
       return I;
   }
   
  -static int mozRun(rpmjs js,
  +static int mozRun(rpmjss jss,
                const char * script, const char * filename, int lineno)
   {
  -    JSI_t I = (JSI_t) js->I;
  +    JSI_t I = (JSI_t) jss->I;
   
       JSClass * _clasp = (JSClass *)&global_class;
   #ifdef       NOTYET
  @@ -140,24 +144,25 @@
   static struct JSIO_s _mozjs38 = { mozFini, mozInit, mozRun };
   JSIO_t mozjs38 = &_mozjs38;
   
  -#if defined(RPMJS_SELF_TEST)
  +#if defined(RPMJSS_SELF_TEST)
  +struct rpmjss_s _jss;
  +rpmjss jss = &_jss;
  +
   /*==============================================================*/
   int main(int argc, const char *argv[])
   {
       int rc = 0;
   
  -    JSI_t I = (JSI_t) mozInit(js);
  -    js->I = I;
  +    JSI_t I = (JSI_t) mozInit(jss);
  +    jss->I = I;
   
       {
        const char *script = "'hello'+'world, it is '+new Date()";
  -     const char *filename = "noname";
  -     int lineno = 1;
  -     rc = mozRun(js, script, filename, lineno);
  +     rc = mozRun(jss, script, __FILE__, __LINE__);
       }
   
  -    mozFini(js);
  +    mozFini(jss);
   
       return rc;
   }
  -#endif       /* RPMJS_SELF_TEST */
  +#endif       /* RPMJSS_SELF_TEST */
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/rpmjs45.cpp
  ============================================================================
  $ cvs diff -u -r1.1.2.5 -r1.1.2.6 rpmjs45.cpp
  --- rpm/rpmio/rpmjs45.cpp     23 Jun 2017 00:43:55 -0000      1.1.2.5
  +++ rpm/rpmio/rpmjs45.cpp     23 Jun 2017 03:39:43 -0000      1.1.2.6
  @@ -6,18 +6,18 @@
   
   #include "system.h"
   
  -#define      js      jsns
   #include "jsapi.h"
   #include "js/Initialization.h"
  -#undef       js
  +#include "js/Conversions.h"
  +using namespace JS;
  +using namespace js;
   
  -#define      _RPMJS_INTERNAL
  -#include <rpmjs.h>
  +#define      _RPMJSS_INTERNAL
  +#include <rpmjss.h>
   
   #include "debug.h"
   
   /*==============================================================*/
  -#ifdef       NOTYET          /* XXX HandleObject and HandleId */
   static bool
   global_enumerate(JSContext* cx, HandleObject obj)
   {
  @@ -43,7 +43,6 @@
   {
       return JS_MayResolveStandardClass(names, id, maybeObj);
   }
  -#endif       /* NOTYET */
   
   static JSClass global_class = {
       "global",
  @@ -52,15 +51,9 @@
       nullptr,
       nullptr,
       nullptr,
  -#ifdef       NOTYET          /* XXX HandleObject and HandleId */
       global_enumerate,
       global_resolve,
       global_mayResolve,
  -#else
  -    nullptr,
  -    nullptr,
  -    nullptr,
  -#endif
       nullptr,
       nullptr,
       nullptr,
  @@ -68,11 +61,11 @@
       JS_GlobalObjectTraceHook
   };
   
  -static int rpmjs_nopens;
  +static int rpmjss_nopens;
   
  -static int _rpmjs45_debug;
  +static int _rpmjss45_debug;
   #define SPEW(_fmt, ...) \
  -    if (_rpmjs45_debug) \
  +    if (_rpmjss45_debug) \
        fprintf(stderr, _fmt, __VA_ARGS__)
   
   /*==============================================================*/
  @@ -84,17 +77,652 @@
   };
   
   static void
  -rpmjsReportError(JSContext *cx, const char *message, JSErrorReport *report)
  +rpmjssReportError(JSContext *cx, const char *message, JSErrorReport *report)
   {
       fprintf(stderr, "%s:%u:%s\n",
        report->filename ? report->filename : "<no filename=\"filename\">",
        (unsigned int) report->lineno, message);
   }
   
  +static void
  +rpmjssOOMCallback(JSContext* cx, void* data)
  +{
  +#ifdef       NOTYET
  +    // If a script is running, the engine is about to throw the string "out 
of
  +    // memory", which may or may not be caught. Otherwise the engine will 
just
  +    // unwind and return null/false, with no exception set.
  +    if (!JS_IsRunning(cx))
  +        GetShellRuntime(cx)->gotError = true;
  +#endif
  +}
  +
  +enum JSShellErrNum {
  +#define MSG_DEF(name, count, exception, format) \
  +    name,
  +#include "jsshell.msg"
  +#undef MSG_DEF
  +    JSShellErr_Limit
  +};
  +
  +static const JSErrorFormatString jsShell_ErrorFormatString[JSShellErr_Limit] 
= {
  +#define MSG_DEF(name, count, exception, format) \
  +    { format, count, JSEXN_ERR } ,
  +#include "jsshell.msg"
  +#undef MSG_DEF
  +};
  +
  +const JSErrorFormatString*
  +my_GetErrorMessage(void* userRef, const unsigned errorNumber)
  +{
  +    if (errorNumber == 0 || errorNumber >= JSShellErr_Limit)
  +        return nullptr;
  +
  +    return &jsShell_ErrorFormatString[errorNumber];
  +}
  +
  +/*==============================================================*/
  +static bool compileOnly = false;
  +
  +static bool
  +Version(JSContext *cx, unsigned argc, Value* vp)
  +{
  +    CallArgs args = CallArgsFromVp(argc, vp);
  +    JSVersion origVersion = JS_GetVersion(cx);
  +    if (args.length() == 0 || args[0].isUndefined()) {
  +        /* Get version. */
  +        args.rval().setInt32(origVersion);
  +    } else {
  +        /* Set version. */
  +        int32_t v = -1;
  +        if (args[0].isInt32()) {
  +            v = args[0].toInt32();
  +        } else
  +     if (args[0].isDouble()) {
  +            double fv = args[0].toDouble();
  +         int32_t fvi;
  +         if (JS_DoubleIsInt32(fv, &fvi))
  +             v = fvi;
  +     }
  +        if (v < 0 || v > JSVERSION_LATEST) {
  +            JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, 
JSSMSG_INVALID_ARGS, "version");
  +            return false;
  +        }
  +        JS_SetVersionForCompartment(js::GetContextCompartment(cx), 
JSVersion(v));
  +        args.rval().setInt32(origVersion);
  +    }
  +    return true;
  +}
  +
  +#ifdef       NOTYET
  +static bool
  +LoadScript(JSContext* cx, unsigned argc, Value* vp, bool scriptRelative)
  +{
  +    CallArgs args = CallArgsFromVp(argc, vp);
  +
  +    RootedString str(cx);
  +    for (unsigned i = 0; i < args.length(); i++) {
  +        str = JS::ToString(cx, args[i]);
  +        if (!str) {
  +            JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, 
JSSMSG_INVALID_ARGS, "load");
  +            return false;
  +        }
  +        str = ResolvePath(cx, str, scriptRelative ? ScriptRelative : 
RootRelative);
  +        if (!str) {
  +            JS_ReportError(cx, "unable to resolve path");
  +            return false;
  +        }
  +        JSAutoByteString filename(cx, str);
  +        if (!filename)
  +            return false;
  +        errno = 0;
  +        CompileOptions opts(cx);
  +        opts.setIntroductionType("js shell load")
  +            .setUTF8(true)
  +            .setIsRunOnce(true)
  +            .setNoScriptRval(true);
  +        RootedScript script(cx);
  +        RootedValue unused(cx);
  +        if ((compileOnly && !Compile(cx, opts, filename.ptr(), &script)) ||
  +            !Evaluate(cx, opts, filename.ptr(), &unused))
  +        {
  +            return false;
  +        }
  +    }
  +
  +    args.rval().setUndefined();
  +    return true;
  +}
  +
  +static bool
  +Load(JSContext* cx, unsigned argc, Value* vp)
  +{
  +    return LoadScript(cx, argc, vp, false);
  +}
  +#endif       /* NOTYET */
  +
  +static const JSFunctionSpec global_functions[] = {
  +    JS_FN("version", Version,        0,0),
  +#ifdef       NOTYET
  +    JS_FN("load",    Load,           1,0),
  +    JS_FN("evaluate",        Evaluate,       1,0),
  +    JS_FN("run",     Run,            1,0),
  +#ifdef       NOTYET
  +    JS_FN("readline",        ReadLine,       0,0),
  +#endif
  +    JS_FN("print",   Print,          0,0),
  +    JS_FN("putstr",  PutStr,         0,0),
  +    JS_FN("dateNow", Now,            0,0),
  +    JS_FS("require", Require,        0,0),
  +#endif
  +    JS_FS_END
  +};
  +
  +/*==============================================================*/
  +#ifdef       NOTYET
  +static const JSFunctionSpecWithHelp shell_functions[] = {
  +    JS_FN_HELP("version", Version, 0, 0,
  +"version([number])",
  +"  Get or force a script compilation version number."),
  +
  +    JS_FN_HELP("options", Options, 0, 0,
  +"options([option ...])",
  +"  Get or toggle JavaScript options."),
  +
  +    JS_FN_HELP("load", Load, 1, 0,
  +"load(['foo.js' ...])",
  +"  Load files named by string arguments. Filename is relative to the\n"
  +"      current working directory."),
  +
  +    JS_FN_HELP("loadRelativeToScript", LoadScriptRelativeToScript, 1, 0,
  +"loadRelativeToScript(['foo.js' ...])",
  +"  Load files named by string arguments. Filename is relative to the\n"
  +"      calling script."),
  +
  +    JS_FN_HELP("evaluate", Evaluate, 2, 0,
  +"evaluate(code[, options])",
  +"  Evaluate code as though it were the contents of a file.\n"
  +"  options is an optional object that may have these properties:\n"
  +"      isRunOnce: use the isRunOnce compiler option (default: false)\n"
  +"      noScriptRval: use the no-script-rval compiler option (default: 
false)\n"
  +"      fileName: filename for error messages and debug info\n"
  +"      lineNumber: starting line number for error messages and debug info\n"
  +"      columnNumber: starting column number for error messages and debug 
info\n"
  +"      global: global in which to execute the code\n"
  +"      newContext: if true, create and use a new cx (default: false)\n"
  +"      saveFrameChain: if true, save the frame chain before evaluating 
code\n"
  +"         and restore it afterwards\n"
  +"      catchTermination: if true, catch termination (failure without\n"
  +"         an exception value, as for slow scripts or out-of-memory)\n"
  +"         and return 'terminated'\n"
  +"      element: if present with value |v|, convert |v| to an object |o| 
and\n"
  +"         mark the source as being attached to the DOM element |o|. If the\n"
  +"         property is omitted or |v| is null, don't attribute the source 
to\n"
  +"         any DOM element.\n"
  +"      elementAttributeName: if present and not undefined, the name of\n"
  +"         property of 'element' that holds this code. This is what\n"
  +"         Debugger.Source.prototype.elementAttributeName returns.\n"
  +"      sourceMapURL: if present with value |v|, convert |v| to a string, 
and\n"
  +"         provide that as the code's source map URL. If omitted, attach no\n"
  +"         source map URL to the code (although the code may provide one 
itself,\n"
  +"         via a //#sourceMappingURL comment).\n"
  +"      sourceIsLazy: if present and true, indicates that, after compilation, 
\n"
  +          "script source should not be cached by the JS engine and should be 
\n"
  +          "lazily loaded from the embedding as-needed.\n"
  +"      loadBytecode: if true, and if the source is a CacheEntryObject,\n"
  +"         the bytecode would be loaded and decoded from the cache entry 
instead\n"
  +"         of being parsed, then it would be executed as usual.\n"
  +"      saveBytecode: if true, and if the source is a CacheEntryObject,\n"
  +"         the bytecode would be encoded and saved into the cache entry 
after\n"
  +"         the script execution.\n"
  +"      assertEqBytecode: if true, and if both loadBytecode and saveBytecode 
are \n"
  +"         true, then the loaded bytecode and the encoded bytecode are 
compared.\n"
  +"         and an assertion is raised if they differ.\n"
  +),
  +
  +    JS_FN_HELP("run", Run, 1, 0,
  +"run('foo.js')",
  +"  Run the file named by the first argument, returning the number of\n"
  +"  of milliseconds spent compiling and executing it."),
  +
  +    JS_FN_HELP("readline", ReadLine, 0, 0,
  +"readline()",
  +"  Read a single line from stdin."),
  +
  +    JS_FN_HELP("print", Print, 0, 0,
  +"print([exp ...])",
  +"  Evaluate and print expressions to stdout."),
  +
  +    JS_FN_HELP("printErr", PrintErr, 0, 0,
  +"printErr([exp ...])",
  +"  Evaluate and print expressions to stderr."),
  +
  +    JS_FN_HELP("putstr", PutStr, 0, 0,
  +"putstr([exp])",
  +"  Evaluate and print expression without newline."),
  +
  +    JS_FN_HELP("dateNow", Now, 0, 0,
  +"dateNow()",
  +"  Return the current time with sub-ms precision."),
  +
  +    JS_FN_HELP("help", Help, 0, 0,
  +"help([name ...])",
  +"  Display usage and help messages."),
  +
  +    JS_FN_HELP("quit", Quit, 0, 0,
  +"quit()",
  +"  Quit the shell."),
  +
  +    JS_FN_HELP("assertEq", AssertEq, 2, 0,
  +"assertEq(actual, expected[, msg])",
  +"  Throw if the first two arguments are not the same (both +0 or both -0,\n"
  +"  both NaN, or non-zero and ===)."),
  +
  +    JS_FN_HELP("startTimingMutator", StartTimingMutator, 0, 0,
  +"startTimingMutator()",
  +"  Start accounting time to mutator vs GC."),
  +
  +    JS_FN_HELP("stopTimingMutator", StopTimingMutator, 0, 0,
  +"stopTimingMutator()",
  +"  Stop accounting time to mutator vs GC and dump the results."),
  +
  +    JS_FN_HELP("throwError", ThrowError, 0, 0,
  +"throwError()",
  +"  Throw an error from JS_ReportError."),
  +
  +#ifdef DEBUG
  +    JS_FN_HELP("disassemble", DisassembleToString, 1, 0,
  +"disassemble([fun/code])",
  +"  Return the disassembly for the given function or code.\n"
  +"  All disassembly functions take these options as leading string 
arguments:\n"
  +"    \"-r\" (disassemble recursively)\n"
  +"    \"-l\" (show line numbers)\n"
  +"    \"-S\" (omit source notes)"),
  +
  +    JS_FN_HELP("dis", Disassemble, 1, 0,
  +"dis([fun/code])",
  +"  Disassemble functions into bytecodes."),
  +
  +    JS_FN_HELP("disfile", DisassFile, 1, 0,
  +"disfile('foo.js')",
  +"  Disassemble script file into bytecodes.\n"),
  +
  +    JS_FN_HELP("dissrc", DisassWithSrc, 1, 0,
  +"dissrc([fun/code])",
  +"  Disassemble functions with source lines."),
  +
  +    JS_FN_HELP("notes", Notes, 1, 0,
  +"notes([fun])",
  +"  Show source notes for functions."),
  +
  +    JS_FN_HELP("stackDump", StackDump, 3, 0,
  +"stackDump(showArgs, showLocals, showThisProps)",
  +"  Tries to print a lot of information about the current stack. \n"
  +"  Similar to the DumpJSStack() function in the browser."),
  +
  +#endif
  +    JS_FN_HELP("intern", Intern, 1, 0,
  +"intern(str)",
  +"  Internalize str in the atom table."),
  +
  +    JS_FN_HELP("getslx", GetSLX, 1, 0,
  +"getslx(obj)",
  +"  Get script line extent."),
  +
  +    JS_FN_HELP("evalcx", EvalInContext, 1, 0,
  +"evalcx(s[, o])",
  +"  Evaluate s in optional sandbox object o.\n"
  +"  if (s == '' && !o) return new o with eager standard classes\n"
  +"  if (s == 'lazy' && !o) return new o with lazy standard classes"),
  +
  +    JS_FN_HELP("evalInWorker", EvalInWorker, 1, 0,
  +"evalInWorker(str)",
  +"  Evaluate 'str' in a separate thread with its own runtime.\n"),
  +
  +    JS_FN_HELP("getSharedArrayBuffer", GetSharedArrayBuffer, 0, 0,
  +"getSharedArrayBuffer()",
  +"  Retrieve the SharedArrayBuffer object from the cross-worker mailbox.\n"
  +"  The object retrieved may not be identical to the object that was\n"
  +"  installed, but it references the same shared memory.\n"
  +"  getSharedArrayBuffer performs an ordering memory barrier.\n"),
  +
  +    JS_FN_HELP("setSharedArrayBuffer", SetSharedArrayBuffer, 0, 0,
  +"setSharedArrayBuffer()",
  +"  Install the SharedArrayBuffer object in the cross-worker mailbox.\n"
  +"  setSharedArrayBuffer performs an ordering memory barrier.\n"),
  +
  +    JS_FN_HELP("shapeOf", ShapeOf, 1, 0,
  +"shapeOf(obj)",
  +"  Get the shape of obj (an implementation detail)."),
  +
  +#ifdef DEBUG
  +    JS_FN_HELP("arrayInfo", ArrayInfo, 1, 0,
  +"arrayInfo(a1, a2, ...)",
  +"  Report statistics about arrays."),
  +#endif
  +
  +    JS_FN_HELP("sleep", Sleep_fn, 1, 0,
  +"sleep(dt)",
  +"  Sleep for dt seconds."),
  +
  +    JS_FN_HELP("compile", Compile, 1, 0,
  +"compile(code)",
  +"  Compiles a string to bytecode, potentially throwing."),
  +
  +    JS_FN_HELP("parseModule", ParseModule, 1, 0,
  +"parseModule(code)",
  +"  Parses source text as a module and returns a Module object."),
  +
  +    JS_FN_HELP("setModuleResolveHook", SetModuleResolveHook, 1, 0,
  +"setModuleResolveHook(function(module, specifier) {})",
  +"  Set the HostResolveImportedModule hook to |function|.\n"
  +"  This hook is used to look up a previously loaded module object.  It 
should\n"
  +"  be implemented by the module loader."),
  +
  +    JS_FN_HELP("getModuleLoadPath", GetModuleLoadPath, 0, 0,
  +"getModuleLoadPath()",
  +"  Return any --module-load-path argument passed to the shell.  Used by 
the\n"
  +"  module loader.\n"),
  +
  +    JS_FN_HELP("parse", Parse, 1, 0,
  +"parse(code)",
  +"  Parses a string, potentially throwing."),
  +
  +    JS_FN_HELP("syntaxParse", SyntaxParse, 1, 0,
  +"syntaxParse(code)",
  +"  Check the syntax of a string, returning success value"),
  +
  +    JS_FN_HELP("offThreadCompileScript", OffThreadCompileScript, 1, 0,
  +"offThreadCompileScript(code[, options])",
  +"  Compile |code| on a helper thread. To wait for the compilation to 
finish\n"
  +"  and run the code, call |runOffThreadScript|. If present, |options| may\n"
  +"  have properties saying how the code should be compiled:\n"
  +"      noScriptRval: use the no-script-rval compiler option (default: 
false)\n"
  +"      fileName: filename for error messages and debug info\n"
  +"      lineNumber: starting line number for error messages and debug info\n"
  +"      columnNumber: starting column number for error messages and debug 
info\n"
  +"      element: if present with value |v|, convert |v| to an object |o| 
and\n"
  +"         mark the source as being attached to the DOM element |o|. If the\n"
  +"         property is omitted or |v| is null, don't attribute the source 
to\n"
  +"         any DOM element.\n"
  +"      elementAttributeName: if present and not undefined, the name of\n"
  +"         property of 'element' that holds this code. This is what\n"
  +"         Debugger.Source.prototype.elementAttributeName returns.\n"),
  +
  +    JS_FN_HELP("runOffThreadScript", runOffThreadScript, 0, 0,
  +"runOffThreadScript()",
  +"  Wait for off-thread compilation to complete. If an error occurred,\n"
  +"  throw the appropriate exception; otherwise, run the script and return\n"
  +"  its value."),
  +
  +    JS_FN_HELP("timeout", Timeout, 1, 0,
  +"timeout([seconds], [func])",
  +"  Get/Set the limit in seconds for the execution time for the current 
context.\n"
  +"  A negative value (default) means that the execution time is unlimited.\n"
  +"  If a second argument is provided, it will be invoked when the timer 
elapses.\n"
  +"  Calling this function will replace any callback set by 
|setInterruptCallback|.\n"),
  +
  +    JS_FN_HELP("interruptIf", InterruptIf, 1, 0,
  +"interruptIf(cond)",
  +"  Requests interrupt callback if cond is true. If a callback function is 
set via\n"
  +"  |timeout| or |setInterruptCallback|, it will be called. No-op 
otherwise."),
  +
  +    JS_FN_HELP("invokeInterruptCallback", InvokeInterruptCallbackWrapper, 0, 
0,
  +"invokeInterruptCallback(fun)",
  +"  Forcefully set the interrupt flag and invoke the interrupt handler. If 
a\n"
  +"  callback function is set via |timeout| or |setInterruptCallback|, it 
will\n"
  +"  be called. Before returning, fun is called with the return value of the\n"
  +"  interrupt handler."),
  +
  +    JS_FN_HELP("setInterruptCallback", SetInterruptCallback, 1, 0,
  +"setInterruptCallback(func)",
  +"  Sets func as the interrupt callback function.\n"
  +"  Calling this function will replace any callback set by |timeout|.\n"),
  +
  +    JS_FN_HELP("enableLastWarning", EnableLastWarning, 0, 0,
  +"enableLastWarning()",
  +"  Enable storing the last warning."),
  +
  +    JS_FN_HELP("disableLastWarning", DisableLastWarning, 0, 0,
  +"disableLastWarning()",
  +"  Disable storing the last warning."),
  +
  +    JS_FN_HELP("getLastWarning", GetLastWarning, 0, 0,
  +"getLastWarning()",
  +"  Returns an object that represents the last warning."),
  +
  +    JS_FN_HELP("clearLastWarning", ClearLastWarning, 0, 0,
  +"clearLastWarning()",
  +"  Clear the last warning."),
  +
  +    JS_FN_HELP("elapsed", Elapsed, 0, 0,
  +"elapsed()",
  +"  Execution time elapsed for the current context."),
  +
  +    JS_FN_HELP("decompileFunction", DecompileFunction, 1, 0,
  +"decompileFunction(func)",
  +"  Decompile a function."),
  +
  +    JS_FN_HELP("decompileThis", DecompileThisScript, 0, 0,
  +"decompileThis()",
  +"  Decompile the currently executing script."),
  +
  +    JS_FN_HELP("thisFilename", ThisFilename, 0, 0,
  +"thisFilename()",
  +"  Return the filename of the current script"),
  +
  +    JS_FN_HELP("newGlobal", NewGlobal, 1, 0,
  +"newGlobal([options])",
  +"  Return a new global object in a new compartment. If options\n"
  +"  is given, it may have any of the following properties:\n"
  +"      sameZoneAs: the compartment will be in the same zone as the given 
object (defaults to a new zone)\n"
  +"      invisibleToDebugger: the global will be invisible to the debugger 
(default false)\n"
  +"      principal: if present, its value converted to a number must be an\n"
  +"         integer that fits in 32 bits; use that as the new compartment's\n"
  +"         principal. Shell principals are toys, meant only for testing; 
one\n"
  +"         shell principal subsumes another if its set bits are a superset 
of\n"
  +"         the other's. Thus, a principal of 0 subsumes nothing, while a\n"
  +"         principals of ~0 subsumes all other principals. The absence of a\n"
  +"         principal is treated as if its bits were 0xffff, for subsumption\n"
  +"         purposes. If this property is omitted, supply no principal."),
  +
  +    JS_FN_HELP("nukeCCW", NukeCCW, 1, 0,
  +"nukeCCW(wrapper)",
  +"  Nuke a CrossCompartmentWrapper, which turns it into a DeadProxyObject."),
  +
  +    JS_FN_HELP("createMappedArrayBuffer", CreateMappedArrayBuffer, 1, 0,
  +"createMappedArrayBuffer(filename, [offset, [size]])",
  +"  Create an array buffer that mmaps the given file."),
  +
  +    JS_FN_HELP("getMaxArgs", GetMaxArgs, 0, 0,
  +"getMaxArgs()",
  +"  Return the maximum number of supported args for a call."),
  +
  +    JS_FN_HELP("objectEmulatingUndefined", ObjectEmulatingUndefined, 0, 0,
  +"objectEmulatingUndefined()",
  +"  Return a new object obj for which typeof obj === \"undefined\", obj == 
null\n"
  +"  and obj == undefined (and vice versa for !=), and ToBoolean(obj) === 
false.\n"),
  +
  +    JS_FN_HELP("isCachingEnabled", IsCachingEnabled, 0, 0,
  +"isCachingEnabled()",
  +"  Return whether JS caching is enabled."),
  +
  +    JS_FN_HELP("setCachingEnabled", SetCachingEnabled, 1, 0,
  +"setCachingEnabled(b)",
  +"  Enable or disable JS caching."),
  +
  +    JS_FN_HELP("cacheEntry", CacheEntry, 1, 0,
  +"cacheEntry(code)",
  +"  Return a new opaque object which emulates a cache entry of a script.  
This\n"
  +"  object encapsulates the code and its cached content. The cache entry is 
filled\n"
  +"  and read by the \"evaluate\" function by using it in place of the source, 
and\n"
  +"  by setting \"saveBytecode\" and \"loadBytecode\" options."),
  +
  +    JS_FN_HELP("printProfilerEvents", PrintProfilerEvents, 0, 0,
  +"printProfilerEvents()",
  +"  Register a callback with the profiler that prints javascript profiler 
events\n"
  +"  to stderr.  Callback is only registered if profiling is enabled."),
  +
  +    JS_FN_HELP("enableSingleStepProfiling", EnableSingleStepProfiling, 0, 0,
  +"enableSingleStepProfiling()",
  +"  This function will fail on platforms that don't support single-step 
profiling\n"
  +"  (currently everything but ARM-simulator). When enabled, at every 
instruction a\n"
  +"  backtrace will be recorded and stored in an array. Adjacent duplicate 
backtraces\n"
  +"  are discarded."),
  +
  +    JS_FN_HELP("disableSingleStepProfiling", DisableSingleStepProfiling, 0, 
0,
  +"disableSingleStepProfiling()",
  +"  Return the array of backtraces recorded by enableSingleStepProfiling."),
  +
  +    JS_FN_HELP("isLatin1", IsLatin1, 1, 0,
  +"isLatin1(s)",
  +"  Return true iff the string's characters are stored as Latin1."),
  +
  +    JS_FN_HELP("stackPointerInfo", StackPointerInfo, 0, 0,
  +"stackPointerInfo()",
  +"  Return an int32 value which corresponds to the offset of the latest 
stack\n"
  +"  pointer, such that one can take the differences of 2 to estimate a 
frame-size."),
  +
  +    JS_FN_HELP("entryPoints", EntryPoints, 1, 0,
  +"entryPoints(params)",
  +"Carry out some JSAPI operation as directed by |params|, and return an array 
of\n"
  +"objects describing which JavaScript entry points were invoked as a 
result.\n"
  +"|params| is an object whose properties indicate what operation to perform. 
Here\n"
  +"are the recognized groups of properties:\n"
  +"\n"
  +"{ function }: Call the object |params.function| with no arguments.\n"
  +"\n"
  +"{ object, property }: Fetch the property named |params.property| of\n"
  +"|params.object|.\n"
  +"\n"
  +"{ ToString }: Apply JS::ToString to |params.toString|.\n"
  +"\n"
  +"{ ToNumber }: Apply JS::ToNumber to |params.toNumber|.\n"
  +"\n"
  +"{ eval }: Apply JS::Evaluate to |params.eval|.\n"
  +"\n"
  +"The return value is an array of strings, with one element for each\n"
  +"JavaScript invocation that occurred as a result of the given\n"
  +"operation. Each element is the name of the function invoked, or the\n"
  +"string 'eval:FILENAME' if the code was invoked by 'eval' or something\n"
  +"similar.\n"),
  +
  +    JS_FS_HELP_END
  +};
  +#endif       /* NOTYET */
  +
  +/*==============================================================*/
  +static JSObject*
  +NewGlobalObject(JSContext* cx, JS::CompartmentOptions& options,
  +                JSPrincipals* principals)
  +{
  +
  +    JSClass * _clasp = (JSClass *)&global_class;
  +    const JSFunctionSpec * _functions = global_functions; /* XXX 
shell_functions */
  +
  +    RootedObject glob(cx,
  +             JS_NewGlobalObject(cx, _clasp, principals, 
JS::DontFireOnNewGlobalHook, options));
  +    if (!glob)
  +        return nullptr;
  +
  +    {
  +        JSAutoCompartment ac(cx, glob);
  +
  +#ifndef LAZY_STANDARD_CLASSES
  +        if (!JS_InitStandardClasses(cx, glob))
  +            return nullptr;
  +#endif
  +
  +#ifdef       DYING
  +        bool succeeded;
  +        if (!JS_SetImmutablePrototype(cx, glob, &succeeded))
  +            return nullptr;
  +        MOZ_ASSERT(succeeded,
  +                   "a fresh, unexposed global object is always capable of "
  +                   "having its [[Prototype]] be immutable");
  +#endif
  +
  +#ifdef JS_HAS_CTYPES
  +        if (!JS_InitCTypesClass(cx, glob))
  +            return nullptr;
  +#endif
  +
  +#ifdef       MOZILLA_DYING
  +        if (!JS_InitReflectParse(cx, glob))
  +            return nullptr;
  +        if (!JS_DefineDebuggerObject(cx, glob))
  +            return nullptr;
  +        if (!JS::RegisterPerfMeasurement(cx, glob))
  +            return nullptr;
  +        if (!JS_DefineFunctionsWithHelp(cx, glob, shell_functions) ||
  +            !JS_DefineProfilingFunctions(cx, glob))
  +        {
  +            return nullptr;
  +        }
  +#else        /* MOZILLA_DYING */
  +        if (!JS_DefineFunctions(cx, glob, _functions))
  +        {
  +            return nullptr;
  +        }
  +#endif       /* MOZILLA_DYING */
  +
  +#ifdef       DYING
  +        if (!js::DefineTestingFunctions(cx, glob, fuzzingSafe, 
disableOOMFunctions))
  +            return nullptr;
  +
  +        if (!fuzzingSafe) {
  +            if (!JS_DefineFunctionsWithHelp(cx, glob, 
fuzzing_unsafe_functions))
  +                return nullptr;
  +            if (!DefineConsole(cx, glob))
  +                return nullptr;
  +        }
  +
  +        if (!DefineOS(cx, glob, fuzzingSafe))
  +            return nullptr;
  +
  +        RootedObject performanceObj(cx, JS_NewObject(cx, nullptr));
  +        if (!performanceObj)
  +            return nullptr;
  +        RootedObject mozMemoryObj(cx, JS_NewObject(cx, nullptr));
  +        if (!mozMemoryObj)
  +            return nullptr;
  +        RootedObject gcObj(cx, gc::NewMemoryInfoObject(cx));
  +        if (!gcObj)
  +            return nullptr;
  +        if (!JS_DefineProperty(cx, glob, "performance", performanceObj, 
JSPROP_ENUMERATE))
  +            return nullptr;
  +        if (!JS_DefineProperty(cx, performanceObj, "mozMemory", 
mozMemoryObj, JSPROP_ENUMERATE))
  +            return nullptr;
  +        if (!JS_DefineProperty(cx, mozMemoryObj, "gc", gcObj, 
JSPROP_ENUMERATE))
  +            return nullptr;
  +
  +        /* Initialize FakeDOMObject. */
  +        static const js::DOMCallbacks DOMcallbacks = {
  +            InstanceClassHasProtoAtDepth
  +        };
  +        SetDOMCallbacks(cx->runtime(), &DOMcallbacks);
  +
  +        RootedObject domProto(cx, JS_InitClass(cx, glob, nullptr, 
&dom_class, dom_constructor,
  +                                               0, dom_props, dom_methods, 
nullptr, nullptr));
  +        if (!domProto)
  +            return nullptr;
  +
  +        /* Initialize FakeDOMObject.prototype */
  +        InitDOMObject(domProto);
  +
  +        if (!js::InitModuleClasses(cx, glob))
  +            return nullptr;
  +#endif       /* DYING */
  +    }
  +
  +    JS_FireOnNewGlobalObject(cx, glob);
  +
  +    return glob;
  +}
  +
   /*==============================================================*/
  -static void mozFini(rpmjs js)
  +static void mozFini(rpmjss jss)
   {
  -    JSI_t I = (JSI_t) js->I;
  +    JSI_t I = (JSI_t) jss->I;
   
       if (I->cx)
        JS_DestroyContext(I->cx);
  @@ -104,23 +732,24 @@
        JS_DestroyRuntime(I->rt);
       I->rt = NULL;
   
  -    if (--rpmjs_nopens <= 0)  {
  +    if (--rpmjss_nopens <= 0)  {
        JS_ShutDown();
  -     rpmjs_nopens = 0; 
  +     rpmjss_nopens = 0; 
       }   
       free(I);
   }
   
  -static void * mozInit(rpmjs js)
  +static void * mozInit(rpmjss jss)
   {   
       JSI_t I = NULL;
  -    uint32_t flags = js->flags;
  +    uint32_t flags = jss->flags;
   
       static uint32_t _maxbytes = 8L * 1024L * 1024L;
       static size_t _stackChunkSize = 8192;
  +    JSPrincipals * _principals = NULL;
       bool ok;
   
  -    if (rpmjs_nopens++ == 0)
  +    if (rpmjss_nopens++ == 0)
        JS_Init();
   
       I = (JSI_t) calloc(1, sizeof(*I));
  @@ -128,17 +757,27 @@
   
       I->rt = JS_NewRuntime(_maxbytes);
   assert(I->rt);
  -    JS_SetRuntimePrivate(I->rt, (void *)js);
  +    JS_SetRuntimePrivate(I->rt, (void *)jss);
   
       I->cx = JS_NewContext(I->rt, _stackChunkSize);
   assert(I->cx);
  -    JS_SetContextPrivate(I->cx, (void *)js);
  +    JS_SetContextPrivate(I->cx, (void *)jss);
   
  -#ifdef       NOTYET
  -    JS_SetErrorReporter(I->cx, rpmjsReportError);
  -#endif
  +    JS_SetErrorReporter(I->rt, rpmjssReportError);
  +    SetOutOfMemoryCallback(I->rt, rpmjssOOMCallback, nullptr);
   
  +  {
  +     RootedObject glob(I->cx);
  +     JS::CompartmentOptions options;
  +     options.setVersion(JSVERSION_DEFAULT);
  +     glob = NewGlobalObject(I->cx, options, _principals);
  +     I->global = glob;
  +assert(I->global);
  +  }
  +    
   #ifdef       HACK
  +     ok = JS_InitStandardClasses(I->cx, global);
  +assert(ok);
   #ifdef  JS_HAS_CTYPES
       ok = JS_InitCTypesClass(I->cx, I->global);
   assert(ok);
  @@ -153,39 +792,20 @@
       return I;
   }
   
  -static int mozRun(rpmjs js,
  -             const char * script, const char * filename, int lineno)
  +static int mozRun(rpmjss jss,
  +             const char * script, const char * fn, int ln)
   {
  -    JSI_t I = (JSI_t) js->I;
  +    JSI_t I = (JSI_t) jss->I;
   
  -    JSClass * _clasp = (JSClass *)&global_class;
  -#ifdef       NOTYET
  -    JSFunctionSpec * _functions = global_functions;
  -#endif
  -    JSPrincipals * _principals = NULL;
       bool ok;
   
  -    // In practice, you would want to exit this any
  -    // time you're spinning the event loop
  -    JSAutoRequest ar(I->cx);
  -
  -    JS::RootedObject global(I->cx,
  -             JS_NewGlobalObject(I->cx, _clasp, _principals, 
JS::FireOnNewGlobalHook));
  -    if (!global)
  -     return 1;
  -
  -    I->global = global;
  -assert(I->global);
  -
       JS::RootedValue rval(I->cx);
   
       {        // Scope for JSAutoCompartment
        JSAutoCompartment ac(I->cx, I->global);
  -     ok = JS_InitStandardClasses(I->cx, global);
  -assert(ok);
   
        JS::CompileOptions opts(I->cx);
  -     opts.setFileAndLine(filename, lineno);
  +     opts.setFileAndLine(fn, ln);
        ok = JS::Evaluate(I->cx, opts, script, strlen(script), &rval);
   
        if (!ok)
  @@ -201,27 +821,25 @@
   static struct JSIO_s _mozjs45 = { mozFini, mozInit, mozRun };
   JSIO_t mozjs45 = &_mozjs45;
   
  -#if defined(RPMJS_SELF_TEST)
  -struct rpmjs_s _js;
  -rpmjs js = &_js;
  +#if defined(RPMJSS_SELF_TEST)
  +struct rpmjss_s _jss;
  +rpmjss jss = &_jss;
   
   /*==============================================================*/
   int main(int argc, const char *argv[])
   {
       int rc = 0;
   
  -    JSI_t I = (JSI_t) mozInit(js);
  -    js->I = I;
  +    JSI_t I = (JSI_t) mozInit(jss);
  +    jss->I = I;
   
       {
        const char *script = "'hello'+'world, it is '+new Date()";
  -     const char *filename = "noname";
  -     int lineno = 1;
  -     rc = mozRun(js, script, filename, lineno);
  +     rc = mozRun(jss, script, __FILE__, __LINE__);
       }
   
  -    mozFini(js);
  +    mozFini(jss);
   
       return rc;
   }
  -#endif       /* RPMJS_SELF_TEST */
  +#endif       /* RPMJSS_SELF_TEST */
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/rpmjss.h
  ============================================================================
  $ cvs diff -u -r0 -r1.1.2.1 rpmjss.h
  --- /dev/null 2017-06-23 05:38:19.000000000 +0200
  +++ rpmjss.h  2017-06-23 05:39:44.199733788 +0200
  @@ -0,0 +1,141 @@
  +#ifndef RPMJSS_H
  +#define RPMJSS_H
  +
  +/** \ingroup rpmio
  + * \file rpmio/rpmjss.h
  + */
  +
  +#include <rpmiotypes.h>
  +#include <rpmio.h>
  +
  +typedef struct rpmjss_s * rpmjss;
  +
  +extern int _rpmjss_debug;
  +
  +extern rpmjss _rpmjssI;
  +
  +extern uint32_t _rpmjss_options;
  +
  +extern int _rpmjss_zeal;
  +
  +#if defined(_RPMJSS_INTERNAL)
  +/**
  + * Interpreter flags.
  + */
  +enum rpmjssFlags_e {
  +    RPMJSS_FLAGS_NONE                = 0,
  +    RPMJSS_FLAGS_STRICT              = (1<< 0),      /* JSOPTION_STRICT */
  +    RPMJSS_FLAGS_WERROR              = (1<< 1),      /* JSOPTION_WERROR */
  +    RPMJSS_FLAGS_VAROBJFIX   = (1<< 2),      /* JSOPTION_VAROBJFIX */
  +    RPMJSS_FLAGS_PRIVATE_IS_NSISUPPORTS = (1<< 3), /* 
JSOPTION_PRIVATE_IS_NSISUPPORTS */
  +    RPMJSS_FLAGS_COMPILE_N_GO        = (1<< 4),      /* 
JSOPTION_COMPILE_N_GO */
  +    RPMJSS_FLAGS_ATLINE              = (1<< 5),      /* JSOPTION_ATLINE */
  +    RPMJSS_FLAGS_XML         = (1<< 6),      /* JSOPTION_XML */
  +     /* bit 7 unused */
  +    RPMJSS_FLAGS_DONT_REPORT_UNCAUGHT = (1<< 8),     /* 
JSOPTION_DONT_REPORT_UNCAUGHT */
  +    RPMJSS_FLAGS_RELIMIT             = (1<< 9),      /* JSOPTION_RELIMIT */
  +    RPMJSS_FLAGS_ANONFUNFIX  = (1<<10),      /* JSOPTION_ANONFUNFIX */
  +    RPMJSS_FLAGS_JIT         = (1<<11),      /* JSOPTION_JIT */
  +    RPMJSS_FLAGS_NO_SCRIPT_RVAL      = (1<<12),      /* 
JSOPTION_NO_SCRIPT_RVAL */
  +    RPMJSS_FLAGS_UNROOTED_GLOBAL     = (1<<13),      /* 
JSOPTION_UNROOTED_GLOBAL */
  +     /* bits 14-15 unused */
  +    RPMJSS_FLAGS_NOEXEC              = (1<<16),      /*!< -n */
  +    RPMJSS_FLAGS_SKIPSHEBANG = (1<<17),      /*!< -F */
  +    RPMJSS_FLAGS_LOADRC              = (1<<18),      /*!< -R */
  +    RPMJSS_FLAGS_NOUTF8              = (1<<19),      /*!< -U */
  +    RPMJSS_FLAGS_NOCACHE             = (1<<20),      /*!< -C */
  +    RPMJSS_FLAGS_NOWARN              = (1<<21),      /*!< -W */
  +    RPMJSS_FLAGS_ALLOW               = (1<<22),      /*!< -a */
  +     /* bits 23-30 unused */
  +    RPMJSS_FLAGS_GLOBAL              = (1<<31),
  +};
  +
  +typedef      struct JSIO_s * JSIO_t;
  +struct JSIO_s {
  +    void (*mozFini)  (rpmjss jss);
  +    void * (*mozInit)        (rpmjss jss);
  +    int  (*mozRun)   (rpmjss jss, const char * script, const char * 
filename, int lineno);
  +};
  +
  +extern JSIO_t mozjs185;
  +extern JSIO_t mozjs17;
  +extern JSIO_t mozjs24;
  +extern JSIO_t mozjs31;
  +extern JSIO_t mozjs38;
  +extern JSIO_t mozjs45;
  +
  +struct rpmjss_s {
  +    struct rpmioItem_s _item;        /*!< usage mutex and pool identifier. */
  +    uint32_t flags;          /*!< JSOPTION_FOO in 0xffff bits */
  +    JSIO_t jsio;
  +    void * I;                        /*!< JS interpreter {rt, cx, globalObj} 
*/
  +};
  +
  +struct rpmjss_s _rpmjss;
  +
  +#endif /* _RPMJSS_INTERNAL */
  +
  +#ifdef __cplusplus
  +extern "C" {
  +#endif
  +
  +/**
  + * Unreference a js shell interpreter instance.
  + * @param jss                js shell interpreter
  + * @return           NULL on last dereference
  + */
  +rpmjss rpmjssUnlink (rpmjss jss);
  +#define      rpmjssUnlink(_jss)      \
  +    ((rpmjss)rpmioUnlinkPoolItem((rpmioItem)(_jss), __FUNCTION__, __FILE__, 
__LINE__))
  +
  +/**
  + * Reference a js shell interpreter instance.
  + * @param jss                js shell interpreter
  + * @return           new js shell interpreter reference
  + */
  +rpmjss rpmjssLink (rpmjss jss);
  +#define      rpmjssLink(_jss)        \
  +    ((rpmjss)rpmioLinkPoolItem((rpmioItem)(_jss), __FUNCTION__, __FILE__, 
__LINE__))
  +
  +/**
  + * Destroy a js shell interpreter.
  + * @param jss                js shell interpreter
  + * @return           NULL on last dereference
  + */
  +rpmjss rpmjssFree(rpmjss jss);
  +#define      rpmjssFree(_jss)        \
  +    ((rpmjss)rpmioFreePoolItem((rpmioItem)(_jss), __FUNCTION__, __FILE__, 
__LINE__))
  +
  +/**
  + * Create and load a js shell interpreter.
  + * @param av         js shell interpreter args (or NULL)
  + * @param flags              js shell interpreter flags ((1<<31): use global 
interpreter)
  + * @return           new js interpreter
  + */
  +rpmjss rpmjssNew(char ** av, uint32_t flags);
  +
  +/**
  + * Execute js from a file.
  + * @param js         js interpreter (NULL uses global interpreter)
  + * @param fn         js file to run (NULL returns RPMRC_FAIL)
  + * @param Iargv              js script argv
  + * @param resultp    *resultp js exec result
  + * @return           RPMRC_OK on success
  + */
  +rpmRC rpmjssRunFile(rpmjss jss, const char * fn,
  +             char *const * Iargv, const char ** resultp);
  +
  +/**
  + * Execute js string.
  + * @param js         js interpreter (NULL uses global interpreter)
  + * @param str                js string to execute (NULL returns RPMRC_FAIL)
  + * @param resultp    *resultp js exec result
  + * @return           RPMRC_OK on success
  + */
  +rpmRC rpmjssRun(rpmjss jss, const char * str, const char ** resultp);
  +
  +#ifdef __cplusplus
  +}
  +#endif
  +
  +#endif /* RPMJSS_H */
  @@ .
______________________________________________________________________
RPM Package Manager                                    http://rpm5.org
CVS Sources Repository                                rpm-cvs@rpm5.org

Reply via email to