/*
 * Copyright (C) 2007-2022 Apple Inc. All rights reserved.
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

@globalPrivate
function createObjectWithoutPrototype(/* key1, value1, key2, value2, ... */)
{
    if (arguments.length % 2 !== 0)
        @throwRangeError("`createObjectWithoutPrototype` requires that each key argument be followed by a value, resulting in an even number of arguments.");

    let object = @Object.@create(null)
    for (let i = 0; i < arguments.length; i += 2)
        object[arguments[i]] = arguments[i + 1];

    return object;
}

@globalPrivate
function createArrayWithoutPrototype(/* value1, value2, ... */)
{
    let array = new @Array(arguments.length);
    array.__proto__ = null;
    
    for (let i = 0; i < arguments.length; ++i)
        @arrayPush(array, arguments[i]);
    
    return array;
}

@globalPrivate
function createInspectorInjectedScript(InjectedScriptHost, inspectedGlobalObject, injectedScriptId)
{

function toString(obj)
{
    return @String(obj);
}

function toStringDescription(obj)
{
    if (obj === 0 && 1 / obj < 0)
        return "-0";

    if (isBigInt(obj))
        return toString(obj) + "n";

    return toString(obj);
}

function isUInt32(obj)
{
    if (typeof obj === "number")
        return obj >>> 0 === obj && (obj > 0 || 1 / obj > 0);
    return "" + (obj >>> 0) === obj;
}

function isSymbol(value)
{
    return typeof value === "symbol";
}

function isBigInt(value)
{
    return typeof value === "bigint";
}

function isEmptyObject(object)
{
    for (let key in object)
        return false;
    return true;
}

function isDefined(value)
{
    return !!value || InjectedScriptHost.isHTMLAllCollection(value);
}

function isPrimitiveValue(value)
{
    switch (typeof value) {
    case "boolean":
    case "number":
    case "string":
        return true;
    case "undefined":
        return !InjectedScriptHost.isHTMLAllCollection(value);
    default:
        return false;
    }
}
    
function createIterableWithoutPrototypeFromArguments(argumentsObject) {
    let iteratorFunction = argumentsObject.@@iterator;
    return @wrappedIterator(iteratorFunction.@call(argumentsObject));
}

function max(a, b) {
    return a > b ? a : b;
}

// -------

let InjectedScript = class InjectedScript
{
    constructor()
    {
        this._lastBoundObjectId = 1;
        this._idToWrappedObject = @createObjectWithoutPrototype();
        this._idToObjectGroupName = @createObjectWithoutPrototype();
        this._objectGroups = @createObjectWithoutPrototype();
        this._modules = @createObjectWithoutPrototype();
        this._nextSavedResultIndex = 1;
        this._savedResults = @createArrayWithoutPrototype();
    }

    // InjectedScript C++ API

    execute(functionString, objectGroup, includeCommandLineAPI, returnByValue, generatePreview, saveResult, args)
    {
        return this._wrapAndSaveCall(objectGroup, returnByValue, generatePreview, saveResult, () => {
            const isEvalOnCallFrame = false;
            return this._evaluateOn(InjectedScriptHost.evaluateWithScopeExtension, InjectedScriptHost, functionString, isEvalOnCallFrame, includeCommandLineAPI).@apply(@undefined, args);
        });
    }

    evaluate(expression, objectGroup, includeCommandLineAPI, returnByValue, generatePreview, saveResult)
    {
        const isEvalOnCallFrame = false;
        return this._evaluateAndWrap(InjectedScriptHost.evaluateWithScopeExtension, InjectedScriptHost, expression, objectGroup, isEvalOnCallFrame, includeCommandLineAPI, returnByValue, generatePreview, saveResult);
    }

    awaitPromise(promiseObjectId, returnByValue, generatePreview, saveResult, callback)
    {
        let parsedPromiseObjectId = this._parseObjectId(promiseObjectId);
        let promiseObject = this._objectForId(parsedPromiseObjectId);
        let promiseObjectGroupName = this._idToObjectGroupName[parsedPromiseObjectId.id];

        if (!isDefined(promiseObject)) {
            callback("Could not find object with given id");
            return;
        }

        if (!(promiseObject instanceof @Promise)) {
            callback("Object with given id is not a Promise");
            return;
        }

        let resolve = (value) => {
            let returnObject = @createObjectWithoutPrototype(
                "wasThrown", false,
                "result", RemoteObject.create(value, promiseObjectGroupName, returnByValue, generatePreview),
            );

            if (saveResult) {
                this._savedResultIndex = 0;
                this._saveResult(returnObject.result);
                if (this._savedResultIndex)
                    returnObject.savedResultIndex = this._savedResultIndex;
            }

            callback(returnObject);
        };
        let reject = (reason) => {
            callback(this._createThrownValue(reason, promiseObjectGroupName));
        };
        promiseObject.@then(resolve, reject);
    }

    evaluateOnCallFrame(topCallFrame, callFrameId, expression, objectGroup, includeCommandLineAPI, returnByValue, generatePreview, saveResult)
    {
        let callFrame = this._callFrameForId(topCallFrame, callFrameId);
        if (!callFrame)
            return "Could not find call frame with given id";
        const isEvalOnCallFrame = true;
        return this._evaluateAndWrap(callFrame.evaluateWithScopeExtension, callFrame, expression, objectGroup, isEvalOnCallFrame, includeCommandLineAPI, returnByValue, generatePreview, saveResult);
    }

    callFunctionOn(objectId, expression, args, returnByValue, generatePreview)
    {
        let parsedObjectId = this._parseObjectId(objectId);
        let object = this._objectForId(parsedObjectId);
        let objectGroupName = this._idToObjectGroupName[parsedObjectId.id];

        if (!isDefined(object))
            return "Could not find object with given id";

        let resolvedArgs = @createArrayWithoutPrototype();
        if (args) {
            let callArgs = InjectedScriptHost.evaluate(args);
            for (let i = 0; i < callArgs.length; ++i) {
                try {
                    resolvedArgs[i] = this._resolveCallArgument(callArgs[i]);
                } catch (e) {
                    return @String(e);
                }
            }
        }

        try {
            let func = InjectedScriptHost.evaluate("(" + expression + ")");
            if (typeof func !== "function")
                return "Given expression does not evaluate to a function";

            return @createObjectWithoutPrototype(
                "wasThrown", false,
                "result", RemoteObject.create(func.@apply(object, resolvedArgs), objectGroupName, returnByValue, generatePreview),
            );
        } catch (e) {
            return this._createThrownValue(e, objectGroupName);
        }
    }

    getFunctionDetails(objectId)
    {
        let parsedObjectId = this._parseObjectId(objectId);
        let object = this._objectForId(parsedObjectId);
        if (typeof object !== "function")
            return "Cannot resolve function by id.";
        return this.functionDetails(object);
    }

    functionDetails(func)
    {
        let details = InjectedScriptHost.functionDetails(func);
        if (!details)
            return "Cannot resolve function details.";
        return details;
    }

    getPreview(objectId)
    {
        let parsedObjectId = this._parseObjectId(objectId);
        let object = this._objectForId(parsedObjectId);
        return RemoteObject.createObjectPreviewForValue(object, true);
    }

    getProperties(objectId, ownProperties, fetchStart, fetchCount, generatePreview)
    {
        let collectionMode = ownProperties ? InjectedScript.CollectionMode.OwnProperties : InjectedScript.CollectionMode.AllProperties;
        return this._getProperties(objectId, collectionMode, @createObjectWithoutPrototype(
            "fetchStart", fetchStart,
            "fetchCount", fetchCount,
            "generatePreview", generatePreview,
        ));
    }

    getDisplayableProperties(objectId, fetchStart, fetchCount, generatePreview)
    {
        let collectionMode = InjectedScript.CollectionMode.OwnProperties | InjectedScript.CollectionMode.NativeGetterProperties;
        return this._getProperties(objectId, collectionMode, @createObjectWithoutPrototype(
            "fetchStart", fetchStart,
            "fetchCount", fetchCount,
            "generatePreview", generatePreview,
            "nativeGettersAsValues", true,
        ));
    }

    getInternalProperties(objectId, generatePreview)
    {
        let parsedObjectId = this._parseObjectId(objectId);
        let object = this._objectForId(parsedObjectId);
        let objectGroupName = this._idToObjectGroupName[parsedObjectId.id];

        if (!isDefined(object))
            return false;

        if (isSymbol(object))
            return false;

        let descriptors = this._internalPropertyDescriptors(object);
        if (!descriptors)
            return @createArrayWithoutPrototype();

        for (let i = 0; i < descriptors.length; ++i) {
            let descriptor = descriptors[i];
            if ("value" in descriptor)
                descriptor.value = RemoteObject.create(descriptor.value, objectGroupName, false, generatePreview);
        }

        return descriptors;
    }

    getCollectionEntries(objectId, objectGroupName, fetchStart, fetchCount)
    {
        let parsedObjectId = this._parseObjectId(objectId);
        let object = this._objectForId(parsedObjectId);
        objectGroupName = objectGroupName || this._idToObjectGroupName[parsedObjectId.id];

        if (!isDefined(object))
            return;

        if (typeof object !== "object")
            return;

        let entries = this._entries(object, InjectedScriptHost.subtype(object), fetchStart, fetchCount);
        for (let i = 0; i < entries.length; ++i) {
            let entry = entries[i];
            entry.value = RemoteObject.create(entry.value, objectGroupName, false, true);
            if ("key" in entry)
                entry.key = RemoteObject.create(entry.key, objectGroupName, false, true);
        }
        return entries;
    }

    saveResult(callArgumentJSON)
    {
        this._savedResultIndex = 0;

        try {
            let callArgument = InjectedScriptHost.evaluate("(" + callArgumentJSON + ")");
            let value = this._resolveCallArgument(callArgument);
            this._saveResult(value);
        } catch { }

        return this._savedResultIndex;
    }

    wrapCallFrames(callFrame)
    {
        if (!callFrame)
            return false;

        let result = @createArrayWithoutPrototype();
        let depth = 0;
        do {
            @arrayPush(result, new InjectedScript.CallFrameProxy(depth++, callFrame));
            callFrame = callFrame.caller;
        } while (callFrame);
        return result;
    }

    wrapObject(object, groupName, canAccessInspectedGlobalObject, generatePreview)
    {
        if (!canAccessInspectedGlobalObject)
            return this._fallbackWrapper(object);

        return RemoteObject.create(object, groupName, false, generatePreview);
    }

    wrapJSONString(jsonString, groupName, generatePreview)
    {
        try {
            return this.wrapObject(@jsonParse(jsonString), groupName, true, generatePreview);
        } catch {
            return null;
        }
    }

    wrapTable(canAccessInspectedGlobalObject, table, columns)
    {
        if (!canAccessInspectedGlobalObject)
            return this._fallbackWrapper(table);

        // FIXME: Currently columns are ignored. Instead, the frontend filters all
        // properties based on the provided column names and in the provided order.
        // We could filter here to avoid sending very large preview objects.

        let columnNames = null;
        if (typeof columns === "string")
            columns = @createArrayWithoutPrototype(columns);

        if (InjectedScriptHost.subtype(columns) === "array") {
            columnNames = @createArrayWithoutPrototype();
            for (let i = 0; i < columns.length; ++i)
                @arrayPush(columnNames, toString(columns[i]));
        }

        return RemoteObject.create(table, "console", false, true, columnNames);
    }

    previewValue(value)
    {
        return RemoteObject.createObjectPreviewForValue(value, true);
    }

    setEventValue(value)
    {
        this._eventValue = value;
    }

    clearEventValue()
    {
        delete this._eventValue;
    }

    setExceptionValue(value)
    {
        this._exceptionValue = value;
    }

    clearExceptionValue()
    {
        delete this._exceptionValue;
    }

    findObjectById(objectId)
    {
        let parsedObjectId = this._parseObjectId(objectId);
        return this._objectForId(parsedObjectId);
    }

    releaseObject(objectId)
    {
        let parsedObjectId = this._parseObjectId(objectId);
        this._releaseObject(parsedObjectId.id);
    }

    releaseObjectGroup(objectGroupName)
    {
        if (objectGroupName === "console") {
            delete this._lastResult;
            this._nextSavedResultIndex = 1;
            this._savedResults = @createArrayWithoutPrototype();
        }

        let group = this._objectGroups[objectGroupName];
        if (!group)
            return;

        for (let i = 0; i < group.length; i++)
            this._releaseObject(group[i]);

        delete this._objectGroups[objectGroupName];
    }

    createCommandLineAPIObject(callFrame)
    {
        return new CommandLineAPI(callFrame || null);
    }

    // CommandLineAPI

    inspectObject(object)
    {
        if (this._inspectObject)
            this._inspectObject(object);
    }

    // InjectedScriptModule C++ API

    hasInjectedModule(name)
    {
        return this._modules[name];
    }

    injectModule(name, moduleFunction, host)
    {
        this._modules[name] = false;

        if (typeof moduleFunction !== "function")
            throw "Error: Web Inspector: a function was expected for injectModule";
        moduleFunction(InjectedScriptHost, inspectedGlobalObject, injectedScriptId, this, @createObjectWithoutPrototype(
            "RemoteObject", RemoteObject,
            "CommandLineAPI", CommandLineAPI,
        ), host);

        this._modules[name] = true;
    }

    // InjectedScriptModule JavaScript API

    isPrimitiveValue(value)
    {
        return isPrimitiveValue(value);
    }

    // Private

    _parseObjectId(objectId)
    {
        return InjectedScriptHost.evaluate("(" + objectId + ")");
    }

    _objectForId(objectId)
    {
        return this._idToWrappedObject[objectId.id];
    }

    _bind(object, objectGroupName)
    {
        let id = this._lastBoundObjectId++;
        let objectId = `{"injectedScriptId":${injectedScriptId},"id":${id}}`;

        this._idToWrappedObject[id] = object;

        if (objectGroupName) {
            let group = this._objectGroups[objectGroupName];
            if (!group) {
                group = @createArrayWithoutPrototype();
                this._objectGroups[objectGroupName] = group;
            }
            @arrayPush(group, id);
            this._idToObjectGroupName[id] = objectGroupName;
        }

        return objectId;
    }

    _releaseObject(id)
    {
        delete this._idToWrappedObject[id];
        delete this._idToObjectGroupName[id];
    }

    _fallbackWrapper(object)
    {
        let result = @createObjectWithoutPrototype("type", typeof object);
        if (isPrimitiveValue(object))
            result.value = object;
        else
            result.description = toStringDescription(object);
        return result;
    }

    _resolveCallArgument(callArgumentJSON)
    {
        if ("value" in callArgumentJSON)
            return callArgumentJSON.value;

        let objectId = callArgumentJSON.objectId;
        if (objectId) {
            let parsedArgId = this._parseObjectId(objectId);
            if (!parsedArgId || parsedArgId["injectedScriptId"] !== injectedScriptId)
                throw "Arguments should belong to the same JavaScript world as the target object.";

            let resolvedArg = this._objectForId(parsedArgId);
            if (!isDefined(resolvedArg))
                throw "Could not find object with given id";

            return resolvedArg;
        }

        return @undefined;
    }

    _createThrownValue(value, objectGroup)
    {
        let remoteObject = RemoteObject.create(value, objectGroup);
        try {
            remoteObject.description = toStringDescription(value);
        } catch { }
        return @createObjectWithoutPrototype(
            "wasThrown", true,
            "result", remoteObject,
        );
    }

    _evaluateAndWrap(evalFunction, object, expression, objectGroup, isEvalOnCallFrame, includeCommandLineAPI, returnByValue, generatePreview, saveResult)
    {
        return this._wrapAndSaveCall(objectGroup, returnByValue, generatePreview, saveResult, () => {
            return this._evaluateOn(evalFunction, object, expression, isEvalOnCallFrame, includeCommandLineAPI);
        });
    }

    _wrapAndSaveCall(objectGroup, returnByValue, generatePreview, saveResult, func)
    {
        return this._wrapCall(objectGroup, returnByValue, generatePreview, saveResult, () => {
            let result = func();
            if (saveResult)
                this._saveResult(result);
            return result;
        });
    }

    _wrapCall(objectGroup, returnByValue, generatePreview, saveResult, func)
    {
        try {
            this._savedResultIndex = 0;

            let returnObject = @createObjectWithoutPrototype(
                "wasThrown", false,
                "result", RemoteObject.create(func(), objectGroup, returnByValue, generatePreview),
            );

            if (saveResult && this._savedResultIndex)
                returnObject.savedResultIndex = this._savedResultIndex;

            return returnObject;
        } catch (e) {
            return this._createThrownValue(e, objectGroup);
        }
    }

    _evaluateOn(evalFunction, object, expression, isEvalOnCallFrame, includeCommandLineAPI)
    {
        let commandLineAPI = null;
        if (includeCommandLineAPI)
            commandLineAPI = this.createCommandLineAPIObject(isEvalOnCallFrame ? object : null);
        return evalFunction.@call(object, expression, commandLineAPI);
    }

    _callFrameForId(topCallFrame, callFrameId)
    {
        let parsedCallFrameId = InjectedScriptHost.evaluate("(" + callFrameId + ")");
        let ordinal = parsedCallFrameId["ordinal"];
        let callFrame = topCallFrame;
        while (--ordinal >= 0 && callFrame)
            callFrame = callFrame.caller;
        return callFrame;
    }

    _getProperties(objectId, collectionMode, {fetchStart, fetchCount, generatePreview, nativeGettersAsValues})
    {
        let parsedObjectId = this._parseObjectId(objectId);
        let object = this._objectForId(parsedObjectId);
        let objectGroupName = this._idToObjectGroupName[parsedObjectId.id];

        if (!isDefined(object))
            return false;

        if (isSymbol(object))
            return false;

        let start = fetchStart || 0;
        if (start < 0)
            start = 0;

        let count = fetchCount || 0;
        if (count < 0)
            count = 0;

        // Always include __proto__ at the end, but only for the first fetch.
        let includeProto = !start;

        let descriptors = @createArrayWithoutPrototype();
        this._forEachPropertyDescriptor(object, collectionMode, (descriptor) => {
            if (start > 0) {
                --start;
                return InjectedScript.PropertyFetchAction.Continue;
            }

            if ("get" in descriptor)
                descriptor.get = RemoteObject.create(descriptor.get, objectGroupName);
            if ("set" in descriptor)
                descriptor.set = RemoteObject.create(descriptor.set, objectGroupName);
            if ("value" in descriptor)
                descriptor.value = RemoteObject.create(descriptor.value, objectGroupName, false, generatePreview);
            if ("symbol" in descriptor)
                descriptor.symbol = RemoteObject.create(descriptor.symbol, objectGroupName);
            @arrayPush(descriptors, descriptor);

            if (includeProto && count && descriptors.length >= count && descriptor.name !== "__proto__")
                return InjectedScript.PropertyFetchAction.Stop;

            return (count && descriptors.length >= count) ? InjectedScript.PropertyFetchAction.Stop : InjectedScript.PropertyFetchAction.Continue;
        }, @createObjectWithoutPrototype(
            "nativeGettersAsValues", nativeGettersAsValues,
            "includeProto", includeProto,
        ));
        return descriptors;
    }

    _internalPropertyDescriptors(object, completeDescriptor)
    {
        let internalProperties = InjectedScriptHost.getInternalProperties(object);
        if (!internalProperties)
            return null;

        let descriptors = @createArrayWithoutPrototype();
        for (let i = 0; i < internalProperties.length; i++) {
            let property = internalProperties[i];
            let descriptor = @createObjectWithoutPrototype(
                "name", property.name,
                "value", property.value,
            );
            if (completeDescriptor)
                descriptor.isOwn = true;
            @arrayPush(descriptors, descriptor);
        }
        return descriptors;
    }

    _forEachPropertyDescriptor(object, collectionMode, callback, {nativeGettersAsValues, includeProto})
    {
        if (InjectedScriptHost.subtype(object) === "proxy")
            return;

        let nameProcessed = new @Set;

        // Handled below when `includeProto`.
        nameProcessed.@add("__proto__");

        function createFakeValueDescriptor(name, symbol, descriptor, isOwnProperty, possibleNativeBindingGetter)
        {
            try {
                let fakeDescriptor = @createObjectWithoutPrototype(
                    "name", name,
                    "value", object[name],
                );
                if (descriptor) {
                    if (descriptor.writable)
                        fakeDescriptor.writable = true;
                    if (descriptor.configurable)
                        fakeDescriptor.configurable = true;
                    if (descriptor.enumerable)
                        fakeDescriptor.enumerable = true;
                }
                if (possibleNativeBindingGetter)
                    fakeDescriptor.nativeGetter = true;
                if (isOwnProperty)
                    fakeDescriptor.isOwn = true;
                if (symbol)
                    fakeDescriptor.symbol = symbol;
                // Silence any possible unhandledrejection exceptions created from accessing a native accessor with a wrong this object.
                if (fakeDescriptor.value instanceof @Promise && InjectedScriptHost.isPromiseRejectedWithNativeGetterTypeError(fakeDescriptor.value))
                    fakeDescriptor.value.@catch(function(){});
                return fakeDescriptor;
            } catch (e) {
                let errorDescriptor = @createObjectWithoutPrototype(
                    "name", name,
                    "value", e,
                    "wasThrown", true,
                );
                if (isOwnProperty)
                    errorDescriptor.isOwn = true;
                if (symbol)
                    errorDescriptor.symbol = symbol;
                return errorDescriptor;
            }
        }

        function processDescriptor(descriptor, isOwnProperty, possibleNativeBindingGetter)
        {
            // All properties.
            if (collectionMode & InjectedScript.CollectionMode.AllProperties)
                return callback(descriptor);

            // Own properties.
            if (collectionMode & InjectedScript.CollectionMode.OwnProperties && isOwnProperty)
                return callback(descriptor);

            // Native Getter properties.
            if (collectionMode & InjectedScript.CollectionMode.NativeGetterProperties) {
                if (possibleNativeBindingGetter)
                    return callback(descriptor);
            }
        }

        function processProperty(o, propertyName, isOwnProperty)
        {
            if (nameProcessed.@has(propertyName))
                return InjectedScript.PropertyFetchAction.Continue;

            nameProcessed.@add(propertyName);

            let name = toString(propertyName);
            let symbol = isSymbol(propertyName) ? propertyName : null;

            let descriptor = @Object.@getOwnPropertyDescriptor(o, propertyName);
            if (!descriptor) {
                // FIXME: Bad descriptor. Can we get here?
                // Fall back to very restrictive settings.
                let fakeDescriptor = createFakeValueDescriptor(name, symbol, descriptor, isOwnProperty);
                return processDescriptor(fakeDescriptor, isOwnProperty);
            }

            if (nativeGettersAsValues) {
                if (@String(descriptor.get).@endsWith("[native code]\n}") || (!descriptor.get && @Object.@hasOwn(descriptor, "get") && !descriptor.set && @Object.@hasOwn(descriptor, "set"))) {
                    // Developers may create such a descriptor, so we should be resilient:
                    // let x = {}; Object.defineProperty(x, "p", {get:undefined}); Object.getOwnPropertyDescriptor(x, "p")
                    let fakeDescriptor = createFakeValueDescriptor(name, symbol, descriptor, isOwnProperty, true);
                    return processDescriptor(fakeDescriptor, isOwnProperty, true);
                }
            }

            descriptor.name = name;
            if (isOwnProperty)
                descriptor.isOwn = true;
            if (symbol)
                descriptor.symbol = symbol;
            return processDescriptor(descriptor, isOwnProperty);
        }

        let isArrayLike = false;
        try {
            isArrayLike = RemoteObject.subtype(object) === "array" && @isFinite(object.length) && object.length > 0;
        } catch { }

        for (let o = object; isDefined(o); o = @Object.@getPrototypeOf(o)) {
            let isOwnProperty = o === object;
            let shouldBreak = false;

            // FIXME: <https://webkit.org/b/201861> Web Inspector: show autocomplete entries for non-index properties on arrays
            if (isArrayLike && isOwnProperty) {
                for (let i = 0; i < o.length; ++i) {
                    if (!(i in o))
                        continue;

                    let result = processProperty(o, toString(i), isOwnProperty);
                    shouldBreak = result === InjectedScript.PropertyFetchAction.Stop;
                    if (shouldBreak)
                        break;
                }
            } else {
                let propertyNames = @Object.@getOwnPropertyNames(o);
                for (let i = 0; i < propertyNames.length; ++i) {
                    let result = processProperty(o, propertyNames[i], isOwnProperty);
                    shouldBreak = result === InjectedScript.PropertyFetchAction.Stop;
                    if (shouldBreak)
                        break;
                }
            }

            if (shouldBreak)
                break;

            let propertySymbols = @Object.@getOwnPropertySymbols(o);
            for (let i = 0; i < propertySymbols.length; ++i) {
                let result = processProperty(o, propertySymbols[i], isOwnProperty);
                shouldBreak = result === InjectedScript.PropertyFetchAction.Stop;
                if (shouldBreak)
                    break;
            }

            if (shouldBreak)
                break;

            if (collectionMode === InjectedScript.CollectionMode.OwnProperties)
                break;
        }

        if (includeProto) {
            try {
                if (object.__proto__)
                    callback(@createObjectWithoutPrototype(
                        "name", "__proto__",
                        "value", object.__proto__,
                        "writable", true,
                        "configurable", true,
                        "isOwn", true,
                    ));
            } catch { }
        }
    }

    _getSetEntries(object, fetchStart, fetchCount)
    {
        let entries = @createArrayWithoutPrototype();

        for (let value of @builtinSetIterable(object)) {
            if (fetchStart > 0) {
                fetchStart--;
                continue;
            }

            @arrayPush(entries, @createObjectWithoutPrototype("value", value));

            if (fetchCount && entries.length === fetchCount)
                break;
        }

        return entries;
    }

    _getMapEntries(object, fetchStart, fetchCount)
    {
        let entries = @createArrayWithoutPrototype();

        for (let [key, value] of @builtinMapIterable(object)) {
            if (fetchStart > 0) {
                fetchStart--;
                continue;
            }

            @arrayPush(entries, @createObjectWithoutPrototype(
                "key", key,
                "value", value,
            ));

            if (fetchCount && entries.length === fetchCount)
                break;
        }

        return entries;
    }

    _getWeakMapEntries(object, fetchCount)
    {
        return InjectedScriptHost.weakMapEntries(object, fetchCount);
    }

    _getWeakSetEntries(object, fetchCount)
    {
        return InjectedScriptHost.weakSetEntries(object, fetchCount);
    }

    _getIteratorEntries(object, fetchCount)
    {
        return InjectedScriptHost.iteratorEntries(object, fetchCount);
    }

    _entries(object, subtype, fetchStart, fetchCount)
    {
        if (subtype === "set")
            return this._getSetEntries(object, fetchStart, fetchCount);
        if (subtype === "map")
            return this._getMapEntries(object, fetchStart, fetchCount);
        if (subtype === "weakmap")
            return this._getWeakMapEntries(object, fetchCount);
        if (subtype === "weakset")
            return this._getWeakSetEntries(object, fetchCount);
        if (subtype === "iterator")
            return this._getIteratorEntries(object, fetchCount);

        throw "unexpected type";
    }

    _saveResult(result)
    {
        this._lastResult = result;

        if (result === @undefined || result === null)
            return;

        let existingIndex = @Array.prototype.@indexOf.@call(this._savedResults, result);
        if (existingIndex !== -1) {
            this._savedResultIndex = existingIndex;
            return;
        }

        this._savedResultIndex = this._nextSavedResultIndex;
        this._savedResults[this._nextSavedResultIndex++] = result;

        // $n is limited from $1-$99. $0 is special.
        if (this._nextSavedResultIndex >= 100)
            this._nextSavedResultIndex = 1;
    }
};

InjectedScript.CollectionMode = @createObjectWithoutPrototype(
    "OwnProperties", 1 << 0,          // own properties.
    "NativeGetterProperties", 1 << 1, // native getter properties in the prototype chain.
    "AllProperties", 1 << 2,          // all properties in the prototype chain.
);

InjectedScript.PropertyFetchAction = @createObjectWithoutPrototype(
    "Continue", @createPrivateSymbol("continue"),
    "Stop", @createPrivateSymbol("stop"),
);

var injectedScript = new InjectedScript;

// -------

let RemoteObject = class RemoteObject
{
    constructor(object, objectGroupName, forceValueType, generatePreview, columnNames)
    {
        this.type = typeof object;

        if (this.type === "undefined" && InjectedScriptHost.isHTMLAllCollection(object))
            this.type = "object";

        if (isPrimitiveValue(object) || isBigInt(object) || object === null || forceValueType) {
            // We don't send undefined values over JSON.
            // BigInt values are not JSON serializable.
            if (this.type !== "undefined" && this.type !== "bigint")
                this.value = object;

            // Null object is object with 'null' subtype.
            if (object === null)
                this.subtype = "null";

            // Provide user-friendly number values.
            if (this.type === "number" || this.type === "bigint")
                this.description = toStringDescription(object);

            return;
        }

        this.objectId = injectedScript._bind(object, objectGroupName);

        let subtype = RemoteObject.subtype(object);
        if (subtype)
            this.subtype = subtype;

        this.className = InjectedScriptHost.internalConstructorName(object);
        this.description = RemoteObject.describe(object);

        if (subtype === "array")
            this.size = typeof object.length === "number" ? object.length : 0;
        else if (subtype === "set" || subtype === "map")
            this.size = object.size;
        else if (subtype === "weakmap")
            this.size = InjectedScriptHost.weakMapSize(object);
        else if (subtype === "weakset")
            this.size = InjectedScriptHost.weakSetSize(object);
        else if (subtype === "class") {
            this.classPrototype = RemoteObject.create(object.prototype, objectGroupName);
            this.className = object.name;
        }

        if (generatePreview && this.type === "object") {
            if (subtype === "proxy") {
                this.preview = this._generatePreview(InjectedScriptHost.proxyTargetValue(object));
                this.preview.lossless = false;
            } else
                this.preview = this._generatePreview(object, @undefined, columnNames);
        }
    }

    // Static

    static create(object, objectGroupName, forceValueType, generatePreview, columnNames)
    {
        try {
            return new RemoteObject(object, objectGroupName, forceValueType, generatePreview, columnNames);
        } catch (e) {
            let description;
            try {
                description = RemoteObject.describe(e);
            } catch (ex) {
                inspectedGlobalObject.console.error(ex.message);
                description = "<failed to convert exception to string>";
            }
            return new RemoteObject(description);
        }
    }

    static createObjectPreviewForValue(value, generatePreview, columnNames)
    {
        let remoteObject = new RemoteObject(value, @undefined, false, generatePreview, columnNames);
        if (remoteObject.objectId)
            injectedScript.releaseObject(remoteObject.objectId);
        if (remoteObject.classPrototype && remoteObject.classPrototype.objectId)
            injectedScript.releaseObject(remoteObject.classPrototype.objectId);
        return remoteObject.preview || remoteObject._emptyPreview();
    }

    static subtype(value)
    {
        if (value === null)
            return "null";

        if (isPrimitiveValue(value) || isBigInt(value) || isSymbol(value))
            return null;

        if (InjectedScriptHost.isHTMLAllCollection(value))
            return "array";

        let preciseType = InjectedScriptHost.subtype(value);
        if (preciseType)
            return preciseType;

        // FireBug's array detection.
        try {
            if (typeof value.splice === "function" && @isFinite(value.length))
                return "array";
        } catch { }

        return null;
    }

    static describe(value)
    {
        if (isPrimitiveValue(value))
            return null;

        if (isBigInt(value))
            return null;

        if (isSymbol(value))
            return toString(value);

        let subtype = RemoteObject.subtype(value);

        if (subtype === "regexp")
            return toString(value);

        if (subtype === "date")
            return toString(value);

        if (subtype === "error")
            return toString(value);

        if (subtype === "proxy")
            return "Proxy";

        if (subtype === "node")
            return RemoteObject.nodePreview(value);

        let className = InjectedScriptHost.internalConstructorName(value);
        if (subtype === "array")
            return className;

        if (subtype === "iterator" && @@toStringTag in value)
            return value.@@toStringTag;

        // NodeList in JSC is a function, check for array prior to this.
        if (typeof value === "function")
            return value.toString();

        // If Object, try for a better name from the constructor.
        if (className === "Object") {
            let constructorName = value.constructor && value.constructor.name;
            if (constructorName)
                return constructorName;
        }

        return className;
    }

    static nodePreview(node)
    {
        // FIXME: <webkit.org/b/239774> Injected script should use WebCore built-ins.
        let isXMLDocument = node.ownerDocument && !!node.ownerDocument.xmlVersion;
        let nodeName = isXMLDocument ? node.nodeName : node.nodeName.toLowerCase();

        switch (node.nodeType) {
        case 1: // Node.ELEMENT_NODE
            if (node.id)
                return "<" + nodeName + " id=\"" + node.id + "\">";
            if (node.classList.length)
                return "<" + nodeName + " class=\"" + node.classList.toString().replace(/\s+/, " ") + "\">";
            if (nodeName === "input" && node.type)
                return "<" + nodeName + " type=\"" + node.type + "\">";
            return "<" + nodeName + ">";

        case 3: // Node.TEXT_NODE
            return nodeName + " \"" + node.nodeValue + "\"";

        case 8: // Node.COMMENT_NODE
            return "<!--" + node.nodeValue + "-->";

        case 10: // Node.DOCUMENT_TYPE_NODE
            return "<!DOCTYPE " + nodeName + ">";

        default:
            return nodeName;
        }
    }

    // Private

    _initialPreview()
    {
        let preview = @createObjectWithoutPrototype(
            "type", this.type,
            "description", this.description || toString(this.value),
            "lossless", true,
        );

        if (this.subtype) {
            preview.subtype = this.subtype;
            if (this.subtype !== "null") {
                preview.overflow = false;
                preview.properties = @createArrayWithoutPrototype();
            }
        }

        if ("size" in this)
            preview.size = this.size;

        return preview;
    }

    _emptyPreview()
    {
        let preview = this._initialPreview();

        if (this.subtype === "map" || this.subtype === "set" || this.subtype === "weakmap" || this.subtype === "weakset" || this.subtype === "iterator") {
            if (this.size) {
                preview.entries = @createArrayWithoutPrototype();
                preview.lossless = false;
                preview.overflow = true;
            }
        }

        return preview;
    }

    _generatePreview(object, firstLevelKeys, secondLevelKeys)
    {
        let preview = this._initialPreview();
        let isTableRowsRequest = secondLevelKeys === null || secondLevelKeys;
        let firstLevelKeysCount = firstLevelKeys ? firstLevelKeys.length : 0;

        let propertiesThreshold = @createObjectWithoutPrototype(
            "properties", isTableRowsRequest ? 1000 : max(5, firstLevelKeysCount),
            "indexes", isTableRowsRequest ? 1000 : max(10, firstLevelKeysCount),
        );

        try {
            // Maps, Sets, and Iterators have entries.
            if (this.subtype === "map" || this.subtype === "set" || this.subtype === "weakmap" || this.subtype === "weakset" || this.subtype === "iterator")
                this._appendEntryPreviews(object, preview);

            preview.properties = @createArrayWithoutPrototype();

            // Internal Properties.
            let internalPropertyDescriptors = injectedScript._internalPropertyDescriptors(object, true);
            if (internalPropertyDescriptors) {
                for (let i = 0; i < internalPropertyDescriptors.length; ++i) {
                    let result = this._appendPropertyPreview(object, preview, internalPropertyDescriptors[i], propertiesThreshold, firstLevelKeys, secondLevelKeys, @createObjectWithoutPrototype("internal", true));
                    if (result === InjectedScript.PropertyFetchAction.Stop)
                        return preview;
                }
            }

            if (preview.entries)
                return preview;

            // Properties.
            injectedScript._forEachPropertyDescriptor(object, InjectedScript.CollectionMode.AllProperties, (descriptor) => {
                return this._appendPropertyPreview(object, preview, descriptor, propertiesThreshold, firstLevelKeys, secondLevelKeys);
            }, @createObjectWithoutPrototype(
                "nativeGettersAsValues", true,
                "includeProto", true,
            ));
        } catch {
            preview.lossless = false;
        }

        return preview;
    }

    _appendPropertyPreview(object, preview, descriptor, propertiesThreshold, firstLevelKeys, secondLevelKeys, {internal} = @createObjectWithoutPrototype())
    {
        // Error in descriptor.
        if (descriptor.wasThrown) {
            preview.lossless = false;
            return InjectedScript.PropertyFetchAction.Continue;
        }

        // Do not show "__proto__" in preview.
        let name = descriptor.name;
        if (name === "__proto__") {
            // Non basic __proto__ objects may have interesting, non-enumerable, methods to show.
            if (descriptor.value && descriptor.value.constructor
                && descriptor.value.constructor !== @Object
                && descriptor.value.constructor !== @Array
                && descriptor.value.constructor !== @RegExp)
                preview.lossless = false;
            return InjectedScript.PropertyFetchAction.Continue;
        }

        // For arrays, only allow indexes.
        if (this.subtype === "array" && !isUInt32(name))
            return InjectedScript.PropertyFetchAction.Continue;

        // Do not show non-enumerable non-own properties.
        // Special case to allow array indexes that may be on the prototype.
        // Special case to allow native getters on non-RegExp objects.
        if (!descriptor.enumerable && !descriptor.isOwn && !(this.subtype === "array" || (this.subtype !== "regexp" && descriptor.nativeGetter)))
            return InjectedScript.PropertyFetchAction.Continue;

        // If we have a filter, only show properties in the filter.
        // FIXME: Currently these filters do nothing on the backend.
        if (firstLevelKeys && !@Array.prototype.@includes.@call(firstLevelKeys, name))
            return InjectedScript.PropertyFetchAction.Continue;

        function appendPreview(property) {
            if (toString(property.name >>> 0) === property.name)
                propertiesThreshold.indexes--;
            else
                propertiesThreshold.properties--;

            if (propertiesThreshold.indexes < 0 || propertiesThreshold.properties < 0) {
                preview.overflow = true;
                preview.lossless = false;
                return InjectedScript.PropertyFetchAction.Stop;
            }

            if (internal)
                property.internal = true;

            @arrayPush(preview.properties, property);
            return InjectedScript.PropertyFetchAction.Continue;
        }

        // Getter/setter.
        if (!("value" in descriptor)) {
            preview.lossless = false;
            return appendPreview(@createObjectWithoutPrototype(
                "name", name,
                "type", "accessor",
            ));
        }

        // Null value.
        let value = descriptor.value;
        if (value === null)
            return appendPreview(@createObjectWithoutPrototype(
                "name", name,
                "type", "object",
                "subtype", "null",
                "value", "null",
            ));

        // Ignore non-enumerable functions.
        let type = typeof value;
        if (!descriptor.enumerable && type === "function")
            return InjectedScript.PropertyFetchAction.Continue;

        // Fix type of document.all.
        if (InjectedScriptHost.isHTMLAllCollection(value))
            type = "object";

        // Primitive.
        const maxLength = 100;
        if (isPrimitiveValue(value) || isBigInt(value)) {
            if (type === "string" && value.length > maxLength) {
                value = this._abbreviateString(value, maxLength, true);
                preview.lossless = false;
            }
            return appendPreview(@createObjectWithoutPrototype(
                "name", name,
                "type", type,
                "value", toStringDescription(value),
            ));
        }

        // Symbol.
        if (isSymbol(value)) {
            let symbolString = toString(value);
            if (symbolString.length > maxLength) {
                symbolString = this._abbreviateString(symbolString, maxLength, true);
                preview.lossless = false;
            }
            return appendPreview(@createObjectWithoutPrototype(
                "name", name,
                "type", type,
                "value", symbolString,
            ));
        }

        // Object.
        let property = @createObjectWithoutPrototype(
            "name", name,
            "type", type,
        );
        let subtype = RemoteObject.subtype(value);
        if (subtype)
            property.subtype = subtype;

        // Second level.
        if ((secondLevelKeys === null || secondLevelKeys) || this._isPreviewableObject(value, object)) {
            // FIXME: If we want secondLevelKeys filter to continue we would need some refactoring.
            let subPreview = RemoteObject.createObjectPreviewForValue(value, value !== object, secondLevelKeys);
            property.valuePreview = subPreview;
            if (!subPreview.lossless)
                preview.lossless = false;
            if (subPreview.overflow)
                preview.overflow = true;
        } else {
            let description = "";
            if (type !== "function" || subtype === "class") {
                let fullDescription;
                if (subtype === "class")
                    fullDescription = "class " + value.name;
                else if (subtype === "node")
                    fullDescription = RemoteObject.nodePreview(value);
                else
                    fullDescription = RemoteObject.describe(value);
                description = this._abbreviateString(fullDescription, maxLength, subtype === "regexp");
            }
            property.value = description;
            preview.lossless = false;
        }

        return appendPreview(property);
    }

    _appendEntryPreviews(object, preview)
    {
        // Fetch 6, but only return 5, so we can tell if we overflowed.
        let entries = injectedScript._entries(object, this.subtype, 0, 6);
        if (!entries)
            return;

        if (entries.length > 5) {
            @Array.prototype.@pop.@call(entries);
            preview.overflow = true;
            preview.lossless = false;
        }

        function updateMainPreview(subPreview) {
            if (!subPreview.lossless)
                preview.lossless = false;
        }

        preview.entries = @Array.prototype.@map.@call(entries, function(entry) {
            entry.value = RemoteObject.createObjectPreviewForValue(entry.value, entry.value !== object);
            updateMainPreview(entry.value);
            if ("key" in entry) {
                entry.key = RemoteObject.createObjectPreviewForValue(entry.key, entry.key !== object);
                updateMainPreview(entry.key);
            }
            return entry;
        });
    }

    _isPreviewableObject(value, object)
    {
        let set = new @Set;
        set.@add(object);

        return this._isPreviewableObjectInternal(value, set, 1);
    }

    _isPreviewableObjectInternal(object, knownObjects, depth)
    {
        // Deep object.
        if (depth > 3)
            return false;

        // Primitive.
        if (isPrimitiveValue(object) || isBigInt(object) || isSymbol(object))
            return true;

        // Null.
        if (object === null)
            return true;

        // Cyclic objects.
        if (knownObjects.@has(object))
            return false;

        ++depth;
        knownObjects.@add(object);

        // Arrays are simple if they have 5 or less simple objects.
        let subtype = RemoteObject.subtype(object);
        if (subtype === "array") {
            let length = object.length;
            if (length > 5)
                return false;
            for (let i = 0; i < length; ++i) {
                if (!this._isPreviewableObjectInternal(object[i], knownObjects, depth))
                    return false;
            }
            return true;
        }

        // Not a basic object.
        if (object.__proto__ && object.__proto__.__proto__)
            return false;

        // Objects are simple if they have 3 or less simple value properties.
        let ownPropertyNames = @Object.@getOwnPropertyNames(object);
        if (ownPropertyNames.length > 3)
            return false;
        for (let i = 0; i < ownPropertyNames.length; ++i) {
            let propertyName = ownPropertyNames[i];
            let descriptor = @Object.@getOwnPropertyDescriptor(object, propertyName);
            if (descriptor && !("value" in descriptor))
                return false;
            if (!this._isPreviewableObjectInternal(object[propertyName], knownObjects, depth))
                return false;
        }

        return true;
    }

    _abbreviateString(string, maxLength, middle)
    {
        if (string.length <= maxLength)
            return string;

        if (middle) {
            let leftHalf = maxLength >> 1;
            let rightHalf = maxLength - leftHalf - 1;
            return string.@substr(0, leftHalf) + "\u2026" + string.@substr(string.length - rightHalf, rightHalf);
        }

        return string.@substr(0, maxLength) + "\u2026";
    }
};

// -------

InjectedScript.CallFrameProxy = class CallFrameProxy {
    constructor(ordinal, callFrame)
    {
        this.callFrameId = `{"ordinal":${ordinal},"injectedScriptId":${injectedScriptId}}`;
        this.functionName = callFrame.functionName;

        this.location = @createObjectWithoutPrototype(
            "scriptId", @String(callFrame.sourceID),
            "lineNumber", callFrame.line,
            "columnNumber", callFrame.column,
        );

        this.scopeChain = this._wrapScopeChain(callFrame);
        this.this = RemoteObject.create(callFrame.thisObject, "backtrace");
        this.isTailDeleted = callFrame.isTailDeleted;
    }

    _wrapScopeChain(callFrame)
    {
        let scopeChain = callFrame.scopeChain;
        let scopeDescriptions = callFrame.scopeDescriptions();

        let scopeChainProxy = @createArrayWithoutPrototype();
        for (let i = 0; i < scopeChain.length; i++)
            scopeChainProxy[i] = InjectedScript.CallFrameProxy._createScopeJson(scopeChain[i], scopeDescriptions[i], "backtrace");
        return scopeChainProxy;
    }

    static _createScopeJson(object, {name, type, location}, groupId)
    {
        let scope = @createObjectWithoutPrototype(
            "object", RemoteObject.create(object, groupId),
            "type", InjectedScript.CallFrameProxy._scopeTypeNames[type],
        );

        if (name)
            scope.name = name;

        if (location)
            scope.location = location;

        if (isEmptyObject(object))
            scope.empty = true;

        return scope;
    }
};

InjectedScript.CallFrameProxy._scopeTypeNames = @createObjectWithoutPrototype(
    0, "global", // GLOBAL_SCOPE
    1, "with", // WITH_SCOPE
    2, "closure", // CLOSURE_SCOPE
    3, "catch", // CATCH_SCOPE
    4, "functionName", // FUNCTION_NAME_SCOPE
    5, "globalLexicalEnvironment", // GLOBAL_LEXICAL_ENVIRONMENT
    6, "nestedLexical", // NESTED_LEXICAL_SCOPE
);

// -------

function CommandLineAPI(callFrame)
{
    let savedResultAlias = InjectedScriptHost.savedResultAlias;

    let defineGetter = (key, value, wrap) => {
        if (wrap) {
            let originalValue = value;
            value = function() { return originalValue; };
        }

        @Object.@defineProperty(this, "$" + key, @createObjectWithoutPrototype("get", value));
        if (savedResultAlias && savedResultAlias !== "$")
            @Object.@defineProperty(this, savedResultAlias + key, @createObjectWithoutPrototype("get", value));
    };

    if ("_lastResult" in injectedScript)
        defineGetter("_", injectedScript._lastResult, true);

    if ("_exceptionValue" in injectedScript)
        defineGetter("exception", injectedScript._exceptionValue, true);

    if ("_eventValue" in injectedScript)
        defineGetter("event", injectedScript._eventValue, true);

    // $1-$99
    for (let i = 1; i < injectedScript._savedResults.length; ++i)
        defineGetter(i, injectedScript._savedResults[i], true);

    for (let name in CommandLineAPI.getters)
        defineGetter(name, CommandLineAPI.getters[name]);

    for (let name in CommandLineAPI.methods)
        this[name] = CommandLineAPI.methods[name];
}

CommandLineAPI.getters = @createObjectWithoutPrototype();

CommandLineAPI.methods = @createObjectWithoutPrototype();

CommandLineAPI.methods["keys"] = function(object) { return @Object.@keys(object); };
CommandLineAPI.methods["values"] = function(object) { return @Object.@values(object); };

CommandLineAPI.methods["queryInstances"] = function() { return InjectedScriptHost.queryInstances(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["queryObjects"] = function() { return InjectedScriptHost.queryInstances(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["queryHolders"] = function() { return InjectedScriptHost.queryHolders(...createIterableWithoutPrototypeFromArguments(arguments)); };

CommandLineAPI.methods["inspect"] = function(object) { return injectedScript.inspectObject(object); };

CommandLineAPI.methods["assert"] = function() { return inspectedGlobalObject.console.assert(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["clear"] = function() { return inspectedGlobalObject.console.clear(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["count"] = function() { return inspectedGlobalObject.console.count(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["countReset"] = function() { return inspectedGlobalObject.console.countReset(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["debug"] = function() { return inspectedGlobalObject.console.debug(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["dir"] = function() { return inspectedGlobalObject.console.dir(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["dirxml"] = function() { return inspectedGlobalObject.console.dirxml(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["error"] = function() { return inspectedGlobalObject.console.error(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["group"] = function() { return inspectedGlobalObject.console.group(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["groupCollapsed"] = function() { return inspectedGlobalObject.console.groupCollapsed(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["groupEnd"] = function() { return inspectedGlobalObject.console.groupEnd(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["info"] = function() { return inspectedGlobalObject.console.info(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["log"] = function() { return inspectedGlobalObject.console.log(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["profile"] = function() { return inspectedGlobalObject.console.profile(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["profileEnd"] = function() { return inspectedGlobalObject.console.profileEnd(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["record"] = function() { return inspectedGlobalObject.console.record(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["recordEnd"] = function() { return inspectedGlobalObject.console.recordEnd(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["screenshot"] = function() { return inspectedGlobalObject.console.screenshot(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["table"] = function() { return inspectedGlobalObject.console.table(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["takeHeapSnapshot"] = function() { return inspectedGlobalObject.console.takeHeapSnapshot(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["time"] = function() { return inspectedGlobalObject.console.time(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["timeEnd"] = function() { return inspectedGlobalObject.console.timeEnd(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["timeLog"] = function() { return inspectedGlobalObject.console.timeLog(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["timeStamp"] = function() { return inspectedGlobalObject.console.timeStamp(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["trace"] = function() { return inspectedGlobalObject.console.trace(...createIterableWithoutPrototypeFromArguments(arguments)); };
CommandLineAPI.methods["warn"] = function() { return inspectedGlobalObject.console.warn(...createIterableWithoutPrototypeFromArguments(arguments)); };

for (let name in CommandLineAPI.methods)
    CommandLineAPI.methods[name].toString = function() { return "function " + name + "() { [Command Line API] }"; };

return injectedScript;
}
