1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
/***************************************************************/
/*** Tables of code merge points ***/
/***************************************************************/
#ifndef _MERGEPOINTS_H
#define _MERGEPOINTS_H
#include "psyco.h"
#include "dispatcher.h"
#include <compile.h>
/* A merge point is a point reached by two or more control paths in
the bytecode. They are a subset of the targets found by the standard
module function dis.findlabels(). It may be a subset because some
targets can only be reached by jumping from a single point, e.g. 'else:'.
Such targets are not merge points.
*/
struct mergepoint_s {
int bytecode_position;
global_entries_t entries;
};
/* 'bytecode_ptr' gives the position of the merge point in the bytecode.
An array of mergepoint_t structures is sorted against this field.
'entries' is a list of snapshots of the compiler states previously
encountered at this point.
*/
/* Caching version of the following function */
EXTERNFN PyObject* psyco_get_merge_points(PyCodeObject* co, int module);
/* The following function detects the merge points and builds an array of
mergepoint_t structures, stored into a Python string object. It returns
Py_None if the bytecode uses unsupported instructions. */
EXTERNFN PyObject* psyco_build_merge_points(PyCodeObject* co, int module);
/* Get a pointer to the first mergepoint_t structure in the array whose
'bytecode_ptr' is >= position. */
EXTERNFN mergepoint_t* psyco_next_merge_point(PyObject* mergepoints,
int position);
/* Get a pointer to the very first mergepoint_t structure in the array */
PSY_INLINE mergepoint_t* psyco_first_merge_point(PyObject* mergepoints)
{
extra_assert(PyString_Check(mergepoints));
return (mergepoint_t*) PyString_AS_STRING(mergepoints);
}
/* Same as psyco_next_merge_point() but returns NULL if bytecode_ptr!=position */
PSY_INLINE mergepoint_t* psyco_exact_merge_point(PyObject* mergepoints,
int position)
{
mergepoint_t* mp = psyco_next_merge_point(mergepoints, position);
if (mp->bytecode_position != position)
mp = NULL;
return mp;
}
#define MP_FLAGS_HAS_EXCEPT 1 /* the code block has an 'except' clause */
#define MP_FLAGS_HAS_FINALLY 2 /* the code block has a 'finally' clause */
#define MP_FLAGS_INLINABLE 4 /* function could be inlined */
#define MP_FLAGS_MODULE 8 /* can only run as module top-level code */
#define MP_FLAGS_CONTROLFLOW 16 /* can use early deletion of locals */
#define MP_FLAGS_EXTRA (-256)
PSY_INLINE int psyco_mp_flags(PyObject* mergepoints)
{
char* endptr = PyString_AS_STRING(mergepoints)+PyString_GET_SIZE(mergepoints);
return ((int*) endptr)[-1];
}
/* end of PsycoObject construction */
PSY_INLINE mergepoint_t* PsycoObject_Ready(PsycoObject* po) {
mergepoint_t* mp;
psyco_assert_coherent(po);
mp = psyco_first_merge_point(po->pr.merge_points);
psyco_delete_unused_vars(po, &mp->entries);
return mp;
}
/* A user-defined filter function to prevent compilation of some code objs */
EXTERNVAR PyObject* psyco_codeobj_filter_fn;
#endif /* _MERGEPOINTS_H */
|