示例#1
0
def subst_expr (expr):
	if expr.kind == 'Symbol':
		return mk_word32 (symbols[expr.name][0])
	elif expr.is_op ('PAlignValid'):
		[typ, p] = expr.vals
		assert typ.kind == 'Type'
		return logic.mk_align_valid_ineq (('Type', typ.val), p)
	elif expr.kind in ['Op', 'Var', 'Num', 'Type']:
		return None
	else:
		assert not 'expression simple-substitutable', expr
示例#2
0
def subst_expr(expr):
    if expr.kind == 'Symbol':
        if expr.name in symbols:
            return mk_word32(symbols[expr.name][0])
        else:
            return None
    elif expr.is_op('PAlignValid'):
        [typ, p] = expr.vals
        assert typ.kind == 'Type'
        return logic.mk_align_valid_ineq(('Type', typ.val), p)
    elif expr.kind in ['Op', 'Var', 'Num', 'Type']:
        return None
    else:
        assert not 'expression simple-substitutable', expr
示例#3
0
def compile_accs (replaces, expr):
	r = compile_const_global_acc (expr)
	if r:
		return compile_accs (replaces, r)

	if expr.kind == 'Field':
		expr = compile_field_acc (expr.field[0], expr.struct, replaces)
		return compile_accs (replaces, expr)
	elif expr.is_op ('ArrayIndex'):
		[arr, n] = expr.vals
		expr2 = compile_array_acc (n, arr, replaces, False)
		if expr2:
			return compile_accs (replaces, expr2)
		arr = compile_accs (replaces, arr)
		n = compile_accs (replaces, n)
		expr2 = compile_array_acc (n, arr, replaces, False)
		if expr2:
			return compile_accs (replaces, expr2)
		else:
			return mk_arr_index (arr, n)
	elif (expr.is_op ('MemUpdate')
			and expr.vals[2].is_op ('MemAcc')
			and expr.vals[2].vals[0] == expr.vals[0]
			and expr.vals[2].vals[1] == expr.vals[1]):
		# null memory copy. probably created by ops below
		return compile_accs (replaces, expr.vals[0])
	elif (expr.is_op ('MemUpdate')
			and expr.vals[2].kind == 'FieldUpd'):
		[m, p, f_upd] = expr.vals
		assert f_upd.typ.kind == 'Struct'
		(typ, offs, _) = structs[f_upd.typ.name].fields[f_upd.field[0]]
		assert f_upd.val.typ == typ
		return compile_accs (replaces,
			mk_memupd (mk_memupd (m, p, f_upd.struct),
				mk_plus (p, mk_word32 (offs)), f_upd.val))
	elif (expr.is_op ('MemUpdate')
			and expr.vals[2].typ.kind == 'Struct'):
		[m, p, s_val] = expr.vals
		struct = structs[s_val.typ.name]
		for (nm, (typ, offs, _)) in struct.fields.iteritems ():
			f = compile_field_acc (nm, s_val, replaces)
			assert f.typ == typ
			m = mk_memupd (m, mk_plus (p, mk_word32 (offs)), f)
		return compile_accs (replaces, m)
	elif (expr.is_op ('MemUpdate')
			and expr.vals[2].is_op ('ArrayUpdate')):
		[m, p, arr_upd] = expr.vals
		[arr, i, v] = arr_upd.vals
		return compile_accs (replaces,
			mk_memupd (mk_memupd (m, p, arr),
				mk_arroffs (p, arr.typ, i), v))
	elif (expr.is_op ('MemUpdate')
				and expr.vals[2].typ.kind == 'Array'):
		[m, p, arr] = expr.vals
		n = arr.typ.num
		typ = arr.typ.el_typ
		for i in range (n):
			offs = i * typ.size ()
			assert offs == i or offs % 4 == 0
			e = compile_array_acc (i, arr, replaces)
			m = mk_memupd (m, mk_plus (p, mk_word32 (offs)), e)
		return compile_accs (replaces, m)
	elif expr.is_op ('Equals') \
			and expr.vals[0].typ.kind in ['Struct', 'Array']:
		[x, y] = expr.vals
		assert x.typ == y.typ
		xs = compile_val_fields (x, replaces)
		ys = compile_val_fields (y, replaces)
		eq = foldr1 (mk_and, map (mk_eq, xs, ys))
		return compile_accs (replaces, eq)
	elif expr.is_op ('PAlignValid'):
		[typ, p] = expr.vals
		p = compile_accs (replaces, p)
		assert typ.kind == 'Type'
		return logic.mk_align_valid_ineq (('Type', typ.val), p)
	elif expr.kind == 'Op':
		vals = [compile_accs (replaces, v) for v in expr.vals]
		return Expr ('Op', expr.typ, expr.name, vals = vals)
	elif expr.kind == 'Symbol':
		return mk_word32 (symbols[expr.name][0])
	else:
		if expr.kind not in {'Var':True, 'ConstGlobal':True,
				'Num':True, 'Invent':True, 'Type':True}:
			print expr
			assert not 'field acc compiled'
		return expr
