[pypy-svn] r10272 - in pypy/dist/pypy/translator/llvm: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Sun Apr 3 20:23:50 CEST 2005


Author: cfbolz
Date: Sun Apr  3 20:23:50 2005
New Revision: 10272

Added:
   pypy/dist/pypy/translator/llvm/classrepr.py
   pypy/dist/pypy/translator/llvm/funcrepr.py
   pypy/dist/pypy/translator/llvm/seqrepr.py
   pypy/dist/pypy/translator/llvm/typerepr.py
Modified:
   pypy/dist/pypy/translator/llvm/genllvm.py
   pypy/dist/pypy/translator/llvm/llvmbc.py
   pypy/dist/pypy/translator/llvm/representation.py
   pypy/dist/pypy/translator/llvm/test/llvmsnippet.py
Log:
Splitted representation.py into more manageable chunks.

Added: pypy/dist/pypy/translator/llvm/classrepr.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/llvm/classrepr.py	Sun Apr  3 20:23:50 2005
@@ -0,0 +1,254 @@
+import autopath
+import sets
+
+from types import FunctionType
+
+from pypy.objspace.flow.model import Constant
+from pypy.annotation import model as annmodel
+from pypy.annotation.classdef import ClassDef
+from pypy.translator.llvm import llvmbc
+
+from pypy.translator.llvm.representation import debug, LLVMRepr
+from pypy.translator.llvm.typerepr import TypeRepr, PointerTypeRepr
+from pypy.translator.llvm.funcrepr import FunctionRepr, BoundMethodRepr
+from pypy.translator.llvm.funcrepr import VirtualMethodRepr
+
+class ClassRepr(TypeRepr):
+    l_classes = {}
+    def get(obj, gen):
+        classdef = None
+        if obj.__class__ is Constant:
+            bind = gen.annotator.binding(obj)
+            if bind.__class__ is annmodel.SomePBC and \
+                gen.annotator.bookkeeper.userclasses.has_key(bind.const):
+                    classdef = gen.annotator.bookkeeper.userclasses[bind.const]
+        elif isinstance(obj, annmodel.SomeInstance):
+            classdef = obj.classdef
+        elif isinstance(obj, ClassDef):
+            classdef = obj
+        if classdef is None:
+            return None
+        if (classdef, gen) not in ClassRepr.l_classes:
+            ClassRepr.l_classes[(classdef, gen)] = ClassRepr(classdef, gen)
+        return ClassRepr.l_classes[(classdef, gen)]
+    get = staticmethod(get)
+
+    def __init__(self, obj, gen):
+        if debug:
+            print "ClassRepr: %s, %s" % (obj, hex(id(self)))
+        self.classdef = obj
+        self.gen = gen
+        self.includefile = ""
+        self.name = gen.get_global_tmp("class.%s" % self.classdef.cls.__name__)
+        self.objectname = gen.get_global_tmp("class.%s.object" %
+                                             self.classdef.cls.__name__)
+        if debug:
+            print self.name
+        self.dependencies = sets.Set()
+        self.setup_done = False
+        self.attr_num = {}
+
+    def setup(self):
+        if self.setup_done:
+            return
+        self.setup_done = True
+        if debug:
+            print "ClassRepr.setup()", id(self), hex(id(self)), self.setup_done
+            print len(ClassRepr.l_classes)
+        gen = self.gen
+        if self.classdef.basedef is not None: #get attributes from base classes
+            self.l_base = gen.get_repr(self.classdef.basedef)
+            self.dependencies.add(self.l_base)
+            attribs = self.l_base.attributes
+        else:
+            self.l_base = None
+            attribs = []
+        meth = []
+        if debug:
+            print "attributes", self.classdef.attrs
+        #get attributes of this class and decide whether they are methods
+        for key, attr in self.classdef.attrs.items():
+            if debug:
+                print key, attr, attr.sources, attr.s_value,
+            if len(attr.sources) != 0:
+                func = self.classdef.cls.__dict__[attr.name]
+                meth.append((key, func))
+                if debug:
+                    print "--> method1"
+            elif isinstance(attr.s_value, annmodel.SomePBC) and \
+               attr.s_value.knowntype is FunctionType:
+                func = self.classdef.cls.__dict__[attr.name]
+                meth.append((key, func))
+                if debug:
+                    print "--> method2"
+            else:
+                attribs.append(attr)
+                if debug:
+                    print "--> value"
+        self.l_attrs_types = [gen.get_repr(attr.s_value) for attr in attribs]
+        self.dependencies = sets.Set(self.l_attrs_types)
+        attributes = ", ".join([at.llvmname() for at in self.l_attrs_types])
+        self.definition = "%s = type {%%std.class*, %s}" % (self.name,
+                                                           attributes)
+        self.attributes = attribs
+        self.attr_num = {}
+        for i, attr in enumerate(attribs):
+            self.attr_num[attr.name] = i + 1
+        self.methods = dict(meth)
+
+    def get_globals(self):
+        s = "\n%s = internal global %%std.class {%%std.class* null, uint %i}"
+        s = s % (self.objectname, abs(id(self)))
+        return self.definition + s
+
+    def collect_init_code(self, lblock, l_func):
+        if self.l_base is None:
+            return
+        l_tmp = self.gen.get_local_tmp(None, l_func)
+        i = "%s = getelementptr %%std.class* %s, int 0, uint 0" % \
+            (l_tmp.llvmname(), self.objectname)
+        lblock.instruction(i)
+        lblock.instruction("store %%std.class* %s, %%std.class** %s" %
+                           (self.l_base.objectname, l_tmp.llvmname()))
+
+    def llvmtype(self):
+        return "%std.class* "
+
+    def typed_name(self):
+        #XXXX: Ouch. I get bitten by the fact that
+        #      in LLVM typedef != class object
+        # This will work, as long as class objects are only passed to functions
+        # (as opposed to used in LLVM instructions)
+        return "%%std.class* %s" % self.objectname
+
+    def op_simple_call(self, l_target, args, lblock, l_func):
+        lblock.malloc(l_target, self)
+        l_tmp = self.gen.get_local_tmp(
+            PointerTypeRepr("%std.class*", self.gen), l_func)
+        lblock.getelementptr(l_tmp, l_target, [0, 0])
+        lblock.instruction("store %%std.class* %s, %s" %
+                           (self.objectname, l_tmp.typed_name()))
+        init = None
+        for cls in self.classdef.getmro():
+            if "__init__" in cls.attrs:
+                init = cls.attrs["__init__"].getvalue()
+                break
+        if init is not None:
+            l_init = self.gen.get_repr(init)
+            l_func.dependencies.add(l_init)
+            l_args = [self.gen.get_repr(arg) for arg in args[1:]]
+            self.dependencies.update(l_args)
+            # XXX
+            if isinstance(l_init, VirtualMethodRepr):
+                l_init = l_init.l_funcs[l_init.l_classes.index(self)]
+            lblock.call_void(l_init, [l_target] + l_args)
+
+    def t_op_getattr(self, l_target, args, lblock, l_func):
+        if debug:
+            print "t_op_getattr of ClassRepr called", l_target, args, self.name
+        if not isinstance(args[1], Constant):
+            raise CompileError,"getattr called with non-constant: %s" % args[1]
+        if args[1].value in self.attr_num:
+            l_args0 = self.gen.get_repr(args[0])
+            l_func.dependencies.add(l_args0)
+            l_pter = self.gen.get_local_tmp(
+                PointerTypeRepr(l_target.llvmtype(), self.gen), l_func)
+            lblock.getelementptr(l_pter, l_args0,
+                                 [0, self.attr_num[args[1].value]])
+            lblock.load(l_target, l_pter)
+            return
+        else:
+            if debug:
+                print list(self.classdef.getmro())
+            for cls in self.classdef.getmro():
+                l_cls = self.gen.get_repr(cls)
+                self.dependencies.add(l_cls)
+                if args[1].value in l_cls.methods:
+                    if debug:
+                        print "class %s, %s matches" % (cls, l_cls)
+                    l_args0 = self.gen.get_repr(args[0])
+                    l_func.dependencies.add(l_args0)
+                    l_method = BoundMethodRepr(l_target.type, l_args0, l_cls,
+                                               self.gen)
+                    l_func.dependencies.add(l_method)
+                    l_method.setup()
+                    l_target.type = l_method
+                    return
+        raise CompileError, ("getattr called with unknown attribute %s" % \
+                             args[1].value)
+
+    def t_op_setattr(self, l_target, args, lblock, l_func):
+        if not isinstance(args[1], Constant):
+            raise CompileError,"setattr called with non-constant: %s" % args[1]
+        if args[1].value in self.attr_num:
+            l_args0 = self.gen.get_repr(args[0])
+            l_value = self.gen.get_repr(args[2])
+            self.dependencies.update([l_args0, l_value])
+            l_pter = self.gen.get_local_tmp(
+                PointerTypeRepr(l_value.llvmtype(), self.gen), l_func)
+            lblock.getelementptr(l_pter, l_args0,
+                                 [0, self.attr_num[args[1].value]])
+            lblock.store(l_value, l_pter)
+        else:
+            raise CompileError, ("setattr called with unknown attribute %s" % \
+                                 args[1].value)
+
+    def iter_subclasses(self):
+        for cls, classdef in self.classdef.subdefs.iteritems():
+            l_cls = self.gen.get_repr(classdef)
+            yield l_cls
+            for l_c in l_cls.iter_subclasses():
+                yield l_c
+
+class ExceptionTypeRepr(TypeRepr):
+    def get(obj, gen):
+        try:
+            if isinstance(obj, Constant):
+                if issubclass(obj.value, Exception):
+                    return ExceptionTypeRepr(obj.value, gen)
+                return None
+            elif issubclass(obj, Exception):
+                return ExceptionTypeRepr(obj, gen)
+        except TypeError:
+            pass
+        return None
+    get = staticmethod(get)
+
+    def __init__(self, exception, gen):
+        if debug:
+            print "ExceptionTypeRepr: %s" % exception
+        self.gen = gen
+        self.exception = exception
+        self.name = "%std.exception"
+        self.objectname = gen.get_global_tmp("class.%s.object" %
+                                             self.exception.__name__)
+        s = "%s = internal global %%std.class {%%std.class* null, uint %i}"
+        self.definition = s % (self.objectname, abs(id(exception)))
+        self.dependencies = sets.Set()
+
+    def setup(self):
+        if len(self.exception.__bases__) != 0:
+            self.l_base = self.gen.get_repr(self.exception.__bases__[0])
+            self.dependencies.add(self.l_base)
+        else:
+            self.l_base = None
+
+    def llvmname(self):
+        return "%std.exception* "
+
+    def llvmtype(self):
+        return "%std.class* "
+
+    def typed_name(self):
+        return "%%std.class* %s" % self.objectname
+
+    def collect_init_code(self, lblock, l_func):
+        if self.l_base is None:
+            return
+        l_tmp = self.gen.get_local_tmp(None, l_func)
+        i = "%s = getelementptr %%std.class* %s, int 0, uint 0" % \
+            (l_tmp.llvmname(), self.objectname)
+        lblock.instruction(i)
+        lblock.instruction("store %%std.class* %s, %%std.class** %s" %
+                           (self.l_base.objectname, l_tmp.llvmname()))
+

