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

arigo at codespeak.net arigo at codespeak.net
Thu Dec 20 19:50:20 CET 2007


Author: arigo
Date: Thu Dec 20 19:50:20 2007
New Revision: 49966

Modified:
   pypy/dist/pypy/translator/llvm/arraynode.py
   pypy/dist/pypy/translator/llvm/codewriter.py
   pypy/dist/pypy/translator/llvm/database.py
   pypy/dist/pypy/translator/llvm/gc.py
   pypy/dist/pypy/translator/llvm/opwriter.py
   pypy/dist/pypy/translator/llvm/structnode.py
   pypy/dist/pypy/translator/llvm/test/test_symbolic.py
   pypy/dist/pypy/translator/llvm/typedefnode.py
Log:
A lot of efforts to insert the GC header fields in front of the
corresponding structures.  This is a mess because we have to
change all the 'getelementptr', which needs field indices.


Modified: pypy/dist/pypy/translator/llvm/arraynode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/arraynode.py	(original)
+++ pypy/dist/pypy/translator/llvm/arraynode.py	Thu Dec 20 19:50:20 2007
@@ -35,6 +35,8 @@
         self.make_name(name)
 
     def setup(self):
+        for value in self.db.gcpolicy.gcheader_initdata(self.value):
+            self.db.prepare_constant(lltype.typeOf(value), value)
         for item in self.value.items:
             self.db.prepare_constant(self.arraytype, item)
 
@@ -60,22 +62,24 @@
 
     def get_typerepr(self):
         arraylen = self.get_arrayvalue()[0]
-        typeval = self.db.repr_type(self.arraytype)
-        return "{ %s, [%s x %s] }" % (self.db.get_machine_word(),
-                                      arraylen, typeval)
+        typedefnode = self.db.obj2node[lltype.typeOf(self.value)]
+        return typedefnode.get_typerepr(arraylen)
     
     def constantvalue(self):
         physicallen, arrayrepr = self.get_arrayvalue()
         typeval = self.db.repr_type(self.arraytype)
 
         # first length is logical, second is physical
