# 全局

以下全局常量和函数与标准库的类一起存在。

# 常量

  • const NaN: auto // f32 or f64
    

    根据上下文,作为 32 位或 64 位浮点数的非数。编译为常量。

  • const Infinity: auto // f32 or f64
    

    根据上下文,作为 32 位或 64 位浮点数的正无穷大。编译为常量。

# 函数

  • function isNaN<T>(value: T): bool
    

    测试 32 位或 64 位浮点数是否为 NaN

  • function isFinite<T>(value: T): bool
    

    测试 32 位或 64 位浮点数是否为有限,即不是 NaN 或 +/-Infinity

  • function parseInt(str: string, radix?: i32): f64
    

    将表示整数的字符串解析为 f64 数字。在无效输入时返回 NaN

    类型特定的 parseInt 变体单独提供

    • F32.parseInt 解析为 32 位浮点数。
    • I8.parseInt 解析为带符号的 8 位整数,分别为 U8.parseInt 如果无符号。
    • I16.parseInt 解析为带符号的 16 位整数,分别为 U16.parseInt 如果无符号。
    • I32.parseInt 解析为带符号的 32 位整数,分别为 U32.parseInt 如果无符号。
    • I64.parseInt 解析为带符号的 64 位整数,分别为 U64.parseInt 如果无符号。
  • function parseFloat(str: string): f64
    

    将字符串解析为 64 位浮点数。在无效输入时返回 NaN

# 内建函数

以下内建函数提供对 WebAssembly 和编译器功能的直接访问。它们构成了标准库的低级基础,同时也供所有人使用,以便在需要直接利用 WebAssembly 或编译器时使用。

# 静态类型检查

通过使用以下特殊的类型检查,特别是在泛型上下文中,可以静态地消除未执行的分支,从而导致处理一种特定类型的具体 WebAssembly 函数。

  • function isInteger<T>(value?: T): bool
    

    测试指定的类型表达式是否为整数类型且不是引用。编译为常量。

  • function isSigned<T>(value?: T): bool
    

    测试指定的类型表达式是否可以表示负数。编译为常量。

  • function isFloat<T>(value?: T): bool
    

    测试指定的类型表达式是否为浮点类型。编译为常量。

  • function isVector<T>(value?: T): bool
    

    测试指定的类型表达式是否为 SIMD 向量类型。编译为常量。

  • function isReference<T>(value?: T): bool
    

    测试指定的类型表达式是否为引用类型。编译为常量。

  • function isString<T>(value?: T): bool
    

    测试指定的类型表达式是否可以作为字符串使用。编译为常量。

  • function isArray<T>(value?: T): bool
    

    测试指定的类型表达式是否可以作为数组使用。编译为常量。

  • function isFunction<T>(value?: T): bool
    

    测试指定的类型表达式是否为函数类型。编译为常量。

  • function isNullable<T>(value?: T): bool
    

    测试指定的类型表达式是否为可空引用类型。编译为常量。

  • function isDefined(expression: auto): bool
    

    测试指定的表达式是否解析为已定义的元素。编译为常量。

  • function isConstant(expression: auto): bool
    

    测试指定的表达式是否计算为常量值。编译为常量。

  • function isManaged<T>(expression: auto): bool
    

    测试指定的类型表达式是否为托管类型。编译为常量。通常只在实现自定义集合类时才相关。

# 静态类型检查示例

function add<T>(a: T, b: T): T {
  return a + b // addition if numeric, string concatenation if a string
}

function add<T>(a: T, b: T): T {
  if (isString<T>()) { // eliminated if T is not a string
    return parseInt(a) + parseInt(b)
  } else { // eliminated if T is a string
    return a + b
  }
}

提示

如果你在可预见的未来不会使用低级 WebAssembly,请随时在以后再回来查看以下段落。

# 实用程序

  • function bswap<T>(value: T): T
    

    反转指定整数的字节顺序。

  • function sizeof<T>(): usize
    

    确定相应的基本类型的字节大小。意思是:如果 T 是一个类类型,则返回 usize(指针类型)的大小。要获取类在内存中的大小,请改用 offsetof<T>()。编译为常量。

  • function offsetof<T>(fieldName?: string): usize
    

    确定给定类类型中指定字段的偏移量。如果省略 fieldName,则返回可以解释为类大小或下一个字段将位于的偏移量(在对齐之前)。编译为常量。fieldName 参数必须是编译时常量 string,因为在运行时不再有关于字段名称的信息。因此,在计算返回值时,必须知道字段的名称。

  • function alignof<T>(): usize
    

    确定指定底层基本类型的对齐方式(log2);例如,如果 T 是一个类类型,则返回 usize 的对齐方式。编译为常量。

  • function assert<T>(isTrueish: T, message?: string): T
    

    如果指定的值不是真值,则抛出异常,否则返回不可空的值。类似于 C 中的断言,如果期望值失败,则中止整个程序。在需要时,可以使用 --noAssert 编译器选项在生产中禁用断言。

  • function trace(message: string, n?: i32, a0?: f64, a1?: f64, a2?: f64, a3?: f64, a4?: f64): void
    

    简单的跟踪函数,它将 message 和 5 个可选的 f64 参数打印到控制台。n 是已用参数的数量。

    # 使用示例

    trace("foo");
    trace("one arg:", 1, 5.0);
    trace("three args:", 3, 1.0, <f64>2, 3);
    
  • function instantiate<T>(...args: auto[]): T
    

    使用指定的构造函数参数实例化一个新的 T 实例。

  • function changetype<T>(value: auto): T
    

    将值的类型更改为另一个类型。用于将类实例强制转换为其指针值,反之亦然。

  • function idof<T>(): u32
    

    获取计算的类类型的唯一 ID。通常只在分配对象或在外部处理 RTTI 时才相关。

  • function nameof<T>(value?: T): string
    

    返回给定类型的名称。