示例#4
0
def compile_accs(replaces, expr):
    r = compile_const_global_acc(expr)
    if r:
        return compile_accs(replaces, r)

    if expr.kind == 'Field':
        expr = compile_field_acc(expr.field[0], expr.struct, replaces)
        return compile_accs(replaces, expr)
    elif expr.is_op('ArrayIndex'):
        [arr, n] = expr.vals
        expr2 = compile_array_acc(n, arr, replaces, False)
        if expr2:
            return compile_accs(replaces, expr2)
        arr = compile_accs(replaces, arr)
        n = compile_accs(replaces, n)
        expr2 = compile_array_acc(n, arr, replaces, False)
        if expr2:
            return compile_accs(replaces, expr2)
        else:
            return mk_arr_index(arr, n)
    elif (expr.is_op('MemUpdate') and expr.vals[2].is_op('MemAcc')
          and expr.vals[2].vals[0] == expr.vals[0]
          and expr.vals[2].vals[1] == expr.vals[1]):
        # null memory copy. probably created by ops below
        return compile_accs(replaces, expr.vals[0])
    elif (expr.is_op('MemUpdate') and expr.vals[2].kind == 'FieldUpd'):
        [m, p, f_upd] = expr.vals
        assert f_upd.typ.kind == 'Struct'
        (typ, offs, _) = structs[f_upd.typ.name].fields[f_upd.field[0]]
        assert f_upd.val.typ == typ
        return compile_accs(
            replaces,
            mk_memupd(mk_memupd(m, p, f_upd.struct),
                      mk_plus(p, mk_word32(offs)), f_upd.val))
    elif (expr.is_op('MemUpdate') and expr.vals[2].typ.kind == 'Struct'):
        [m, p, s_val] = expr.vals
        struct = structs[s_val.typ.name]
        for (nm, (typ, offs, _)) in struct.fields.iteritems():
            f = compile_field_acc(nm, s_val, replaces)
            assert f.typ == typ
            m = mk_memupd(m, mk_plus(p, mk_word32(offs)), f)
        return compile_accs(replaces, m)
    elif (expr.is_op('MemUpdate') and expr.vals[2].is_op('ArrayUpdate')):
        [m, p, arr_upd] = expr.vals
        [arr, i, v] = arr_upd.vals
        return compile_accs(
            replaces,
            mk_memupd(mk_memupd(m, p, arr), mk_arroffs(p, arr.typ, i), v))
    elif (expr.is_op('MemUpdate') and expr.vals[2].typ.kind == 'Array'):
        [m, p, arr] = expr.vals
        n = arr.typ.num
        typ = arr.typ.el_typ
        for i in range(n):
            offs = i * typ.size()
            assert offs == i or offs % 4 == 0
            e = compile_array_acc(i, arr, replaces)
            m = mk_memupd(m, mk_plus(p, mk_word32(offs)), e)
        return compile_accs(replaces, m)
    elif expr.is_op ('Equals') \
      and expr.vals[0].typ.kind in ['Struct', 'Array']:
        [x, y] = expr.vals
        assert x.typ == y.typ
        xs = compile_val_fields(x, replaces)
        ys = compile_val_fields(y, replaces)
        eq = foldr1(mk_and, map(mk_eq, xs, ys))
        return compile_accs(replaces, eq)
    elif expr.is_op('PAlignValid'):
        [typ, p] = expr.vals
        p = compile_accs(replaces, p)
        assert typ.kind == 'Type'
        return logic.mk_align_valid_ineq(('Type', typ.val), p)
    elif expr.kind == 'Op':
        vals = [compile_accs(replaces, v) for v in expr.vals]
        return syntax.adjust_op_vals(expr, vals)
    elif expr.kind == 'Symbol':
        return mk_word32(symbols[expr.name][0])
    else:
        if expr.kind not in {
                'Var': True,
                'ConstGlobal': True,
                'Num': True,
                'Invent': True,
                'Type': True
        }:
            print expr
            assert not 'field acc compiled'
        return expr