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 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
|
/***************************************************************/
/*** Psyco equivalent of object.h ***/
/***************************************************************/
#ifndef _PSY_OBJECT_H
#define _PSY_OBJECT_H
#include "../Python/pycompiler.h"
/*#define OB_REFCOUNT never directly manipulated*/
#define OB_type DEF_FIELD(PyObject, PyTypeObject*, ob_type, NO_PREV_FIELD)
#define FIX_size NONNEG_FIELD(PyVarObject, int, ob_size, OB_type)
#define VAR_size FMUT(FIX_size)
#define FIX_signed_size DEF_FIELD(PyVarObject, int, ob_size, OB_type)
#define VAR_signed_size FMUT(FIX_signed_size)
#define iOB_TYPE FIELD_INDEX(OB_type)
#define iFIX_SIZE FIELD_INDEX(FIX_size)
#define iVAR_SIZE FIELD_INDEX(VAR_size)
/* common type checkers, rewritten because in Psyco we manipulate type
objects directly and Python's usual macros insist on taking a regular
PyObject* whose type is checked. */
#if NEW_STYLE_TYPES
# define PyType_TypeCheck(tp1, tp) \
((tp1) == (tp) || PyType_IsSubtype((tp1), (tp)))
#else
# define PyType_TypeCheck(tp1, tp) ((tp1) == (tp))
#endif
#define PsycoIter_Check(tp) \
(PyType_HasFeature(tp, Py_TPFLAGS_HAVE_ITER) && \
(tp)->tp_iternext != NULL)
#define PsycoSequence_Check(tp) \
((tp)->tp_as_sequence && (tp)->tp_as_sequence->sq_item != NULL)
/* Return the type of an object, or NULL in case of exception (typically
a promotion exception). */
EXTERNFN PyTypeObject* Psyco_NeedType(PsycoObject* po, vinfo_t* vi);
PSY_INLINE PyTypeObject* Psyco_FastType(vinfo_t* vi) {
/* fast version. Only call this when you know the type has
already been loaded by a previous Psyco_NeedType() */
vinfo_t* vtp = vinfo_getitem(vi, iOB_TYPE);
if (vtp == NULL) {
PyObject* o = (PyObject*) CompileTime_Get(vi->source)->value;
return o->ob_type;
}
else {
return (PyTypeObject*) CompileTime_Get(vtp->source)->value;
}
}
#if USE_RUNTIME_SWITCHES
# error "Disabled because of type inheritance. The switch overlooks subtypes."
/* Check for the type of an object. Returns the index in the set 'fs' or
-1 if not in the set (or if exception). Used this is better than
Psyco_NeedType() if you are only interested in some types, not all of them. */
PSY_INLINE int Psyco_TypeSwitch(PsycoObject* po, vinfo_t* vi, fixed_switch_t* fs) {
vinfo_t* vtp = get_array_item(po, vi, OB_TYPE);
if (vtp == NULL)
return -1;
return psyco_switch_index(po, vtp, fs);
}
#endif
/* Is the given object is of the given type (or a subtype of it) ?
Returns -1 in case of error or if promotion is requested. */
PSY_INLINE int Psyco_VerifyType(PsycoObject* po, vinfo_t* vi, PyTypeObject* tp) {
PyTypeObject* vtp = Psyco_NeedType(po, vi);
if (vtp == NULL)
return -1;
return PyType_TypeCheck(vtp, tp);
}
/* Return the type that the object is known to be of, or NULL if unknown.
Never fails. */
EXTERNFN PyTypeObject* Psyco_KnownType(vinfo_t* vi);
/* Use this to assert the type of an object. Do not use unless you are
sure about it! (e.g. don't use this for integer-computing functions
if they might return a long in case of overflow) */
PSY_INLINE void Psyco_AssertType(PsycoObject* po, vinfo_t* vi, PyTypeObject* tp) {
psyco_assert_field(po, vi, OB_type, (long) tp);
}
/* Same as integer_non_null() but assumes we are testing a PyObject* pointer,
so that only compile-time NULLs or run-time pointers from which we have
not read anything yet can be NULL. Virtual-time pointers are assumed never
to be NULL. */
PSY_INLINE condition_code_t object_non_null(PsycoObject* po, vinfo_t* v) {
if (is_virtualtime(v->source) || v->array != NullArray)
return CC_ALWAYS_TRUE;
else
return integer_non_null(po, v);
}
/* The following functions are Psyco implementations of common functions
of the standard interpreter. */
EXTERNFN vinfo_t* PsycoObject_IsTrue(PsycoObject* po, vinfo_t* vi);
EXTERNFN vinfo_t* PsycoObject_Repr(PsycoObject* po, vinfo_t* vi);
/* Note: DelAttr() is SetAttr() with 'v' set to NULL (and not some vinfo_t
that would happend to contain zero). */
EXTERNFN vinfo_t* PsycoObject_GetAttr(PsycoObject* po, vinfo_t* o,
vinfo_t* attr_name);
EXTERNFN bool PsycoObject_SetAttr(PsycoObject* po, vinfo_t* o,
vinfo_t* attr_name, vinfo_t* v);
#if NEW_STYLE_TYPES /* Python >= 2.2b1 */
EXTERNFN vinfo_t* PsycoObject_GenericGetAttr(PsycoObject* po, vinfo_t* obj,
vinfo_t* vname);
#endif
EXTERNFN vinfo_t* PsycoObject_RichCompare(PsycoObject* po, vinfo_t* v,
vinfo_t* w, int op);
EXTERNFN vinfo_t* PsycoObject_RichCompareBool(PsycoObject* po,
vinfo_t* v,
vinfo_t* w, int op);
/* a quick way to specify the type of the object returned by an operation
when it is known, without having to go into all the details of the
operation itself (be careful, you must be *sure* of the return type): */
#define DEF_KNOWN_RET_TYPE_1(cname, op, flags, knowntype) \
DEF_KNOWN_RET_TYPE_internal(cname, knowntype, \
(PsycoObject* po, vinfo_t* v1), \
(po, op, flags, "v", v1))
#define DEF_KNOWN_RET_TYPE_2(cname, op, flags, knowntype) \
DEF_KNOWN_RET_TYPE_internal(cname, knowntype, \
(PsycoObject* po, vinfo_t* v1, vinfo_t* v2), \
(po, op, flags, "vv", v1, v2))
#define DEF_KNOWN_RET_TYPE_3(cname, op, flags, knowntype) \
DEF_KNOWN_RET_TYPE_internal(cname, knowntype, \
(PsycoObject* po, vinfo_t* v1, vinfo_t* v2, \
vinfo_t* v3), \
(po, op, flags, "vvv", v1, v2, v3))
#define DEF_KNOWN_RET_TYPE_4(cname, op, flags, knowntype) \
DEF_KNOWN_RET_TYPE_internal(cname, knowntype, \
(PsycoObject* po, vinfo_t* v1, vinfo_t* v2, \
vinfo_t* v3, vinfo_t* v4), \
(po, op, flags, "vvvv", v1, v2, v3, v4))
#define DEF_KNOWN_RET_TYPE_internal(cname, knowntype, fargs, gargs) \
static vinfo_t* cname fargs { \
vinfo_t* result = psyco_generic_call gargs ; \
if (result != NULL && !IS_NOTIMPLEMENTED(result)) { \
Psyco_AssertType(po, result, knowntype); \
} \
return result; \
}
/* 'true' unless 'x' is exactly the special 'not implemented' value
built by psyco_generic_call with CfPyErrNotImplemented */
#define IS_IMPLEMENTED(x) ((x) == NULL || !IS_NOTIMPLEMENTED(x))
/* is 'x' the special 'not implemented' value? */
#define IS_NOTIMPLEMENTED(x) \
((x)->source == CompileTime_NewSk(&psyco_skNotImplemented))
#if USE_RUNTIME_SWITCHES
/* definition of commonly used "fixed switches", i.e. sets of
values (duplicating fixed switch structures for the same set
of value can inccur a run-time performance loss in some cases) */
/* the variable names list the values in order.
'int' means '&PyInt_Type' etc. */
EXTERNVAR fixed_switch_t psyfs_int;
EXTERNVAR fixed_switch_t psyfs_int_long;
EXTERNVAR fixed_switch_t psyfs_int_long_float;
EXTERNVAR fixed_switch_t psyfs_tuple_list;
EXTERNVAR fixed_switch_t psyfs_string_unicode;
EXTERNVAR fixed_switch_t psyfs_tuple;
EXTERNVAR fixed_switch_t psyfs_dict;
EXTERNVAR fixed_switch_t psyfs_none;
/* NOTE: don't forget to update pobject.c when adding new variables here */
#endif
/* for dispatcher.c */
EXTERNFN vinfo_t* Psyco_SafelyDeleteVar(PsycoObject* po, vinfo_t* vi);
#endif /* _PSY_OBJECT_H */
|