/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sts=4 et sw=4 tw=99:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/* JS shell. */

#include "mozilla/ArrayUtils.h"
#include "mozilla/Atomics.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/GuardObjects.h"
#if !defined(STARBOARD)
// mozalloc is only (minimally) used in the shell, and thus is not fully
// starboardized.  Don't bother including it and just ifdef out references to
// stuff from it.
#include "mozilla/mozalloc.h"
#endif  // !defined(STARBOARD)
#include "mozilla/PodOperations.h"

#ifdef XP_WIN
# include <direct.h>
# include <process.h>
#endif
#include <errno.h>
#include <fcntl.h>
#if defined(XP_WIN)
# include <io.h>     /* for isatty() */
#endif
#include <locale.h>
#if defined(MALLOC_H)
# include MALLOC_H    /* for malloc_usable_size, malloc_size, _msize */
#endif
#include <math.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#ifdef XP_UNIX
# include <sys/mman.h>
# include <sys/stat.h>
# include <sys/wait.h>
# include <unistd.h>
#endif

#include "jsapi.h"
#include "jsarray.h"
#include "jsatom.h"
#include "jscntxt.h"
#include "jsfun.h"
#include "jslock.h"
#include "jsobj.h"
#include "jsprf.h"
#include "jsscript.h"
#include "jstypes.h"
#include "jsutil.h"
#ifdef XP_WIN
# include "jswin.h"
#endif
#include "jswrapper.h"
#include "shellmoduleloader.out.h"

#include "builtin/ModuleObject.h"
#include "builtin/TestingFunctions.h"
#include "frontend/Parser.h"
#include "gc/GCInternals.h"
#include "jit/arm/Simulator-arm.h"
#include "jit/InlinableNatives.h"
#include "jit/Ion.h"
#include "jit/JitcodeMap.h"
#include "jit/OptimizationTracking.h"
#include "js/Debug.h"
#include "js/GCAPI.h"
#include "js/Initialization.h"
#include "js/StructuredClone.h"
#include "js/TrackedOptimizationInfo.h"
#include "perf/jsperf.h"
#include "shell/jsoptparse.h"
#include "shell/OSObject.h"
#include "vm/ArgumentsObject.h"
#include "vm/Compression.h"
#include "vm/Debugger.h"
#include "vm/HelperThreads.h"
#include "vm/Monitor.h"
#include "vm/Shape.h"
#include "vm/SharedArrayObject.h"
#include "vm/StringBuffer.h"
#include "vm/Time.h"
#include "vm/TypedArrayObject.h"
#include "vm/WrapperObject.h"

#include "jscompartmentinlines.h"
#include "jsobjinlines.h"

#include "vm/ErrorObject-inl.h"
#include "vm/Interpreter-inl.h"
#include "vm/Stack-inl.h"

// Unified leak fix:
#include "jsshell.h"

#if defined(STARBOARD)

#if !defined(PATH_MAX)
#include "starboard/configuration.h"
#define PATH_MAX (SB_FILE_MAX_PATH + 1)
#endif

#include "starboard/client_porting/poem/stdio_poem.h"
#include "starboard/client_porting/poem/string_poem.h"
#include "starboard/client_porting/wrap_main/wrap_main.h"
#include "starboard/memory.h"

#endif


using namespace js;
using namespace js::cli;
using namespace js::shell;

using mozilla::ArrayLength;
using mozilla::Atomic;
using mozilla::MakeUnique;
using mozilla::Maybe;
using mozilla::NumberEqualsInt32;
using mozilla::PodCopy;
using mozilla::PodEqual;
using mozilla::UniquePtr;

// Unified leak fix:
using namespace JS;

enum JSShellExitCode {
    EXITCODE_RUNTIME_ERROR      = 3,
    EXITCODE_FILE_NOT_FOUND     = 4,
    EXITCODE_OUT_OF_MEMORY      = 5,
    EXITCODE_TIMEOUT            = 6
};

static const size_t gStackChunkSize = 8192;

/*
 * Note: This limit should match the stack limit set by the browser in
 *       js/xpconnect/src/XPCJSRuntime.cpp
 */
#if defined(MOZ_ASAN) || (defined(DEBUG) && !defined(XP_WIN))
static const size_t gMaxStackSize = 2 * 128 * sizeof(size_t) * 1024;
#else
static const size_t gMaxStackSize = 128 * sizeof(size_t) * 1024;
#endif

/*
 * Limit the timeout to 30 minutes to prevent an overflow on platfoms
 * that represent the time internally in microseconds using 32-bit int.
 */
static const double MAX_TIMEOUT_INTERVAL = 1800.0;

// Per-runtime shell state.
struct ShellRuntime
{
    ShellRuntime();

    bool isWorker;
    double timeoutInterval;
    Atomic<bool> serviceInterrupt;
    JS::PersistentRootedValue interruptFunc;
    bool lastWarningEnabled;
    JS::PersistentRootedValue lastWarning;

    /*
     * Watchdog thread state.
     */
    PRLock* watchdogLock;
    PRCondVar* watchdogWakeup;
    PRThread* watchdogThread;
    bool watchdogHasTimeout;
    int64_t watchdogTimeout;

    PRCondVar* sleepWakeup;

    int exitCode;
    bool quitting;
    bool gotError;
};

// Shell state set once at startup.
static bool enableCodeCoverage = false;
static bool enableDisassemblyDumps = false;
static bool offthreadCompilation = false;
static bool enableBaseline = false;
static bool enableIon = false;
static bool enableAsmJS = false;
static bool enableNativeRegExp = false;
static bool enableUnboxedArrays = false;
#ifdef JS_GC_ZEAL
static char gZealStr[128];
#endif
static bool printTiming = false;
static const char* jsCacheDir = nullptr;
static const char* jsCacheAsmJSPath = nullptr;
static FILE* gErrFile = nullptr;
static FILE* gOutFile = nullptr;
static bool reportWarnings = true;
static bool compileOnly = false;
static bool fuzzingSafe = false;
static bool disableOOMFunctions = false;
static const char* moduleLoadPath = ".";

#ifdef DEBUG
static bool dumpEntrainedVariables = false;
static bool OOM_printAllocationCount = false;
#endif

// Shell state this is only accessed on the main thread.
bool jsCachingEnabled = false;
mozilla::Atomic<bool> jsCacheOpened(false);

static bool
SetTimeoutValue(JSContext* cx, double t);

static bool
InitWatchdog(JSRuntime* rt);

static void
KillWatchdog(JSRuntime *rt);

static bool
ScheduleWatchdog(JSRuntime* rt, double t);

static void
CancelExecution(JSRuntime* rt);

static JSContext*
NewContext(JSRuntime* rt);

static void
DestroyContext(JSContext* cx, bool withGC);

static JSObject*
NewGlobalObject(JSContext* cx, JS::CompartmentOptions& options,
                JSPrincipals* principals);

/*
 * A toy principals type for the shell.
 *
 * In the shell, a principal is simply a 32-bit mask: P subsumes Q if the
 * set bits in P are a superset of those in Q. Thus, the principal 0 is
 * subsumed by everything, and the principal ~0 subsumes everything.
 *
 * As a special case, a null pointer as a principal is treated like 0xffff.
 *
 * The 'newGlobal' function takes an option indicating which principal the
 * new global should have; 'evaluate' does for the new code.
 */
class ShellPrincipals final : public JSPrincipals {
    uint32_t bits;

    static uint32_t getBits(JSPrincipals* p) {
        if (!p)
            return 0xffff;
        return static_cast<ShellPrincipals*>(p)->bits;
    }

  public:
    explicit ShellPrincipals(uint32_t bits, int32_t refcount = 0) : bits(bits) {
        this->refcount = refcount;
    }

    bool write(JSContext* cx, JSStructuredCloneWriter* writer) override {
        MOZ_ASSERT(false, "not implemented");
        return false;
    }

    static void destroy(JSPrincipals* principals) {
        MOZ_ASSERT(principals != &fullyTrusted);
        MOZ_ASSERT(principals->refcount == 0);
        js_delete(static_cast<const ShellPrincipals*>(principals));
    }

    static bool subsumes(JSPrincipals* first, JSPrincipals* second) {
        uint32_t firstBits  = getBits(first);
        uint32_t secondBits = getBits(second);
        return (firstBits | secondBits) == firstBits;
    }

    static JSSecurityCallbacks securityCallbacks;

    // Fully-trusted principals singleton.
    static ShellPrincipals fullyTrusted;
};

JSSecurityCallbacks ShellPrincipals::securityCallbacks = {
    nullptr, // contentSecurityPolicyAllows
    subsumes
};

// The fully-trusted principal subsumes all other principals.
ShellPrincipals ShellPrincipals::fullyTrusted(-1, 1);

#ifdef EDITLINE
extern "C" {
extern JS_EXPORT_API(char*) readline(const char* prompt);
extern JS_EXPORT_API(void)   add_history(char* line);
} // extern "C"
#endif

ShellRuntime::ShellRuntime()
  : isWorker(false),
    timeoutInterval(-1.0),
    serviceInterrupt(false),
    lastWarningEnabled(false),
    watchdogLock(nullptr),
    watchdogWakeup(nullptr),
    watchdogThread(nullptr),
    watchdogHasTimeout(false),
    watchdogTimeout(0),
    sleepWakeup(nullptr),
    exitCode(0),
    quitting(false),
    gotError(false)
{}

static ShellRuntime*
GetShellRuntime(JSRuntime *rt)
{
    ShellRuntime* sr = static_cast<ShellRuntime*>(JS_GetRuntimePrivate(rt));
    MOZ_ASSERT(sr);
    return sr;
}

static ShellRuntime*
GetShellRuntime(JSContext* cx)
{
    return GetShellRuntime(cx->runtime());
}

static char*
GetLine(FILE* file, const char * prompt)
{
#ifdef EDITLINE
    /*
     * Use readline only if file is stdin, because there's no way to specify
     * another handle.  Are other filehandles interactive?
     */
    if (file == stdin) {
        char* linep = readline(prompt);
        /*
         * We set it to zero to avoid complaining about inappropriate ioctl
         * for device in the case of EOF. Looks like errno == 251 if line is
         * finished with EOF and errno == 25 (EINVAL on Mac) if there is
         * nothing left to read.
         */
        if (errno == 251 || errno == 25 || errno == EINVAL)
            errno = 0;
        if (!linep)
            return nullptr;
        if (linep[0] != '\0')
            add_history(linep);
        return linep;
    }
#endif

    size_t len = 0;
    if (*prompt != '\0') {
        fprintf(gOutFile, "%s", prompt);
        fflush(gOutFile);
    }

    size_t size = 80;
    char* buffer = static_cast<char*>(malloc(size));
    if (!buffer)
        return nullptr;

    char* current = buffer;
    while (true) {
        while (true) {
            if (fgets(current, size - len, file))
                break;
            if (errno != EINTR) {
                free(buffer);
                return nullptr;
            }
        }

        len += strlen(current);
        char* t = buffer + len - 1;
        if (*t == '\n') {
            /* Line was read. We remove '\n' and exit. */
            *t = '\0';
            return buffer;
        }

        if (len + 1 == size) {
            size = size * 2;
            char* tmp = static_cast<char*>(realloc(buffer, size));
            if (!tmp) {
                free(buffer);
                return nullptr;
            }
            buffer = tmp;
        }
        current = buffer + len;
    }

    if (len && !ferror(file))
        return buffer;
    free(buffer);
    return nullptr;
}

/* State to store as JSContext private. */
struct JSShellContextData {
    /* Creation timestamp, used by the elapsed() shell builtin. */
    int64_t startTime;
};

static JSShellContextData*
NewContextData()
{
    JSShellContextData* data = (JSShellContextData*)
                               js_calloc(sizeof(JSShellContextData), 1);
    if (!data)
        return nullptr;
    data->startTime = PRMJ_Now();
    return data;
}

static inline JSShellContextData*
GetContextData(JSContext* cx)
{
    JSShellContextData* data = (JSShellContextData*) JS_GetContextPrivate(cx);

    MOZ_ASSERT(data);
    return data;
}

static bool
ShellInterruptCallback(JSContext* cx)
{
    ShellRuntime* sr = GetShellRuntime(cx);
    if (!sr->serviceInterrupt)
        return true;

    // Reset serviceInterrupt. CancelExecution or InterruptIf will set it to
    // true to distinguish watchdog or user triggered interrupts.
    // Do this first to prevent other interrupts that may occur while the
    // user-supplied callback is executing from re-entering the handler.
    sr->serviceInterrupt = false;

    bool result;
    RootedValue interruptFunc(cx, sr->interruptFunc);
    if (!interruptFunc.isNull()) {
        JS::AutoSaveExceptionState savedExc(cx);
        JSAutoCompartment ac(cx, &interruptFunc.toObject());
        RootedValue rval(cx);
        if (!JS_CallFunctionValue(cx, nullptr, interruptFunc,
                                  JS::HandleValueArray::empty(), &rval))
        {
            return false;
        }
        if (rval.isBoolean())
            result = rval.toBoolean();
        else
            result = false;
    } else {
        result = false;
    }

    if (!result && sr->exitCode == 0)
        sr->exitCode = EXITCODE_TIMEOUT;

    return result;
}

/*
 * Some UTF-8 files, notably those written using Notepad, have a Unicode
 * Byte-Order-Mark (BOM) as their first character. This is useless (byte-order
 * is meaningless for UTF-8) but causes a syntax error unless we skip it.
 */
static void
SkipUTF8BOM(FILE* file)
{
    int ch1 = fgetc(file);
    int ch2 = fgetc(file);
    int ch3 = fgetc(file);

    // Skip the BOM
    if (ch1 == 0xEF && ch2 == 0xBB && ch3 == 0xBF)
        return;

    // No BOM - revert
    if (ch3 != EOF)
        ungetc(ch3, file);
    if (ch2 != EOF)
        ungetc(ch2, file);
    if (ch1 != EOF)
        ungetc(ch1, file);
}

static void
RunFile(JSContext* cx, const char* filename, FILE* file, bool compileOnly)
{
    ShellRuntime* sr = GetShellRuntime(cx);

    SkipUTF8BOM(file);

    // To support the UNIX #! shell hack, gobble the first line if it starts
    // with '#'.
    int ch = fgetc(file);
    if (ch == '#') {
        while ((ch = fgetc(file)) != EOF) {
            if (ch == '\n' || ch == '\r')
                break;
        }
    }
    ungetc(ch, file);

    int64_t t1 = PRMJ_Now();
    RootedScript script(cx);

    {
        CompileOptions options(cx);
        options.setIntroductionType("js shell file")
               .setUTF8(true)
               .setFileAndLine(filename, 1)
               .setIsRunOnce(true)
               .setNoScriptRval(true);

        sr->gotError = false;
        (void) JS::Compile(cx, options, file, &script);
        MOZ_ASSERT_IF(!script, sr->gotError);
    }

    #ifdef DEBUG
        if (dumpEntrainedVariables)
            AnalyzeEntrainedVariables(cx, script);
    #endif
    if (script && !compileOnly) {
        if (!JS_ExecuteScript(cx, script)) {
            if (!sr->quitting && sr->exitCode != EXITCODE_TIMEOUT)
                sr->exitCode = EXITCODE_RUNTIME_ERROR;
        }
        int64_t t2 = PRMJ_Now() - t1;
        if (printTiming)
            printf("runtime = %.3f ms\n", double(t2) / PRMJ_USEC_PER_MSEC);
    }
}

static bool
InitModuleLoader(JSContext* cx)
{
    // Decompress and evaluate the embedded module loader source to initialize
    // the module loader for the current compartment.

    uint32_t srcLen = moduleloader::GetRawScriptsSize();
    ScopedJSFreePtr<char> src(cx->pod_malloc<char>(srcLen));
    if (!src || !DecompressString(moduleloader::compressedSources, moduleloader::GetCompressedSize(),
                                  reinterpret_cast<unsigned char*>(src.get()), srcLen))
    {
        return false;
    }

    CompileOptions options(cx);
    options.setIntroductionType("shell module loader");
    options.setFileAndLine("shell/ModuleLoader.js", 1);
    options.setSelfHostingMode(false);
    options.setCanLazilyParse(false);
    options.setVersion(JSVERSION_LATEST);
    options.werrorOption = true;
    options.strictOption = true;

    RootedValue rv(cx);
    return Evaluate(cx, options, src, srcLen, &rv);
}

static bool
GetLoaderObject(JSContext* cx, MutableHandleObject resultOut)
{
    // Look up the |Reflect.Loader| object that has been defined by the module
    // loader.

    RootedObject object(cx, cx->global());
    RootedValue value(cx);
    if (!JS_GetProperty(cx, object, "Reflect", &value) || !value.isObject())
        return false;

    object = &value.toObject();
    if (!JS_GetProperty(cx, object, "Loader", &value) || !value.isObject())
        return false;

    resultOut.set(&value.toObject());
    return true;
}

static bool
GetImportMethod(JSContext* cx, HandleObject loader, MutableHandleFunction resultOut)
{
    // Look up the module loader's |import| method.

    RootedValue value(cx);
    if (!JS_GetProperty(cx, loader, "import", &value) || !value.isObject())
        return false;

    RootedObject object(cx, &value.toObject());
    if (!object->is<JSFunction>())
        return false;

    resultOut.set(&object->as<JSFunction>());
    return true;
}

static void
RunModule(JSContext* cx, const char* filename, FILE* file, bool compileOnly)
{
    // Exectute a module by calling |Reflect.Loader.import(filename)|.

    ShellRuntime* sr = GetShellRuntime(cx);

    RootedObject loaderObj(cx);
    MOZ_ALWAYS_TRUE(GetLoaderObject(cx, &loaderObj));

    RootedFunction importFun(cx);
    MOZ_ALWAYS_TRUE(GetImportMethod(cx, loaderObj, &importFun));

    AutoValueArray<2> args(cx);
    args[0].setString(JS_NewStringCopyZ(cx, filename));
    args[1].setUndefined();

    RootedValue value(cx);
    if (!JS_CallFunction(cx, loaderObj, importFun, args, &value)) {
        sr->exitCode = EXITCODE_RUNTIME_ERROR;
        return;
    }
}

static bool
EvalAndPrint(JSContext* cx, const char* bytes, size_t length,
             int lineno, bool compileOnly, FILE* out)
{
    // Eval.
    JS::CompileOptions options(cx);
    options.setIntroductionType("js shell interactive")
           .setUTF8(true)
           .setIsRunOnce(true)
           .setFileAndLine("typein", lineno);
    RootedScript script(cx);
    if (!JS::Compile(cx, options, bytes, length, &script))
        return false;
    if (compileOnly)
        return true;
    RootedValue result(cx);
    if (!JS_ExecuteScript(cx, script, &result))
        return false;

    if (!result.isUndefined()) {
        // Print.
        RootedString str(cx);
        str = JS_ValueToSource(cx, result);
        if (!str)
            return false;

        char* utf8chars = JS_EncodeStringToUTF8(cx, str);
        if (!utf8chars)
            return false;
        fprintf(out, "%s\n", utf8chars);
        JS_free(cx, utf8chars);
    }
    return true;
}

static void
ReadEvalPrintLoop(JSContext* cx, FILE* in, FILE* out, bool compileOnly)
{
    ShellRuntime* sr = GetShellRuntime(cx);
    int lineno = 1;
    bool hitEOF = false;

    do {
        /*
         * Accumulate lines until we get a 'compilable unit' - one that either
         * generates an error (before running out of source) or that compiles
         * cleanly.  This should be whenever we get a complete statement that
         * coincides with the end of a line.
         */
        int startline = lineno;
        typedef Vector<char, 32> CharBuffer;
        CharBuffer buffer(cx);
        do {
            ScheduleWatchdog(cx->runtime(), -1);
            sr->serviceInterrupt = false;
            errno = 0;

            char* line = GetLine(in, startline == lineno ? "js> " : "");
            if (!line) {
                if (errno) {
                    JS_ReportError(cx, strerror(errno));
                    return;
                }
                hitEOF = true;
                break;
            }

            if (!buffer.append(line, strlen(line)) || !buffer.append('\n'))
                return;

            lineno++;
            if (!ScheduleWatchdog(cx->runtime(), sr->timeoutInterval)) {
                hitEOF = true;
                break;
            }
        } while (!JS_BufferIsCompilableUnit(cx, cx->global(), buffer.begin(), buffer.length()));

        if (hitEOF && buffer.empty())
            break;

        if (!EvalAndPrint(cx, buffer.begin(), buffer.length(), startline, compileOnly,
                          out))
        {
            // Catch the error, report it, and keep going.
            JS_ReportPendingException(cx);
        }
    } while (!hitEOF && !sr->quitting);

    fprintf(out, "\n");
}

enum FileKind
{
    FileScript,
    FileModule
};

static void
Process(JSContext* cx, const char* filename, bool forceTTY, FileKind kind = FileScript)
{
    FILE* file;
    if (forceTTY || !filename || strcmp(filename, "-") == 0) {
        file = stdin;
    } else {
        file = fopen(filename, "r");
        if (!file) {
            JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr,
                                 JSSMSG_CANT_OPEN, filename, strerror(errno));
            return;
        }
    }
    AutoCloseFile autoClose(file);

    if (!forceTTY && !isatty(fileno(file))) {
        // It's not interactive - just execute it.
        if (kind == FileScript)
            RunFile(cx, filename, file, compileOnly);
        else
            RunModule(cx, filename, file, compileOnly);
    } else {
        // It's an interactive filehandle; drop into read-eval-print loop.
        MOZ_ASSERT(kind == FileScript);
        ReadEvalPrintLoop(cx, file, gOutFile, compileOnly);
    }
}

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 (NumberEqualsInt32(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;
}

static bool
CreateMappedArrayBuffer(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    if (args.length() < 1 || args.length() > 3) {
        JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr,
                             args.length() < 1 ? JSSMSG_NOT_ENOUGH_ARGS : JSSMSG_TOO_MANY_ARGS,
                             "createMappedArrayBuffer");
        return false;
    }

    RootedString rawFilenameStr(cx, JS::ToString(cx, args[0]));
    if (!rawFilenameStr)
        return false;
    // It's a little bizarre to resolve relative to the script, but for testing
    // I need a file at a known location, and the only good way I know of to do
    // that right now is to include it in the repo alongside the test script.
    // Bug 944164 would introduce an alternative.
    JSString* filenameStr = ResolvePath(cx, rawFilenameStr, ScriptRelative);
    if (!filenameStr)
        return false;
    JSAutoByteString filename(cx, filenameStr);
    if (!filename)
        return false;

    uint32_t offset = 0;
    if (args.length() >= 2) {
        if (!JS::ToUint32(cx, args[1], &offset))
            return false;
    }

    bool sizeGiven = false;
    uint32_t size;
    if (args.length() >= 3) {
        if (!JS::ToUint32(cx, args[2], &size))
            return false;
        sizeGiven = true;
        if (offset > size) {
            JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
                                 JSMSG_ARG_INDEX_OUT_OF_RANGE, "2");
            return false;
        }
    }

    FILE* file = fopen(filename.ptr(), "r");
    if (!file) {
        JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr,
                             JSSMSG_CANT_OPEN, filename.ptr(), strerror(errno));
        return false;
    }
    AutoCloseFile autoClose(file);

    if (!sizeGiven) {
        struct stat st;
        if (fstat(fileno(file), &st) < 0) {
            JS_ReportError(cx, "Unable to stat file");
            return false;
        }
        if (st.st_size < off_t(offset)) {
            JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
                                 JSMSG_ARG_INDEX_OUT_OF_RANGE, "2");
            return false;
        }
        size = st.st_size - offset;
    }

    void* contents = JS_CreateMappedArrayBufferContents(fileno(file), offset, size);
    if (!contents) {
        JS_ReportError(cx, "failed to allocate mapped array buffer contents (possibly due to bad alignment)");
        return false;
    }

    RootedObject obj(cx, JS_NewMappedArrayBufferWithContents(cx, size, contents));
    if (!obj)
        return false;

    args.rval().setObject(*obj);
    return true;
}