Added: pypy/dist/pypy/translator/llvm/funcrepr.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/llvm/funcrepr.py	Sun Apr  3 20:23:50 2005
@@ -0,0 +1,473 @@
+import autopath
+import sets, StringIO
+
+from types import FunctionType, MethodType
+
+from pypy.objspace.flow.model import Variable, Constant, Block, Link
+from pypy.objspace.flow.model import last_exception, last_exc_value
+from pypy.objspace.flow.model import traverse, checkgraph
+from pypy.annotation import model as annmodel
+from pypy.translator.llvm import llvmbc
+from pypy.translator.unsimplify import remove_double_links
+
+from pypy.translator.llvm.representation import debug, LLVMRepr
+from pypy.translator.llvm.typerepr import TypeRepr, PointerTypeRepr
+
+
+INTRINSIC_OPS = ["lt", "le", "eq", "ne", "gt", "ge", "is", "is_true", "len",
+                 "neg", "pos", "invert", "add", "sub", "mul", "truediv",
+                 "floordiv", "div", "mod", "pow", "lshift", "rshift", "and_",
+                 "or", "xor", "inplace_add", "inplace_sub", "inplace_mul",
+                 "inplace_truediv", "inplace_floordiv", "inplace_div",
+                 "inplace_mod", "inplace_pow", "inplace_lshift",
+                 "inplace_rshift", "inplace_and", "inplace_or", "inplace_xor",
+                 "contains", "newlist", "newtuple", "alloc_and_set"]
+
+C_SIMPLE_TYPES = {annmodel.SomeChar: "char",
+                  annmodel.SomeString: "char*",
+                  annmodel.SomeBool: "unsigned char",
+                  annmodel.SomeInteger: "int"}
+
+
+class BuiltinFunctionRepr(LLVMRepr):
+    def get(obj, gen):
+        if isinstance(obj, Constant) and \
+           isinstance(gen.annotator.binding(obj), annmodel.SomeBuiltin):
+            return BuiltinFunctionRepr(obj.value.__name__, gen)
+        elif isinstance(obj, annmodel.SomeBuiltin):
+            name = obj.analyser.__name__.replace("method_", "")
+            return BuiltinFunctionRepr(name, gen)
+        return None
+    get = staticmethod(get)
+
+    def __init__(self, name, gen):
+        self.name = "%std." + name
+        self.gen = gen
+
+    def llvmname(self):
+        return self.name
+
+    def op_simple_call(self, l_target, args, lblock, l_func):
+        l_args = [self.gen.get_repr(arg) for arg in args]
+        l_func.dependencies.update(l_args)
+        if self.name == "%std.isinstance":
+            l_tmp = self.gen.get_local_tmp(PointerTypeRepr("%std.object",
+                                                           self.gen), l_func)
+            l_func.dependencies.add(l_tmp)
+            lblock.cast(l_tmp, l_args[1])
+            l_args[1] = l_tmp
+        lblock.call(l_target, l_args[0], l_args[1:])
+
+class FunctionRepr(LLVMRepr):
+    l_functions = {}
+    def get(obj, gen):
+        name = None
+        if isinstance(obj, annmodel.SomePBC) and \
+                 len(obj.prebuiltinstances) == 1:
+            obj = obj.prebuiltinstances.keys()[0]
+        elif isinstance(obj, Constant):
+            obj = obj.value
+        if isinstance(obj, MethodType):
+            name = obj.im_class.__name__ + "." + obj.im_func.__name__
+            obj = obj.im_func
+        if isinstance(obj, FunctionType):
+            if (obj, gen) in FunctionRepr.l_functions:
+                return FunctionRepr.l_functions[(obj, gen)]
+            if name is None:
+                name = obj.__name__
+            l_func = FunctionRepr(gen.get_global_tmp(name), obj, gen)
+            FunctionRepr.l_functions[(obj, gen)] = l_func
+            return l_func
+        return None
+    get = staticmethod(get)
+
+    def __init__(self, name, function, gen):
+        if debug:
+            print "FunctionRepr: %s" % name
+        self.gen = gen
+        self.func = function
+        self.translator = gen.translator
+        self.name = name
+        self.graph = self.translator.getflowgraph(self.func)
+        self.annotator = gen.translator.annotator
+        self.blocknum = {}
+        self.allblocks = []
+        self.pyrex_source = ""
+        self.dependencies = sets.Set()
+        remove_double_links(self.translator, self.graph)
+        self.get_bbs()
+        self.se = False
+
+    def setup(self):
+        if self.se:
+            return
+        self.se = True
+        self.l_args = [self.gen.get_repr(ar)
+                       for ar in self.graph.startblock.inputargs]
+        self.dependencies.update(self.l_args)
+        self.retvalue = self.gen.get_repr(self.graph.returnblock.inputargs[0])
+        self.dependencies.add(self.retvalue)
+        self.build_bbs()
+
+    def get_returntype():
+        return self.rettype.llvmname()
+
+    def get_bbs(self):
+        def visit(node):
+            if isinstance(node, Block) and node not in self.blocknum:
+                self.allblocks.append(node)
+                self.blocknum[node] = len(self.blocknum)
+        traverse(visit, self.graph)
+        self.same_origin_block = [False] * len(self.allblocks)
+
+    def build_bbs(self):
+        checkgraph(self.graph)
+        a = self.annotator
+        for number, pyblock in enumerate(self.allblocks):
+            pyblock = self.allblocks[number]
+            is_tryblock = isinstance(pyblock.exitswitch, Constant) and \
+                          pyblock.exitswitch.value == last_exception
+            if is_tryblock:
+                regularblock = "block%i" % self.blocknum[
+                    pyblock.exits[0].target]
+                exceptblock = "block%i.except" % self.blocknum[pyblock]
+                lblock = llvmbc.TryBasicBlock("block%i" % number,
+                                              regularblock, exceptblock)
+                l_excblock = llvmbc.BasicBlock("block%i.except" % number)
+                l_excp = self.gen.get_repr(last_exception)
+                l_uip = self.gen.get_local_tmp(PointerTypeRepr("uint",
+                                                               self.gen), self)
+                l_ui = self.gen.get_local_tmp(
+                    self.gen.get_repr(annmodel.SomeInteger(True, True)), self)
+                self.dependencies.update([l_excp, l_uip, l_ui])
+                l_excblock.load(l_cl, l_excp)
+                l_excblock.getelementptr(l_uip, l_cl, [0, 1])
+                l_excblock.load(l_ui, l_uip)
+                l_excblock.switch(l_ui, "%%block%i.unwind" % number,
+                                  [(str(abs(id(l_c))),
+                                    XXXXXXXXXXXXX)
+                                   for exc in pyblock.exits[1:]])
+            else:
+                lblock = llvmbc.BasicBlock("block%i" % number)
+            if number == 0:
+                self.llvm_func = llvmbc.Function(self.llvmfuncdef(), lblock)
+            else:
+                self.llvm_func.basic_block(lblock)
+            #Create Phi nodes (but not for the first block)
+            incoming_links = []
+            def visit(node):
+                if isinstance(node, Link) and node.target == pyblock:
+                    incoming_links.append(node)
+            traverse(visit, self.graph)
+            if len(incoming_links) != 0:
+                for i, arg in enumerate(pyblock.inputargs):
+                    l_arg = self.gen.get_repr(arg)
+                    l_values = [self.gen.get_repr(l.args[i])
+                                for l in incoming_links]
+                    for j in range(len(l_values)):
+                        if l_values[j].llvmtype() != l_arg.llvmtype():
+                            try:
+                                l_values[j] = \
+                                        l_values[j].alt_types[l_arg.llvmtype()]
+                            except KeyError:
+                                pass
+                    self.dependencies.add(l_arg)
+                    self.dependencies.update(l_values)
+                    lblock.phi(l_arg, l_values,
+                               ["%%block%i" % self.blocknum[l.prevblock]
+                                for l in incoming_links])
+            #Handle SpaceOperations
+            for op in pyblock.operations:
+                l_target = self.gen.get_repr(op.result)
+                self.dependencies.add(l_target)
+                l_arg0 = self.gen.get_repr(op.args[0])
+                self.dependencies.add(l_arg0)
+                l_op = getattr(l_arg0, "op_" + op.opname, None)
+                if l_op is not None:
+                    l_op(l_target, op.args, lblock, self)
+                #XXX need to find more elegant solution for this special case
+                elif op.opname == "newtuple":
+                    l_target.type.t_op_newtuple(l_target, op.args,
+                                                lblock, self)
+                elif op.opname in INTRINSIC_OPS:
+                    l_args = [self.gen.get_repr(arg) for arg in op.args[1:]]
+                    self.dependencies.update(l_args)
+                    lblock.spaceop(l_target, op.opname, [l_arg0] + l_args)
+                else:
+                        s = "SpaceOperation %s not supported. Target: %s " \
+                            "Args: %s " % (op.opname, l_target, op.args) + \
+                            "Dispatched on: %s" % l_arg0
+                            
+                        raise CompileError, s
+            # XXX: If a variable is passed to another block and has a different
+            # type there, we have to make the cast in this block since the phi
+            # instructions in the next block cannot be preceded by any other
+            # instruction
+            for link in pyblock.exits:
+                for i, arg in enumerate(link.args):
+                    localtype = self.annotator.binding(arg)
+                    targettype = self.annotator.binding(
+                        link.target.inputargs[i])
+                    l_targettype = self.gen.get_repr(targettype)
+                    l_localtype = self.gen.get_repr(localtype)
+                    l_local = self.gen.get_repr(arg)
+                    self.dependencies.update([l_targettype, l_localtype,
+                                              l_local])
+                    if l_targettype.llvmname() != l_localtype.llvmname():
+                        l_tmp = self.gen.get_local_tmp(l_targettype, self)
+                        lblock.cast(l_tmp, l_local)
+                        l_local.alt_types = {l_targettype.llvmname(): l_tmp}
+            #Create branches
+            if pyblock.exitswitch is None:
+                if pyblock == self.graph.returnblock:
+                    l_returnvalue = self.gen.get_repr(pyblock.inputargs[0])
+                    self.dependencies.add(l_returnvalue)
+                    lblock.ret(l_returnvalue)
+                else:
+                    lblock.uncond_branch(
+                        "%%block%i" % self.blocknum[pyblock.exits[0].target])
+            elif isinstance(pyblock.exitswitch, Constant) and \
+                 pyblock.exitswitch.value == last_exception:
+                lblock.uncond_branch(
+                    "%%block%i" % self.blocknum[pyblock.exits[0].target])
+            else:
+                assert isinstance(a.binding(pyblock.exitswitch),
+                                  annmodel.SomeBool)
+                l_switch = self.gen.get_repr(pyblock.exitswitch)
+                self.dependencies.add(l_switch)
+                lblock.cond_branch(
+                    l_switch,
+                    "%%block%i" % self.blocknum[pyblock.exits[1].target],
+                    "%%block%i" % self.blocknum[pyblock.exits[0].target])
+
+    def llvmfuncdef(self):
+        s = "internal %s %s(" % (self.retvalue.llvmtype(), self.name)
+        return s + ", ".join([a.typed_name() for a in self.l_args]) + ")"
+
+    def rettype(self):
+        return self.retvalue.llvmtype()
+
+    def get_functions(self):
+        return str(self.llvm_func)
+
+    def llvmtype(self):
+        assert self.llvmfuncdef().count(self.name) == 1
+        return self.llvmfuncdef().replace(self.name + "(", "(") + "*"
+
+    def op_simple_call(self, l_target, args, lblock, l_func):
+        l_args = [self.gen.get_repr(arg) for arg in args]
+        for i, (l_a1, l_a2) in enumerate(zip(l_args[1:], self.l_args)):
+            if l_a1.llvmtype() != l_a2.llvmtype():
+                l_tmp = self.gen.get_local_tmp(l_a2.type, l_func)
+                lblock.cast(l_tmp, l_a1)
+                l_args[1 + i] = l_tmp
+        l_func.dependencies.update(l_args)
+        lblock.call(l_target, l_args[0], l_args[1:])
+
+class EntryFunctionRepr(LLVMRepr):
+    def get(obj, gen):
+        return None
+    get = staticmethod(get)
+
+    def __init__(self, name, function, gen):
+        self.gen = gen
+        self.function = function
+        self.name = name
+        self.dependencies = sets.Set()
+        self.branch_added = False
+
+    def setup(self):
+        self.l_function = self.gen.get_repr(self.function)
+        self.dependencies.add(self.l_function)
+        lblock = llvmbc.BasicBlock("entry")
+        lblock.instruction("%tmp = load bool* %Initialized.0__")
+        lblock.instruction("br bool %tmp, label %real_entry, label %init")
+        self.llvm_func = llvmbc.Function(self.llvmfuncdef(), lblock)
+        self.init_block = llvmbc.BasicBlock("init")
+        self.init_block.instruction("store bool true, bool* %Initialized.0__")
+        real_entry = llvmbc.BasicBlock("real_entry")
+        l_ret = self.gen.get_local_tmp(self.l_function.retvalue.type, self)
+        self.l_function.op_simple_call(
+            l_ret, [self.function] + self.l_function.l_args, real_entry, self)
+        real_entry.ret(l_ret)
+        self.llvm_func.basic_block(real_entry)
+        self.llvm_func.basic_block(self.init_block)
+        
+    def cfuncdef(self):
+        a = self.l_function.translator.annotator
+        retv = self.l_function.graph.returnblock.inputargs[0]
+        rettype_c = C_SIMPLE_TYPES[a.binding(retv).__class__]
+        args = self.l_function.graph.startblock.inputargs
+        argtypes_c = [C_SIMPLE_TYPES[a.binding(v).__class__] for v in args]
+        fd = "%s %s(%s)" % (rettype_c, self.name[1:],
+                            ", ".join(argtypes_c))
+        return fd
+
+    def llvmfuncdef(self):
+        s = "%s %s(" % (self.l_function.retvalue.llvmtype(), self.name)
+        s += ", ".join([a.typed_name() for a in self.l_function.l_args]) + ")"
+        return s
+
+    def get_pyrex_source(self):
+        name = self.name[1:]
+        args = self.l_function.graph.startblock.inputargs
+        self.pyrex_source = ["cdef extern %s\n" %
+                             (self.cfuncdef())]
+        self.pyrex_source += ["def wrap_%s(" % name]
+        t = []
+        for i, a in enumerate(args):
+            t += ["%s" % a]
+        t = ", ".join(t)
+        self.pyrex_source += t + "):\n\treturn %s(%s)\n\n" % (name, t)
+        self.pyrex_source = "".join(self.pyrex_source)
+        return self.pyrex_source
+
+    def rettype(self):
+        return self.l_function.retvalue.llvmtype()
+
+    def get_functions(self):
+        if not self.branch_added:
+            self.init_block.uncond_branch("%real_entry")
+        return str(self.llvm_func)
+
+    def get_globals(self):
+        return "%Initialized.0__ = internal global bool false"
+
+    def llvmtype(self):
+        assert self.llvmfuncdef().count(self.name) == 1
+        return self.llvmfuncdef().replace(self.name + "(", "(") + "*"
+
+    def op_simple_call(self, l_target, args, lblock, l_func):
+        self.l_function.op_simple_call(l_target, [self.function] + args,
+                                       lblock, l_func)
+
+class VirtualMethodRepr(LLVMRepr):
+    # Really stupid implementation of virtual functions:
+    # Do a switch on the id of the class of the object and cast the object
+    # to the appropriate class
+    # Should be replaced by function pointers
+    def get(obj, gen):
+        if isinstance(obj, annmodel.SomePBC) and \
+                 len(obj.prebuiltinstances) > 1 and \
+                 isinstance(obj.prebuiltinstances.keys()[0], FunctionType):
+            return VirtualMethodRepr(obj.prebuiltinstances, gen)
+        return None
+    get = staticmethod(get)
+
+    def __init__(self, prebuiltinstances, gen):
+        if debug:
+            print "VirtualMethodRepr: %s" % prebuiltinstances
+        self.gen = gen
+        classes = prebuiltinstances.values()
+        self.commonbase = reduce(lambda a, b: a.commonbase(b), classes)
+        self.funcs = prebuiltinstances.keys()
+        self.name = "%" + self.funcs[0].__name__ + ".virtual"
+        self.attribute = self.funcs[0].__name__
+        self.dependencies = sets.Set()
+
+    def setup(self):
+        self.l_commonbase = self.gen.get_repr(self.commonbase)
+        self.l_classes = [self.l_commonbase] + \
+                         list(self.l_commonbase.iter_subclasses())
+        self.dependencies.update(self.l_classes)
+        self.l_funcs = []
+        #find appropriate method for every class
+        for l_cls in self.l_classes:
+            for classdef in l_cls.classdef.getmro():
+                if classdef.cls.__dict__.has_key(self.attribute):
+                    self.l_funcs.append(self.gen.get_repr(
+                        classdef.cls.__dict__[self.attribute]))
+                    break
+            else:
+                raise CompileError, "Couldn't find method %s for %s" % \
+                      (self.attribute, l_cls.classdef.cls)
+        self.dependencies.update(self.l_funcs)
+        self.retvalue = self.l_funcs[0].retvalue
+        self.type_numbers = [id(l_c) for l_c in self.l_classes]
+        self.l_args = [self.gen.get_repr(ar)
+                       for ar in self.l_funcs[0].graph.startblock.inputargs]
+        l_retvalue = self.retvalue
+        self.dependencies.update(self.l_args)
+        #create function
+        #XXX pretty messy
+        entryblock = llvmbc.BasicBlock("entry")
+        l_clp = self.gen.get_local_tmp(PointerTypeRepr("%std.class*",
+                                                       self.gen), self)
+        l_cl = self.gen.get_local_tmp(PointerTypeRepr("%std.class",
+                                                      self.gen), self)
+        l_uip = self.gen.get_local_tmp(PointerTypeRepr("uint", self.gen),
+                                       self)
+        l_ui = self.gen.get_local_tmp(
+            self.gen.get_repr(annmodel.SomeInteger(True, True)), self)
+        self.dependencies.update([l_clp, l_cl, l_uip, l_ui])
+        entryblock.getelementptr(l_clp, self.l_args[0], [0, 0])
+        entryblock.load(l_cl, l_clp)
+        entryblock.getelementptr(l_uip, l_cl, [0, 1])
+        entryblock.load(l_ui, l_uip)
+        entryblock.switch(l_ui, "%" + self.l_commonbase.classdef.cls.__name__,
+                          [(str(abs(id(l_c))), "%" + l_c.classdef.cls.__name__)
+                           for l_c in self.l_classes])
+        lfunc = llvmbc.Function(self.llvmfuncdef(), entryblock)
+        for i, l_cls in enumerate(self.l_classes):
+            lblock = llvmbc.BasicBlock(l_cls.classdef.cls.__name__)
+            lfunc.basic_block(lblock)
+            l_tmp = self.gen.get_local_tmp(l_cls, self)
+            lblock.cast(l_tmp, self.l_args[0])
+            l_tmp_ret = self.gen.get_local_tmp(l_retvalue.type, self)
+            self.l_funcs[i].op_simple_call(
+                l_tmp_ret, [self.l_funcs[i], l_tmp] + 
+                self.l_funcs[0].graph.startblock.inputargs[1:], lblock, self)
+            lblock.ret(l_tmp_ret)
+        self.llvm_func = lfunc
+
+    def op_simple_call(self, l_target, args, lblock, l_func):
+        name = self.name[1:-8]
+        l_args = [self.gen.get_repr(arg) for arg in args]
+        l_func.dependencies.update(l_args)
+        # call the method directly if no subclass of the class of args[1] has
+        # a special version of this method defined
+        for l_cls in l_args[1].type.iter_subclasses():
+            if l_cls.classdef.cls.__dict__.has_key(name):
+                break
+        else:
+            for clsdef in l_args[1].type.classdef.getmro():
+                if clsdef.cls.__dict__.has_key(name):
+                    l_method = self.gen.get_repr(clsdef.cls.__dict__[name])
+                    args[0] = l_method
+                    print l_method.llvmname(), l_method
+                    l_method.op_simple_call(l_target, args, lblock, l_func)
+                    return
+        if l_args[1].llvmtype() != self.l_args[0].llvmtype():
+            l_tmp = self.gen.get_local_tmp(self.l_args[0].type, l_func)
+            l_func.dependencies.add(l_tmp)
+            lblock.cast(l_tmp, l_args[1])
+            l_args[1] = l_tmp
+        lblock.call(l_target, l_args[0], l_args[1:])
+        return
+        
+    def get_functions(self):
+        return str(self.llvm_func)
+
+    def llvmfuncdef(self):
+        s = "internal %s %s(" % (self.l_funcs[0].retvalue.llvmtype(),
+                                 self.name)
+        return s + ", ".join([a.typed_name() for a in self.l_args]) + ")"
+
+    def rettype(self):
+        return self.retvalue.llvmtype()
+
+class BoundMethodRepr(LLVMRepr):
+    def get(obj, gen):
+        return None
+    get = staticmethod(get)
+    def __init__(self, l_func, l_self, l_class, gen):
+        self.gen = gen
+        self.l_func = l_func
+        self.l_self = l_self
+        self.l_class = l_class
+        self.dependencies = sets.Set([l_self, l_class, l_func])
+
+    def t_op_simple_call(self, l_target, args, lblock, l_func):
+        self.l_func.op_simple_call(l_target,
+                                   [self.l_func, self.l_self] + args[1:],
+                                   lblock, l_func)

