~ubuntu-branches/ubuntu/karmic/pypy/karmic

« back to all changes in this revision

Viewing changes to pypy/objspace/cpy/typedef.py

  • Committer: Bazaar Package Importer
  • Author(s): Alexandre Fayolle
  • Date: 2007-04-13 09:33:09 UTC
  • Revision ID: james.westby@ubuntu.com-20070413093309-yoojh4jcoocu2krz
Tags: upstream-1.0.0
ImportĀ upstreamĀ versionĀ 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""
 
2
Generic support to turn interpreter objects (subclasses of Wrappable)
 
3
into CPython objects (subclasses of W_Object) based on their typedef.
 
4
"""
 
5
 
 
6
from pypy.objspace.cpy.capi import *
 
7
from pypy.interpreter.error import OperationError
 
8
from pypy.interpreter.baseobjspace import Wrappable, SpaceCache
 
9
from pypy.interpreter.function import Function
 
10
from pypy.interpreter.typedef import GetSetProperty
 
11
from pypy.rlib.objectmodel import we_are_translated
 
12
from pypy.rpython.rcpy import CPyTypeInterface, cpy_export, cpy_import
 
13
from pypy.rpython.rcpy import cpy_typeobject, rpython_object, cpy_allocate
 
14
from pypy.rpython.rcpy import init_rpython_data, get_rpython_data
 
15
from pypy.rpython.lltypesystem import lltype
 
16
 
 
17
 
 
18
def rpython2cpython(space, x):
 
19
    cache = space.fromcache(TypeDefCache)
 
20
    typeintf = cache.getorbuild(x.typedef)
 
21
    if we_are_translated():
 
22
        obj = cpy_export(typeintf, x)
 
23
        return W_Object(obj)
 
24
    else:
 
25
        w_x = x.__cpy_wrapper__
 
26
        if w_x is None:
 
27
            w_type = cache.wraptypeintf(x.__class__, typeintf)
 
28
            w_x = W_Object(rpython_object.__new__(w_type.value))
 
29
            init_rpython_data(w_x.value, x)
 
30
            x.__cpy_wrapper__ = w_x
 
31
        return w_x
 
32
rpython2cpython.allow_someobjects = True
 
33
rpython2cpython._annspecialcase_ = "specialize:argtype(1)"
 
34
 
 
35
def rpython2cpytype(space, Cls):
 
36
    cache = space.fromcache(TypeDefCache)
 
37
    typeintf = cache.getorbuild(Cls.typedef)
 
38
    if we_are_translated():
 
39
        cpytype = cpy_typeobject(typeintf, Cls)
 
40
        return W_Object(cpytype)        
 
41
    else:
 
42
        return cache.wraptypeintf(Cls, typeintf)
 
43
rpython2cpytype.allow_someobjects = True
 
44
rpython2cpytype._annspecialcase_ = "specialize:arg(1)"
 
45
    
 
46
def cpython2rpython_raw(space, w_obj):
 
47
    "NOT_RPYTHON."
 
48
    try:
 
49
        w_obj, result, follow = space.wrap_cache[id(w_obj)]
 
50
    except KeyError:
 
51
        if isinstance(w_obj.value, rpython_object):
 
52
            result = get_rpython_data(w_obj.value)
 
53
        else:
 
54
            result = None
 
55
    return result
 
56
 
 
57
def cpython2rpython(space, RequiredClass, w_obj):
 
58
    if we_are_translated():
 
59
        cache = space.fromcache(TypeDefCache)
 
60
        typeintf = cache.getorbuild(RequiredClass.typedef)
 
61
        cpytype = cpy_typeobject(typeintf, RequiredClass)
 
62
        w_cpytype = W_Object(cpytype)
 
63
        if space.is_true(space.isinstance(w_obj, w_cpytype)):
 
64
            x = w_obj.value
 
65
            return cpy_import(RequiredClass, x)
 
66
    else:
 
67
        result = cpython2rpython_raw(space, w_obj)
 
68
        if isinstance(result, RequiredClass):
 
69
            return result
 
70
    w_objtype = space.type(w_obj)
 
71
    w_name = space.getattr(w_objtype, space.wrap('__name__'))
 
72
    typename = space.str_w(w_name)
 
73
    msg = "'%s' object expected, got '%s' instead" % (
 
74
        RequiredClass.typedef.name, typename)
 
75
    raise OperationError(space.w_TypeError, space.wrap(msg))
 
76
cpython2rpython._annspecialcase_ = 'specialize:arg(1)'
 
77
cpython2rpython.allow_someobjects = True
 
78
 
 
79
def cpython_allocate(cls, w_subtype):
 
80
    return cpy_allocate(cls, w_subtype.value)
 
81
cpython_allocate._annspecialcase_ = 'specialize:arg(0)'
 
82
cpython_allocate.allow_someobjects = True
 
83
 
 
84
# ____________________________________________________________
 
85
 
 
86
class TypeDefCache(SpaceCache):
 
87
    def __init__(self, space):
 
88
        super(TypeDefCache, self).__init__(space)
 
89
        self.wrappedtypes = {}
 
90
 
 
91
    def build(cache, typedef):
 
92
        if typedef in (Function.typedef, GetSetProperty.typedef):
 
93
            raise ValueError("cannot wrap at run-time an interpreter object "
 
94
                             "of type %r" % (typedef.name,))
 
95
        space = cache.space
 
96
        objects = {}
 
97
        for name, value in typedef.rawdict.items():
 
98
            #if name.startswith('__') and name.endswith('__'):
 
99
            #    raise NotImplementedError("missing support for special "
 
100
            #                              "attributes in TypeDef-to-CPython "
 
101
            #                              "converter (%s.%s)" % (
 
102
            #        typedef.name, name))
 
103
            w_value = space.wrap(value)
 
104
            objects[name] = lltype.pyobjectptr(w_value.value)
 
105
        typeintf = CPyTypeInterface(typedef.name, objects, typedef.acceptable_as_base_class)
 
106
        return typeintf
 
107
 
 
108
    def wraptypeintf(cache, cls, typeintf):
 
109
        "NOT_RPYTHON.  Not available after translation."
 
110
        try:
 
111
            return cache.wrappedtypes[cls]
 
112
        except KeyError:
 
113
            typedef = cls.typedef
 
114
            space = cache.space
 
115
            newtype = typeintf.emulate(cls)
 
116
            w_result = W_Object(newtype)
 
117
            space.wrap_cache[id(w_result)] = w_result, typedef, follow_annotations
 
118
            cache.wrappedtypes[cls] = w_result
 
119
            return w_result
 
120
 
 
121
def follow_annotations(bookkeeper, w_type):
 
122
    pass
 
123
 
 
124
 
 
125
# hack!
 
126
Wrappable.__cpy_wrapper__ = None