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

« back to all changes in this revision

Viewing changes to pypy/translator/c/src/module.h

  • 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
/************************************************************/
 
3
 /***  C header subsection: CPython-extension-module-ness  ***/
 
4
 
 
5
#ifdef COUNT_OP_MALLOCS
 
6
# define METHODDEF_MALLOC_COUNTERS      \
 
7
                { "malloc_counters", malloc_counters, METH_VARARGS },
 
8
#else
 
9
# define METHODDEF_MALLOC_COUNTERS      /* nothing */
 
10
#endif
 
11
 
 
12
#define METHODDEF_DEBUGINFO    /* nothing, unless overridden by g_debuginfo.h */
 
13
 
 
14
#define MODULE_INITFUNC(modname)                        \
 
15
        static PyMethodDef my_methods[] = {             \
 
16
                METHODDEF_MALLOC_COUNTERS               \
 
17
                METHODDEF_DEBUGINFO                     \
 
18
                { (char *)NULL, (PyCFunction)NULL } };  \
 
19
        PyMODINIT_FUNC init##modname(void)
 
20
 
 
21
#define SETUP_MODULE(modname)   \
 
22
        char *errmsg; \
 
23
        PyObject *m = Py_InitModule(#modname, my_methods); \
 
24
        PyModule_AddStringConstant(m, "__sourcefile__", __FILE__); \
 
25
        this_module_globals = PyModule_GetDict(m); \
 
26
        PyGenCFunction_Type.tp_base = &PyCFunction_Type;        \
 
27
        PyGenCFunction_Type.tp_getset = PyCFunction_Type.tp_getset; \
 
28
        PyType_Ready(&PyGenCFunction_Type);     \
 
29
        RPythonError = PyErr_NewException(#modname ".RPythonError", \
 
30
                                          NULL, NULL); \
 
31
        if (RPythonError == NULL) \
 
32
                return; \
 
33
        PyModule_AddObject(m, "RPythonError", RPythonError); \
 
34
        errmsg = RPython_StartupCode(); \
 
35
        if (errmsg) { \
 
36
                PyErr_SetString(PyExc_RuntimeError, errmsg); \
 
37
                return; \
 
38
        } \
 
39
        if (setup_globalfunctions(globalfunctiondefs, #modname) < 0) \
 
40
                return; \
 
41
        if (setup_exportglobalobjects(cpyobjheaddefs) < 0)      \
 
42
                return; \
 
43
        if (setup_initcode(frozen_initcode, FROZEN_INITCODE_SIZE) < 0) \
 
44
                return; \
 
45
        if (setup_globalobjects(globalobjectdefs, cpyobjheaddefs) < 0) \
 
46
                return;
 
47
 
 
48
/*** table of global objects ***/
 
49
 
 
50
static PyObject *this_module_globals;
 
51
 
 
52
typedef struct {
 
53
        PyObject** p;
 
54
        char* name;
 
55
} globalobjectdef_t;
 
56
 
 
57
typedef struct {
 
58
        char* name;
 
59
        PyObject* cpyobj;
 
60
        void (*setupfn)(PyObject *);
 
61
} cpyobjheaddef_t;
 
62
 
 
63
typedef struct {
 
64
        PyObject** p;
 
65
        char* gfunc_name;
 
66
        PyMethodDef ml;
 
67
} globalfunctiondef_t;
 
68
 
 
69
/* helper-hook for post-setup */
 
70
static globalfunctiondef_t *globalfunctiondefsptr;
 
71
static PyObject *postsetup_get_typedict(PyObject *tp);
 
72
static PyObject *postsetup_get_methodname(int funcidx);
 
73
static PyObject *postsetup_build_method(int funcidx, PyObject *type);
 
74
int call_postsetup(PyObject *m);
 
75
 
 
76
/* implementations */
 
77
 
 
78
#ifndef PYPY_NOT_MAIN_FILE
 
79
 
 
80
static int setup_exportglobalobjects(cpyobjheaddef_t* cpyheadtable)
 
81
{
 
82
        PyObject* obj;
 
83
        cpyobjheaddef_t* cpydef;
 
84
 
 
85
        /* Store the object given by their heads into the module's dict.
 
86
           Warning: these object heads might still be invalid, e.g.
 
87
           typically their ob_type needs patching!
 
88
           But PyDict_SetItemString() doesn't inspect them...
 
89
        */
 
90
        for (cpydef = cpyheadtable; cpydef->name != NULL; cpydef++) {
 
91
                obj = cpydef->cpyobj;
 
92
                if (obj->ob_type == NULL)
 
93
                        obj->ob_type = &PyType_Type;
 
94
                if (PyDict_SetItemString(this_module_globals,
 
95
                                         cpydef->name, obj) < 0)
 
96
                        return -1;
 
97
        }
 
98
        return 0;
 
99
}
 
100
 
 
101
static int setup_globalobjects(globalobjectdef_t* globtable,
 
102
                               cpyobjheaddef_t* cpyheadtable)
 
103
{
 
104
        PyObject* obj;
 
105
        globalobjectdef_t* def;
 
106
        cpyobjheaddef_t* cpydef;
 
107
 
 
108
        /* Patch all locations that need to contain a specific PyObject*.
 
109
           This must go after the previous loop, otherwise
 
110
           PyDict_GetItemString() might not find some of them.
 
111
         */
 
112
        for (def = globtable; def->p != NULL; def++) {
 
113
                obj = PyDict_GetItemString(this_module_globals, def->name);
 
114
                if (obj == NULL) {
 
115
                        PyErr_Format(PyExc_AttributeError,
 
116
                                     "initialization code should have "
 
117
                                     "created '%s'", def->name);
 
118
                        return -1;
 
119
                }
 
120
                Py_INCREF(obj);
 
121
                *def->p = obj;   /* store the object ref in the global var */
 
122
        }
 
123
        /* All objects should be valid at this point.  Loop again and
 
124
           make sure all types are ready.
 
125
        */
 
126
        for (cpydef = cpyheadtable; cpydef->name != NULL; cpydef++) {
 
127
                obj = cpydef->cpyobj;
 
128
                if (PyType_Check(obj)) {
 
129
                        /* XXX hmmm */
 
130
                        obj->ob_type = NULL;
 
131
                        if (PyType_Ready((PyTypeObject*) obj) < 0)
 
132
                                return -1;
 
133
                }
 
134
        }
 
135
        /* call the user-defined setups *after* all types are ready
 
136
         * in case of dependencies */
 
137
        for (cpydef = cpyheadtable; cpydef->name != NULL; cpydef++) {
 
138
                obj = cpydef->cpyobj;
 
139
                if (cpydef->setupfn) {
 
140
                        cpydef->setupfn(obj);
 
141
                        if (RPyExceptionOccurred()) {
 
142
                                RPyConvertExceptionToCPython();
 
143
                                return -1;
 
144
                        }
 
145
                }
 
146
        }
 
147
        return 0;
 
148
}
 
149
 
 
150
static int setup_globalfunctions(globalfunctiondef_t* def, char* modname)
 
151
{
 
152
        PyObject* fn;
 
153
        PyObject* modname_o = PyString_FromString(modname);
 
154
        if (modname_o == NULL)
 
155
                return -1;
 
156
 
 
157
        for (; def->p != NULL; def++) {
 
158
                fn = PyCFunction_NewEx(&def->ml, NULL, modname_o);
 
159
                if (fn == NULL)
 
160
                        return -1;
 
161
                fn->ob_type = &PyGenCFunction_Type;
 
162
                *def->p = fn;   /* store the object ref in the global var */
 
163
 
 
164
                if (PyDict_SetItemString(this_module_globals,
 
165
                                         def->gfunc_name,
 
166
                                         fn) < 0)
 
167
                        return -1;
 
168
        }
 
169
        return 0;
 
170
}
 
171
 
 
172
static int setup_initcode(char* frozendata[], int len)
 
173
{
 
174
        PyObject* co;
 
175
        PyObject* globals;
 
176
        PyObject* res;
 
177
        char *buffer, *bufp;
 
178
        int chunk, count = 0;
 
179
        
 
180
        buffer = PyMem_NEW(char, len);
 
181
        if (buffer == NULL)
 
182
                return -1;
 
183
        bufp = buffer;
 
184
        while (count < len) {
 
185
                chunk = len-count < 1024 ? len-count : 1024;
 
186
                memcpy(bufp, *frozendata, chunk);
 
187
                bufp += chunk;
 
188
                count += chunk;
 
189
                ++frozendata;
 
190
        }
 
191
        co = PyMarshal_ReadObjectFromString(buffer, len);
 
192
        if (co == NULL)
 
193
                return -1;
 
194
        PyMem_DEL(buffer);
 
195
        if (!PyCode_Check(co)) {
 
196
                PyErr_SetString(PyExc_TypeError, "uh?");
 
197
                return -1;
 
198
        }
 
199
        globals = this_module_globals;
 
200
        if (PyDict_GetItemString(globals, "__builtins__") == NULL)
 
201
                PyDict_SetItemString(globals, "__builtins__",
 
202
                                     PyEval_GetBuiltins());
 
203
        res = PyEval_EvalCode((PyCodeObject *) co, globals, globals);
 
204
        if (res == NULL)
 
205
                return -1;
 
206
        Py_DECREF(res);
 
207
        return 0;
 
208
}
 
209
 
 
210
static PyObject *postsetup_get_typedict(PyObject *tp)
 
211
{
 
212
    PyTypeObject *type = (PyTypeObject *)tp;
 
213
    PyObject *ret;
 
214
 
 
215
    ret = type->tp_dict;
 
216
    Py_INCREF(ret);
 
217
    return ret;
 
218
}
 
219
 
 
220
static PyObject *postsetup_get_methodname(int funcidx)
 
221
{   
 
222
    globalfunctiondef_t *gfuncdef = &globalfunctiondefsptr[funcidx];
 
223
 
 
224
    if (gfuncdef->p)
 
225
        return PyString_FromString(gfuncdef->gfunc_name);
 
226
    Py_INCREF(Py_None);
 
227
    return Py_None;
 
228
}
 
229
 
 
230
static PyObject *postsetup_build_method(int funcidx, PyObject *type)
 
231
{   
 
232
    globalfunctiondef_t *gfuncdef = &globalfunctiondefsptr[funcidx];
 
233
 
 
234
    if (gfuncdef->p)
 
235
        return PyDescr_NewMethod((PyTypeObject *)type, &gfuncdef->ml);
 
236
    Py_INCREF(Py_None);
 
237
    return Py_None;
 
238
}
 
239
 
 
240
int call_postsetup(PyObject *m)
 
241
{
 
242
    PyObject *init, *ret;
 
243
    
 
244
    init = PyDict_GetItemString(this_module_globals, "__init__");
 
245
    if (init == NULL) {
 
246
        PyErr_Clear();
 
247
        return 0;
 
248
    }
 
249
    ret = PyObject_CallFunction(init, "O", m);
 
250
    if (ret == NULL)
 
251
        return -1;
 
252
    return 0;
 
253
}
 
254
 
 
255
#endif /* PYPY_NOT_MAIN_FILE */