Modified: pypy/dist/pypy/translator/llvm/genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/genllvm.py	(original)
+++ pypy/dist/pypy/translator/llvm/genllvm.py	Sun Apr  3 20:23:50 2005
@@ -18,8 +18,11 @@
 from pypy.translator.llvm.test import llvmsnippet as test2
 
 
-from pypy.translator.llvm.representation import *
+from pypy.translator.llvm import representation, funcrepr, typerepr, seqrepr
+from pypy.translator.llvm import classrepr
 
+from pypy.translator.llvm.representation import LLVMRepr, TmpVariableRepr
+from pypy.translator.llvm.funcrepr import EntryFunctionRepr
 
 debug = True
 
@@ -44,9 +47,10 @@
         self.annotator = self.translator.annotator
         self.global_counts = {}
         self.local_counts = {}
-        self.repr_classes = [eval(s)
-                             for s in dir(sys.modules.get(self.__module__))
-                             if "Repr" in s]
+        self.repr_classes = []
+        for mod in [representation, funcrepr, typerepr, seqrepr, classrepr]:
+            self.repr_classes += [getattr(mod, s)
+                                  for s in dir(mod) if "Repr" in s]
         self.llvm_reprs = {}
         self.depth = 0
         self.entryname = self.translator.functions[0].__name__
