Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/js/src/jit-test/tests/errors/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 10 kB image not shown  

Quelle  capture-stack.js   Sprache: JAVA

 
// |jit-test| --setpref=experimental.error_capture_stack_trace;
load(libdir + "asserts.js");

if ('captureStackTrace' in Error) {
    assertEq(Error.captureStackTrace.length, 2);

    let x = Error.captureStackTrace({});
    assertEq(x, undefined);

    assertThrowsInstanceOf(() => Error.captureStackTrace(), TypeError);
    assertThrowsInstanceOf(() => Error.captureStackTrace(2), TypeError);

    Error.captureStackTrace({}, 2);
    Error.captureStackTrace({}, null);
    Error.captureStackTrace({}, {});

    function caller(f) {
        return f();
    }

    function fill() {
        let x = {}
        Error.captureStackTrace(x, caller);
        return x;
    }

    function test_elision() {
        let x = caller(fill);
        let { stack } = x;
        assertEq(stack.includes("caller"), false);
        assertEq(stack.includes("fill"), false);


        ({ stack } = caller(() => caller(fill)))
        print(stack);
        assertEq(stack.includes("caller"), true); // Only elide the first caller!
        assertEq(stack.includes("fill"), false);
    }

    test_elision();

    function nestedLambda(f) {
        (() => {
            (() => {
                (() => {
                    (() => {
                        f();
                    })();
                })();
            })();
        })();
    }


    // If we never see a matching frame when requesting a truncated
    // stack we should return the empty string
    function test_no_match() {
        let obj = {};
        // test_elision chosen arbitrarily as a function object which
        // doesn't exist in the call stack here.
        let capture = () => Error.captureStackTrace(obj, test_elision);
        nestedLambda(capture);
        assertEq(obj.stack, "");
    }
    test_no_match()

    function count_frames(str) {
        return str.split("\n").length
    }

    function test_nofilter() {
        let obj = {};
        let capture = () => Error.captureStackTrace(obj);
        nestedLambda(capture);
        assertEq(count_frames(obj.stack), 9);
    }
    test_nofilter();

    function test_in_eval() {
        let obj = eval(`
        let obj = {};
        let capture = () => Error.captureStackTrace(obj);
        nestedLambda(capture);
        obj
        `)

        // Same as above, with an eval frame added!
        assertEq(count_frames(obj.stack), 10);
    }
    test_in_eval();

    //
    // [[ErrorData]]
    //
    const stackGetter = Object.getOwnPropertyDescriptor(Error.prototype, 'stack').get;
    const getStack = function (obj) {
        return stackGetter.call(obj);
    };

    function test_uncensored() {
        let err = undefined;
        function create_err() {
            err = new Error;
            Error.captureStackTrace(err, test_uncensored);
        }

        nestedLambda(create_err);

        // Calling Error.captureStackTrace doesn't mess with the internal
        // [[ErrorData]] slot
        assertEq(count_frames(err.stack), 2);
        assertEq(count_frames(getStack(err)), 9)
    }
    test_uncensored()

    // In general, the stacks a non-caller version of Error.captureStackStrace
    // should match what Error gives you
    function compare_stacks() {
        function censor_column(str) {
            return str.replace(/:(\d+):\d+\n/g, ":$1:censored\n")
        }

        let obj = {};
        let err = (Error.captureStackTrace(obj), new Error)
        assertEq(censor_column(err.stack), censor_column(obj.stack));
    }
    compare_stacks();
    nestedLambda(compare_stacks)

    // New global

    function test_in_global(global) {
        global.evaluate(caller.toString());
        global.evaluate(fill.toString());
        global.evaluate(test_elision.toString());
        global.evaluate("test_elision()");

        global.evaluate(nestedLambda.toString())
        global.evaluate(test_no_match.toString());
        global.evaluate("test_no_match()");


        global.evaluate(compare_stacks.toString());
        global.evaluate(`
            compare_stacks();
            nestedLambda(compare_stacks)
        `)
    }

    let global = newGlobal();
    test_in_global(global);

    let global2 = newGlobal({ principal: 0 });
    test_in_global(global2)

    let global3 = newGlobal({ principal: 0xfffff });
    test_in_global(global3)

    // What if the caller is a proxy?
    const caller_proxy = new Proxy(caller, {
        apply: function (target, thisArg, arguments) {
            return target(...arguments);
        }
    });

    function fill_proxy() {
        let x = {}
        Error.captureStackTrace(x, caller_proxy);
        return x;
    }

    // Proxies don't count for elision.
    function test_proxy_elision() {
        let x = caller_proxy(fill_proxy);
        let { stack } = x;
        assertEq(stack.includes("caller"), true);
        assertEq(stack.includes("fill_proxy"), true);
    }
    test_proxy_elision();

    const trivial_proxy = new Proxy(caller, {});
    function fill_trivial() {
        let x = {}
        Error.captureStackTrace(x, trivial_proxy);
        return x;
    }

    // Elision doesn't work even on forwarding proxy
    function test_trivial_elision() {
        let x = caller(fill_trivial);
        let { stack } = x;
        assertEq(stack.includes("caller"), true);
        assertEq(stack.includes("fill"), true);
    }
    test_trivial_elision();

    // Elision happens through bind
    function test_bind_elision() {
        let b = caller.bind(undefined, fill);
        let { stack } = b();
        assertEq(stack.includes("caller"), false);
        assertEq(stack.includes("fill"), false);
    }
    test_bind_elision();

    // Cross Realm testing

    let nr = newGlobal({ newCompartment: true })
    nr.eval(`globalThis.x = {}`);
    Error.captureStackTrace(nr.x);

    // Test strict definition
    function test_strict_definition() {
        "use strict";
        assertThrowsInstanceOf(() => Error.captureStackTrace(Object.freeze({ stack: null })), TypeError);
    }
    test_strict_definition();

    function test_property_descriptor() {
        let o = {};
        Error.captureStackTrace(o);
        let desc = Object.getOwnPropertyDescriptor(o, "stack");
        assertEq(desc.configurable, true)
        assertEq(desc.writable, true)
        assertEq(desc.enumerable, false)
    }
    test_property_descriptor();

    function test_delete() {
        let o = {};
        Error.captureStackTrace(o);
        delete o.stack
        assertEq("stack" in o, false)
    }
    test_delete();

    // Principal testing: This is basic/shell-principals.js extended to support
    // and compare Error.captureStackTrace.
    //
    // Reminder:
    // >  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.

    // Given a string of letters |expected|, say "abc", assert that the stack
    // contains calls to a series of functions named by the next letter from
    // the string, say a, b, and then c. Younger frames appear earlier in
    // |expected| than older frames.
    let count = 0;
    function check(expected, stack) {
        print("check(" + JSON.stringify(expected) + ") against:\n" + stack);
        count++;

        // Extract only the function names from the stack trace. Omit the frames
        // for the top-level evaluation, if it is present.
        var split = stack.split(/(.)?@.*\n/).slice(0, -1);
        if (split[split.length - 1] === undefined)
            split = split.slice(0, -2);

        print(JSON.stringify(split));
        // Check the function names against the expected sequence.
        assertEq(split.length, expected.length * 2);
        for (var i = 0; i < expected.length; i++)
            assertEq(split[i * 2 + 1], expected[i]);
    }

    var low = newGlobal({ principal: 0 });
    var mid = newGlobal({ principal: 0xffff });
    var high = newGlobal({ principal: 0xfffff });

    eval('function a() { let o = {}; Error.captureStackTrace(o); check("a", o.stack); b(); }');
    low.eval('function b() { let o = {}; Error.captureStackTrace(o); check("b", o.stack); c(); }');
    mid.eval('function c() { let o = {}; Error.captureStackTrace(o); check("cba", o.stack); d(); }');
    high.eval('function d() { let o = {}; Error.captureStackTrace(o); check("dcba", o.stack); e(); }');

    // Globals created with no explicit principals get 0xffff.
    eval('function e() { let o = {}; Error.captureStackTrace(o); check("ecba", o.stack); f(); }');

    low.eval('function f() { let o = {}; Error.captureStackTrace(o); check("fb", o.stack); g(); }');
    mid.eval('function g() { let o = {}; Error.captureStackTrace(o); check("gfecba", o.stack); h(); }');
    high.eval('function h() { let o = {}; Error.captureStackTrace(o); check("hgfedcba", o.stack); }');

    // Make everyone's functions visible to each other, as needed.
    b = low.b;
    low.c = mid.c;
    mid.d = high.d;
    high.e = e;
    f = low.f;
    low.g = mid.g;
    mid.h = high.h;

    low.check = mid.check = high.check = check;

    // Kick the whole process off.
    a();

    assertEq(count, 8);

    // Ensure filtering is based on caller realm not on target object.
    low.eval("low_target = {}");
    mid.eval("mid_target = {}");
    high.eval("high_target = {}");

    high.low_target = mid.low_target = low.low_target;
    high.mid_target = low.mid_target = mid.mid_target;
    mid.high_target = low.high_target = high.high_target;

    high.low_cst = mid.low_cst = low.low_cst = low.Error.captureStackTrace;
    high.mid_cst = low.mid_cst = mid.mid_cst = mid.Error.captureStackTrace;
    mid.high_cst = low.high_cst = high.high_cst = high.Error.captureStackTrace;

    for (let g of [low, mid, high]) {
        assertEq("low_target" in g, true);
        assertEq("mid_target" in g, true);
        assertEq("high_target" in g, true);

        assertEq("low_cst" in g, true);
        assertEq("mid_cst" in g, true);
        assertEq("high_cst" in g, true);

        // install caller function z -- single letter name for
        // check compat.
        g.eval("function z(f) { f() }")
    }

    low.eval("function q() { Error.captureStackTrace(low_target); }")


    high.q = low.q;

    // Caller function z is from high, but using low Error.captureStackTrace, so
    // z should be elided.
    high.eval("z(q)");
    check("q", low.low_target.stack);

    low.eval("function r() { high_cst(low_target) }")
    high.r = low.r;

    // Can see everything here using high cst and low target.
    high.eval("function t() { z(r) }");
    high.t();
    check("rzt", low.low_target.stack);


}

Messung V0.5
C=91 H=96 G=93

¤ Dauer der Verarbeitung: 0.25 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.