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

Quelle  large-memory.js   Sprache: JAVA

 
// |jit-test| skip-if: !largeArrayBufferSupported(); allow-oom

var pagesz = PageSizeInBytes;
var pages_limit = MaxPagesIn32BitMemory;

// 40000 is well above 2GB but not anything that might run into boundary
// conditions near 4GB.
var pages_vanilla = 40000;

for ( let [pages,maxpages] of [[pages_vanilla, pages_vanilla+100],
                               [pages_limit - 3, pages_limit],
                               [pages_limit, pages_limit]] ) {
    assertEq(pages == maxpages || maxpages - pages >= 3, true)
    let ins = wasmEvalText(`
(module
  (memory (export "mem") ${pages} ${maxpages})

  (data (i32.const ${(pages-5)*pagesz}) "yabbadabbado")
  (data $flintstone "yabbadabbado")

  (func (export "get_constaddr") (result i32)
    (i32.load (i32.const ${pages*pagesz-4})))

  (func (export "get_varaddr") (param $p i32) (result i32)
    (i32.load (local.get $p)))

  (func (export "set_constaddr") (param $v i32)
    (i32.store (i32.const ${pages*pagesz-8}) (local.get $v)))

  (func (export "set_varaddr") (param $p i32) (param $v i32)
    (i32.store (local.get $p) (local.get $v)))

  (func (export "get_constaddr_large_offset") (result i32)
    (i32.load offset=${(pages-100)*pagesz-4} (i32.const ${pagesz*100})))

  (func (export "get_varaddr_large_offset") (param $p i32) (result i32)
    (i32.load offset=${(pages-100)*pagesz-4} (local.get $p)))

  (func (export "get_constaddr_small_offset") (result i32)
    (i32.load offset=${pagesz-4} (i32.const ${(pages-1)*pagesz})))

  (func (export "get_varaddr_small_offset") (param $p i32) (result i32)
    (i32.load offset=${pagesz-4} (local.get $p)))

  (func (export "set_constaddr_large_offset") (param $v i32)
    (i32.store offset=${(pages-100)*pagesz-16} (i32.const ${pagesz*100}) (local.get $v)))

  (func (export "set_varaddr_large_offset") (param $p i32) (param $v i32)
    (i32.store offset=${(pages-100)*pagesz-20} (local.get $p) (local.get $v)))

  (func (export "set_constaddr_small_offset") (param $v i32)
    (i32.store offset=${pagesz-24} (i32.const ${(pages-1)*pagesz}) (local.get $v)))

  (func (export "set_varaddr_small_offset") (param $p i32) (param $v i32)
    (i32.store offset=${pagesz-28} (local.get $p) (local.get $v)))

  (func (export "copy") (param $dest i32) (param $src i32)
    (memory.copy (local.get $dest) (local.get $src) (i32.const 12)))

  (func (export "init") (param $dest i32)
    (memory.init $flintstone (local.get $dest) (i32.const 0) (i32.const 12)))

  (func (export "fill") (param $dest i32) (param $val i32) (param $len i32)
    (memory.fill (local.get 0) (local.get 1) (local.get 2)))

  (func (export "grow1") (result i32)
    (memory.grow (i32.const 1)))
)`);

    let buf = new Int32Array(ins.exports.mem.buffer);

    let checkFlintstoneAt = function (addr) {
        assertEq(buf[addr/4], 0x62626179)   // "yabb", little-endian
        assertEq(buf[addr/4+1], 0x62616461) // "adab", ditto
        assertEq(buf[addr/4+2], 0x6f646162) // "bado"
    }

    buf[pages*pagesz/4-1] = 0xdeadbeef;
    assertEq(ins.exports.get_constaddr(), 0xdeadbeef|0);
    assertEq(ins.exports.get_varaddr(pages*pagesz-4), 0xdeadbeef|0);

    assertEq(ins.exports.get_constaddr_large_offset(), 0xdeadbeef|0);
    assertEq(ins.exports.get_varaddr_large_offset(pagesz*100), 0xdeadbeef|0);

    assertEq(ins.exports.get_constaddr_small_offset(), 0xdeadbeef|0);
    assertEq(ins.exports.get_varaddr_small_offset((pages-1)*pagesz), 0xdeadbeef|0);

    ins.exports.set_constaddr(0xcafebab0);
    assertEq(buf[pages*pagesz/4-2], 0xcafebab0|0);

    ins.exports.set_varaddr(pages*pagesz-12, 0xcafebab1);
    assertEq(buf[pages*pagesz/4-3], 0xcafebab1|0);

    ins.exports.set_constaddr_large_offset(0xcafebab2);
    assertEq(buf[pages*pagesz/4-4], 0xcafebab2|0);

    ins.exports.set_varaddr_large_offset(pagesz*100, 0xcafebab3);
    assertEq(buf[pages*pagesz/4-5], 0xcafebab3|0);

    ins.exports.set_constaddr_small_offset(0xcafebab4);
    assertEq(buf[pages*pagesz/4-6], 0xcafebab4|0);

    ins.exports.set_varaddr_small_offset((pages-1)*pagesz, 0xcafebab5);
    assertEq(buf[pages*pagesz/4-7], 0xcafebab5|0);

    if (pages*pagesz < 0x1_0000_0000) {
        assertErrorMessage(() => ins.exports.get_varaddr(pages*pagesz),
                           WebAssembly.RuntimeError,
                           /index out of bounds/);
    }

    assertErrorMessage(() => ins.exports.get_varaddr_large_offset(pagesz*100+4),
                       WebAssembly.RuntimeError,
                       /index out of bounds/);

    assertErrorMessage(() => ins.exports.get_varaddr_small_offset((pages-1)*pagesz+4),
                       WebAssembly.RuntimeError,
                       /index out of bounds/);

    ins.exports.set_varaddr(pages*pagesz-4, 0); // Should work
    if (pages*pagesz < 0x1_0000_0000) {
        assertErrorMessage(() => ins.exports.set_varaddr(pages*pagesz, 0),
                           WebAssembly.RuntimeError,
                           /index out of bounds/);
    }

    ins.exports.set_varaddr_large_offset(pagesz*100+16, 0); // Should work
    assertErrorMessage(() => ins.exports.set_varaddr_large_offset(pagesz*100+20, 0),
                       WebAssembly.RuntimeError,
                       /index out of bounds/);

    ins.exports.set_varaddr_small_offset((pages-1)*pagesz+24); // Should work
    assertErrorMessage(() => ins.exports.set_varaddr_small_offset((pages-1)*pagesz+28, 0),
                       WebAssembly.RuntimeError,
                       /index out of bounds/);

    // Active init
    checkFlintstoneAt((pages-5)*pagesz);

    // memory.init
    ins.exports.init((pages-6)*pagesz);
    checkFlintstoneAt((pages-6)*pagesz);

    ins.exports.init(pages*pagesz-12); // Should work
    // Dest goes OOB
    assertErrorMessage(() => ins.exports.init(pages*pagesz-6),
                       WebAssembly.RuntimeError,
                       /index out of bounds/);

    // memory.copy

    // Dest and src are in bounds
    ins.exports.copy((pages-10)*pagesz, (pages-5)*pagesz);
    checkFlintstoneAt((pages-10)*pagesz);

    // Dest goes OOB
    assertErrorMessage(() => ins.exports.copy((pages)*pagesz-6, (pages-5)*pagesz, 12),
                       WebAssembly.RuntimeError,
                       /index out of bounds/);

    ins.exports.copy((pages)*pagesz-12, (pages-1)*pagesz); // Should work
    // Src goes OOB
    assertErrorMessage(() => ins.exports.copy((pages)*pagesz-12, (pages)*pagesz-6),
                       WebAssembly.RuntimeError,
                       /index out of bounds/);


    // memory.fill
    let lastpg = (pages-1)*pagesz;
    ins.exports.fill(lastpg, 0x37, pagesz);
    for ( let i=0; i < pagesz/4; i++ )
        assertEq(buf[lastpg/4+i], 0x37373737);

    assertErrorMessage(() => ins.exports.fill(lastpg, 0x42, pagesz+1),
                       WebAssembly.RuntimeError,
                       /index out of bounds/);

    done:
    if (pages < maxpages) {
        let res = 0;

        res = ins.exports.grow1();
        if (res == -1) break done;
        assertEq(res, pages);

        res = ins.exports.grow1();
        if (res == -1) break done;
        assertEq(res, pages+1);

        res = ins.exports.grow1();
        if (res == -1) break done;
        assertEq(res, pages+2);

        assertEq(ins.exports.get_varaddr((pages+2)*pagesz), 0);

        let i = 0;
        while (ins.exports.grow1() != -1) {
            i++;
        }
        // We can't assert equality because we might OOM before we get to the
        // max, but we can assert we did not go beyond that.
        assertEq(i <= maxpages-pages-3, true);
    }
}

// Very large offsets should be allowed (but may of course be OOB).  Observe
// that offset=0xffffffff is accepted by the validator even though this access
// could never succeed.
{
    let ins = wasmEvalText(`
(module
  (memory (export "mem") 1)
  (func (export "get1") (param $p i32) (result i32)
    (i32.load offset=0x80000000 (local.get $p)))
  (func (export "get2") (param $p i32) (result i32)
    (i32.load offset=0xfffffffc (local.get $p)))
  (func (export "get3") (param $p i32) (result i32)
    (i32.load offset=0xffffffff (local.get $p))))
`);
    assertErrorMessage(() => ins.exports.get1(0),
                       WebAssembly.RuntimeError,
                       /index out of bounds/);
    assertErrorMessage(() => ins.exports.get2(0),
                       WebAssembly.RuntimeError,
                       /index out of bounds/);
    assertErrorMessage(() => ins.exports.get3(0),
                       WebAssembly.RuntimeError,
                       /index out of bounds/);
}

{
    let ins = wasmEvalText(`
(module
  (memory (export "mem") 32768)
  (func (export "get1") (param $p i32) (result i32)
    (i32.load8_s offset=0x7fffffff (local.get $p))))
`);
    assertEq(ins.exports.get1(0), 0);
    assertErrorMessage(() => ins.exports.get1(1),
                       WebAssembly.RuntimeError,
                       /index out of bounds/);
    assertErrorMessage(() => ins.exports.get1(-1),
                       WebAssembly.RuntimeError,
                       /index out of bounds/);
}

