// Locally-defined globals
assertErrorMessage(() => wasmEvalText(`(module (global))`), SyntaxError, /wasm text error/); // A global field in the text format is valid with an empty expression, but this produces an invalid module
assertErrorMessage(() => wasmEvalText(`(module (global i32))`), WebAssembly.CompileError, /popping value/);
assertErrorMessage(() => wasmEvalText(`(module (global (mut i32)))`), WebAssembly.CompileError, /popping value/);
wasmFailValidateText(`(module (global i32 (global.get 0)))`, /out of range/);
wasmFailValidateText(`(module (global i32 (global.get 1)) (global i32 (i32.const 1)))`, /out of range/);
// Test a well-defined global section. function testInner(type, initialValue, nextValue, coercion)
{ var module = wasmEvalText(`(module
(global (mut ${type}) (${type}.const ${initialValue}))
(global ${type} (${type}.const ${initialValue}))
// Example use of dynamic linking
{ // Make a memory for two dynamically-linked modules to share. Each module gets five pages. const mem = new WebAssembly.Memory({ initial: 15, maximum: 15 });
const mod1 = new WebAssembly.Module(wasmTextToBinary(`(module
(memory (import"env""memory") 15 15)
(global $memBase (import"env""__memory_base") i32)
(data (offset (global.get $memBase)) "Hello from module 1.")
(data (offset (i32.add (global.get $memBase) (i32.const 65536))) "Goodbye from module 1.")
)`)); const instance1 = new WebAssembly.Instance(mod1, {
env: {
memory: mem,
__memory_base: 65536 * 5, // this module's memory starts at page 5
},
});
const mod2 = new WebAssembly.Module(wasmTextToBinary(`(module
(memory (import"env""memory") 15 15)
(global $memBase (import"env""__memory_base") i32)
(data (offset (global.get $memBase)) "Hello from module 2.")
(data (offset (i32.add (global.get $memBase) (i32.const 65536))) "Goodbye from module 2.")
)`)); const instance2 = new WebAssembly.Instance(mod2, {
env: {
memory: mem,
__memory_base: 65536 * 10, // this module's memory starts at page 10
},
});
// All four strings should now be present in the memory.
function assertStringInMem(mem, str, addr) { const bytes = new Uint8Array(mem.buffer).slice(addr, addr + str.length);
let memStr = String.fromCharCode(...bytes);
assertEq(memStr, str);
}
assertStringInMem(mem, "Hello from module 1.", 65536 * 5);
assertStringInMem(mem, "Goodbye from module 1.", 65536 * 6);
assertStringInMem(mem, "Hello from module 2.", 65536 * 10);
assertStringInMem(mem, "Goodbye from module 2.", 65536 * 11);
}
// Semantic errors.
wasmFailValidateText(`(module (global (mut i32) (i32.const 1337)) (func (global.set 1 (i32.const 0))))`, /(out of range)|(global index out of bounds)/);
wasmFailValidateText(`(module (global i32 (i32.const 1337)) (func (global.set 0 (i32.const 0))))`, /(can't write an immutable global)|(global is immutable)/);
// Big module with many variables: test that setting one doesn't overwrite the // other ones. function get_set(i, type) { return `
(func $get_${i} (result ${type}) (global.get ${i}))
(func $set_${i} (param ${type}) (global.set ${i} (local.get 0)))
`;
}
// Nothing special about NaN, it coerces just fine
assertEq((new Global({value: "i32"}, NaN)).value, 0);
// The default init value is zero.
assertEq((new Global({value: "i32"})).value, 0);
assertEq((new Global({value: "f32"})).value, 0);
assertEq((new Global({value: "f64"})).value, 0);
let mod = wasmEvalText(`(module
(import"""g" (global i64))
(func (export "f") (result i32)
(i64.eqz (global.get 0))))`,
{"":{g: new Global({value: "i64"})}});
assertEq(mod.exports.f(), 1);
{ // "value" is enumerable
let x = new Global({value: "i32"});
let s = ""; for ( let i in x )
s = s + i + ","; if (getBuildConfiguration("release_or_beta")) {
assertEq(s, "valueOf,value,");
} else {
assertEq(s, "type,valueOf,value,");
}
}
// "value" is defined on the prototype, not on the object
assertEq("value" in Global.prototype, true);
// Can't set the value of an immutable global
assertErrorMessage(() => (new Global({value: "i32"})).value = 10,
TypeError,
/can't set value of immutable global/);
{ // Can set the value of a mutable global
let g = new Global({value: "i32", mutable: true}, 37);
g.value = 10;
assertEq(g.value, 10);
}
{ // Misc internal conversions
let g = new Global({value: "i32"}, 42);
// An exported global can be imported into another instance even if // it is an object:
let j = wasmEvalText(`(module
(global (import"""g") i32)
(func (export "f") (result i32)
(global.get 0)))`,
{ "": { "g": i.exports.g }});
// And when it is then accessed it has the right value:
assertEq(j.exports.f(), 42);
}
// Identity of Global objects (independent of mutablity).
{ // When a global is exported twice, the two objects are the same.
let i = wasmEvalText(`(module
(global i32 (i32.const 0))
(export "a" (global 0))
(export "b" (global 0)))`);
assertEq(i.exports.a, i.exports.b);
// When a global is imported and then exported, the exported object is // the same as the imported object.
let j = wasmEvalText(`(module
(import"""a" (global i32))
(export "x" (global 0)))`,
{ "": {a: i.exports.a}});
assertEq(i.exports.a, j.exports.x);
// When a global is imported twice (ie aliased) and then exported twice, // the exported objects are the same, and are also the same as the // imported object.
let k = wasmEvalText(`(module
(import"""a" (global i32))
(import"""b" (global i32))
(export "x" (global 0))
(export "y" (global 1)))`,
{ "": {a: i.exports.a,
b: i.exports.a}});
// Mutability of import declaration and imported value have to match
{ const mutErr = /imported global mutability mismatch/;
let m1 = new Module(wasmTextToBinary(`(module
(import"m""g" (global i32)))`));
// Mutable Global matched to immutable import
let gm = new Global({value: "i32", mutable: true}, 42);
assertErrorMessage(() => new Instance(m1, {m: {g: gm}}),
LinkError,
mutErr);
let m2 = new Module(wasmTextToBinary(`(module
(import"m""g" (global (mut i32))))`));
// Immutable Global matched to mutable import
let gi = new Global({value: "i32", mutable: false}, 42);
assertErrorMessage(() => new Instance(m2, {m: {g: gi}}),
LinkError,
mutErr);
// Constant value is the same as immutable Global
assertErrorMessage(() => new Instance(m2, {m: {g: 42}}),
LinkError,
mutErr);
}
// TEST THIS LAST
// "value" is deletable
assertEq(delete Global.prototype.value, true);
assertEq("value" in Global.prototype, false);
// ADD NO MORE TESTS HERE!
}
// Standard wat syntax: the parens around the initializer expression are // optional.
{
let i1 = wasmEvalText(
`(module
(global $g i32 i32.const 37)
(func (export "f") (result i32) (global.get $g)))`);
assertEq(i1.exports.f(), 37);
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.