def to_bytes_m(expr, arg, out_typ): out_info = out_typ._bytes_info _check_bytes(expr, arg, out_typ, max_bytes_allowed=out_info.m) if isinstance(arg.typ, ByteArrayType): bytes_val = LOAD(bytes_data_ptr(arg)) # zero out any dirty bytes (which can happen in the last # word of a bytearray) len_ = get_bytearray_length(arg) num_zero_bits = IRnode.from_list(["mul", ["sub", 32, len_], 8]) with num_zero_bits.cache_when_complex("bits") as (b, num_zero_bits): arg = shl(num_zero_bits, shr(num_zero_bits, bytes_val)) arg = b.resolve(arg) elif is_bytes_m_type(arg.typ): arg_info = arg.typ._bytes_info # clamp if it's a downcast if arg_info.m > out_info.m: arg = bytes_clamp(arg, out_info.m) elif is_integer_type(arg.typ) or is_base_type(arg.typ, "address"): int_bits = arg.typ._int_info.bits if out_info.m_bits < int_bits: # question: allow with runtime clamp? # arg = int_clamp(m_bits, signed=int_info.signed) _FAIL(arg.typ, out_typ, expr) # note: neg numbers not OOB. keep sign bit arg = shl(256 - out_info.m_bits, arg) elif is_decimal_type(arg.typ): if out_info.m_bits < arg.typ._decimal_info.bits: _FAIL(arg.typ, out_typ, expr) # note: neg numbers not OOB. keep sign bit arg = shl(256 - out_info.m_bits, arg) else: # bool arg = shl(256 - out_info.m_bits, arg) return IRnode.from_list(arg, typ=out_typ)
def parse_AugAssign(self): target = self._get_target(self.stmt.target) sub = Expr.parse_value_expr(self.stmt.value, self.context) if not isinstance(target.typ, BaseType): return with target.cache_when_complex("_loc") as (b, target): rhs = Expr.parse_value_expr( vy_ast.BinOp( left=IRnode.from_list(LOAD(target), typ=target.typ), right=sub, op=self.stmt.op, lineno=self.stmt.lineno, col_offset=self.stmt.col_offset, end_lineno=self.stmt.end_lineno, end_col_offset=self.stmt.end_col_offset, node_source_code=self.stmt.get("node_source_code"), ), self.context, ) return b.resolve(STORE(target, rhs))
def _bytes_to_num(arg, out_typ, signed): # converting a bytestring to a number: # bytestring and bytes_m are right-padded with zeroes, int is left-padded. # convert by shr or sar the number of zero bytes (converted to bits) # e.g. "abcd000000000000" -> bitcast(000000000000abcd, output_type) if isinstance(arg.typ, ByteArrayLike): _len = get_bytearray_length(arg) arg = LOAD(bytes_data_ptr(arg)) num_zero_bits = ["mul", 8, ["sub", 32, _len]] elif is_bytes_m_type(arg.typ): info = arg.typ._bytes_info num_zero_bits = 8 * (32 - info.m) else: raise CompilerPanic("unreachable") # pragma: notest if signed: ret = sar(num_zero_bits, arg) else: ret = shr(num_zero_bits, arg) annotation = (f"__intrinsic__byte_array_to_num({out_typ})", ) return IRnode.from_list(ret, annotation=annotation)
def load_bytearray(side): return LOAD(bytes_data_ptr(side))