@@ -160,3 +164,8 @@
     yield l_repr
 
 
+t = Translator(test2.two_exceptions)
+a = t.annotate([int])
+a.simplify()
+## t.view()
+f = llvmcompile(t)

Modified: pypy/dist/pypy/translator/llvm/llvmbc.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/llvmbc.py	(original)
+++ pypy/dist/pypy/translator/llvm/llvmbc.py	Sun Apr  3 20:23:50 2005
@@ -128,6 +128,9 @@
                                     l_target.llvmtype())
         self.instructions.append(s)
 
+    def unwind(self):
+        self.instructions.append("unwind")
+
     def __str__(self):
         s = [self.label + ":\n"]
         for ins in self.instructions:
@@ -144,6 +147,19 @@
         self.instructions = []
         self.finalized = False
 
+    def spaceop(self, l_target, opname, l_args):
+        if l_target.llvmtype() == "void":
+            s = "invoke void %%std.%s.exc(" % opname
+        else:
+            s = "%s = invoke %s %%std.%s.exc(" % (l_target.llvmname(),
+                                                  l_target.llvmtype(), opname)
+        s += ", ".join([a.typed_name() for a in l_args]) + ")"
+        s += "\n\t\tto label %%%s.%i\n\t\texcept label %%%s" % \
+             (self.label, len(self.llvmblocks), self.exceptblock)        
+        self.instructions.append(s)
+        self.llvmblocks.append(self.instructions)
+        self.instructions = []
+
     def invoke(self, l_target, l_func, l_args):
         if l_target.llvmtype() == "void":
             s = "invoke void %s(" % l_func.llvmname()
@@ -153,24 +169,27 @@
             s = "%s = invoke %s %s(" % (l_target.llvmname(),
                                         l_target.llvmtype(), l_func.llvmname())
         s += ", ".join([a.typed_name() for a in l_args]) + ")"
-        s += "\n\t\tto label %s.%i\n\t\texcept label %s" % \
+        s += "\n\t\tto label %%%s.%i\n\t\texcept label %%%s" % \
              (self.label, len(self.llvmblocks), self.exceptblock)
         self.instructions.append(s)
         self.llvmblocks.append(self.instructions)
         self.instructions = []
 
+    call = invoke
+
     def invoke_void(self, l_func, l_args):
         s = "call %s %s(" % (l_func.rettype(), l_func.llvmname())
         s += ", ".join([a.typed_name() for a in l_args]) + ")"
-        s += "\n\t\tto label %s.%i\n\t\texcept label %s" % \
+        s += "\n\t\tto label %%%s.%i\n\t\texcept label %%%s" % \
              (self.label, len(self.llvmblocks), self.exceptblock)
         self.instructions.append(s)
         self.llvmblocks.append(self.instructions)
         self.instructions = []
 
+    call_void = invoke_void
+
     def __str__(self):
         if not self.finalized:
-            self.uncond_branch(self.regularblock)
             self.llvmblocks.append(self.instructions)
             self.instructions = []
             self.finalized = True

Modified: pypy/dist/pypy/translator/llvm/representation.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/representation.py	(original)
+++ pypy/dist/pypy/translator/llvm/representation.py	Sun Apr  3 20:23:50 2005
@@ -1,41 +1,16 @@
 import autopath
-import exceptions, sets, StringIO
+import sets
 
-from types import FunctionType, MethodType, ClassType
-import new
-
-from pypy.objspace.flow.model import Variable, Constant, SpaceOperation
-from pypy.objspace.flow.model import FunctionGraph, Block, Link
-from pypy.objspace.flow.model import last_exception, last_exc_value
-from pypy.objspace.flow.model import traverse, uniqueitems, checkgraph
+from pypy.objspace.flow.model import Variable, Constant
 from pypy.annotation import model as annmodel
-from pypy.annotation.classdef import ClassDef
-from pypy.translator.llvm import llvmbc
-from pypy.translator.unsimplify import remove_double_links
-
-INTRINSIC_OPS = ["lt", "le", "eq", "ne", "gt", "ge", "is", "is_true", "len",
-                 "neg", "pos", "invert", "add", "sub", "mul", "truediv",
-                 "floordiv", "div", "mod", "pow", "lshift", "rshift", "and_",
-                 "or", "xor", "inplace_add", "inplace_sub", "inplace_mul",
-                 "inplace_truediv", "inplace_floordiv", "inplace_div",
-                 "inplace_mod", "inplace_pow", "inplace_lshift",
-                 "inplace_rshift", "inplace_and", "inplace_or", "inplace_xor",
-                 "contains", "newlist", "newtuple", "alloc_and_set"]
-
-C_SIMPLE_TYPES = {annmodel.SomeChar: "char",
-                  annmodel.SomeString: "char*",
-                  annmodel.SomeBool: "unsigned char",
-                  annmodel.SomeInteger: "int"}
-
 
 LLVM_SIMPLE_TYPES = {annmodel.SomeChar: "sbyte",
                      annmodel.SomeBool: "bool"}
 
-
 debug = False
 
 
-class CompileError(exceptions.Exception):
+class CompileError(Exception):
     pass
 
 
@@ -71,7 +46,7 @@
     def get_dependencies(self):
         try:
             return self.dependencies
-        except exceptions.AttributeError:
+        except AttributeError:
             return []
 
 
@@ -279,942 +254,3 @@
                                    % repr(name))
 
 