static bool
Options(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    JS::RuntimeOptions oldRuntimeOptions = JS::RuntimeOptionsRef(cx);
    for (unsigned i = 0; i < args.length(); i++) {
        JSString* str = JS::ToString(cx, args[i]);
        if (!str)
            return false;
        args[i].setString(str);

        JSAutoByteString opt(cx, str);
        if (!opt)
            return false;

        if (strcmp(opt.ptr(), "strict") == 0)
            JS::RuntimeOptionsRef(cx).toggleExtraWarnings();
        else if (strcmp(opt.ptr(), "werror") == 0)
            JS::RuntimeOptionsRef(cx).toggleWerror();
        else if (strcmp(opt.ptr(), "throw_on_asmjs_validation_failure") == 0)
            JS::RuntimeOptionsRef(cx).toggleThrowOnAsmJSValidationFailure();
        else if (strcmp(opt.ptr(), "strict_mode") == 0)
            JS::RuntimeOptionsRef(cx).toggleStrictMode();
        else {
            JS_ReportError(cx,
                           "unknown option name '%s'."
                           " The valid names are strict,"
                           " werror, and strict_mode.",
                           opt.ptr());
            return false;
        }
    }

    char* names = strdup("");
    bool found = false;
    if (names && oldRuntimeOptions.extraWarnings()) {
        names = JS_sprintf_append(names, "%s%s", found ? "," : "", "strict");
        found = true;
    }
    if (names && oldRuntimeOptions.werror()) {
        names = JS_sprintf_append(names, "%s%s", found ? "," : "", "werror");
        found = true;
    }
    if (names && oldRuntimeOptions.throwOnAsmJSValidationFailure()) {
        names = JS_sprintf_append(names, "%s%s", found ? "," : "", "throw_on_asmjs_validation_failure");
        found = true;
    }
    if (names && oldRuntimeOptions.strictMode()) {
        names = JS_sprintf_append(names, "%s%s", found ? "," : "", "strict_mode");
        found = true;
    }
    if (!names) {
        JS_ReportOutOfMemory(cx);
        return false;
    }

    JSString* str = JS_NewStringCopyZ(cx, names);
    free(names);
    if (!str)
        return false;
    args.rval().setString(str);
    return true;
}

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);
}

static bool
LoadScriptRelativeToScript(JSContext* cx, unsigned argc, Value* vp)
{
    return LoadScript(cx, argc, vp, true);
}

// Populate |options| with the options given by |opts|'s properties. If we
// need to convert a filename to a C string, let fileNameBytes own the
// bytes.
static bool
ParseCompileOptions(JSContext* cx, CompileOptions& options, HandleObject opts,
                    JSAutoByteString& fileNameBytes)
{
    RootedValue v(cx);
    RootedString s(cx);

    if (!JS_GetProperty(cx, opts, "isRunOnce", &v))
        return false;
    if (!v.isUndefined())
        options.setIsRunOnce(ToBoolean(v));

    if (!JS_GetProperty(cx, opts, "noScriptRval", &v))
        return false;
    if (!v.isUndefined())
        options.setNoScriptRval(ToBoolean(v));

    if (!JS_GetProperty(cx, opts, "fileName", &v))
        return false;
    if (v.isNull()) {
        options.setFile(nullptr);
    } else if (!v.isUndefined()) {
        s = ToString(cx, v);
        if (!s)
            return false;
        char* fileName = fileNameBytes.encodeLatin1(cx, s);
        if (!fileName)
            return false;
        options.setFile(fileName);
    }

    if (!JS_GetProperty(cx, opts, "element", &v))
        return false;
    if (v.isObject())
        options.setElement(&v.toObject());

    if (!JS_GetProperty(cx, opts, "elementAttributeName", &v))
        return false;
    if (!v.isUndefined()) {
        s = ToString(cx, v);
        if (!s)
            return false;
        options.setElementAttributeName(s);
    }

    if (!JS_GetProperty(cx, opts, "lineNumber", &v))
        return false;
    if (!v.isUndefined()) {
        uint32_t u;
        if (!ToUint32(cx, v, &u))
            return false;
        options.setLine(u);
    }

    if (!JS_GetProperty(cx, opts, "columnNumber", &v))
        return false;
    if (!v.isUndefined()) {
        int32_t c;
        if (!ToInt32(cx, v, &c))
            return false;
        options.setColumn(c);
    }

    if (!JS_GetProperty(cx, opts, "sourceIsLazy", &v))
        return false;
    if (v.isBoolean())
        options.setSourceIsLazy(v.toBoolean());

    return true;
}

class AutoNewContext
{
  private:
    JSContext* oldcx;
    JSContext* newcx;
    Maybe<JSAutoRequest> newRequest;
    Maybe<AutoCompartment> newCompartment;

    AutoNewContext(const AutoNewContext&) = delete;

  public:
    AutoNewContext() : oldcx(nullptr), newcx(nullptr) {}

    bool enter(JSContext* cx) {
        MOZ_ASSERT(!JS_IsExceptionPending(cx));
        oldcx = cx;
        newcx = NewContext(JS_GetRuntime(cx));
        if (!newcx)
            return false;
        JS::ContextOptionsRef(newcx).setDontReportUncaught(true);

        newRequest.emplace(newcx);
        newCompartment.emplace(newcx, JS::CurrentGlobalOrNull(cx));
        return true;
    }

    JSContext* get() { return newcx; }

    ~AutoNewContext() {
        if (newcx) {
            RootedValue exc(oldcx);
            bool throwing = JS_IsExceptionPending(newcx);
            if (throwing)
                JS_GetPendingException(newcx, &exc);
            newCompartment.reset();
            newRequest.reset();
            if (throwing && JS_WrapValue(oldcx, &exc))
                JS_SetPendingException(oldcx, exc);
            DestroyContext(newcx, false);
        }
    }
};

static void
my_LargeAllocFailCallback(void* data)
{
    JSContext* cx = (JSContext*)data;
    JSRuntime* rt = cx->runtime();

    if (!cx->isJSContext())
        return;

    MOZ_ASSERT(!rt->isHeapBusy());
    MOZ_ASSERT(!rt->currentThreadHasExclusiveAccess());

    JS::PrepareForFullGC(rt);
    AutoKeepAtoms keepAtoms(cx->perThreadData);
    rt->gc.gc(GC_NORMAL, JS::gcreason::SHARED_MEMORY_LIMIT);
}

static const uint32_t CacheEntry_SOURCE = 0;
static const uint32_t CacheEntry_BYTECODE = 1;

static const JSClass CacheEntry_class = {
    "CacheEntryObject", JSCLASS_HAS_RESERVED_SLOTS(2)
};

static bool
CacheEntry(JSContext* cx, unsigned argc, JS::Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    if (args.length() != 1 || !args[0].isString()) {
        JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_INVALID_ARGS, "CacheEntry");
        return false;
    }

    RootedObject obj(cx, JS_NewObject(cx, &CacheEntry_class));
    if (!obj)
        return false;

    SetReservedSlot(obj, CacheEntry_SOURCE, args[0]);
    SetReservedSlot(obj, CacheEntry_BYTECODE, UndefinedValue());
    args.rval().setObject(*obj);
    return true;
}

static bool
CacheEntry_isCacheEntry(JSObject* cache)
{
    return JS_GetClass(cache) == &CacheEntry_class;
}

static JSString*
CacheEntry_getSource(HandleObject cache)
{
    MOZ_ASSERT(CacheEntry_isCacheEntry(cache));
    Value v = JS_GetReservedSlot(cache, CacheEntry_SOURCE);
    if (!v.isString())
        return nullptr;

    return v.toString();
}

static uint8_t*
CacheEntry_getBytecode(HandleObject cache, uint32_t* length)
{
    MOZ_ASSERT(CacheEntry_isCacheEntry(cache));
    Value v = JS_GetReservedSlot(cache, CacheEntry_BYTECODE);
    if (!v.isObject() || !v.toObject().is<ArrayBufferObject>())
        return nullptr;

    ArrayBufferObject* arrayBuffer = &v.toObject().as<ArrayBufferObject>();
    *length = arrayBuffer->byteLength();
    return arrayBuffer->dataPointer();
}

static bool
CacheEntry_setBytecode(JSContext* cx, HandleObject cache, uint8_t* buffer, uint32_t length)
{
    MOZ_ASSERT(CacheEntry_isCacheEntry(cache));

    ArrayBufferObject::BufferContents contents =
        ArrayBufferObject::BufferContents::create<ArrayBufferObject::PLAIN>(buffer);
    Rooted<ArrayBufferObject*> arrayBuffer(cx, ArrayBufferObject::create(cx, length, contents));
    if (!arrayBuffer)
        return false;

    SetReservedSlot(cache, CacheEntry_BYTECODE, ObjectValue(*arrayBuffer));
    return true;
}

class AutoSaveFrameChain
{
    JSContext* cx_;
    bool saved_;

  public:
    explicit AutoSaveFrameChain(JSContext* cx)
      : cx_(cx),
        saved_(false)
    {}

    bool save() {
        if (!JS_SaveFrameChain(cx_))
            return false;
        saved_ = true;
        return true;
    }

    ~AutoSaveFrameChain() {
        if (saved_)
            JS_RestoreFrameChain(cx_);
    }
};

static bool
Evaluate(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    if (args.length() < 1 || args.length() > 2) {
        JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr,
                             args.length() < 1 ? JSSMSG_NOT_ENOUGH_ARGS : JSSMSG_TOO_MANY_ARGS,
                             "evaluate");
        return false;
    }

    RootedString code(cx, nullptr);
    RootedObject cacheEntry(cx, nullptr);
    if (args[0].isString()) {
        code = args[0].toString();
    } else if (args[0].isObject() && CacheEntry_isCacheEntry(&args[0].toObject())) {
        cacheEntry = &args[0].toObject();
        code = CacheEntry_getSource(cacheEntry);
    }

    if (!code || (args.length() == 2 && args[1].isPrimitive())) {
        JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_INVALID_ARGS, "evaluate");
        return false;
    }

    CompileOptions options(cx);
    JSAutoByteString fileNameBytes;
    bool newContext = false;
    RootedString displayURL(cx);
    RootedString sourceMapURL(cx);
    RootedObject global(cx, nullptr);
    bool catchTermination = false;
    bool saveFrameChain = false;
    bool loadBytecode = false;
    bool saveBytecode = false;
    bool assertEqBytecode = false;
    RootedObject callerGlobal(cx, cx->global());

    options.setIntroductionType("js shell evaluate")
           .setFileAndLine("@evaluate", 1);

    global = JS_GetGlobalForObject(cx, &args.callee());
    if (!global)
        return false;

    if (args.length() == 2) {
        RootedObject opts(cx, &args[1].toObject());
        RootedValue v(cx);

        if (!ParseCompileOptions(cx, options, opts, fileNameBytes))
            return false;

        if (!JS_GetProperty(cx, opts, "newContext", &v))
            return false;
        if (!v.isUndefined())
            newContext = ToBoolean(v);

        if (!JS_GetProperty(cx, opts, "displayURL", &v))
            return false;
        if (!v.isUndefined()) {
            displayURL = ToString(cx, v);
            if (!displayURL)
                return false;
        }

        if (!JS_GetProperty(cx, opts, "sourceMapURL", &v))
            return false;
        if (!v.isUndefined()) {
            sourceMapURL = ToString(cx, v);
            if (!sourceMapURL)
                return false;
        }

        if (!JS_GetProperty(cx, opts, "global", &v))
            return false;
        if (!v.isUndefined()) {
            if (v.isObject()) {
                global = js::UncheckedUnwrap(&v.toObject());
                if (!global)
                    return false;
            }
            if (!global || !(JS_GetClass(global)->flags & JSCLASS_IS_GLOBAL)) {
                JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_UNEXPECTED_TYPE,
                                     "\"global\" passed to evaluate()", "not a global object");
                return false;
            }
        }

        if (!JS_GetProperty(cx, opts, "catchTermination", &v))
            return false;
        if (!v.isUndefined())
            catchTermination = ToBoolean(v);

        if (!JS_GetProperty(cx, opts, "saveFrameChain", &v))
            return false;
        if (!v.isUndefined())
            saveFrameChain = ToBoolean(v);

        if (!JS_GetProperty(cx, opts, "loadBytecode", &v))
            return false;
        if (!v.isUndefined())
            loadBytecode = ToBoolean(v);

        if (!JS_GetProperty(cx, opts, "saveBytecode", &v))
            return false;
        if (!v.isUndefined())
            saveBytecode = ToBoolean(v);

        if (!JS_GetProperty(cx, opts, "assertEqBytecode", &v))
            return false;
        if (!v.isUndefined())
            assertEqBytecode = ToBoolean(v);

        // We cannot load or save the bytecode if we have no object where the
        // bytecode cache is stored.
        if (loadBytecode || saveBytecode) {
            if (!cacheEntry) {
                JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_INVALID_ARGS,
                                     "evaluate");
                return false;
            }
        }
    }

    AutoStableStringChars codeChars(cx);
    if (!codeChars.initTwoByte(cx, code))
        return false;

    AutoNewContext ancx;
    if (newContext) {
        if (!ancx.enter(cx))
            return false;
        cx = ancx.get();
    }

    uint32_t loadLength = 0;
    uint8_t* loadBuffer = nullptr;
    uint32_t saveLength = 0;
    ScopedJSFreePtr<uint8_t> saveBuffer;

    if (loadBytecode) {
        loadBuffer = CacheEntry_getBytecode(cacheEntry, &loadLength);
        if (!loadBuffer)
            return false;
    }

    {
        AutoSaveFrameChain asfc(cx);
        if (saveFrameChain && !asfc.save())
            return false;

        JSAutoCompartment ac(cx, global);
        RootedScript script(cx);

        {
            if (saveBytecode) {
                if (!JS::CompartmentOptionsRef(cx).cloneSingletons()) {
                    JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr,
                                         JSSMSG_CACHE_SINGLETON_FAILED);
                    return false;
                }

                // cloneSingletons implies that singletons are used as template objects.
                MOZ_ASSERT(JS::CompartmentOptionsRef(cx).getSingletonsAsTemplates());
            }

            if (loadBytecode) {
                script = JS_DecodeScript(cx, loadBuffer, loadLength);
            } else {
                mozilla::Range<const char16_t> chars = codeChars.twoByteRange();
                (void) JS::Compile(cx, options, chars.start().get(), chars.length(), &script);
            }

            if (!script)
                return false;
        }

        if (displayURL && !script->scriptSource()->hasDisplayURL()) {
            JSFlatString* flat = displayURL->ensureFlat(cx);
            if (!flat)
                return false;

            AutoStableStringChars chars(cx);
            if (!chars.initTwoByte(cx, flat))
                return false;

            const char16_t* durl = chars.twoByteRange().start().get();
            if (!script->scriptSource()->setDisplayURL(cx, durl))
                return false;
        }
        if (sourceMapURL && !script->scriptSource()->hasSourceMapURL()) {
            JSFlatString* flat = sourceMapURL->ensureFlat(cx);
            if (!flat)
                return false;

            AutoStableStringChars chars(cx);
            if (!chars.initTwoByte(cx, flat))
                return false;

            const char16_t* smurl = chars.twoByteRange().start().get();
            if (!script->scriptSource()->setSourceMapURL(cx, smurl))
                return false;
        }
        if (!JS_ExecuteScript(cx, script, args.rval())) {
            if (catchTermination && !JS_IsExceptionPending(cx)) {
                JSAutoCompartment ac1(cx, callerGlobal);
                JSString* str = JS_NewStringCopyZ(cx, "terminated");
                if (!str)
                    return false;
                args.rval().setString(str);
                return true;
            }
            return false;
        }

        if (saveBytecode) {
            saveBuffer = reinterpret_cast<uint8_t*>(JS_EncodeScript(cx, script, &saveLength));
            if (!saveBuffer)
                return false;
        }
    }

    if (saveBytecode) {
        // If we are both loading and saving, we assert that we are going to
        // replace the current bytecode by the same stream of bytes.
        if (loadBytecode && assertEqBytecode) {
            if (saveLength != loadLength) {
                char loadLengthStr[16];
                JS_snprintf(loadLengthStr, sizeof(loadLengthStr), "%u", loadLength);
                char saveLengthStr[16];
                JS_snprintf(saveLengthStr, sizeof(saveLengthStr), "%u", saveLength);

                JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_CACHE_EQ_SIZE_FAILED,
                                     loadLengthStr, saveLengthStr);
                return false;
            }

            if (!PodEqual(loadBuffer, saveBuffer.get(), loadLength)) {
                JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr,
                                     JSSMSG_CACHE_EQ_CONTENT_FAILED);
                return false;
            }
        }

        if (!CacheEntry_setBytecode(cx, cacheEntry, saveBuffer, saveLength))
            return false;

        saveBuffer.forget();
    }

    return JS_WrapValue(cx, args.rval());
}

JSString*
js::shell::FileAsString(JSContext* cx, const char* pathname)
{
    FILE* file;
    RootedString str(cx);
    size_t len, cc;
    char* buf;

    file = fopen(pathname, "rb");
    if (!file) {
        JS_ReportError(cx, "can't open %s: %s", pathname, strerror(errno));
        return nullptr;
    }
    AutoCloseFile autoClose(file);

    if (fseek(file, 0, SEEK_END) != 0) {
        JS_ReportError(cx, "can't seek end of %s", pathname);
    } else {
        len = ftell(file);
        if (fseek(file, 0, SEEK_SET) != 0) {
            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 {
                    char16_t* ucbuf =
                        JS::UTF8CharsToNewTwoByteCharsZ(cx, JS::UTF8Chars(buf, len), &len).get();
                    if (!ucbuf) {
                        JS_ReportError(cx, "Invalid UTF-8 in file '%s'", pathname);
                        return nullptr;
                    }
                    str = JS_NewUCStringCopyN(cx, ucbuf, len);
                    free(ucbuf);
                }
                JS_free(cx, buf);
            }
        }
    }

    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 bool
Run(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    if (args.length() != 1) {
        JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_INVALID_ARGS, "run");
        return false;
    }

    RootedString str(cx, JS::ToString(cx, args[0]));
    if (!str)
        return false;
    args[0].setString(str);
    JSAutoByteString filename(cx, str);
    if (!filename)
        return false;

    str = FileAsString(cx, filename.ptr());
    if (!str)
        return false;

    AutoStableStringChars chars(cx);
    if (!chars.initTwoByte(cx, str))
        return false;

    const char16_t* ucbuf = chars.twoByteRange().start().get();
    size_t buflen = str->length();

    RootedScript script(cx);
    int64_t startClock = PRMJ_Now();
    {
        JS::CompileOptions options(cx);
        options.setIntroductionType("js shell run")
               .setFileAndLine(filename.ptr(), 1)
               .setIsRunOnce(true)
               .setNoScriptRval(true);
        if (!JS_CompileUCScript(cx, ucbuf, buflen, options, &script))
            return false;
    }

    if (!JS_ExecuteScript(cx, script))
        return false;

    int64_t endClock = PRMJ_Now();

    args.rval().setDouble((endClock - startClock) / double(PRMJ_USEC_PER_MSEC));
    return true;
}

/*
 * function readline()
 * Provides a hook for scripts to read a line from stdin.
 */
static bool
ReadLine(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

#define BUFSIZE 256
    FILE* from = stdin;
    size_t buflength = 0;
    size_t bufsize = BUFSIZE;
    char* buf = (char*) JS_malloc(cx, bufsize);
    if (!buf)
        return false;

    bool sawNewline = false;
    size_t gotlength;
    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 = true;
            break;
        } else if (buflength < bufsize - 1) {
            break;
        }

        /* Else, grow our buffer for another pass. */
        char* tmp;
        bufsize *= 2;
        if (bufsize > buflength) {
            tmp = static_cast<char*>(JS_realloc(cx, buf, bufsize / 2, bufsize));
        } else {
            JS_ReportOutOfMemory(cx);
            tmp = nullptr;
        }

        if (!tmp) {
            JS_free(cx, buf);
            return false;
        }

        buf = tmp;
    }

    /* Treat the empty string specially. */
    if (buflength == 0) {
        args.rval().set(feof(from) ? NullValue() : JS_GetEmptyStringValue(cx));
        JS_free(cx, buf);
        return true;
    }

    /* Shrink the buffer to the real size. */
    char* tmp = static_cast<char*>(JS_realloc(cx, buf, bufsize, buflength));
    if (!tmp) {
        JS_free(cx, buf);
        return false;
    }

    buf = tmp;

    /*
     * Turn buf into a JSString. Note that buflength includes the trailing null
     * character.
     */
    JSString* str = JS_NewStringCopyN(cx, buf, sawNewline ? buflength - 1 : buflength);
    JS_free(cx, buf);
    if (!str)
        return false;

    args.rval().setString(str);
    return true;
}

static bool
PutStr(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    if (args.length() != 0) {
        RootedString str(cx, JS::ToString(cx, args[0]));
        if (!str)
            return false;
        char* bytes = JS_EncodeStringToUTF8(cx, str);
        if (!bytes)
            return false;
        fputs(bytes, gOutFile);
        JS_free(cx, bytes);
        fflush(gOutFile);
    }

    args.rval().setUndefined();
    return true;
}

static bool
Now(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    double now = PRMJ_Now() / double(PRMJ_USEC_PER_MSEC);
    args.rval().setDouble(now);
    return true;
}

static bool
PrintInternal(JSContext* cx, const CallArgs& args, FILE* file)
{
    for (unsigned i = 0; i < args.length(); i++) {
        RootedString str(cx, JS::ToString(cx, args[i]));
        if (!str)
            return false;
        char* bytes = JS_EncodeStringToUTF8(cx, str);
        if (!bytes)
            return false;
        fprintf(file, "%s%s", i ? " " : "", bytes);
        JS_free(cx, bytes);
    }

    fputc('\n', file);
    fflush(file);

    args.rval().setUndefined();
    return true;
}

static bool
Print(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    return PrintInternal(cx, args, gOutFile);
}

static bool
PrintErr(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    return PrintInternal(cx, args, gErrFile);
}

static bool
Help(JSContext* cx, unsigned argc, Value* vp);

static bool
Quit(JSContext* cx, unsigned argc, Value* vp)
{
    ShellRuntime* sr = GetShellRuntime(cx);

#ifdef JS_MORE_DETERMINISTIC
    // Print a message to stderr in more-deterministic builds to help jsfunfuzz
    // find uncatchable-exception bugs.
    fprintf(stderr, "quit called\n");
#endif

    CallArgs args = CallArgsFromVp(argc, vp);
    int32_t code;
    if (!ToInt32(cx, args.get(0), &code))
        return false;

    // The fuzzers check the shell's exit code and assume a value >= 128 means
    // the process crashed (for instance, SIGSEGV will result in code 139). On
    // POSIX platforms, the exit code is 8-bit and negative values can also
    // result in an exit code >= 128. We restrict the value to range [0, 127] to
    // avoid false positives.
    if (code < 0 || code >= 128) {
        JS_ReportError(cx, "quit exit code should be in range 0-127");
        return false;
    }

    sr->exitCode = code;
    sr->quitting = true;
    return false;
}

static bool
StartTimingMutator(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    if (args.length() > 0) {
        JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr,
                             JSSMSG_TOO_MANY_ARGS, "startTimingMutator");
        return false;
    }

    if (!cx->runtime()->gc.stats.startTimingMutator()) {
        JS_ReportError(cx, "StartTimingMutator should only be called from outside of GC");
        return false;
    }

    args.rval().setUndefined();
    return true;
}

static bool
StopTimingMutator(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    if (args.length() > 0) {
        JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr,
                             JSSMSG_TOO_MANY_ARGS, "stopTimingMutator");
        return false;
    }

    double mutator_ms, gc_ms;
    if (!cx->runtime()->gc.stats.stopTimingMutator(mutator_ms, gc_ms)) {
        JS_ReportError(cx, "stopTimingMutator called when not timing the mutator");
        return false;
    }
    double total_ms = mutator_ms + gc_ms;
    if (total_ms > 0) {
        fprintf(gOutFile, "Mutator: %.3fms (%.1f%%), GC: %.3fms (%.1f%%)\n",
                mutator_ms, mutator_ms / total_ms * 100.0, gc_ms, gc_ms / total_ms * 100.0);
    }

    args.rval().setUndefined();
    return true;
}

static const char*
ToSource(JSContext* cx, MutableHandleValue vp, JSAutoByteString* bytes)
{
    JSString* str = JS_ValueToSource(cx, vp);
    if (str) {
        vp.setString(str);
        if (bytes->encodeLatin1(cx, str))
            return bytes->ptr();
    }
    JS_ClearPendingException(cx);
    return "<<error converting value to string>>";
}

static bool
AssertEq(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    if (!(args.length() == 2 || (args.length() == 3 && args[2].isString()))) {
        JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr,
                             (args.length() < 2)
                             ? JSSMSG_NOT_ENOUGH_ARGS
                             : (args.length() == 3)
                             ? JSSMSG_INVALID_ARGS
                             : JSSMSG_TOO_MANY_ARGS,
                             "assertEq");
        return false;
    }

    bool same;
    if (!JS_SameValue(cx, args[0], args[1], &same))
        return false;
    if (!same) {
        JSAutoByteString bytes0, bytes1;
        const char* actual = ToSource(cx, args[0], &bytes0);
        const char* expected = ToSource(cx, args[1], &bytes1);
        if (args.length() == 2) {
            JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_ASSERT_EQ_FAILED,
                                 actual, expected);
        } else {
            JSAutoByteString bytes2(cx, args[2].toString());
            if (!bytes2)
                return false;
            JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_ASSERT_EQ_FAILED_MSG,
                                 actual, expected, bytes2.ptr());
        }
        return false;
    }
    args.rval().setUndefined();
    return true;
}

static JSScript*
ValueToScript(JSContext* cx, Value vArg, JSFunction** funp = nullptr)
{
    RootedValue v(cx, vArg);

    if (v.isString()) {
        // To convert a string to a script, compile it. Parse it as an ES6 Program.
        RootedLinearString linearStr(cx, StringToLinearString(cx, v.toString()));
        if (!linearStr)
            return nullptr;
        size_t len = GetLinearStringLength(linearStr);
        AutoStableStringChars linearChars(cx);
        if (!linearChars.initTwoByte(cx, linearStr))
            return nullptr;
        const char16_t* chars = linearChars.twoByteRange().start().get();

        RootedScript script(cx);
        CompileOptions options(cx);
        if (!JS::Compile(cx, options, chars, len, &script))
            return nullptr;
        return script;
    }

    RootedFunction fun(cx, JS_ValueToFunction(cx, v));
    if (!fun)
        return nullptr;

    // Unwrap bound functions.
    while (fun->isBoundFunction()) {
        JSObject* target = fun->getBoundFunctionTarget();
        if (target && target->is<JSFunction>())
            fun = &target->as<JSFunction>();
        else
            break;
    }

    if (!fun->isInterpreted()) {
        JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_SCRIPTS_ONLY);
        return nullptr;
    }

    JSScript* script = fun->getOrCreateScript(cx);
    if (!script)
        return nullptr;

    if (fun && funp)
        *funp = fun;

    return script;
}

static JSScript*
GetTopScript(JSContext* cx)
{
    NonBuiltinScriptFrameIter iter(cx);
    return iter.done() ? nullptr : iter.script();
}

static bool
GetScriptAndPCArgs(JSContext* cx, unsigned argc, Value* argv, MutableHandleScript scriptp,
                   int32_t* ip)
{
    RootedScript script(cx, GetTopScript(cx));
    *ip = 0;
    if (argc != 0) {
        Value v = argv[0];
        unsigned intarg = 0;
        if (v.isObject() &&
            JS_GetClass(&v.toObject()) == Jsvalify(&JSFunction::class_)) {
            script = ValueToScript(cx, v);
            if (!script)
                return false;
            intarg++;
        }
        if (argc > intarg) {
            if (!JS::ToInt32(cx, HandleValue::fromMarkedLocation(&argv[intarg]), ip))
                return false;
            if ((uint32_t)*ip >= script->length()) {
                JS_ReportError(cx, "Invalid PC");
                return false;
            }
        }
    }

    scriptp.set(script);

    return true;
}

static bool
LineToPC(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    if (args.length() == 0) {
        JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_LINE2PC_USAGE);
        return false;
    }

    RootedScript script(cx, GetTopScript(cx));
    int32_t lineArg = 0;
    if (args[0].isObject() && args[0].toObject().is<JSFunction>()) {
        script = ValueToScript(cx, args[0]);
        if (!script)
            return false;
        lineArg++;
    }

    uint32_t lineno;
    if (!ToUint32(cx, args.get(lineArg), &lineno))
         return false;

    jsbytecode* pc = LineNumberToPC(script, lineno);
    if (!pc)
        return false;
    args.rval().setInt32(script->pcToOffset(pc));
    return true;
}

static bool
PCToLine(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    RootedScript script(cx);
    int32_t i;
    unsigned lineno;

    if (!GetScriptAndPCArgs(cx, args.length(), args.array(), &script, &i))
        return false;
    lineno = PCToLineNumber(script, script->offsetToPC(i));
    if (!lineno)
        return false;
    args.rval().setInt32(lineno);
    return true;
}

#ifdef DEBUG

static void
UpdateSwitchTableBounds(JSContext* cx, HandleScript script, unsigned offset,
                        unsigned* start, unsigned* end)
{
    jsbytecode* pc;
    JSOp op;
    ptrdiff_t jmplen;
    int32_t low, high, n;

    pc = script->offsetToPC(offset);
    op = JSOp(*pc);
    switch (op) {
      case JSOP_TABLESWITCH:
        jmplen = JUMP_OFFSET_LEN;
        pc += jmplen;
        low = GET_JUMP_OFFSET(pc);
        pc += JUMP_OFFSET_LEN;
        high = GET_JUMP_OFFSET(pc);
        pc += JUMP_OFFSET_LEN;
        n = high - low + 1;
        break;

      default:
        /* [condswitch] switch does not have any jump or lookup tables. */
        MOZ_ASSERT(op == JSOP_CONDSWITCH);
        return;
    }

    *start = script->pcToOffset(pc);
    *end = *start + (unsigned)(n * jmplen);
}

static void
SrcNotes(JSContext* cx, HandleScript script, Sprinter* sp)
{
    Sprint(sp, "\nSource notes:\n");
    Sprint(sp, "%4s %4s %5s %6s %-8s %s\n",
           "ofs", "line", "pc", "delta", "desc", "args");
    Sprint(sp, "---- ---- ----- ------ -------- ------\n");
    unsigned offset = 0;
    unsigned colspan = 0;
    unsigned lineno = script->lineno();
    jssrcnote* notes = script->notes();
    unsigned switchTableEnd = 0, switchTableStart = 0;
    for (jssrcnote* sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
        unsigned delta = SN_DELTA(sn);
        offset += delta;
        SrcNoteType type = (SrcNoteType) SN_TYPE(sn);
        const char* name = js_SrcNoteSpec[type].name;
        Sprint(sp, "%3u: %4u %5u [%4u] %-8s", unsigned(sn - notes), lineno, offset, delta, name);
        switch (type) {
          case SRC_NULL:
          case SRC_IF:
          case SRC_CONTINUE:
          case SRC_BREAK:
          case SRC_BREAK2LABEL:
          case SRC_SWITCHBREAK:
          case SRC_ASSIGNOP:
          case SRC_XDELTA:
            break;

          case SRC_COLSPAN:
            colspan = SN_OFFSET_TO_COLSPAN(GetSrcNoteOffset(sn, 0));
            Sprint(sp, "%d", colspan);
            break;

          case SRC_SETLINE:
            lineno = GetSrcNoteOffset(sn, 0);
            Sprint(sp, " lineno %u", lineno);
            break;

          case SRC_NEWLINE:
            ++lineno;
            break;

          case SRC_FOR:
            Sprint(sp, " cond %u update %u tail %u",
                   unsigned(GetSrcNoteOffset(sn, 0)),
                   unsigned(GetSrcNoteOffset(sn, 1)),
                   unsigned(GetSrcNoteOffset(sn, 2)));
            break;

          case SRC_IF_ELSE:
            Sprint(sp, " else %u", unsigned(GetSrcNoteOffset(sn, 0)));
            break;

          case SRC_FOR_IN:
          case SRC_FOR_OF:
            Sprint(sp, " closingjump %u", unsigned(GetSrcNoteOffset(sn, 0)));
            break;

          case SRC_COND:
          case SRC_WHILE:
          case SRC_NEXTCASE:
            Sprint(sp, " offset %u", unsigned(GetSrcNoteOffset(sn, 0)));
            break;

          case SRC_TABLESWITCH: {
            JSOp op = JSOp(script->code()[offset]);
            MOZ_ASSERT(op == JSOP_TABLESWITCH);
            Sprint(sp, " length %u", unsigned(GetSrcNoteOffset(sn, 0)));
            UpdateSwitchTableBounds(cx, script, offset,
                                    &switchTableStart, &switchTableEnd);
            break;
          }
          case SRC_CONDSWITCH: {
            JSOp op = JSOp(script->code()[offset]);
            MOZ_ASSERT(op == JSOP_CONDSWITCH);
            Sprint(sp, " length %u", unsigned(GetSrcNoteOffset(sn, 0)));
            unsigned caseOff = (unsigned) GetSrcNoteOffset(sn, 1);
            if (caseOff)
                Sprint(sp, " first case offset %u", caseOff);
            UpdateSwitchTableBounds(cx, script, offset,
                                    &switchTableStart, &switchTableEnd);
            break;
          }

          case SRC_TRY:
            MOZ_ASSERT(JSOp(script->code()[offset]) == JSOP_TRY);
            Sprint(sp, " offset to jump %u", unsigned(GetSrcNoteOffset(sn, 0)));
            break;

          default:
            MOZ_ASSERT(0);
            break;
        }
        Sprint(sp, "\n");
    }
}

static bool
Notes(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    Sprinter sprinter(cx);
    if (!sprinter.init())
        return false;

    for (unsigned i = 0; i < args.length(); i++) {
        RootedScript script (cx, ValueToScript(cx, args[i]));
        if (!script)
            return false;

        SrcNotes(cx, script, &sprinter);
    }

    JSString* str = JS_NewStringCopyZ(cx, sprinter.string());
    if (!str)
        return false;
    args.rval().setString(str);
    return true;
}

JS_STATIC_ASSERT(JSTRY_CATCH == 0);
JS_STATIC_ASSERT(JSTRY_FINALLY == 1);
JS_STATIC_ASSERT(JSTRY_FOR_IN == 2);

static const char* const TryNoteNames[] = { "catch", "finally", "for-in", "for-of", "loop" };

static bool
TryNotes(JSContext* cx, HandleScript script, Sprinter* sp)
{
    if (!script->hasTrynotes())
        return true;

    JSTryNote* tn = script->trynotes()->vector;
    JSTryNote* tnlimit = tn + script->trynotes()->length;
    Sprint(sp, "\nException table:\nkind      stack    start      end\n");
    do {
        MOZ_ASSERT(tn->kind < ArrayLength(TryNoteNames));
        Sprint(sp, " %-7s %6u %8u %8u\n",
               TryNoteNames[tn->kind], tn->stackDepth,
               tn->start, tn->start + tn->length);
    } while (++tn != tnlimit);
    return true;
}

static bool
BlockNotes(JSContext* cx, HandleScript script, Sprinter* sp)
{
    if (!script->hasBlockScopes())
        return true;

    Sprint(sp, "\nBlock table:\n   index   parent    start      end\n");

    BlockScopeArray* scopes = script->blockScopes();
    for (uint32_t i = 0; i < scopes->length; i++) {
        const BlockScopeNote* note = &scopes->vector[i];
        if (note->index == BlockScopeNote::NoBlockScopeIndex)
            Sprint(sp, "%8s ", "(none)");
        else
            Sprint(sp, "%8u ", note->index);
        if (note->parent == BlockScopeNote::NoBlockScopeIndex)
            Sprint(sp, "%8s ", "(none)");
        else
            Sprint(sp, "%8u ", note->parent);
        Sprint(sp, "%8u %8u\n", note->start, note->start + note->length);
    }
    return true;
}

static bool
DisassembleScript(JSContext* cx, HandleScript script, HandleFunction fun,
                  bool lines, bool recursive, bool sourceNotes, Sprinter* sp)
{
    if (fun) {
        Sprint(sp, "flags:");
        if (fun->isLambda())
            Sprint(sp, " LAMBDA");
        if (fun->needsCallObject())
            Sprint(sp, " NEEDS_CALLOBJECT");
        if (fun->isConstructor())
            Sprint(sp, " CONSTRUCTOR");
        if (fun->isExprBody())
            Sprint(sp, " EXPRESSION_CLOSURE");
        if (fun->isFunctionPrototype())
            Sprint(sp, " Function.prototype");
        if (fun->isSelfHostedBuiltin())
            Sprint(sp, " SELF_HOSTED");
        if (fun->isArrow())
            Sprint(sp, " ARROW");
        Sprint(sp, "\n");
    }

    if (!Disassemble(cx, script, lines, sp))
        return false;
    if (sourceNotes)
        SrcNotes(cx, script, sp);
    TryNotes(cx, script, sp);
    BlockNotes(cx, script, sp);

    if (recursive && script->hasObjects()) {
        ObjectArray* objects = script->objects();
        for (unsigned i = 0; i != objects->length; ++i) {
            JSObject* obj = objects->vector[i];
            if (obj->is<JSFunction>()) {
                Sprint(sp, "\n");
                RootedFunction fun(cx, &obj->as<JSFunction>());
                if (fun->isInterpreted()) {
                    RootedScript script(cx, fun->getOrCreateScript(cx));
                    if (script) {
                        if (!DisassembleScript(cx, script, fun, lines, recursive, sourceNotes, sp))
                            return false;
                    }
                } else {
                    Sprint(sp, "[native code]\n");
                }
            }
        }
    }
    return true;
}

namespace {

struct DisassembleOptionParser {
    unsigned argc;
    Value* argv;
    bool lines;
    bool recursive;
    bool sourceNotes;

    DisassembleOptionParser(unsigned argc, Value* argv)
      : argc(argc), argv(argv), lines(false), recursive(false), sourceNotes(true) {}

    bool parse(JSContext* cx) {
        /* Read options off early arguments */
        while (argc > 0 && argv[0].isString()) {
            JSString* str = argv[0].toString();
            JSFlatString* flatStr = JS_FlattenString(cx, str);
            if (!flatStr)
                return false;
            if (JS_FlatStringEqualsAscii(flatStr, "-l"))
                lines = true;
            else if (JS_FlatStringEqualsAscii(flatStr, "-r"))
                recursive = true;
            else if (JS_FlatStringEqualsAscii(flatStr, "-S"))
                sourceNotes = false;
            else
                break;
            argv++, argc--;
        }
        return true;
    }
};

} /* anonymous namespace */

static bool
DisassembleToSprinter(JSContext* cx, unsigned argc, Value* vp, Sprinter* sprinter)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    DisassembleOptionParser p(args.length(), args.array());
    if (!p.parse(cx))
        return false;

    if (p.argc == 0) {
        /* Without arguments, disassemble the current script. */
        RootedScript script(cx, GetTopScript(cx));
        if (script) {
            JSAutoCompartment ac(cx, script);
            if (!Disassemble(cx, script, p.lines, sprinter))
                return false;
            SrcNotes(cx, script, sprinter);
            TryNotes(cx, script, sprinter);
            BlockNotes(cx, script, sprinter);
        }
    } else {
        for (unsigned i = 0; i < p.argc; i++) {
            RootedFunction fun(cx);
            RootedScript script(cx);
            RootedValue value(cx, p.argv[i]);
            if (value.isObject() && value.toObject().is<ModuleObject>())
                script = value.toObject().as<ModuleObject>().script();
            else
                script = ValueToScript(cx, value, fun.address());
            if (!script)
                return false;
            if (!DisassembleScript(cx, script, fun, p.lines, p.recursive, p.sourceNotes, sprinter))
                return false;
        }
    }

    return !sprinter->hadOutOfMemory();
}

static bool
DisassembleToString(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    Sprinter sprinter(cx);
    if (!sprinter.init())
        return false;
    if (!DisassembleToSprinter(cx, args.length(), vp, &sprinter))
        return false;

    JSString* str = JS_NewStringCopyZ(cx, sprinter.string());
    if (!str)
        return false;
    args.rval().setString(str);
    return true;
}

static bool
Disassemble(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    Sprinter sprinter(cx);
    if (!sprinter.init())
        return false;
    if (!DisassembleToSprinter(cx, args.length(), vp, &sprinter))
        return false;

    fprintf(stdout, "%s\n", sprinter.string());
    args.rval().setUndefined();
    return true;
}

static bool
DisassFile(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    /* Support extra options at the start, just like Disassemble. */
    DisassembleOptionParser p(args.length(), args.array());
    if (!p.parse(cx))
        return false;

    if (!p.argc) {
        args.rval().setUndefined();
        return true;
    }

    // We should change DisassembleOptionParser to store CallArgs.
    JSString* str = JS::ToString(cx, HandleValue::fromMarkedLocation(&p.argv[0]));
    if (!str)
        return false;
    JSAutoByteString filename(cx, str);
    if (!filename)
        return false;
    RootedScript script(cx);

    {
        CompileOptions options(cx);
        options.setIntroductionType("js shell disFile")
               .setUTF8(true)
               .setFileAndLine(filename.ptr(), 1)
               .setIsRunOnce(true)
               .setNoScriptRval(true);

        if (!JS::Compile(cx, options, filename.ptr(), &script))
            return false;
    }

    Sprinter sprinter(cx);
    if (!sprinter.init())
        return false;
    bool ok = DisassembleScript(cx, script, nullptr, p.lines, p.recursive, p.sourceNotes, &sprinter);
    if (ok)
        fprintf(stdout, "%s\n", sprinter.string());
    if (!ok)
        return false;

    args.rval().setUndefined();
    return true;
}

static bool
DisassWithSrc(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

#define LINE_BUF_LEN 512
    unsigned len, line1, line2, bupline;
    FILE* file;
    char linebuf[LINE_BUF_LEN];
    static const char sep[] = ";-------------------------";

    bool ok = true;
    RootedScript script(cx);
    for (unsigned i = 0; ok && i < args.length(); i++) {
        script = ValueToScript(cx, args[i]);
        if (!script)
           return false;

        if (!script->filename()) {
            JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr,
                                 JSSMSG_FILE_SCRIPTS_ONLY);
            return false;
        }

        file = fopen(script->filename(), "r");
        if (!file) {
            JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr,
                                 JSSMSG_CANT_OPEN, script->filename(),
                                 strerror(errno));
            return false;
        }

        jsbytecode* pc = script->code();
        jsbytecode* end = script->codeEnd();

        Sprinter sprinter(cx);
        if (!sprinter.init()) {
            ok = false;
            goto bail;
        }

        /* burn the leading lines */
        line2 = PCToLineNumber(script, pc);
        for (line1 = 0; line1 < line2 - 1; line1++) {
            char* tmp = fgets(linebuf, LINE_BUF_LEN, file);
            if (!tmp) {
                JS_ReportError(cx, "failed to read %s fully", script->filename());
                ok = false;
                goto bail;
            }
        }

        bupline = 0;
        while (pc < end) {
            line2 = PCToLineNumber(script, pc);

            if (line2 < line1) {
                if (bupline != line2) {
                    bupline = line2;
                    Sprint(&sprinter, "%s %3u: BACKUP\n", sep, line2);
                }
            } else {
                if (bupline && line1 == line2)
                    Sprint(&sprinter, "%s %3u: RESTORE\n", sep, line2);
                bupline = 0;
                while (line1 < line2) {
                    if (!fgets(linebuf, LINE_BUF_LEN, file)) {
                        JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr,
                                             JSSMSG_UNEXPECTED_EOF,
                                             script->filename());
                        ok = false;
                        goto bail;
                    }
                    line1++;
                    Sprint(&sprinter, "%s %3u: %s", sep, line1, linebuf);
                }
            }

            len = Disassemble1(cx, script, pc, script->pcToOffset(pc), true, &sprinter);
            if (!len) {
                ok = false;
                goto bail;
            }
            pc += len;
        }

        fprintf(stdout, "%s\n", sprinter.string());

      bail:
        fclose(file);
    }
    args.rval().setUndefined();
    return ok;
#undef LINE_BUF_LEN
}

#endif /* DEBUG */

static bool
Intern(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    JSString* str = JS::ToString(cx, args.get(0));
    if (!str)
        return false;

    AutoStableStringChars strChars(cx);
    if (!strChars.initTwoByte(cx, str))
        return false;

    mozilla::Range<const char16_t> chars = strChars.twoByteRange();

    if (!JS_AtomizeAndPinUCStringN(cx, chars.start().get(), chars.length()))
        return false;

    args.rval().setUndefined();
    return true;
}

static bool
Clone(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    RootedObject parent(cx);
    RootedObject funobj(cx);

    if (!args.length()) {
        JS_ReportError(cx, "Invalid arguments to clone");
        return false;
    }

    {
        Maybe<JSAutoCompartment> ac;
        RootedObject obj(cx, args[0].isPrimitive() ? nullptr : &args[0].toObject());

        if (obj && obj->is<CrossCompartmentWrapperObject>()) {
            obj = UncheckedUnwrap(obj);
            ac.emplace(cx, obj);
            args[0].setObject(*obj);
        }
        if (obj && obj->is<JSFunction>()) {
            funobj = obj;
        } else {
            JSFunction* fun = JS_ValueToFunction(cx, args[0]);
            if (!fun)
                return false;
            funobj = JS_GetFunctionObject(fun);
        }
    }

    if (args.length() > 1) {
        if (!JS_ValueToObject(cx, args[1], &parent))
            return false;
    } else {
        parent = js::GetGlobalForObjectCrossCompartment(&args.callee());
    }

    // Should it worry us that we might be getting with wrappers
    // around with wrappers here?
    JS::AutoObjectVector scopeChain(cx);
    if (!parent->is<GlobalObject>() && !scopeChain.append(parent))
        return false;
    JSObject* clone = JS::CloneFunctionObject(cx, funobj, scopeChain);
    if (!clone)
        return false;
    args.rval().setObject(*clone);
    return true;
}

static bool
GetSLX(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    RootedScript script(cx);

    script = ValueToScript(cx, args.get(0));
    if (!script)
        return false;
    args.rval().setInt32(GetScriptLineExtent(script));
    return true;
}

static bool
ThrowError(JSContext* cx, unsigned argc, Value* vp)
{
    JS_ReportError(cx, "This is an error");
    return false;
}

#define LAZY_STANDARD_CLASSES

/* A class for easily testing the inner/outer object callbacks. */
typedef struct ComplexObject {
    bool isInner;
    bool frozen;
    JSObject* inner;
    JSObject* outer;
} ComplexObject;

static bool
sandbox_enumerate(JSContext* cx, HandleObject obj)
{
    RootedValue v(cx);

    if (!JS_GetProperty(cx, obj, "lazy", &v))
        return false;

    if (!ToBoolean(v))
        return true;

    return JS_EnumerateStandardClasses(cx, obj);
}

