mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-09 00:08:12 +02:00
508 lines
21 KiB
ObjectPascal
508 lines
21 KiB
ObjectPascal
{ This file is part of wasmbin - a collection of WebAssembly binary utils.
|
|
|
|
Copyright (C) 2019, 2020 Dmitry Boyarintsev <skalogryz.lists@gmail.com>
|
|
Copyright (C) 2020 by the Free Pascal development team
|
|
|
|
This source is free software; you can redistribute it and/or modify it under
|
|
the terms of the GNU General Public License as published by the Free
|
|
Software Foundation; either version 2 of the License, or (at your option)
|
|
any later version.
|
|
|
|
This code is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
details.
|
|
|
|
A copy of the GNU General Public License is available on the World Wide Web
|
|
at <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing
|
|
to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
|
Boston, MA 02110-1335, USA.
|
|
}
|
|
|
|
unit wasmbincode;
|
|
// WebAssembly instructions information
|
|
// http://webassembly.github.io/spec/core/binary/instructions.html
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, lebutils;
|
|
|
|
const
|
|
VALTYPE_NONE = $40;
|
|
VALTYPE_I32 = $7F;
|
|
VALTYPE_I64 = $7E;
|
|
VALTYPE_F32 = $7D;
|
|
VALTYPE_F64 = $7C;
|
|
|
|
INST_TRAP = $00;
|
|
// ..
|
|
INST_IF = $04;
|
|
INST_ELSE = $05;
|
|
// ...
|
|
INST_END = $0b;
|
|
|
|
INST_block = $02;
|
|
INST_loop = $03;
|
|
INST_unreachable = $00;
|
|
INST_nop = $01;
|
|
INST_br = $0C;
|
|
INST_br_if = $0D;
|
|
INST_br_table = $0E;
|
|
INST_return = $0F;
|
|
INST_call = $10;
|
|
INST_call_indirect = $11;
|
|
|
|
//INST_if = $04;
|
|
//INST_else = $05;
|
|
//INST_end = $0B;
|
|
INST_drop = $1A;
|
|
INST_select = $1B;
|
|
INST_local_get = $20;
|
|
INST_local_set = $21;
|
|
INST_local_tee = $22;
|
|
INST_global_get = $23;
|
|
INST_global_set = $24;
|
|
|
|
INST_i32_load = $28;
|
|
INST_i64_load = $29;
|
|
INST_f32_load = $2a;
|
|
INST_f64_load = $2b;
|
|
INST_i32_load8_s = $2c;
|
|
INST_i32_load8_u = $2d;
|
|
INST_i32_load16_s = $2e;
|
|
INST_i32_load16_u = $2f;
|
|
INST_i64_load8_s = $30;
|
|
INST_i64_load8_u = $31;
|
|
INST_i64_load16_s = $32;
|
|
INST_i64_load16_u = $33;
|
|
INST_i64_load32_s = $34;
|
|
INST_i64_load32_u = $35;
|
|
INST_i32_store = $36;
|
|
INST_i64_store = $37;
|
|
INST_f32_store = $38;
|
|
INST_f64_store = $39;
|
|
INST_i32_store8 = $3a;
|
|
INST_i32_store16 = $3b;
|
|
INST_i64_store8 = $3c;
|
|
INST_i64_store16 = $3d;
|
|
INST_i64_store32 = $3e;
|
|
INST_memory_size = $3f;
|
|
INST_memory_grow = $40;
|
|
INST_i32_const = $41;
|
|
INST_i64_const = $42;
|
|
INST_f32_const = $43;
|
|
INST_f64_const = $44;
|
|
|
|
INST_i32_clz = $67;
|
|
INST_i32_ctz = $68;
|
|
INST_i32_popcnt = $69;
|
|
INST_i32_add = $6a;
|
|
INST_i32_sub = $6b;
|
|
INST_i32_mul = $6c;
|
|
INST_i32_div_s = $6d;
|
|
INST_i32_div_u = $6e;
|
|
INST_i32_rem_s = $6f;
|
|
INST_i32_rem_u = $70;
|
|
INST_i32_and = $71;
|
|
INST_i32_or = $72;
|
|
INST_i32_xor = $73;
|
|
INST_i32_shl = $74;
|
|
INST_i32_shr_s = $75;
|
|
INST_i32_shr_u = $76;
|
|
INST_i32_rotl = $77;
|
|
INST_i32_rotr = $78;
|
|
INST_i64_clz = $79;
|
|
INST_i64_ctz = $7a;
|
|
INST_i64_popcnt = $7b;
|
|
INST_i64_add = $7c;
|
|
INST_i64_sub = $7d;
|
|
INST_i64_mul = $7e;
|
|
INST_i64_div_s = $7f;
|
|
INST_i64_div_u = $80;
|
|
INST_i64_rem_s = $81;
|
|
INST_i64_rem_u = $82;
|
|
INST_i64_and = $83;
|
|
INST_i64_or = $84;
|
|
INST_i64_xor = $85;
|
|
INST_i64_shl = $86;
|
|
INST_i64_shr_s = $87;
|
|
INST_i64_shr_u = $88;
|
|
INST_i64_rotl = $89;
|
|
INST_i64_rotr = $8a;
|
|
INST_f32_abs = $8b;
|
|
INST_f32_neg = $8c;
|
|
INST_f32_ceil = $8d;
|
|
INST_f32_floor = $8e;
|
|
INST_f32_trunc = $8f;
|
|
INST_f32_nearest = $90;
|
|
INST_f32_sqrt = $91;
|
|
INST_f32_add = $92;
|
|
INST_f32_sub = $93;
|
|
INST_f32_mul = $94;
|
|
INST_f32_div = $95;
|
|
INST_f32_min = $96;
|
|
INST_f32_max = $97;
|
|
INST_f32_copysign = $98;
|
|
INST_f64_abs = $99;
|
|
INST_f64_neg = $9a;
|
|
INST_f64_ceil = $9b;
|
|
INST_f64_floor = $9c;
|
|
INST_f64_trunc = $9d;
|
|
INST_f64_nearest = $9e;
|
|
INST_f64_sqrt = $9f;
|
|
INST_f64_add = $a0;
|
|
INST_f64_sub = $a1;
|
|
INST_f64_mul = $a2;
|
|
INST_f64_div = $a3;
|
|
INST_f64_min = $a4;
|
|
INST_f64_max = $a5;
|
|
INST_f64_copysign = $a6;
|
|
|
|
INST_i32_eqz = $45;
|
|
INST_i32_eq = $46;
|
|
INST_i32_ne = $47;
|
|
INST_i32_lt_s = $48;
|
|
INST_i32_lt_u = $49;
|
|
INST_i32_gt_s = $4a;
|
|
INST_i32_gt_u = $4b;
|
|
INST_i32_le_s = $4c;
|
|
INST_i32_le_u = $4d;
|
|
INST_i32_ge_s = $4e;
|
|
INST_i32_ge_u = $4f;
|
|
INST_i64_eqz = $50;
|
|
INST_i64_eq = $51;
|
|
INST_i64_ne = $52;
|
|
INST_i64_lt_s = $53;
|
|
INST_i64_lt_u = $54;
|
|
INST_i64_gt_s = $55;
|
|
INST_i64_gt_u = $56;
|
|
INST_i64_le_s = $57;
|
|
INST_i64_le_u = $58;
|
|
INST_i64_ge_s = $59;
|
|
INST_i64_ge_u = $5a;
|
|
INST_f32_eq = $5b;
|
|
INST_f32_ne = $5c;
|
|
INST_f32_lt = $5d;
|
|
INST_f32_gt = $5e;
|
|
INST_f32_le = $5f;
|
|
INST_f32_ge = $60;
|
|
INST_f64_eq = $61;
|
|
INST_f64_ne = $62;
|
|
INST_f64_lt = $63;
|
|
INST_f64_gt = $64;
|
|
INST_f64_le = $65;
|
|
INST_f64_ge = $66;
|
|
|
|
INST_i32_wrap_i64 = $a7;
|
|
INST_i32_trunc_f32_s = $a8;
|
|
INST_i32_trunc_f32_u = $a9;
|
|
INST_i32_trunc_f64_s = $aa;
|
|
INST_i32_trunc_f64_u = $ab;
|
|
INST_i64_extend_i32_s = $ac;
|
|
INST_i64_extend_i32_u = $ad;
|
|
INST_i64_trunc_f32_s = $ae;
|
|
INST_i64_trunc_f32_u = $af;
|
|
INST_i64_trunc_f64_s = $b0;
|
|
INST_i64_trunc_f64_u = $b1;
|
|
INST_f32_convert_i32_s = $b2;
|
|
INST_f32_convert_i32_u = $b3;
|
|
INST_f32_convert_i64_s = $b4;
|
|
INST_f32_convert_i64_u = $b5;
|
|
INST_f32_demote_f64 = $b6;
|
|
INST_f64_convert_i32_s = $b7;
|
|
INST_f64_convert_i32_u = $b8;
|
|
INST_f64_convert_i64_s = $b9;
|
|
INST_f64_convert_i64_u = $ba;
|
|
INST_f64_promote_f32 = $bb;
|
|
INST_i32_reinterpret_f32 = $bc;
|
|
INST_i64_reinterpret_f64 = $bd;
|
|
INST_f32_reinterpret_i32 = $be;
|
|
INST_f64_reinterpret_i64 = $bf;
|
|
// ...
|
|
INST_REINTERPRET_I64 = $BF;
|
|
|
|
MIN_INST = INST_TRAP;
|
|
MAX_INST = INST_REINTERPRET_I64;
|
|
|
|
type
|
|
TInstParamType = (ipNone,
|
|
ipLeb, // label index or function index
|
|
ipOfsAlign, // memory arguments, ask for offset + align
|
|
ipi32, // signed Leb of maximum 4 bytes
|
|
ipi64, // signed Leb of maximum 8 bytes
|
|
ipu32, // unsigned Leb of maximum 4 bytes
|
|
ipu64, // unsigned Leb of maximum 8 bytes
|
|
ipf32, // float point single
|
|
ipf64, // float point double
|
|
ipJumpVec, // an array of jump labels used for br_table only
|
|
ipResType, // result type used for blocks, such as If, block or loop
|
|
ipCallType, // used for call_indirect
|
|
ipi32OrFunc, // use for i32.const. Either a numeric OR function id is accepted.
|
|
// numeric is used as an actually value.
|
|
// function Id will be replaced with a reference number to the function
|
|
// and relocation information would be generated
|
|
ipZero // followed by a single byte zero
|
|
);
|
|
TInstFlag = record
|
|
valid : Boolean;
|
|
Param : TInstParamType;
|
|
align : Byte; // used for memory operations only
|
|
end;
|
|
|
|
const
|
|
INST_FLAGS : array [MIN_INST..MAX_INST] of TInstFlag = (
|
|
(valid: true; Param: ipNone; align: 0) // 00 trap (unreachable)
|
|
,(valid: true; Param: ipNone; align: 0) // 01 nop
|
|
,(valid: true; Param: ipResType; align: 0) // 02 block
|
|
,(valid: true; Param: ipResType; align: 0) // 03 lock
|
|
,(valid: true; Param: ipResType; align: 0) // 04 if
|
|
,(valid: true; Param: ipNone; align: 0) // 05 else
|
|
,(valid: false; Param: ipNone; align: 0) // 06
|
|
,(valid: false; Param: ipNone; align: 0) // 07
|
|
,(valid: false; Param: ipNone; align: 0) // 08
|
|
,(valid: false; Param: ipNone; align: 0) // 09
|
|
,(valid: false; Param: ipNone; align: 0) // 0A
|
|
,(valid: true; Param: ipNone; align: 0) // 0B end
|
|
,(valid: true; Param: ipLeb; align: 0) // 0C br
|
|
,(valid: true; Param: ipLeb; align: 0) // 0D br_if
|
|
,(valid: true; Param: ipJumpVec; align: 0) // 0E br_table
|
|
,(valid: true; Param: ipNone; align: 0) // 0F return
|
|
,(valid: true; Param: ipLeb; align: 0) // 10 call
|
|
,(valid: true; Param: ipCallType; align: 0) // 11 call_indirect
|
|
,(valid: false; Param: ipNone; align: 0) // 12
|
|
,(valid: false; Param: ipNone; align: 0) // 13
|
|
,(valid: false; Param: ipNone; align: 0) // 14
|
|
,(valid: false; Param: ipNone; align: 0) // 15
|
|
,(valid: false; Param: ipNone; align: 0) // 16
|
|
,(valid: false; Param: ipNone; align: 0) // 17
|
|
,(valid: false; Param: ipNone; align: 0) // 18
|
|
,(valid: false; Param: ipNone; align: 0) // 19
|
|
,(valid: true; Param: ipNone; align: 0) // 1A drop
|
|
,(valid: true; Param: ipNone; align: 0) // 1B select
|
|
,(valid: false; Param: ipNone; align: 0) // 1C
|
|
,(valid: false; Param: ipNone; align: 0) // 1D
|
|
,(valid: false; Param: ipNone; align: 0) // 1E
|
|
,(valid: false; Param: ipNone; align: 0) // 1F
|
|
,(valid: true; Param: ipLeb; align: 0) // 20 local.get
|
|
,(valid: true; Param: ipLeb; align: 0) // 21 local.set
|
|
,(valid: true; Param: ipLeb; align: 0) // 22 local.tee
|
|
,(valid: true; Param: ipLeb; align: 0) // 23 global.get
|
|
,(valid: true; Param: ipLeb; align: 0) // 24 global.set
|
|
,(valid: false; Param: ipNone; align: 0) // 25
|
|
,(valid: false; Param: ipNone; align: 0) // 26
|
|
,(valid: false; Param: ipNone; align: 0) // 27
|
|
,(valid: true; Param: ipOfsAlign; align: 2) // 28 i32.load
|
|
,(valid: true; Param: ipOfsAlign; align: 3) // 29 i64_load
|
|
,(valid: true; Param: ipOfsAlign; align: 2) // 2A f32_load
|
|
,(valid: true; Param: ipOfsAlign; align: 3) // 2B f64_load
|
|
,(valid: true; Param: ipOfsAlign; align: 0) // 2C i32_load8_s
|
|
,(valid: true; Param: ipOfsAlign; align: 0) // 2D i32_load8_u
|
|
,(valid: true; Param: ipOfsAlign; align: 1) // 2E i32_load16_s
|
|
,(valid: true; Param: ipOfsAlign; align: 1) // 2F i32_load16_u
|
|
,(valid: true; Param: ipOfsAlign; align: 0) // 30 i64_load8_s
|
|
,(valid: true; Param: ipOfsAlign; align: 0) // 31 i64_load8_u
|
|
,(valid: true; Param: ipOfsAlign; align: 1) // 32 i64_load16_s
|
|
,(valid: true; Param: ipOfsAlign; align: 1) // 33 i64_load16_u
|
|
,(valid: true; Param: ipOfsAlign; align: 2) // 34 i64.load32_s
|
|
,(valid: true; Param: ipOfsAlign; align: 2) // 35 i64.load32_u
|
|
,(valid: true; Param: ipOfsAlign; align: 2) // 36 i32_store
|
|
,(valid: true; Param: ipOfsAlign; align: 3) // 37 i64_store
|
|
,(valid: true; Param: ipOfsAlign; align: 2) // 38 f32_store
|
|
,(valid: true; Param: ipOfsAlign; align: 3) // 39 f64_store
|
|
,(valid: true; Param: ipOfsAlign; align: 0) // 3A i32_store8
|
|
,(valid: true; Param: ipOfsAlign; align: 1) // 3B i32_store16
|
|
,(valid: true; Param: ipOfsAlign; align: 0) // 3C i64_store8
|
|
,(valid: true; Param: ipOfsAlign; align: 1) // 3D i64_store16
|
|
,(valid: true; Param: ipOfsAlign; align: 2) // 3E i64_store32
|
|
,(valid: true; Param: ipZero; align: 0) // 3F memory_size
|
|
,(valid: true; Param: ipZero; align: 0) // 40 memory_grow
|
|
,(valid: true; Param: ipi32OrFunc; align: 0) // 41 i32_const
|
|
,(valid: true; Param: ipi64; align: 0) // 42 i64_const
|
|
,(valid: true; Param: ipf32; align: 0) // 43 f32_const
|
|
,(valid: true; Param: ipf64; align: 0) // 44 f64_const
|
|
,(valid: true; Param: ipNone; align: 0) // 45 i32_eqz
|
|
,(valid: true; Param: ipNone; align: 0) // 46 i32_eq
|
|
,(valid: true; Param: ipNone; align: 0) // 47 i32_ne
|
|
,(valid: true; Param: ipNone; align: 0) // 48 i32_lt_s
|
|
,(valid: true; Param: ipNone; align: 0) // 49 i32_lt_u
|
|
,(valid: true; Param: ipNone; align: 0) // 4A i32_gt_s
|
|
,(valid: true; Param: ipNone; align: 0) // 4B i32_gt_u
|
|
,(valid: true; Param: ipNone; align: 0) // 4C i32_le_s
|
|
,(valid: true; Param: ipNone; align: 0) // 4D i32_le_u
|
|
,(valid: true; Param: ipNone; align: 0) // 4E i32_ge_s
|
|
,(valid: true; Param: ipNone; align: 0) // 4F i32_ge_u
|
|
,(valid: true; Param: ipNone; align: 0) // 50 i64_eqz
|
|
,(valid: true; Param: ipNone; align: 0) // 51 i64_eq
|
|
,(valid: true; Param: ipNone; align: 0) // 52 i64_ne
|
|
,(valid: true; Param: ipNone; align: 0) // 53 i64_lt_s
|
|
,(valid: true; Param: ipNone; align: 0) // 54 i64_lt_u
|
|
,(valid: true; Param: ipNone; align: 0) // 55 i64_gt_s
|
|
,(valid: true; Param: ipNone; align: 0) // 56 i64_gt_u
|
|
,(valid: true; Param: ipNone; align: 0) // 57 i64_le_s
|
|
,(valid: true; Param: ipNone; align: 0) // 58 i64_le_u
|
|
,(valid: true; Param: ipNone; align: 0) // 59 i64_ge_s
|
|
,(valid: true; Param: ipNone; align: 0) // 5A i64_ge_u
|
|
,(valid: true; Param: ipNone; align: 0) // 5B f32_eq
|
|
,(valid: true; Param: ipNone; align: 0) // 5C f32_ne
|
|
,(valid: true; Param: ipNone; align: 0) // 5D f32_lt
|
|
,(valid: true; Param: ipNone; align: 0) // 5E f32_gt
|
|
,(valid: true; Param: ipNone; align: 0) // 5F f32_le
|
|
,(valid: true; Param: ipNone; align: 0) // 60 f32_ge
|
|
,(valid: true; Param: ipNone; align: 0) // 61 f64_eq
|
|
,(valid: true; Param: ipNone; align: 0) // 62 f64_ne
|
|
,(valid: true; Param: ipNone; align: 0) // 63 f64_lt
|
|
,(valid: true; Param: ipNone; align: 0) // 64 f64_gt
|
|
,(valid: true; Param: ipNone; align: 0) // 65 f64_le
|
|
,(valid: true; Param: ipNone; align: 0) // 66 f64_ge
|
|
,(valid: true; Param: ipNone; align: 0) // 67 i32_clz
|
|
,(valid: true; Param: ipNone; align: 0) // 68 i32_ctz
|
|
,(valid: true; Param: ipNone; align: 0) // 69 i32_popcnt
|
|
,(valid: true; Param: ipNone; align: 0) // 6A i32_add
|
|
,(valid: true; Param: ipNone; align: 0) // 6B i32_sub
|
|
,(valid: true; Param: ipNone; align: 0) // 6C i32_mul
|
|
,(valid: true; Param: ipNone; align: 0) // 6D i32_div_s
|
|
,(valid: true; Param: ipNone; align: 0) // 6E i32_div_u
|
|
,(valid: true; Param: ipNone; align: 0) // 6F i32_rem_s
|
|
,(valid: true; Param: ipNone; align: 0) // 70 i32_rem_u
|
|
,(valid: true; Param: ipNone; align: 0) // 71 i32_and
|
|
,(valid: true; Param: ipNone; align: 0) // 72 i32_or
|
|
,(valid: true; Param: ipNone; align: 0) // 73 i32_xor
|
|
,(valid: true; Param: ipNone; align: 0) // 74 i32_shl
|
|
,(valid: true; Param: ipNone; align: 0) // 75 i32_shr_s
|
|
,(valid: true; Param: ipNone; align: 0) // 76 i32_shr_u
|
|
,(valid: true; Param: ipNone; align: 0) // 77 i32_rotl
|
|
,(valid: true; Param: ipNone; align: 0) // 78 i32_rotr
|
|
,(valid: true; Param: ipNone; align: 0) // 79 i64_clz
|
|
,(valid: true; Param: ipNone; align: 0) // 7A i64_ctz
|
|
,(valid: true; Param: ipNone; align: 0) // 7B i64_popcnt
|
|
,(valid: true; Param: ipNone; align: 0) // 7C i64_add
|
|
,(valid: true; Param: ipNone; align: 0) // 7D i64_sub
|
|
,(valid: true; Param: ipNone; align: 0) // 7E i64_mul
|
|
,(valid: true; Param: ipNone; align: 0) // 7F i64_div_s
|
|
,(valid: true; Param: ipNone; align: 0) // 80 i64_div_u
|
|
,(valid: true; Param: ipNone; align: 0) // 81 i64_rem_s
|
|
,(valid: true; Param: ipNone; align: 0) // 82 i64_rem_u
|
|
,(valid: true; Param: ipNone; align: 0) // 83 i64_and
|
|
,(valid: true; Param: ipNone; align: 0) // 84 i64_or
|
|
,(valid: true; Param: ipNone; align: 0) // 85 i64_xor
|
|
,(valid: true; Param: ipNone; align: 0) // 86 i64_shl
|
|
,(valid: true; Param: ipNone; align: 0) // 87 i64_shr_s
|
|
,(valid: true; Param: ipNone; align: 0) // 88 i64_shr_u
|
|
,(valid: true; Param: ipNone; align: 0) // 89 i64_rotl
|
|
,(valid: true; Param: ipNone; align: 0) // 8A i64_rotr
|
|
,(valid: true; Param: ipNone; align: 0) // 8B f32_abs
|
|
,(valid: true; Param: ipNone; align: 0) // 8C f32_neg
|
|
,(valid: true; Param: ipNone; align: 0) // 8D f32_ceil
|
|
,(valid: true; Param: ipNone; align: 0) // 8E f32_floor
|
|
,(valid: true; Param: ipNone; align: 0) // 8F f32_trunc
|
|
,(valid: true; Param: ipNone; align: 0) // 90 f32_nearest
|
|
,(valid: true; Param: ipNone; align: 0) // 91 f32_sqrt
|
|
,(valid: true; Param: ipNone; align: 0) // 92 f32_add
|
|
,(valid: true; Param: ipNone; align: 0) // 93 f32_sub
|
|
,(valid: true; Param: ipNone; align: 0) // 94 f32_mul
|
|
,(valid: true; Param: ipNone; align: 0) // 95 f32_div
|
|
,(valid: true; Param: ipNone; align: 0) // 96 f32_min
|
|
,(valid: true; Param: ipNone; align: 0) // 97 f32_max
|
|
,(valid: true; Param: ipNone; align: 0) // 98 f32_copysign
|
|
,(valid: true; Param: ipNone; align: 0) // 99 f64_abs
|
|
,(valid: true; Param: ipNone; align: 0) // 9A f64_neg
|
|
,(valid: true; Param: ipNone; align: 0) // 9B f64_ceil
|
|
,(valid: true; Param: ipNone; align: 0) // 9C f64_floor
|
|
,(valid: true; Param: ipNone; align: 0) // 9D f64_trunc
|
|
,(valid: true; Param: ipNone; align: 0) // 9E f64_nearest
|
|
,(valid: true; Param: ipNone; align: 0) // 9F f64_sqrt
|
|
,(valid: true; Param: ipNone; align: 0) // A0 f64_add
|
|
,(valid: true; Param: ipNone; align: 0) // A1 f64_sub
|
|
,(valid: true; Param: ipNone; align: 0) // A2 f64_mul
|
|
,(valid: true; Param: ipNone; align: 0) // A3 f64_div
|
|
,(valid: true; Param: ipNone; align: 0) // A4 f64_min
|
|
,(valid: true; Param: ipNone; align: 0) // A5 f64_max
|
|
,(valid: true; Param: ipNone; align: 0) // A6 f64_copysign
|
|
,(valid: true; Param: ipNone; align: 0) // A7 i32_wrap_i64
|
|
,(valid: true; Param: ipNone; align: 0) // A8 i32_trunc_f32_s
|
|
,(valid: true; Param: ipNone; align: 0) // A9 i32_trunc_f32_u
|
|
,(valid: true; Param: ipNone; align: 0) // AA i32_trunc_f64_s
|
|
,(valid: true; Param: ipNone; align: 0) // AB i32_trunc_f64_u
|
|
,(valid: true; Param: ipNone; align: 0) // AC i64_extend_i32_s
|
|
,(valid: true; Param: ipNone; align: 0) // AD i64_extend_i32_u
|
|
,(valid: true; Param: ipNone; align: 0) // AE i64_trunc_f32_s
|
|
,(valid: true; Param: ipNone; align: 0) // AF i64_trunc_f32_u
|
|
,(valid: true; Param: ipNone; align: 0) // B0 i64_trunc_f64_s
|
|
,(valid: true; Param: ipNone; align: 0) // B1 i64_trunc_f64_u
|
|
,(valid: true; Param: ipNone; align: 0) // B2 f32_convert_i32_s
|
|
,(valid: true; Param: ipNone; align: 0) // B3 f32_convert_i32_u
|
|
,(valid: true; Param: ipNone; align: 0) // B4 f32_convert_i64_s
|
|
,(valid: true; Param: ipNone; align: 0) // B5 f32_convert_i64_u
|
|
,(valid: true; Param: ipNone; align: 0) // B6 f32_demote_f64
|
|
,(valid: true; Param: ipNone; align: 0) // B7 f64_convert_i32_s
|
|
,(valid: true; Param: ipNone; align: 0) // B8 f64_convert_i32_u
|
|
,(valid: true; Param: ipNone; align: 0) // B9 f64_convert_i64_s
|
|
,(valid: true; Param: ipNone; align: 0) // BA f64_convert_i64_u
|
|
,(valid: true; Param: ipNone; align: 0) // BB f64_promote_f32
|
|
,(valid: true; Param: ipNone; align: 0) // BC i32_reinterpret_f32
|
|
,(valid: true; Param: ipNone; align: 0) // BD i64_reinterpret_f64
|
|
,(valid: true; Param: ipNone; align: 0) // BE f32_reinterpret_i32
|
|
,(valid: true; Param: ipNone; align: 0) // BF f64_reinterpret_i64
|
|
);
|
|
|
|
function InstLen(st: TStream; endOfInst: Byte = INST_END): Integer;
|
|
|
|
implementation
|
|
|
|
function InstLen(st: TStream; endOfInst: Byte = INST_END): Integer;
|
|
var
|
|
cd : byte;
|
|
ofs : int64;
|
|
b : byte;
|
|
sz : int64;
|
|
begin
|
|
ofs := st.Position;
|
|
try
|
|
sz:=st.Size;
|
|
while ofs < sz do begin
|
|
cd := st.ReadByte;
|
|
|
|
if (cd > MAX_INST) then begin
|
|
Result:=-1; // invalid code
|
|
Exit;
|
|
end;
|
|
if cd = endOfInst then break;
|
|
|
|
case INST_FLAGS[cd].Param of
|
|
ipLeb:
|
|
ReadU(st);
|
|
ipOfsAlign: begin
|
|
ReadU(st);
|
|
ReadU(st);
|
|
end;
|
|
ipJumpVec: begin // not implemented :(
|
|
Result:=-2;
|
|
Exit;
|
|
end;
|
|
ipi32: ReadS(st, 32);
|
|
ipi64: ReadS(st, 64);
|
|
ipf32: st.Position:=st.Position+4;
|
|
ipf64: st.Position:=st.Position+8;
|
|
ipResType: begin
|
|
// it's a block. must go into recursion
|
|
b := st.ReadByte; // reading type
|
|
|
|
if (cd=INST_IF) and (b <> VALTYPE_NONE) then begin
|
|
InstLen(st, INST_ELSE);
|
|
InstLen(st, INST_END);
|
|
end else
|
|
InstLen(st, INST_END)
|
|
end;
|
|
end;
|
|
end;
|
|
finally
|
|
Result := st.Position - ofs;
|
|
st.Position:=ofs;
|
|
end;
|
|
end;
|
|
|
|
end.
|