Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  stringify-fastpath.js   Sprache: JAVA

 
// |reftest| skip-if(!xulRuntime.shell) -- not sure why, but invisible errors when running in browser.

/*
 * Any copyright is dedicated to the Public Domain.
 * https://creativecommons.org/publicdomain/zero/1.0/
 */


if (typeof JSONStringify === "undefined") {
    var JSONStringify = SpecialPowers.Cu.getJSTestingFunctions().JSONStringify;
}

var report = this.console?.error || this.printErr;

report("BUGNUMBER: 1837410");

function compare(obj) {
    let slow;
    try { slow = JSONStringify(obj, "SlowOnly"); } catch (e) { slow = "" + e; }
    let maybeFast;
    try { maybeFast = JSONStringify(obj, "Normal"); } catch (e) { maybeFast = "" + e; }
    if (slow !== maybeFast) {
        report(`Slow:\n${slow}\nFast:\n${maybeFast}`);
        return 1;
    }
    return 0;
}

function newBigInt(val = 7n) {
    let result;
    function grabThis() { result = this; }
    grabThis.call(BigInt(val));
    return result;
}

function testBothPaths() {
    let failures = 0;
    failures += compare([, 3, undefined, ,]);
    failures += compare({ a: 1, b: undefined });
    failures += compare({ a: undefined, b: 1 });
    failures += compare({ a: 1, b: Symbol("fnord") });

    const obj = {};
    obj.first = true;
    obj[0] = 'a';
    obj[1] = undefined;
    obj[2] = 'b';
    obj.last = true;
    failures += compare(obj);

    const cyclic = {};
    cyclic.one = 1;
    cyclic.two = { me: cyclic };
    failures += compare(cyclic);

    const sparse = [10, 20, 30];
    sparse[1000] = 40;
    failures += compare(sparse);

    const arr = [10, 20, 30];
    arr.other = true;
    failures += compare(arr);

    const arr2 = new Array(5);
    arr2[1] = 'hello';
    arr2[3] = 'world';
    failures += compare(arr2);

    const big = { p1: 1, p2: 2, p3: 3, p4: 4, p5: 5, p6: 6, p7: 7, p8: 8, p9: 9 };
    failures += compare(big);

    failures += compare(new Number(3));
    failures += compare(new Boolean(true));
    failures += compare(Number.NaN);
    failures += compare(undefined);
    failures += compare({ x: () => 1 });

    failures += compare({ x: newBigInt() });

    const sparse2 = [];
    Object.defineProperty(sparse2, "0", { value: 7, enumerable: false });
    failures += compare(sparse2);

    return failures;
}

function checkFast(value, expectWhySlow) {
    let whySlow;
    let json;
    try {
        json = JSONStringify(value, "FastOnly");
    } catch (e) {
        const m = e.message.match(/failed mandatory fast path: (\S+)/);
        if (!m) {
            report("Expected fast path fail, got " + e);
            return 1;
        }
        whySlow = m[1];
    }

    if (expectWhySlow) {
        if (!whySlow) {
            report("Expected to bail out of fast path but unexpectedly succeeded");
            report((new Error).stack);
            report(json);
            return 1;
        } else if (whySlow != expectWhySlow) {
            report(`Expected to bail out of fast path because ${expectWhySlow} but bailed because ${whySlow}`);
            return 1;
        }
    } else {
        if (whySlow) {
            report("Expected fast path to succeed, bailed because: " + whySlow);
            return 1; // Fail
        }
    }

    return 0;
}

function testFastPath() {
    let failures = 0;
    failures += checkFast({});
    failures += checkFast([]);
    failures += checkFast({ x: true });
    failures += checkFast([, , 10, ,]);
    failures += checkFast({ x: undefined });
    failures += checkFast({ x: Symbol() });
    failures += checkFast({ x: new Set([10,20,30]) });

    failures += checkFast("primitive""PRIMITIVE");
    failures += checkFast(true"PRIMITIVE");
    failures += checkFast(7, "PRIMITIVE");

    failures += checkFast({ x: new Uint8Array(3) }, "INELIGIBLE_OBJECT");
    failures += checkFast({ x: new Number(3) }, "INELIGIBLE_OBJECT");
    failures += checkFast({ x: new Boolean(true) }, "INELIGIBLE_OBJECT");
    failures += checkFast({ x: newBigInt(3) }, "INELIGIBLE_OBJECT");
    failures += checkFast(Number.NaN, "PRIMITIVE");
    failures += checkFast(undefined, "PRIMITIVE");

    // Array has enumerated indexed + non-indexed slots.
    const nonElements = [];
    Object.defineProperty(nonElements, 0, { value: "hi", enumerated: true, configurable: true });
    nonElements.named = 7;
    failures += checkFast(nonElements, "INELIGIBLE_OBJECT");

    nonElements.splice(0);
    failures += checkFast(nonElements);

    // Array's prototype has indexed slot and/or inherited element.
    const proto = {};
    Object.defineProperty(proto, "0", { value: 1, enumerable: false });
    const holy = [, , 3];
    Object.setPrototypeOf(holy, proto);
    failures += checkFast(holy, "INELIGIBLE_OBJECT");
    Object.setPrototypeOf(holy, { 1: true });
    failures += checkFast(holy, "INELIGIBLE_OBJECT");

    // This is probably redundant with one of the above, but it was
    // found by a fuzzer at one point.
    const accessorProto = Object.create(Array.prototype);
    Object.defineProperty(accessorProto, "0", {
        get() { return 2; }, set() { }
    });
    const child = [];
    Object.setPrototypeOf(child, accessorProto);
    child.push(1);
    failures += checkFast(child, "INELIGIBLE_OBJECT");

    failures += checkFast({ get x() { return 1; } }, "NON_DATA_PROPERTY");

    const self = {};
    self.self = self;
    failures += checkFast(self, "DEEP_RECURSION");
    const ouroboros = ['head''middle', []];
    let p = ouroboros[2];
    let middle;
    for (let i = 0; i < 1000; i++) {
        p.push('middle''middle');
        p = p[2] = [];
        if (i == 10) {
            middle = p;
        }
    }
    failures += checkFast(ouroboros, "DEEP_RECURSION"); // Acyclic but deep
    p[2] = ouroboros;
    failures += checkFast(ouroboros, "DEEP_RECURSION"); // Cyclic and deep
    middle[2] = ouroboros;
    failures += checkFast(ouroboros, "DEEP_RECURSION"); // Cyclic after 10 recursions

    failures += checkFast({ 0: true, 1: true, 10000: true }, "INELIGIBLE_OBJECT");
    const arr = [1, 2, 3];
    arr[10000] = 4;
    failures += checkFast(arr, "INELIGIBLE_OBJECT");

    failures += checkFast({ x: 12n }, "BIGINT");

    failures += checkFast({ x: new Date() }, "HAVE_TOJSON");
    failures += checkFast({ toJSON() { return "json"; } }, "HAVE_TOJSON");
    const custom = { toJSON() { return "value"; } };
    failures += checkFast(Object.create(custom), "HAVE_TOJSON");

    return failures;
}

let failures = testBothPaths() + testFastPath();

if (typeof reportCompare === "function") {
    reportCompare(0, failures);
else {
    assertEq(failures, 0);
}

Messung V0.5
C=93 H=97 G=94

¤ Dauer der Verarbeitung: 0.14 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.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge