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:   10-Jul-2017 11:42:51
  Branch: rpm-5_4                          Handle: 2017071009425100

  Added files:              (Branch: rpm-5_4)
    rpm/rpmio               rpmev.c rpmjss.cpp

  Log:
    - create.

  Summary:
    Revision    Changes     Path
    1.1.2.1     +649 -0     rpm/rpmio/rpmev.c
    1.1.2.1     +996 -0     rpm/rpmio/rpmjss.cpp
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: rpm/rpmio/rpmev.c
  ============================================================================
  $ cvs diff -u -r0 -r1.1.2.1 rpmev.c
  --- /dev/null 2017-07-10 11:35:46.000000000 +0200
  +++ rpmev.c   2017-07-10 11:42:51.797005547 +0200
  @@ -0,0 +1,649 @@
  +#include "system.h"
  +#include <stdarg.h>
  +
  +#if defined(WITH_LIBEV)
  +
  +#if defined(HAVE_EV_H)
  +# include <ev.h>
  +#endif
  +
  +#else        /* WITH_LIBEV */
  +
  +/* XXX stub in enough to include rpmev.h */
  +#define      EV_P_   void * loop,
  +struct ev_watcher {
  +    int active;
  +    int pending;
  +    int priority;
  +    void * data;
  +    void (*cb)(EV_P_ void *w, int revents);
  +};
  +
  +union ev_any_watcher
  +{
  +    struct ev_watcher w;
  +};
  +
  +#endif       /* WITH_LIBEV */
  +
  +#include <rpmio.h>
  +#include <poptIO.h>
  +
  +#define      _RPMEV_INTERNAL
  +#include <rpmev.h>
  +
  +#include "debug.h"
  +
  +int _rpmev_debug = -1;
  +
  +#define SPEW(_fmt, ...) \
  +    if (_rpmev_debug || _rpmio_debug) \
  +     fprintf(stderr, _fmt, __VA_ARGS__)
  +
  +/*==============================================================*/
  +unsigned rpmioEV = 0;
  +struct poptOption rpmioEVTable[] = {
  +#if defined(WITH_LIBEV)
  + { "read", '\0', POPT_BIT_SET,               &rpmioEV, EV_READ,
  +        N_("read"), N_("EV_READ") },
  + { "write", '\0', POPT_BIT_SET,              &rpmioEV, EV_WRITE,
  +        N_("write"), N_("EV_WRITE") },
  + { "internal", '\0', POPT_BIT_SET,   &rpmioEV, EV__IOFDSET,
  +        N_("internal"), N_("EV__IOFDSET") },
  + { "timer", '\0', POPT_BIT_SET,              &rpmioEV, EV_TIMER,
  +        N_("timer"), N_("EV_TIMER") },
  + { "periodic", '\0', POPT_BIT_SET,   &rpmioEV, EV_PERIODIC,
  +        N_("periodic"), N_("EV_PERIODIC") },
  + { "signal", '\0', POPT_BIT_SET,     &rpmioEV, EV_SIGNAL,
  +        N_("signal"), N_("EV_SIGNAL") },
  + { "child", '\0', POPT_BIT_SET,              &rpmioEV, EV_CHILD,
  +        N_("child"), N_("EV_CHILD") },
  + { "stat", '\0', POPT_BIT_SET,               &rpmioEV, EV_STAT,
  +        N_("stat"), N_("EV_STAT") },
  + { "idle", '\0', POPT_BIT_SET,               &rpmioEV, EV_IDLE,
  +        N_("idle"), N_("EV_IDLE") },
  + { "prepare", '\0', POPT_BIT_SET,    &rpmioEV, EV_PREPARE,
  +        N_("prepare"), N_("EV_PREPARE") },
  + { "check", '\0', POPT_BIT_SET,              &rpmioEV, EV_CHECK,
  +        N_("check"), N_("EV_CHECK") },
  + { "embed", '\0', POPT_BIT_SET,              &rpmioEV, EV_EMBED,
  +        N_("embed"), N_("EV_EMBED") },
  + { "fork", '\0', POPT_BIT_SET,               &rpmioEV, EV_FORK,
  +        N_("fork"), N_("EV_FORK") },
  + { "cleanup", '\0', POPT_BIT_SET,    &rpmioEV, EV_CLEANUP,
  +        N_("cleanup"), N_("EV_CLEANUP") },
  + { "async", '\0', POPT_BIT_SET,              &rpmioEV, EV_ASYNC,
  +        N_("async"), N_("EV_ASYNC") },
  + { "custom", '\0', POPT_BIT_SET,     &rpmioEV, EV_CUSTOM,
  +        N_("custom"), N_("EV_CUSTOM") },
  + { "error", '\0', POPT_BIT_SET,              &rpmioEV, EV_ERROR,
  +        N_("error"), N_("EV_ERROR") },
  +#endif       /* WITH_LIBEV */
  +   POPT_TABLEEND
  +};
  +
  +unsigned rpmioEVFLAG = 0;
  +struct poptOption rpmioEVFLAGTable[] = {
  +#if defined(WITH_LIBEV)
  + { "env", '\0', POPT_BIT_CLR|POPT_ARGFLAG_TOGGLE,    &rpmioEVFLAG, 
EVFLAG_NOENV,
  +        N_("env"), N_("EVFLAG_NOENV") },
  + { "forkcheck", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,      &rpmioEVFLAG, 
EVFLAG_FORKCHECK,
  +        N_("forkcheck"), N_("EVFLAG_FORKCHECK") },
  + { "inotify", '\0', POPT_BIT_CLR|POPT_ARGFLAG_TOGGLE, &rpmioEVFLAG, 
EVFLAG_NOINOTIFY,
  +        N_("inotify"), N_("EVFLAG_NOINOTIFY") },
  + { "signalfd", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE, &rpmioEVFLAG, 
EVFLAG_SIGNALFD,
  +        N_("signalfd"), N_("EVFLAG_SIGNALFD") },
  + { "sigmask", '\0', POPT_BIT_CLR|POPT_ARGFLAG_TOGGLE, &rpmioEVFLAG, 
EVFLAG_NOSIGMASK,
  +        N_("sigmask"), N_("EVFLAG_NOSIGMASK") },
  +#endif       /* WITH_LIBEV */
  +   POPT_TABLEEND
  +};
  +
  +unsigned rpmioEVBACKEND = 0;
  +struct poptOption rpmioEVBACKENDTable[] = {
  +#if defined(WITH_LIBEV)
  + { "select", '\0', POPT_BIT_SET,     &rpmioEVBACKEND, EVBACKEND_SELECT,
  +        N_("select"), N_("EVBACKEND_SELECT") },
  + { "poll", '\0', POPT_BIT_SET,               &rpmioEVBACKEND, EVBACKEND_POLL,
  +        N_("poll"), N_("EVBACKEND_POLL") },
  + { "epoll", '\0', POPT_BIT_SET,              &rpmioEVBACKEND, 
EVBACKEND_EPOLL,
  +        N_("epoll"), N_("EVBACKEND_EPOLL") },
  + { "kqueue", '\0', POPT_BIT_SET,     &rpmioEVBACKEND, EVBACKEND_KQUEUE,
  +        N_("kqueue"), N_("EVBACKEND_KQUEUE") },
  + { "devpoll", '\0', POPT_BIT_SET,    &rpmioEVBACKEND, EVBACKEND_DEVPOLL,
  +        N_("devpoll"), N_("EVBACKEND_DEVPOLL") },
  + { "port", '\0', POPT_BIT_SET,               &rpmioEVBACKEND, EVBACKEND_PORT,
  +        N_("port"), N_("EVBACKEND_PORT") },
  +#endif       /* WITH_LIBEV */
  +   POPT_TABLEEND
  +};
  +
  +/*==============================================================*/
  +/* every watcher type has its own typedef'd struct */
  +/* with the name ev_TYPE */
  +
  +static rpmioItem rpmevqHead = NULL;
  +static rpmioItem * rpmevqTail = &rpmevqHead;
  +
  +rpmev rpmevqGetHead(void)
  +{
  +    rpmioItem item;
  +    RPM_GNUC_TM_ATOMIC {
  +        if ((item = rpmevqHead) != NULL) {
  +            rpmevqHead = item->next;
  +            item->next = NULL;
  +            if (rpmevqHead == NULL)
  +                rpmevqTail = &rpmevqHead;
  +        }
  +    }
  +if (item)
  +SPEW("<--\t%s() rc %p\n", __FUNCTION__, item);
  +    return (rpmev) item;
  +}
  +
  +void rpmevqPutTail(rpmev ev)
  +{
  +SPEW("-->\t%s(%p)\n", __FUNCTION__, ev);
  +    if (ev == NULL)
  +     return;
  +    rpmioItem item = &ev->_item;
  +    item->next = NULL;
  +    RPM_GNUC_TM_ATOMIC {
  +     *rpmevqTail = item;
  +        rpmevqTail = (rpmioItem *) &item->next;
  +    }
  +}
  +
  +void rpmevqPutHead(rpmev ev)
  +{
  +SPEW("-->\t%s(%p)\n", __FUNCTION__, ev);
  +    if (ev == NULL)
  +     return;
  +    rpmioItem item = &ev->_item;
  +    RPM_GNUC_TM_ATOMIC {
  +     item->next = rpmevqHead->next;
  +     if (item->next == NULL)
  +         rpmevqTail = (rpmioItem *) &item->next;
  +     rpmevqHead->next = item;
  +    }
  +}
  +
  +static void rpmevqRemove(rpmev ev)
  +{
  +SPEW("-->\t%s(%p)\n", __FUNCTION__, ev);
  +    if (ev == NULL)
  +     return;
  +    rpmioItem item = &ev->_item;
  +    rpmioItem * prev = &rpmevqHead;
  +    while (prev && (*prev)->next != NULL) {
  +     if ((*prev)->next == item) {
  +         (*prev)->next = item->next;
  +         item->next = NULL;
  +         if (rpmevqHead == NULL)
  +             rpmevqTail = &rpmevqHead;
  +         break;
  +     }
  +     prev = (*prev)->next;
  +    }
  +}
  +
  +/* all watcher callbacks have a similar signature */
  +
  +/* --- */
  +static
  +void rpmevChild_cb(EV_P_ void * _w, int revents)
  +{
  +#if defined(WITH_LIBEV)
  +    ev_child * w = (ev_child *) _w;
  +    rpmev ev = (rpmev) w->data;
  +assert(ev && ev->evtype == RPMEV_TYPE_CHILD);
  +  { char *rstr = rpmioB2N(rpmioEVTable, revents);
  +    SPEW("--> %s(%p, %s) pid %u status %u (0x%x)\n", __FUNCTION__, w, rstr, 
w->rpid, __WEXITSTATUS(w->rstatus), w->rstatus);
  +    rstr = _free(rstr);
  +  }
  +    ev_child_stop (EV_A_ w);
  +#ifdef       BUGGY
  +    ev = rpmevFree(ev);              /* XXX deallocate w rpmevRemove(ev)? */
  +#endif
  +#endif       /* WITH_LIBEV */
  +}
  +
  +static
  +int rpmevStart(void)
  +{
  +    int rc;
  +SPEW("--> %s()\n", __FUNCTION__);
  +    pid_t pid = fork();
  +    if (pid < 0) {
  +     rc = -1;
  +     exit(rc);
  +    } else if (pid == 0) {
  +     sleep(2);
  +     rc = 42;
  +     exit(rc);
  +    } else {
  +     rpmev ev = rpmevNew(RPMEV_TYPE_CHILD, NULL, pid, 0);
  +     (void)ev;
  +#ifdef       DYING
  +     ev_child * w = &ev->evw.child;
  +     w->pid = 0;
  +     w->flags = 0;   /** XXX 0=terminate, 1=stop/continue */
  +     ev_child_start (EV_DEFAULT_ w);
  +#endif
  +     rc = 0;
  +    }
  +SPEW("<-- %s() rc %d\n", __FUNCTION__, rc);
  +    return rc;
  +}
  +
  +/* --- */
  +static void rpmevIo_cb(EV_P_ void * _w, int revents)
  +{
  +#if defined(WITH_LIBEV)
  +    ev_io * w = (ev_io *) _w;
  +    rpmev ev = (rpmev) w->data;
  +assert(ev && ev->evtype == RPMEV_TYPE_IO);
  +  { char *rstr = rpmioB2N(rpmioEVTable, revents);
  +    SPEW("--> %s(%p, %s) fd %d events 0x%x\n", __FUNCTION__, w, rstr, w->fd, 
w->events);
  +    rstr = _free(rstr);
  +  }
  +    /* for one-shot events, one must manually stop the watcher */
  +    /* with its corresponding stop function. */
  +    ev_io_stop(EV_A_ w);
  +
  +    /* this causes all nested ev_loop's to stop iterating */
  +    ev_unloop(EV_A_ EVUNLOOP_ALL);
  +#endif       /* WITH_LIBEV */
  +}
  +/* --- */
  +static void rpmevTimer_cb(EV_P_ void * _w, int revents)
  +{
  +#if defined(WITH_LIBEV)
  +    ev_timer * w = (ev_timer *) _w;
  +    rpmev ev = (rpmev) w->data;
  +assert(ev && ev->evtype == RPMEV_TYPE_TIMER);
  +  { char *rstr = rpmioB2N(rpmioEVTable, revents);
  +    SPEW("--> %s(%p, %s) repeat %f\n", __FUNCTION__, w, rstr, w->repeat);
  +    rstr = _free(rstr);
  +  }
  +#ifdef       DYING
  +    /* this causes the innermost ev_loop to stop iterating */
  +    ev_unloop(EV_A_ EVUNLOOP_ONE);
  +#endif
  +    w->repeat = 5.5;
  +    ev_timer_again(EV_A_ w);
  +#endif       /* WITH_LIBEV */
  +}
  +
  +/* --- */
  +static void rpmevPeriodic_cb(EV_P_ void * _w, int revents)
  +{
  +#if defined(WITH_LIBEV)
  +    ev_periodic * w = (ev_periodic *) _w;
  +    rpmev ev = (rpmev) w->data;
  +assert(ev && ev->evtype == RPMEV_TYPE_PERIODIC);
  +  { char *rstr = rpmioB2N(rpmioEVTable, revents);
  +    SPEW("--> %s(%p, %s) offset %f interval %f reschedule_cb %p\n", 
__FUNCTION__, w, rstr, w->offset, w->interval, w->reschedule_cb);
  +    rstr = _free(rstr);
  +  }
  +    rpmevStart();
  +#endif       /* WITH_LIBEV */
  +}
  +
  +/* --- */
  +static void rpmevSignal_cb(EV_P_ void * _w, int revents)
  +{
  +#if defined(WITH_LIBEV)
  +    ev_signal * w = (ev_signal *) _w;
  +    rpmev ev = (rpmev) w->data;
  +assert(ev && ev->evtype == RPMEV_TYPE_SIGNAL);
  +  { char *rstr = rpmioB2N(rpmioEVTable, revents);
  +    SPEW("--> %s(%p, %s) signum %d\n", __FUNCTION__, w, rstr, w->signum);
  +    rstr = _free(rstr);
  +  }
  +#endif       /* WITH_LIBEV */
  +}
  +
  +/* --- */
  +static void rpmevStat_cb(EV_P_ void * _w, int revents)
  +{
  +#if defined(WITH_LIBEV)
  +    ev_stat * w = (ev_stat *) _w;
  +    rpmev ev = (rpmev) w->data;
  +assert(ev && ev->evtype == RPMEV_TYPE_STAT);
  +  { char *rstr = rpmioB2N(rpmioEVTable, revents);
  +    SPEW("--> %s(%p, %s) path %s wd %d\n", __FUNCTION__, w, rstr, w->path, 
w->wd);
  +    rstr = _free(rstr);
  +  }
  +#endif       /* WITH_LIBEV */
  +}
  +
  +/* --- */
  +static void rpmevIdle_cb(EV_P_ void * _w, int revents)
  +{
  +#if defined(WITH_LIBEV)
  +    ev_idle * w = (ev_idle *) _w;
  +    rpmev ev = (rpmev) w->data;
  +assert(ev && ev->evtype == RPMEV_TYPE_IDLE);
  +#ifdef       NOISY
  +  { char *rstr = rpmioB2N(rpmioEVTable, revents);
  +    SPEW("--> %s(%p, %s)\n", __FUNCTION__, w, rstr);
  +    rstr = _free(rstr);
  +  }
  +#endif
  +    struct timespec ts = { 0, 10*1000*1000 };
  +    nanosleep(&ts, NULL);
  +    sched_yield();
  +#endif       /* WITH_LIBEV */
  +}
  +
  +/* --- */
  +static void rpmevPrepare_cb(EV_P_ void * _w, int revents)
  +{
  +#if defined(WITH_LIBEV)
  +    ev_prepare * w = (ev_prepare *) _w;
  +    rpmev ev = (rpmev) w->data;
  +assert(ev && ev->evtype == RPMEV_TYPE_PREPARE);
  +  { char *rstr = rpmioB2N(rpmioEVTable, revents);
  +    SPEW("--> %s(%p, %s)\n", __FUNCTION__, w, rstr);
  +    rstr = _free(rstr);
  +  }
  +#endif       /* WITH_LIBEV */
  +}
  +
  +/* --- */
  +static void rpmevCheck_cb(EV_P_ void * _w, int revents)
  +{
  +#if defined(WITH_LIBEV)
  +    ev_check * w = (ev_check *) _w;
  +    rpmev ev = (rpmev) w->data;
  +assert(ev && ev->evtype == RPMEV_TYPE_CHECK);
  +  { char *rstr = rpmioB2N(rpmioEVTable, revents);
  +    SPEW("--> %s(%p, %s)\n", __FUNCTION__, w, rstr);
  +    rstr = _free(rstr);
  +  }
  +#endif       /* WITH_LIBEV */
  +}
  +
  +/* --- */
  +static void rpmevFork_cb(EV_P_ void * _w, int revents)
  +{
  +#if defined(WITH_LIBEV)
  +    ev_fork * w = (ev_fork *) _w;
  +    rpmev ev = (rpmev) w->data;
  +assert(ev && ev->evtype == RPMEV_TYPE_FORK);
  +  { char *rstr = rpmioB2N(rpmioEVTable, revents);
  +    SPEW("--> %s(%p, %s)\n", __FUNCTION__, w, rstr);
  +    rstr = _free(rstr);
  +  }
  +#endif       /* WITH_LIBEV */
  +}
  +
  +/* --- */
  +static void rpmevCleanup_cb(EV_P_ void * _w, int revents)
  +{
  +#if defined(WITH_LIBEV)
  +    ev_cleanup * w = (ev_cleanup *) _w;
  +    rpmev ev = (rpmev) w->data;
  +assert(ev && ev->evtype == RPMEV_TYPE_CLEANUP);
  +  { char *rstr = rpmioB2N(rpmioEVTable, revents);
  +    SPEW("--> %s(%p, %s)\n", __FUNCTION__, w, rstr);
  +    rstr = _free(rstr);
  +  }
  +#endif       /* WITH_LIBEV */
  +}
  +
  +/* --- */
  +static void rpmevEmbed_cb(EV_P_ void * _w, int revents)
  +{
  +#if defined(WITH_LIBEV)
  +    ev_embed * w = (ev_embed *) _w;
  +    rpmev ev = (rpmev) w->data;
  +assert(ev && ev->evtype == RPMEV_TYPE_EMBED);
  +  { char *rstr = rpmioB2N(rpmioEVTable, revents);
  +    SPEW("--> %s(%p, %s)\n", __FUNCTION__, w, rstr);
  +    rstr = _free(rstr);
  +  }
  +#endif       /* WITH_LIBEV */
  +}
  +
  +/* --- */
  +static void rpmevAsync_cb(EV_P_ void * _w, int revents)
  +{
  +#if defined(WITH_LIBEV)
  +    ev_async * w = (ev_async *) _w;
  +    rpmev ev = (rpmev) w->data;
  +assert(ev && ev->evtype == RPMEV_TYPE_ASYNC);
  +  { char *rstr = rpmioB2N(rpmioEVTable, revents);
  +    SPEW("--> %s(%p, %s)\n", __FUNCTION__, w, rstr);
  +    rstr = _free(rstr);
  +  }
  +#endif       /* WITH_LIBEV */
  +}
  +
  +void rpmevDump(const char *msg, rpmev ev, FILE *fp)
  +{
  +    if (fp == NULL)  fp = stderr;
  +    if (msg) fprintf(stderr, "========================= %s(%p)\n", msg, ev);
  +    if (ev) {
  +#define PRINT(_fmt, _foo) \
  +    {   fprintf(fp, "%25s: %"#_fmt"\n", #_foo, ev->_foo); }
  +     PRINT(u, evtype);
  +     PRINT(d, evw.w.active);
  +     PRINT(d, evw.w.pending);
  +     PRINT(p, evw.w.data);
  +     PRINT(p, evw.w.cb);
  +     PRINT(p, _item.next);
  +fprintf(stderr, "%25s: &%p next %p\n", "head", &rpmevqHead, (rpmevqHead ? 
rpmevqHead->next : NULL));
  +fprintf(stderr, "%25s:  %p next %p\n", "tail", rpmevqTail, (rpmevqTail ? 
*rpmevqTail : NULL));
  +#undef       PRINT
  +
  +    }
  +}
  +
  +static void rpmevFini(void *_ev)
  +{
  +    rpmev ev = (rpmev) _ev;
  +    if (ev) {
  +
  +#ifdef       BUGGY
  +     /* If still linked into thge allocation chain, unlink. */
  +     if (ev->_item.next)
  +         rpmevqRemove(ev);
  +#endif
  +
  +#if defined(WITH_LIBEV)
  +     /* XXX ev->loop private loops? */
  +     struct ev_loop *loop = ev_default_loop_uc_();
  +
  +     if (loop)
  +     switch (ev->evtype) {
  +     default:
  +     case RPMEV_TYPE_UNKNOWN:
  +     {   ev_watcher * w = &ev->evw.w;
  +         (void *)w;
  +     }   break;
  +     case RPMEV_TYPE_IO:
  +     {   ev_io * w = &ev->evw.io;
  +         ev_io_stop(loop, w);
  +     }   break;
  +     case RPMEV_TYPE_TIMER:
  +     {   ev_timer * w = &ev->evw.timer;
  +         ev_timer_stop(loop, w);
  +     }   break;
  +     case RPMEV_TYPE_PERIODIC:
  +     {   ev_periodic * w = &ev->evw.periodic;
  +         ev_periodic_stop(loop, w);
  +     }   break;
  +     case RPMEV_TYPE_SIGNAL:
  +     {   ev_signal * w = &ev->evw.signal;
  +         ev_signal_stop(loop, w);
  +     }   break;
  +     case RPMEV_TYPE_CHILD:
  +     {   ev_child * w = &ev->evw.child;
  +         ev_child_stop(loop, w);
  +     }   break;
  +     case RPMEV_TYPE_STAT:
  +     {   ev_stat * w = &ev->evw.stat;
  +         ev_stat_stop(loop, w);
  +         w->path = _free(w->path);
  +     }   break;
  +     case RPMEV_TYPE_IDLE:
  +     {   ev_idle * w = &ev->evw.idle;
  +         ev_idle_stop(loop, w);
  +     }   break;
  +     case RPMEV_TYPE_PREPARE:
  +     {   ev_prepare * w = &ev->evw.prepare;
  +         ev_prepare_stop(loop, w);
  +     }   break;
  +     case RPMEV_TYPE_CHECK:
  +     {   ev_check * w = &ev->evw.check;
  +         ev_check_stop(loop, w);
  +     }   break;
  +     case RPMEV_TYPE_FORK:
  +     {   ev_fork * w = &ev->evw.fork;
  +         ev_fork_stop(loop, w);
  +     }   break;
  +     case RPMEV_TYPE_CLEANUP:
  +     {   ev_cleanup * w = &ev->evw.cleanup;
  +         ev_cleanup_stop(loop, w);
  +     }   break;
  +     case RPMEV_TYPE_EMBED:
  +     {   ev_embed * w = &ev->evw.embed;
  +         ev_embed_stop(loop, w);
  +     }   break;
  +     case RPMEV_TYPE_ASYNC:
  +     {   ev_async * w = &ev->evw.async;
  +         ev_async_stop(loop, w);
  +     }   break;
  +     }
  +#endif       /* WITH_LIBEV */
  +
  +     /* XXX stop/destroyiterate loop? */
  +     ev->evtype = 0;
  +    }
  +}
  +
  +#define      rpmevDbug       NULL
  +#define      rpmevInit       NULL
  +RPMIOPOOL_MODULE(ev)
  +
  +rpmev rpmevNew(rpmevType evtype, void * _evcb, ...)
  +{
  +    rpmev ev = rpmevGetPool(_rpmevPool);
  +
  +    ev->evtype = evtype;
  +
  +#if defined(WITH_LIBEV)
  +    struct ev_loop *loop = ev_default_loop(EVFLAG_AUTO);
  +    va_list ap;
  +
  +    /* Initialize the base class. */
  +    ev_watcher * watcher = &ev->evw.w;
  +    ev_init(watcher, _evcb);
  +    watcher->data = ev;
  +
  +    /* Process args and start the event. */
  +    va_start(ap, _evcb);
  +
  +    switch (evtype) {
  +    default:
  +    case RPMEV_TYPE_UNKNOWN:
  +    {   ev_watcher * w = &ev->evw.w;
  +     (void *)w;      /* XXX NOTYET */
  +    }        break;
  +    case RPMEV_TYPE_IO:
  +    {        ev_io * w = &ev->evw.io;
  +     w->cb = (_evcb ? _evcb : rpmevIo_cb);
  +     w->fd = va_arg(ap, int);
  +     w->events = va_arg(ap, int);
  +     ev_io_start(loop, w);
  +    }        break;
  +    case RPMEV_TYPE_TIMER:
  +    {        ev_timer * w = &ev->evw.timer;
  +     w->cb = (_evcb ? _evcb : rpmevTimer_cb);
  +     w->at = va_arg(ap, ev_tstamp);
  +     w->repeat = va_arg(ap, ev_tstamp);
  +     ev_timer_start(loop, w);
  +    }        break;
  +    case RPMEV_TYPE_PERIODIC:
  +    {        ev_periodic * w = &ev->evw.periodic;
  +     w->cb = (_evcb ? _evcb : rpmevPeriodic_cb);
  +     w->offset = va_arg(ap, ev_tstamp);
  +     w->interval = va_arg(ap, ev_tstamp);
  +     w->reschedule_cb = va_arg(ap, void *);
  +     ev_periodic_start(loop, w);
  +    }        break;
  +    case RPMEV_TYPE_SIGNAL:
  +    {        ev_signal * w = &ev->evw.signal;
  +     w->cb = (_evcb ? _evcb : rpmevSignal_cb);
  +     w->signum = va_arg(ap, int);
  +     ev_signal_start(loop, w);
  +    }        break;
  +    case RPMEV_TYPE_CHILD:
  +    {        ev_child * w = &ev->evw.child;
  +     w->cb = (_evcb ? _evcb : rpmevChild_cb);
  +     w->flags = va_arg(ap, int);
  +     w->pid = va_arg(ap, int);
  +     ev_child_start (EV_DEFAULT_ w);         /* XXX only main */
  +    }        break;
  +    case RPMEV_TYPE_STAT:
  +    {        ev_stat * w = &ev->evw.stat;
  +     w->cb = (_evcb ? _evcb : rpmevStat_cb);
  +     const char *path = va_arg(ap, const char *);
  +     w->path = (path ? xstrdup(path) : NULL);
  +     w->interval = va_arg(ap, ev_tstamp);
  +     w->wd = -2;
  +     ev_stat_start(loop, w);
  +    }        break;
  +    case RPMEV_TYPE_IDLE:
  +    {        ev_idle * w = &ev->evw.idle;
  +     w->cb = (_evcb ? _evcb : rpmevIdle_cb);
  +rpmevDump("IDLE", ev, NULL);
  +     ev_idle_start(loop, w);
  +    }        break;
  +    case RPMEV_TYPE_PREPARE:
  +    {        ev_prepare * w = &ev->evw.prepare;
  +     w->cb = (_evcb ? _evcb : rpmevPrepare_cb);
  +     ev_prepare_start(loop, w);
  +    }        break;
  +    case RPMEV_TYPE_CHECK:
  +    {        ev_check * w = &ev->evw.check;
  +     w->cb = (_evcb ? _evcb : rpmevCheck_cb);
  +     ev_check_start(loop, w);
  +    }        break;
  +    case RPMEV_TYPE_FORK:
  +    {        ev_fork * w = &ev->evw.fork;
  +     w->cb = (_evcb ? _evcb : rpmevFork_cb);
  +     ev_fork_start(loop, w);
  +    }        break;
  +    case RPMEV_TYPE_CLEANUP:
  +    {        ev_cleanup * w = &ev->evw.cleanup;
  +     w->cb = (_evcb ? _evcb : rpmevCleanup_cb);
  +     ev_cleanup_start(loop, w);
  +    }        break;
  +    case RPMEV_TYPE_EMBED:
  +    {        ev_embed * w = &ev->evw.embed;
  +     w->cb = (_evcb ? _evcb : rpmevEmbed_cb);
  +     w->other = va_arg(ap, void *);
  +     ev_embed_start(loop, w);
  +    }        break;
  +    case RPMEV_TYPE_ASYNC:
  +    {        ev_async * w = &ev->evw.async;
  +     w->cb = (_evcb ? _evcb : rpmevAsync_cb);
  +rpmevDump("ASYNC", ev, NULL);
  +     ev_async_start(loop, w);
  +    }        break;
  +    }
  +
  +    va_end(ap);
  +
  +    /* XXX ev_start? */
  +
  +    /* Add to allocated event chain. */
  +    rpmevqPutTail(ev);
  +#endif       /* WITH_LIBEV */
  +
  +    return rpmevLink(ev);
  +}
  +
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/rpmjss.cpp
  ============================================================================
  $ cvs diff -u -r0 -r1.1.2.1 rpmjss.cpp
  --- /dev/null 2017-07-10 11:35:46.000000000 +0200
  +++ rpmjss.cpp        2017-07-10 11:42:51.811005545 +0200
  @@ -0,0 +1,996 @@
  +#pragma GCC diagnostic ignored "-Winvalid-offsetof"
  +#pragma GCC diagnostic ignored "-Wsuggest-attribute=const"
  +#pragma GCC diagnostic ignored "-Wsuggest-attribute=pure"
  +#pragma GCC diagnostic ignored "-Wextra"
  +
  +#include "system.h"
  +#undef       ioctl
  +#define      rpl_ioctl ioctl
  +
  +/*==============================================================*/
  +#include "shell/OSObject.cpp" 
  +/*==============================================================*/
  +#define main    mozMain
  +#include "shell/js.cpp"
  +#undef  main
  +/*==============================================================*/
  +#include "shell/jsoptparse.cpp"
  +/*==============================================================*/
  +
  +#include <rpmio.h>
  +#include <rpmlog.h>
  +#include <argv.h>
  +#include <poptIO.h>
  +
  +#define _RPMJSS_INTERNAL
  +#include "rpmjss.h"
  +
  +#include "debug.h"
  +
  +int _rpmjss_debug;
  +#define SPEW(_fmt, ...) \
  +      if (_rpmjss_debug) \
  +          fprintf(stderr, _fmt, __VA_ARGS__)
  +
  +/*==============================================================*/
  +static bool
  +rpmSetRuntimeOptions(JSRuntime* rt, const rpmjss jss)
  +{
  +    const char * str;
  +
  +    enableBaseline = ((jss->xf & XF_BASELINE) != 0);
  +    enableIon = ((jss->xf & XF_ION) != 0);
  +    enableAsmJS = ((jss->xf & XF_ASMJS) != 0);
  +    enableNativeRegExp = ((jss->xf & XF_NATIVE_REGEXP) != 0);
  +    enableUnboxedArrays = ((jss->xf & XF_UNBOXED_ARRAYS) != 0);
  +
  +    JS::RuntimeOptionsRef(rt).setBaseline(enableBaseline)
  +                             .setIon(enableIon)
  +                             .setAsmJS(enableAsmJS)
  +                             .setNativeRegExp(enableNativeRegExp)
  +                             .setUnboxedArrays(enableUnboxedArrays);
  +
  +    if (!(jss->xf & XF_UNBOXED_OBJECTS))
  +        jit::JitOptions.disableUnboxedObjects = true;
  +
  +    str = jss->ion_scalar_replacement;
  +    if (str) {
  +        if (strcmp(str, "on") == 0)
  +            jit::JitOptions.disableScalarReplacement = false;
  +        else if (strcmp(str, "off") == 0)
  +            jit::JitOptions.disableScalarReplacement = true;
  +        else
  +            return OptionFailure("ion-scalar-replacement", str);
  +    }
  +
  +    str = jss->ion_shared_stubs;
  +    if (str) {
  +        if (strcmp(str, "on") == 0)
  +            jit::JitOptions.disableSharedStubs = false;
  +        else if (strcmp(str, "off") == 0)
  +            jit::JitOptions.disableSharedStubs = true;
  +        else
  +            return OptionFailure("ion-shared-stubs", str);
  +    }
  +
  +    str = jss->ion_gvn;
  +    if (str) {
  +        if (strcmp(str, "off") == 0) {
  +            jit::JitOptions.disableGvn = true;
  +        } else if (strcmp(str, "on") != 0 &&
  +                   strcmp(str, "optimistic") != 0 &&
  +                   strcmp(str, "pessimistic") != 0)
  +        {
  +            // We accept "pessimistic" and "optimistic" as synonyms for "on"
  +            // for backwards compatibility.
  +            return OptionFailure("ion-gvn", str);
  +        }
  +    }
  +
  +    str = jss->ion_licm;
  +    if (str) {
  +        if (strcmp(str, "on") == 0)
  +            jit::JitOptions.disableLicm = false;
  +        else if (strcmp(str, "off") == 0)
  +            jit::JitOptions.disableLicm = true;
  +        else
  +            return OptionFailure("ion-licm", str);
  +    }
  +
  +    str = jss->ion_edgecase_analysis;
  +    if (str) {
  +        if (strcmp(str, "on") == 0)
  +            jit::JitOptions.disableEdgeCaseAnalysis = false;
  +        else if (strcmp(str, "off") == 0)
  +            jit::JitOptions.disableEdgeCaseAnalysis = true;
  +        else
  +            return OptionFailure("ion-edgecase-analysis", str);
  +    }
  +
  +    str = jss->ion_pgo;
  +    if (str) {
  +        if (strcmp(str, "on") == 0)
  +            jit::JitOptions.disablePgo = false;
  +        else if (strcmp(str, "off") == 0)
  +            jit::JitOptions.disablePgo = true;
  +        else
  +            return OptionFailure("ion-pgo", str);
  +    }
  +
  +    str = jss->ion_range_analysis;
  +    if (str) {
  +        if (strcmp(str, "on") == 0)
  +            jit::JitOptions.disableRangeAnalysis = false;
  +        else if (strcmp(str, "off") == 0)
  +            jit::JitOptions.disableRangeAnalysis = true;
  +        else
  +            return OptionFailure("ion-range-analysis", str);
  +    }
  +
  +    str = jss->ion_sincos;
  +    if (str) {
  +        if (strcmp(str, "on") == 0)
  +            jit::JitOptions.disableSincos = false;
  +        else if (strcmp(str, "off") == 0)
  +            jit::JitOptions.disableSincos = true;
  +        else
  +            return OptionFailure("ion-sincos", str);
  +    }
  +
  +    str = jss->ion_sink;
  +    if (str) {
  +        if (strcmp(str, "on") == 0)
  +            jit::JitOptions.disableSink = false;
  +        else if (strcmp(str, "off") == 0)
  +            jit::JitOptions.disableSink = true;
  +        else
  +            return OptionFailure("ion-sink", str);
  +    }
  +
  +    str = jss->ion_loop_unrolling;
  +    if (str) {
  +        if (strcmp(str, "on") == 0)
  +            jit::JitOptions.disableLoopUnrolling = false;
  +        else if (strcmp(str, "off") == 0)
  +            jit::JitOptions.disableLoopUnrolling = true;
  +        else
  +            return OptionFailure("ion-loop-unrolling", str);
  +    }
  +
  +    str = jss->ion_instruction_reordering;
  +    if (str) {
  +        if (strcmp(str, "on") == 0)
  +            jit::JitOptions.disableInstructionReordering = false;
  +        else if (strcmp(str, "off") == 0)
  +            jit::JitOptions.disableInstructionReordering = true;
  +        else
  +            return OptionFailure("ion-instruction-reordering", str);
  +    }
  +
  +    if (jss->ionf & ION_CHECK_RANGE_ANALYSIS)
  +        jit::JitOptions.checkRangeAnalysis = true;
  +
  +    if (jss->ionf & ION_EXTRA_CHECKS)
  +        jit::JitOptions.runExtraChecks = true;
  +
  +    str = jss->ion_inlining;
  +    if (str) {
  +        if (strcmp(str, "on") == 0)
  +            jit::JitOptions.disableInlining = false;
  +        else if (strcmp(str, "off") == 0)
  +            jit::JitOptions.disableInlining = true;
  +        else
  +            return OptionFailure("ion-inlining", str);
  +    }
  +
  +    str = jss->ion_osr;
  +    if (str) {
  +        if (strcmp(str, "on") == 0)
  +            jit::JitOptions.osr = true;
  +        else if (strcmp(str, "off") == 0)
  +            jit::JitOptions.osr = false;
  +        else
  +            return OptionFailure("ion-osr", str);
  +    }
  +
  +    str = jss->ion_limit_script_size;
  +    if (str) {
  +        if (strcmp(str, "on") == 0)
  +            jit::JitOptions.limitScriptSize = true;
  +        else if (strcmp(str, "off") == 0)
  +            jit::JitOptions.limitScriptSize = false;
  +        else
  +            return OptionFailure("ion-limit-script-size", str);
  +    }
  +
  +    int32_t warmUpThreshold = jss->ion_warmup_threshold;
  +    if (warmUpThreshold >= 0)
  +        jit::JitOptions.setCompilerWarmUpThreshold(warmUpThreshold);
  +
  +    warmUpThreshold = jss->baseline_warmup_threshold;
  +    if (warmUpThreshold >= 0)
  +        jit::JitOptions.baselineWarmUpThreshold = warmUpThreshold;
  +
  +    if (jss->xf & XF_BASELINE_EAGER)
  +        jit::JitOptions.baselineWarmUpThreshold = 0;
  +
  +    str = jss->ion_regalloc;
  +    if (str) {
  +        jit::JitOptions.forcedRegisterAllocator = 
jit::LookupRegisterAllocator(str);
  +        if (!jit::JitOptions.forcedRegisterAllocator.isSome())
  +            return OptionFailure("ion-regalloc", str);
  +    }
  +
  +    if (jss->ionf & ION_EAGER)
  +        jit::JitOptions.setEagerCompilation();
  +
  +    offthreadCompilation = true;
  +    str = jss->ion_offthread_compile;
  +    if (str) {
  +        if (strcmp(str, "off") == 0)
  +            offthreadCompilation = false;
  +        else if (strcmp(str, "on") != 0)
  +            return OptionFailure("ion-offthread-compile", str);
  +    }
  +    rt->setOffthreadIonCompilationEnabled(offthreadCompilation);
  +
  +#if defined(JS_CODEGEN_ARM)  /* XXX FIXME */
  +    if (const char* str = op.getStringOption("arm-hwcap"))
  +        jit::ParseARMHwCapFlags(str);
  +
  +    int32_t fill = op.getIntOption("arm-asm-nop-fill");
  +    if (fill >= 0)
  +        jit::Assembler::NopFill = fill;
  +
  +    int32_t poolMaxOffset = op.getIntOption("asm-pool-max-offset");
  +    if (poolMaxOffset >= 5 && poolMaxOffset <= 1024)
  +        jit::Assembler::AsmPoolMaxOffset = poolMaxOffset;
  +#endif
  +
  +#if defined(JS_SIMULATOR_ARM)        /* XXX FIXME */
  +    if (op.getBoolOption("arm-sim-icache-checks"))
  +        jit::Simulator::ICacheCheckingEnabled = true;
  +
  +    int32_t stopAt = op.getIntOption("arm-sim-stop-at");
  +    if (stopAt >= 0)
  +        jit::Simulator::StopSimAt = stopAt;
  +#elif defined(JS_SIMULATOR_MIPS32) || defined(JS_SIMULATOR_MIPS64)
  +    if (op.getBoolOption("mips-sim-icache-checks"))
  +        jit::Simulator::ICacheCheckingEnabled = true;
  +
  +    int32_t stopAt = op.getIntOption("mips-sim-stop-at");
  +    if (stopAt >= 0)
  +        jit::Simulator::StopSimAt = stopAt;
  +#endif
  +
  +    reportWarnings = ((jss->xf & XF_WARNINGS) != 0);
  +    compileOnly = ((jss->xf & XF_COMPILE_ONLY) != 0);
  +    printTiming = ((jss->xf & XF_PRINT_TIMING) != 0);
  +    enableCodeCoverage = ((jss->xf & XF_CODE_COVERAGE) != 0);
  +    enableDisassemblyDumps = ((jss->xf & XF_DUMP_BYTECODE) != 0);
  +    rt->profilingScripts = enableCodeCoverage || enableDisassemblyDumps;
  +
  +    jsCacheDir = jss->cachedir;
  +    if (jsCacheDir) {
  +        if (jss->xf & XF_CACHE_PER_PROCESS)
  +            jsCacheDir = JS_smprintf("%s/%u", jsCacheDir, 
(unsigned)getpid());
  +        else
  +            jsCacheDir = JS_strdup(rt, jsCacheDir);
  +        jsCacheAsmJSPath = JS_smprintf("%s/asmjs.cache", jsCacheDir);
  +    }
  +
  +#ifdef DEBUG
  +    dumpEntrainedVariables = ((jss->xf & XF_DUMP_ENTRAINED_VARIABLES) != 0);
  +#endif
  +
  +#ifdef JS_GC_ZEAL
  +    const char* zealStr = jss->gc_zeal;
  +    gZealStr[0] = 0;
  +    if (zealStr) {
  +        if (!rt->gc.parseAndSetZeal(zealStr))
  +            return false;
  +        strncpy(gZealStr, zealStr, sizeof(gZealStr));
  +        gZealStr[sizeof(gZealStr)-1] = 0;
  +    }
  +#endif
  +
  +    return true;
  +}
  +
  +/*==============================================================*/
  +#undef       NDEBUG
  +static int rpmjss_nopens;
  +
  +typedef struct JSI_s * JSI_t;
  +struct JSI_s {
  +    JSRuntime *rt;
  +    JSContext *cx;
  +    JSObject  *global;
  +};      
  +
  +static void mozFini(rpmjss jss)
  +{
  +    JSI_t I = (JSI_t) jss->I;
  +
  +    if (enableDisassemblyDumps)
  +     js::DumpCompartmentPCCounts(I->cx);
  +
  +    if (jss->xf & XF_CACHE_PER_PROCESS) {
  +     if (jsCacheAsmJSPath) {
  +         unlink(jsCacheAsmJSPath);
  +         JS_free(I->cx, const_cast<char*>(jsCacheAsmJSPath));
  +     }
  +     if (jsCacheDir) {
  +         rmdir(jsCacheDir);
  +         JS_free(I->cx, const_cast<char*>(jsCacheDir));
  +     }
  +    }
  +
  +    JS::SetLargeAllocationFailureCallback(I->rt, nullptr, nullptr);
  +
  +    if (I->cx)
  +     DestroyContext(I->cx, true);
  +    I->cx = NULL;
  +
  +    KillWatchdog(I->rt);
  +
  +    MOZ_ASSERT_IF(!CanUseExtraThreads(), workerThreads.empty());
  +    for (size_t i = 0; i < workerThreads.length(); i++)
  +        PR_JoinThread(workerThreads[i]);
  +
  +    DestructSharedArrayBufferMailbox();
  +
  +    if (I->rt) {
  +     ShellRuntime* sr = GetShellRuntime(I->rt);
  +     JS_DestroyRuntime(I->rt);
  +     delete sr;
  +    }
  +    I->rt = NULL;
  +
  +    if (--rpmjss_nopens <= 0)  {
  +     JS_ShutDown();
  +     rpmjss_nopens = 0;
  +    }
  +    if (I)
  +     free(I);
  +}
  +
  +static void * mozInit(rpmjss jss)
  +{
  +    JSI_t I = (JSI_t) calloc(1, sizeof(*I));
  +assert(I);
  +
  +    JSPrincipals * _principals = NULL;
  +    bool ok;
  +
  +    // Start the engine.
  +    if (rpmjss_nopens++ == 0) {
  +
  +     MaybeOverrideOutFileFromEnv("JS_STDERR", stderr, &gErrFile);
  +     MaybeOverrideOutFileFromEnv("JS_STDOUT", stdout, &gOutFile);
  +
  +#ifdef JS_CODEGEN_X86
  +     if (!(jss->xf & XF_FPU))
  +         js::jit::CPUInfo::SetFloatingPointDisabled();
  +#endif
  +
  +#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
  +     if (!(jss->xf & XF_SSE3)) {
  +         js::jit::CPUInfo::SetSSE3Disabled();
  +         PropagateFlagToNestedShells("--no-sse3");
  +     }
  +     if (!(jss->xf & XF_SSE4)) {
  +         js::jit::CPUInfo::SetSSE4Disabled();
  +         PropagateFlagToNestedShells("--no-sse4");
  +     }
  +     if (jss->xf & XF_AVX) {
  +         js::jit::CPUInfo::SetAVXEnabled();
  +         PropagateFlagToNestedShells("--enable-avx");
  +     }
  +#endif
  +
  +     if (!(jss->xf && XF_THREADS))
  +         js::DisableExtraThreads();
  +
  +     JS_Init();
  +
  +    }
  +
  +    ok = InitSharedArrayBufferMailbox();
  +assert(ok);
  + 
  +    // The fake thread count must be set before initializing the Runtime,
  +    // which spins up the thread pool.
  +    int32_t threadCount = jss->thread_count;
  +    if (threadCount >= 0)
  +        SetFakeCPUCount(threadCount);
  +
  +    static uint32_t _maxbytes = 8L * 1024L * 1024L;
  +    uint32_t nurseryBytes = jss->nursery_size > 0
  +     ? jss->nursery_size : JS::DefaultNurseryBytes;
  +
  +    JSRuntime * rt = JS_NewRuntime(_maxbytes, nurseryBytes);
  +assert(rt);
  +    I->rt = rt;
  +
  +#ifdef       DYING
  +    mozilla::UniquePtr<ShellRuntime> sr = MakeUnique<ShellRuntime>();
  +#else
  +    ShellRuntime* sr = new ShellRuntime();
  +#endif
  +assert(sr);
  +
  +#ifdef       DYING
  +    JS_SetRuntimePrivate(rt, (void *)jss);
  +#else
  +    JS_SetRuntimePrivate(rt, sr);    // XXX sr.get()
  +#endif
  + 
  +    JS_SetErrorReporter(rt, my_ErrorReporter);
  +    JS::SetOutOfMemoryCallback(rt, my_OOMCallback, nullptr);
  +
  +    ok = rpmSetRuntimeOptions(rt, jss);
  +assert(ok);
  +
  +    sr->interruptFunc.init(rt, NullValue());
  +    sr->lastWarning.init(rt, NullValue());
  +
  +    JS_SetGCParameter(rt, JSGC_MAX_BYTES, 0xffffffff);
  +
  +    size_t availMem = jss->available_memory;
  +    if (availMem > 0) {
  +     JS_SetGCParametersBasedOnAvailableMemory(rt, availMem);
  +assert(jss->available_memory == availMem);
  +    }
  +
  +    JS_SetTrustedPrincipals(rt, &ShellPrincipals::fullyTrusted);
  +    JS_SetSecurityCallbacks(rt, &ShellPrincipals::securityCallbacks);
  +    JS_InitDestroyPrincipalsCallback(rt, ShellPrincipals::destroy);
  +
  +    JS_SetInterruptCallback(rt, ShellInterruptCallback);
  +    JS::SetAsmJSCacheOps(rt, &asmJSCacheOps);
  +
  +    JS_SetNativeStackQuota(rt, gMaxStackSize);
  +
  +    JS::dbg::SetDebuggerMallocSizeOf(rt, moz_malloc_size_of);
  +
  +    ok = offThreadState.init();
  +assert(ok);
  +
  +    ok = InitWatchdog(rt);
  +assert(ok);
  +
  +    JSContext * cx = NewContext(rt);
  +assert(cx);
  +    I->cx = cx;
  +#ifdef       DYING
  +    JS_SetContextPrivate(cx, (void *)jss);
  +#else
  +    JS_SetSecondContextPrivate(cx, (void *)jss);     /* XXX */
  +#endif
  +
  +    JS_SetGCParameter(rt, JSGC_MODE, JSGC_MODE_INCREMENTAL);
  +    JS_SetGCParameterForThread(cx, JSGC_MAX_CODE_CACHE_BYTES, 16 * 1024 * 
1024  );
  +
  +    JS::SetLargeAllocationFailureCallback(rt, my_LargeAllocFailCallback, 
(void  *)cx);
  +
  +    // Set some parameters to allow incremental GC in low memory conditions,
  +    // as is done for the browser, except in more-deterministic builds or 
when
  +    // disabled by command line options.
  +#ifndef JS_MORE_DETERMINISTIC
  +    if (jss->xf & XF_INCREMENTAL_GC) {
  +        JS_SetGCParameter(rt, JSGC_DYNAMIC_HEAP_GROWTH, 1);
  +        JS_SetGCParameter(rt, JSGC_DYNAMIC_MARK_SLICE, 1);
  +        JS_SetGCParameter(rt, JSGC_SLICE_TIME_BUDGET, 10);
  +    }
  +#endif
  +
  +    js::SetPreserveWrapperCallback(rt, DummyPreserveWrapperCallback);
  +
  +    // result = Shell(cx, &op, envp);
  +    {
  +     RootedObject glob(cx);
  +     JS::CompartmentOptions options;
  +     options.setVersion(JSVERSION_DEFAULT);
  +     glob = NewGlobalObject(cx, options, _principals);
  +assert(glob);
  +     I->global = glob;
  +
  +     JSAutoCompartment ac(cx, glob);
  +
  +#ifdef       FIXME
  +     int result = ProcessArgs(cx, op);
  +#endif       /* FIXME */
  +    }
  +
  +    return I;
  +}
  +
  +static int mozRun(rpmjss jss, const char ** resultp,
  +             const char * script, const char * fn, unsigned ln)
  +{
  +    JSI_t I = (JSI_t) jss->I;
  +    JSContext* cx = I->cx;
  +    JSObject* global = I->global;
  +
  +    JS::RootedValue rval(cx);
  +
  +    {        // Scope for JSAutoCompartment
  +     JSAutoCompartment ac(cx, global);
  +
  +     JS::CompileOptions opts(cx);
  +     opts.setFileAndLine(fn, ln);
  +
  +     bool ok = JS::Evaluate(cx, opts, script, strlen(script), &rval);
  +     if (!ok)
  +         return 1;
  +    }
  +
  +    char b[128];
  +    size_t nb = sizeof(b);
  +    char * t = NULL;
  +
  +    if (rval.isNull()) {
  +     t = strdup("");
  +    } else
  +    if (rval.isUndefined()) {
  +     t = strdup("");
  +    } else
  +    if (rval.isBoolean()) {
  +     snprintf(b, nb, "%c", (rval.toBoolean() ? 'T' : 'F'));
  +     t = strdup(b);
  +    } else
  +    if (rval.isInt32()) {    /* int32_t */
  +     snprintf(b, nb, "%d", rval.toInt32());
  +     t = strdup(b);
  +    } else
  +    if (rval.isDouble()) {
  +     snprintf(b, nb, "%.16g", rval.toDouble());
  +     t = strdup(b);
  +    } else
  +    if (rval.isNumber()) {
  +     snprintf(b, nb, "%.16g", rval.toNumber());
  +     t = strdup(b);
  +    } else
  +    if (rval.isString()) {
  +     t = JS_EncodeString(cx, rval.toString());
  +    } else
  +     t = strdup("");
  +
  +    if (resultp)
  +     *resultp = t;
  +    else
  +     t = _free(t);
  +
  +    return 0;
  +}
  +
  +static struct JSIO_s _mozjs45 = { mozFini, mozInit, mozRun };
  +JSIO_t mozjs45 = &_mozjs45;
  +
  +/*==============================================================*/
  +struct rpmjss_s _jss;
  +rpmjss jss = &_jss;
  +
  +/*==============================================================*/
  +struct poptOption rpmjssIPoptTable[] = {
  +  { "allow", '\0', POPT_BIT_SET,
  +     &_jss.flags, RPMJSS_FLAGS_ALLOW,
  +        N_("Allow (read-only) access to caller's environment"), NULL },
  +  { "cache", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.flags, RPMJSS_FLAGS_NOCACHE,
  +        N_("Disables compiler caching via JSScript XDR serialization"), NULL 
},
  +  { "loadrc", '\0', POPT_BIT_SET,
  +     &_jss.flags, RPMJSS_FLAGS_LOADRC,
  +        N_("Load RC file for interpreter based on script filename."), NULL },
  +  { "warn", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.flags, RPMJSS_FLAGS_NOWARN,
  +        N_("Do not report warnings"), NULL },
  +
  +  { "relimit", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.flags, RPMJSS_FLAGS_RELIMIT,
  +        N_("Do not limit regexps to n^3 levels of backtracking"), NULL },
  +  { "jit", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.flags, RPMJSS_FLAGS_JIT,
  +        N_("Disable nanojit"), NULL },
  +  { "strict", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.flags, RPMJSS_FLAGS_STRICT,
  +        N_("Disable Strict mode"), NULL },
  +  { "utf8", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.flags, RPMJSS_FLAGS_NOUTF8,
  +        N_("Disable UTF-8 C string processing"), NULL },
  +  { "xml", '\0', POPT_BIT_SET,
  +     &_jss.flags, RPMJSS_FLAGS_XML,
  +        N_("Parse <!-- comments --> as E4X tokens"), NULL },
  +
  +  { "anonfunfix", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
  +     &_jss.flags, RPMJSS_FLAGS_ANONFUNFIX,
  +        N_("Parse //@line number [\"filename\"] for XUL"), NULL },
  +  { "atline", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
  +     &_jss.flags, RPMJSS_FLAGS_ATLINE,
  +        N_("Parse //@line number [\"filename\"] for XUL"), NULL },
  +  { "werror", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
  +     &_jss.flags, RPMJSS_FLAGS_WERROR,
  +        N_("Convert warnings to errors"), NULL },
  +  POPT_TABLEEND
  +};
  +
  +struct poptOption rpmjssIonPoptTable[] = {
  +#ifdef       NOTYET
  +  { "ion-shared-stubs", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.ionf, ION_SHARED_STUBS,
  +     N_("Use shared stubs (default: off)"), NULL },
  +  { "ion-scalar-replacement", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.ionf, ION_SCALAR_REPLACEMENT,
  +     N_("Scalar replacement (default: on)"), NULL },
  +  { "ion-gvn", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.ionf, ION_GVN,
  +     N_("Global value numbering (default: on)"), NULL },
  +  { "ion-licm", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.ionf, ION_LICM,
  +     N_("Loop invariant code motion (default: on)"), NULL },
  +  { "ion-edgecase-analysis", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.ionf, ION_EDGECASE_ANALYSIS,
  +     N_("Find edge cases where Ion can avoid bailouts (default: off)"), NULL 
},
  +  { "ion-pgo", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.ionf, ION_PGO,
  +     N_("Profile guided optimization (default: off)"), NULL },
  +  { "ion-range-analysis", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.ionf, ION_RANGE_ANALYSIS,
  +     N_("Range analysis (default: on)"), NULL },
  +  { "ion-sincos", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.ionf, ION_SINCOS,
  +     N_("Replace sin(x)/cos(x) to sincos(x) (default: on)"), NULL },
  +  { "ion-sink", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.ionf, ION_SINK,
  +     N_("Sink code motion (default: off)"), NULL },
  +  { "ion-loop-unrolling", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.ionf, ION_LOOP_UNROLLING,
  +     N_("Loop unrolling (default: off)"), NULL },
  +  { "ion-instruction-reordering", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.ionf, ION_INSTRUCTION_REORDERING,
  +     N_("Instruction reordering (default: off)"), NULL },
  +#else
  +  { "ion-shared-stubs", '\0', POPT_ARG_STRING,
  +     &_jss.ion_shared_stubs, 0,
  +     N_("Use shared stubs (default: off)"), NULL },
  +  { "ion-scalar-replacement", '\0', POPT_ARG_STRING,
  +     &_jss.ion_scalar_replacement, 0,
  +     N_("Scalar replacement (default: on)"), NULL },
  +  { "ion-gvn", '\0', POPT_ARG_STRING,
  +     &_jss.ion_gvn, 0,
  +     N_("Global value numbering (default: on)"), NULL },
  +  { "ion-licm", '\0', POPT_ARG_STRING,
  +     &_jss.ion_licm, 0,
  +     N_("Loop invariant code motion (default: on)"), NULL },
  +  { "ion-edgecase-analysis", '\0', POPT_ARG_STRING,
  +     &_jss.ion_edgecase_analysis, 0,
  +     N_("Find edge cases where Ion can avoid bailouts (default: off)"), NULL 
},
  +  { "ion-pgo", '\0', POPT_ARG_STRING,
  +     &_jss.ion_pgo, 0,
  +     N_("Profile guided optimization (default: off)"), NULL },
  +  { "ion-range-analysis", '\0', POPT_ARG_STRING,
  +     &_jss.ion_range_analysis, 0,
  +     N_("Range analysis (default: on)"), NULL },
  +  { "ion-sincos", '\0', POPT_ARG_STRING,
  +     &_jss.ion_sincos, 0,
  +     N_("Replace sin(x)/cos(x) to sincos(x) (default: on)"), NULL },
  +  { "ion-sink", '\0', POPT_ARG_STRING,
  +     &_jss.ion_sink, 0,
  +     N_("Sink code motion (default: off)"), NULL },
  +  { "ion-loop-unrolling", '\0', POPT_ARG_STRING,
  +     &_jss.ion_loop_unrolling, 0,
  +     N_("Loop unrolling (default: off)"), NULL },
  +  { "ion-instruction-reordering", '\0', POPT_ARG_STRING,
  +     &_jss.ion_instruction_reordering, 0,
  +     N_("Instruction reordering (default: off)"), NULL },
  +#endif
  +
  +  { "ion-check-range-analysis", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.ionf, ION_CHECK_RANGE_ANALYSIS,
  +     N_("Range analysis checking (default: off)"), NULL },
  +  { "ion-extra-checks", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.ionf, ION_EXTRA_CHECKS,
  +     N_("Perform extra dynamic validation checks (default: off)"), NULL },
  +
  +#ifdef       NOTYET
  +  { "ion-inlining", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.ionf, ION_INLINING,
  +     N_("Inline methods where possible (default: on)"), NULL },
  +  { "ion-osr", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.ionf, ION_OSR,
  +     N_("On-Stack Replacement(default: on)"), NULL },
  +  { "ion-limit-script-size", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.ionf, ION_LIMIT_SCRIPT_SIZE,
  +     N_("Don't compile large scripts(default: on)"), NULL },
  +#else
  +  { "ion-inlining", '\0', POPT_ARG_STRING,
  +     &_jss.ion_inlining, 0,
  +     N_("Inline methods where possible (default: on)"), NULL },
  +  { "ion-osr", '\0', POPT_ARG_STRING,
  +     &_jss.ion_osr, 0,
  +     N_("On-Stack Replacement(default: on)"), NULL },
  +  { "ion-limit-script-size", '\0', POPT_ARG_STRING,
  +     &_jss.ion_limit_script_size, 0,
  +     N_("Don't compile large scripts(default: on)"), NULL },
  +#endif
  +
  +  { "ion-warmup-threshold", '\0', POPT_ARG_INT,
  +     &_jss.ion_warmup_threshold, 0,
  +     N_("Wait COUNT calls/iterations before compiling"), N_("COUNT") },
  +  { "ion-regalloc", '\0', POPT_ARG_STRING,
  +     &_jss.ion_regalloc, 0,
  +     N_("Specify Ion register allocation MODE"), N_("MODE") },
  +  { "ion-eager", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.ionf, ION_EAGER,
  +     N_("Always ion-compile methods (default: on)"), NULL },
  +
  +#ifdef       NOTYET
  +  { "ion-offthread-compile", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.ionf, ION_OFFTHREAD_COMPILE,
  +     N_("Compile scripts off thread (default: on)"), NULL },
  +#else
  +  { "ion-offthread-compile", '\0', POPT_ARG_STRING,
  +     &_jss.ion_offthread_compile, 0,
  +     N_("Compile scripts off thread (default: on)"), NULL },
  +#endif
  +
  +  POPT_TABLEEND
  +};
  +
  +struct poptOption rpmjssOptionsTable[] = {
  +  { "file", 'f', POPT_ARG_STRING,            &_jss.Ifile, 0,
  +        N_("File PATH to run"), N_("PATH") },
  +  { "module", 'm', POPT_ARG_STRING,          &_jss.Imodule, 0,
  +        N_("Module PATH to run"), N_("PATH") },
  +  { "execute", 'e', POPT_ARG_STRING,         &_jss.Icode, 0,
  +        N_("Inline CODE to run"), N_("CODE") },
  +  { "shell", 'i', POPT_BIT_SET,                      &_jss.xf, 
XF_INTERACTIVE,
  +        N_("Enter prompt after running code"), NULL },
  +  { "compileonly", 'c', POPT_BIT_SET,                &_jss.xf, 
XF_COMPILE_ONLY,
  +        N_("Only compile, don't run (syntax checking mode)"), NULL },
  +     /* XXX collision on -w? */
  +  { "warnings", 'w', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,       &_jss.xf, 
XF_WARNINGS,
  +        N_("Emit warnings"), NULL },
  +  { "strict", 's', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE, &_jss.xf, XF_STRICT,
  +        N_("Check strictness"), NULL },
  +  { "dump-bytecode", 'D', POPT_BIT_SET,              &_jss.xf, 
XF_DUMP_BYTECODE,
  +        N_("Dump bytecode with exec count for all scripts"), NULL },
  +  { "print-timing", 'b', POPT_BIT_SET,               &_jss.xf, 
XF_PRINT_TIMING,
  +        N_("Dump bytecode with exec count for all scripts"), NULL },
  +  { "js-cache", '\0', POPT_ARG_STRING,               &_jss.cachedir, 0,
  +        N_("Enable JS caching in DIR"), N_("DIR") },
  +  { "js-cache-per-process",'\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.xf, XF_CACHE_PER_PROCESS,
  +        N_("Deactivate per-process caching"), NULL },
  +  { "code-coverage", '\0', POPT_BIT_SET,     &_jss.xf, XF_CODE_COVERAGE,
  +        N_("Enable code coverage insturmentation"), NULL },
  +
  +  { "ion", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.xf, XF_ION,
  +     N_("Disable IonMonkey"), NULL },
  +  { "asmjs", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.xf, XF_ASMJS,
  +     N_("Disable asm.js compilation"), NULL },
  +  { "native-regexp", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.xf, XF_NATIVE_REGEXP,
  +     N_("Disable native regexp compilation"), NULL },
  +  { "unboxed-objects", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.xf, XF_UNBOXED_OBJECTS,
  +     N_("Disable creating unboxed plain objects"), NULL },
  +  { "unboxed-arrays", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.xf, XF_UNBOXED_ARRAYS,
  +     N_("Allow creating unboxed arrays"), NULL },
  +
  +  { "print-alloc", 'O', POPT_BIT_SET,                &_jss.xf, 
XF_PRINT_ALLOC,
  +        N_("Print no. of allocatsions at exit"), NULL },
  +  { "script", '\0', POPT_ARG_STRING,         &_jss.script_path, 0,
  +        N_("Script PATH to run"), N_("PATH") },
  +  { "scriptArgs", '\0', POPT_ARG_STRING,     &_jss.script_args, 0,
  +        N_("Script args to bind as |scriptArgs| in global"), N_("XXX") },
  +  { "thread-count", '\0', POPT_ARG_INT,              &_jss.thread_count, 0,
  +        N_("Use COUNT auxiliary threads"), N_("COUNT") },
  +
  +  { "baseline", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.xf, XF_BASELINE,
  +     N_("Enable baseline compiler (default: on)"), NULL },
  +  { "baseline-eager", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.xf, XF_BASELINE_EAGER,
  +     N_("Always baseline-compile methods"), NULL },
  +  { "baseline-warmup-threshold", '\0', POPT_ARG_INT,
  +     &_jss.baseline_warmup_threshold, 0,
  +     N_("Wait COUNT calls/iterations before baseline-compiling"), 
N_("COUNT") },
  +
  +  { "non-writable-jitcode", '\0', POPT_BIT_SET,
  +     &_jss.xf, XF_NONWRITABLE_JITCODE,
  +     N_("Allocate JIT code   as non-writable memory"), NULL },
  +#ifdef JS_CODEGEN_X86
  +  { "fpu", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.xf, XF_FPU,
  +     N_("Assume CPU has a FPU"), NULL },
  +#endif
  +  { "sse3", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.xf, XF_SSE3,
  +     N_("Assume CPU has SSE3 instructions"), NULL },
  +  { "sse4", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.xf, XF_SSE4,
  +     N_("Assume CPU has SSE4 instructions"), NULL },
  +  { "avx", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.xf, XF_AVX,
  +     N_("Assume CPU has AVX instructions"), NULL },
  +  { "enable-avx", '\0', POPT_BIT_SET,
  +     &_jss.xf, XF_AVX,
  +     N_("Assume CPU has AVX instructions"), NULL },
  +  { "fuzzing-safe", '\0', POPT_BIT_SET,
  +     &_jss.xf, XF_FUZZING_SAFE,
  +     N_("Don't expose unsafe functions (when fuzzing)"), NULL },
  +  { "disable-oom-functions", '\0', POPT_BIT_SET,
  +     &_jss.xf, XF_DISABLE_OOM,
  +     N_("Disable functions that trigger OOM"), NULL },
  +  { "threads", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.xf, XF_THREADS,
  +     N_("Disable helper threads"), NULL },
  +
  +#ifdef       DEBUG
  +  { "dump-entrained-variables", '\0', POPT_BIT_SET,
  +     &_jss.xf, XF_DISABLE_OOM,
  +     N_("Print variables entrained by inner functions"), NULL },
  +#endif
  +
  +  { "ggc", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.xf, XF_GGC,
  +     N_("Disable Generational GC"), NULL },
  +  { "cgc", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.xf, XF_CGC,
  +     N_("Disable Compacting GC"), NULL },
  +  { "incremental-gc", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
  +     &_jss.xf, XF_INCREMENTAL_GC,
  +     N_("Disable Incremental GC"), NULL },
  +
  +  { "available-memory", '\0', POPT_ARG_INT,  &_jss.available_memory, 0,
  +        N_("Select GC settings based on SIZE-MB"), N_("SIZE-MB") },
  +
  +#if defined(JS_CODEGEN_ARM)
  +  { "arm-hwcap", '\0', POPT_ARG_STRING,      &_jss.arm_hwcap, 0,
  +        N_("Specify ARM code generation FEATURES"), N_("FEATURES") },
  +
  +  { "arm-asm-nop-fill", '\0', POPT_ARG_INT,  &_jss.arm_asm_nop_fill, 0,
  +        N_("Insert N NOP instructions in pool"), N_("N") },
  +  { "asm-pool-max-offset", '\0', POPT_ARG_INT,       
&_jss.asm_pool_max_offset, 0,
  +        N_("Max PC-relative OFFSET in pool"), N_("OFFSET") },
  +#endif
  +
  +#if defined(JS_SIMULATOR_ARM)
  +  { "arm-sim-icache-checks", '\0', POPT_BIT_SET,
  +     &_jss.xf, XF_ARM_SIM_ICACHE_CHECKS,
  +     N_("(ARM) Enable icache flush checks"), NULL },
  +  { "arm-sim-stop-at", '\0', POPT_ARG_INT,   &_jss.arm_sim_stop_at, 0,
  +        N_("(ARM) Stop simulator after N instructions"), N_("N") },
  +#endif
  +
  +#if defined(JS_SIMULATOR_MIPS32) || defined(JS_SIMULATOR_MIPS64)
  +  { "mips-sim-icache-checks", '\0', POPT_BIT_SET,
  +     &_jss.xf, XF_MIPS_SIM_ICACHE_CHECKS,
  +     N_("(MIPS) Enable icache flush checks"), NULL },
  +  { "mips-sim-stop-at", '\0', POPT_ARG_INT,  &_jss.mips_sim_stop_at, 0,
  +        N_("(MIPS) Stop simulator after N instructions"), N_("N") },
  +#endif
  +
  +  { "nursery-size", '\0', POPT_ARG_INT,              &_jss.nursery_size, 0,
  +        N_("Set nursery SIZE-MB"), N_("SIZE-MB") },
  +
  +#ifdef JS_GC_ZEAL
  +  { "gc-zeal", '\0', POPT_ARG_STRING,                &_jss.gc_zeal, 0,
  +        N_("Set GC zeal to LEVEL"), N_("LEVEL") },
  +#endif
  +
  +  { "module-load-path", '\0', POPT_ARG_STRING,               
&_jss.moduledir, 0,
  +        N_("Load modules from DIR"), N_("DIR") },
  +
  +  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmjssIPoptTable, 0,
  +          N_("JS interpreter options:"), NULL },
  +
  +  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmjssIonPoptTable, 0,
  +          N_("JS ion interpreter options:"), NULL },
  +
  +  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmioAllPoptTable, 0,
  +     N_("Common options for all rpmio executables:"), NULL },
  +
  +  POPT_AUTOALIAS
  +  POPT_AUTOHELP
  +  POPT_TABLEEND
  +};
  +
  +static rpmjssFlags _flagsDefault = (rpmjssFlags) (
  +    RPMJSS_FLAGS_RELIMIT |
  +    RPMJSS_FLAGS_JIT |
  +    RPMJSS_FLAGS_STRICT |
  +    0
  +);
  +
  +static rpmjssIonFlags _ionfDefault = (rpmjssIonFlags) (
  +    ION_SCALAR_REPLACEMENT |
  +    ION_GVN |
  +    ION_LICM |
  +    ION_EDGECASE_ANALYSIS |
  +    ION_RANGE_ANALYSIS |
  +    ION_INLINING |
  +    ION_OSR |
  +    ION_LIMIT_SCRIPT_SIZE |
  +    ION_OFFTHREAD_COMPILE |
  +    0
  +);
  +
  +static rpmjssXFlags _xfDefault = (rpmjssXFlags) (
  +    XF_BASELINE |
  +    XF_ION |
  +    XF_ASMJS |
  +    XF_NATIVE_REGEXP |
  +    XF_UNBOXED_OBJECTS |
  +    XF_CACHE_PER_PROCESS |
  +    XF_FPU |
  +    XF_SSE3 |
  +    XF_SSE4 |
  +    XF_THREADS |
  +    XF_GGC |
  +    XF_CGC |
  +    XF_INCREMENTAL_GC |
  +    0
  +);
  +
  +/*==============================================================*/
  +static void rpmjssFini(void * _jss)
  +{
  +    rpmjss jss = (rpmjss) _jss;
  +
  +    mozFini(jss);
  +    jss->I = NULL;
  +}
  +
  +#define rpmjssDbug   NULL
  +#define rpmjssInit   NULL
  +RPMIOPOOL_INTERP_MODULE(jss)
  +
  +rpmjss rpmjssNew(char ** av, uint32_t flags)
  +{
  +    rpmjss jss =
  +#ifdef       NOTYET
  +     (flags & 0x80000000) ? rpmjsI() :
  +#endif
  +     rpmjssGetPool(_rpmjssPool);
  +
  +    jss->flags = _flagsDefault;
  +    jss->thread_count = -1;
  +    jss->ion_warmup_threshold = -1;
  +    jss->baseline_warmup_threshold = -1;
  +    jss->ion_warmup_threshold = -1;
  +    jss->available_memory = 0; 
  +    jss->arm_asm_nop_fill = 0;
  +    jss->asm_pool_max_offset = 1024;
  +    jss->arm_sim_stop_at = -1;
  +    jss->mips_sim_stop_at = -1;
  +    jss->nursery_size = 16;
  +    jss->ionf = _ionfDefault;  
  +    jss->xf = _xfDefault;
  +
  +    /* XXX parse arguments */
  +
  +    JSI_t I = (JSI_t) mozInit(jss);
  +    jss->I = I;
  +
  +    return rpmjssLink(jss);
  +}
  +
  +rpmRC rpmjssRun(rpmjss jss, const char * str, const char ** resultp)
  +{
  +    rpmRC rc = RPMRC_FAIL; 
  +
  +    if (jss == NULL) jss = rpmjssI();
  +
  +    if (str && *str
  +     && !mozRun(jss, resultp, str, __FILE__, __LINE__))
  +     rc = RPMRC_OK;
  +
  +SPEW("<== %s(%p,|%s|) rc %d |%s|\n", __FUNCTION__, jss, str, rc, (resultp ? 
*resultp : ""));
  +    return rc;
  +}
  @@ .
______________________________________________________________________
RPM Package Manager                                    http://rpm5.org
CVS Sources Repository                                rpm-cvs@rpm5.org

Reply via email to