Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/testing/xpcshell/moz-http2/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 630 B image not shown  

Quelle  utility.js   Sprache: unbekannt

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


/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */

"use strict";

loadRelativeToScript('dumpCFG.js');

// Attribute bits - each call edge may carry a set of 'attrs' bits, saying eg
// that the edge takes place within a scope where GC is suppressed, for
// example.
var ATTR_GC_SUPPRESSED     = 1 << 0;
var ATTR_CANSCRIPT_BOUNDED = 1 << 1; // Unimplemented
var ATTR_DOM_ITERATING     = 1 << 2; // Unimplemented
var ATTR_NONRELEASING      = 1 << 3; // ~RefPtr of value whose refcount will not go to zero
var ATTR_REPLACED          = 1 << 4; // Ignore edge, it was replaced by zero or more better edges.
var ATTR_SYNTHETIC         = 1 << 5; // Call was manufactured in some way.

var ATTR_LAST              = 1 << 5;
var ATTRS_NONE             = 0;
var ATTRS_ALL              = (ATTR_LAST << 1) - 1; // All possible bits set

// The traversal algorithms we run will recurse into children if you change any
// attrs bit to zero. Use all bits set to maximally attributed, including
// additional bits that all just mean "unvisited", so that the first time we
// see a node with this attrs, we're guaranteed to turn at least one bit off
// and thereby keep going.
var ATTRS_UNVISITED = 0xffff;

// gcc appends this to mangled function names for "not in charge"
// constructors/destructors.
var internalMarker = " *INTERNAL* ";

if (! Set.prototype.hasOwnProperty("update")) {
    Object.defineProperty(Set.prototype, "update", {
        value: function (collection) {
            for (let elt of collection)
                this.add(elt);
        }
    });
}

function assert(x, msg)
{
    if (x)
        return;
    debugger;
    if (msg)
        throw new Error("assertion failed: " + msg + "\n");
    else
        throw new Error("assertion failed");
}

function defined(x) {
    return x !== undefined;
}

function xprint(x, padding)
{
    if (!padding)
        padding = "";
    if (x instanceof Array) {
        print(padding + "[");
        for (var elem of x)
            xprint(elem, padding + " ");
        print(padding + "]");
    } else if (x instanceof Object) {
        print(padding + "{");
        for (var prop in x) {
            print(padding + " " + prop + ":");
            xprint(x[prop], padding + " ");
        }
        print(padding + "}");
    } else {
        print(padding + x);
    }
}