{
    let ins = wasmEvalText(`
(module
  (memory (export "mem") 32769)
  (func (export "get1") (param $p i32) (result i32)
    (i32.load8_s offset=0x80000000 (local.get $p))))
`);
    assertEq(ins.exports.get1(0), 0);
    assertEq(ins.exports.get1(65535), 0);
    assertErrorMessage(() => ins.exports.get1(65536),
                       WebAssembly.RuntimeError,
                       /index out of bounds/);
}

{
    let ins = wasmEvalText(`
(module
  (memory (export "mem") ${pages_limit})
  (func (export "get1") (param $p i32) (result i32)
    (i32.load8_s offset=${pages_limit*pagesz-1} (local.get $p))))
`);
    assertEq(ins.exports.get1(0), 0);
    assertErrorMessage(() => ins.exports.get1(1),
                       WebAssembly.RuntimeError,
                       /index out of bounds/);
    assertErrorMessage(() => ins.exports.get1(-1),
                       WebAssembly.RuntimeError,
                       /index out of bounds/);
}

// Fail to grow at the declared max
// Import and export

{
    let ins = wasmEvalText(`
(module
  (memory (export "mem") ${pages_limit} ${pages_limit})

  (func (export "set_it") (param $addr i32) (param $val i32)
    (i32.store (local.get $addr) (local.get $val)))

  (func (export "grow1") (result i32)
    (memory.grow (i32.const 1)))
)`);

    assertEq(ins.exports.grow1(), -1); // Because initial == max

    let ins2 = wasmEvalText(`
(module
  (import "" "mem" (memory 1))

  (func (export "get_it") (param $addr i32) (result i32)
    (i32.load (local.get $addr)))
)`,
                            {"":ins.exports})

    ins.exports.set_it((pages_limit*pagesz)-4, 0xbaadf00d);
    assertEq(ins2.exports.get_it((pages_limit*pagesz)-4), 0xbaadf00d|0)
}

// Fail to grow at the max heap size even if there is headroom
// in the declared max
if (pages_limit < 65536) {
    let ins = wasmEvalText(`
(module
  (memory (export "mem") ${pages_limit} ${pages_limit+2})

  (func (export "grow1") (result i32)
    (memory.grow (i32.const 1)))
)`);

    assertEq(ins.exports.grow1(), -1); // Because current is at the max heap size
}

// Fail to instantiate when the minimum is larger than the max heap size
if (pages_limit < 65536) {
    assertErrorMessage(() => wasmEvalText(`
(module (memory (export "mem") ${pages_limit+1} ${pages_limit+1}))
`),
                       WebAssembly.RuntimeError,
                       /too many memory pages/);
}

Messung V0.5
C=91 H=66 G=79

¤ 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.