def test_local_var(self): stack = OperandStack() stack.push_u32(1) stack.push_u32(3) stack.push_u32(5) self.assertEqual(uint64(3), stack.get_operand(1)) stack.set_operand(1, 7) self.assertEqual(uint64(7), stack.get_operand(1))
def test_nan(self): self.assertEqual(uint32(0x7fc00000), float32(str(math.nan))) self.assertEqual(uint32(0xffc00000), float32('-nan')) self.assertEqual(uint32(0x7f800000), float32(str(math.inf))) self.assertEqual(uint32(0xff800000), float32('-inf')) self.assertEqual(uint64(0x7ff8000000000001), float64(str(math.nan))) self.assertEqual(uint64(0xfff8000000000001), float64('-nan')) self.assertEqual(uint64(0x7ff0000000000000), float64(str(math.inf))) self.assertEqual(uint64(0xfff0000000000000), float64('-inf'))
def unwrap_u64(vt, val): if vt == ValTypeI32: return uint64(val) elif vt == ValTypeI64: return uint64(val) elif vt == ValTypeF32: val = struct.unpack('>l', struct.pack('>f', val))[0] return uint64(val) elif vt == ValTypeF64: val = struct.unpack('>q', struct.pack('>d', val))[0] return uint64(val) else: raise Exception("unreachable")
def __trunc_sat_u(z, n): if math.isnan(z): return 0 if z == -math.inf: return 0 max_value = (uint64(1) << n) - 1 if math.isinf(z): return max_value x = math.trunc(z) if x < 0: return 0 elif x >= float64(max_value): return max_value else: return uint64(x)
def i64_trunc_f64u(vm, _): val = vm.pop_f64() if math.isinf(val): raise ErrIntOverflow if math.isnan(val): raise ErrConvertToInt f = math.trunc(val) if f >= __MaxUint64 or f < 0: raise ErrIntOverflow vm.push_u64(uint64(f))
def decode_var_uint(data, size: int): """ LEB128无符号整数解码 :param data: 解码后的整数 :param size: 实际消耗的字节数 :return: """ result = 0 for i, b in enumerate(data): if i == int(size / 7): if b & 0x80 != 0: raise ErrIntTooLong if (b >> (size - i * 7)) > 0: raise ErrIntTooLarge result |= (uint64(b) & 0x7f) << (i * 7) if b & 0x80 == 0: return result, i + 1 raise ErrUnexpectedEnd
def test_operand_stack(self): stack = OperandStack() stack.push_bool(True) stack.push_bool(False) stack.push_u32(1) stack.push_s32(-2) stack.push_u64(3) stack.push_s64(-4) stack.push_f32(5.5) stack.push_f64(6.5) self.assertEqual(6.5, stack.pop_f64()) self.assertEqual(float32(5.5), stack.pop_f32()) self.assertEqual(int64(-4), stack.pop_s64()) self.assertEqual(uint64(3), stack.pop_u64()) self.assertEqual(int32(-2), stack.pop_s32()) self.assertEqual(uint32(1), stack.pop_u32()) self.assertEqual(False, stack.pop_bool()) self.assertEqual(True, stack.pop_bool()) self.assertEqual(0, len(stack.slots))
def read_u64(vm, mem_arg): buf = [0x00] * 8 offset = get_offset(vm, mem_arg) buf = vm.memory.read(offset, buf) return uint64(int.from_bytes(bytearray(buf), byteorder='little'))
def i64_extend_i32u(vm, _): vm.push_u64(uint64(vm.pop_u32()))
def i64_pop_cnt(vm, _): vm.push_u64(uint64(__ones_count64(vm.pop_u64())))
def pop_u64(self) -> uint64: return uint64(self.slots.pop())
def i64_load_16u(vm, mem_arg): val = read_u16(vm, mem_arg) vm.push_u64(uint64(val))
def test_global_var(self): g = GlobalVar(gt=GlobalType(ValTypeI32, 1), val=0) g.set_as_u64(100) self.assertEqual(uint64(100), g.get_as_u64())
def push_u32(self, val): self.push_numeric(uint64(val))
def get_offset(vm, mem_arg): offset = mem_arg.offset return uint64(vm.pop_u32()) + uint64(offset)
def i64_clz(vm, _): vm.push_u64(uint64(__leading_zeros64(vm.pop_u64())))
def i64_load_8u(vm, mem_arg): val = read_u8(vm, mem_arg) vm.push_u64(uint64(val))
def i64_ctz(vm, _): vm.push_u64(uint64(__trailing_zeros64(vm.pop_u64())))
def i64_load_32u(vm, mem_arg): val = read_u32(vm, mem_arg) vm.push_u64(uint64(val))
def push_u64(self, val): self.slots.append(uint64(val))