# WebAssembly

# 数学

以下泛型内建函数直接编译为 WebAssembly 指令。

  • function clz<T>(value: T): T
    
    对 32 位或 64 位整数执行与符号无关的前导零位计数操作。如果值为零,则所有零位都被视为前导。
    T 指令
    i8, u8, i16, u16, i32, u32, bool i32.clz
    i64, u64 i64.clz
  • function ctz<T>(value: T): T
    
    对 32 位或 64 位整数执行与符号无关的后缀零位计数操作。如果值为零,则所有零位都被视为后缀。
    T 指令
    i8, u8, i16, u16, i32, u32, bool i32.ctz
    i64, u64 i64.ctz
  • function popcnt<T>(value: T): T
    
    对 32 位或 64 位整数执行与符号无关的一位计数操作。
    T 指令
    i8, u8, i16, u16, i32, u32 i32.popcnt
    i64, u64 i64.popcnt
    bool none
  • function rotl<T>(value: T, shift: T): T
    
    对 32 位或 64 位整数执行与符号无关的左移操作。
    T 指令
    i32, u32 i32.rotl
    i64, u64 i64.rotl
    i8, u8, i16, u16 emulated
    bool none
  • function rotr<T>(value: T, shift: T): T
    
    对 32 位或 64 位整数执行与符号无关的右移操作。
    T 指令
    i32, u32 i32.rotr
    i64, u64 i64.rotr
    i8, u8, i16, u16 emulated
    bool none
  • function abs<T>(value: T): T
    
    计算整数或浮点数的绝对值。
    T 指令
    f32 f32.abs
    f64 f64.abs
    i8, i16, i32, i64 emulated
    u8, u16, u32, u64, bool none
  • function max<T>(left: T, right: T): T
    
    确定两个整数或浮点数的最大值。如果任一操作数为 NaN,则返回 NaN
    T 指令
    f32 f32.max
    f64 f64.max
    i8, u8, i16, u16, i32, u32, i64, u64, bool emulated
  • function min<T>(left: T, right: T): T
    
    确定两个整数或浮点数的最小值。如果任一操作数为 NaN,则返回 NaN
    T 指令
    f32 f32.min
    f64 f64.min
    i8, u8, i16, u16, i32, u32, i64, u64, bool emulated
  • function ceil<T>(value: T): T
    
    对 32 位或 64 位浮点数执行向上取整操作。
    T 指令
    f32 f32.ceil
    f64 f64.ceil
    i8, u8, i16, u16, i32, u32, i64, u64, bool none
  • function floor<T>(value: T): T
    
    对 32 位或 64 位浮点数执行向下取整操作。
    T 指令
    f32 f32.floor
    f64 f64.floor
    i8, u8, i16, u16, i32, u32, i64, u64, bool none
  • function copysign<T>(x: T , y: T): T
    
    x 的大小和 y 的符号组成一个 32 位或 64 位浮点数。
    T 指令
    f32 f32.copysign
    f64 f64.copysign
  • function nearest<T>(value: T): T
    
    将 32 位或 64 位浮点数四舍五入到最接近的整数 四舍五入到偶数
    T 指令
    f32 f32.nearest
    f64 f64.nearest
    i8, u8, i16, u16, i32, u32, i64, u64, bool none
  • function reinterpret<TTo>(value: auto): TTo
    
    将指定值的位重新解释为类型 T
    TTo 指令
    i32, u32 i32.reinterpret_f32
    i64, u64 i64.reinterpret_f64
    f32 f32.reinterpret_i32
    f64 f64.reinterpret_i64
  • function sqrt<T>(value: T): T
    
    计算 32 位或 64 位浮点数的平方根。
    T 指令
    f32 f32.sqrt
    f64 f64.sqrt
  • function trunc<T>(value: T): T
    
    将 32 位或 64 位浮点数四舍五入到最接近零的整数。
    T 指令
    f32 f32.trunc
    f64 f64.trunc
    i8, u8, i16, u16, i32, u32, i64, u64, bool none

# 内存

类似地,以下内置函数会发出访问或修改内存的 WebAssembly 指令。

注意

如果提供,immOffsetimmAlign 参数必须是编译时常量值。有关更多详细信息,请参阅 原理 (opens new window)

  • function load<T>(ptr: usize, immOffset?: usize, immAlign?: usize): T
    
    从内存中加载指定类型的值。等效于其他语言中的指针解引用。
    T 指令 如果上下文类型为 i64
    i8 i32.load8_s i64.load8_s
    u8 i32.load8_u i64.load8_u
    i16 i32.load16_s i64.load16_s
    u16 i32.load16_u i64.load16_u
    i32 i32.load i64.load32_s
    u32 i32.load i64.load32_u
    i64, u64 i64.load n/a
    f32 f32.load n/a
    f64 f64.load n/a
    <ref> i32/i64.load n/a
  • function store<T>(ptr: usize, value: auto, immOffset?: usize, immAlign?: usize): void
    
    将指定类型的值存储到内存中。等效于其他语言中的指针解引用并赋值。
    T 指令 如果值为 i64
    i8, u8 i32.store8 i64.store8
    i16, u16 i32.store16 i64.store16
    i32, u32 i32.store i64.store32
    i64, u64 i64.store n/a
    f32 f32.store n/a
    f64 f64.store n/a
    <ref> i32/i64.store n/a
  • function memory.size(): i32
    

    以页为单位返回当前内存的大小。一页为 64kb。

  • function memory.grow(value: i32): i32
    

    以给定的无符号增量页数增加线性内存。一页为 64kb。返回以页为单位的先前内存大小,或者在失败时返回 -1

    警告

    在存在内存管理器的情况下调用 memory.grow 可能会破坏它。

  • function memory.copy(dst: usize, src: usize, n: usize): void
    

    src 中的 n 个字节复制到 dst 。区域可能重叠。如果启用了批量内存,则会发出相应的指令,否则会提供一个填充程序。

  • function memory.fill(dst: usize, value: u8, n: usize): void
    

    用给定的字节 value 填充 dst 处的 n 个字节。如果启用了批量内存,则会发出相应的指令,否则会提供一个填充程序。

  • function memory.repeat(dst: usize, src: usize, srcLength: usize, count: usize): void
    

    将作为 src 给出的字节序列(长度为 srcLength)重复 count 次到目标 dst 中。

  • function memory.compare(lhs: usize, rhs: usize, n: usize): i32
    

    比较 leftright 的前 n 个字节,并返回一个值,表示它们的关系。

    • 负值 如果 lhs 中第一个不同的字节小于 rhs 中的对应字节。
    • 正值 如果 lhs 中第一个不同的字节大于 rhs 中的对应字节。
    • 如果 lhsrhs 的所有 n 个字节都相等。
  • function memory.data(size: i32, align?: i32): usize
    

    获取指向给定大小的零填充静态内存块的指针。对齐方式默认为 16。参数必须是编译时常量。

  • function memory.data<T>(values: T[], align?: i32): usize
    

    获取指向预初始化的静态内存块的指针。对齐方式默认为 T 的大小。参数必须是编译时常量。

# 控制流

  • function select<T>(ifTrue: T, ifFalse: T, condition: bool): T
    

    根据条件选择两个预先计算的值之一。不同于 if/else,因为始终执行两个分支,并且最终值是根据条件在之后选择的。只有在条件是随机的(意味着:分支预测不会执行良好)并且两个备选方案都很便宜的情况下,才会比 if/else 执行得更好。还值得注意的是,Binaryen 会自动执行相关的优化,例如切换到 select,因此简单地使用三元 ? : 可能更可取。

  • function unreachable(): auto
    

    发出一个不可达指令,该指令在执行时会导致运行时错误(陷阱)。既是语句,也是任何类型的表达式。请注意,在受控代码中发生陷阱很可能会导致内存泄漏,甚至会破坏程序,因为它会过早地终止执行。

# 原子操作 🦄

以下指令表示 WebAssembly 线程和原子操作 (opens new window) 规范。必须使用 --enable threads 启用。

  • function atomic.load<T>(ptr: usize, immOffset?: usize): T
    

    原子地从内存中加载一个整数值并返回它。

  • function atomic.store<T>(ptr: usize, value: auto, immOffset?: usize): void
    

    原子地将一个整数值存储到内存中。

  • function atomic.add<T>(ptr: usize, value: T, immOffset?: usize): T
    

    原子地将一个整数值加到内存中。

  • function atomic.sub<T>(ptr: usize, value: T, immOffset?: usize): T
    

    原子地从内存中减去一个整数值。

  • function atomic.and<T>(ptr: usize, value: T, immOffset?: usize): T
    

    原子地对内存中的整数值执行按位 AND 操作。

  • function atomic.or<T>(ptr: usize, value: T, immOffset?: usize): T
    

    原子地对内存中的整数值执行按位 OR 操作。

  • function atomic.xor<T>(ptr: usize, value: T, immOffset?: usize): T
    

    原子地对内存中的整数值执行按位 XOR 操作。

  • function atomic.xchg<T>(ptr: usize, value: T, immOffset?: usize): T
    

    原子地交换内存中的一个整数值。

  • function atomic.cmpxchg<T>(ptr: usize, expected: T, replacement: T, immOffset?: usize): T
    

    如果条件满足,则原子地比较和交换内存中的一个整数值。

  • function atomic.wait<T>(ptr: usize, expected: T, timeout: i64): AtomicWaitResult
    

    对内存中的地址执行等待操作,如果整数值条件满足,则挂起此代理。返回值是

    描述
    0 OK - 由另一个代理唤醒。
    1 NOT_EQUAL - 加载的值与预期值不匹配。
    2 TIMED_OUT - 在超时过期之前没有唤醒。
  • function atomic.notify(ptr: usize, count: i32): i32
    

    对内存中的地址执行通知操作,唤醒挂起的代理。

  • function atomic.fence(): void
    

    执行栅栏操作,保留高级语言的同步保证。

