Permalink
Browse files

modified pyc_asm_list to use symbolic vars

no longer uses literal addresses and registers
  • Loading branch information...
1 parent 0f3942e commit 080f3cf49d8216f76fc23df3047cc8a93df00359 cantora committed Sep 21, 2012
Showing with 104 additions and 98 deletions.
  1. +3 −3 pyc
  2. +63 −91 pyc_asm_list.py
  3. +21 −3 pyc_asm_nodes.py
  4. +17 −1 pyc_ast.py
View
6 pyc
@@ -58,13 +58,13 @@ def run(options):
for ss in ss_list:
log(repr(ss))
- asm_list, sym_tbl = pyc_asm_list.from_ss_list(ss_list)
+ asm_list = pyc_asm_list.from_ss_list(ss_list)
insns = []
insns.extend(asm_prefix())
- if sym_tbl.stack > 0:
- insns.append("subl\t$%s, %%esp" % sym_tbl.stack)
+ #if sym_tbl.stack > 0:
+ # insns.append("subl\t$%s, %%esp" % sym_tbl.stack)
log("asm list:")
for ins_list in asm_list:
View
154 pyc_asm_list.py
@@ -1,101 +1,95 @@
from pyc_asm_nodes import *
from pyc_log import *
+from pyc_ast import DiscardSSList
-class sym_table(dict):
-
- def __init__(self):
- self.stack = 0
-
- def type_size(self, type):
- if type == "long":
- return 4
- else:
- raise Exception("unknown type %s" % type)
-
- def push(self, type):
- size = self.type_size(type)
- self.stack += size
-
- def pop(self, type):
- size = type_size(type)
- self.stack -= size
-
-
-
def from_ss_list(ss_list):
asm_list = []
- st = sym_table()
+ vt = dict()
log("convert simple statements to list of asm nodes")
for ss in ss_list:
- asm_list.append(py_ss_to_asm(ss, st))
+ if isinstance(ss, DiscardSSList):
+ for dss in ss.nodes:
+ asm_list.append(py_ss_to_asm(dss, vt))
+ else:
+ asm_list.append(py_ss_to_asm(ss, vt))
- log("sym_tbl.stack: %d" % st.stack)
- return (asm_list, st)
+ return asm_list
-def py_ss_to_asm(ss, sym_tbl):
+def py_ss_to_asm(ss, var_tbl):
if isinstance(ss, compiler.ast.Assign):
- return assign_to_asm(ss, sym_tbl)
+ return assign_to_asm(ss, var_tbl)
elif isinstance(ss, compiler.ast.Printnl):
- return printnl_to_asm(ss, sym_tbl)
+ return printnl_to_asm(ss, var_tbl)
raise Exception("didnt expect ast node of type %s" % ss.__class__.__name__)
-def assign_to_asm(assign, sym_tbl):
+def assign_to_asm(assign, var_tbl):
log(repr(assign))
nodelen = len(assign.nodes)
if nodelen != 1:
raise Exception("expected Assign with a single assignment")
- sym = assign.nodes[0].name
- addr = None
-
- try:
- addr = sym_tbl[sym]
- except KeyError:
- pass
-
- if addr == None:
- addr = sym_tbl.stack
- sym_tbl.push("long")
+ var = Var(assign.nodes[0].name)
- result = set_mem(addr, assign.expr, sym_tbl)
- sym_tbl[sym] = addr
+ result = set_var(var, assign.expr, var_tbl)
+ var_tbl[var] = True
return result
-"""
-generate asm nodes to put an addition in eax
-imm1, imm2 => [movl($imm1, %eax), addl($imm2, %eax)]
-imm, addr or addr, imm1 => [movl(addr, %eax), addl($imm, %eax)]
-addr1, addr2 => [movl(addr1, %eax), addl(addr2, %eax)]
-"""
-def add(left, right):
- return [
- Mov(left, Register("eax")),
- Add(right, Register("eax"))
- ]
-
+def mov(src, dst):
+ result = []
+
+ #print("%s, %s" % (repr(dst), repr(src)) )
+ if dst == src:
+ pass # noop
+ else:
+ result.append(Mov(src, dst) )
+
+ return result
+
+
+def add_to_var(var, left, right, var_tbl):
+ lop = se_to_operand(left, var_tbl)
+ rop = se_to_operand(right, var_tbl)
+
+ result = []
+ result.extend(mov(rop, var))
+ result.append(Add(lop, var))
+
+ return result
-def se_to_operand(expr, sym_tbl):
+def se_to_operand(expr, var_tbl):
if isinstance(expr, compiler.ast.Const):
return Immed(Int(expr.value) )
elif isinstance(expr, compiler.ast.Name):
- src_addr = sym_tbl[expr.name]
- return EBPIndirect(src_addr)
+ var = Var(expr.name)
+ if not var_tbl[var]:
+ raise Exception("unknown Var %s" % expr.name)
+ return var
raise Exception("expected name or constant, got %s" % expr.__class__.__name__)
-def fn_call(name, args, sym_tbl):
+def neg_to_var(var, expr, var_tbl):
+ insns = []
+ op = se_to_operand(expr, var_tbl)
+
+ insns.extend( mov(op, var) )
+ insns.append( Neg(var) )
+
+ return insns
+
+
+def fn_call(name, args, var_tbl):
insns = []
for i in args:
- insns.insert(0, Push(se_to_operand(i, sym_tbl) ) )
+ insns.insert(0, Push(se_to_operand(i, var_tbl) ) )
insns.append( Call(name) )
@@ -106,55 +100,33 @@ def fn_call(name, args, sym_tbl):
return insns
-def set_mem(addr, expr, sym_tbl):
- dest_op = EBPIndirect(addr)
+def set_var(var, expr, var_tbl):
insns = []
if isinstance(expr, compiler.ast.Const):
#movl $N, -(4+ADDR)(%ebp)
- insns.append( Mov(Immed(Int(expr.value)), dest_op) )
+ insns.append( Mov(Immed(Int(expr.value)), var) )
elif isinstance(expr, compiler.ast.Name):
- src_addr = sym_tbl[expr.name]
- if src_addr == addr:
- pass # assigning a var to itself is a noop
- else:
- insns.extend( [
- Mov(EBPIndirect(src_addr), Register("eax") ),
- Mov(Register("eax"), dest_op )
- ] )
+ op = se_to_operand(expr, var_tbl)
+ insns.extend(mov(op, var))
elif isinstance(expr, compiler.ast.Add):
- l_op = se_to_operand(expr.left, sym_tbl)
- r_op = se_to_operand(expr.right, sym_tbl)
- insns.extend( add(l_op, r_op) )
- insns.append( Mov(Register("eax"), dest_op ) )
+ insns.extend( add_to_var(var, expr.left, expr.right, var_tbl) )
elif isinstance(expr, compiler.ast.CallFunc):
- insns.extend( fn_call(expr.node.name, expr.args, sym_tbl) )
- insns.append( Mov(Register("eax"), dest_op) )
+ insns.extend( fn_call(expr.node.name, expr.args, var_tbl) )
+ insns.append( Mov(Register("eax"), var) )
elif isinstance(expr, compiler.ast.UnarySub):
- op = se_to_operand(expr.expr, sym_tbl)
- if isinstance(op, Immed):
- insns.append( Mov(op, dest_op) )
-
- elif isinstance(op, Indirect):
- if str(op) != str(dest_op):
- insns.append( Mov(op, Register("eax")) )
- insns.append( Mov(Register("eax"), dest_op) )
-
- else:
- raise Exception("expected Indirect or Immed operand, got %s" % op.__class__.__name__)
-
- insns.append( Neg(dest_op) )
+ insns.extend(neg_to_var(var, expr.expr, var_tbl) )
else:
raise Exception("unexpected expr: %s" % expr.__class__.__name__)
return insns
-def printnl_to_asm(printnl, sym_tbl):
+def printnl_to_asm(printnl, var_tbl):
nodelen = len(printnl.nodes)
insns = []
@@ -163,4 +135,4 @@ def printnl_to_asm(printnl, sym_tbl):
if nodelen != 1:
raise Exception("expected printnl with 1 node")
- return fn_call("print_int_nl", [printnl.nodes[0]], sym_tbl)
+ return fn_call("print_int_nl", [printnl.nodes[0]], var_tbl)
View
24 pyc_asm_nodes.py
@@ -12,6 +12,14 @@ def __repr__(self):
fmt = "%%s(%s)" % arg_fmt
return fmt % tup
+ def __eq__(self, other):
+ if type(other) is type(self):
+ return self.__dict__ == other.__dict__
+ else:
+ return False
+
+ def __ne__(self, other):
+ return not __eq__(self, other)
class Mov(AsmNode):
def __init__(self, src, dest):
@@ -72,14 +80,24 @@ def __str__(self):
class Var(AsmNode):
def __init__(self, name):
AsmNode.__init__(self, name)
+ self.name = name
def __str__(self):
return self.name
-class Register(AsmNode):
+ def __eq__(self, other):
+ return str(self).__eq__(str(other))
+
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
+ def __hash__(self):
+ return str(self).__hash__()
+
+
+class Register(Var):
def __init__(self, name):
- AsmNode.__init__(self, name)
- self.name = name
+ Var.__init__(self, name)
def __str__(self):
return "%%%s" % self.name
View
18 pyc_ast.py
@@ -2,6 +2,21 @@
import compiler
from pyc_log import *
+#list of simple statement which can be discarded
+class DiscardSSList(compiler.ast.Node):
+ def __init__(self, nodes, lineno=None):
+ self.nodes = nodes
+
+ def getChildren(self):
+ return self.nodes
+
+ def getChildNodes(self):
+ return self.nodes
+
+ def __repr__(self):
+ return "DiscardSSList(%s)" % repr(self.nodes)
+
+
class OutOfScope(Exception):
pass
@@ -130,7 +145,8 @@ def _to_ss_list(node, depth=0):
result = (compiler.ast.Name(result_name), ss_list)
elif( isinstance(node, compiler.ast.Discard) ):
- result = _to_ss_list(node.expr, depth+1)
+ (dummy, ss_list) = _to_ss_list(node.expr, depth+1)
+ result = (None, [DiscardSSList(ss_list)])
elif( isinstance(node, compiler.ast.Printnl) ):
nlen = len(node.nodes)

0 comments on commit 080f3cf

Please sign in to comment.