mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Update web-platform-tests to revision 3efff9b2d66aed3d8e2061205069883fd54df2be
This commit is contained in:
parent
9832feddf3
commit
f80ff24202
51 changed files with 1026 additions and 868 deletions
|
@ -3,44 +3,401 @@
|
|||
// found in the LICENSE file.
|
||||
|
||||
// Used for encoding f32 and double constants to bits.
|
||||
let __buffer = new ArrayBuffer(8);
|
||||
let byte_view = new Int8Array(__buffer);
|
||||
let f32_view = new Float32Array(__buffer);
|
||||
let f64_view = new Float64Array(__buffer);
|
||||
let f32_view = new Float32Array(1);
|
||||
let f32_bytes_view = new Uint8Array(f32_view.buffer);
|
||||
let f64_view = new Float64Array(1);
|
||||
let f64_bytes_view = new Uint8Array(f64_view.buffer);
|
||||
|
||||
// The bytes function receives one of
|
||||
// - several arguments, each of which is either a number or a string of length
|
||||
// 1; if it's a string, the charcode of the contained character is used.
|
||||
// - a single array argument containing the actual arguments
|
||||
// - a single string; the returned buffer will contain the char codes of all
|
||||
// contained characters.
|
||||
function bytes(...input) {
|
||||
if (input.length == 1 && typeof input[0] == 'array') input = input[0];
|
||||
if (input.length == 1 && typeof input[0] == 'string') {
|
||||
let len = input[0].length;
|
||||
let view = new Uint8Array(len);
|
||||
for (let i = 0; i < len; i++) view[i] = input[0].charCodeAt(i);
|
||||
return view.buffer;
|
||||
}
|
||||
let view = new Uint8Array(input.length);
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
let val = input[i];
|
||||
if (typeof val == 'string') {
|
||||
assertEquals(1, val.length, 'string inputs must have length 1');
|
||||
val = val.charCodeAt(0);
|
||||
}
|
||||
view[i] = val | 0;
|
||||
}
|
||||
return view.buffer;
|
||||
}
|
||||
|
||||
// Header declaration constants
|
||||
var kWasmH0 = 0;
|
||||
var kWasmH1 = 0x61;
|
||||
var kWasmH2 = 0x73;
|
||||
var kWasmH3 = 0x6d;
|
||||
|
||||
var kWasmV0 = 0x1;
|
||||
var kWasmV1 = 0;
|
||||
var kWasmV2 = 0;
|
||||
var kWasmV3 = 0;
|
||||
|
||||
var kHeaderSize = 8;
|
||||
var kPageSize = 65536;
|
||||
var kSpecMaxPages = 65535;
|
||||
var kMaxVarInt32Size = 5;
|
||||
var kMaxVarInt64Size = 10;
|
||||
|
||||
let kDeclNoLocals = 0;
|
||||
|
||||
// Section declaration constants
|
||||
let kUnknownSectionCode = 0;
|
||||
let kTypeSectionCode = 1; // Function signature declarations
|
||||
let kImportSectionCode = 2; // Import declarations
|
||||
let kFunctionSectionCode = 3; // Function declarations
|
||||
let kTableSectionCode = 4; // Indirect function table and other tables
|
||||
let kMemorySectionCode = 5; // Memory attributes
|
||||
let kGlobalSectionCode = 6; // Global declarations
|
||||
let kExportSectionCode = 7; // Exports
|
||||
let kStartSectionCode = 8; // Start function declaration
|
||||
let kElementSectionCode = 9; // Elements section
|
||||
let kCodeSectionCode = 10; // Function code
|
||||
let kDataSectionCode = 11; // Data segments
|
||||
|
||||
// Name section types
|
||||
let kModuleNameCode = 0;
|
||||
let kFunctionNamesCode = 1;
|
||||
let kLocalNamesCode = 2;
|
||||
|
||||
let kWasmFunctionTypeForm = 0x60;
|
||||
let kWasmAnyFunctionTypeForm = 0x70;
|
||||
|
||||
let kHasMaximumFlag = 1;
|
||||
let kResizableMaximumFlag = 1;
|
||||
|
||||
// Function declaration flags
|
||||
let kDeclFunctionName = 0x01;
|
||||
let kDeclFunctionImport = 0x02;
|
||||
let kDeclFunctionLocals = 0x04;
|
||||
let kDeclFunctionExport = 0x08;
|
||||
|
||||
// Local types
|
||||
let kWasmStmt = 0x40;
|
||||
let kWasmI32 = 0x7f;
|
||||
let kWasmI64 = 0x7e;
|
||||
let kWasmF32 = 0x7d;
|
||||
let kWasmF64 = 0x7c;
|
||||
let kWasmS128 = 0x7b;
|
||||
|
||||
let kExternalFunction = 0;
|
||||
let kExternalTable = 1;
|
||||
let kExternalMemory = 2;
|
||||
let kExternalGlobal = 3;
|
||||
|
||||
let kTableZero = 0;
|
||||
let kMemoryZero = 0;
|
||||
|
||||
// Useful signatures
|
||||
let kSig_i_i = makeSig([kWasmI32], [kWasmI32]);
|
||||
let kSig_l_l = makeSig([kWasmI64], [kWasmI64]);
|
||||
let kSig_i_l = makeSig([kWasmI64], [kWasmI32]);
|
||||
let kSig_i_ii = makeSig([kWasmI32, kWasmI32], [kWasmI32]);
|
||||
let kSig_i_iii = makeSig([kWasmI32, kWasmI32, kWasmI32], [kWasmI32]);
|
||||
let kSig_v_iiii = makeSig([kWasmI32, kWasmI32, kWasmI32, kWasmI32], []);
|
||||
let kSig_f_ff = makeSig([kWasmF32, kWasmF32], [kWasmF32]);
|
||||
let kSig_d_dd = makeSig([kWasmF64, kWasmF64], [kWasmF64]);
|
||||
let kSig_l_ll = makeSig([kWasmI64, kWasmI64], [kWasmI64]);
|
||||
let kSig_i_dd = makeSig([kWasmF64, kWasmF64], [kWasmI32]);
|
||||
let kSig_v_v = makeSig([], []);
|
||||
let kSig_i_v = makeSig([], [kWasmI32]);
|
||||
let kSig_l_v = makeSig([], [kWasmI64]);
|
||||
let kSig_f_v = makeSig([], [kWasmF32]);
|
||||
let kSig_d_v = makeSig([], [kWasmF64]);
|
||||
let kSig_v_i = makeSig([kWasmI32], []);
|
||||
let kSig_v_ii = makeSig([kWasmI32, kWasmI32], []);
|
||||
let kSig_v_iii = makeSig([kWasmI32, kWasmI32, kWasmI32], []);
|
||||
let kSig_v_l = makeSig([kWasmI64], []);
|
||||
let kSig_v_d = makeSig([kWasmF64], []);
|
||||
let kSig_v_dd = makeSig([kWasmF64, kWasmF64], []);
|
||||
let kSig_v_ddi = makeSig([kWasmF64, kWasmF64, kWasmI32], []);
|
||||
|
||||
let kSig_v_f = makeSig([kWasmF32], []);
|
||||
let kSig_f_f = makeSig([kWasmF32], [kWasmF32]);
|
||||
let kSig_f_d = makeSig([kWasmF64], [kWasmF32]);
|
||||
let kSig_d_d = makeSig([kWasmF64], [kWasmF64]);
|
||||
|
||||
function makeSig(params, results) {
|
||||
return {params: params, results: results};
|
||||
}
|
||||
|
||||
function makeSig_v_x(x) {
|
||||
return makeSig([x], []);
|
||||
}
|
||||
|
||||
function makeSig_v_xx(x) {
|
||||
return makeSig([x, x], []);
|
||||
}
|
||||
|
||||
function makeSig_r_v(r) {
|
||||
return makeSig([], [r]);
|
||||
}
|
||||
|
||||
function makeSig_r_x(r, x) {
|
||||
return makeSig([x], [r]);
|
||||
}
|
||||
|
||||
function makeSig_r_xx(r, x) {
|
||||
return makeSig([x, x], [r]);
|
||||
}
|
||||
|
||||
// Opcodes
|
||||
let kExprUnreachable = 0x00;
|
||||
let kExprNop = 0x01;
|
||||
let kExprBlock = 0x02;
|
||||
let kExprLoop = 0x03;
|
||||
let kExprIf = 0x04;
|
||||
let kExprElse = 0x05;
|
||||
let kExprTry = 0x06;
|
||||
let kExprCatch = 0x07;
|
||||
let kExprThrow = 0x08;
|
||||
let kExprEnd = 0x0b;
|
||||
let kExprBr = 0x0c;
|
||||
let kExprBrIf = 0x0d;
|
||||
let kExprBrTable = 0x0e;
|
||||
let kExprReturn = 0x0f;
|
||||
let kExprCallFunction = 0x10;
|
||||
let kExprCallIndirect = 0x11;
|
||||
let kExprDrop = 0x1a;
|
||||
let kExprSelect = 0x1b;
|
||||
let kExprGetLocal = 0x20;
|
||||
let kExprSetLocal = 0x21;
|
||||
let kExprTeeLocal = 0x22;
|
||||
let kExprGetGlobal = 0x23;
|
||||
let kExprSetGlobal = 0x24;
|
||||
let kExprI32LoadMem = 0x28;
|
||||
let kExprI64LoadMem = 0x29;
|
||||
let kExprF32LoadMem = 0x2a;
|
||||
let kExprF64LoadMem = 0x2b;
|
||||
let kExprI32LoadMem8S = 0x2c;
|
||||
let kExprI32LoadMem8U = 0x2d;
|
||||
let kExprI32LoadMem16S = 0x2e;
|
||||
let kExprI32LoadMem16U = 0x2f;
|
||||
let kExprI64LoadMem8S = 0x30;
|
||||
let kExprI64LoadMem8U = 0x31;
|
||||
let kExprI64LoadMem16S = 0x32;
|
||||
let kExprI64LoadMem16U = 0x33;
|
||||
let kExprI64LoadMem32S = 0x34;
|
||||
let kExprI64LoadMem32U = 0x35;
|
||||
let kExprI32StoreMem = 0x36;
|
||||
let kExprI64StoreMem = 0x37;
|
||||
let kExprF32StoreMem = 0x38;
|
||||
let kExprF64StoreMem = 0x39;
|
||||
let kExprI32StoreMem8 = 0x3a;
|
||||
let kExprI32StoreMem16 = 0x3b;
|
||||
let kExprI64StoreMem8 = 0x3c;
|
||||
let kExprI64StoreMem16 = 0x3d;
|
||||
let kExprI64StoreMem32 = 0x3e;
|
||||
let kExprMemorySize = 0x3f;
|
||||
let kExprMemoryGrow = 0x40;
|
||||
let kExprI32Const = 0x41;
|
||||
let kExprI64Const = 0x42;
|
||||
let kExprF32Const = 0x43;
|
||||
let kExprF64Const = 0x44;
|
||||
let kExprI32Eqz = 0x45;
|
||||
let kExprI32Eq = 0x46;
|
||||
let kExprI32Ne = 0x47;
|
||||
let kExprI32LtS = 0x48;
|
||||
let kExprI32LtU = 0x49;
|
||||
let kExprI32GtS = 0x4a;
|
||||
let kExprI32GtU = 0x4b;
|
||||
let kExprI32LeS = 0x4c;
|
||||
let kExprI32LeU = 0x4d;
|
||||
let kExprI32GeS = 0x4e;
|
||||
let kExprI32GeU = 0x4f;
|
||||
let kExprI64Eqz = 0x50;
|
||||
let kExprI64Eq = 0x51;
|
||||
let kExprI64Ne = 0x52;
|
||||
let kExprI64LtS = 0x53;
|
||||
let kExprI64LtU = 0x54;
|
||||
let kExprI64GtS = 0x55;
|
||||
let kExprI64GtU = 0x56;
|
||||
let kExprI64LeS = 0x57;
|
||||
let kExprI64LeU = 0x58;
|
||||
let kExprI64GeS = 0x59;
|
||||
let kExprI64GeU = 0x5a;
|
||||
let kExprF32Eq = 0x5b;
|
||||
let kExprF32Ne = 0x5c;
|
||||
let kExprF32Lt = 0x5d;
|
||||
let kExprF32Gt = 0x5e;
|
||||
let kExprF32Le = 0x5f;
|
||||
let kExprF32Ge = 0x60;
|
||||
let kExprF64Eq = 0x61;
|
||||
let kExprF64Ne = 0x62;
|
||||
let kExprF64Lt = 0x63;
|
||||
let kExprF64Gt = 0x64;
|
||||
let kExprF64Le = 0x65;
|
||||
let kExprF64Ge = 0x66;
|
||||
let kExprI32Clz = 0x67;
|
||||
let kExprI32Ctz = 0x68;
|
||||
let kExprI32Popcnt = 0x69;
|
||||
let kExprI32Add = 0x6a;
|
||||
let kExprI32Sub = 0x6b;
|
||||
let kExprI32Mul = 0x6c;
|
||||
let kExprI32DivS = 0x6d;
|
||||
let kExprI32DivU = 0x6e;
|
||||
let kExprI32RemS = 0x6f;
|
||||
let kExprI32RemU = 0x70;
|
||||
let kExprI32And = 0x71;
|
||||
let kExprI32Ior = 0x72;
|
||||
let kExprI32Xor = 0x73;
|
||||
let kExprI32Shl = 0x74;
|
||||
let kExprI32ShrS = 0x75;
|
||||
let kExprI32ShrU = 0x76;
|
||||
let kExprI32Rol = 0x77;
|
||||
let kExprI32Ror = 0x78;
|
||||
let kExprI64Clz = 0x79;
|
||||
let kExprI64Ctz = 0x7a;
|
||||
let kExprI64Popcnt = 0x7b;
|
||||
let kExprI64Add = 0x7c;
|
||||
let kExprI64Sub = 0x7d;
|
||||
let kExprI64Mul = 0x7e;
|
||||
let kExprI64DivS = 0x7f;
|
||||
let kExprI64DivU = 0x80;
|
||||
let kExprI64RemS = 0x81;
|
||||
let kExprI64RemU = 0x82;
|
||||
let kExprI64And = 0x83;
|
||||
let kExprI64Ior = 0x84;
|
||||
let kExprI64Xor = 0x85;
|
||||
let kExprI64Shl = 0x86;
|
||||
let kExprI64ShrS = 0x87;
|
||||
let kExprI64ShrU = 0x88;
|
||||
let kExprI64Rol = 0x89;
|
||||
let kExprI64Ror = 0x8a;
|
||||
let kExprF32Abs = 0x8b;
|
||||
let kExprF32Neg = 0x8c;
|
||||
let kExprF32Ceil = 0x8d;
|
||||
let kExprF32Floor = 0x8e;
|
||||
let kExprF32Trunc = 0x8f;
|
||||
let kExprF32NearestInt = 0x90;
|
||||
let kExprF32Sqrt = 0x91;
|
||||
let kExprF32Add = 0x92;
|
||||
let kExprF32Sub = 0x93;
|
||||
let kExprF32Mul = 0x94;
|
||||
let kExprF32Div = 0x95;
|
||||
let kExprF32Min = 0x96;
|
||||
let kExprF32Max = 0x97;
|
||||
let kExprF32CopySign = 0x98;
|
||||
let kExprF64Abs = 0x99;
|
||||
let kExprF64Neg = 0x9a;
|
||||
let kExprF64Ceil = 0x9b;
|
||||
let kExprF64Floor = 0x9c;
|
||||
let kExprF64Trunc = 0x9d;
|
||||
let kExprF64NearestInt = 0x9e;
|
||||
let kExprF64Sqrt = 0x9f;
|
||||
let kExprF64Add = 0xa0;
|
||||
let kExprF64Sub = 0xa1;
|
||||
let kExprF64Mul = 0xa2;
|
||||
let kExprF64Div = 0xa3;
|
||||
let kExprF64Min = 0xa4;
|
||||
let kExprF64Max = 0xa5;
|
||||
let kExprF64CopySign = 0xa6;
|
||||
let kExprI32ConvertI64 = 0xa7;
|
||||
let kExprI32SConvertF32 = 0xa8;
|
||||
let kExprI32UConvertF32 = 0xa9;
|
||||
let kExprI32SConvertF64 = 0xaa;
|
||||
let kExprI32UConvertF64 = 0xab;
|
||||
let kExprI64SConvertI32 = 0xac;
|
||||
let kExprI64UConvertI32 = 0xad;
|
||||
let kExprI64SConvertF32 = 0xae;
|
||||
let kExprI64UConvertF32 = 0xaf;
|
||||
let kExprI64SConvertF64 = 0xb0;
|
||||
let kExprI64UConvertF64 = 0xb1;
|
||||
let kExprF32SConvertI32 = 0xb2;
|
||||
let kExprF32UConvertI32 = 0xb3;
|
||||
let kExprF32SConvertI64 = 0xb4;
|
||||
let kExprF32UConvertI64 = 0xb5;
|
||||
let kExprF32ConvertF64 = 0xb6;
|
||||
let kExprF64SConvertI32 = 0xb7;
|
||||
let kExprF64UConvertI32 = 0xb8;
|
||||
let kExprF64SConvertI64 = 0xb9;
|
||||
let kExprF64UConvertI64 = 0xba;
|
||||
let kExprF64ConvertF32 = 0xbb;
|
||||
let kExprI32ReinterpretF32 = 0xbc;
|
||||
let kExprI64ReinterpretF64 = 0xbd;
|
||||
let kExprF32ReinterpretI32 = 0xbe;
|
||||
let kExprF64ReinterpretI64 = 0xbf;
|
||||
|
||||
class Binary {
|
||||
constructor() {
|
||||
this.length = 0;
|
||||
this.buffer = new Uint8Array(8192);
|
||||
}
|
||||
|
||||
ensure_space(needed) {
|
||||
if (this.buffer.length - this.length >= needed) return;
|
||||
let new_capacity = this.buffer.length * 2;
|
||||
while (new_capacity - this.length < needed) new_capacity *= 2;
|
||||
let new_buffer = new Uint8Array(new_capacity);
|
||||
new_buffer.set(this.buffer);
|
||||
this.buffer = new_buffer;
|
||||
}
|
||||
|
||||
trunc_buffer() {
|
||||
return this.buffer = this.buffer.slice(0, this.length);
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.length = 0;
|
||||
}
|
||||
|
||||
class Binary extends Array {
|
||||
emit_u8(val) {
|
||||
this.push(val);
|
||||
this.ensure_space(1);
|
||||
this.buffer[this.length++] = val;
|
||||
}
|
||||
|
||||
emit_u16(val) {
|
||||
this.push(val & 0xff);
|
||||
this.push((val >> 8) & 0xff);
|
||||
this.ensure_space(2);
|
||||
this.buffer[this.length++] = val;
|
||||
this.buffer[this.length++] = val >> 8;
|
||||
}
|
||||
|
||||
emit_u32(val) {
|
||||
this.push(val & 0xff);
|
||||
this.push((val >> 8) & 0xff);
|
||||
this.push((val >> 16) & 0xff);
|
||||
this.push((val >> 24) & 0xff);
|
||||
this.ensure_space(4);
|
||||
this.buffer[this.length++] = val;
|
||||
this.buffer[this.length++] = val >> 8;
|
||||
this.buffer[this.length++] = val >> 16;
|
||||
this.buffer[this.length++] = val >> 24;
|
||||
}
|
||||
|
||||
emit_u32v(val) {
|
||||
while (true) {
|
||||
emit_leb(val, max_len) {
|
||||
this.ensure_space(max_len);
|
||||
for (let i = 0; i < max_len; ++i) {
|
||||
let v = val & 0xff;
|
||||
val = val >>> 7;
|
||||
if (val == 0) {
|
||||
this.push(v);
|
||||
break;
|
||||
this.buffer[this.length++] = v;
|
||||
return;
|
||||
}
|
||||
this.push(v | 0x80);
|
||||
this.buffer[this.length++] = v | 0x80;
|
||||
}
|
||||
throw new Error("Leb value exceeds maximum length of " + max_len);
|
||||
}
|
||||
|
||||
emit_u32v(val) {
|
||||
this.emit_leb(val, kMaxVarInt32Size);
|
||||
}
|
||||
|
||||
emit_u64v(val) {
|
||||
this.emit_leb(val, kMaxVarInt64Size);
|
||||
}
|
||||
|
||||
emit_bytes(data) {
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
this.push(data[i] & 0xff);
|
||||
}
|
||||
this.ensure_space(data.length);
|
||||
this.buffer.set(data, this.length);
|
||||
this.length += data.length;
|
||||
}
|
||||
|
||||
emit_string(string) {
|
||||
|
@ -61,21 +418,22 @@ class Binary extends Array {
|
|||
}
|
||||
|
||||
emit_header() {
|
||||
this.push(kWasmH0, kWasmH1, kWasmH2, kWasmH3,
|
||||
kWasmV0, kWasmV1, kWasmV2, kWasmV3);
|
||||
this.emit_bytes([
|
||||
kWasmH0, kWasmH1, kWasmH2, kWasmH3, kWasmV0, kWasmV1, kWasmV2, kWasmV3
|
||||
]);
|
||||
}
|
||||
|
||||
emit_section(section_code, content_generator) {
|
||||
// Emit section name.
|
||||
this.emit_u8(section_code);
|
||||
// Emit the section to a temporary buffer: its full length isn't know yet.
|
||||
let section = new Binary;
|
||||
const section = new Binary;
|
||||
content_generator(section);
|
||||
// Emit section length.
|
||||
this.emit_u32v(section.length);
|
||||
// Copy the temporary buffer.
|
||||
// Avoid spread because {section} can be huge.
|
||||
for (let b of section) this.push(b);
|
||||
this.emit_bytes(section.trunc_buffer());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,8 +525,9 @@ class WasmModuleBuilder {
|
|||
}
|
||||
|
||||
addType(type) {
|
||||
// TODO: canonicalize types?
|
||||
this.types.push(type);
|
||||
var pl = type.params.length; // should have params
|
||||
var rl = type.results.length; // should have results
|
||||
return this.types.length - 1;
|
||||
}
|
||||
|
||||
|
@ -187,28 +546,28 @@ class WasmModuleBuilder {
|
|||
return func;
|
||||
}
|
||||
|
||||
addImport(module = "", name, type) {
|
||||
addImport(module, name, type) {
|
||||
let type_index = (typeof type) == "number" ? type : this.addType(type);
|
||||
this.imports.push({module: module, name: name, kind: kExternalFunction,
|
||||
type: type_index});
|
||||
return this.num_imported_funcs++;
|
||||
}
|
||||
|
||||
addImportedGlobal(module = "", name, type) {
|
||||
addImportedGlobal(module, name, type) {
|
||||
let o = {module: module, name: name, kind: kExternalGlobal, type: type,
|
||||
mutable: false}
|
||||
this.imports.push(o);
|
||||
return this.num_imported_globals++;
|
||||
}
|
||||
|
||||
addImportedMemory(module = "", name, initial = 0, maximum) {
|
||||
addImportedMemory(module, name, initial = 0, maximum) {
|
||||
let o = {module: module, name: name, kind: kExternalMemory,
|
||||
initial: initial, maximum: maximum};
|
||||
this.imports.push(o);
|
||||
return this;
|
||||
}
|
||||
|
||||
addImportedTable(module = "", name, initial, maximum) {
|
||||
addImportedTable(module, name, initial, maximum) {
|
||||
let o = {module: module, name: name, kind: kExternalTable, initial: initial,
|
||||
maximum: maximum};
|
||||
this.imports.push(o);
|
||||
|
@ -263,17 +622,7 @@ class WasmModuleBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
// TODO(ssauleau): legacy, remove this
|
||||
setFunctionTableLength(length) {
|
||||
return this.setTableBounds(length);
|
||||
}
|
||||
|
||||
// TODO(ssauleau): legacy, remove this
|
||||
setTableLength(min, max = undefined) {
|
||||
return this.setTableBounds(min, max);
|
||||
}
|
||||
|
||||
toArray(debug = false) {
|
||||
toBuffer(debug = false) {
|
||||
let binary = new Binary;
|
||||
let wasm = this;
|
||||
|
||||
|
@ -394,22 +743,12 @@ class WasmModuleBuilder {
|
|||
case kWasmF32:
|
||||
section.emit_u8(kExprF32Const);
|
||||
f32_view[0] = global.init;
|
||||
section.emit_u8(byte_view[0]);
|
||||
section.emit_u8(byte_view[1]);
|
||||
section.emit_u8(byte_view[2]);
|
||||
section.emit_u8(byte_view[3]);
|
||||
section.emit_bytes(f32_bytes_view);
|
||||
break;
|
||||
case kWasmF64:
|
||||
section.emit_u8(kExprF64Const);
|
||||
f64_view[0] = global.init;
|
||||
section.emit_u8(byte_view[0]);
|
||||
section.emit_u8(byte_view[1]);
|
||||
section.emit_u8(byte_view[2]);
|
||||
section.emit_u8(byte_view[3]);
|
||||
section.emit_u8(byte_view[4]);
|
||||
section.emit_u8(byte_view[5]);
|
||||
section.emit_u8(byte_view[6]);
|
||||
section.emit_u8(byte_view[7]);
|
||||
section.emit_bytes(f64_bytes_view);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
@ -443,7 +782,7 @@ class WasmModuleBuilder {
|
|||
}
|
||||
|
||||
// Add start function section.
|
||||
if (wasm.start_index != undefined) {
|
||||
if (wasm.start_index !== undefined) {
|
||||
if (debug) print("emitting start function @ " + binary.length);
|
||||
binary.emit_section(kStartSectionCode, section => {
|
||||
section.emit_u32v(wasm.start_index);
|
||||
|
@ -480,7 +819,9 @@ class WasmModuleBuilder {
|
|||
if (debug) print("emitting code @ " + binary.length);
|
||||
binary.emit_section(kCodeSectionCode, section => {
|
||||
section.emit_u32v(wasm.functions.length);
|
||||
let header = new Binary;
|
||||
for (let func of wasm.functions) {
|
||||
header.reset();
|
||||
// Function body length will be patched later.
|
||||
let local_decls = [];
|
||||
let l = func.locals;
|
||||
|
@ -500,7 +841,6 @@ class WasmModuleBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
let header = new Binary;
|
||||
header.emit_u32v(local_decls.length);
|
||||
for (let decl of local_decls) {
|
||||
header.emit_u32v(decl.count);
|
||||
|
@ -508,7 +848,7 @@ class WasmModuleBuilder {
|
|||
}
|
||||
|
||||
section.emit_u32v(header.length + func.body.length);
|
||||
section.emit_bytes(header);
|
||||
section.emit_bytes(header.trunc_buffer());
|
||||
section.emit_bytes(func.body);
|
||||
}
|
||||
});
|
||||
|
@ -562,24 +902,51 @@ class WasmModuleBuilder {
|
|||
});
|
||||
}
|
||||
|
||||
return binary;
|
||||
return binary.trunc_buffer();
|
||||
}
|
||||
|
||||
toBuffer(debug = false) {
|
||||
let bytes = this.toArray(debug);
|
||||
let buffer = new ArrayBuffer(bytes.length);
|
||||
let view = new Uint8Array(buffer);
|
||||
for (let i = 0; i < bytes.length; i++) {
|
||||
let val = bytes[i];
|
||||
if ((typeof val) == "string") val = val.charCodeAt(0);
|
||||
view[i] = val | 0;
|
||||
}
|
||||
return new Uint8Array(buffer);
|
||||
toArray(debug = false) {
|
||||
return Array.from(this.toBuffer(debug));
|
||||
}
|
||||
|
||||
instantiate(...args) {
|
||||
let module = new WebAssembly.Module(this.toBuffer());
|
||||
let instance = new WebAssembly.Instance(module, ...args);
|
||||
instantiate(ffi) {
|
||||
let module = this.toModule();
|
||||
let instance = new WebAssembly.Instance(module, ffi);
|
||||
return instance;
|
||||
}
|
||||
|
||||
asyncInstantiate(ffi) {
|
||||
return WebAssembly.instantiate(this.toBuffer(), ffi)
|
||||
.then(({module, instance}) => instance);
|
||||
}
|
||||
|
||||
toModule(debug = false) {
|
||||
return new WebAssembly.Module(this.toBuffer(debug));
|
||||
}
|
||||
}
|
||||
|
||||
function wasmI32Const(val) {
|
||||
let bytes = [kExprI32Const];
|
||||
for (let i = 0; i < 4; ++i) {
|
||||
bytes.push(0x80 | ((val >> (7 * i)) & 0x7f));
|
||||
}
|
||||
bytes.push((val >> (7 * 4)) & 0x7f);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
function wasmF32Const(f) {
|
||||
f32_view[0] = f;
|
||||
return [
|
||||
kExprF32Const, f32_bytes_view[0], f32_bytes_view[1], f32_bytes_view[2],
|
||||
f32_bytes_view[3]
|
||||
];
|
||||
}
|
||||
|
||||
function wasmF64Const(f) {
|
||||
f64_view[0] = f;
|
||||
return [
|
||||
kExprF64Const, f64_bytes_view[0], f64_bytes_view[1], f64_bytes_view[2],
|
||||
f64_bytes_view[3], f64_bytes_view[4], f64_bytes_view[5], f64_bytes_view[6],
|
||||
f64_bytes_view[7]
|
||||
];
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue