43
43
#define REAL_SIZE_TP (tp ) PyLong_AsSsize_t(PyDict_GetItem((tp)->tp_dict, polyglot_from_string("n_fields", SRC_CS)))
44
44
#define REAL_SIZE (op ) REAL_SIZE_TP(Py_TYPE(op))
45
45
46
+ char * PyStructSequence_UnnamedField = "unnamed field" ;
47
+
46
48
static void
47
49
structseq_dealloc (PyStructSequence * obj )
48
50
{
@@ -55,87 +57,104 @@ structseq_dealloc(PyStructSequence *obj)
55
57
PyObject_GC_Del (obj );
56
58
}
57
59
58
- /* StructSequences a.k.a. 'namedtuple' */
59
- UPCALL_ID (PyStructSequence_New );
60
+ typedef PyObject * ( * structseq_new_fun_t )( PyTypeObject * );
61
+ UPCALL_TYPED_ID (PyStructSequence_New , structseq_new_fun_t );
60
62
PyObject * PyStructSequence_New (PyTypeObject * o ) {
61
- return UPCALL_CEXT_O ( _jls_PyStructSequence_New , native_type_to_java (o ));
63
+ return _jls_PyStructSequence_New ( native_type_to_java (o ));
62
64
}
63
65
64
- UPCALL_ID (PyStructSequence_InitType2 );
65
- int PyStructSequence_InitType2 (PyTypeObject * type , PyStructSequence_Desc * desc ) {
66
- Py_ssize_t n_members = desc -> n_in_sequence ;
66
+ static Py_ssize_t
67
+ count_members (PyStructSequence_Desc * desc , Py_ssize_t * n_unnamed_members ) {
67
68
Py_ssize_t i ;
68
69
69
- memset (type , 0 , sizeof (PyTypeObject ));
70
-
71
- // put field names and doc strings into two tuples
72
- PyObject * field_names = PyTuple_New (n_members );
73
- PyObject * field_docs = PyTuple_New (n_members );
74
- PyStructSequence_Field * fields = desc -> fields ;
75
- for (i = 0 ; i < n_members ; i ++ ) {
76
- PyTuple_SetItem (field_names , i , polyglot_from_string (fields [i ].name , SRC_CS ));
77
- PyTuple_SetItem (field_docs , i , polyglot_from_string (fields [i ].doc , SRC_CS ));
70
+ * n_unnamed_members = 0 ;
71
+ for (i = 0 ; desc -> fields [i ].name != NULL ; ++ i ) {
72
+ if (desc -> fields [i ].name == PyStructSequence_UnnamedField ) {
73
+ (* n_unnamed_members )++ ;
74
+ }
78
75
}
76
+ return i ;
77
+ }
79
78
80
- // we create the new type managed
81
- PyTypeObject * newType = (PyTypeObject * ) UPCALL_CEXT_O (_jls_PyStructSequence_InitType2 ,
82
- polyglot_from_string (desc -> name , SRC_CS ),
83
- polyglot_from_string (desc -> doc , SRC_CS ),
84
- native_to_java (field_names ),
85
- native_to_java (field_docs ));
79
+ typedef int (* structseq_init_fun_t )(void * , void * , void * , int );
80
+ UPCALL_TYPED_ID (PyStructSequence_InitType2 , structseq_init_fun_t );
81
+ int PyStructSequence_InitType2 (PyTypeObject * type , PyStructSequence_Desc * desc ) {
82
+ Py_ssize_t n_members , n_unnamed_members , n_named_members ;
83
+ Py_ssize_t i ;
84
+
85
+ memset (type , 0 , sizeof (PyTypeObject ));
86
86
87
- if (newType == NULL ) {
88
- Py_DECREF (field_names );
89
- Py_DECREF (field_docs );
90
- return -1 ;
91
- }
92
87
93
88
// copy generic fields (CPython mem-copies a template)
89
+ type -> tp_name = desc -> name ;
94
90
type -> tp_basicsize = sizeof (PyStructSequence ) - sizeof (PyObject * );
95
91
type -> tp_itemsize = sizeof (PyObject * );
96
- type -> tp_repr = newType -> tp_repr ;
97
92
type -> tp_flags = Py_TPFLAGS_DEFAULT ;
98
93
type -> tp_members = NULL ;
99
- type -> tp_new = newType -> tp_new ;
94
+ type -> tp_doc = desc -> doc ;
100
95
type -> tp_base = & PyTuple_Type ;
101
- type -> tp_alloc = newType -> tp_alloc ;
102
96
type -> tp_dealloc = (destructor )structseq_dealloc ;
103
97
104
- // now copy specific fields
105
- type -> tp_name = newType -> tp_name ;
106
- type -> tp_doc = newType -> tp_doc ;
107
- type -> tp_dict = newType -> tp_dict ;
108
-
109
- Py_DECREF (newType );
110
-
111
98
// now initialize the type
112
99
if (PyType_Ready (type ) < 0 )
113
100
return -1 ;
114
101
Py_INCREF (type );
115
102
116
- return 0 ;
103
+ n_members = count_members (desc , & n_unnamed_members );
104
+ n_named_members = n_members - n_unnamed_members ;
105
+ // put field names and doc strings into two lists
106
+ void * * field_names = (void * * ) truffle_managed_malloc (n_named_members * sizeof (void * ));
107
+ void * * field_docs = (void * * ) truffle_managed_malloc (n_named_members * sizeof (void * ));
108
+ PyStructSequence_Field * fields = desc -> fields ;
109
+ int j = 0 ;
110
+ for (i = 0 ; i < n_members ; i ++ ) {
111
+ if (fields [i ].name != PyStructSequence_UnnamedField ) {
112
+ field_names [j ] = polyglot_from_string (fields [i ].name , SRC_CS );
113
+ field_docs [j ] = polyglot_from_string (fields [i ].doc , SRC_CS );
114
+ j ++ ;
115
+ }
116
+ }
117
+
118
+ // this initializes the type dict (adds attributes)
119
+ return _jls_PyStructSequence_InitType2 (
120
+ native_type_to_java (type ),
121
+ /* TODO(fa): use polyglot_from_VoidPtr_array once this is visible */
122
+ polyglot_from_PyObjectPtr_array ((PyObjectPtr * ) field_names , (uint64_t ) n_members ),
123
+ polyglot_from_PyObjectPtr_array ((PyObjectPtr * ) field_docs , (uint64_t ) n_members ),
124
+ desc -> n_in_sequence
125
+ );
117
126
}
118
127
128
+ typedef PyTypeObject * (* structseq_newtype_fun_t )(void * , void * , void * , void * , int );
129
+ UPCALL_TYPED_ID (PyStructSequence_NewType , structseq_newtype_fun_t );
119
130
PyTypeObject * PyStructSequence_NewType (PyStructSequence_Desc * desc ) {
120
- Py_ssize_t n_members = desc -> n_in_sequence ;
131
+ Py_ssize_t n_members , n_unnamed_members , n_named_members ;
121
132
Py_ssize_t i ;
122
133
123
- // put field names and doc strings into two tuples
124
- PyObject * field_names = PyTuple_New (n_members );
125
- PyObject * field_docs = PyTuple_New (n_members );
134
+ n_members = count_members (desc , & n_unnamed_members );
135
+ n_named_members = n_members - n_unnamed_members ;
136
+ // put field names and doc strings into two lists
137
+ void * * field_names = (void * * ) truffle_managed_malloc (n_named_members * sizeof (void * ));
138
+ void * * field_docs = (void * * ) truffle_managed_malloc (n_named_members * sizeof (void * ));
126
139
PyStructSequence_Field * fields = desc -> fields ;
140
+ int j = 0 ;
127
141
for (i = 0 ; i < n_members ; i ++ ) {
128
- PyTuple_SetItem (field_names , i , polyglot_from_string (fields [i ].name , SRC_CS ));
129
- PyTuple_SetItem (field_docs , i , polyglot_from_string (fields [i ].doc , SRC_CS ));
142
+ if (fields [i ].name != PyStructSequence_UnnamedField ) {
143
+ field_names [j ] = polyglot_from_string (fields [i ].name , SRC_CS );
144
+ field_docs [j ] = polyglot_from_string (fields [i ].doc , SRC_CS );
145
+ j ++ ;
146
+ }
130
147
}
131
148
132
149
// we create the new type managed
133
- PyTypeObject * newType = (PyTypeObject * ) UPCALL_CEXT_O (_jls_PyStructSequence_InitType2 ,
134
- polyglot_from_string (desc -> name , SRC_CS ),
135
- polyglot_from_string (desc -> doc , SRC_CS ),
136
- native_to_java (field_names ),
137
- native_to_java (field_docs ));
138
- return newType ;
150
+ return _jls_PyStructSequence_NewType (
151
+ polyglot_from_string (desc -> name , SRC_CS ),
152
+ polyglot_from_string (desc -> doc , SRC_CS ),
153
+ /* TODO(fa): use polyglot_from_VoidPtr_array once this is visible */
154
+ polyglot_from_PyObjectPtr_array ((PyObjectPtr * ) field_names , (uint64_t ) n_members ),
155
+ polyglot_from_PyObjectPtr_array ((PyObjectPtr * ) field_docs , (uint64_t ) n_members ),
156
+ desc -> n_in_sequence
157
+ );
139
158
}
140
159
141
160
// taken from CPython "Objects/structseq.c"
0 commit comments