[pypy-svn] r12180 - in pypy/dist/pypy/translator/genc: . test
arigo at codespeak.net
arigo at codespeak.net
Wed May 11 16:16:08 CEST 2005
Author: arigo
Date: Wed May 11 16:16:08 2005
New Revision: 12180
Added:
pypy/dist/pypy/translator/genc/ll_include.h (contents, props changed)
pypy/dist/pypy/translator/genc/lltype.py (contents, props changed)
pypy/dist/pypy/translator/genc/test/test_lltyped.py (contents, props changed)
Modified:
pypy/dist/pypy/translator/genc/ctyper.py
pypy/dist/pypy/translator/genc/g_include.h
pypy/dist/pypy/translator/genc/genc.py
pypy/dist/pypy/translator/genc/inttype.py
Log:
Hackish draft of support of the LowLevelTypes in GenC. Very partial and
without memory management. It is also very much indirect because it plugs in
the existing CTyper, which was meant to support a much more indirect,
C-template-based approach than actually needed now.
Modified: pypy/dist/pypy/translator/genc/ctyper.py
==============================================================================
--- pypy/dist/pypy/translator/genc/ctyper.py (original)
+++ pypy/dist/pypy/translator/genc/ctyper.py Wed May 11 16:16:08 2005
@@ -6,6 +6,7 @@
from pypy.translator.typer import Specializer
from pypy.objspace.flow.model import Constant, Variable, SpaceOperation
from pypy.annotation.model import SomeInteger, SomePBC, SomeTuple, SomeList
+from pypy.annotation.model import SomePtr
from pypy.translator.genc.pyobjtype import CPyObjectType
from pypy.translator.genc.inttype import CIntType
from pypy.translator.genc.nonetype import CNoneType
@@ -14,6 +15,8 @@
from pypy.translator.genc.listtype import CListType
from pypy.translator.genc.classtype import CClassPtrType
from pypy.translator.genc.instancetype import CInstanceType
+from pypy.translator.genc.lltype import CPtrType, CLiteralTypeName
+from pypy.rpython import lltypes
import types
from pypy.interpreter.pycode import CO_VARARGS
@@ -110,12 +113,28 @@
# besttype = self.annotator.translator.getconcretetype(
# CListType, item_ct)
+ elif isinstance(s_value, SomePtr):
+ besttype = self.annotator.translator.getconcretetype(
+ CPtrType, s_value.ll_ptrtype)
+
return besttype
def specialized_op(self, op, bindings):
if op.opname in ('newtuple', 'newlist'):
# operations that are controlled by their return type
s_binding = self.annotator.binding(op.result, True)
+ elif op.opname == 'simple_call' and isinstance(op.args[0], Constant):
+ # XXX move me elsewhere
+ func = op.args[0].value
+ if func is lltypes.malloc:
+ assert len(op.args) == 2 # for now
+ s_result = self.annotator.binding(op.result)
+ ct = self.annotator.translator.getconcretetype(CLiteralTypeName)
+ return [
+ self.typed_op(SpaceOperation('malloc', [op.args[1]],
+ op.result),
+ [ct], self.annotation2concretetype(s_result))
+ ]
elif bindings:
# operations are by default controlled by their 1st arg
s_binding = bindings[0]
Modified: pypy/dist/pypy/translator/genc/g_include.h
==============================================================================
--- pypy/dist/pypy/translator/genc/g_include.h (original)
+++ pypy/dist/pypy/translator/genc/g_include.h Wed May 11 16:16:08 2005
@@ -20,3 +20,4 @@
#include "none_include.h"
#include "pyobj_include.h"
#include "tuple_include.h"
+#include "ll_include.h"
Modified: pypy/dist/pypy/translator/genc/genc.py
==============================================================================
--- pypy/dist/pypy/translator/genc/genc.py (original)
+++ pypy/dist/pypy/translator/genc/genc.py Wed May 11 16:16:08 2005
@@ -125,14 +125,20 @@
# the footer proper: the module init function */
print >> f, self.C_FOOTER % info
+ def need_typedecl_now(self, ct):
+ if ct not in self.ctypes_alreadyseen:
+ self.ctypes_alreadyseen[ct] = True
+ return ct.init_globals(self)
+ else:
+ return []
+
def gen_global_declarations(self):
# collect more of the latercode between the functions,
# and produce the corresponding global declarations
insert_first = []
for ct in self.translator.ctlist:
if ct not in self.ctypes_alreadyseen:
- insert_first += list(ct.init_globals(self))
- self.ctypes_alreadyseen[ct] = True
+ insert_first += list(self.need_typedecl_now(ct))
self.globaldecl[:0] = insert_first
for ct in self.translator.ctlist:
self.globaldecl += list(ct.collect_globals(self))
Modified: pypy/dist/pypy/translator/genc/inttype.py
==============================================================================
--- pypy/dist/pypy/translator/genc/inttype.py (original)
+++ pypy/dist/pypy/translator/genc/inttype.py Wed May 11 16:16:08 2005
@@ -10,3 +10,13 @@
def nameof(self, v, debug=None):
return '%d' % (v,)
+
+
+class CUnsignedType(CType):
+ typename = 'unsigned'
+ error_return = '-1'
+ s_annotation = SomeInteger(nonneg=True, unsigned=True)
+
+ def nameof(self, v, debug=None):
+ assert v >= 0
+ return '%d' % (v,)
Added: pypy/dist/pypy/translator/genc/ll_include.h
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/genc/ll_include.h Wed May 11 16:16:08 2005
@@ -0,0 +1,15 @@
+
+/************************************************************/
+ /*** C header subsection: operations on LowLevelTypes ***/
+
+
+/* XXX no reference counting */
+
+#define OP_MALLOC(typename, r, err) \
+ r = PyObject_Malloc(sizeof(typename)); \
+ if (r == NULL) { PyErr_NoMemory(); FAIL(err) } \
+ memset((void*) r, 0, sizeof(typename));
+
+#define OP_GETFIELD(x, fieldname, r, err) r = x->fieldname;
+#define OP_SETFIELD(x, fieldname, val, r, err) x->fieldname = val;
+#define OP_GETSUBSTRUCT(x, fieldname, r, err) r = &x->fieldname;
Added: pypy/dist/pypy/translator/genc/lltype.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/genc/lltype.py Wed May 11 16:16:08 2005
@@ -0,0 +1,150 @@
+from __future__ import generators
+from pypy.translator.genc.basetype import CType
+from pypy.translator.gensupp import C_IDENTIFIER
+from pypy.objspace.flow.model import SpaceOperation, Constant, Variable
+from pypy.rpython import lltypes
+
+
+class CLiteral(CType): # HACK! TEMPORARY
+ def nameof(self, obj, debug=None):
+ assert isinstance(obj, str)
+ return obj
+
+class CLiteralTypeName(CType): # HACK! TEMPORARY
+ def nameof(self, obj, debug=None):
+ assert isinstance(obj, lltypes.LowLevelType)
+ ct = ll2concretetype(self.translator, obj)
+ return ct.typename
+
+
+class CLLType(CType):
+
+ def __init__(self, translator, lltype):
+ super(CLLType, self).__init__(translator)
+ self.lltype = lltype
+## self.globaldecl = []
+
+ def debugname(self):
+ # a nice textual name for debugging...
+ return str(self.lltype)
+
+## def collect_globals(self, genc):
+## result = self.globaldecl
+## self.globaldecl = []
+## return result
+
+
+class CPtrType(CLLType):
+ error_return = 'NULL'
+ Counter = 0
+
+ def __init__(self, translator, lltype):
+ super(CPtrType, self).__init__(translator, lltype)
+ ct = ll2concretetype(translator, lltype.TO)
+ self.typename = 'ptr%d_%s' % (CPtrType.Counter,
+ ct.typename.translate(C_IDENTIFIER))
+ CPtrType.Counter += 1
+
+ def init_globals(self, genc):
+ ct = ll2concretetype(genc.translator, self.lltype.TO)
+ yield 'typedef %s* %s;' % (ct.typename, self.typename)
+ yield '#define OP_DECREF_%s(x) /* XXX nothing for now */' % (
+ self.typename)
+
+ def spec_getattr(self, typer, op):
+ v_ptr, v_attrname = op.args
+ assert isinstance(v_attrname, Constant)
+ attrname = v_attrname.value
+ attrtype = self.lltype.TO._flds[attrname]
+ cliteral = typer.annotator.translator.getconcretetype(CLiteral)
+ s_result = typer.annotator.binding(op.result)
+ ctresult = typer.annotation2concretetype(s_result)
+ if isinstance(attrtype, lltypes.ContainerType):
+ yield typer.typed_op(op, [self, cliteral], ctresult,
+ newopname='getsubstruct')
+ else:
+ yield typer.typed_op(op, [self, cliteral], ctresult,
+ newopname='getfield')
+
+ def spec_setattr(self, typer, op):
+ v_ptr, v_attrname, v_value = op.args
+ assert isinstance(v_attrname, Constant)
+ attrname = v_attrname.value
+ attrtype = self.lltype.TO._flds[attrname]
+ cliteral = typer.annotator.translator.getconcretetype(CLiteral)
+ if isinstance(attrtype, lltypes.ContainerType):
+ raise AssertionError("cannot setattr to a substructure")
+ ctinput = ll2concretetype(typer.annotator.translator, attrtype)
+ yield typer.typed_op(op, [self, cliteral, ctinput], typer.TNone,
+ newopname='setfield')
+
+
+class CStructType(CLLType):
+ Counter = 0
+
+ def __init__(self, translator, lltype):
+ super(CStructType, self).__init__(translator, lltype)
+ basename = lltype._name.translate(C_IDENTIFIER)
+ self.typename = 'struct ll_%s%d' % (basename, CStructType.Counter)
+ CStructType.Counter += 1
+
+ def init_globals(self, genc):
+ # make sure that the field types are defined before we use them
+ lines = ['%s {' % self.typename]
+ for fieldname in self.lltype._names:
+ T = self.lltype._flds[fieldname]
+ ct = ll2concretetype(genc.translator, T)
+ for line in genc.need_typedecl_now(ct):
+ yield line
+ lines.append('\t%s %s;' % (ct.typename, fieldname))
+ lines.append('};')
+ for line in lines:
+ yield line
+
+
+class CArrayType(CLLType):
+ Counter = 0
+
+ def __init__(self, translator, lltype):
+ super(CArrayType, self).__init__(translator, lltype)
+ self.typename = 'struct array%d ' % CArrayType.Counter
+ CArrayType.Counter += 1
+
+ def init_globals(self, genc):
+ # define first the struct containing one item of this array
+ ct = ll2concretetype(genc.translator, self.lltype.OF)
+ for line in genc.need_typedecl_now(ct):
+ yield line
+ # the array struct itself
+ yield '%s {' % self.typename
+ yield '\tlong size;'
+ yield '\t%s items[1]; /* variable-sized */' % ct.typename
+ yield '};'
+
+
+# ____________________________________________________________
+
+from pypy.translator.genc import inttype, nonetype
+
+primitivetypemap = {
+ lltypes.Signed: inttype.CIntType,
+ lltypes.Unsigned: inttype.CUnsignedType,
+ #lltypes.Char: ...
+ lltypes.Bool: inttype.CIntType,
+ lltypes.Void: nonetype.CNoneType,
+ }
+
+def get_primitive_type(translator, lltype):
+ cls = primitivetypemap[lltype]
+ return translator.getconcretetype(cls)
+
+ll2concretetypemap = {
+ lltypes.Struct: CStructType,
+ lltypes.Array: CArrayType,
+ lltypes._PtrType: CPtrType,
+ lltypes.Primitive: get_primitive_type,
+ }
+
+def ll2concretetype(translator, lltype):
+ cls = ll2concretetypemap[lltype.__class__]
+ return translator.getconcretetype(cls, lltype)
Added: pypy/dist/pypy/translator/genc/test/test_lltyped.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/genc/test/test_lltyped.py Wed May 11 16:16:08 2005
@@ -0,0 +1,37 @@
+from pypy.rpython.lltypes import *
+from pypy.translator.tool.buildpyxmodule import skip_missing_compiler
+from pypy.translator.translator import Translator
+from pypy.translator.genc.ctyper import GenCSpecializer
+
+
+class TestLowLevelType:
+ objspacename = 'flow'
+
+ def getcompiled(self, func, argstypelist=[]):
+ t = Translator(func, simplifying=True)
+ # builds starting-types from func_defs
+ a = t.annotate(argstypelist)
+ a.simplify()
+ GenCSpecializer(a).specialize()
+ t.checkgraphs()
+ t.view()
+ return skip_missing_compiler(t.ccompile)
+
+ def test_simple(self):
+ S = Struct("s", ('v', Signed))
+ def llf():
+ s = malloc(S)
+ return s.v
+ fn = self.getcompiled(llf)
+ assert fn() == 0
+
+ def test_simple2(self):
+ S = Struct("s", ('v', Signed))
+ S2 = Struct("s2", ('a',S), ('b',S))
+ def llf():
+ s = malloc(S2)
+ s.a.v = 6
+ s.b.v = 12
+ return s.a.v+s.b.v
+ fn = self.getcompiled(llf)
+ assert fn() == 18
More information about the Pypy-commit
mailing list