# SIMD 🦄

同样,这些表示 WebAssembly SIMD (opens new window) 规范。必须使用 --enable simd 启用。

  • function v128(a: i8, ... , p: i8): v128
    

    从十六个 8 位整数值初始化一个 128 位向量。参数必须是编译时常量。

    有关其他类型特定的选项,请参阅 构造常量向量

  • function v128.splat<T>(x: T): v128
    
    创建一个具有相同通道的向量。
    T 指令
    i8, u8 i8x16.splat
    i16, u16 i16x8.splat
    i32, u32 i32x4.splat
    i64, u64 i64x2.splat
    f32 f32x4.splat
    f64 f64x2.splat
  • function v128.extract_lane<T>(x: v128, idx: u8): T
    
    将一个通道提取为标量。
    T 指令
    i8 i8x16.extract_lane_s
    u8 i8x16.extract_lane_u
    i16 i16x8.extract_lane_s
    u16 i16x8.extract_lane_u
    i32, u32 i32x4.extract_lane
    i64, u64 i64x2.extract_lane
    f32 f32x4.extract_lane
    f64 f64x2.extract_lane
  • function v128.replace_lane<T>(x: v128, idx: u8, value: T): v128
    
    替换一个通道。
    T 指令
    i8, u8 i8x16.replace_lane
    i16, u16 i16x8.replace_lane
    i32, u32 i32x4.replace_lane
    i64, u64 i64x2.replace_lane
    f32 f32x4.replace_lane
    f64 f64x2.replace_lane
  • function v128.shuffle<T>(a: v128, b: v128, ...lanes: u8[]): v128
    
    根据指定的通道索引从任一向量中选择通道。
    T 指令
    i8, u8 i8x16.shuffle
    i16, u16 i8x16.shuffle 模拟 i16x8.shuffle
    i32, u32 i8x16.shuffle 模拟 i32x4.shuffle
    i64, u64 i8x16.shuffle 模拟 i64x2.shuffle
    f32 i8x16.shuffle 模拟 f32x4.shuffle
    f64 i8x16.shuffle 模拟 f64x2.shuffle
  • function v128.swizzle(a: v128, s: v128): v128
    

    根据第二个向量 8 位通道指定的索引 [0-15] 从第一个向量中选择 8 位通道。

  • function v128.load(ptr: usize, immOffset?: usize, immAlign?: usize): v128
    

    从内存中加载向量。

  • function v128.load_ext<TFrom>(ptr: usize, immOffset?: usize, immAlign?: usize): v128
    
    通过加载指定整数类型的通道并将每个通道扩展到下一个更大的类型来创建一个向量。
    TFrom 指令
    i8 v128.load8x8_s
    u8 v128.load8x8_u
    i16 v128.load16x4_s
    u16 v128.load16x4_u
    i32 v128.load32x2_s
    u32 v128.load32x2_u
  • function v128.load_zero<TFrom>(ptr: usize, immOffset?: usize, immAlign?: usize): v128
    
    通过将指定类型的值加载到最低位并将向量的所有其他位初始化为零来创建一个向量。
    TFrom 指令
    i32, u32, f32 v128.load32_zero
    i64, u64, f64 v128.load64_zero
  • function v128.load_lane<T>(
      ptr: usize, vec: v128, idx: u8, immOffset?: usize, immAlign?: usize
    ): v128
    
    将内存中的单个通道加载到给定向量的指定通道中。其他通道按原样旁路。
    T 指令
    i8, u8 v128.load8_lane
    i16, u16 v128.load16_lane
    i32, u32, f32 v128.load32_lane
    i64, u64, f64 v128.load64_lane
  • function v128.store_lane<T>(
      ptr: usize, vec: v128, idx: u8, immOffset?: usize, immAlign?: usize
    ): v128
    
    将给定向量的指定索引处的单个通道存储到内存中。
    T 指令
    i8, u8 v128.store8_lane
    i16, u16 v128.store16_lane
    i32, u32, f32 v128.store32_lane
    i64, u64, f64 v128.store64_lane
  • function v128.load_splat<T>(ptr: usize, immOffset?: usize, immAlign?: usize): v128
    
    通过加载散列的值来创建一个具有相同通道的向量。
    T 指令
    i8, u8 v128.load8_splat
    i16, u16 v128.load16_splat
    i32, u32, f32 v128.load32_splat
    i64, u64, f64 v128.load64_splat
  • function v128.store(ptr: usize, value: v128, immOffset?: usize, immAlign?: usize): void
    

    将向量存储到内存中。

  • function v128.add<T>(a: v128, b: v128): v128
    
    将每个通道加起来。
    T 指令
    i8, u8 i8x16.add
    i16, u16 i16x8.add
    i32, u32 i32x4.add
    i64, u64 i64x2.add
    f32 f32x4.add
    f64 f64x2.add
  • function v128.sub<T>(a: v128, b: v128): v128
    
    将每个通道减去。
    T 指令
    i8, u8 i8x16.sub
    i16, u16 i16x8.sub
    i32, u32 i32x4.sub
    i64, u64 i64x2.sub
    f32 f32x4.sub
    f64 f64x2.sub
  • function v128.mul<T>(a: v128, b: v128): v128
    
    将每个通道乘起来。
    T 指令
    i16, u16 i16x8.mul
    i32, u32 i32x4.mul
    i64, u64 i64x2.mul
    f32 f32x4.mul
    f64 f64x2.mul
  • function v128.div<T>(a: v128, b: v128): v128
    
    将每个浮点通道除以。
    T 指令
    f32 f32x4.div
    f64 f64x2.div
  • function v128.neg<T>(a: v128): v128
    
    将每个通道取反。
    T 指令
    i8, u8 i8x16.neg
    i16, u16 i16x8.neg
    i32, u32 i32x4.neg
    i64, u64 i64x2.neg
    f32 f32x4.neg
    f64 f64x2.neg
  • function v128.add_sat<T>(a: v128, b: v128): v128
    
    使用饱和度将每个带符号的小整数通道加起来。
    T 指令
    i8 i8x16.add_sat_s
    u8 i8x16.add_sat_u
    i16 i16x8.add_sat_s
    u16 i16x8.add_sat_u
  • function v128.sub_sat<T>(a: v128, b: v128): v128
    
    使用饱和度将每个带符号的小整数通道减去。
    T 指令
    i8 i8x16.sub_sat_s
    u8 i8x16.sub_sat_u
    i16 i16x8.sub_sat_s
    u16 i16x8.sub_sat_u
  • function v128.shl<T>(a: v128, b: i32): v128
    
    对每个整数通道执行按位左移标量运算。
    T 指令
    i8, u8 i8x16.shl
    i16, u16 i16x8.shl
    i32, u32 i32x4.shl
    i64, u64 i64x2.shl
  • function v128.shr<T>(a: v128, b: i32): v128
    
    对每个整数通道执行按位右移标量运算。
    T 指令
    i8 i8x16.shr_s
    u8 i8x16.shr_u
    i16 i16x8.shr_s
    u16 i16x8.shr_u
    i32 i32x4.shr_s
    u32 i32x4.shr_u
    i64 i64x2.shr_s
    u64 i64x2.shr_u
  • function v128.and(a: v128, b: v128): v128
    

    对每个通道执行按位 a & b 操作。

  • function v128.or(a: v128, b: v128): v128
    

    对每个通道执行按位 a | b 操作。

  • function v128.xor(a: v128, b: v128): v128
    

    对每个通道执行按位 a ^ b 操作。

  • function v128.andnot(a: v128, b: v128): v128
    

    对每个通道执行按位 a & !b 操作。

  • function v128.not(a: v128): v128
    

    对每个通道执行按位 !a 操作。

  • function v128.bitselect(v1: v128, v2: v128, mask: v128): v128
    

    根据指定的掩码选择任一向量的位。如果 mask 中的位为 1,则从 v1 中选择,否则从 v2 中选择。

  • function v128.any_true(a: v128): bool
    

    将向量缩减为一个标量,指示任何通道是否被认为是 true

  • function v128.all_true<T>(a: v128): bool
    
    将向量缩减为一个标量,指示所有通道是否被认为是 true
    T 指令
    i8, u8 i8x16.all_true
    i16, u16 i16x8.all_true
    i32, u32 i32x4.all_true
    i64, u64 i64x2.all_true
  • function v128.bitmask<T>(a: v128): bool
    
    提取每个整数通道(64 位除外)的高位,并生成一个所有位连接起来的标量掩码。
    T 指令
    i8, u8 i8x16.bitmask
    i16, u16 i16x8.bitmask
    i32, u32 i32x4.bitmask
    i64, u64 i64x2.bitmask
  • function v128.popcnt<T>(a: v128): v128
    
    计算每个通道中设置为 1 的位数。
    T 指令
    i8, u8 i8x16.popcnt
  • function v128.min<T>(a: v128, b: v128): v128
    
    计算每个通道的最小值。
    T 指令
    i8 i8x16.min_s
    u8 i8x16.min_u
    i16 i16x8.min_s
    u16 i16x8.min_u
    i32 i32x4.min_s
    u32 i32x4.min_u
    f32 f32x4.min
    f64 f64x2.min
  • function v128.max<T>(a: v128, b: v128): v128
    
    计算每个通道的最大值。
    T 指令
    i8 i8x16.max_s
    u8 i8x16.max_u
    i16 i16x8.max_s
    u16 i16x8.max_u
    i32 i32x4.max_s
    u32 i32x4.max_u
    f32 f32x4.max
    f64 f64x2.max
  • function v128.pmin<T>(a: v128, b: v128): v128
    
    计算每个通道的伪最小值。
    T 指令
    f32 f32x4.pmin
    f64 f64x2.pmin
  • function v128.pmax<T>(a: v128, b: v128): v128
    
    计算每个通道的伪最大值。
    T 指令
    f32 f32x4.pmax
    f64 f64x2.pmax
  • function v128.dot<T>(a: v128, b: v128): v128
    
    计算两个 16 位整数通道的点积,每个通道的宽度都比输入大一个尺寸。
    T 指令
    i16 i32x4.dot_i16x8_s
  • function v128.avgr<T>(a: v128, b: v128): v128)
    
    计算每个无符号小整数通道的舍入平均值。
    T 指令
    u8 i8x16.avgr_u
    u16 i16x8.avgr_u
  • function v128.abs<T>(a: v128): v128
    
    计算每个通道的绝对值(64 位整数除外)。
    T 指令
    i8, u8 i8x16.abs
    i16, u16 i16x8.abs
    i32, u32 i32x4.abs
    i64, u64 i64x2.abs
    f32 f32x4.abs
    f64 f64x2.abs
  • function v128.sqrt<T>(a: v128): v128
    
    计算每个浮点通道的平方根。
    T 指令
    f32 f32x4.sqrt
    f64 f64x2.sqrt
  • function v128.ceil<T>(a: v128): v128
    
    对每个通道执行向上取整操作。
    T 指令
    f32 f32x4.ceil
    f64 f64x2.ceil
  • function v128.floor<T>(a: v128): v128
    
    对每个通道执行向下取整操作。
    T 指令
    f32 f32x4.floor
    f64 f64x2.floor
  • function v128.trunc<T>(a: v128): v128
    
    将每个通道舍入到最接近零的整数。
    T 指令
    f32 f32x4.trunc
    f64 f64x2.trunc
  • function v128.nearest<T>(a: v128): v128
    
    将每个通道舍入到最接近的整数 四舍五入
    T 指令
    f32 f32x4.nearest
    f64 f64x2.nearest
  • function v128.eq<T>(a: v128, b: v128): v128
    
    计算哪些通道相等。
    T 指令
    i8, u8 i8x16.eq
    i16, u16 i16x8.eq
    i32, u32 i32x4.eq
    i64, u64 i64x2.eq
    f32 f32x4.eq
    f64 f64x2.eq
  • function v128.ne<T>(a: v128, b: v128): v128
    
    计算哪些通道不相等。
    T 指令
    i8, u8 i8x16.ne
    i16, u16 i16x8.ne
    i32, u32 i32x4.ne
    i64, u64 i64x2.ne
    f32 f32x4.ne
    f64 f64x2.ne
  • function v128.lt<T>(a: v128, b: v128): v128
    
    计算第一个向量中哪些通道小于第二个向量的通道。
    T 指令
    i8 i8x16.lt_s
    u8 i8x16.lt_u
    i16 i16x8.lt_s
    u16 i16x8.lt_u
    i32 i32x4.lt_s
    u32 i32x4.lt_u
    i64 i64x2.lt_s
    f32 f32x4.lt
    f64 f64x2.lt
  • function v128.le<T>(a: v128, b: v128): v128
    
    计算第一个向量中哪些通道小于或等于第二个向量的通道。
    T 指令
    i8 i8x16.le_s
    u8 i8x16.le_u
    i16 i16x8.le_s
    u16 i16x8.le_u
    i32 i32x4.le_s
    u32 i32x4.le_u
    i64 i64x2.le_s
    f32 f32x4.le
    f64 f64x2.le
  • function v128.gt<T>(a: v128, b: v128): v128
    
    计算第一个向量中哪些通道大于第二个向量的通道。
    T 指令
    i8 i8x16.gt_s
    u8 i8x16.gt_u
    i16 i16x8.gt_s
    u16 i16x8.gt_u
    i32 i32x4.gt_s
    u32 i32x4.gt_u
    i64 i64x2.gt_s
    f32 f32x4.gt
    f64 f64x2.gt
  • function v128.ge<T>(a: v128, b: v128): v128
    
    计算第一个向量中哪些通道大于或等于第二个向量的通道。
    T 指令
    i8 i8x16.ge_s
    u8 i8x16.ge_u
    i16 i16x8.ge_s
    u16 i16x8.ge_u
    i32 i32x4.ge_s
    u32 i32x4.ge_u
    i64 i64x2.ge_s
    f32 f32x4.ge
    f64 f64x2.ge
  • function v128.convert<TFrom>(a: v128): v128
    
    将向量中每个通道从整数转换为单精度浮点数。
    TFrom 指令
    i32 f32x4.convert_i32x4_s
    u32 f32x4.convert_i32x4_u
  • function v128.convert_low<TFrom>(a: v128): v128
    
    将向量中低位通道从整数转换为双精度浮点数。
    TFrom 指令
    i32 f64x2.convert_low_i32x4_s
    u32 f64x2.convert_low_i32x4_u
  • function v128.trunc_sat<TTo>(a: v128): v128
    
    将向量中每个通道从单精度浮点数截断为带饱和的整数。 接受目标类型。
    TTo 指令
    i32 i32x4.trunc_sat_f32x4_s
    u32 i32x4.trunc_sat_f32x4_u
  • function v128.trunc_sat_zero<TTo>(a: v128): v128
    
    将向量中每个通道从双精度浮点数截断为带饱和的整数。 接受目标类型。
    TTo 指令
    i32 i32x4.trunc_sat_f64x2_s_zero
    u32 i32x4.trunc_sat_f64x2_u_zero
  • function v128.narrow<TFrom>(a: v128, b: v128): v128
    
    将较宽的整数通道缩窄到各自的较窄通道。
    TFrom 指令
    i16 i8x16.narrow_i16x8_s
    u16 i8x16.narrow_i16x8_u
    i32 i16x8.narrow_i32x4_s
    u32 i16x8.narrow_i32x4_u
  • function v128.extend_low<TFrom>(a: v128): v128
    
    将较窄整数通道的低半部分扩展到各自的较宽通道。
    TFrom 指令
    i8 i16x8.extend_low_i8x16_s
    u8 i16x8.extend_low_i8x16_u
    i16 i32x4.extend_low_i16x8_s
    u16 i32x4.extend_low_i16x8_u
    i32 i64x2.extend_low_i32x4_s
    u32 i64x2.extend_low_i32x4_u
  • function v128.extend_high<TFrom>(a: v128): v128
    
    将较窄整数通道的高半部分扩展到各自的较宽通道。
    TFrom 指令
    i8 i16x8.extend_high_i8x16_s
    u8 i16x8.extend_high_i8x16_u
    i16 i32x4.extend_high_i16x8_s
    u16 i32x4.extend_high_i16x8_u
    i32 i64x2.extend_high_i32x4_s
    u32 i64x2.extend_high_i32x4_u
  • function v128.extadd_pairwise<TFrom>(a: v128): v128
    
    将通道成对加起来,生成两倍宽的扩展结果。
    TFrom 指令
    i16 i16x8.extadd_pairwise_i8x16_s
    u16 i16x8.extadd_pairwise_i8x16_u
    i32 i32x4.extadd_pairwise_i16x8_s
    u32 i32x4.extadd_pairwise_i16x8_u
  • function v128.demote_zero<T>(a: v128): v128
    
    将每个浮点通道降级为较低精度。 结果的高位通道初始化为零。
    T 指令
    f64 f32x4.demote_f64x2_zero
  • function v128.promote_low<T>(a: v128): v128
    
    将低位浮点通道提升为更高精度。
    T 指令
    f32 f64x2.promote_low_f32x4
  • function v128.q15mulr_sat<T>(a: v128, b: v128): v128
    
    执行 Q15 格式的逐行饱和舍入乘法 ((a[i] * b[i] + (1 << (Q - 1))) >> Q 其中 Q=15)。
    T 指令
    i16 i16x8.q15mulr_sat_s
  • function v128.extmul_low<T>(a: v128, b: v128): v128
    
    执行低位通道的逐通道整数扩展乘法,生成比输入两倍宽的结果。
    T 指令
    i8 i16x8.extmul_low_i8x16_s
    u8 i16x8.extmul_low_i8x16_u
    i16 i32x4.extmul_low_i16x8_s
    u16 i32x4.extmul_low_i16x8_u
    i32 i64x2.extmul_low_i32x4_s
    u32 i64x2.extmul_low_i32x4_u
  • function v128.extmul_high<T>(a: v128, b: v128): v128
    
    执行高位通道的逐通道整数扩展乘法,生成比输入两倍宽的结果。
    T 指令
    i8 i16x8.extmul_high_i8x16_s
    u8 i16x8.extmul_high_i8x16_u
    i16 i32x4.extmul_high_i16x8_s
    u16 i32x4.extmul_high_i16x8_u
    i32 i64x2.extmul_high_i32x4_s
    u32 i64x2.extmul_high_i32x4_u

