/* -*- 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)

#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;
static char gZealStr[128];
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

    if (cobalt::configuration::Configuration::GetInstance()->CobaltGcZeal()) {
      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;
      }
    }

    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;

    if (cobalt::configuration::Configuration::GetInstance()->CobaltGcZeal()) {
      if (*gZealStr)
        rt->gc.parseAndSetZeal(gZealStr);
    }

    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) ||
        (cobalt::configuration::Configuration::GetInstance()->CobaltGcZeal() &&
         !op.addStringOption('z', "gc-zeal", "LEVEL[,N]",
                             gc::ZealModeHelpText)) ||
        !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;
}