static bool
sandbox_resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp)
{
    RootedValue v(cx);
    if (!JS_GetProperty(cx, obj, "lazy", &v))
        return false;

    if (ToBoolean(v))
        return JS_ResolveStandardClass(cx, obj, id, resolvedp);
    return true;
}

static const JSClass sandbox_class = {
    "sandbox",
    JSCLASS_GLOBAL_FLAGS,
    nullptr, nullptr, nullptr, nullptr,
    sandbox_enumerate, sandbox_resolve,
    nullptr, nullptr,
    nullptr, nullptr, nullptr,
    JS_GlobalObjectTraceHook
};

static JSObject*
NewSandbox(JSContext* cx, bool lazy)
{
    RootedObject obj(cx, JS_NewGlobalObject(cx, &sandbox_class, nullptr,
                                            JS::DontFireOnNewGlobalHook));
    if (!obj)
        return nullptr;

    {
        JSAutoCompartment ac(cx, obj);
        if (!lazy && !JS_InitStandardClasses(cx, obj))
            return nullptr;

        RootedValue value(cx, BooleanValue(lazy));
        if (!JS_SetProperty(cx, obj, "lazy", value))
            return nullptr;
    }

    JS_FireOnNewGlobalObject(cx, obj);

    if (!cx->compartment()->wrap(cx, &obj))
        return nullptr;
    return obj;
}

static bool
EvalInContext(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    if (!args.requireAtLeast(cx, "evalcx", 1))
        return false;

    RootedString str(cx, ToString(cx, args[0]));
    if (!str)
        return false;

    RootedObject sobj(cx);
    if (args.hasDefined(1)) {
        sobj = ToObject(cx, args[1]);
        if (!sobj)
            return false;
    }

    AutoStableStringChars strChars(cx);
    if (!strChars.initTwoByte(cx, str))
        return false;

    mozilla::Range<const char16_t> chars = strChars.twoByteRange();
    size_t srclen = chars.length();
    const char16_t* src = chars.start().get();

    bool lazy = false;
    if (srclen == 4) {
        if (src[0] == 'l' && src[1] == 'a' && src[2] == 'z' && src[3] == 'y') {
            lazy = true;
            srclen = 0;
        }
    }

    if (!sobj) {
        sobj = NewSandbox(cx, lazy);
        if (!sobj)
            return false;
    }

    if (srclen == 0) {
        args.rval().setObject(*sobj);
        return true;
    }

    JS::AutoFilename filename;
    unsigned lineno;

    DescribeScriptedCaller(cx, &filename, &lineno);
    {
        Maybe<JSAutoCompartment> ac;
        unsigned flags;
        JSObject* unwrapped = UncheckedUnwrap(sobj, true, &flags);
        if (flags & Wrapper::CROSS_COMPARTMENT) {
            sobj = unwrapped;
            ac.emplace(cx, sobj);
        }

        sobj = ToWindowIfWindowProxy(sobj);

        if (!(sobj->getClass()->flags & JSCLASS_IS_GLOBAL)) {
            JS_ReportError(cx, "Invalid scope argument to evalcx");
            return false;
        }
        JS::CompileOptions opts(cx);
        opts.setFileAndLine(filename.get(), lineno);
        if (!JS::Evaluate(cx, opts, src, srclen, args.rval())) {
            return false;
        }
    }

    if (!cx->compartment()->wrap(cx, args.rval()))
        return false;

    return true;
}

struct WorkerInput
{
    JSRuntime* runtime;
    char16_t* chars;
    size_t length;

    WorkerInput(JSRuntime* runtime, char16_t* chars, size_t length)
      : runtime(runtime), chars(chars), length(length)
    {}

    ~WorkerInput() {
        js_free(chars);
    }
};

static void SetWorkerRuntimeOptions(JSRuntime* rt);

static void
WorkerMain(void* arg)
{
    WorkerInput* input = (WorkerInput*) arg;

    JSRuntime* rt = JS_NewRuntime(8L * 1024L * 1024L, 2L * 1024L * 1024L, input->runtime);
    if (!rt) {
        js_delete(input);
        return;
    }

    mozilla::UniquePtr<ShellRuntime> sr = MakeUnique<ShellRuntime>();
    if (!sr) {
        JS_DestroyRuntime(rt);
        js_delete(input);
        return;
    }

    sr->isWorker = true;
    JS_SetRuntimePrivate(rt, sr.get());
    JS_SetErrorReporter(rt, my_ErrorReporter);
    SetWorkerRuntimeOptions(rt);

    if (!InitWatchdog(rt)) {
        JS_DestroyRuntime(rt);
        js_delete(input);
        return;
    }

    JSContext* cx = NewContext(rt);
    if (!cx) {
        JS_DestroyRuntime(rt);
        js_delete(input);
        return;
    }

    JS::SetLargeAllocationFailureCallback(rt, my_LargeAllocFailCallback, (void*)cx);

    do {
        JSAutoRequest ar(cx);

        JS::CompartmentOptions compartmentOptions;
        compartmentOptions.setVersion(JSVERSION_DEFAULT);
        RootedObject global(cx, NewGlobalObject(cx, compartmentOptions, nullptr));
        if (!global)
            break;

        JSAutoCompartment ac(cx, global);

        JS::CompileOptions options(cx);
        options.setFileAndLine("<string>", 1)
               .setIsRunOnce(true);

        RootedScript script(cx);
        if (!JS::Compile(cx, options, input->chars, input->length, &script))
            break;
        RootedValue result(cx);
        JS_ExecuteScript(cx, script, &result);
    } while (0);

    JS::SetLargeAllocationFailureCallback(rt, nullptr, nullptr);

    DestroyContext(cx, false);
    JS_DestroyRuntime(rt);

    js_delete(input);
}

Vector<PRThread*, 0, SystemAllocPolicy> workerThreads;

static bool
EvalInWorker(JSContext* cx, unsigned argc, Value* vp)
{
    if (!CanUseExtraThreads()) {
        JS_ReportError(cx, "Can't create worker threads with --no-threads");
        return false;
    }

    CallArgs args = CallArgsFromVp(argc, vp);
    if (!args.get(0).isString()) {
        JS_ReportError(cx, "Invalid arguments to evalInWorker");
        return false;
    }

    if (!args[0].toString()->ensureLinear(cx))
        return false;

    JSLinearString* str = &args[0].toString()->asLinear();

    char16_t* chars = (char16_t*) js_malloc(str->length() * sizeof(char16_t));
    if (!chars)
        return false;
    CopyChars(chars, *str);

    WorkerInput* input = js_new<WorkerInput>(cx->runtime(), chars, str->length());
    if (!input)
        return false;

    PRThread* thread = PR_CreateThread(PR_USER_THREAD, WorkerMain, input,
                                       PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD,
                                       gMaxStackSize + 128 * 1024);
    if (!thread || !workerThreads.append(thread))
        return false;

    return true;
}

static bool
ShapeOf(JSContext* cx, unsigned argc, JS::Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    if (!args.get(0).isObject()) {
        JS_ReportError(cx, "shapeOf: object expected");
        return false;
    }
    JSObject* obj = &args[0].toObject();
    args.rval().set(JS_NumberValue(double(uintptr_t(obj->maybeShape()) >> 3)));
    return true;
}

/*
 * Check that t1 comes strictly before t2. The function correctly deals with
 * wrap-around between t2 and t1 assuming that t2 and t1 stays within INT32_MAX
 * from each other. We use MAX_TIMEOUT_INTERVAL to enforce this restriction.
 */
static bool
IsBefore(int64_t t1, int64_t t2)
{
    return int32_t(t1 - t2) < 0;
}

static bool
Sleep_fn(JSContext* cx, unsigned argc, Value* vp)
{
    ShellRuntime* sr = GetShellRuntime(cx);
    CallArgs args = CallArgsFromVp(argc, vp);
    int64_t t_ticks;

    if (args.length() == 0) {
        t_ticks = 0;
    } else {
        double t_secs;

        if (!ToNumber(cx, args[0], &t_secs))
            return false;

        /* NB: The next condition also filter out NaNs. */
        if (!(t_secs <= MAX_TIMEOUT_INTERVAL)) {
            JS_ReportError(cx, "Excessive sleep interval");
            return false;
        }
        t_ticks = (t_secs <= 0.0)
                  ? 0
                  : int64_t(PRMJ_USEC_PER_SEC * t_secs);
    }
    PR_Lock(sr->watchdogLock);
    int64_t to_wakeup = PRMJ_Now() + t_ticks;
    for (;;) {
        PR_WaitCondVar(sr->sleepWakeup, PR_MillisecondsToInterval(t_ticks / 1000));
        if (sr->serviceInterrupt)
            break;
        int64_t now = PRMJ_Now();
        if (!IsBefore(now, to_wakeup))
            break;
        t_ticks = to_wakeup - now;
    }
    PR_Unlock(sr->watchdogLock);
    args.rval().setUndefined();
    return !sr->serviceInterrupt;
}

static bool
InitWatchdog(JSRuntime* rt)
{
    ShellRuntime* sr = GetShellRuntime(rt);
    MOZ_ASSERT(!sr->watchdogThread);
    sr->watchdogLock = PR_NewLock();
    if (sr->watchdogLock) {
        sr->watchdogWakeup = PR_NewCondVar(sr->watchdogLock);
        if (sr->watchdogWakeup) {
            sr->sleepWakeup = PR_NewCondVar(sr->watchdogLock);
            if (sr->sleepWakeup)
                return true;
            PR_DestroyCondVar(sr->watchdogWakeup);
        }
        PR_DestroyLock(sr->watchdogLock);
    }
    return false;
}

static void
KillWatchdog(JSRuntime* rt)
{
    ShellRuntime* sr = GetShellRuntime(rt);
    PRThread* thread;

    PR_Lock(sr->watchdogLock);
    thread = sr->watchdogThread;
    if (thread) {
        /*
         * The watchdog thread is running, tell it to terminate waking it up
         * if necessary.
         */
        sr->watchdogThread = nullptr;
        PR_NotifyCondVar(sr->watchdogWakeup);
    }
    PR_Unlock(sr->watchdogLock);
    if (thread)
        PR_JoinThread(thread);
    PR_DestroyCondVar(sr->sleepWakeup);
    PR_DestroyCondVar(sr->watchdogWakeup);
    PR_DestroyLock(sr->watchdogLock);
}

static void
WatchdogMain(void* arg)
{
    PR_SetCurrentThreadName("JS Watchdog");

    JSRuntime* rt = (JSRuntime*) arg;
    ShellRuntime* sr = GetShellRuntime(rt);

    PR_Lock(sr->watchdogLock);
    while (sr->watchdogThread) {
        int64_t now = PRMJ_Now();
        if (sr->watchdogHasTimeout && !IsBefore(now, sr->watchdogTimeout)) {
            /*
             * The timeout has just expired. Request an interrupt callback
             * outside the lock.
             */
            sr->watchdogHasTimeout = false;
            PR_Unlock(sr->watchdogLock);
            CancelExecution(rt);
            PR_Lock(sr->watchdogLock);

            /* Wake up any threads doing sleep. */
            PR_NotifyAllCondVar(sr->sleepWakeup);
        } else {
            if (sr->watchdogHasTimeout) {
                /*
                 * Time hasn't expired yet. Simulate an interrupt callback
                 * which doesn't abort execution.
                 */
                JS_RequestInterruptCallback(rt);
            }

            uint64_t sleepDuration = PR_INTERVAL_NO_TIMEOUT;
            if (sr->watchdogHasTimeout)
                sleepDuration = PR_TicksPerSecond() / 10;
            mozilla::DebugOnly<PRStatus> status =
              PR_WaitCondVar(sr->watchdogWakeup, sleepDuration);
            MOZ_ASSERT(status == PR_SUCCESS);
        }
    }
    PR_Unlock(sr->watchdogLock);
}

static bool
ScheduleWatchdog(JSRuntime* rt, double t)
{
    ShellRuntime* sr = GetShellRuntime(rt);

    if (t <= 0) {
        PR_Lock(sr->watchdogLock);
        sr->watchdogHasTimeout = false;
        PR_Unlock(sr->watchdogLock);
        return true;
    }

    int64_t interval = int64_t(ceil(t * PRMJ_USEC_PER_SEC));
    int64_t timeout = PRMJ_Now() + interval;
    PR_Lock(sr->watchdogLock);
    if (!sr->watchdogThread) {
        MOZ_ASSERT(!sr->watchdogHasTimeout);
        sr->watchdogThread = PR_CreateThread(PR_USER_THREAD,
                                          WatchdogMain,
                                          rt,
                                          PR_PRIORITY_NORMAL,
                                          PR_GLOBAL_THREAD,
                                          PR_JOINABLE_THREAD,
                                          0);
        if (!sr->watchdogThread) {
            PR_Unlock(sr->watchdogLock);
            return false;
        }
    } else if (!sr->watchdogHasTimeout || IsBefore(timeout, sr->watchdogTimeout)) {
         PR_NotifyCondVar(sr->watchdogWakeup);
    }
    sr->watchdogHasTimeout = true;
    sr->watchdogTimeout = timeout;
    PR_Unlock(sr->watchdogLock);
    return true;
}

static void
CancelExecution(JSRuntime* rt)
{
    ShellRuntime* sr = GetShellRuntime(rt);
    sr->serviceInterrupt = true;
    JS_RequestInterruptCallback(rt);

    if (!sr->interruptFunc.isNull()) {
        static const char msg[] = "Script runs for too long, terminating.\n";
        fputs(msg, stderr);
    }
}

static bool
SetTimeoutValue(JSContext* cx, double t)
{
    /* NB: The next condition also filter out NaNs. */
    if (!(t <= MAX_TIMEOUT_INTERVAL)) {
        JS_ReportError(cx, "Excessive timeout value");
        return false;
    }
    GetShellRuntime(cx)->timeoutInterval = t;
    if (!ScheduleWatchdog(cx->runtime(), t)) {
        JS_ReportError(cx, "Failed to create the watchdog");
        return false;
    }
    return true;
}

static bool
Timeout(JSContext* cx, unsigned argc, Value* vp)
{
    ShellRuntime* sr = GetShellRuntime(cx);
    CallArgs args = CallArgsFromVp(argc, vp);

    if (args.length() == 0) {
        args.rval().setNumber(sr->timeoutInterval);
        return true;
    }

    if (args.length() > 2) {
        JS_ReportError(cx, "Wrong number of arguments");
        return false;
    }

    double t;
    if (!ToNumber(cx, args[0], &t))
        return false;

    if (args.length() > 1) {
        RootedValue value(cx, args[1]);
        if (!value.isObject() || !value.toObject().is<JSFunction>()) {
            JS_ReportError(cx, "Second argument must be a timeout function");
            return false;
        }
        sr->interruptFunc = value;
    }

    args.rval().setUndefined();
    return SetTimeoutValue(cx, t);
}

static bool
InterruptIf(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    if (args.length() != 1) {
        JS_ReportError(cx, "Wrong number of arguments");
        return false;
    }

    if (ToBoolean(args[0])) {
        GetShellRuntime(cx)->serviceInterrupt = true;
        JS_RequestInterruptCallback(cx->runtime());
    }

    args.rval().setUndefined();
    return true;
}

static bool
InvokeInterruptCallbackWrapper(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    if (args.length() != 1) {
        JS_ReportError(cx, "Wrong number of arguments");
        return false;
    }

    GetShellRuntime(cx)->serviceInterrupt = true;
    JS_RequestInterruptCallback(cx->runtime());
    bool interruptRv = CheckForInterrupt(cx);

    // The interrupt handler could have set a pending exception. Since we call
    // back into JS, don't have it see the pending exception. If we have an
    // uncatchable exception that's not propagating a debug mode forced
    // return, return.
    if (!interruptRv && !cx->isExceptionPending() && !cx->isPropagatingForcedReturn())
        return false;

    JS::AutoSaveExceptionState savedExc(cx);
    Value argv[1] = { BooleanValue(interruptRv) };
    RootedValue rv(cx);
    if (!Invoke(cx, UndefinedValue(), args[0], 1, argv, &rv))
        return false;

    args.rval().setUndefined();
    return interruptRv;
}

static bool
SetInterruptCallback(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    if (args.length() != 1) {
        JS_ReportError(cx, "Wrong number of arguments");
        return false;
    }

    RootedValue value(cx, args[0]);
    if (!value.isObject() || !value.toObject().is<JSFunction>()) {
        JS_ReportError(cx, "Argument must be a function");
        return false;
    }
    GetShellRuntime(cx)->interruptFunc = value;

    args.rval().setUndefined();
    return true;
}

static bool
EnableLastWarning(JSContext* cx, unsigned argc, Value* vp)
{
    ShellRuntime* sr = GetShellRuntime(cx);
    CallArgs args = CallArgsFromVp(argc, vp);

    sr->lastWarningEnabled = true;
    sr->lastWarning.setNull();

    args.rval().setUndefined();
    return true;
}

static bool
DisableLastWarning(JSContext* cx, unsigned argc, Value* vp)
{
    ShellRuntime* sr = GetShellRuntime(cx);
    CallArgs args = CallArgsFromVp(argc, vp);

    sr->lastWarningEnabled = false;
    sr->lastWarning.setNull();

    args.rval().setUndefined();
    return true;
}

static bool
GetLastWarning(JSContext* cx, unsigned argc, Value* vp)
{
    ShellRuntime* sr = GetShellRuntime(cx);
    CallArgs args = CallArgsFromVp(argc, vp);

    if (!sr->lastWarningEnabled) {
        JS_ReportError(cx, "Call enableLastWarning first.");
        return false;
    }

    if (!JS_WrapValue(cx, &sr->lastWarning))
        return false;

    args.rval().set(sr->lastWarning);
    return true;
}

static bool
ClearLastWarning(JSContext* cx, unsigned argc, Value* vp)
{
    ShellRuntime* sr = GetShellRuntime(cx);
    CallArgs args = CallArgsFromVp(argc, vp);

    if (!sr->lastWarningEnabled) {
        JS_ReportError(cx, "Call enableLastWarning first.");
        return false;
    }

    sr->lastWarning.setNull();

    args.rval().setUndefined();
    return true;
}

#ifdef DEBUG
static bool
StackDump(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    bool showArgs = ToBoolean(args.get(0));
    bool showLocals = ToBoolean(args.get(1));
    bool showThisProps = ToBoolean(args.get(2));

    char* buf = JS::FormatStackDump(cx, nullptr, showArgs, showLocals, showThisProps);
    if (!buf) {
        fputs("Failed to format JavaScript stack for dump\n", gOutFile);
    } else {
        fputs(buf, gOutFile);
        JS_smprintf_free(buf);
    }

    args.rval().setUndefined();
    return true;
}
#endif

static bool
StackPointerInfo(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    // Copy the truncated stack pointer to the result.  This value is not used
    // as a pointer but as a way to measure frame-size from JS.
    args.rval().setInt32(int32_t(reinterpret_cast<size_t>(&args) & 0xfffffff));
    return true;
}


static bool
Elapsed(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    if (args.length() == 0) {
        double d = 0.0;
        JSShellContextData* data = GetContextData(cx);
        if (data)
            d = PRMJ_Now() - data->startTime;
        args.rval().setDouble(d);
        return true;
    }
    JS_ReportError(cx, "Wrong number of arguments");
    return false;
}

static bool
Compile(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    if (args.length() < 1) {
        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
                             "compile", "0", "s");
        return false;
    }
    if (!args[0].isString()) {
        const char* typeName = InformalValueTypeName(args[0]);
        JS_ReportError(cx, "expected string to compile, got %s", typeName);
        return false;
    }

    RootedObject global(cx, JS::CurrentGlobalOrNull(cx));
    JSFlatString* scriptContents = args[0].toString()->ensureFlat(cx);
    if (!scriptContents)
        return false;

    AutoStableStringChars stableChars(cx);
    if (!stableChars.initTwoByte(cx, scriptContents))
        return false;

    JS::CompileOptions options(cx);
    options.setIntroductionType("js shell compile")
           .setFileAndLine("<string>", 1)
           .setIsRunOnce(true)
           .setNoScriptRval(true);
    RootedScript script(cx);
    const char16_t* chars = stableChars.twoByteRange().start().get();
    bool ok = JS_CompileUCScript(cx, chars, scriptContents->length(), options, &script);
    args.rval().setUndefined();
    return ok;
}

static bool
ParseModule(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    if (args.length() == 0) {
        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
                             JSMSG_MORE_ARGS_NEEDED, "parseModule", "0", "s");
        return false;
    }

    if (!args[0].isString()) {
        const char* typeName = InformalValueTypeName(args[0]);
        JS_ReportError(cx, "expected string to compile, got %s", typeName);
        return false;
    }

    RootedObject global(cx, JS::CurrentGlobalOrNull(cx));
    JSFlatString* scriptContents = args[0].toString()->ensureFlat(cx);
    if (!scriptContents)
        return false;

    mozilla::UniquePtr<char, JS::FreePolicy> filename;
    CompileOptions options(cx);
    if (args.length() > 1) {
        if (!args[1].isString()) {
            const char* typeName = InformalValueTypeName(args[1]);
            JS_ReportError(cx, "expected filename string, got %s", typeName);
            return false;
        }

        RootedString str(cx, args[1].toString());
        filename.reset(JS_EncodeString(cx, str));
        if (!filename)
            return false;

        options.setFileAndLine(filename.get(), 1);
    } else {
        options.setFileAndLine("<string>", 1);
    }

    AutoStableStringChars stableChars(cx);
    if (!stableChars.initTwoByte(cx, scriptContents))
        return false;

    const char16_t* chars = stableChars.twoByteRange().start().get();
    SourceBufferHolder srcBuf(chars, scriptContents->length(),
                              SourceBufferHolder::NoOwnership);

    RootedObject module(cx, frontend::CompileModule(cx, global, options, srcBuf));
    if (!module)
        return false;

    args.rval().setObject(*module);
    return true;
}

static bool
SetModuleResolveHook(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    if (args.length() != 1) {
        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
                             JSMSG_MORE_ARGS_NEEDED, "setModuleResolveHook", "0", "s");
        return false;
    }

    if (!args[0].isObject() || !args[0].toObject().is<JSFunction>()) {
        const char* typeName = InformalValueTypeName(args[0]);
        JS_ReportError(cx, "expected hook function, got %s", typeName);
        return false;
    }

    RootedFunction hook(cx, &args[0].toObject().as<JSFunction>());
    Rooted<GlobalObject*> global(cx, cx->global());
    global->setModuleResolveHook(hook);
    args.rval().setUndefined();
    return true;
}

static bool
GetModuleLoadPath(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    args.rval().setString(JS_NewStringCopyZ(cx, moduleLoadPath));
    return true;
}

static bool
Parse(JSContext* cx, unsigned argc, Value* vp)
{
    using namespace js::frontend;

    CallArgs args = CallArgsFromVp(argc, vp);

    if (args.length() < 1) {
        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
                             "parse", "0", "s");
        return false;
    }
    if (!args[0].isString()) {
        const char* typeName = InformalValueTypeName(args[0]);
        JS_ReportError(cx, "expected string to parse, got %s", typeName);
        return false;
    }

    JSFlatString* scriptContents = args[0].toString()->ensureFlat(cx);
    if (!scriptContents)
        return false;

    AutoStableStringChars stableChars(cx);
    if (!stableChars.initTwoByte(cx, scriptContents))
        return false;

    size_t length = scriptContents->length();
    const char16_t* chars = stableChars.twoByteRange().start().get();

    CompileOptions options(cx);
    options.setIntroductionType("js shell parse")
           .setFileAndLine("<string>", 1);
    Parser<FullParseHandler> parser(cx, &cx->tempLifoAlloc(), options, chars, length,
                                    /* foldConstants = */ true, nullptr, nullptr);
    if (!parser.checkOptions())
        return false;

    ParseNode* pn = parser.parse();
    if (!pn)
        return false;
