import * as ieee754 from "./ieee754" ; import { flatten } from "./utils" ; export const MAGIC = [ 0x00 , 0x61 , 0x73 , 0x6d ] ; export const WASM_VERSION = [ 0x01 , 0x00 , 0x00 , 0x00 ] ; export const EPSILON = 0.00001 ; export const SECTION = { TYPE : 1 , IMPORT : 2 , FUNC : 3 , MEMORY : 5 , GLOBAL : 6 , EXPORT : 7 , CODE : 10 , } ; export const EXPORT_TYPE = { FUNC : 0x00 , TABLE : 0x01 , MEMORY : 0x02 , GLOBAL : 0x03 , } as const ; type Align = 1 | 2 | 3 ; export const op = { block : ( blockType ) => [ 0x02 , blockType ] , loop : ( blockType ) => [ 0x03 , blockType ] , if : ( retType ) => [ 0x04 , retType ] , else : 0x05 , end : 0x0b , br_if : ( i ) => [ 0x0d , ... unsignedLEB128 ( i ) ] , call : ( i ) => [ 0x10 , ... unsignedLEB128 ( i ) ] , drop : 0x1a , select : 0x1b , local_get : ( i ) => [ 0x20 , ... unsignedLEB128 ( i ) ] , local_set : ( i ) => [ 0x21 , ... unsignedLEB128 ( i ) ] , local_tee : ( i ) => [ 0x22 , ... unsignedLEB128 ( i ) ] , global_get : ( i ) => [ 0x23 , ... unsignedLEB128 ( i ) ] , global_set : ( i ) => [ 0x24 , ... unsignedLEB128 ( i ) ] , f64_load : ( align , offset ) => [ 0x2b , ... unsignedLEB128 ( align ) , ... unsignedLEB128 ( offset ) , ] , f64_store : ( align , offset ) => [ 0x39 , ... unsignedLEB128 ( align ) , ... unsignedLEB128 ( offset ) , ] , i32_const : ( i ) => [ 0x41 , ... signedLEB128 ( i ) ] , f64_const : ( i ) => [ 0x44 , ... encodef64 ( i ) ] , i32_eqz : 0x45 , i32_ne : 0x47 , i32_lt_s : 0x48 , i32_lt_u : 0x49 , i32_gt_s : 0x4a , i32_le_s : 0x4c , i32_le_u : 0x4d , i32_ge_s : 0x4e , f64_eq : 0x61 , f64_ne : 0x62 , f64_lt : 0x63 , f64_gt : 0x64 , f64_le : 0x65 , f64_ge : 0x66 , i32_add : 0x6a , i32_sub : 0x6b , i32_mul : 0x6c , i32_rem_s : 0x6f , i32_and : 0x71 , i32_or : 0x72 , i64_rem_s : 0x81 , i64_and : 0x83 , i64_or : 0x84 , f64_abs : 0x99 , f64_neg : 0x9a , f64_ceil : 0x9b , f64_floor : 0x9c , f64_sqrt : 0x9f , f64_add : 0xa0 , f64_sub : 0xa1 , f64_mul : 0xa2 , f64_div : 0xa3 , f64_min : 0xa4 , f64_max : 0xa5 , i32_trunc_f64_s : 0xaa , i32_trunc_f64_u : 0xab , i64_trunc_s_f64 : 0xb0 , f64_convert_i64_s : 0xb9 , f64_convert_i32_s : 0xb7 , } ; export const VAL_TYPE = { i32 : 0x7f , i64 : 0x7e , f32 : 0x7d , f64 : 0x7c , } as const ; export const MUTABILITY = { const : 0x00 , var : 0x01 , } ; export const BLOCK = { void : 0x40 , i32 : 0x7f , i64 : 0x7e , f32 : 0x7d , f64 : 0x7c , } as const ; type BlockKeys = keyof typeof BLOCK ; export type BlockType = typeof BLOCK [ BlockKeys ] ; export const FUNCTION_TYPE = 0x60 ; export const MEMORY_IDX = 0x02 ; export const GLOBAL_TYPE = 0x03 ; export const TYPE_IDX = 0x00 ; export const IS_ZEROISH = [ op . f64_abs , ... op . f64_const ( EPSILON ) , op . f64_lt , ] ; export const IS_NOT_ZEROISH = [ op . f64_abs , ... op . f64_const ( EPSILON ) , op . f64_gt , ] ; export function encodef64 ( num ) { const arr = new Uint8Array ( 8 ) ; ieee754 . write ( arr , num ) ; return arr ; } export const encodeString = ( str ) : number [ ] => [ str . length ] . concat ( str . split ( "" ) . map ( s => s . charCodeAt ( 0 ) ) ) ; export function unsignedLEB128 ( n ) { const buffer = [ ] ; do { let byte = n & 0x7f ; n >>>= 7 ; if ( n !== 0 ) { byte |= 0x80 ; } buffer . push ( byte ) ; } while ( n !== 0 ) ; return buffer ; } export function signedLEB128 ( value ) { let bytes = [ ] ; let byte = 0x00 ; let size = Math . ceil ( Math . log2 ( Math . abs ( value ) ) ) ; let negative = value < 0 ; let more = true ; while ( more ) { byte = value & 127 ; value = value >> 7 ; if ( negative ) { value = value | - ( 1 << ( size - 7 ) ) ; } if ( ( value == 0 && ( byte & 0x40 ) == 0 ) || ( value == - 1 && ( byte & 0x40 ) == 0x40 ) ) { more = false ; } else { byte = byte | 128 ; } bytes . push ( byte ) ; } return bytes ; } export const encodeFlatVector = ( data ) : number [ ] => unsignedLEB128 ( data . length ) . concat ( data ) ; export const encodeNestedVector = ( data ) : number [ ] => unsignedLEB128 ( data . length ) . concat ( flatten ( data ) ) ; export function encodeSection ( type , subSections ) { if ( subSections . length === 0 ) { return [ ] ; } const vec = encodeFlatVector ( encodeNestedVector ( subSections ) ) ; vec . unshift ( type ) ; return vec ; }