-class TypeRepr(LLVMRepr):
-    def get(obj, gen):
-        if (isinstance(obj, annmodel.SomePBC) and \
-               obj.prebuiltinstances.keys()[0] is None) or obj is type(None):
-            return TypeRepr("%std.void", "%std.void = type sbyte", "", gen)
-    get = staticmethod(get)
-
-    def __init__(self, llvmname, definition, includefile, gen):
-        if debug:
-            print "TypeRepr: %s, %s" % (llvmname, definition)
-        self.name = llvmname
-        self.definition = definition
-        self.gen = gen
-        self.includefile = includefile
-
-    def get_globals(self):
-        try:
-            return self.definition
-        except exceptions.AttributeError:
-            return ""
-
-    def get_functions(self):
-        try:
-            if self.includefile != "":
-                f = file(autopath.this_dir + "/" + self.includefile, "r")
-                s = f.read()
-                f.close()
-                return s
-        except exceptions.AttributeError:
-            pass
-        return ""
-
-    def llvmname(self):
-        return self.name + "*"
-
-    def llvmname_wo_pointer(self):
-        return self.name
-
-class StringTypeRepr(TypeRepr):
-    def get(obj, gen):
-        if obj.__class__ is annmodel.SomeString or obj is str:
-            return StringTypeRepr(gen)
-    get = staticmethod(get)
-
-    def __init__(self, gen):
-        if debug:
-            print "StringTypeRepr"
-        self.gen = gen
-        self.dependencies = sets.Set()
-
-    def setup(self):
-        self.l_charlist = self.gen.get_repr(
-            annmodel.SomeList(None, annmodel.SomeChar()))
-        self.dependencies.add(self.l_charlist)
-        self.name = self.l_charlist.llvmname_wo_pointer()
-
-    def t_op_getitem(self, l_target, args, lblock, l_func):
-        l_args = [self.gen.get_repr(arg) for arg in args]
-        l_func.dependencies.update(l_args)
-        lblock.spaceop(l_target, "getitem", l_args)
-
-    def t_op_inplace_add(self, l_target, args, lblock, l_func):
-        l_args = [self.gen.get_repr(arg) for arg in args]
-        l_func.dependencies.update(l_args)
-        lblock.spaceop(l_target, "add", l_args)
-
-class ListTypeRepr(TypeRepr):
-    l_listtypes = {}
-    def get(obj, gen):
-        if obj.__class__ is annmodel.SomeList:
-            if (obj.s_item.__class__, gen) in ListTypeRepr.l_listtypes:
-                return ListTypeRepr.l_listtypes[(obj.s_item.__class__, gen)]
-            l_repr = ListTypeRepr(obj, gen)
-            ListTypeRepr.l_listtypes[(obj.s_item.__class__, gen)] = l_repr
-            return l_repr
-        return None
-    get = staticmethod(get)
-
-    def __init__(self, obj, gen):
-        if debug:
-            print "ListTypeRepr: %s, %s" % (obj, obj.s_item)
-        self.gen = gen
-        self.l_itemtype = gen.get_repr(obj.s_item)
-        self.dependencies = sets.Set([self.l_itemtype])
-        itemtype = self.l_itemtype.llvmname()
-        self.name = "%%std.list.%s" % itemtype.strip("%").replace("*", "")
-        self.definition = self.name + " = type {uint, %s*}" % itemtype
-
-    def get_functions(self):
-        f = file(autopath.this_dir + "/list_template.ll", "r")
-        s = f.read()
-        f.close()
-        itemtype = self.l_itemtype.llvmname()
-        s = s.replace("%(item)s", self.l_itemtype.llvmname())
-        s = s.replace("%(name)s", itemtype.strip("%").replace("*", ""))
-        if isinstance(self.l_itemtype, IntTypeRepr):
-            f1 = file(autopath.this_dir + "/int_list.ll", "r")
-            s += f1.read()
-            f1.close()
-        return s
-
-    def t_op_getitem(self, l_target, args, lblock, l_func):
-        l_args = [self.gen.get_repr(arg) for arg in args]
-        l_func.dependencies.update(l_args)
-        lblock.spaceop(l_target, "getitem", l_args)
-
-    def t_op_setitem(self, l_target, args, lblock, l_func):
-        l_args = [self.gen.get_repr(arg) for arg in args]
-        l_func.dependencies.update(l_args)
-        lblock.spaceop(l_target, "setitem", l_args)
-
-    def t_op_delitem(self, l_target, args, lblock, l_func):
-        l_args = [self.gen.get_repr(arg) for arg in args]
-        l_func.dependencies.update(l_args)
-        lblock.spaceop(l_target, "delitem", l_args)
-
-    def t_op_getattr(self, l_target, args, lblock, l_func):
-        if isinstance(args[1], Constant) and \
-               args[1].value in ["append", "reverse", "pop"]:
-            l_args0 = self.gen.get_repr(args[0])
-            l_func.dependencies.add(l_args0)
-            l_method = BoundMethodRepr(l_target.type, l_args0, self, self.gen)
-            l_method.setup()
-            l_target.type = l_method
-        else:
-            raise CompileError, "List method %s not supported." % args[1].value
-
-class TupleTypeRepr(TypeRepr):
-    def get(obj, gen):
-        if isinstance(obj, annmodel.SomeTuple):
-            return TupleTypeRepr(obj, gen)
-        return None
-    get = staticmethod(get)
-
-    def __init__(self, obj, gen):
-        self.gen = gen
-        self.l_itemtypes = [gen.get_repr(l) for l in obj.items]
-        self.name = (("{" + ", ".join(["%s"] * len(self.l_itemtypes)) + "}") %
-                     tuple([l.llvmname() for l in self.l_itemtypes]))
-
-    def get_functions(self):
-        s = ("internal int %%std.len(%s %%t) {\n\tret int %i\n}\n" %
-             (self.llvmname(), len(self.l_itemtypes)))
-        return s
-
-    def t_op_newtuple(self, l_target, args, lblock, l_func):
-        l_args = [self.gen.get_repr(arg) for arg in args]
-        l_func.dependencies.update(l_args)
-        lblock.malloc(l_target, self)
-        l_ptrs = [self.gen.get_local_tmp(\
-            PointerTypeRepr(l.llvmname(),self.gen), l_func)
-                  for l in self.l_itemtypes]
-        l_func.dependencies.update(l_ptrs)
-        for i, l in enumerate(self.l_itemtypes):
-            lblock.getelementptr(l_ptrs[i], l_target, [0, i])
-            lblock.store(l_args[i], l_ptrs[i])
-
-    def t_op_getitem(self, l_target, args, lblock, l_func):
-        if not isinstance(args[1], Constant):
-            raise CompileError, "index for tuple's getitem has to be constant"
-        l_args = [self.gen.get_repr(arg) for arg in args]
-        l_func.dependencies.update(l_args)
-        l_tmp = self.gen.get_local_tmp(PointerTypeRepr(l_target.llvmtype(),
-                                                       self.gen), l_func)
-        cast = getattr(l_args[1], "cast_to_unsigned", None)
-        if cast is not None:
-            l_unsigned = cast(l_args[1], lblock, l_func)
-        else:
-            raise CompileError, "Invalid arguments to getitem"
-        lblock.getelementptr(l_tmp, l_args[0], [0, l_unsigned])
-        lblock.load(l_target, l_tmp)
-
-class IntTypeRepr(TypeRepr):
-    def get(obj, gen):
-        if obj.__class__ is annmodel.SomeInteger:
-            return IntTypeRepr(obj, gen)
-        return None
-    get = staticmethod(get)
-
-    def __init__(self, annotation, gen):
-        if debug:
-            print "IntTypeRepr: %s" % annotation
-        self.annotation = annotation
-        if annotation.unsigned:
-            self.name = "uint"
-        else:
-            self.name = "int"
-        self.gen = gen
-
-    def llvmname(self):
-        return self.name
-
-    def cast_to_signed(self, l_val, lblock, l_function):
-        if not self.annotation.unsigned:
-            return l_val
-        ann = annmodel.SomeInteger()
-        l_type = self.gen.get_repr(ann)
-        l_tmp = self.gen.get_local_tmp(l_type, l_function)
-        l_function.dependencies.update([l_type, l_tmp])
-        lblock.cast(l_tmp, l_val, l_type)
-        return l_tmp
-
-    def cast_to_unsigned(self, l_val, lblock, l_function):
-        if self.annotation.unsigned:
-            return l_val
-        ann = annmodel.SomeInteger(True, True)
-        l_type = self.gen.get_repr(ann)
-        l_tmp = self.gen.get_local_tmp(l_type, l_function)
-        l_function.dependencies.update([l_type, l_tmp])
-        lblock.cast(l_tmp, l_val, l_type)
-        return l_tmp
-
-class ClassObjectRepr(TypeRepr):
-    def get(obj, gen):
-        pass
-    get = staticmethod(get)
-
-
-class SimpleTypeRepr(TypeRepr):
-    def get(obj, gen):
-        if obj.__class__ is annmodel.SomeInteger:
-            l_repr = SimpleTypeRepr("int", gen)
-            return l_repr
-        elif obj.__class__ is annmodel.SomeBool:
-            l_repr = SimpleTypeRepr("bool", gen)
-            return l_repr
-        elif obj.__class__ is annmodel.SomeChar:
-            l_repr = SimpleTypeRepr("sbyte", gen)
-            return l_repr
-        elif obj.__class__ is annmodel.SomePBC:
-            if obj.knowntype == object or obj.knowntype == ClassType:
-                return SimpleTypeRepr("%std.class", gen)
-        return None
-    get = staticmethod(get)
-
-    def __init__(self, llvmname, gen):
-        if debug:
-            print "SimpleTypeRepr: %s" % llvmname
-        self.name = llvmname
-        self.gen = gen
-        self.definition = ""
-        self.includefile = ""
-
-    def llvmname(self):
-        return self.name
-
-class PointerTypeRepr(TypeRepr):
-    def get(obj, gen):
-        return None
-    get = staticmethod(get)
-
-    def __init__(self, type, gen):
-        self.type = type
-
-    def llvmname(self):
-        return self.type + "*"
-
-class ImpossibleValueRepr(TypeRepr):
-    def get(obj, gen):
-        if obj.__class__ is annmodel.SomeImpossibleValue:
-            return ImpossibleValueRepr()
-        return None
-    get = staticmethod(get)
-    
-    def __init__(self):
-        self.definition = ""
-        self.dependencies = sets.Set()
-        self.includefile = ""
-
-    def llvmname(self):
-        return "void"
-
-
-class ClassRepr(TypeRepr):
-    l_classes = {}
-    def get(obj, gen):
-        classdef = None
-        if obj.__class__ is Constant:
-            bind = gen.annotator.binding(obj)
-            if bind.__class__ is annmodel.SomePBC and \
-                gen.annotator.bookkeeper.userclasses.has_key(bind.const):
-                    classdef = gen.annotator.bookkeeper.userclasses[bind.const]
-        elif isinstance(obj, annmodel.SomeInstance):
-            classdef = obj.classdef
-        elif isinstance(obj, ClassDef):
-            classdef = obj
-        if classdef is None:
-            return None
-        if (classdef, gen) not in ClassRepr.l_classes:
-            ClassRepr.l_classes[(classdef, gen)] = ClassRepr(classdef, gen)
-        return ClassRepr.l_classes[(classdef, gen)]
-    get = staticmethod(get)
-
-    def __init__(self, obj, gen):
-        if debug:
-            print "ClassRepr: %s, %s" % (obj, hex(id(self)))
-        self.classdef = obj
-        self.gen = gen
-        self.includefile = ""
-        self.name = gen.get_global_tmp("class.%s" % self.classdef.cls.__name__)
-        self.objectname = gen.get_global_tmp("class.%s.object" %
-                                             self.classdef.cls.__name__)
-        if debug:
-            print self.name
-        self.dependencies = sets.Set()
-        self.setup_done = False
-        self.attr_num = {}
-
-    def setup(self):
-        if self.setup_done:
-            return
-        self.setup_done = True
-        if debug:
-            print "ClassRepr.setup()", id(self), hex(id(self)), self.setup_done
-            print len(ClassRepr.l_classes)
-        gen = self.gen
-        if self.classdef.basedef is not None: #get attributes from base classes
-            self.l_base = gen.get_repr(self.classdef.basedef)
-            self.dependencies.add(self.l_base)
-            attribs = self.l_base.attributes
-        else:
-            self.l_base = None
-            attribs = []
-        meth = []
-        if debug:
-            print "attributes", self.classdef.attrs
-        #get attributes of this class and decide whether they are methods
-        for key, attr in self.classdef.attrs.items():
-            if debug:
-                print key, attr, attr.sources, attr.s_value,
-            if len(attr.sources) != 0:
-                func = self.classdef.cls.__dict__[attr.name]
-                meth.append((key, func))
-                if debug:
-                    print "--> method1"
-            elif isinstance(attr.s_value, annmodel.SomePBC) and \
-               attr.s_value.knowntype is FunctionType:
-                func = self.classdef.cls.__dict__[attr.name]
-                meth.append((key, func))
-                if debug:
-                    print "--> method2"
-            else:
-                attribs.append(attr)
-                if debug:
-                    print "--> value"
-        self.l_attrs_types = [gen.get_repr(attr.s_value) for attr in attribs]
-        self.dependencies = sets.Set(self.l_attrs_types)
-        attributes = ", ".join([at.llvmname() for at in self.l_attrs_types])
-        self.definition = "%s = type {%%std.class*, %s}" % (self.name,
-                                                           attributes)
-        self.attributes = attribs
-        self.attr_num = {}
-        for i, attr in enumerate(attribs):
-            self.attr_num[attr.name] = i + 1
-        self.methods = dict(meth)
-
-    def get_globals(self):
-        s = "\n%s = internal global %%std.class {%%std.class* null, uint %i}"
-        s = s % (self.objectname, abs(id(self)))
-        return self.definition + s
-
-    def collect_init_code(self, lblock, l_func):
-        if self.l_base is None:
-            return
-        l_tmp = self.gen.get_local_tmp(None, l_func)
-        i = "%s = getelementptr %%std.class* %s, int 0, uint 0" % \
-            (l_tmp.llvmname(), self.objectname)
-        lblock.instruction(i)
-        lblock.instruction("store %%std.class* %s, %%std.class** %s" %
-                           (self.l_base.objectname, l_tmp.llvmname()))
-
-    def llvmtype(self):
-        return "%std.class* "
-
-    def typed_name(self):
-        #XXXX: Ouch. I get bitten by the fact that
-        #      in LLVM typedef != class object
-        # This will work, as long as class objects are only passed to functions
-        # (as opposed to used in LLVM instructions)
-        return "%%std.class* %s" % self.objectname
-
-    def op_simple_call(self, l_target, args, lblock, l_func):
-        lblock.malloc(l_target, self)
-        l_tmp = self.gen.get_local_tmp(
-            PointerTypeRepr("%std.class*", self.gen), l_func)
-        lblock.getelementptr(l_tmp, l_target, [0, 0])
-        lblock.instruction("store %%std.class* %s, %s" %
-                           (self.objectname, l_tmp.typed_name()))
-        init = None
-        for cls in self.classdef.getmro():
-            if "__init__" in cls.attrs:
-                init = cls.attrs["__init__"].getvalue()
-                break
-        if init is not None:
-            l_init = self.gen.get_repr(init)
-            l_func.dependencies.add(l_init)
-            l_args = [self.gen.get_repr(arg) for arg in args[1:]]
-            self.dependencies.update(l_args)
-            # XXX
-            if isinstance(l_init, VirtualMethodRepr):
-                l_init = l_init.l_funcs[l_init.l_classes.index(self)]
-            lblock.call_void(l_init, [l_target] + l_args)
-
-    def t_op_getattr(self, l_target, args, lblock, l_func):
-        if debug:
-            print "t_op_getattr of ClassRepr called", l_target, args, self.name
-        if not isinstance(args[1], Constant):
-            raise CompileError,"getattr called with non-constant: %s" % args[1]
-        if args[1].value in self.attr_num:
-            l_args0 = self.gen.get_repr(args[0])
-            l_func.dependencies.add(l_args0)
-            l_pter = self.gen.get_local_tmp(
-                PointerTypeRepr(l_target.llvmtype(), self.gen), l_func)
-            lblock.getelementptr(l_pter, l_args0,
-                                 [0, self.attr_num[args[1].value]])
-            lblock.load(l_target, l_pter)
-            return
-        else:
-            if debug:
-                print list(self.classdef.getmro())
-            for cls in self.classdef.getmro():
-                l_cls = self.gen.get_repr(cls)
-                self.dependencies.add(l_cls)
-                if args[1].value in l_cls.methods:
-                    if debug:
-                        print "class %s, %s matches" % (cls, l_cls)
-                    l_args0 = self.gen.get_repr(args[0])
-                    l_func.dependencies.add(l_args0)
-                    l_method = BoundMethodRepr(l_target.type, l_args0, l_cls,
-                                               self.gen)
-                    l_func.dependencies.add(l_method)
-                    l_method.setup()
-                    l_target.type = l_method
-                    return
-        raise CompileError, ("getattr called with unknown attribute %s" % \
-                             args[1].value)
-
-    def t_op_setattr(self, l_target, args, lblock, l_func):
-        if not isinstance(args[1], Constant):
-            raise CompileError,"setattr called with non-constant: %s" % args[1]
-        if args[1].value in self.attr_num:
-            l_args0 = self.gen.get_repr(args[0])
-            l_value = self.gen.get_repr(args[2])
-            self.dependencies.update([l_args0, l_value])
-            l_pter = self.gen.get_local_tmp(
-                PointerTypeRepr(l_value.llvmtype(), self.gen), l_func)
-            lblock.getelementptr(l_pter, l_args0,
-                                 [0, self.attr_num[args[1].value]])
-            lblock.store(l_value, l_pter)
-        else:
-            raise CompileError, ("setattr called with unknown attribute %s" % \
-                                 args[1].value)
-
-    def iter_subclasses(self):
-        for cls, classdef in self.classdef.subdefs.iteritems():
-            l_cls = self.gen.get_repr(classdef)
-            yield l_cls
-            for l_c in l_cls.iter_subclasses():
-                yield l_c
-
-class ExceptionTypeRepr(TypeRepr):
-    def get(obj, gen):
-        try:
-            if isinstance(obj, Constant):
-                if issubclass(obj.value, Exception):
-                    return ExceptionTypeRepr(obj.value, gen)
-                return None
-            elif issubclass(obj, Exception):
-                return ExceptionTypeRepr(obj, gen)
-        except TypeError:
-            pass
-        return None
-    get = staticmethod(get)
-
-    def __init__(self, exception, gen):
-        if debug:
-            print "ExceptionTypeRepr: %s" % exception
-        self.gen = gen
-        self.exception = exception
-        self.name = "%std.exception"
-        self.objectname = gen.get_global_tmp("class.%s.object" %
-                                             self.exception.__name__)
-        s = "%s = internal global %%std.class {%%std.class* null, uint %i}"
-        self.definition = s % (self.objectname, abs(id(exception)))
-        self.dependencies = sets.Set()
-
-    def setup(self):
-        if len(self.exception.__bases__) != 0:
-            self.l_base = self.gen.get_repr(self.exception.__bases__[0])
-            self.dependencies.add(self.l_base)
-        else:
-            self.l_base = None
-
-    def llvmname(self):
-        return "%std.exception* "
-
-    def llvmtype(self):
-        return "%std.class* "
-
-    def typed_name(self):
-        return "%%std.class* %s" % self.objectname
-
-    def collect_init_code(self, lblock, l_func):
-        if self.l_base is None:
-            return
-        l_tmp = self.gen.get_local_tmp(None, l_func)
-        i = "%s = getelementptr %%std.class* %s, int 0, uint 0" % \
-            (l_tmp.llvmname(), self.objectname)
-        lblock.instruction(i)
-        lblock.instruction("store %%std.class* %s, %%std.class** %s" %
-                           (self.l_base.objectname, l_tmp.llvmname()))
-
-class BuiltinFunctionRepr(LLVMRepr):
-    def get(obj, gen):
-        if isinstance(obj, Constant) and \
-           isinstance(gen.annotator.binding(obj), annmodel.SomeBuiltin):
-            return BuiltinFunctionRepr(obj.value.__name__, gen)
-        elif isinstance(obj, annmodel.SomeBuiltin):
-            name = obj.analyser.__name__.replace("method_", "")
-            return BuiltinFunctionRepr(name, gen)
-        return None
-    get = staticmethod(get)
-
-    def __init__(self, name, gen):
-        self.name = "%std." + name
-        self.gen = gen
-
-    def llvmname(self):
-        return self.name
-
-    def op_simple_call(self, l_target, args, lblock, l_func):
-        l_args = [self.gen.get_repr(arg) for arg in args]
-        l_func.dependencies.update(l_args)
-        if self.name == "%std.isinstance":
-            l_tmp = self.gen.get_local_tmp(PointerTypeRepr("%std.object",
-                                                           self.gen), l_func)
-            l_func.dependencies.add(l_tmp)
-            lblock.cast(l_tmp, l_args[1])
-            l_args[1] = l_tmp
-        lblock.call(l_target, l_args[0], l_args[1:])
-
-class FunctionRepr(LLVMRepr):
-    l_functions = {}
-    def get(obj, gen):
-        name = None
-        if isinstance(obj, annmodel.SomePBC) and \
-                 len(obj.prebuiltinstances) == 1:
-            obj = obj.prebuiltinstances.keys()[0]
-        elif isinstance(obj, Constant):
-            obj = obj.value
-        if isinstance(obj, MethodType):
-            name = obj.im_class.__name__ + "." + obj.im_func.__name__
-            obj = obj.im_func
-        if isinstance(obj, FunctionType):
-            if (obj, gen) in FunctionRepr.l_functions:
-                return FunctionRepr.l_functions[(obj, gen)]
-            if name is None:
-                name = obj.__name__
-            l_func = FunctionRepr(gen.get_global_tmp(name), obj, gen)
-            FunctionRepr.l_functions[(obj, gen)] = l_func
-            return l_func
-        return None
-    get = staticmethod(get)
-
-    def __init__(self, name, function, gen):
-        if debug:
-            print "FunctionRepr: %s" % name
-        self.gen = gen
-        self.func = function
-        self.translator = gen.translator
-        self.name = name
-        self.graph = self.translator.getflowgraph(self.func)
-        self.annotator = gen.translator.annotator
-        self.blocknum = {}
-        self.allblocks = []
-        self.pyrex_source = ""
-        self.dependencies = sets.Set()
-        remove_double_links(self.translator, self.graph)
-        self.get_bbs()
-        self.se = False
-
-    def setup(self):
-        if self.se:
-            return
-        self.se = True
-        self.l_args = [self.gen.get_repr(ar)
-                       for ar in self.graph.startblock.inputargs]
-        self.dependencies.update(self.l_args)
-        self.retvalue = self.gen.get_repr(self.graph.returnblock.inputargs[0])
-        self.dependencies.add(self.retvalue)
-        self.build_bbs()
-
-    def get_returntype():
-        return self.rettype.llvmname()
-
-    def get_bbs(self):
-        def visit(node):
-            if isinstance(node, Block) and node not in self.blocknum:
-                self.allblocks.append(node)
-                self.blocknum[node] = len(self.blocknum)
-        traverse(visit, self.graph)
-        self.same_origin_block = [False] * len(self.allblocks)
-
-    def build_bbs(self):
-        checkgraph(self.graph)
-        a = self.annotator
-        for number, pyblock in enumerate(self.allblocks):
-            pyblock = self.allblocks[number]
-            is_tryblock = isinstance(pyblock.exitswitch, Constant) and \
-                          pyblock.exitswitch == last_exception
-            if is_tryblock:
-                regularblock = "block%i" % self.blocknum[self.exits[0].target]
-                exceptblock = "block%i" % self.blocknum[self.exits[1].target]
-                pyblock = llvmbc.TryBasicBlock("block%i" % number,
-                                               regularblock, exceptblock)
-            else:
-                lblock = llvmbc.BasicBlock("block%i" % number)
-            if number == 0:
-                self.llvm_func = llvmbc.Function(self.llvmfuncdef(), lblock)
-            else:
-                self.llvm_func.basic_block(lblock)
-            #Create Phi nodes (but not for the first block)
-            incoming_links = []
-            def visit(node):
-                if isinstance(node, Link) and node.target == pyblock:
-                    incoming_links.append(node)
-            traverse(visit, self.graph)
-            if len(incoming_links) != 0:
-                for i, arg in enumerate(pyblock.inputargs):
-                    l_arg = self.gen.get_repr(arg)
-                    l_values = [self.gen.get_repr(l.args[i])
-                                for l in incoming_links]
-                    for j in range(len(l_values)):
-                        if l_values[j].llvmtype() != l_arg.llvmtype():
-                            try:
-                                l_values[j] = \
-                                        l_values[j].alt_types[l_arg.llvmtype()]
-                            except KeyError:
-                                pass
-                    self.dependencies.add(l_arg)
-                    self.dependencies.update(l_values)
-                    lblock.phi(l_arg, l_values,
-                               ["%%block%i" % self.blocknum[l.prevblock]
-                                for l in incoming_links])
-            #Handle SpaceOperations
-            for op in pyblock.operations:
-                l_target = self.gen.get_repr(op.result)
-                self.dependencies.add(l_target)
-                l_arg0 = self.gen.get_repr(op.args[0])
-                self.dependencies.add(l_arg0)
-                l_op = getattr(l_arg0, "op_" + op.opname, None)
-                if l_op is not None:
-                    l_op(l_target, op.args, lblock, self)
-                #XXX need to find more elegant solution for this special case
-                elif op.opname == "newtuple":
-                    l_target.type.t_op_newtuple(l_target, op.args,
-                                                lblock, self)
-                elif op.opname in INTRINSIC_OPS:
-                    l_args = [self.gen.get_repr(arg) for arg in op.args[1:]]
-                    self.dependencies.update(l_args)
-                    lblock.spaceop(l_target, op.opname, [l_arg0] + l_args)
-                else:
-                        s = "SpaceOperation %s not supported. Target: %s " \
-                            "Args: %s " % (op.opname, l_target, op.args) + \
-                            "Dispatched on: %s" % l_arg0
-                            
-                        raise CompileError, s
-            # XXX: If a variable is passed to another block and has a different
-            # type there, we have to make the cast in this block since the phi
-            # instructions in the next block cannot be preceded by any other
-            # instruction
-            for link in pyblock.exits:
-                for i, arg in enumerate(link.args):
-                    localtype = self.annotator.binding(arg)
-                    targettype = self.annotator.binding(
-                        link.target.inputargs[i])
-                    l_targettype = self.gen.get_repr(targettype)
-                    l_localtype = self.gen.get_repr(localtype)
-                    l_local = self.gen.get_repr(arg)
-                    self.dependencies.update([l_targettype, l_localtype,
-                                              l_local])
-                    if l_targettype.llvmname() != l_localtype.llvmname():
-                        l_tmp = self.gen.get_local_tmp(l_targettype, self)
-                        lblock.cast(l_tmp, l_local)
-                        l_local.alt_types = {l_targettype.llvmname(): l_tmp}
-            #Create branches
-            if pyblock.exitswitch is None:
-                if pyblock == self.graph.returnblock:
-                    l_returnvalue = self.gen.get_repr(pyblock.inputargs[0])
-                    self.dependencies.add(l_returnvalue)
-                    lblock.ret(l_returnvalue)
-                else:
-                    lblock.uncond_branch(
-                        "%%block%i" % self.blocknum[pyblock.exits[0].target])
-            elif isinstance(pyblock.exitswitch, Constant) and \
-                 pyblock.exitswitch.value == last_exception:
-                lblock.uncond_branch(
-                    "%%block%i" % self.blocknum[pyblock.exits[0].target])
-            else:
-                assert isinstance(a.binding(pyblock.exitswitch),
-                                  annmodel.SomeBool)
-                l_switch = self.gen.get_repr(pyblock.exitswitch)
-                self.dependencies.add(l_switch)
-                lblock.cond_branch(
-                    l_switch,
-                    "%%block%i" % self.blocknum[pyblock.exits[1].target],
-                    "%%block%i" % self.blocknum[pyblock.exits[0].target])
-
-    def llvmfuncdef(self):
-        s = "internal %s %s(" % (self.retvalue.llvmtype(), self.name)
-        return s + ", ".join([a.typed_name() for a in self.l_args]) + ")"
-
-    def rettype(self):
-        return self.retvalue.llvmtype()
-
-    def get_functions(self):
-        return str(self.llvm_func)
-
-    def llvmtype(self):
-        assert self.llvmfuncdef().count(self.name) == 1
-        return self.llvmfuncdef().replace(self.name + "(", "(") + "*"
-
-    def op_simple_call(self, l_target, args, lblock, l_func):
-        l_args = [self.gen.get_repr(arg) for arg in args]
-        for i, (l_a1, l_a2) in enumerate(zip(l_args[1:], self.l_args)):
-            if l_a1.llvmtype() != l_a2.llvmtype():
-                l_tmp = self.gen.get_local_tmp(l_a2.type, l_func)
-                lblock.cast(l_tmp, l_a1)
-                l_args[1 + i] = l_tmp
-        l_func.dependencies.update(l_args)
-        lblock.call(l_target, l_args[0], l_args[1:])
-
-class EntryFunctionRepr(LLVMRepr):
-    def get(obj, gen):
-        return None
-    get = staticmethod(get)
-
-    def __init__(self, name, function, gen):
-        self.gen = gen
-        self.function = function
-        self.name = name
-        self.dependencies = sets.Set()
-        self.branch_added = False
-
-    def setup(self):
-        self.l_function = self.gen.get_repr(self.function)
-        self.dependencies.add(self.l_function)
-        lblock = llvmbc.BasicBlock("entry")
-        lblock.instruction("%tmp = load bool* %Initialized.0__")
-        lblock.instruction("br bool %tmp, label %real_entry, label %init")
-        self.llvm_func = llvmbc.Function(self.llvmfuncdef(), lblock)
-        self.init_block = llvmbc.BasicBlock("init")
-        self.init_block.instruction("store bool true, bool* %Initialized.0__")
-        real_entry = llvmbc.BasicBlock("real_entry")
-        l_ret = self.gen.get_local_tmp(self.l_function.retvalue.type, self)
-        self.l_function.op_simple_call(
-            l_ret, [self.function] + self.l_function.l_args, real_entry, self)
-        real_entry.ret(l_ret)
-        self.llvm_func.basic_block(real_entry)
-        self.llvm_func.basic_block(self.init_block)
-        
-    def cfuncdef(self):
-        a = self.l_function.translator.annotator
-        retv = self.l_function.graph.returnblock.inputargs[0]
-        rettype_c = C_SIMPLE_TYPES[a.binding(retv).__class__]
-        args = self.l_function.graph.startblock.inputargs
-        argtypes_c = [C_SIMPLE_TYPES[a.binding(v).__class__] for v in args]
-        fd = "%s %s(%s)" % (rettype_c, self.name[1:],
-                            ", ".join(argtypes_c))
-        return fd
-
-    def llvmfuncdef(self):
-        s = "%s %s(" % (self.l_function.retvalue.llvmtype(), self.name)
-        s += ", ".join([a.typed_name() for a in self.l_function.l_args]) + ")"
-        return s
-
-    def get_pyrex_source(self):
-        name = self.name[1:]
-        args = self.l_function.graph.startblock.inputargs
-        self.pyrex_source = ["cdef extern %s\n" %
-                             (self.cfuncdef())]
-        self.pyrex_source += ["def wrap_%s(" % name]
-        t = []
-        for i, a in enumerate(args):
-            t += ["%s" % a]
-        t = ", ".join(t)
-        self.pyrex_source += t + "):\n\treturn %s(%s)\n\n" % (name, t)
-        self.pyrex_source = "".join(self.pyrex_source)
-        return self.pyrex_source
-
-    def rettype(self):
-        return self.l_function.retvalue.llvmtype()
-
-    def get_functions(self):
-        if not self.branch_added:
-            self.init_block.uncond_branch("%real_entry")
-        return str(self.llvm_func)
-
-    def get_globals(self):
-        return "%Initialized.0__ = internal global bool false"
-
-    def llvmtype(self):
-        assert self.llvmfuncdef().count(self.name) == 1
-        return self.llvmfuncdef().replace(self.name + "(", "(") + "*"
-
-    def op_simple_call(self, l_target, args, lblock, l_func):
-        self.l_function.op_simple_call(l_target, [self.function] + args,
-                                       lblock, l_func)
-
-class VirtualMethodRepr(LLVMRepr):
-    # Really stupid implementation of virtual functions:
-    # Do a switch on the id of the class of the object and cast the object
-    # to the appropriate class
-    # Should be replaced by function pointers
-    def get(obj, gen):
-        if isinstance(obj, annmodel.SomePBC) and \
-                 len(obj.prebuiltinstances) > 1 and \
-                 isinstance(obj.prebuiltinstances.keys()[0], FunctionType):
-            return VirtualMethodRepr(obj.prebuiltinstances, gen)
-        return None
-    get = staticmethod(get)
-
-    def __init__(self, prebuiltinstances, gen):
-        if debug:
-            print "VirtualMethodRepr: %s" % prebuiltinstances
-        self.gen = gen
-        classes = prebuiltinstances.values()
-        self.commonbase = reduce(lambda a, b: a.commonbase(b), classes)
-        self.funcs = prebuiltinstances.keys()
-        self.name = "%" + self.funcs[0].__name__ + ".virtual"
-        self.attribute = self.funcs[0].__name__
-        self.dependencies = sets.Set()
-
-    def setup(self):
-        self.l_commonbase = self.gen.get_repr(self.commonbase)
-        self.l_classes = [self.l_commonbase] + \
-                         list(self.l_commonbase.iter_subclasses())
-        self.dependencies.update(self.l_classes)
-        self.l_funcs = []
-        #find appropriate method for every class
-        for l_cls in self.l_classes:
-            for classdef in l_cls.classdef.getmro():
-                if classdef.cls.__dict__.has_key(self.attribute):
-                    self.l_funcs.append(self.gen.get_repr(
-                        classdef.cls.__dict__[self.attribute]))
-                    break
-            else:
-                raise CompileError, "Couldn't find method %s for %s" % \
-                      (self.attribute, l_cls.classdef.cls)
-        self.dependencies.update(self.l_funcs)
-        self.retvalue = self.l_funcs[0].retvalue
-        self.type_numbers = [id(l_c) for l_c in self.l_classes]
-        self.l_args = [self.gen.get_repr(ar)
-                       for ar in self.l_funcs[0].graph.startblock.inputargs]
-        l_retvalue = self.retvalue
-        self.dependencies.update(self.l_args)
-        #create function
-        #XXX pretty messy
-        entryblock = llvmbc.BasicBlock("entry")
-        l_clp = self.gen.get_local_tmp(PointerTypeRepr("%std.class*",
-                                                       self.gen), self)
-        l_cl = self.gen.get_local_tmp(PointerTypeRepr("%std.class",
-                                                      self.gen), self)
-        l_uip = self.gen.get_local_tmp(PointerTypeRepr("uint", self.gen),
-                                       self)
-        l_ui = self.gen.get_local_tmp(
-            self.gen.get_repr(annmodel.SomeInteger(True, True)), self)
-        self.dependencies.update([l_clp, l_cl, l_uip, l_ui])
-        entryblock.getelementptr(l_clp, self.l_args[0], [0, 0])
-        entryblock.load(l_cl, l_clp)
-        entryblock.getelementptr(l_uip, l_cl, [0, 1])
-        entryblock.load(l_ui, l_uip)
-        entryblock.switch(l_ui, "%" + self.l_commonbase.classdef.cls.__name__,
-                          [(str(abs(id(l_c))), "%" + l_c.classdef.cls.__name__)
-                           for l_c in self.l_classes])
-        lfunc = llvmbc.Function(self.llvmfuncdef(), entryblock)
-        for i, l_cls in enumerate(self.l_classes):
-            lblock = llvmbc.BasicBlock(l_cls.classdef.cls.__name__)
-            lfunc.basic_block(lblock)
-            l_tmp = self.gen.get_local_tmp(l_cls, self)
-            lblock.cast(l_tmp, self.l_args[0])
-            l_tmp_ret = self.gen.get_local_tmp(l_retvalue.type, self)
-            self.l_funcs[i].op_simple_call(
-                l_tmp_ret, [self.l_funcs[i], l_tmp] + 
-                self.l_funcs[0].graph.startblock.inputargs[1:], lblock, self)
-            lblock.ret(l_tmp_ret)
-        self.llvm_func = lfunc
-
-    def op_simple_call(self, l_target, args, lblock, l_func):
-        name = self.name[1:-8]
-        l_args = [self.gen.get_repr(arg) for arg in args]
-        l_func.dependencies.update(l_args)
-        # call the method directly if no subclass of the class of args[1] has
-        # a special version of this method defined
-        for l_cls in l_args[1].type.iter_subclasses():
-            if l_cls.classdef.cls.__dict__.has_key(name):
-                break
-        else:
-            for clsdef in l_args[1].type.classdef.getmro():
-                if clsdef.cls.__dict__.has_key(name):
-                    l_method = self.gen.get_repr(clsdef.cls.__dict__[name])
-                    args[0] = l_method
-                    print l_method.llvmname(), l_method
-                    l_method.op_simple_call(l_target, args, lblock, l_func)
-                    return
-        if l_args[1].llvmtype() != self.l_args[0].llvmtype():
-            l_tmp = self.gen.get_local_tmp(self.l_args[0].type, l_func)
-            l_func.dependencies.add(l_tmp)
-            lblock.cast(l_tmp, l_args[1])
-            l_args[1] = l_tmp
-        lblock.call(l_target, l_args[0], l_args[1:])
-        return
-        
-    def get_functions(self):
-        return str(self.llvm_func)
-
-    def llvmfuncdef(self):
-        s = "internal %s %s(" % (self.l_funcs[0].retvalue.llvmtype(),
-                                 self.name)
-        return s + ", ".join([a.typed_name() for a in self.l_args]) + ")"
-
-    def rettype(self):
-        return self.retvalue.llvmtype()
-
-class BoundMethodRepr(LLVMRepr):
-    def get(obj, gen):
-        return None
-    get = staticmethod(get)
-    def __init__(self, l_func, l_self, l_class, gen):
-        self.gen = gen
-        self.l_func = l_func
-        self.l_self = l_self
-        self.l_class = l_class
-        self.dependencies = sets.Set([l_self, l_class, l_func])
-
-    def t_op_simple_call(self, l_target, args, lblock, l_func):
-        self.l_func.op_simple_call(l_target,
-                                   [self.l_func, self.l_self] + args[1:],
-                                   lblock, l_func)