#ifdef DEBUG
    DumpParseTree(pn);
    fputc('\n', stderr);
#endif
    args.rval().setUndefined();
    return true;
}

static bool
SyntaxParse(JSContext* cx, unsigned argc, Value* vp)
{
    using namespace js::frontend;

    CallArgs args = CallArgsFromVp(argc, vp);

    if (args.length() < 1) {
        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
                             "parse", "0", "s");
        return false;
    }
    if (!args[0].isString()) {
        const char* typeName = InformalValueTypeName(args[0]);
        JS_ReportError(cx, "expected string to parse, got %s", typeName);
        return false;
    }

    JSFlatString* scriptContents = args[0].toString()->ensureFlat(cx);
    if (!scriptContents)
        return false;
    CompileOptions options(cx);
    options.setIntroductionType("js shell syntaxParse")
           .setFileAndLine("<string>", 1);

    AutoStableStringChars stableChars(cx);
    if (!stableChars.initTwoByte(cx, scriptContents))
        return false;

    const char16_t* chars = stableChars.twoByteRange().start().get();
    size_t length = scriptContents->length();
    Parser<frontend::SyntaxParseHandler> parser(cx, &cx->tempLifoAlloc(),
                                                options, chars, length, false, nullptr, nullptr);
    if (!parser.checkOptions())
        return false;

    bool succeeded = parser.parse();
    if (cx->isExceptionPending())
        return false;

    if (!succeeded && !parser.hadAbortedSyntaxParse()) {
        // If no exception is posted, either there was an OOM or a language
        // feature unhandled by the syntax parser was encountered.
        MOZ_ASSERT(cx->runtime()->hadOutOfMemory);
        return false;
    }

    args.rval().setBoolean(succeeded);
    return true;
}

class OffThreadState {
  public:
    enum State {
        IDLE,           /* ready to work; no token, no source */
        COMPILING,      /* working; no token, have source */
        DONE            /* compilation done: have token and source */
    };

    OffThreadState() : monitor(), state(IDLE), token(), source(nullptr) { }
    bool init() { return monitor.init(); }

    bool startIfIdle(JSContext* cx, ScopedJSFreePtr<char16_t>& newSource) {
        AutoLockMonitor alm(monitor);
        if (state != IDLE)
            return false;

        MOZ_ASSERT(!token);

        source = newSource.forget();

        state = COMPILING;
        return true;
    }

    void abandon(JSContext* cx) {
        AutoLockMonitor alm(monitor);
        MOZ_ASSERT(state == COMPILING);
        MOZ_ASSERT(!token);
        MOZ_ASSERT(source);

        js_free(source);
        source = nullptr;

        state = IDLE;
    }

    void markDone(void* newToken) {
        AutoLockMonitor alm(monitor);
        MOZ_ASSERT(state == COMPILING);
        MOZ_ASSERT(!token);
        MOZ_ASSERT(source);
        MOZ_ASSERT(newToken);

        token = newToken;
        state = DONE;
        alm.notify();
    }

    void* waitUntilDone(JSContext* cx) {
        AutoLockMonitor alm(monitor);
        if (state == IDLE)
            return nullptr;

        if (state == COMPILING) {
            while (state != DONE)
                alm.wait();
        }

        MOZ_ASSERT(source);
        js_free(source);
        source = nullptr;

        MOZ_ASSERT(token);
        void* holdToken = token;
        token = nullptr;
        state = IDLE;
        return holdToken;
    }

  private:
    Monitor monitor;
    State state;
    void* token;
    char16_t* source;
};

static OffThreadState offThreadState;

static void
OffThreadCompileScriptCallback(void* token, void* callbackData)
{
    offThreadState.markDone(token);
}

static bool
OffThreadCompileScript(JSContext* cx, unsigned argc, Value* vp)
{
    if (!CanUseExtraThreads()) {
        JS_ReportError(cx, "Can't use offThreadCompileScript with --no-threads");
        return false;
    }

    CallArgs args = CallArgsFromVp(argc, vp);

    if (args.length() < 1) {
        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
                             "offThreadCompileScript", "0", "s");
        return false;
    }
    if (!args[0].isString()) {
        const char* typeName = InformalValueTypeName(args[0]);
        JS_ReportError(cx, "expected string to parse, got %s", typeName);
        return false;
    }

    JSAutoByteString fileNameBytes;
    CompileOptions options(cx);
    options.setIntroductionType("js shell offThreadCompileScript")
           .setFileAndLine("<string>", 1);

    if (args.length() >= 2) {
        if (args[1].isPrimitive()) {
            JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_INVALID_ARGS, "evaluate");
            return false;
        }

        RootedObject opts(cx, &args[1].toObject());
        if (!ParseCompileOptions(cx, options, opts, fileNameBytes))
            return false;
    }

    // These option settings must override whatever the caller requested.
    options.setIsRunOnce(true)
           .setSourceIsLazy(false);

    // We assume the caller wants caching if at all possible, ignoring
    // heuristics that make sense for a real browser.
    options.forceAsync = true;

    JSString* scriptContents = args[0].toString();
    AutoStableStringChars stableChars(cx);
    if (!stableChars.initTwoByte(cx, scriptContents))
        return false;

    size_t length = scriptContents->length();
    const char16_t* chars = stableChars.twoByteRange().start().get();

    // Make sure we own the string's chars, so that they are not freed before
    // the compilation is finished.
    ScopedJSFreePtr<char16_t> ownedChars;
    if (stableChars.maybeGiveOwnershipToCaller()) {
        ownedChars = const_cast<char16_t*>(chars);
    } else {
        char16_t* copy = cx->pod_malloc<char16_t>(length);
        if (!copy)
            return false;

        mozilla::PodCopy(copy, chars, length);
        ownedChars = copy;
        chars = copy;
    }

    if (!JS::CanCompileOffThread(cx, options, length)) {
        JS_ReportError(cx, "cannot compile code on worker thread");
        return false;
    }

    if (!offThreadState.startIfIdle(cx, ownedChars)) {
        JS_ReportError(cx, "called offThreadCompileScript without calling runOffThreadScript"
                       " to receive prior off-thread compilation");
        return false;
    }

    if (!JS::CompileOffThread(cx, options, chars, length,
                              OffThreadCompileScriptCallback, nullptr))
    {
        offThreadState.abandon(cx);
        return false;
    }

    args.rval().setUndefined();
    return true;
}

static bool
runOffThreadScript(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    JSRuntime* rt = cx->runtime();
    if (OffThreadParsingMustWaitForGC(rt))
        gc::AutoFinishGC finishgc(rt);

    void* token = offThreadState.waitUntilDone(cx);
    if (!token) {
        JS_ReportError(cx, "called runOffThreadScript when no compilation is pending");
        return false;
    }

    RootedScript script(cx, JS::FinishOffThreadScript(cx, rt, token));
    if (!script)
        return false;

    return JS_ExecuteScript(cx, script, args.rval());
}

struct MOZ_RAII FreeOnReturn
{
    JSContext* cx;
    const char* ptr;
    MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER

    explicit FreeOnReturn(JSContext* cx, const char* ptr = nullptr
                 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
      : cx(cx), ptr(ptr)
    {
        MOZ_GUARD_OBJECT_NOTIFIER_INIT;
    }

    void init(const char* ptr) {
        MOZ_ASSERT(!this->ptr);
        this->ptr = ptr;
    }

    ~FreeOnReturn() {
        JS_free(cx, (void*)ptr);
    }
};

static int sArgc;
static char** sArgv;

class AutoCStringVector
{
    Vector<char*> argv_;
  public:
    explicit AutoCStringVector(JSContext* cx) : argv_(cx) {}
    ~AutoCStringVector() {
        for (size_t i = 0; i < argv_.length(); i++)
            js_free(argv_[i]);
    }
    bool append(char* arg) {
        if (!argv_.append(arg)) {
            js_free(arg);
            return false;
        }
        return true;
    }
    char* const* get() const {
        return argv_.begin();
    }
    size_t length() const {
        return argv_.length();
    }
    char* operator[](size_t i) const {
        return argv_[i];
    }
    void replace(size_t i, char* arg) {
        js_free(argv_[i]);
        argv_[i] = arg;
    }
    char* back() const {
        return argv_.back();
    }
    void replaceBack(char* arg) {
        js_free(argv_.back());
        argv_.back() = arg;
    }
};

#if defined(XP_WIN)
static bool
EscapeForShell(AutoCStringVector& argv)
{
    // Windows will break arguments in argv by various spaces, so we wrap each
    // argument in quotes and escape quotes within. Even with quotes, \ will be
    // treated like an escape character, so inflate each \ to \\.

    for (size_t i = 0; i < argv.length(); i++) {
        if (!argv[i])
            continue;

        size_t newLen = 3;  // quotes before and after and null-terminator
        for (char* p = argv[i]; *p; p++) {
            newLen++;
            if (*p == '\"' || *p == '\\')
                newLen++;
        }

        char* escaped = (char*)js_malloc(newLen);
        if (!escaped)
            return false;

        char* src = argv[i];
        char* dst = escaped;
        *dst++ = '\"';
        while (*src) {
            if (*src == '\"' || *src == '\\')
                *dst++ = '\\';
            *dst++ = *src++;
        }
        *dst++ = '\"';
        *dst++ = '\0';
        MOZ_ASSERT(escaped + newLen == dst);

        argv.replace(i, escaped);
    }
    return true;
}
#endif

static Vector<const char*, 4, js::SystemAllocPolicy> sPropagatedFlags;

static bool
PropagateFlagToNestedShells(const char* flag)
{
    return sPropagatedFlags.append(flag);
}

static bool
NestedShell(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    AutoCStringVector argv(cx);

    // The first argument to the shell is its path, which we assume is our own
    // argv[0].
    if (sArgc < 1) {
        JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_NESTED_FAIL);
        return false;
    }
    if (!argv.append(strdup(sArgv[0])))
        return false;

    // Propagate selected flags from the current shell
    for (unsigned i = 0; i < sPropagatedFlags.length(); i++) {
        char* cstr = strdup(sPropagatedFlags[i]);
        if (!cstr || !argv.append(cstr))
            return false;
    }

    // The arguments to nestedShell are stringified and append to argv.
    RootedString str(cx);
    for (unsigned i = 0; i < args.length(); i++) {
        str = ToString(cx, args[i]);
        if (!str || !argv.append(JS_EncodeString(cx, str)))
            return false;

        // As a special case, if the caller passes "--js-cache", replace that
        // with "--js-cache=$(jsCacheDir)"
        if (!strcmp(argv.back(), "--js-cache") && jsCacheDir) {
            char* newArg = JS_smprintf("--js-cache=%s", jsCacheDir);
            if (!newArg)
                return false;
            argv.replaceBack(newArg);
        }
    }

    // execv assumes argv is null-terminated
    if (!argv.append(nullptr))
        return false;

    int status = 0;
#if defined(STARBOARD)
    return false;
#elif defined(XP_WIN)
    if (!EscapeForShell(argv))
        return false;
    status = _spawnv(_P_WAIT, sArgv[0], argv.get());
#else
    pid_t pid = fork();
    switch (pid) {
      case -1:
        JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_NESTED_FAIL);
        return false;
      case 0:
        (void)execv(sArgv[0], argv.get());
        exit(-1);
      default: {
        while (waitpid(pid, &status, 0) < 0 && errno == EINTR)
            continue;
        break;
      }
    }
#endif

    if (status != 0) {
        JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_NESTED_FAIL);
        return false;
    }

    args.rval().setUndefined();
    return true;
}

static bool
DecompileFunction(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    if (args.length() < 1 || !args[0].isObject() || !args[0].toObject().is<JSFunction>()) {
        args.rval().setUndefined();
        return true;
    }
    RootedFunction fun(cx, &args[0].toObject().as<JSFunction>());
    JSString* result = JS_DecompileFunction(cx, fun, 0);
    if (!result)
        return false;
    args.rval().setString(result);
    return true;
}

static bool
DecompileThisScript(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    NonBuiltinScriptFrameIter iter(cx);
    if (iter.done()) {
        args.rval().setString(cx->runtime()->emptyString);
        return true;
    }

    {
        JSAutoCompartment ac(cx, iter.script());

        RootedScript script(cx, iter.script());
        JSString* result = JS_DecompileScript(cx, script, "test", 0);
        if (!result)
            return false;

        args.rval().setString(result);
    }

    return JS_WrapValue(cx, args.rval());
}

static bool
ThisFilename(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    JS::AutoFilename filename;
    if (!DescribeScriptedCaller(cx, &filename) || !filename.get()) {
        args.rval().setString(cx->runtime()->emptyString);
        return true;
    }

    JSString* str = JS_NewStringCopyZ(cx, filename.get());
    if (!str)
        return false;

    args.rval().setString(str);
    return true;
}

static bool
WrapWithProto(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    Value obj = UndefinedValue(), proto = UndefinedValue();
    if (args.length() == 2) {
        obj = args[0];
        proto = args[1];
    }
    if (!obj.isObject() || !proto.isObjectOrNull()) {
        JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_INVALID_ARGS,
                             "wrapWithProto");
        return false;
    }

    WrapperOptions options(cx);
    options.setProto(proto.toObjectOrNull());
    JSObject* wrapped = Wrapper::New(cx, &obj.toObject(),
                                     &Wrapper::singletonWithPrototype, options);
    if (!wrapped)
        return false;

    args.rval().setObject(*wrapped);
    return true;
}

static bool
NewGlobal(JSContext* cx, unsigned argc, Value* vp)
{
    JSPrincipals* principals = nullptr;
    JS::CompartmentOptions options;
    options.setVersion(JSVERSION_DEFAULT);

    CallArgs args = CallArgsFromVp(argc, vp);
    if (args.length() == 1 && args[0].isObject()) {
        RootedObject opts(cx, &args[0].toObject());
        RootedValue v(cx);

        if (!JS_GetProperty(cx, opts, "sameZoneAs", &v))
            return false;
        if (v.isObject())
            options.setSameZoneAs(UncheckedUnwrap(&v.toObject()));

        if (!JS_GetProperty(cx, opts, "invisibleToDebugger", &v))
            return false;
        if (v.isBoolean())
            options.setInvisibleToDebugger(v.toBoolean());

        if (!JS_GetProperty(cx, opts, "cloneSingletons", &v))
            return false;
        if (v.isBoolean())
            options.setCloneSingletons(v.toBoolean());

        if (!JS_GetProperty(cx, opts, "disableLazyParsing", &v))
            return false;
        if (v.isBoolean())
            options.setDisableLazyParsing(v.toBoolean());

        if (!JS_GetProperty(cx, opts, "principal", &v))
            return false;
        if (!v.isUndefined()) {
            uint32_t bits;
            if (!ToUint32(cx, v, &bits))
                return false;
            principals = cx->new_<ShellPrincipals>(bits);
            if (!principals)
                return false;
            JS_HoldPrincipals(principals);
        }
    }

    RootedObject global(cx, NewGlobalObject(cx, options, principals));
    if (principals)
        JS_DropPrincipals(cx->runtime(), principals);
    if (!global)
        return false;

    if (!JS_WrapObject(cx, &global))
        return false;

    args.rval().setObject(*global);
    return true;
}

static bool
GetMaxArgs(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    args.rval().setInt32(ARGS_LENGTH_MAX);
    return true;
}

static bool
ObjectEmulatingUndefined(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    static const JSClass cls = {
        "ObjectEmulatingUndefined",
        JSCLASS_EMULATES_UNDEFINED
    };

    RootedObject obj(cx, JS_NewObject(cx, &cls));
    if (!obj)
        return false;
    args.rval().setObject(*obj);
    return true;
}

static bool
GetSelfHostedValue(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    if (args.length() != 1 || !args[0].isString()) {
        JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_INVALID_ARGS,
                             "getSelfHostedValue");
        return false;
    }
    RootedAtom srcAtom(cx, ToAtom<CanGC>(cx, args[0]));
    if (!srcAtom)
        return false;
    RootedPropertyName srcName(cx, srcAtom->asPropertyName());
    return cx->runtime()->cloneSelfHostedValue(cx, srcName, args.rval());
}

class ShellSourceHook: public SourceHook {
    // The function we should call to lazily retrieve source code.
    PersistentRootedFunction fun;

  public:
    ShellSourceHook(JSContext* cx, JSFunction& fun) : fun(cx, &fun) {}

    bool load(JSContext* cx, const char* filename, char16_t** src, size_t* length) {
        RootedString str(cx, JS_NewStringCopyZ(cx, filename));
        if (!str)
            return false;
        RootedValue filenameValue(cx, StringValue(str));

        RootedValue result(cx);
        if (!Call(cx, UndefinedHandleValue, fun, HandleValueArray(filenameValue), &result))
            return false;

        str = JS::ToString(cx, result);
        if (!str)
            return false;

        *length = JS_GetStringLength(str);
        *src = cx->pod_malloc<char16_t>(*length);
        if (!*src)
            return false;

        JSLinearString* linear = str->ensureLinear(cx);
        if (!linear)
            return false;

        CopyChars(*src, *linear);
        return true;
    }
};

static bool
WithSourceHook(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    RootedObject callee(cx, &args.callee());

    if (args.length() != 2) {
        ReportUsageError(cx, callee, "Wrong number of arguments.");
        return false;
    }

    if (!args[0].isObject() || !args[0].toObject().is<JSFunction>()
        || !args[1].isObject() || !args[1].toObject().is<JSFunction>()) {
        ReportUsageError(cx, callee, "First and second arguments must be functions.");
        return false;
    }

    UniquePtr<ShellSourceHook> hook =
        MakeUnique<ShellSourceHook>(cx, args[0].toObject().as<JSFunction>());
    if (!hook)
        return false;

    UniquePtr<SourceHook> savedHook = js::ForgetSourceHook(cx->runtime());
    js::SetSourceHook(cx->runtime(), Move(hook));

    RootedObject fun(cx, &args[1].toObject());
    bool result = Call(cx, UndefinedHandleValue, fun, JS::HandleValueArray::empty(), args.rval());
    js::SetSourceHook(cx->runtime(), Move(savedHook));
    return result;
}

static bool
IsCachingEnabled(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    args.rval().setBoolean(jsCachingEnabled && jsCacheAsmJSPath != nullptr);
    return true;
}

static bool
SetCachingEnabled(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    if (GetShellRuntime(cx)->isWorker) {
        JS_ReportError(cx, "Caching is not supported in workers");
        return false;
    }

    jsCachingEnabled = ToBoolean(args.get(0));
    args.rval().setUndefined();
    return true;
}

static void
PrintProfilerEvents_Callback(const char* msg)
{
    fprintf(stderr, "PROFILER EVENT: %s\n", msg);
}

static bool
PrintProfilerEvents(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    if (cx->runtime()->spsProfiler.enabled())
        js::RegisterRuntimeProfilingEventMarker(cx->runtime(), &PrintProfilerEvents_Callback);
    args.rval().setUndefined();
    return true;
}

#if defined(JS_SIMULATOR_ARM) || defined(JS_SIMULATOR_MIPS64)
typedef Vector<char16_t, 0, SystemAllocPolicy> StackChars;
Vector<StackChars, 0, SystemAllocPolicy> stacks;

static void
SingleStepCallback(void* arg, jit::Simulator* sim, void* pc)
{
    JSRuntime* rt = reinterpret_cast<JSRuntime*>(arg);

    // If profiling is not enabled, don't do anything.
    if (!rt->spsProfiler.enabled())
        return;

    JS::ProfilingFrameIterator::RegisterState state;
    state.pc = pc;
#if defined(JS_SIMULATOR_ARM)
    state.sp = (void*)sim->get_register(jit::Simulator::sp);
    state.lr = (void*)sim->get_register(jit::Simulator::lr);
#elif defined(JS_SIMULATOR_MIPS64)
    state.sp = (void*)sim->getRegister(jit::Simulator::sp);
    state.lr = (void*)sim->getRegister(jit::Simulator::ra);
#endif

    mozilla::DebugOnly<void*> lastStackAddress = nullptr;
    StackChars stack;
    uint32_t frameNo = 0;
    for (JS::ProfilingFrameIterator i(rt, state); !i.done(); ++i) {
        MOZ_ASSERT(i.stackAddress() != nullptr);
        MOZ_ASSERT(lastStackAddress <= i.stackAddress());
        lastStackAddress = i.stackAddress();
        JS::ProfilingFrameIterator::Frame frames[16];
        uint32_t nframes = i.extractStack(frames, 0, 16);
        for (uint32_t i = 0; i < nframes; i++) {
            if (frameNo > 0)
                stack.append(",", 1);
            stack.append(frames[i].label, strlen(frames[i].label));
            frameNo++;
        }
    }

    // Only append the stack if it differs from the last stack.
    if (stacks.empty() ||
        stacks.back().length() != stack.length() ||
        !PodEqual(stacks.back().begin(), stack.begin(), stack.length()))
    {
        stacks.append(Move(stack));
    }
}
#endif

static bool
EnableSingleStepProfiling(JSContext* cx, unsigned argc, Value* vp)
{
#if defined(JS_SIMULATOR_ARM) || defined(JS_SIMULATOR_MIPS64)
    CallArgs args = CallArgsFromVp(argc, vp);

    jit::Simulator* sim = cx->runtime()->simulator();
    sim->enable_single_stepping(SingleStepCallback, cx->runtime());

    args.rval().setUndefined();
    return true;
#else
    JS_ReportError(cx, "single-step profiling not enabled on this platform");
    return false;
#endif
}

static bool
DisableSingleStepProfiling(JSContext* cx, unsigned argc, Value* vp)
{
#if defined(JS_SIMULATOR_ARM) || defined(JS_SIMULATOR_MIPS64)
    CallArgs args = CallArgsFromVp(argc, vp);

    jit::Simulator* sim = cx->runtime()->simulator();
    sim->disable_single_stepping();

    AutoValueVector elems(cx);
    for (size_t i = 0; i < stacks.length(); i++) {
        JSString* stack = JS_NewUCStringCopyN(cx, stacks[i].begin(), stacks[i].length());
        if (!stack)
            return false;
        if (!elems.append(StringValue(stack)))
            return false;
    }

    JSObject* array = JS_NewArrayObject(cx, elems);
    if (!array)
        return false;

    stacks.clear();
    args.rval().setObject(*array);
    return true;
#else
    JS_ReportError(cx, "single-step profiling not enabled on this platform");
    return false;
#endif
}

static bool
IsLatin1(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    bool isLatin1 = args.get(0).isString() && args[0].toString()->hasLatin1Chars();
    args.rval().setBoolean(isLatin1);
    return true;
}

// Global mailbox that is used to communicate a SharedArrayBuffer
// value from one worker to another.
//
// For simplicity we store only the SharedArrayRawBuffer; retaining
// the SAB object would require per-runtime storage, and would have no
// real benefits.
//
// Invariant: when a SARB is in the mailbox its reference count is at
// least 1, accounting for the reference from the mailbox.
//
// The lock guards the mailbox variable and prevents a race where two
// workers try to set the mailbox at the same time to replace a SARB
// that is only referenced from the mailbox: the workers will both
// decrement the reference count on the old SARB, and one of those
// decrements will be on a garbage object.  We could implement this
// with atomics and a CAS loop but it's not worth the bother.

static PRLock* sharedArrayBufferMailboxLock;
static SharedArrayRawBuffer* sharedArrayBufferMailbox;

static bool
InitSharedArrayBufferMailbox()
{
    sharedArrayBufferMailboxLock = PR_NewLock();
    return sharedArrayBufferMailboxLock != nullptr;
}

static void
DestructSharedArrayBufferMailbox()
{
    // All workers need to have terminated at this point.
    if (sharedArrayBufferMailbox)
        sharedArrayBufferMailbox->dropReference();
    PR_DestroyLock(sharedArrayBufferMailboxLock);
}