// Command-line argument parser.
//
// `parameters` is a dict of parameters specs, each of which is a dict with keys:
//
//   - name: name of option, prefixed with "--" if it is named (otherwise, it
//     is interpreted as a positional parameter.)
//   - dest: key to store the result in, defaulting to the parameter name without
//     any leading "--"" and with dashes replaced with underscores.
//   - default: value of option if no value is given. Positional parameters with
//     a default value are optional. If no default is given, the parameter's name
//     is not included in the return value.
//   - type: `bool` if it takes no argument, otherwise an argument is required.
//     Named arguments default to 'bool', positional arguments to 'string'.
//   - nargs: the only supported value is `+`, which means to grab all following
//     arguments, up to the next named option, and store them as a list.
//
// The command line is parsed for `--foo=value` and `--bar` arguments.
//
// Return value is a dict of parameter values, keyed off of `dest` as determined
// above. An extra option named "rest" will be set to the list of all remaining
// arguments passed in.
//
function parse_options(parameters, inArgs = scriptArgs) {
    const options = {};

    const named = {};
    const positional = [];
    for (const param of parameters) {
        if (param.name.startsWith("-")) {
            named[param.name] = param;
            if (!param.dest) {
                if (!param.name.startsWith("--")) {
                    throw new Error(`parameter '${param.name}' requires param.dest to be set`);
                }
                param.dest = param.name.substring(2).replace("-""_");
            }
        } else {
            if (!('default' in param) && positional.length > 0 && ('default' in positional.at(-1))) {
                throw new Error(`required parameter '${param.name}' follows optional parameter`);
            }
            param.positional = true;
            positional.push(param);
            param.dest = param.dest || param.name.replace("-""_");
        }

        if (!param.type) {
            if (param.nargs === "+") {
                param.type = "list";
            } else if (param.positional) {
                param.type = "string";
            } else {
                param.type = "bool";
            }
        }

        if ('default' in param) {
            options[param.dest] = param.default;
        }
    }

    options.rest = [];
    const args = [...inArgs];
    let grabbing_into = undefined;
    while (args.length > 0) {
        let arg = args.shift();
        let param;
        if (arg.startsWith("-") && arg in named) {
            param = named[arg];
            if (param.type !== 'bool') {
                if (args.length == 0) {
                    throw(new Error(`${param.name} requires an argument`));
                }
                arg = args.shift();
            }
        } else {
            const pos = arg.indexOf("=");
            if (pos != -1) {
                const name = arg.substring(0, pos);
                param = named[name];
                if (!param) {
                    throw(new Error(`Unknown option '${name}'`));
                } else if (param.type === 'bool') {
                    throw(new Error(`--${param.name} does not take an argument`));
                }
                arg = arg.substring(pos + 1);
            }
        }

        // If this isn't a --named param, and we're not accumulating into a nargs="+" param, then
        // use the next positional.
        if (!param && !grabbing_into && positional.length > 0) {
            param = positional.shift();
        }

        // If a parameter was identified, then any old accumulator is done and we might start a new one.
        if (param) {
            if (param.type === 'list') {
                grabbing_into = options[param.dest] = options[param.dest] || [];
            } else {
                grabbing_into = undefined;
            }
        }

        if (grabbing_into) {
            grabbing_into.push(arg);
        } else if (param) {
            if (param.type === 'bool') {
                options[param.dest] = true;
            } else {
                options[param.dest] = arg;
            }
        } else {
            options.rest.push(arg);
        }
    }

    for (const param of positional) {
        if (!('default' in param)) {
            throw(new Error(`'${param.name}' option is required`));
        }
    }

    for (const param of parameters) {
        if (param.nargs === '+' && options[param.dest].length == 0) {
            throw(new Error(`at least one value required for option '${param.name}'`));
        }
    }

    return options;
}

function sameBlockId(id0, id1)
{
    if (id0.Kind != id1.Kind)
        return false;
    if (!sameVariable(id0.Variable, id1.Variable))
        return false;
    if (id0.Kind == "Loop" && id0.Loop != id1.Loop)
        return false;
    return true;
}

function sameVariable(var0, var1)
{
    assert("Name" in var0 || var0.Kind == "This" || var0.Kind == "Return");
    assert("Name" in var1 || var1.Kind == "This" || var1.Kind == "Return");
    if ("Name" in var0)
        return "Name" in var1 && var0.Name[0] == var1.Name[0];
    return var0.Kind == var1.Kind;
}

function blockIdentifier(body)
{
    if (body.BlockId.Kind == "Loop")
        return body.BlockId.Loop;
    assert(body.BlockId.Kind == "Function""body.Kind should be Function, not " + body.BlockId.Kind);
    return body.BlockId.Variable.Name[0];
}

function collectBodyEdges(body)
{
    body.predecessors = [];
    body.successors = [];
    if (!("PEdge" in body))
        return;

    for (var edge of body.PEdge) {
        var [ source, target ] = edge.Index;
        if (!(target in body.predecessors))
            body.predecessors[target] = [];
        body.predecessors[target].push(edge);
        if (!(source in body.successors))
            body.successors[source] = [];
        body.successors[source].push(edge);
    }
}

function getPredecessors(body)
{
    if (!('predecessors' in body))
        collectBodyEdges(body);
    return body.predecessors;
}

function getSuccessors(body)
{
    if (!('successors' in body))
        collectBodyEdges(body);
    return body.successors;
}

// Split apart a function from sixgill into its mangled and unmangled name. If
// no mangled name was given, use the unmangled name as its mangled name
function splitFunction(func)
{
    var split = func.indexOf("$");
    if (split != -1)
        return [ func.substr(0, split), func.substr(split+1) ];
    split = func.indexOf("|");
    if (split != -1)
        return [ func.substr(0, split), func.substr(split+1) ];
    return [ func, func ];
}

function mangled(fullname)
{
    var [ mangled, unmangled ] = splitFunction(fullname);
    return mangled;
}

function readable(fullname)
{
    var [ mangled, unmangled ] = splitFunction(fullname);
    return unmangled;
}