Added: pypy/dist/pypy/translator/llvm/seqrepr.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/llvm/seqrepr.py	Sun Apr  3 20:23:50 2005
@@ -0,0 +1,117 @@
+import autopath
+import sets
+
+from pypy.objspace.flow.model import Constant
+from pypy.annotation import model as annmodel
+
+from pypy.translator.llvm.representation import debug, LLVMRepr
+from pypy.translator.llvm.typerepr import TypeRepr, IntTypeRepr
+from pypy.translator.llvm.typerepr import PointerTypeRepr
+from pypy.translator.llvm.funcrepr import BoundMethodRepr
+
+
+class ListTypeRepr(TypeRepr):
+    l_listtypes = {}
+    def get(obj, gen):
+        if obj.__class__ is annmodel.SomeList:
+            if (obj.s_item.__class__, gen) in ListTypeRepr.l_listtypes:
+                return ListTypeRepr.l_listtypes[(obj.s_item.__class__, gen)]
+            l_repr = ListTypeRepr(obj, gen)
+            ListTypeRepr.l_listtypes[(obj.s_item.__class__, gen)] = l_repr
+            return l_repr
+        return None
+    get = staticmethod(get)
+
+    def __init__(self, obj, gen):
+        if debug:
+            print "ListTypeRepr: %s, %s" % (obj, obj.s_item)
+        self.gen = gen
+        self.l_itemtype = gen.get_repr(obj.s_item)
+        self.dependencies = sets.Set([self.l_itemtype])
+        itemtype = self.l_itemtype.llvmname()
+        self.name = "%%std.list.%s" % itemtype.strip("%").replace("*", "")
+        self.definition = self.name + " = type {uint, %s*}" % itemtype
+
+    def get_functions(self):
+        f = file(autopath.this_dir + "/list_template.ll", "r")
+        s = f.read()
+        f.close()
+        itemtype = self.l_itemtype.llvmname()
+        s = s.replace("%(item)s", self.l_itemtype.llvmname())
+        s = s.replace("%(name)s", itemtype.strip("%").replace("*", ""))
+        if isinstance(self.l_itemtype, IntTypeRepr):
+            f1 = file(autopath.this_dir + "/int_list.ll", "r")
+            s += f1.read()
+            f1.close()
+        return s
+
+    def t_op_getitem(self, l_target, args, lblock, l_func):
+        l_args = [self.gen.get_repr(arg) for arg in args]
+        l_func.dependencies.update(l_args)
+        lblock.spaceop(l_target, "getitem", l_args)
+
+    def t_op_setitem(self, l_target, args, lblock, l_func):
+        l_args = [self.gen.get_repr(arg) for arg in args]
+        l_func.dependencies.update(l_args)
+        lblock.spaceop(l_target, "setitem", l_args)
+
+    def t_op_delitem(self, l_target, args, lblock, l_func):
+        l_args = [self.gen.get_repr(arg) for arg in args]
+        l_func.dependencies.update(l_args)
+        lblock.spaceop(l_target, "delitem", l_args)
+
+    def t_op_getattr(self, l_target, args, lblock, l_func):
+        if isinstance(args[1], Constant) and \
+               args[1].value in ["append", "reverse", "pop"]:
+            l_args0 = self.gen.get_repr(args[0])
+            l_func.dependencies.add(l_args0)
+            l_method = BoundMethodRepr(l_target.type, l_args0, self, self.gen)
+            l_method.setup()
+            l_target.type = l_method
+        else:
+            raise CompileError, "List method %s not supported." % args[1].value
+
+class TupleTypeRepr(TypeRepr):
+    def get(obj, gen):
+        if isinstance(obj, annmodel.SomeTuple):
+            return TupleTypeRepr(obj, gen)
+        return None
+    get = staticmethod(get)
+
+    def __init__(self, obj, gen):
+        self.gen = gen
+        self.l_itemtypes = [gen.get_repr(l) for l in obj.items]
+        self.name = (("{" + ", ".join(["%s"] * len(self.l_itemtypes)) + "}") %
+                     tuple([l.llvmname() for l in self.l_itemtypes]))
+
+    def get_functions(self):
+        s = ("internal int %%std.len(%s %%t) {\n\tret int %i\n}\n" %
+             (self.llvmname(), len(self.l_itemtypes)))
+        return s
+
+    def t_op_newtuple(self, l_target, args, lblock, l_func):
+        l_args = [self.gen.get_repr(arg) for arg in args]
+        l_func.dependencies.update(l_args)
+        lblock.malloc(l_target, self)
+        l_ptrs = [self.gen.get_local_tmp(\
+            PointerTypeRepr(l.llvmname(),self.gen), l_func)
+                  for l in self.l_itemtypes]
+        l_func.dependencies.update(l_ptrs)
+        for i, l in enumerate(self.l_itemtypes):
+            lblock.getelementptr(l_ptrs[i], l_target, [0, i])
+            lblock.store(l_args[i], l_ptrs[i])
+
+    def t_op_getitem(self, l_target, args, lblock, l_func):
+        if not isinstance(args[1], Constant):
+            raise CompileError, "index for tuple's getitem has to be constant"
+        l_args = [self.gen.get_repr(arg) for arg in args]
+        l_func.dependencies.update(l_args)
+        l_tmp = self.gen.get_local_tmp(PointerTypeRepr(l_target.llvmtype(),
+                                                       self.gen), l_func)
+        cast = getattr(l_args[1], "cast_to_unsigned", None)
+        if cast is not None:
+            l_unsigned = cast(l_args[1], lblock, l_func)
+        else:
+            raise CompileError, "Invalid arguments to getitem"
+        lblock.getelementptr(l_tmp, l_args[0], [0, l_unsigned])
+        lblock.load(l_target, l_tmp)