static bool
GetSharedArrayBuffer(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    JSObject* newObj = nullptr;
    bool rval = true;

    PR_Lock(sharedArrayBufferMailboxLock);
    SharedArrayRawBuffer* buf = sharedArrayBufferMailbox;
    if (buf) {
        buf->addReference();
        newObj = SharedArrayBufferObject::New(cx, buf);
        if (!newObj) {
            buf->dropReference();
            rval = false;
        }
    }
    PR_Unlock(sharedArrayBufferMailboxLock);

    args.rval().setObjectOrNull(newObj);
    return rval;
}

static bool
SetSharedArrayBuffer(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    SharedArrayRawBuffer* newBuffer = nullptr;

    if (argc == 0 || args.get(0).isNullOrUndefined()) {
        // Clear out the mailbox
    }
    else if (args.get(0).isObject() && args[0].toObject().is<SharedArrayBufferObject>()) {
        newBuffer = args[0].toObject().as<SharedArrayBufferObject>().rawBufferObject();
        newBuffer->addReference();
    } else {
        JS_ReportError(cx, "Only a SharedArrayBuffer can be installed in the global mailbox");
        return false;
    }

    PR_Lock(sharedArrayBufferMailboxLock);
    SharedArrayRawBuffer* oldBuffer = sharedArrayBufferMailbox;
    if (oldBuffer)
        oldBuffer->dropReference();
    sharedArrayBufferMailbox = newBuffer;
    PR_Unlock(sharedArrayBufferMailboxLock);

    args.rval().setUndefined();
    return true;
}

class SprintOptimizationTypeInfoOp : public JS::ForEachTrackedOptimizationTypeInfoOp
{
    Sprinter* sp;
    bool startedTypes_;

  public:
    explicit SprintOptimizationTypeInfoOp(Sprinter* sp)
      : sp(sp),
        startedTypes_(false)
    { }

    void readType(const char* keyedBy, const char* name,
                  const char* location, Maybe<unsigned> lineno) override
    {
        if (!startedTypes_) {
            startedTypes_ = true;
            Sprint(sp, "{\"typeset\": [");
        }
        Sprint(sp, "{\"keyedBy\":\"%s\"", keyedBy);
        if (name)
            Sprint(sp, ",\"name\":\"%s\"", name);
        if (location) {
            char buf[512];
            PutEscapedString(buf, mozilla::ArrayLength(buf), location, strlen(location), '"');
            Sprint(sp, ",\"location\":%s", buf);
        }
        if (lineno.isSome())
            Sprint(sp, ",\"line\":%u", *lineno);
        Sprint(sp, "},");
    }

    void operator()(JS::TrackedTypeSite site, const char* mirType) override {
        if (startedTypes_) {
            // Clear trailing ,
            if ((*sp)[sp->getOffset() - 1] == ',')
                (*sp)[sp->getOffset() - 1] = ' ';
            Sprint(sp, "],");
            startedTypes_ = false;
        } else {
            Sprint(sp, "{");
        }

        Sprint(sp, "\"site\":\"%s\",\"mirType\":\"%s\"},",
               TrackedTypeSiteString(site), mirType);
    }
};

class SprintOptimizationAttemptsOp : public JS::ForEachTrackedOptimizationAttemptOp
{
    Sprinter* sp;

  public:
    explicit SprintOptimizationAttemptsOp(Sprinter* sp)
      : sp(sp)
    { }

    void operator()(JS::TrackedStrategy strategy, JS::TrackedOutcome outcome) override {
        Sprint(sp, "{\"strategy\":\"%s\",\"outcome\":\"%s\"},",
               TrackedStrategyString(strategy), TrackedOutcomeString(outcome));
    }
};

static bool
ReflectTrackedOptimizations(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    RootedObject callee(cx, &args.callee());
    JSRuntime* rt = cx->runtime();

    if (!rt->hasJitRuntime() || !rt->jitRuntime()->isOptimizationTrackingEnabled(rt)) {
        JS_ReportError(cx, "Optimization tracking is off.");
        return false;
    }

    if (args.length() != 1) {
        ReportUsageError(cx, callee, "Wrong number of arguments");
        return false;
    }

    if (!args[0].isObject() || !args[0].toObject().is<JSFunction>()) {
        ReportUsageError(cx, callee, "Argument must be a function");
        return false;
    }

    RootedFunction fun(cx, &args[0].toObject().as<JSFunction>());
    if (!fun->hasScript() || !fun->nonLazyScript()->hasIonScript()) {
        args.rval().setNull();
        return true;
    }

    // Suppress GC for the unrooted JitcodeGlobalEntry below.
    gc::AutoSuppressGC suppress(cx);

    jit::JitcodeGlobalTable* table = rt->jitRuntime()->getJitcodeGlobalTable();
    jit::JitcodeGlobalEntry entry;
    jit::IonScript* ion = fun->nonLazyScript()->ionScript();
    table->lookupInfallible(ion->method()->raw(), &entry, rt);

    if (!entry.hasTrackedOptimizations()) {
        JSObject* obj = JS_NewPlainObject(cx);
        if (!obj)
            return false;
        args.rval().setObject(*obj);
        return true;
    }

    Sprinter sp(cx);
    if (!sp.init())
        return false;

    const jit::IonTrackedOptimizationsRegionTable* regions =
        entry.ionEntry().trackedOptimizationsRegionTable();

    Sprint(&sp, "{\"regions\": [");
    for (uint32_t i = 0; i < regions->numEntries(); i++) {
        jit::IonTrackedOptimizationsRegion region = regions->entry(i);
        jit::IonTrackedOptimizationsRegion::RangeIterator iter = region.ranges();
        while (iter.more()) {
            uint32_t startOffset, endOffset;
            uint8_t index;
            iter.readNext(&startOffset, &endOffset, &index);
            JSScript* script;
            jsbytecode* pc;
            // Use endOffset, as startOffset may be associated with a
            // previous, adjacent region ending exactly at startOffset. That
            // is, suppose we have two regions [0, startOffset], [startOffset,
            // endOffset]. Since we are not querying a return address, we want
            // the second region and not the first.
            uint8_t* addr = ion->method()->raw() + endOffset;
            entry.youngestFrameLocationAtAddr(rt, addr, &script, &pc);
            Sprint(&sp, "{\"location\":\"%s:%u\",\"offset\":%u,\"index\":%u}%s",
                   script->filename(), script->lineno(), script->pcToOffset(pc), index,
                   iter.more() ? "," : "");
        }
    }
    Sprint(&sp, "],");

    Sprint(&sp, "\"opts\": [");
    for (uint8_t i = 0; i < entry.ionEntry().numOptimizationAttempts(); i++) {
        Sprint(&sp, "%s{\"typeinfo\":[", i == 0 ? "" : ",");
        SprintOptimizationTypeInfoOp top(&sp);
        jit::IonTrackedOptimizationsTypeInfo::ForEachOpAdapter adapter(top);
        entry.trackedOptimizationTypeInfo(i).forEach(adapter, entry.allTrackedTypes());
        // Clear the trailing ,
        if (sp[sp.getOffset() - 1] == ',')
            sp[sp.getOffset() - 1] = ' ';
        Sprint(&sp, "],\"attempts\":[");
        SprintOptimizationAttemptsOp aop(&sp);
        entry.trackedOptimizationAttempts(i).forEach(aop);
        // Clear the trailing ,
        if (sp[sp.getOffset() - 1] == ',')
            sp[sp.getOffset() - 1] = ' ';
        Sprint(&sp, "]}");
    }
    Sprint(&sp, "]}");

    if (sp.hadOutOfMemory())
        return false;

    RootedString str(cx, JS_NewStringCopyZ(cx, sp.string()));
    if (!str)
        return false;
    RootedValue jsonVal(cx);
    if (!JS_ParseJSON(cx, str, &jsonVal))
        return false;

    args.rval().set(jsonVal);
    return true;
}

#ifdef DEBUG
static bool
DumpStaticScopeChain(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    RootedObject callee(cx, &args.callee());

    if (args.length() != 1) {
        ReportUsageError(cx, callee, "Wrong number of arguments");
        return false;
    }

    if (!args[0].isObject() ||
        !(args[0].toObject().is<JSFunction>() || args[0].toObject().is<ModuleObject>()))
    {
        ReportUsageError(cx, callee, "Argument must be an interpreted function or a module");
        return false;
    }

    RootedObject obj(cx, &args[0].toObject());
    RootedScript script(cx);

    if (obj->is<JSFunction>()) {
        RootedFunction fun(cx, &obj->as<JSFunction>());
        if (!fun->isInterpreted()) {
            ReportUsageError(cx, callee, "Argument must be an interpreted function");
            return false;
        }
        script = fun->getOrCreateScript(cx);
    } else {
        script = obj->as<ModuleObject>().script();
    }

    js::DumpStaticScopeChain(script);

    args.rval().setUndefined();
    return true;
}
#endif

namespace js {
namespace shell {

class ShellAutoEntryMonitor : JS::dbg::AutoEntryMonitor {
    Vector<UniqueChars, 1, js::SystemAllocPolicy> log;
    bool oom;
    bool enteredWithoutExit;

  public:
    explicit ShellAutoEntryMonitor(JSContext *cx)
      : AutoEntryMonitor(cx),
        oom(false),
        enteredWithoutExit(false)
    { }

    ~ShellAutoEntryMonitor() {
        MOZ_ASSERT(!enteredWithoutExit);
    }

    void Entry(JSContext* cx, JSFunction* function, JS::HandleValue asyncStack,
               JS::HandleString asyncCause) override {
        MOZ_ASSERT(!enteredWithoutExit);
        enteredWithoutExit = true;

        RootedString displayId(cx, JS_GetFunctionDisplayId(function));
        if (displayId) {
            UniqueChars displayIdStr(JS_EncodeStringToUTF8(cx, displayId));
            oom = !displayIdStr || !log.append(mozilla::Move(displayIdStr));
            return;
        }

        oom = !log.append(make_string_copy("anonymous"));
    }

    void Entry(JSContext* cx, JSScript* script, JS::HandleValue asyncStack,
               JS::HandleString asyncCause) override {
        MOZ_ASSERT(!enteredWithoutExit);
        enteredWithoutExit = true;

        UniqueChars label(JS_smprintf("eval:%s", JS_GetScriptFilename(script)));
        oom = !label || !log.append(mozilla::Move(label));
    }

    void Exit(JSContext* cx) override {
        MOZ_ASSERT(enteredWithoutExit);
        enteredWithoutExit = false;
    }

    bool buildResult(JSContext *cx, MutableHandleValue resultValue) {
        if (oom) {
            JS_ReportOutOfMemory(cx);
            return false;
        }

        RootedObject result(cx, JS_NewArrayObject(cx, log.length()));
        if (!result)
            return false;

        for (size_t i = 0; i < log.length(); i++) {
            char *name = log[i].get();
            RootedString string(cx, Atomize(cx, name, strlen(name)));
            if (!string)
                return false;
            RootedValue value(cx, StringValue(string));
            if (!JS_SetElement(cx, result, i, value))
                return false;
        }

        resultValue.setObject(*result.get());
        return true;
    }
};

} // namespace shell
} // namespace js

static bool
EntryPoints(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    if (args.length() != 1) {
        JS_ReportError(cx, "Wrong number of arguments");
        return false;
    }

    RootedObject opts(cx, ToObject(cx, args[0]));
    if (!opts)
        return false;

    // { function: f } --- Call f.
    {
        RootedValue fun(cx), dummy(cx);

        if (!JS_GetProperty(cx, opts, "function", &fun))
            return false;
        if (!fun.isUndefined()) {
            js::shell::ShellAutoEntryMonitor sarep(cx);
            if (!Call(cx, UndefinedHandleValue, fun, JS::HandleValueArray::empty(), &dummy))
                return false;
            return sarep.buildResult(cx, args.rval());
        }
    }

    // { object: o, property: p, value: v } --- Fetch o[p], or if
    // v is present, assign o[p] = v.
    {
        RootedValue objectv(cx), propv(cx), valuev(cx);

        if (!JS_GetProperty(cx, opts, "object", &objectv) ||
            !JS_GetProperty(cx, opts, "property", &propv))
            return false;
        if (!objectv.isUndefined() && !propv.isUndefined()) {
            RootedObject object(cx, ToObject(cx, objectv));
            if (!object)
                return false;

            RootedString string(cx, ToString(cx, propv));
            if (!string)
                return false;
            RootedId id(cx);
            if (!JS_StringToId(cx, string, &id))
                return false;

            if (!JS_GetProperty(cx, opts, "value", &valuev))
                return false;

            js::shell::ShellAutoEntryMonitor sarep(cx);

            if (!valuev.isUndefined()) {
                if (!JS_SetPropertyById(cx, object, id, valuev))
                    return false;
            } else {
                if (!JS_GetPropertyById(cx, object, id, &valuev))
                    return false;
            }

            return sarep.buildResult(cx, args.rval());
        }
    }

    // { ToString: v } --- Apply JS::ToString to v.
    {
        RootedValue v(cx);

        if (!JS_GetProperty(cx, opts, "ToString", &v))
            return false;
        if (!v.isUndefined()) {
            js::shell::ShellAutoEntryMonitor sarep(cx);
            if (!JS::ToString(cx, v))
                return false;
            return sarep.buildResult(cx, args.rval());
        }
    }

    // { ToNumber: v } --- Apply JS::ToNumber to v.
    {
        RootedValue v(cx);
        double dummy;

        if (!JS_GetProperty(cx, opts, "ToNumber", &v))
            return false;
        if (!v.isUndefined()) {
            js::shell::ShellAutoEntryMonitor sarep(cx);
            if (!JS::ToNumber(cx, v, &dummy))
                return false;
            return sarep.buildResult(cx, args.rval());
        }
    }

    // { eval: code } --- Apply ToString and then Evaluate to code.
    {
        RootedValue code(cx), dummy(cx);

        if (!JS_GetProperty(cx, opts, "eval", &code))
            return false;
        if (!code.isUndefined()) {
            RootedString codeString(cx, ToString(cx, code));
            if (!codeString || !codeString->ensureFlat(cx))
                return false;

            AutoStableStringChars stableChars(cx);
            if (!stableChars.initTwoByte(cx, codeString))
                return false;
            const char16_t* chars = stableChars.twoByteRange().start().get();
            size_t length = codeString->length();

            CompileOptions options(cx);
            options.setIntroductionType("entryPoint eval")
                   .setFileAndLine("entryPoint eval", 1);

            js::shell::ShellAutoEntryMonitor sarep(cx);
            if (!JS::Evaluate(cx, options, chars, length, &dummy))
                return false;
            return sarep.buildResult(cx, args.rval());
        }
    }

    JS_ReportError(cx, "bad 'params' object");
    return false;
}

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("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
};

static const JSFunctionSpecWithHelp fuzzing_unsafe_functions[] = {
    JS_FN_HELP("clone", Clone, 1, 0,
"clone(fun[, scope])",
"  Clone function object."),

    JS_FN_HELP("getSelfHostedValue", GetSelfHostedValue, 1, 0,
"getSelfHostedValue()",
"  Get a self-hosted value by its name. Note that these values don't get \n"
"  cached, so repeatedly getting the same value creates multiple distinct clones."),

    JS_FN_HELP("line2pc", LineToPC, 0, 0,
"line2pc([fun,] line)",
"  Map line number to PC."),

    JS_FN_HELP("pc2line", PCToLine, 0, 0,
"pc2line(fun[, pc])",
"  Map PC to line number."),

    JS_FN_HELP("nestedShell", NestedShell, 0, 0,
"nestedShell(shellArgs...)",
"  Execute the given code in a new JS shell process, passing this nested shell\n"
"  the arguments passed to nestedShell. argv[0] of the nested shell will be argv[0]\n"
"  of the current shell (which is assumed to be the actual path to the shell.\n"
"  arguments[0] (of the call to nestedShell) will be argv[1], arguments[1] will\n"
"  be argv[2], etc."),

    JS_INLINABLE_FN_HELP("assertFloat32", testingFunc_assertFloat32, 2, 0, TestAssertFloat32,
"assertFloat32(value, isFloat32)",
"  In IonMonkey only, asserts that value has (resp. hasn't) the MIRType_Float32 if isFloat32 is true (resp. false)."),

    JS_INLINABLE_FN_HELP("assertRecoveredOnBailout", testingFunc_assertRecoveredOnBailout, 2, 0,
TestAssertRecoveredOnBailout,
"assertRecoveredOnBailout(var)",
"  In IonMonkey only, asserts that variable has RecoveredOnBailout flag."),

    JS_FN_HELP("withSourceHook", WithSourceHook, 1, 0,
"withSourceHook(hook, fun)",
"  Set this JS runtime's lazy source retrieval hook (that is, the hook\n"
"  used to find sources compiled with |CompileOptions::LAZY_SOURCE|) to\n"
"  |hook|; call |fun| with no arguments; and then restore the runtime's\n"
"  original hook. Return or throw whatever |fun| did. |hook| gets\n"
"  passed the requested code's URL, and should return a string.\n"
"\n"
"  Notes:\n"
"\n"
"  1) SpiderMonkey may assert if the returned code isn't close enough\n"
"  to the script's real code, so this function is not fuzzer-safe.\n"
"\n"
"  2) The runtime can have only one source retrieval hook active at a\n"
"  time. If |fun| is not careful, |hook| could be asked to retrieve the\n"
"  source code for compilations that occurred long before it was set,\n"
"  and that it knows nothing about. The reverse applies as well: the\n"
"  original hook, that we reinstate after the call to |fun| completes,\n"
"  might be asked for the source code of compilations that |fun|\n"
"  performed, and which, presumably, only |hook| knows how to find.\n"),

    JS_FN_HELP("wrapWithProto", WrapWithProto, 2, 0,
"wrapWithProto(obj)",
"  Wrap an object into a noop wrapper with prototype semantics.\n"
"  Note: This is not fuzzing safe because it can be used to construct\n"
"        deeply nested wrapper chains that cannot exist in the wild."),

    JS_FN_HELP("trackedOpts", ReflectTrackedOptimizations, 1, 0,
"trackedOpts(fun)",
"  Returns an object describing the tracked optimizations of |fun|, if\n"
"  any. If |fun| is not a scripted function or has not been compiled by\n"
"  Ion, null is returned."),

#ifdef DEBUG
    JS_FN_HELP("dumpStaticScopeChain", DumpStaticScopeChain, 1, 0,
"dumpStaticScopeChain(obj)",
"  Prints the static scope chain of an interpreted function or a module."),
#endif

    JS_FS_HELP_END
};

static const JSFunctionSpecWithHelp console_functions[] = {
    JS_FN_HELP("log", Print, 0, 0,
"log([exp ...])",
"  Evaluate and print expressions to stdout.\n"
"  This function is an alias of the print() function."),
    JS_FS_HELP_END
};

bool
DefineConsole(JSContext* cx, HandleObject global)
{
    RootedObject obj(cx, JS_NewPlainObject(cx));
    return obj &&
           JS_DefineFunctionsWithHelp(cx, obj, console_functions) &&
           JS_DefineProperty(cx, global, "console", obj, 0);
}

#ifdef MOZ_PROFILING
# define PROFILING_FUNCTION_COUNT 5
# ifdef MOZ_CALLGRIND
#  define CALLGRIND_FUNCTION_COUNT 3
# else
#  define CALLGRIND_FUNCTION_COUNT 0
# endif
# ifdef MOZ_VTUNE
#  define VTUNE_FUNCTION_COUNT 4
# else
#  define VTUNE_FUNCTION_COUNT 0
# endif
# define EXTERNAL_FUNCTION_COUNT (PROFILING_FUNCTION_COUNT + CALLGRIND_FUNCTION_COUNT + VTUNE_FUNCTION_COUNT)
#else
# define EXTERNAL_FUNCTION_COUNT 0
#endif

#undef PROFILING_FUNCTION_COUNT
#undef CALLGRIND_FUNCTION_COUNT
#undef VTUNE_FUNCTION_COUNT
#undef EXTERNAL_FUNCTION_COUNT

static bool
PrintHelpString(JSContext* cx, Value v)
{
    JSString* str = v.toString();

    JSLinearString* linear = str->ensureLinear(cx);
    if (!linear)
        return false;

    JS::AutoCheckCannotGC nogc;
    if (linear->hasLatin1Chars()) {
        for (const Latin1Char* p = linear->latin1Chars(nogc); *p; p++)
            fprintf(gOutFile, "%c", char(*p));
    } else {
        for (const char16_t* p = linear->twoByteChars(nogc); *p; p++)
            fprintf(gOutFile, "%c", char(*p));
    }
    fprintf(gOutFile, "\n");

    return true;
}

static bool
PrintHelp(JSContext* cx, HandleObject obj)
{
    RootedValue usage(cx);
    if (!JS_GetProperty(cx, obj, "usage", &usage))
        return false;
    RootedValue help(cx);
    if (!JS_GetProperty(cx, obj, "help", &help))
        return false;

    if (usage.isUndefined() || help.isUndefined())
        return true;

    return PrintHelpString(cx, usage) && PrintHelpString(cx, help);
}

static bool
Help(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    fprintf(gOutFile, "%s\n", JS_GetImplementationVersion());

    RootedObject obj(cx);
    if (args.length() == 0) {
        RootedObject global(cx, JS::CurrentGlobalOrNull(cx));
        Rooted<IdVector> ida(cx, IdVector(cx));
        if (!JS_Enumerate(cx, global, &ida))
            return false;

        for (size_t i = 0; i < ida.length(); i++) {
            RootedValue v(cx);
            RootedId id(cx, ida[i]);
            if (!JS_GetPropertyById(cx, global, id, &v))
                return false;
            if (v.isPrimitive()) {
                JS_ReportError(cx, "primitive arg");
                return false;
            }
            obj = v.toObjectOrNull();
            if (!PrintHelp(cx, obj))
                return false;
        }
    } else {
        for (unsigned i = 0; i < args.length(); i++) {
            if (args[i].isPrimitive()) {
                JS_ReportError(cx, "primitive arg");
                return false;
            }
            obj = args[i].toObjectOrNull();
            if (!PrintHelp(cx, obj))
                return false;
        }
    }

    args.rval().setUndefined();
    return true;
}

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*
js::shell::my_GetErrorMessage(void* userRef, const unsigned errorNumber)
{
    if (errorNumber == 0 || errorNumber >= JSShellErr_Limit)
        return nullptr;

    return &jsShell_ErrorFormatString[errorNumber];
}

static bool
CreateLastWarningObject(JSContext* cx, JSErrorReport* report)
{
    RootedObject warningObj(cx, JS_NewObject(cx, nullptr));
    if (!warningObj)
        return false;

    RootedString nameStr(cx);
    if (report->exnType == JSEXN_NONE)
        nameStr = JS_NewStringCopyZ(cx, "None");
    else
        nameStr = GetErrorTypeName(cx->runtime(), report->exnType);
    if (!nameStr)
        return false;
    RootedValue nameVal(cx, StringValue(nameStr));
    if (!DefineProperty(cx, warningObj, cx->names().name, nameVal))
        return false;

    RootedString messageStr(cx, JS_NewUCStringCopyZ(cx, report->ucmessage));
    if (!messageStr)
        return false;
    RootedValue messageVal(cx, StringValue(messageStr));
    if (!DefineProperty(cx, warningObj, cx->names().message, messageVal))
        return false;

    RootedValue linenoVal(cx, Int32Value(report->lineno));
    if (!DefineProperty(cx, warningObj, cx->names().lineNumber, linenoVal))
        return false;

    RootedValue columnVal(cx, Int32Value(report->column));
    if (!DefineProperty(cx, warningObj, cx->names().columnNumber, columnVal))
        return false;

    GetShellRuntime(cx)->lastWarning.setObject(*warningObj);
    return true;
}