function xdbLibrary()
{
    var lib = ctypes.open(os.getenv('XDB'));
    var api = {
        open: lib.declare("xdb_open", ctypes.default_abi, ctypes.void_t, ctypes.char.ptr),
        min_data_stream: lib.declare("xdb_min_data_stream", ctypes.default_abi, ctypes.int),
        max_data_stream: lib.declare("xdb_max_data_stream", ctypes.default_abi, ctypes.int),
        read_key: lib.declare("xdb_read_key", ctypes.default_abi, ctypes.char.ptr, ctypes.int),
        read_entry: lib.declare("xdb_read_entry", ctypes.default_abi, ctypes.char.ptr, ctypes.char.ptr),
        free_string: lib.declare("xdb_free", ctypes.default_abi, ctypes.void_t, ctypes.char.ptr)
    };
    try {
        api.lookup_key = lib.declare("xdb_lookup_key", ctypes.default_abi, ctypes.int, ctypes.char.ptr);
    } catch (e) {
        // lookup_key is for development use only and is not strictly necessary.
    }
    return api;
}

function openLibrary(names) {
    for (const name of names) {
        try {
            return ctypes.open(name);
        } catch(e) {
        }
    }
    return undefined;
}

function cLibrary()
{
    const lib = openLibrary(['libc.so.6''libc.so''libc.dylib']);
    if (!lib) {
        throw new Error("Unable to open libc");
    }

    if (getBuildConfiguration("moz-memory")) {
        throw new Error("cannot use libc functions with --enable-jemalloc, since they will be routed " +
                        "through jemalloc, but calling libc.free() directly will bypass it and the " +
                        "malloc/free will be mismatched");
    }

    return {
        fopen: lib.declare("fopen", ctypes.default_abi, ctypes.void_t.ptr, ctypes.char.ptr, ctypes.char.ptr),
        getline: lib.declare("getline", ctypes.default_abi, ctypes.ssize_t, ctypes.char.ptr.ptr, ctypes.size_t.ptr, ctypes.void_t.ptr),
        fclose: lib.declare("fclose", ctypes.default_abi, ctypes.int, ctypes.void_t.ptr),
        free: lib.declare("free", ctypes.default_abi, ctypes.void_t, ctypes.void_t.ptr),
    };
}

function* readFileLines_gen(filename)
{
    var libc = cLibrary();
    var linebuf = ctypes.char.ptr();
    var bufsize = ctypes.size_t(0);
    var fp = libc.fopen(filename, "r");
    if (fp.isNull())
        throw new Error("Unable to open '" + filename + "'");

    while (libc.getline(linebuf.address(), bufsize.address(), fp) > 0)
        yield linebuf.readString();
    libc.fclose(fp);
    libc.free(ctypes.void_t.ptr(linebuf));
}

function addToKeyedList(collection, key, entry)
{
    if (!(key in collection))
        collection[key] = [];
    collection[key].push(entry);
    return collection[key];
}

function addToMappedList(map, key, entry)
{
    if (!map.has(key))
        map.set(key, []);
    map.get(key).push(entry);
    return map.get(key);
}

function loadTypeInfo(filename)
{
    return JSON.parse(os.file.readFile(filename));
}

// Given the range `first` .. `last`, break it down into `count` batches and
// return the start of the (1-based) `num` batch.
function batchStart(num, count, first, last) {
  const N = (last - first) + 1;
  return Math.floor((num - 1) / count * N) + first;
}

// As above, but return the last value in the (1-based) `num` batch.
function batchLast(num, count, first, last) {
  const N = (last - first) + 1;
  return Math.floor(num / count * N) + first - 1;
}

// Debugging tool. See usage below.
function PropertyTracer(traced_prop, check) {
    return {
        matches(prop, value) {
            if (prop != traced_prop)
                return false;
            if ('value' in check)
                return value == check.value;
            return true;
        },

        // Also called when defining a property.
        set(obj, prop, value) {
            if (this.matches(prop, value))
                debugger;
            return Reflect.set(...arguments);
        },
    };
}

// Usage: var myobj = traced({}, 'name', {value: 'Bob'})
//
// This will execute a `debugger;` statement when myobj['name'] is defined or
// set to 'Bob'.
function traced(obj, traced_prop, check) {
  return new Proxy(obj, PropertyTracer(traced_prop, check));
}

91%


[ 0.32Quellennavigators  Projekt   ]