Modified: pypy/dist/pypy/translator/llvm/test/llvmsnippet.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/test/llvmsnippet.py	(original)
+++ pypy/dist/pypy/translator/llvm/test/llvmsnippet.py	Sun Apr  3 20:23:50 2005
@@ -272,6 +272,7 @@
 def two_exceptions(n):
     lst = range(10)
     try:
+        lst[n] += 1
         lst[n]
     except IndexError:
         return 2

Added: pypy/dist/pypy/translator/llvm/typerepr.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/llvm/typerepr.py	Sun Apr  3 20:23:50 2005
@@ -0,0 +1,177 @@
+import autopath
+import sets
+
+from types import ClassType
+
+from pypy.objspace.flow.model import Variable, Constant
+from pypy.objspace.flow.model import last_exception, last_exc_value
+from pypy.annotation import model as annmodel
+
+from pypy.translator.llvm.representation import debug, LLVMRepr
+from pypy.translator.llvm.representation import LLVM_SIMPLE_TYPES
+
+
+
+class TypeRepr(LLVMRepr):
+    def get(obj, gen):
+        if (isinstance(obj, annmodel.SomePBC) and \
+               obj.prebuiltinstances.keys()[0] is None) or obj is type(None):
+            return TypeRepr("%std.void", "%std.void = type sbyte", "", gen)
+    get = staticmethod(get)
+
+    def __init__(self, llvmname, definition, includefile, gen):
+        if debug:
+            print "TypeRepr: %s, %s" % (llvmname, definition)
+        self.name = llvmname
+        self.definition = definition
+        self.gen = gen
+        self.includefile = includefile
+
+    def get_globals(self):
+        try:
+            return self.definition
+        except AttributeError:
+            return ""
+
+    def get_functions(self):
+        try:
+            if self.includefile != "":
+                f = file(autopath.this_dir + "/" + self.includefile, "r")
+                s = f.read()
+                f.close()
+                return s
+        except AttributeError:
+            pass
+        return ""
+
+    def llvmname(self):
+        return self.name + "*"
+
+    def llvmname_wo_pointer(self):
+        return self.name
+
+class StringTypeRepr(TypeRepr):
+    def get(obj, gen):
+        if obj.__class__ is annmodel.SomeString or obj is str:
+            return StringTypeRepr(gen)
+    get = staticmethod(get)
+
+    def __init__(self, gen):
+        if debug:
+            print "StringTypeRepr"
+        self.gen = gen
+        self.dependencies = sets.Set()
+
+    def setup(self):
+        self.l_charlist = self.gen.get_repr(
+            annmodel.SomeList(None, annmodel.SomeChar()))
+        self.dependencies.add(self.l_charlist)
+        self.name = self.l_charlist.llvmname_wo_pointer()
+
+    def t_op_getitem(self, l_target, args, lblock, l_func):
+        l_args = [self.gen.get_repr(arg) for arg in args]
+        l_func.dependencies.update(l_args)
+        lblock.spaceop(l_target, "getitem", l_args)
+
+    def t_op_inplace_add(self, l_target, args, lblock, l_func):
+        l_args = [self.gen.get_repr(arg) for arg in args]
+        l_func.dependencies.update(l_args)
+        lblock.spaceop(l_target, "add", l_args)
+
+
+class IntTypeRepr(TypeRepr):
+    def get(obj, gen):
+        if obj.__class__ is annmodel.SomeInteger:
+            return IntTypeRepr(obj, gen)
+        return None
+    get = staticmethod(get)
+
+    def __init__(self, annotation, gen):
+        if debug:
+            print "IntTypeRepr: %s" % annotation
+        self.annotation = annotation
+        if annotation.unsigned:
+            self.name = "uint"
+        else:
+            self.name = "int"
+        self.gen = gen
+
+    def llvmname(self):
+        return self.name
+
+    def cast_to_signed(self, l_val, lblock, l_function):
+        if not self.annotation.unsigned:
+            return l_val
+        ann = annmodel.SomeInteger()
+        l_type = self.gen.get_repr(ann)
+        l_tmp = self.gen.get_local_tmp(l_type, l_function)
+        l_function.dependencies.update([l_type, l_tmp])
+        lblock.cast(l_tmp, l_val, l_type)
+        return l_tmp
+
+    def cast_to_unsigned(self, l_val, lblock, l_function):
+        if self.annotation.unsigned:
+            return l_val
+        ann = annmodel.SomeInteger(True, True)
+        l_type = self.gen.get_repr(ann)
+        l_tmp = self.gen.get_local_tmp(l_type, l_function)
+        l_function.dependencies.update([l_type, l_tmp])
+        lblock.cast(l_tmp, l_val, l_type)
+        return l_tmp
+
+
+class SimpleTypeRepr(TypeRepr):
+    def get(obj, gen):
+        if obj.__class__ is annmodel.SomeInteger:
+            l_repr = SimpleTypeRepr("int", gen)
+            return l_repr
+        elif obj.__class__ is annmodel.SomeBool:
+            l_repr = SimpleTypeRepr("bool", gen)
+            return l_repr
+        elif obj.__class__ is annmodel.SomeChar:
+            l_repr = SimpleTypeRepr("sbyte", gen)
+            return l_repr
+        elif obj.__class__ is annmodel.SomePBC:
+            if obj.knowntype == object or obj.knowntype == ClassType:
+                return SimpleTypeRepr("%std.class", gen)
+        return None
+    get = staticmethod(get)
+
+    def __init__(self, llvmname, gen):
+        if debug:
+            print "SimpleTypeRepr: %s" % llvmname
+        self.name = llvmname
+        self.gen = gen
+        self.definition = ""
+        self.includefile = ""
+
+    def llvmname(self):
+        return self.name
+
+class PointerTypeRepr(TypeRepr):
+    def get(obj, gen):
+        return None
+    get = staticmethod(get)
+
+    def __init__(self, type, gen):
+        self.type = type
+
+    def llvmname(self):
+        return self.type + "*"
+
+class ImpossibleValueRepr(TypeRepr):
+    def get(obj, gen):
+        if obj.__class__ is annmodel.SomeImpossibleValue:
+            return ImpossibleValueRepr()
+        return None
+    get = staticmethod(get)
+    
+    def __init__(self):
+        self.definition = ""
+        self.dependencies = sets.Set()
+        self.includefile = ""
+
+    def llvmname(self):
+        return "void"
+
+



More information about the Pypy-commit mailing list