static bool
PrintStackTrace(JSContext* cx, HandleValue exn)
{
    if (!exn.isObject())
        return false;

    Maybe<JSAutoCompartment> ac;
    RootedObject exnObj(cx, &exn.toObject());
    if (IsCrossCompartmentWrapper(exnObj)) {
        exnObj = UncheckedUnwrap(exnObj);
        ac.emplace(cx, exnObj);
    }

    // Ignore non-ErrorObject thrown by |throw| statement.
    if (!exnObj->is<ErrorObject>())
        return true;

    // Exceptions thrown while compiling top-level script have no stack.
    RootedObject stackObj(cx, exnObj->as<ErrorObject>().stack());
    if (!stackObj)
        return true;

    RootedString stackStr(cx);
    if (!BuildStackString(cx, stackObj, &stackStr, 2))
        return false;

    UniquePtr<char[], JS::FreePolicy> stack(JS_EncodeStringToUTF8(cx, stackStr));
    if (!stack)
        return false;

    fputs("Stack:\n", gErrFile);
    fputs(stack.get(), gErrFile);

    return true;
}

void
js::shell::my_ErrorReporter(JSContext* cx, const char* message, JSErrorReport* report)
{
    ShellRuntime* sr = GetShellRuntime(cx);

    if (report && JSREPORT_IS_WARNING(report->flags) && sr->lastWarningEnabled) {
        JS::AutoSaveExceptionState savedExc(cx);
        if (!CreateLastWarningObject(cx, report)) {
            fputs("Unhandled error happened while creating last warning object.\n", gOutFile);
            fflush(gOutFile);
        }
        savedExc.restore();
    }

    // Get exception object before printing and clearing exception.
    RootedValue exn(cx);
    if (JS_IsExceptionPending(cx))
        (void) JS_GetPendingException(cx, &exn);

    sr->gotError = PrintError(cx, gErrFile, message, report, reportWarnings);
    if (!exn.isUndefined()) {
        JS::AutoSaveExceptionState savedExc(cx);
        if (!PrintStackTrace(cx, exn))
            fputs("(Unable to print stack trace)\n", gOutFile);
        savedExc.restore();
    }

    if (report->exnType != JSEXN_NONE && !JSREPORT_IS_WARNING(report->flags)) {
        if (report->errorNumber == JSMSG_OUT_OF_MEMORY)
            sr->exitCode = EXITCODE_OUT_OF_MEMORY;
        else
            sr->exitCode = EXITCODE_RUNTIME_ERROR;
    }
}

static void
my_OOMCallback(JSContext* cx, void* data)
{
    // 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;
}

static bool
global_enumerate(JSContext* cx, HandleObject obj)
{
#ifdef LAZY_STANDARD_CLASSES
    return JS_EnumerateStandardClasses(cx, obj);
#else
    return true;
#endif
}

static bool
global_resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp)
{
#ifdef LAZY_STANDARD_CLASSES
    if (!JS_ResolveStandardClass(cx, obj, id, resolvedp))
        return false;
#endif
    return true;
}

static bool
global_mayResolve(const JSAtomState& names, jsid id, JSObject* maybeObj)
{
    return JS_MayResolveStandardClass(names, id, maybeObj);
}

static const JSClass global_class = {
    "global", JSCLASS_GLOBAL_FLAGS,
    nullptr, nullptr, nullptr, nullptr,
    global_enumerate, global_resolve, global_mayResolve,
    nullptr,
    nullptr, nullptr, nullptr,
    JS_GlobalObjectTraceHook
};

/*
 * Define a FakeDOMObject constructor. It returns an object with a getter,
 * setter and method with attached JitInfo. This object can be used to test
 * IonMonkey DOM optimizations in the shell.
 */
static const uint32_t DOM_OBJECT_SLOT = 0;

static bool
dom_genericGetter(JSContext* cx, unsigned argc, JS::Value* vp);

static bool
dom_genericSetter(JSContext* cx, unsigned argc, JS::Value* vp);

static bool
dom_genericMethod(JSContext* cx, unsigned argc, JS::Value* vp);

#ifdef DEBUG
static const JSClass* GetDomClass();
#endif

static bool
dom_get_x(JSContext* cx, HandleObject obj, void* self, JSJitGetterCallArgs args)
{
    MOZ_ASSERT(JS_GetClass(obj) == GetDomClass());
    MOZ_ASSERT(self == (void*)0x1234);
    args.rval().set(JS_NumberValue(double(3.14)));
    return true;
}

static bool
dom_set_x(JSContext* cx, HandleObject obj, void* self, JSJitSetterCallArgs args)
{
    MOZ_ASSERT(JS_GetClass(obj) == GetDomClass());
    MOZ_ASSERT(self == (void*)0x1234);
    return true;
}

static bool
dom_doFoo(JSContext* cx, HandleObject obj, void* self, const JSJitMethodCallArgs& args)
{
    MOZ_ASSERT(JS_GetClass(obj) == GetDomClass());
    MOZ_ASSERT(self == (void*)0x1234);

    /* Just return args.length(). */
    args.rval().setInt32(args.length());
    return true;
}

static const JSJitInfo dom_x_getterinfo = {
    { (JSJitGetterOp)dom_get_x },
    { 0 },    /* protoID */
    0,        /* depth */
    JSJitInfo::AliasNone, /* aliasSet */
    JSJitInfo::Getter,
    JSVAL_TYPE_UNKNOWN, /* returnType */
    true,     /* isInfallible. False in setters. */
    true,     /* isMovable */
    true,     /* isEliminatable */
    false,    /* isAlwaysInSlot */
    false,    /* isLazilyCachedInSlot */
    false,    /* isTypedMethod */
    0         /* slotIndex */
};

static const JSJitInfo dom_x_setterinfo = {
    { (JSJitGetterOp)dom_set_x },
    { 0 },    /* protoID */
    0,        /* depth */
    JSJitInfo::Setter,
    JSJitInfo::AliasEverything, /* aliasSet */
    JSVAL_TYPE_UNKNOWN, /* returnType */
    false,    /* isInfallible. False in setters. */
    false,    /* isMovable. */
    false,    /* isEliminatable. */
    false,    /* isAlwaysInSlot */
    false,    /* isLazilyCachedInSlot */
    false,    /* isTypedMethod */
    0         /* slotIndex */
};

static const JSJitInfo doFoo_methodinfo = {
    { (JSJitGetterOp)dom_doFoo },
    { 0 },    /* protoID */
    0,        /* depth */
    JSJitInfo::Method,
    JSJitInfo::AliasEverything, /* aliasSet */
    JSVAL_TYPE_UNKNOWN, /* returnType */
    false,    /* isInfallible. False in setters. */
    false,    /* isMovable */
    false,    /* isEliminatable */
    false,    /* isAlwaysInSlot */
    false,    /* isLazilyCachedInSlot */
    false,    /* isTypedMethod */
    0         /* slotIndex */
};

static const JSPropertySpec dom_props[] = {
    {"x",
     JSPROP_SHARED | JSPROP_ENUMERATE,
     { { dom_genericGetter, &dom_x_getterinfo } },
     { { dom_genericSetter, &dom_x_setterinfo } }
    },
    JS_PS_END
};

static const JSFunctionSpec dom_methods[] = {
    JS_FNINFO("doFoo", dom_genericMethod, &doFoo_methodinfo, 3, JSPROP_ENUMERATE),
    JS_FS_END
};

static const JSClass dom_class = {
    "FakeDOMObject", JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(2)
};

#ifdef DEBUG
static const JSClass* GetDomClass() {
    return &dom_class;
}
#endif

static bool
dom_genericGetter(JSContext* cx, unsigned argc, JS::Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    RootedObject obj(cx, JS_THIS_OBJECT(cx, vp));
    if (!obj)
        return false;

    if (JS_GetClass(obj) != &dom_class) {
        args.rval().set(UndefinedValue());
        return true;
    }

    JS::Value val = js::GetReservedSlot(obj, DOM_OBJECT_SLOT);

    const JSJitInfo* info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
    MOZ_ASSERT(info->type() == JSJitInfo::Getter);
    JSJitGetterOp getter = info->getter;
    return getter(cx, obj, val.toPrivate(), JSJitGetterCallArgs(args));
}

static bool
dom_genericSetter(JSContext* cx, unsigned argc, JS::Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    RootedObject obj(cx, JS_THIS_OBJECT(cx, vp));
    if (!obj)
        return false;

    MOZ_ASSERT(args.length() == 1);

    if (JS_GetClass(obj) != &dom_class) {
        args.rval().set(UndefinedValue());
        return true;
    }

    JS::Value val = js::GetReservedSlot(obj, DOM_OBJECT_SLOT);

    const JSJitInfo* info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
    MOZ_ASSERT(info->type() == JSJitInfo::Setter);
    JSJitSetterOp setter = info->setter;
    if (!setter(cx, obj, val.toPrivate(), JSJitSetterCallArgs(args)))
        return false;
    args.rval().set(UndefinedValue());
    return true;
}

static bool
dom_genericMethod(JSContext* cx, unsigned argc, JS::Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    RootedObject obj(cx, JS_THIS_OBJECT(cx, vp));
    if (!obj)
        return false;

    if (JS_GetClass(obj) != &dom_class) {
        args.rval().set(UndefinedValue());
        return true;
    }

    JS::Value val = js::GetReservedSlot(obj, DOM_OBJECT_SLOT);

    const JSJitInfo* info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
    MOZ_ASSERT(info->type() == JSJitInfo::Method);
    JSJitMethodOp method = info->method;
    return method(cx, obj, val.toPrivate(), JSJitMethodCallArgs(args));
}

static void
InitDOMObject(HandleObject obj)
{
    /* Fow now just initialize to a constant we can check. */
    SetReservedSlot(obj, DOM_OBJECT_SLOT, PrivateValue((void*)0x1234));
}

static bool
dom_constructor(JSContext* cx, unsigned argc, JS::Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    RootedObject callee(cx, &args.callee());
    RootedValue protov(cx);
    if (!GetProperty(cx, callee, callee, cx->names().prototype, &protov))
        return false;

    if (!protov.isObject()) {
        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_BAD_PROTOTYPE, "FakeDOMObject");
        return false;
    }

    RootedObject proto(cx, &protov.toObject());
    RootedObject domObj(cx, JS_NewObjectWithGivenProto(cx, &dom_class, proto));
    if (!domObj)
        return false;

    InitDOMObject(domObj);

    args.rval().setObject(*domObj);
    return true;
}

static bool
InstanceClassHasProtoAtDepth(const Class* clasp, uint32_t protoID, uint32_t depth)
{
    /* There's only a single (fake) DOM object in the shell, so just return true. */
    return true;
}

class ScopedFileDesc
{
    intptr_t fd_;
  public:
    enum LockType { READ_LOCK, WRITE_LOCK };
    ScopedFileDesc(int fd, LockType lockType)
      : fd_(fd)
    {
        if (fd == -1)
            return;
        if (!jsCacheOpened.compareExchange(false, true)) {
            close(fd_);
            fd_ = -1;
            return;
        }
    }
    ~ScopedFileDesc() {
        if (fd_ == -1)
            return;
        MOZ_ASSERT(jsCacheOpened == true);
        jsCacheOpened = false;
        close(fd_);
    }
    operator intptr_t() const {
        return fd_;
    }
    intptr_t forget() {
        intptr_t ret = fd_;
        fd_ = -1;
        return ret;
    }
};

// To guard against corrupted cache files generated by previous crashes, write
// asmJSCacheCookie to the first uint32_t of the file only after the file is
// fully serialized and flushed to disk.
static const uint32_t asmJSCacheCookie = 0xabbadaba;

static bool
ShellOpenAsmJSCacheEntryForRead(HandleObject global, const char16_t* begin, const char16_t* limit,
                                size_t* serializedSizeOut, const uint8_t** memoryOut,
                                intptr_t* handleOut)
{
    // Starboard does not support memory mapped files, so this function is
    // stubbed when running on top of starboard, as if |jsCachingEnabled| was
    // set to false.
#if defined(STARBOARD)
    return false;
#else  // defined(STARBOARD)

    if (!jsCachingEnabled || !jsCacheAsmJSPath)
        return false;

    ScopedFileDesc fd(open(jsCacheAsmJSPath, O_RDWR), ScopedFileDesc::READ_LOCK);
    if (fd == -1)
        return false;

    // Get the size and make sure we can dereference at least one uint32_t.
    off_t off = lseek(fd, 0, SEEK_END);
    if (off == -1 || off < (off_t)sizeof(uint32_t))
        return false;

#if defined(XP_WIN)
    HANDLE fdOsHandle = (HANDLE)_get_osfhandle(fd);
    HANDLE fileMapping = CreateFileMapping(fdOsHandle, nullptr, PAGE_READWRITE, 0, 0, nullptr);
    if (!fileMapping)
        return false;

    memory = MapViewOfFile(fileMapping, FILE_MAP_READ, 0, 0, 0);
    CloseHandle(fileMapping);
    if (!memory)
        return false;
#else
    memory = mmap(nullptr, off, PROT_READ, MAP_SHARED, fd, 0);
    if (memory == MAP_FAILED)
        return false;
#endif

    // Perform check described by asmJSCacheCookie comment.
    if (*(uint32_t*)memory != asmJSCacheCookie) {
#if defined(XP_WIN)
        UnmapViewOfFile(memory);
#else
        munmap(memory, off);
#endif
        return false;
    }

    // The embedding added the cookie so strip it off of the buffer returned to
    // the JS engine.
    *serializedSizeOut = off - sizeof(uint32_t);
    *memoryOut = (uint8_t*)memory + sizeof(uint32_t);
    *handleOut = fd.forget();
    return true;
#endif  // defined(STARBOARD)
}

static void
ShellCloseAsmJSCacheEntryForRead(size_t serializedSize, const uint8_t* memory, intptr_t handle)
{
#if defined(STARBOARD)
    return;
#else  // defined(STARBOARD)

    // Undo the cookie adjustment done when opening the file.
    memory -= sizeof(uint32_t);
    serializedSize += sizeof(uint32_t);

    // Release the memory mapping and file.
#if defined(XP_WIN)
    UnmapViewOfFile(const_cast<uint8_t*>(memory));
#else
    munmap(const_cast<uint8_t*>(memory), serializedSize);
#endif

    MOZ_ASSERT(jsCacheOpened == true);
    jsCacheOpened = false;
    close(handle);
#endif  // defined(STARBOARD)
}

static JS::AsmJSCacheResult
ShellOpenAsmJSCacheEntryForWrite(HandleObject global, bool installed,
                                 const char16_t* begin, const char16_t* end,
                                 size_t serializedSize, uint8_t** memoryOut, intptr_t* handleOut)
{
#if defined(STARBOARD)
    return JS::AsmJSCache_Disabled_ShellFlags;
#else  // defined(STARBOARD)

    if (!jsCachingEnabled || !jsCacheAsmJSPath)
        return JS::AsmJSCache_Disabled_ShellFlags;

    // Create the cache directory if it doesn't already exist.
    struct stat dirStat;
    if (stat(jsCacheDir, &dirStat) == 0) {
        if (!(dirStat.st_mode & S_IFDIR))
            return JS::AsmJSCache_InternalError;
    } else {
#ifdef XP_WIN
        if (mkdir(jsCacheDir) != 0)
            return JS::AsmJSCache_InternalError;
#else
        if (mkdir(jsCacheDir, 0777) != 0)
            return JS::AsmJSCache_InternalError;
#endif
    }

    ScopedFileDesc fd(open(jsCacheAsmJSPath, O_CREAT|O_RDWR, 0660), ScopedFileDesc::WRITE_LOCK);
    if (fd == -1)
        return JS::AsmJSCache_InternalError;

    // Include extra space for the asmJSCacheCookie.
    serializedSize += sizeof(uint32_t);

    // Resize the file to the appropriate size after zeroing their contents.
#ifdef XP_WIN
    if (chsize(fd, 0))
        return JS::AsmJSCache_InternalError;
    if (chsize(fd, serializedSize))
        return JS::AsmJSCache_InternalError;
#else
    if (ftruncate(fd, 0))
        return JS::AsmJSCache_InternalError;
    if (ftruncate(fd, serializedSize))
        return JS::AsmJSCache_InternalError;
#endif

    // Map the file into memory.
    void* memory;
#if defined(XP_WIN)
    HANDLE fdOsHandle = (HANDLE)_get_osfhandle(fd);
    HANDLE fileMapping = CreateFileMapping(fdOsHandle, nullptr, PAGE_READWRITE, 0, 0, nullptr);
    if (!fileMapping)
        return JS::AsmJSCache_InternalError;

    memory = MapViewOfFile(fileMapping, FILE_MAP_WRITE, 0, 0, 0);
    CloseHandle(fileMapping);
    if (!memory)
        return JS::AsmJSCache_InternalError;
#else
    memory = mmap(nullptr, serializedSize, PROT_WRITE, MAP_SHARED, fd, 0);
    if (memory == MAP_FAILED)
        return JS::AsmJSCache_InternalError;
#endif

    // The embedding added the cookie so strip it off of the buffer returned to
    // the JS engine. The asmJSCacheCookie will be written on close, below.
    MOZ_ASSERT(*(uint32_t*)memory == 0);
    *memoryOut = (uint8_t*)memory + sizeof(uint32_t);
    *handleOut = fd.forget();
    return JS::AsmJSCache_Success;
#endif  // defined(STARBOARD)
}

static void
ShellCloseAsmJSCacheEntryForWrite(size_t serializedSize, uint8_t* memory, intptr_t handle)
{
#if defined(STARBOARD)
    return;
#else  // defined(STARBOARD)

    // Undo the cookie adjustment done when opening the file.
    memory -= sizeof(uint32_t);
    serializedSize += sizeof(uint32_t);

    // Write the magic cookie value after flushing the entire cache entry.
#if defined(XP_WIN)
    FlushViewOfFile(memory, serializedSize);
    FlushFileBuffers(HANDLE(_get_osfhandle(handle)));
#else
    msync(memory, serializedSize, MS_SYNC);
#endif

    MOZ_ASSERT(*(uint32_t*)memory == 0);
    *(uint32_t*)memory = asmJSCacheCookie;

    // Free the memory mapping and file.
#if defined(XP_WIN)
    UnmapViewOfFile(const_cast<uint8_t*>(memory));
#else
    munmap(memory, serializedSize);
#endif

    MOZ_ASSERT(jsCacheOpened == true);
    jsCacheOpened = false;
    close(handle);
#endif  // defined(STARBOARD)
}

static bool
ShellBuildId(JS::BuildIdCharVector* buildId)
{
    // The browser embeds the date into the buildid and the buildid is embedded
    // in the binary, so every 'make' necessarily builds a new firefox binary.
    // Fortunately, the actual firefox executable is tiny -- all the code is in
    // libxul.so and other shared modules -- so this isn't a big deal. Not so
    // for the statically-linked JS shell. To avoid recompmiling js.cpp and
    // re-linking 'js' on every 'make', we use a constant buildid and rely on
    // the shell user to manually clear the cache (deleting the dir passed to
    // --js-cache) between cache-breaking updates. Note: jit_tests.py does this
    // on every run).
    const char buildid[] = "JS-shell";
    return buildId->append(buildid, sizeof(buildid));
}

static const JS::AsmJSCacheOps asmJSCacheOps = {
    ShellOpenAsmJSCacheEntryForRead,
    ShellCloseAsmJSCacheEntryForRead,
    ShellOpenAsmJSCacheEntryForWrite,
    ShellCloseAsmJSCacheEntryForWrite,
    ShellBuildId
};

static JSContext*
NewContext(JSRuntime* rt)
{
    JSContext* cx = JS_NewContext(rt, gStackChunkSize);
    if (!cx)
        return nullptr;

    JSShellContextData* data = NewContextData();
    if (!data) {
        DestroyContext(cx, false);
        return nullptr;
    }

    JS_SetContextPrivate(cx, data);
    return cx;
}

static void
DestroyContext(JSContext* cx, bool withGC)
{
    // Don't use GetContextData as |data| could be a nullptr in the case of
    // destroying a context precisely because we couldn't create its private
    // data.
    JSShellContextData* data = (JSShellContextData*) JS_GetContextPrivate(cx);
    JS_SetContextPrivate(cx, nullptr);
    js_free(data);
    withGC ? JS_DestroyContext(cx) : JS_DestroyContextNoGC(cx);
}

static JSObject*
NewGlobalObject(JSContext* cx, JS::CompartmentOptions& options,
                JSPrincipals* principals)
{
    RootedObject glob(cx, JS_NewGlobalObject(cx, &global_class, principals,
                                             JS::DontFireOnNewGlobalHook, options));
    if (!glob)
        return nullptr;

    {
        JSAutoCompartment ac(cx, glob);

#ifndef LAZY_STANDARD_CLASSES
        if (!JS_InitStandardClasses(cx, glob))
            return nullptr;
#endif

        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");

#ifdef JS_HAS_CTYPES
        if (!JS_InitCTypesClass(cx, glob))
            return nullptr;
#endif
        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;
        }
        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;
    }

    JS_FireOnNewGlobalObject(cx, glob);

    return glob;
}

static bool
BindScriptArgs(JSContext* cx, OptionParser* op)
{
    MultiStringRange msr = op->getMultiStringArg("scriptArgs");
    RootedObject scriptArgs(cx);
    scriptArgs = JS_NewArrayObject(cx, 0);
    if (!scriptArgs)
        return false;

    if (!JS_DefineProperty(cx, cx->global(), "scriptArgs", scriptArgs, 0))
        return false;

    for (size_t i = 0; !msr.empty(); msr.popFront(), ++i) {
        const char* scriptArg = msr.front();
        JS::RootedString str(cx, JS_NewStringCopyZ(cx, scriptArg));
        if (!str ||
            !JS_DefineElement(cx, scriptArgs, i, str, JSPROP_ENUMERATE))
        {
            return false;
        }
    }

    const char* scriptPath = op->getStringArg("script");
    RootedValue scriptPathValue(cx);
    if (scriptPath) {
        RootedString scriptPathString(cx, JS_NewStringCopyZ(cx, scriptPath));
        if (!scriptPathString)
            return false;
        scriptPathValue = StringValue(scriptPathString);
    } else {
        scriptPathValue = UndefinedValue();
    }

    if (!JS_DefineProperty(cx, cx->global(), "scriptPath", scriptPathValue, 0))
        return false;

    return true;
}

static bool
OptionFailure(const char* option, const char* str)
{
    fprintf(stderr, "Unrecognized option for %s: %s\n", option, str);
    return false;
}