# 构造常量向量

  • function i8x16(a: i8, ... , p: i8): v128
    

    从十六个 8 位整数值初始化一个 128 位向量。

  • function i16x8(a: i16, ..., h: i16): v128
    

    从八个 16 位整数值初始化一个 128 位向量。

  • function i32x4(a: i32, b: i32, c: i32, d: i32): v128
    

    从四个 32 位整数值初始化一个 128 位向量。

  • function i64x2(a: i64, b: i64): v128
    

    从两个 64 位整数值初始化一个 128 位向量。

  • function f32x4(a: f32, b: f32, c: f32, d: f32): v128
    

    从四个 32 位浮点值初始化一个 128 位向量。

  • function f64x2(a: f64, b: f64): v128
    

    从两个 64 位浮点值初始化一个 128 位向量。

# 松散 SIMD 🦄

以下指令表示 WebAssembly 松散 SIMD (opens new window) 规范。 必须使用 --enable relaxed-simd 启用。

  • function v128.relaxed_swizzle(a: v128, s: v128): v128
    

    使用 s 中的索引从 a 中选择 8 位通道。 范围 [0-15] 内的索引选择 a 的第 i 个元素。

    v128.swizzle 不同,超出界限索引的结果是实现定义的,取决于硬件功能:要么是 0,要么是 a[s[i]%16]

  • function v128.relaxed_trunc<T>(a: v128): v128
    
    将向量中每个通道从 32 位浮点数截断为 32 位有符号或无符号整数,如 T 所示。
    T 指令
    i32 i32x4.relaxed_trunc_f32x4_s
    u32 i32x4.relaxed_trunc_f32x4_u

    v128.trunc_sat 不同,超出目标类型范围的通道结果是实现定义的,取决于硬件功能

    • 如果输入通道包含 NaN,则结果要么是 0,要么是相应的最大整数值。
    • 如果输入通道包含超出目标类型范围的值,则结果要么是饱和结果,要么是最大整数值。
  • function v128.relaxed_trunc_zero<T>(a: v128): v128
    
    将向量中每个通道从 64 位浮点数截断为 32 位有符号或无符号整数,如 T 所示。 结果的未使用的较高整数通道初始化为零。
    T 指令
    i32 i32x4.relaxed_trunc_f64x2_s_zero
    u32 i32x4.relaxed_trunc_f64x2_u_zero

    v128.trunc_sat_zero 不同,超出目标类型范围的通道结果是实现定义的,取决于硬件功能

    • 如果输入通道包含 NaN,则结果要么是 0,要么是相应的最大整数值。
    • 如果输入通道包含超出目标类型范围的值,则结果要么是饱和结果,要么是最大整数值。
  • function v128.relaxed_madd<T>(a: v128, b: v128, c: v128): v128
    
    对 32 位或 64 位浮点通道执行融合乘加运算 (a * b + c),如 T 所示。
    T 指令
    f32 f32x4.relaxed_madd
    f64 f64x2.relaxed_madd

    结果是实现定义的,取决于硬件功能

    • 要么 a * b 舍入一次,最终结果再次舍入,要么
    • 使用更高精度评估表达式,只舍入一次
  • function v128.relaxed_nmadd<T>(a: v128, b: v128, c: v128): v128
    
    对 32 位或 64 位浮点通道执行融合负乘加运算 (-(a * b) + c),如 T 所示。
    T 指令
    f32 f32x4.relaxed_nmadd
    f64 f64x2.relaxed_nmadd

    结果是实现定义的,取决于硬件功能

    • 要么 a * b 舍入一次,最终结果再次舍入,要么
    • 使用更高精度评估表达式,只舍入一次
  • function v128.relaxed_laneselect<T>(a: v128, b: v128, m: v128): v128
    
    根据 m 中的掩码,从 ab 中选择 8 位、16 位、32 位或 64 位整数通道,如 T 所示。
    T 指令
    i8, u8 i8x16.relaxed_laneselect
    i16, u16 i16x8.relaxed_laneselect
    i32, u32 i32x4.relaxed_laneselect
    i64, u64 i64x2.relaxed_laneselect

    如果 m 中的掩码的所有位都设置 (结果为 a[i]) 或未设置 (结果为 b[i]),则行为类似于 v128.bitselect。 否则,结果是实现定义的,取决于硬件功能:如果 m 的最高有效位设置,则结果要么是 bitselect(a[i], b[i], mask),要么是 a[i],否则结果是 b[i]

  • function v128.relaxed_min<T>(a: v128, b: v128): v128
    
    计算每个 32 位或 64 位浮点通道的最小值,如 T 所示。
    T 指令
    f32 f32x4.relaxed_min
    f64 f64x2.relaxed_min

    v128.min 不同,如果任一值为 NaN 或两者都为 -0.0+0.0,则结果是实现定义的,取决于硬件功能:要么是 a[i],要么是 b[i]

  • function v128.relaxed_max<T>(a: v128, b: v128): v128
    
    计算每个 32 位或 64 位浮点通道的最大值,如 T 所示。
    T 指令
    f32 f32x4.relaxed_max
    f64 f64x2.relaxed_max

    v128.max 不同,如果任一值为 NaN 或两者都为 -0.0+0.0,则结果是实现定义的,取决于硬件功能:要么是 a[i],要么是 b[i]

  • function v128.relaxed_q15mulr<T>(a: v128, b: v128): v128
    
    执行 Q15 格式的逐通道舍入乘法 ((a[i] * b[i] + (1 << (Q - 1))) >> Q 其中 Q=15)。
    T 指令
    i16 i16x8.relaxed_q15mulr_s

    v128.q15mulr_sat 不同,如果两个输入都是最小有符号值,则结果是实现定义的:要么是最小值,要么是最大有符号值。

  • function v128.relaxed_dot<T>(a: v128, b: v128): v128
    
    计算两个 8 位整数通道的点积,生成比输入大一个大小的通道。
    T 指令
    i16 i16x8.relaxed_dot_i8x16_i7x16_s

    v128.dot 不同,如果 b[i] 的最高有效位设置,则 b[i] 是由中间乘法解释为有符号还是无符号,是实现定义的。

  • function v128.relaxed_dot_add<T>(a: v128, b: v128, c: v128): v128
    
    计算两个 8 位整数通道的点积,生成比输入大两个大小的通道,并将 c 的通道累积到结果中。
    T 指令
    i32 i32x4.relaxed_dot_i8x16_i7x16_add_s

    v128.dot 不同,如果 b[i] 的最高有效位设置,则 b[i] 是由中间乘法解释为有符号还是无符号,是实现定义的。

# 内联指令

除了使用上面的通用内置函数外,大多数 WebAssembly 指令可以直接在 AssemblyScript 代码中编写。 例如,以下是等效的

// generic builtin
v128.splat<i32>(42);

// inline instruction
i32x4.splat(42);