-        value = "%s %s, [%s x %s]\n\t%s" % (self.db.get_machine_word(),
+        result = ""
+        for value in self.db.gcpolicy.gcheader_initdata(self.value):
+            result += "%s, " % (self.db.repr_constant(value)[1],)
+        result += "%s %s, [%s x %s]\n\t%s" % (self.db.get_machine_word(),
                                             self.get_length(),
                                             physicallen,
                                             typeval,
                                             arrayrepr)
 
-        return "%s {%s}" % (self.get_typerepr(), value)
+        return "%s {%s}" % (self.get_typerepr(), result)
 
 class ArrayNoLengthNode(ArrayNode):
     def get_typerepr(self):
@@ -85,7 +89,6 @@
 
     def constantvalue(self):
         physicallen, arrayrepr = self.get_arrayvalue()
-        typeval = self.db.repr_type(self.arraytype)
         s = "%s %s" % (self.get_typerepr(), arrayrepr)
         return s
 
@@ -113,6 +116,9 @@
         r = 'c"%s"' % "".join(s)
         return item_length, r
 
+class StrArrayNoLengthNode(StrArrayNode, ArrayNoLengthNode):
+    pass
+
 class VoidArrayNode(ConstantNode):
     __slots__ = "db value".split()
     prefix = '@voidarrayinstance'
@@ -124,10 +130,23 @@
         name = '' #str(value).split()[1]
         self.make_name(name)
 
+    def setup(self):
+        for value in self.db.gcpolicy.gcheader_initdata(self.value):
+            self.db.prepare_constant(lltype.typeOf(value), value)
+
     def get_typerepr(self):
-        return '[%s x i8]' % self.get_length()
+        typedefnode = self.db.obj2node[lltype.typeOf(self.value)]
+        return typedefnode.get_typerepr()
+
+    def get_length(self):
+        """ returns logical length of array """
+        items = self.value.items
+        return len(items)
 
     def constantvalue(self):
-        return "{ %s } {%s %s}" % (self.db.get_machine_word(),
-                                   self.db.get_machine_word(),
-                                   len(self.value.items))
+        result = ""
+        for value in self.db.gcpolicy.gcheader_initdata(self.value):
+            result += "%s %s, " % self.db.repr_constant(value)
+        result += "%s %s" % (self.db.get_machine_word(),
+                             self.get_length())
+        return "%s { %s }" % (self.get_typerepr(), result)

Modified: pypy/dist/pypy/translator/llvm/codewriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/codewriter.py	(original)
+++ pypy/dist/pypy/translator/llvm/codewriter.py	Thu Dec 20 19:50:20 2007
@@ -46,6 +46,7 @@
         self._append("    %s:" % name)
 
     def globalinstance(self, name, typeandata, linkage=None):
+        assert not typeandata.startswith('i8')
         if linkage is None:
             linkage = self.linkage
         self._append("%s = %sglobal %s" % (name, linkage, typeandata))

Modified: pypy/dist/pypy/translator/llvm/database.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/database.py	(original)
+++ pypy/dist/pypy/translator/llvm/database.py	Thu Dec 20 19:50:20 2007
@@ -3,14 +3,15 @@
 from pypy.translator.llvm.log import log 
 
 from pypy.translator.llvm.typedefnode import create_typedef_node
+from pypy.translator.llvm.typedefnode import getindexhelper
 
 from pypy.translator.llvm.funcnode import FuncImplNode
 from pypy.translator.llvm.extfuncnode import ExternalFuncNode
 from pypy.translator.llvm.opaquenode import OpaqueNode, ExtOpaqueNode
 from pypy.translator.llvm.structnode import StructNode, StructVarsizeNode, \
-     getindexhelper,  FixedSizeArrayNode
+     FixedSizeArrayNode
 from pypy.translator.llvm.arraynode import ArrayNode, StrArrayNode, \
-     VoidArrayNode, ArrayNoLengthNode, DebugStrNode
+     VoidArrayNode, ArrayNoLengthNode, StrArrayNoLengthNode, DebugStrNode
      
 from pypy.rpython.lltypesystem import lltype, llmemory, llarena, rffi
 from pypy.objspace.flow.model import Constant, Variable
@@ -95,7 +96,10 @@
                     
         elif isinstance(type_, lltype.Array):
             if type_.OF is lltype.Char:
-                node = StrArrayNode(self, value)
+                if type_._hints.get("nolength", False):
+                    node = StrArrayNoLengthNode(self, value)
+                else:
+                    node = StrArrayNode(self, value)
             elif type_.OF is lltype.Void:
                 node = VoidArrayNode(self, value)
             else:
@@ -240,35 +244,11 @@
         indices = [("i32", 0)]
 
         for _, ii in children:
-            name = None
-
-            # this is because FixedSizeArray can sometimes be accessed like an
-            # Array and then sometimes a Struct
+            typedefnode = self.obj2node[TYPE]
             if isinstance(ii, str):
-                name = ii
-                assert name in list(TYPE._names)
-                fieldnames = TYPE._names_without_voids()
-                indexref = fieldnames.index(name)
-            else:
-                indexref = ii
-
-            if isinstance(TYPE, lltype.FixedSizeArray):
-                indices.append(("i32", indexref))
-                TYPE = TYPE.OF
-
-            elif isinstance(TYPE, lltype.Array):
-                if not TYPE._hints.get("nolength", False):
-                    indices.append(("i32", 1))
-                indices.append(("i32", indexref))
-                TYPE = TYPE.OF
-
-            elif isinstance(TYPE, lltype.Struct):
-                assert name is not None
-                TYPE = getattr(TYPE, name)
-                indices.append(("i32", indexref))
-
+                TYPE = typedefnode.fieldname_to_getelementptr(indices, ii)
             else:
-                raise Exception("unsupported type: %s" % TYPE)
+                TYPE = typedefnode.indexref_to_getelementptr(indices, ii)
 
         indices_str = ', '.join ([('%s %s' % (x,y)) for x, y in indices])
         ref = "getelementptr(%s* %s, %s)" % (
@@ -604,19 +584,6 @@
 
         from_, indices, to = self.get_offset(value, [])
 
-        # void array special cases
-        if isinstance(from_, lltype.Array) and from_.OF is lltype.Void:
-            assert not isinstance(value, (llmemory.FieldOffset, llmemory.ItemOffset))
-            if isinstance(value, llmemory.ArrayLengthOffset):
-                pass # ok cases!
-            elif isinstance(value, llmemory.ArrayItemsOffset):
-                to = from_
-                indices = [(self.database.get_machine_word(), 1)]
-            else:
-                s = value.offsets[0]
-                isinstance(value, llmemory.CompositeOffset) 
-                return self.repr_offset(s)
-
         if from_ is lltype.Void:
             assert isinstance(value, llmemory.ItemOffset)
             return "0"
@@ -649,7 +616,7 @@
 
             # jumps to a field position in a struct
             from_ = value.TYPE
-            pos = getindexhelper(value.fldname, value.TYPE)
+            pos = getindexhelper(self.database, value.fldname, value.TYPE)
             indices.append((word, pos))
             to = getattr(value.TYPE, value.fldname)            
 
@@ -662,7 +629,9 @@
             # jumps to the place where the array length is stored
             from_ = value.TYPE     # <Array of T> or <GcArray of T>
             assert isinstance(value.TYPE, lltype.Array)
-            indices.append((word, 0))
+            typedefnode = self.database.obj2node[value.TYPE]
+            indexref = typedefnode.indexref_for_length()
+            indices.append((word, indexref))
             to = lltype.Signed
 
         elif isinstance(value, llmemory.ArrayItemsOffset):
@@ -671,11 +640,19 @@
                     pass
                 else:
                     indices.append((word, 0))
-                    
+
+            if value.TYPE.OF is lltype.Void:
+                # skip over the whole structure in order to get to the
+                # (not-really-existent) array part
+                return self.get_offset(llmemory.ItemOffset(value.TYPE),
+                                       indices)
+
             # jumps to the beginning of array area
             from_ = value.TYPE
             if not isinstance(value.TYPE, lltype.FixedSizeArray) and not value.TYPE._hints.get("nolength", False):
-                indices.append((word, 1))
+                typedefnode = self.database.obj2node[value.TYPE]
+                indexref = typedefnode.indexref_for_items()
+                indices.append((word, indexref))
                 indices.append((word, 0)) # go to the 1st item
             if isinstance(value.TYPE, lltype.FixedSizeArray):
                 indices.append((word, 0)) # go to the 1st item
@@ -685,7 +662,9 @@
         elif isinstance(value, llmemory.CompositeOffset):
             from_, indices, to = self.get_offset(value.offsets[0], indices)
             for item in value.offsets[1:]:
-                _, indices, to = self.get_offset(item, indices)
+                _, indices, to1 = self.get_offset(item, indices)
+                if to1 is not lltype.Void:
+                    to = to1
 
         else:
             raise Exception("unsupported offset")

Modified: pypy/dist/pypy/translator/llvm/gc.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/gc.py	(original)
+++ pypy/dist/pypy/translator/llvm/gc.py	Thu Dec 20 19:50:20 2007
@@ -1,5 +1,6 @@
 import sys
 from pypy.rpython.lltypesystem.rstr import STR
+from pypy.rpython.lltypesystem import lltype
 from pypy.translator.c import gc
 
 from pypy.translator.llvm.log import log
@@ -17,10 +18,16 @@
     
     def genextern_code(self):
         return ''
+
+    def gcheader_definition(self, TYPE):
+        return []
+
+    def gcheader_initdata(self, container):
+        return []
     
     def gc_libraries(self):
         return []
-    
+
     def get_count(self, inc=False):
         if inc:
             self.n_malloced = self.n_malloced + 1
@@ -158,9 +165,33 @@
         r += '#define __GC_SETUP_CODE__\n'
         return r
 
+    def gcheader_definition(self, TYPE):
+        if needs_gcheader(TYPE):
+            return self.db.gctransformer.gc_fields()
+        else:
+            return []
+
+    def gcheader_initdata(self, container):
+        if needs_gcheader(container._TYPE):
+            o = lltype.top_container(container)
+            return self.db.gctransformer.gc_field_values_for(o)
+        else:
+            return []
+
     def gc_libraries(self):
         return ['pthread']
 
     def get_real_weakref_type(self):
         from pypy.rpython.memory.gctransform import framework
         return framework.WEAKREF
+
+
+def needs_gcheader(T):
+    if not isinstance(T, lltype.ContainerType):
+        return False
+    if T._gckind != 'gc':
+        return False
+    if isinstance(T, lltype.GcStruct):
+        if T._first_struct() != (None, None):
+            return False   # gcheader already in the first field
+    return True

Modified: pypy/dist/pypy/translator/llvm/opwriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/opwriter.py	(original)
+++ pypy/dist/pypy/translator/llvm/opwriter.py	Thu Dec 20 19:50:20 2007
@@ -104,7 +104,9 @@
             if not ARRAYTYPE._hints.get("nolength", False):
                 # skip the length field
                 indices.append((self.word, 0))
-                indices.append((self.word, 1))
+                typedefnode = self.db.obj2node[ARRAYTYPE]
+                indexref = typedefnode.indexref_for_items()
+                indices.append((self.word, indexref))
         else:
             assert isinstance(ARRAYTYPE, lltype.FixedSizeArray)
             indices.append((self.word, 0))
@@ -326,34 +328,15 @@
         else:
             indices = [("i32", 0)]
         for arg in args:
-            name = None
-            # this is because FixedSizeArray can sometimes be accessed like an
-            # Array and then sometimes a Struct
+            typedefnode = self.db.obj2node[TYPE]
             if arg.concretetype is lltype.Void:
+                # access via a field name
                 name = arg.value
-                assert name in list(TYPE._names)
-                fieldnames = TYPE._names_without_voids()
-                indexref = fieldnames.index(name)
+                TYPE = typedefnode.fieldname_to_getelementptr(indices, name)
             else:
+                # access via an array index
                 indexref = self.db.repr_arg(arg)
-
-            if isinstance(TYPE, lltype.FixedSizeArray):
-                indices.append(("i32", indexref))
-                TYPE = TYPE.OF
-
-            elif isinstance(TYPE, lltype.Array):
-                if not TYPE._hints.get("nolength", False):
-                    indices.append(("i32", 1))
-                indices.append(("i32", indexref))
-                TYPE = TYPE.OF
-
-            elif isinstance(TYPE, lltype.Struct):
-                assert name is not None
-                TYPE = getattr(TYPE, name)
-                indices.append(("i32", indexref))
-
-            else:
-                raise Exception("unsupported type: %s" % TYPE)
+                TYPE = typedefnode.indexref_to_getelementptr(indices, indexref)
 
         return TYPE, indices
 
@@ -405,7 +388,9 @@
         if isinstance(TYPE, lltype.Array):
             assert not TYPE._hints.get("nolength", False) 
             # gets the length
-            indices.append(("i32", 0))
+            typedefnode = self.db.obj2node[TYPE]
+            indexref = typedefnode.indexref_for_length()
+            indices.append(("i32", indexref))
             lengthref = self._tmp()
             self.codewriter.getelementptr(lengthref, opr.argtypes[0], opr.argrefs[0], indices, getptr=False)
         else:
@@ -417,11 +402,12 @@
     getarraysize = getinteriorarraysize
 
     def direct_fieldptr(self, opr):        
-        from pypy.translator.llvm.structnode import getindexhelper
+        from pypy.translator.llvm.typedefnode import getindexhelper
         
         op = opr.op
         assert opr.rettype != "void"
-        index = getindexhelper(op.args[1].value,
+        index = getindexhelper(self.db,
+                               op.args[1].value,
                                op.args[0].concretetype.TO)
         assert index != -1
         tmpvar = self._tmp()

Modified: pypy/dist/pypy/translator/llvm/structnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/structnode.py	(original)
+++ pypy/dist/pypy/translator/llvm/structnode.py	Thu Dec 20 19:50:20 2007
@@ -1,16 +1,7 @@
 from pypy.translator.llvm.node import ConstantNode
+from pypy.translator.llvm.gc import needs_gcheader
 from pypy.rpython.lltypesystem import lltype
 
-def getindexhelper(name, struct):
-    assert name in list(struct._names)
-
-    fieldnames = struct._names_without_voids()
-    try:
-        index = fieldnames.index(name)
-    except ValueError:
-        index = -1
-    return index
-        
 class StructNode(ConstantNode):
     __slots__ = "db value structtype _get_types".split()
 
@@ -26,21 +17,24 @@
         self.make_name(name)
 
     def _compute_types(self):
-        return [(name, self.structtype._flds[name])
-                for name in self.structtype._names_without_voids()]
+        result = list(self.db.gcpolicy.gcheader_definition(self.structtype))
+        for name in self.structtype._names_without_voids():
+            result.append((name, self.structtype._flds[name]))
+        return result
 
     def _getvalues(self):
-        values = []
-        for name, T in self._get_types:
-            value = getattr(self.value, name)
-            values.append(self.db.repr_constant(value)[1])
+        values = list(self.db.gcpolicy.gcheader_initdata(self.value))
+        for name in self.structtype._names_without_voids():
+            values.append(getattr(self.value, name))
         return values
-    
+
+    def _getvaluesrepr(self):
+        values = self._getvalues()
+        return [self.db.repr_constant(value)[1] for value in values]
+
     def setup(self):
-        for name, T in self._get_types:
-            assert T is not lltype.Void
-            value = getattr(self.value, name)
-            self.db.prepare_constant(T, value)
+        for value in self._getvalues():
+            self.db.prepare_constant(lltype.typeOf(value), value)
 
         p, c = lltype.parentlink(self.value)
         if p is not None:
@@ -51,7 +45,7 @@
     
     def constantvalue(self):
         """ Returns the constant representation for this node. """
-        values = self._getvalues()
+        values = self._getvaluesrepr()
         if len(values) > 3:
             all_values = ",\n\t".join(values)
             return "%s {\n\t%s }" % (self.get_typerepr(), all_values)
@@ -69,7 +63,7 @@
 
     def constantvalue(self):
         """ Returns the constant representation for this node. """
-        values = self._getvalues()
+        values = self._getvaluesrepr()
         all_values = ",\n  ".join(values)
         return "%s [\n  %s\n  ]\n" % (self.get_typerepr(), all_values)
 
@@ -84,14 +78,6 @@
 class StructVarsizeNode(StructNode):
     prefix = '@sv_inst_'
 
-    def _getvalues(self):
-        values = []
-        for name, T in self._get_types[:-1]:
-            value = getattr(self.value, name)
-            values.append(self.db.repr_constant(value)[1])
-        values.append(self._get_lastnoderepr())
-        return values
-
     def _get_lastnode_helper(self):
         lastname, LASTT = self._get_types[-1]
         assert isinstance(LASTT, lltype.Array) or (
@@ -102,16 +88,13 @@
     def _get_lastnode(self):
         return self._get_lastnode_helper()[0]
 
-    def _get_lastnoderepr(self):
-        return self._get_lastnode_helper()[1]
-
     def setup(self):
         super(StructVarsizeNode, self).setup()
     
     def get_typerepr(self):
         try:
             return self._get_typerepr_cache
-        except:
+        except AttributeError:
             # last type is a special case and need to be worked out recursively
             types = self._get_types[:-1]
             types_repr = [self.db.repr_type(T) for name, T in types]

Modified: pypy/dist/pypy/translator/llvm/test/test_symbolic.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/test/test_symbolic.py	(original)
+++ pypy/dist/pypy/translator/llvm/test/test_symbolic.py	Thu Dec 20 19:50:20 2007
@@ -167,7 +167,6 @@
 def test_itemoffset_void():
     A = lltype.GcArray(lltype.Void)
     s = llmemory.sizeof(A, 1)
-    s += llmemory.sizeof(lltype.Signed)
     def f():
         return s
     fn = compile_function(f, [])

Modified: pypy/dist/pypy/translator/llvm/typedefnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/typedefnode.py	(original)
+++ pypy/dist/pypy/translator/llvm/typedefnode.py	Thu Dec 20 19:50:20 2007
@@ -1,6 +1,18 @@
 from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.translator.llvm.node import Node
 
+def getindexhelper(db, name, struct):
+    assert name in list(struct._names)
+
+    fieldnames = struct._names_without_voids()
+    try:
+        index = fieldnames.index(name)
+    except ValueError:
+        index = -1
+    else:
+        index += len(db.gcpolicy.gcheader_definition(struct))
+    return index
+
 class TypeDefNode(Node):
     __slots__ = "".split()
     
@@ -30,15 +42,38 @@
         
     def setup(self):
         self.db.prepare_type(self.ARRAY.OF)
+        for name, F in self.db.gcpolicy.gcheader_definition(self.ARRAY):
+            self.db.prepare_type(F)
 
-    def writetypedef(self, codewriter):
+    def get_typerepr(self, arraylen=0):
+        gchdr = self.db.gcpolicy.gcheader_definition(self.ARRAY)
         if self.ARRAY._hints.get("nolength", False):
-            codewriter.typedef(self.ref, 
-                               "%s" % self.db.repr_type(self.ARRAY.OF))
+            assert len(gchdr) == 0
+            return "%s" % self.db.repr_type(self.ARRAY.OF)
         else:
-            codewriter.typedef(self.ref, 
-                               "{ %s, [0 x %s] }" % (self.db.get_machine_word(),
-                                                     self.db.repr_type(self.ARRAY.OF)))
+            fields = [self.db.repr_type(F) for name, F in gchdr]
+            fields.append(self.db.get_machine_word())
+            fields.append("[%d x %s]" % (arraylen,
+                                         self.db.repr_type(self.ARRAY.OF),))
+            return "{ %s }" % ", ".join(fields)
+
+    def writetypedef(self, codewriter):
+        codewriter.typedef(self.ref, self.get_typerepr())
+
+    def indexref_to_getelementptr(self, indices, indexref):
+        TYPE = self.ARRAY
+        if not TYPE._hints.get("nolength", False):
+            indices.append(("i32", self.indexref_for_items()))
+        indices.append(("i32", indexref))
+        return TYPE.OF
+
+    def indexref_for_length(self):
+        gchdr = self.db.gcpolicy.gcheader_definition(self.ARRAY)
+        return len(gchdr) + 0
+
+    def indexref_for_items(self):
+        gchdr = self.db.gcpolicy.gcheader_definition(self.ARRAY)
+        return len(gchdr) + 1
 
 class VoidArrayTypeNode(TypeDefNode):
     " void arrays dont have any real elements "
@@ -53,8 +88,23 @@
         self.ARRAY = ARRAY
         self.make_name()
 
+    def setup(self):
+        for name, F in self.db.gcpolicy.gcheader_definition(self.ARRAY):
+            self.db.prepare_type(F)
+
+    def get_typerepr(self, arraylen=0):
+        assert not self.ARRAY._hints.get("nolength", False), "XXX"
+        gchdr = self.db.gcpolicy.gcheader_definition(self.ARRAY)
+        fields = [self.db.repr_type(F) for name, F in gchdr]
+        fields.append(self.db.get_machine_word())
+        return "{ %s }" % ", ".join(fields)
+
     def writetypedef(self, codewriter):
-        codewriter.typedef(self.ref, "{ %s }" % self.db.get_machine_word())
+        codewriter.typedef(self.ref, self.get_typerepr())
+
+    def indexref_for_length(self):
+        gchdr = self.db.gcpolicy.gcheader_definition(self.ARRAY)
+        return len(gchdr) + 0
 
 class StructTypeNode(TypeDefNode):
     __slots__ = "db STRUCT".split()
@@ -69,9 +119,13 @@
         self.make_name(name)
 
     def _fields(self):
-        return [getattr(self.STRUCT, name) 
-                for name in self.STRUCT._names_without_voids()]
-    
+        types = []
+        for name, T in self.db.gcpolicy.gcheader_definition(self.STRUCT):
+            types.append(T)
+        for name in self.STRUCT._names_without_voids():
+            types.append(getattr(self.STRUCT, name))
+        return types
+
     def setup(self):
         for F in self._fields():
             self.db.prepare_type(F)
@@ -81,10 +135,17 @@
         codewriter.typedef(self.ref, 
                            "{ %s }" % ", ".join(fields_types))
 
+    def fieldname_to_getelementptr(self, indices, name):
+        TYPE = self.STRUCT
+        indexref = getindexhelper(self.db, name, TYPE)
+        indices.append(("i32", indexref))
+        return getattr(TYPE, name)
+
 class FixedSizeArrayTypeNode(StructTypeNode):
     prefix = '%fixarray_'
 
     def setup(self):
+        assert self.STRUCT._gckind != 'gc'
         FIELDS = self._fields()
         if FIELDS:
             self.db.prepare_type(FIELDS[0])
@@ -94,6 +155,12 @@
                            "[%s x %s]" % (self.STRUCT.length, 
                                           self.db.repr_type(self.STRUCT.OF)))
 
+    def indexref_to_getelementptr(self, indices, indexref):
+        TYPE = self.STRUCT
+        assert TYPE._gckind != 'gc'
+        indices.append(("i32", indexref))
+        return TYPE.OF
+
 class FuncTypeNode(TypeDefNode):
     __slots__ = "db T".split()
     prefix = '%functiontype'



More information about the Pypy-commit mailing list