def ceil(viper_ast: ViperAST, dec, scaling_factor: int, pos=None, info=None): mceil = mangled.MATH_CEIL domain = mangled.MATH_DOMAIN scaling_factor_lit = viper_ast.IntLit(scaling_factor, pos) args = [dec, scaling_factor_lit] return viper_ast.DomainFuncApp(mceil, args, viper_ast.Int, pos, info, domain)
def map_sum(viper_ast: ViperAST, ref, key_type, pos=None, info=None): type_vars = {viper_ast.TypeVar(mangled.MAP_KEY_VAR): key_type} type = viper_ast.Int msum = mangled.MAP_SUM domain = mangled.MAP_INT_DOMAIN return viper_ast.DomainFuncApp(msum, [ref], type, pos, info, domain, type_vars)
def w_unwrap(viper_ast: ViperAST, value, pos=None, info=None): if isinstance(viper_ast, WrappedViperAST): viper_ast = viper_ast.viper_ast wi_unwrap = mangled.WRAPPED_INT_UNWRAP domain = mangled.WRAPPED_INT_DOMAIN return viper_ast.DomainFuncApp(wi_unwrap, [value], viper_ast.Int, pos, info, domain)
def floor(viper_ast: ViperAST, dec, scaling_factor: int, pos=None, info=None): mfloor = mangled.MATH_FLOOR domain = mangled.MATH_DOMAIN scaling_factor_lit = viper_ast.IntLit(scaling_factor, pos) args = [dec, scaling_factor_lit] return viper_ast.DomainFuncApp(mfloor, args, viper_ast.Int, pos, info, domain)
def method_id(viper_ast: ViperAST, method, len: int, pos=None, info=None): mid = mangled.BLOCKCHAIN_METHOD_ID domain = mangled.BLOCKCHAIN_DOMAIN rl = viper_ast.IntLit(len, pos) return viper_ast.DomainFuncApp(mid, [method, rl], viper_ast.SeqType(viper_ast.Int), pos, info, domain)
def convert_bytes32_to_unsigned_int(viper_ast: ViperAST, bytes, pos=None, info=None): domain = mangled.CONVERT_DOMAIN function = mangled.CONVERT_BYTES32_TO_UNSIGNED_INT return viper_ast.DomainFuncApp(function, [bytes], viper_ast.Int, pos, info, domain)
def w_mul(viper_ast: ViperAST, first, second, pos=None, info=None): if isinstance(viper_ast, WrappedViperAST): viper_ast = viper_ast.viper_ast wi_mul = mangled.WRAPPED_INT_MUL domain = mangled.WRAPPED_INT_DOMAIN args = [first, second] return viper_ast.DomainFuncApp(wi_mul, args, wrapped_int_type(viper_ast), pos, info, domain)
def struct_init(viper_ast: ViperAST, args, struct: StructType, pos=None, info=None): domain = mangled.struct_name(struct.name, struct.kind) init_name = mangled.struct_init_name(struct.name, struct.kind) type = struct_type(viper_ast) return viper_ast.DomainFuncApp(init_name, args, type, pos, info, domain)
def convert_unsigned_int_to_bytes32(viper_ast: ViperAST, i, pos=None, info=None): domain = mangled.CONVERT_DOMAIN function = mangled.CONVERT_UNSIGNED_INT_TO_BYTES32 return viper_ast.DomainFuncApp(function, [i], viper_ast.SeqType(viper_ast.Int), pos, info, domain)
def struct_eq(viper_ast: ViperAST, left, right, struct: StructType, pos=None, info=None): domain = mangled.struct_name(struct.name, struct.kind) eq = mangled.struct_eq_name(struct.name, struct.kind) return viper_ast.DomainFuncApp(eq, [left, right], viper_ast.Bool, pos, info, domain)
def mod(viper_ast: ViperAST, dividend, divisor, pos=None, info=None): # We need a special mod function because Vyper uses truncating division # instead of Viper's floor division mmod = mangled.MATH_MOD domain = mangled.MATH_DOMAIN # We pass the Viper floor division as a third argument to trigger a correct # division by 0 error instead of an assertion failure if divisor == 0 args = [dividend, divisor, viper_ast.Mod(dividend, divisor, pos)] return viper_ast.DomainFuncApp(mmod, args, viper_ast.Int, pos, info, domain)
def pad32(viper_ast: ViperAST, bytes, pos=None, info=None): """ Left-pads a byte array shorter than 32 bytes with 0s so that its resulting length is 32. Left-crops a byte array longer than 32 bytes so that its resulting length is 32. """ domain = mangled.CONVERT_DOMAIN function = mangled.CONVERT_PAD32 return viper_ast.DomainFuncApp(function, [bytes], viper_ast.SeqType(viper_ast.Int), pos, info, domain)
def map_eq(viper_ast: ViperAST, left, right, key_type, value_type, pos=None, info=None): type_vars = _map_type_var_map(viper_ast, key_type, value_type) eq = mangled.MAP_EQ domain = mangled.MAP_DOMAIN return viper_ast.DomainFuncApp(eq, [left, right], viper_ast.Bool, pos, info, domain, type_vars)
def map_init(viper_ast: ViperAST, arg, key_type, value_type, pos=None, info=None): mp_type = map_type(viper_ast, key_type, value_type) type_vars = _map_type_var_map(viper_ast, key_type, value_type) init = mangled.MAP_INIT domain = mangled.MAP_DOMAIN return viper_ast.DomainFuncApp(init, [arg], mp_type, pos, info, domain, type_vars)
def implements(viper_ast: ViperAST, address, interface: str, ctx: Context, pos=None, info=None): impl = mangled.IMPLEMENTS domain = mangled.CONTRACT_DOMAIN intf = viper_ast.IntLit( first_index(lambda i: i == interface, ctx.program.interfaces), pos) return viper_ast.DomainFuncApp(impl, [address, intf], viper_ast.Bool, pos, info, domain)
def map_get(viper_ast: ViperAST, ref, idx, key_type, value_type, pos=None, info=None): type_vars = _map_type_var_map(viper_ast, key_type, value_type) get = mangled.MAP_GET domain = mangled.MAP_DOMAIN return viper_ast.DomainFuncApp(get, [ref, idx], value_type, pos, info, domain, type_vars)
def struct_type_tag(viper_ast: ViperAST, ref, pos=None, info=None): """ Returns the type tag of a struct which we store at index -1 of a struct """ domain = mangled.STRUCT_OPS_DOMAIN idx = viper_ast.IntLit(mangled.STRUCT_TYPE_LOC) field = struct_loc(viper_ast, ref, idx, pos) getter = mangled.STRUCT_GET type_type = viper_ast.Int type_map = _struct_type_var_map(viper_ast, type_type) return viper_ast.DomainFuncApp(getter, [field], type_type, pos, info, domain, type_map)
def struct_get_idx(viper_ast: ViperAST, ref, idx: Union[int, Expr], viper_type, pos=None, info=None): domain = mangled.STRUCT_OPS_DOMAIN idx_lit = viper_ast.IntLit(idx) if isinstance(idx, int) else idx field = struct_loc(viper_ast, ref, idx_lit, pos, info) getter = mangled.STRUCT_GET type_map = _struct_type_var_map(viper_ast, viper_type) return viper_ast.DomainFuncApp(getter, [field], viper_type, pos, info, domain, type_map)
def array_init(viper_ast: ViperAST, arg, size: int, element_type, pos=None, info=None): arr_type = array_type(viper_ast, element_type) type_vars = {viper_ast.TypeVar(mangled.ARRAY_ELEMENT_VAR): element_type} size = viper_ast.IntLit(size, pos, info) init = mangled.ARRAY_INIT domain = mangled.ARRAY_DOMAIN return viper_ast.DomainFuncApp(init, [arg, size], arr_type, pos, info, domain, type_vars)
def struct_set_idx(viper_ast: ViperAST, ref, val, idx: int, member_type, pos=None, info=None): setter = mangled.STRUCT_SET s_type = struct_type(viper_ast) domain = mangled.STRUCT_OPS_DOMAIN idx = viper_ast.IntLit(idx) type_map = _struct_type_var_map(viper_ast, member_type) return viper_ast.DomainFuncApp(setter, [ref, idx, val], s_type, pos, info, domain, type_map)
def struct_get(viper_ast: ViperAST, ref, member: str, member_type, struct_type: StructType, pos=None, info=None): domain = mangled.STRUCT_OPS_DOMAIN idx = viper_ast.IntLit(struct_type.member_indices[member]) field = struct_loc(viper_ast, ref, idx, pos, info) getter = mangled.STRUCT_GET type_map = _struct_type_var_map(viper_ast, member_type) return viper_ast.DomainFuncApp(getter, [field], member_type, pos, info, domain, type_map)
def map_set(viper_ast: ViperAST, ref, idx, value, key_type, value_type, pos=None, info=None): type_vars = _map_type_var_map(viper_ast, key_type, value_type) mtype = map_type(viper_ast, key_type, value_type) mset = mangled.MAP_SET domain = mangled.MAP_DOMAIN return viper_ast.DomainFuncApp(mset, [ref, idx, value], mtype, pos, info, domain, type_vars)
def struct_set(viper_ast: ViperAST, ref, val, member: str, member_type, type: StructType, pos=None, info=None): setter = mangled.STRUCT_SET s_type = struct_type(viper_ast) domain = mangled.STRUCT_OPS_DOMAIN idx = viper_ast.IntLit(type.member_indices[member]) type_map = _struct_type_var_map(viper_ast, member_type) return viper_ast.DomainFuncApp(setter, [ref, idx, val], s_type, pos, info, domain, type_map)
def w_mod(viper_ast: ViperAST, first, second, pos=None, info=None): if isinstance(viper_ast, WrappedViperAST): viper_ast = viper_ast.viper_ast wi_mod = mangled.WRAPPED_INT_MOD domain = mangled.WRAPPED_INT_DOMAIN args = [first, second] func_app = viper_ast.DomainFuncApp(wi_mod, args, wrapped_int_type(viper_ast), pos, info, domain) is_div_zero = viper_ast.EqCmp(viper_ast.IntLit(0), w_unwrap(viper_ast, second, pos, info), pos, info) artificial_div_zero = w_wrap( viper_ast, viper_ast.Mod(w_unwrap(viper_ast, first, pos, info), w_unwrap(viper_ast, second, pos, info), pos, info), pos, info) return viper_ast.CondExp(is_div_zero, artificial_div_zero, func_app, pos, info)
def range(viper_ast: ViperAST, start, end, pos=None, info=None): range_func = mangled.RANGE_RANGE range_type = viper_ast.SeqType(viper_ast.Int) domain = mangled.RANGE_DOMAIN return viper_ast.DomainFuncApp(range_func, [start, end], range_type, pos, info, domain)
def shift(viper_ast: ViperAST, arg, shift, pos=None, info=None): b_shift = mangled.MATH_SHIFT domain = mangled.MATH_DOMAIN return viper_ast.DomainFuncApp(b_shift, [arg, shift], viper_ast.Int, pos, info, domain)
def bitwise_not(viper_ast: ViperAST, arg, pos=None, info=None): b_not = mangled.MATH_BITWISE_NOT domain = mangled.MATH_DOMAIN return viper_ast.DomainFuncApp(b_not, [arg], viper_ast.Int, pos, info, domain)
def bitwise_and(viper_ast: ViperAST, a, b, pos=None, info=None): b_and = mangled.MATH_BITWISE_AND domain = mangled.MATH_DOMAIN return viper_ast.DomainFuncApp(b_and, [a, b], viper_ast.Int, pos, info, domain)
def bitwise_xor(viper_ast: ViperAST, a, b, pos=None, info=None): b_xor = mangled.MATH_BITWISE_XOR domain = mangled.MATH_DOMAIN return viper_ast.DomainFuncApp(b_xor, [a, b], viper_ast.Int, pos, info, domain)
def struct_loc(viper_ast: ViperAST, ref, idx, pos=None, info=None): domain = mangled.STRUCT_DOMAIN loc = mangled.STRUCT_LOC return viper_ast.DomainFuncApp(loc, [ref, idx], viper_ast.Int, pos, info, domain)