static int
ProcessArgs(JSContext* cx, OptionParser* op)
{
    ShellRuntime* sr = GetShellRuntime(cx);

    if (op->getBoolOption('s'))
        JS::RuntimeOptionsRef(cx).toggleExtraWarnings();

    /* |scriptArgs| gets bound on the global before any code is run. */
    if (!BindScriptArgs(cx, op))
        return EXIT_FAILURE;

    MultiStringRange filePaths = op->getMultiStringOption('f');
    MultiStringRange codeChunks = op->getMultiStringOption('e');
    MultiStringRange modulePaths = op->getMultiStringOption('m');

    if (filePaths.empty() &&
        codeChunks.empty() &&
        modulePaths.empty() &&
        !op->getStringArg("script"))
    {
        Process(cx, nullptr, true); /* Interactive. */
        return sr->exitCode;
    }

    if (const char* path = op->getStringOption("module-load-path"))
        moduleLoadPath = path;

    if (!modulePaths.empty() && !InitModuleLoader(cx))
        return EXIT_FAILURE;

    while (!filePaths.empty() || !codeChunks.empty() || !modulePaths.empty()) {
        size_t fpArgno = filePaths.empty() ? SIZE_MAX : filePaths.argno();
        size_t ccArgno = codeChunks.empty() ? SIZE_MAX : codeChunks.argno();
        size_t mpArgno = modulePaths.empty() ? SIZE_MAX : modulePaths.argno();

        if (fpArgno < ccArgno && fpArgno < mpArgno) {
            char* path = filePaths.front();
            Process(cx, path, false, FileScript);
            if (sr->exitCode)
                return sr->exitCode;
            filePaths.popFront();
        } else if (ccArgno < fpArgno && ccArgno < mpArgno) {
            const char* code = codeChunks.front();
            RootedValue rval(cx);
            JS::CompileOptions opts(cx);
            opts.setFileAndLine("-e", 1);
            if (!JS::Evaluate(cx, opts, code, strlen(code), &rval))
                return sr->exitCode ? sr->exitCode : EXITCODE_RUNTIME_ERROR;
            codeChunks.popFront();
            if (sr->quitting)
                break;
        } else {
            MOZ_ASSERT(mpArgno < fpArgno && mpArgno < ccArgno);
            char* path = modulePaths.front();
            Process(cx, path, false, FileModule);
            if (sr->exitCode)
                return sr->exitCode;
            modulePaths.popFront();
        }
    }

    if (sr->quitting)
        return sr->exitCode ? sr->exitCode : EXIT_SUCCESS;

    /* The |script| argument is processed after all options. */
    if (const char* path = op->getStringArg("script")) {
        Process(cx, path, false);
        if (sr->exitCode)
            return sr->exitCode;
    }

    if (op->getBoolOption('i'))
        Process(cx, nullptr, true);

    return sr->exitCode ? sr->exitCode : EXIT_SUCCESS;
}

static bool
SetRuntimeOptions(JSRuntime* rt, const OptionParser& op)
{
    enableBaseline = !op.getBoolOption("no-baseline");
    enableIon = !op.getBoolOption("no-ion");
    enableAsmJS = !op.getBoolOption("no-asmjs");
    enableNativeRegExp = !op.getBoolOption("no-native-regexp");
    enableUnboxedArrays = op.getBoolOption("unboxed-arrays");

    JS::RuntimeOptionsRef(rt).setBaseline(enableBaseline)
                             .setIon(enableIon)
                             .setAsmJS(enableAsmJS)
                             .setNativeRegExp(enableNativeRegExp)
                             .setUnboxedArrays(enableUnboxedArrays);

    if (op.getBoolOption("no-unboxed-objects"))
        jit::JitOptions.disableUnboxedObjects = true;

    if (const char* str = op.getStringOption("ion-scalar-replacement")) {
        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);
    }

    if (const char* str = op.getStringOption("ion-shared-stubs")) {
        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);
    }

    if (const char* str = op.getStringOption("ion-gvn")) {
        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);
        }
    }

    if (const char* str = op.getStringOption("ion-licm")) {
        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);
    }

    if (const char* str = op.getStringOption("ion-edgecase-analysis")) {
        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);
    }

    if (const char* str = op.getStringOption("ion-pgo")) {
        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);
    }

    if (const char* str = op.getStringOption("ion-range-analysis")) {
        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);
    }

    if (const char *str = op.getStringOption("ion-sincos")) {
        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);
    }

    if (const char* str = op.getStringOption("ion-sink")) {
        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);
    }

    if (const char* str = op.getStringOption("ion-loop-unrolling")) {
        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);
    }

    if (const char* str = op.getStringOption("ion-instruction-reordering")) {
        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 (op.getBoolOption("ion-check-range-analysis"))
        jit::JitOptions.checkRangeAnalysis = true;

    if (op.getBoolOption("ion-extra-checks"))
        jit::JitOptions.runExtraChecks = true;

    if (const char* str = op.getStringOption("ion-inlining")) {
        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);
    }

    if (const char* str = op.getStringOption("ion-osr")) {
        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);
    }

    if (const char* str = op.getStringOption("ion-limit-script-size")) {
        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 = op.getIntOption("ion-warmup-threshold");
    if (warmUpThreshold >= 0)
        jit::JitOptions.setCompilerWarmUpThreshold(warmUpThreshold);

    warmUpThreshold = op.getIntOption("baseline-warmup-threshold");
    if (warmUpThreshold >= 0)
        jit::JitOptions.baselineWarmUpThreshold = warmUpThreshold;

    if (op.getBoolOption("baseline-eager"))
        jit::JitOptions.baselineWarmUpThreshold = 0;

    if (const char* str = op.getStringOption("ion-regalloc")) {
        jit::JitOptions.forcedRegisterAllocator = jit::LookupRegisterAllocator(str);
        if (!jit::JitOptions.forcedRegisterAllocator.isSome())
            return OptionFailure("ion-regalloc", str);
    }

    if (op.getBoolOption("ion-eager"))
        jit::JitOptions.setEagerCompilation();

    offthreadCompilation = true;
    if (const char* str = op.getStringOption("ion-offthread-compile")) {
        if (strcmp(str, "off") == 0)
            offthreadCompilation = false;
        else if (strcmp(str, "on") != 0)
            return OptionFailure("ion-offthread-compile", str);
    }
    rt->setOffthreadIonCompilationEnabled(offthreadCompilation);

    if (op.getStringOption("ion-parallel-compile")) {
        fprintf(stderr, "--ion-parallel-compile is deprecated. Please use --ion-offthread-compile instead.\n");
        return false;
    }

#if defined(JS_CODEGEN_ARM)
    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)
    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 = op.getBoolOption('w');
    compileOnly = op.getBoolOption('c');
    printTiming = op.getBoolOption('b');
    enableCodeCoverage = op.getBoolOption("code-coverage");
    enableDisassemblyDumps = op.getBoolOption('D');
    rt->profilingScripts = enableCodeCoverage || enableDisassemblyDumps;

    jsCacheDir = op.getStringOption("js-cache");
    if (jsCacheDir) {
        if (!op.getBoolOption("no-js-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 = op.getBoolOption("dump-entrained-variables");
#endif

#ifdef JS_GC_ZEAL
    const char* zealStr = op.getStringOption("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;
}

static void
SetWorkerRuntimeOptions(JSRuntime* rt)
{
    // Copy option values from the main thread.
    JS::RuntimeOptionsRef(rt).setBaseline(enableBaseline)
                             .setIon(enableIon)
                             .setAsmJS(enableAsmJS)
                             .setNativeRegExp(enableNativeRegExp)
                             .setUnboxedArrays(enableUnboxedArrays);
    rt->setOffthreadIonCompilationEnabled(offthreadCompilation);
    rt->profilingScripts = enableCodeCoverage || enableDisassemblyDumps;

#ifdef JS_GC_ZEAL
    if (*gZealStr)
        rt->gc.parseAndSetZeal(gZealStr);
#endif

    JS_SetNativeStackQuota(rt, gMaxStackSize);
}

static int
Shell(JSContext* cx, OptionParser* op, char** envp)
{
    Maybe<JS::AutoDisableGenerationalGC> noggc;
    if (op->getBoolOption("no-ggc"))
        noggc.emplace(cx->runtime());

    Maybe<AutoDisableCompactingGC> nocgc;
    if (op->getBoolOption("no-cgc"))
        nocgc.emplace(cx->runtime());

    JSAutoRequest ar(cx);

    if (op->getBoolOption("fuzzing-safe"))
        fuzzingSafe = true;
    else
        fuzzingSafe = (js_sb_getenv("MOZ_FUZZING_SAFE") && js_sb_getenv("MOZ_FUZZING_SAFE")[0] != '0');

    if (op->getBoolOption("disable-oom-functions"))
        disableOOMFunctions = true;

    RootedObject glob(cx);
    JS::CompartmentOptions options;
    options.setVersion(JSVERSION_DEFAULT);
    glob = NewGlobalObject(cx, options, nullptr);
    if (!glob)
        return 1;

    JSAutoCompartment ac(cx, glob);

    int result = ProcessArgs(cx, op);

    if (enableDisassemblyDumps)
        js::DumpCompartmentPCCounts(cx);

    if (!op->getBoolOption("no-js-cache-per-process")) {
        if (jsCacheAsmJSPath) {
            unlink(jsCacheAsmJSPath);
            JS_free(cx, const_cast<char*>(jsCacheAsmJSPath));
        }
        if (jsCacheDir) {
            rmdir(jsCacheDir);
            JS_free(cx, const_cast<char*>(jsCacheDir));
        }
    }

    return result;
}

static void
MaybeOverrideOutFileFromEnv(const char* const envVar,
                            FILE* defaultOut,
                            FILE** outFile)
{
    const char* outPath = js_sb_getenv(envVar);
    if (!outPath || !*outPath || !(*outFile = fopen(outPath, "w"))) {
        *outFile = defaultOut;
    }
}

/* Pretend we can always preserve wrappers for dummy DOM objects. */
static bool
DummyPreserveWrapperCallback(JSContext* cx, JSObject* obj)
{
    return true;
}

static void
PreInit()
{
#ifdef XP_WIN
    const char* crash_option = js_sb_getenv("XRE_NO_WINDOWS_CRASH_DIALOG");
    if (crash_option && strncmp(crash_option, "1", 1)) {
        // Disable the segfault dialog. We want to fail the tests immediately
        // instead of hanging automation.
        UINT newMode = SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX;
        UINT prevMode = SetErrorMode(newMode);
        SetErrorMode(prevMode | newMode);
    }
#endif
}

int
main(int argc, char** argv, char** envp)
{
    PreInit();

    sArgc = argc;
    sArgv = argv;

    JSRuntime* rt;
    JSContext* cx;
    int result;

#ifdef HAVE_SETLOCALE
    setlocale(LC_ALL, "");
#endif

    MaybeOverrideOutFileFromEnv("JS_STDERR", stderr, &gErrFile);
    MaybeOverrideOutFileFromEnv("JS_STDOUT", stdout, &gOutFile);

    OptionParser op("Usage: {progname} [options] [[script] scriptArgs*]");

    op.setDescription("The SpiderMonkey shell provides a command line interface to the "
        "JavaScript engine. Code and file options provided via the command line are "
        "run left to right. If provided, the optional script argument is run after "
        "all options have been processed. Just-In-Time compilation modes may be enabled via "
        "command line options.");
    op.setDescriptionWidth(72);
    op.setHelpWidth(80);
    op.setVersion(JS_GetImplementationVersion());

    if (!op.addMultiStringOption('f', "file", "PATH", "File path to run")
        || !op.addMultiStringOption('m', "module", "PATH", "Module path to run")
        || !op.addMultiStringOption('e', "execute", "CODE", "Inline code to run")
        || !op.addBoolOption('i', "shell", "Enter prompt after running code")
        || !op.addBoolOption('c', "compileonly", "Only compile, don't run (syntax checking mode)")
        || !op.addBoolOption('w', "warnings", "Emit warnings")
        || !op.addBoolOption('W', "nowarnings", "Don't emit warnings")
        || !op.addBoolOption('s', "strict", "Check strictness")
        || !op.addBoolOption('D', "dump-bytecode", "Dump bytecode with exec count for all scripts")
        || !op.addBoolOption('b', "print-timing", "Print sub-ms runtime for each file that's run")
        || !op.addStringOption('\0', "js-cache", "[path]",
                               "Enable the JS cache by specifying the path of the directory to use "
                               "to hold cache files")
        || !op.addBoolOption('\0', "no-js-cache-per-process",
                               "Deactivates cache per process. Otherwise, generate a separate cache"
                               "sub-directory for this process inside the cache directory"
                               "specified by --js-cache. This cache directory will be removed"
                               "when the js shell exits. This is useful for running tests in"
                               "parallel.")
        || !op.addBoolOption('\0', "code-coverage", "Enable code coverage instrumentation.")
#ifdef DEBUG
        || !op.addBoolOption('O', "print-alloc", "Print the number of allocations at exit")
#endif
        || !op.addOptionalStringArg("script", "A script to execute (after all options)")
        || !op.addOptionalMultiStringArg("scriptArgs",
                                         "String arguments to bind as |scriptArgs| in the "
                                         "shell's global")
        || !op.addIntOption('\0', "thread-count", "COUNT", "Use COUNT auxiliary threads "
                            "(default: # of cores - 1)", -1)
        || !op.addBoolOption('\0', "ion", "Enable IonMonkey (default)")
        || !op.addBoolOption('\0', "no-ion", "Disable IonMonkey")
        || !op.addBoolOption('\0', "no-asmjs", "Disable asm.js compilation")
        || !op.addBoolOption('\0', "no-native-regexp", "Disable native regexp compilation")
        || !op.addBoolOption('\0', "no-unboxed-objects", "Disable creating unboxed plain objects")
        || !op.addBoolOption('\0', "unboxed-arrays", "Allow creating unboxed arrays")
        || !op.addStringOption('\0', "ion-shared-stubs", "on/off",
                               "Use shared stubs (default: off, on to enable)")
        || !op.addStringOption('\0', "ion-scalar-replacement", "on/off",
                               "Scalar Replacement (default: on, off to disable)")
        || !op.addStringOption('\0', "ion-gvn", "[mode]",
                               "Specify Ion global value numbering:\n"
                               "  off: disable GVN\n"
                               "  on:  enable GVN (default)\n")
        || !op.addStringOption('\0', "ion-licm", "on/off",
                               "Loop invariant code motion (default: on, off to disable)")
        || !op.addStringOption('\0', "ion-edgecase-analysis", "on/off",
                               "Find edge cases where Ion can avoid bailouts (default: on, off to disable)")
        || !op.addStringOption('\0', "ion-pgo", "on/off",
                               "Profile guided optimization (default: off, on to enable)")
        || !op.addStringOption('\0', "ion-range-analysis", "on/off",
                               "Range analysis (default: on, off to disable)")
#if defined(__APPLE__)
        || !op.addStringOption('\0', "ion-sincos", "on/off",
                               "Replace sin(x)/cos(x) to sincos(x) (default: on, off to disable)")
#else
        || !op.addStringOption('\0', "ion-sincos", "on/off",
                               "Replace sin(x)/cos(x) to sincos(x) (default: off, on to enable)")
#endif
        || !op.addStringOption('\0', "ion-sink", "on/off",
                               "Sink code motion (default: off, on to enable)")
        || !op.addStringOption('\0', "ion-loop-unrolling", "on/off",
                               "Loop unrolling (default: off, on to enable)")
        || !op.addStringOption('\0', "ion-instruction-reordering", "on/off",
                               "Instruction reordering (default: off, on to enable)")
        || !op.addBoolOption('\0', "ion-check-range-analysis",
                               "Range analysis checking")
        || !op.addBoolOption('\0', "ion-extra-checks",
                               "Perform extra dynamic validation checks")
        || !op.addStringOption('\0', "ion-inlining", "on/off",
                               "Inline methods where possible (default: on, off to disable)")
        || !op.addStringOption('\0', "ion-osr", "on/off",
                               "On-Stack Replacement (default: on, off to disable)")
        || !op.addStringOption('\0', "ion-limit-script-size", "on/off",
                               "Don't compile very large scripts (default: on, off to disable)")
        || !op.addIntOption('\0', "ion-warmup-threshold", "COUNT",
                            "Wait for COUNT calls or iterations before compiling "
                            "(default: 1000)", -1)
        || !op.addStringOption('\0', "ion-regalloc", "[mode]",
                               "Specify Ion register allocation:\n"
                               "  backtracking: Priority based backtracking register allocation (default)\n"
                               "  testbed: Backtracking allocator with experimental features\n"
                               "  stupid: Simple block local register allocation")
        || !op.addBoolOption('\0', "ion-eager", "Always ion-compile methods (implies --baseline-eager)")
        || !op.addStringOption('\0', "ion-offthread-compile", "on/off",
                               "Compile scripts off thread (default: on)")
        || !op.addStringOption('\0', "ion-parallel-compile", "on/off",
                               "--ion-parallel compile is deprecated. Use --ion-offthread-compile.")
        || !op.addBoolOption('\0', "baseline", "Enable baseline compiler (default)")
        || !op.addBoolOption('\0', "no-baseline", "Disable baseline compiler")
        || !op.addBoolOption('\0', "baseline-eager", "Always baseline-compile methods")
        || !op.addIntOption('\0', "baseline-warmup-threshold", "COUNT",
                            "Wait for COUNT calls or iterations before baseline-compiling "
                            "(default: 10)", -1)
        || !op.addBoolOption('\0', "non-writable-jitcode", "Allocate JIT code as non-writable memory.")
        || !op.addBoolOption('\0', "no-fpu", "Pretend CPU does not support floating-point operations "
                             "to test JIT codegen (no-op on platforms other than x86).")
        || !op.addBoolOption('\0', "no-sse3", "Pretend CPU does not support SSE3 instructions and above "
                             "to test JIT codegen (no-op on platforms other than x86 and x64).")
        || !op.addBoolOption('\0', "no-sse4", "Pretend CPU does not support SSE4 instructions"
                             "to test JIT codegen (no-op on platforms other than x86 and x64).")
        || !op.addBoolOption('\0', "enable-avx", "AVX is disabled by default. Enable AVX. "
                             "(no-op on platforms other than x86 and x64).")
        || !op.addBoolOption('\0', "no-avx", "No-op. AVX is currently disabled by default.")
        || !op.addBoolOption('\0', "fuzzing-safe", "Don't expose functions that aren't safe for "
                             "fuzzers to call")
        || !op.addBoolOption('\0', "disable-oom-functions", "Disable functions that cause "
                            "artificial OOMs")
        || !op.addBoolOption('\0', "no-threads", "Disable helper threads")
#ifdef DEBUG
        || !op.addBoolOption('\0', "dump-entrained-variables", "Print variables which are "
                             "unnecessarily entrained by inner functions")
#endif
        || !op.addBoolOption('\0', "no-ggc", "Disable Generational GC")
        || !op.addBoolOption('\0', "no-cgc", "Disable Compacting GC")
        || !op.addBoolOption('\0', "no-incremental-gc", "Disable Incremental GC")
        || !op.addIntOption('\0', "available-memory", "SIZE",
                            "Select GC settings based on available memory (MB)", 0)
#if defined(JS_CODEGEN_ARM)
        || !op.addStringOption('\0', "arm-hwcap", "[features]",
                               "Specify ARM code generation features, or 'help' to list all features.")
        || !op.addIntOption('\0', "arm-asm-nop-fill", "SIZE",
                            "Insert the given number of NOP instructions at all possible pool locations.", 0)
        || !op.addIntOption('\0', "asm-pool-max-offset", "OFFSET",
                            "The maximum pc relative OFFSET permitted in pool reference instructions.", 1024)
#endif
#if defined(JS_SIMULATOR_ARM)
        || !op.addBoolOption('\0', "arm-sim-icache-checks", "Enable icache flush checks in the ARM "
                             "simulator.")
        || !op.addIntOption('\0', "arm-sim-stop-at", "NUMBER", "Stop the ARM simulator after the given "
                            "NUMBER of instructions.", -1)
#elif defined(JS_SIMULATOR_MIPS32) || defined(JS_SIMULATOR_MIPS64)
	|| !op.addBoolOption('\0', "mips-sim-icache-checks", "Enable icache flush checks in the MIPS "
                             "simulator.")
        || !op.addIntOption('\0', "mips-sim-stop-at", "NUMBER", "Stop the MIPS simulator after the given "
                            "NUMBER of instructions.", -1)
#endif
        || !op.addIntOption('\0', "nursery-size", "SIZE-MB", "Set the maximum nursery size in MB", 16)
#ifdef JS_GC_ZEAL
        || !op.addStringOption('z', "gc-zeal", "LEVEL[,N]", gc::ZealModeHelpText)
#endif
        || !op.addStringOption('\0', "module-load-path", "DIR", "Set directory to load modules from")
    )
    {
        return EXIT_FAILURE;
    }

    op.setArgTerminatesOptions("script", true);
    op.setArgCapturesRest("scriptArgs");

    switch (op.parseArgs(argc, argv)) {
      case OptionParser::EarlyExit:
        return EXIT_SUCCESS;
      case OptionParser::ParseError:
        op.printHelp(argv[0]);
        return EXIT_FAILURE;
      case OptionParser::Fail:
        return EXIT_FAILURE;
      case OptionParser::Okay:
        break;
    }

    if (op.getHelpOption())
        return EXIT_SUCCESS;

#ifdef DEBUG
    /*
     * Process OOM options as early as possible so that we can observe as many
     * allocations as possible.
     */
    OOM_printAllocationCount = op.getBoolOption('O');
#endif

    if (op.getBoolOption("non-writable-jitcode")) {
        js::jit::ExecutableAllocator::nonWritableJitCode = true;
        PropagateFlagToNestedShells("--non-writable-jitcode");
    }

#ifdef JS_CODEGEN_X86
    if (op.getBoolOption("no-fpu"))
        js::jit::CPUInfo::SetFloatingPointDisabled();
#endif

#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
    if (op.getBoolOption("no-sse3")) {
        js::jit::CPUInfo::SetSSE3Disabled();
        PropagateFlagToNestedShells("--no-sse3");
    }
    if (op.getBoolOption("no-sse4")) {
        js::jit::CPUInfo::SetSSE4Disabled();
        PropagateFlagToNestedShells("--no-sse4");
    }
    if (op.getBoolOption("enable-avx")) {
        js::jit::CPUInfo::SetAVXEnabled();
        PropagateFlagToNestedShells("--enable-avx");
    }
#endif

    if (op.getBoolOption("no-threads"))
        js::DisableExtraThreads();

    // Start the engine.
    if (!JS_Init())
        return 1;

    if (!InitSharedArrayBufferMailbox())
        return 1;

    // The fake thread count must be set before initializing the Runtime,
    // which spins up the thread pool.
    int32_t threadCount = op.getIntOption("thread-count");
    if (threadCount >= 0)
        SetFakeCPUCount(threadCount);

    size_t nurseryBytes = JS::DefaultNurseryBytes;
    nurseryBytes = op.getIntOption("nursery-size") * 1024L * 1024L;

    /* Use the same parameters as the browser in xpcjsruntime.cpp. */
    rt = JS_NewRuntime(JS::DefaultHeapMaxBytes, nurseryBytes);
    if (!rt)
        return 1;

    mozilla::UniquePtr<ShellRuntime> sr = MakeUnique<ShellRuntime>();
    if (!sr)
        return 1;

    JS_SetRuntimePrivate(rt, sr.get());
    JS_SetErrorReporter(rt, my_ErrorReporter);
    JS::SetOutOfMemoryCallback(rt, my_OOMCallback, nullptr);
    if (!SetRuntimeOptions(rt, op))
        return 1;

    sr->interruptFunc.init(rt, NullValue());
    sr->lastWarning.init(rt, NullValue());

    JS_SetGCParameter(rt, JSGC_MAX_BYTES, 0xffffffff);

    size_t availMem = op.getIntOption("available-memory");
    if (availMem > 0)
        JS_SetGCParametersBasedOnAvailableMemory(rt, 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);

#if !defined(STARBOARD)
    JS::dbg::SetDebuggerMallocSizeOf(rt, moz_malloc_size_of);
#endif

    if (!offThreadState.init())
        return 1;

    if (!InitWatchdog(rt))
        return 1;

    cx = NewContext(rt);
    if (!cx)
        return 1;

    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 (!op.getBoolOption("no-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);

#ifdef DEBUG
    if (OOM_printAllocationCount)
        printf("OOM max count: %u\n", OOM_counter);
#endif

    JS::SetLargeAllocationFailureCallback(rt, nullptr, nullptr);

    DestroyContext(cx, true);

    KillWatchdog(rt);

    MOZ_ASSERT_IF(!CanUseExtraThreads(), workerThreads.empty());
    for (size_t i = 0; i < workerThreads.length(); i++)
        PR_JoinThread(workerThreads[i]);

    DestructSharedArrayBufferMailbox();

    JS_DestroyRuntime(rt);
    JS_ShutDown();
    return result;
}
