4343#define REAL_SIZE_TP (tp ) PyLong_AsSsize_t(PyDict_GetItem((tp)->tp_dict, polyglot_from_string("n_fields", SRC_CS)))
4444#define REAL_SIZE (op ) REAL_SIZE_TP(Py_TYPE(op))
4545
46+ char * PyStructSequence_UnnamedField = "unnamed field" ;
47+
4648static void
4749structseq_dealloc (PyStructSequence * obj )
4850{
@@ -55,87 +57,104 @@ structseq_dealloc(PyStructSequence *obj)
5557 PyObject_GC_Del (obj );
5658}
5759
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 );
6062PyObject * 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 ));
6264}
6365
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 ) {
6768 Py_ssize_t i ;
6869
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+ }
7875 }
76+ return i ;
77+ }
7978
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 ));
8686
87- if (newType == NULL ) {
88- Py_DECREF (field_names );
89- Py_DECREF (field_docs );
90- return -1 ;
91- }
9287
9388 // copy generic fields (CPython mem-copies a template)
89+ type -> tp_name = desc -> name ;
9490 type -> tp_basicsize = sizeof (PyStructSequence ) - sizeof (PyObject * );
9591 type -> tp_itemsize = sizeof (PyObject * );
96- type -> tp_repr = newType -> tp_repr ;
9792 type -> tp_flags = Py_TPFLAGS_DEFAULT ;
9893 type -> tp_members = NULL ;
99- type -> tp_new = newType -> tp_new ;
94+ type -> tp_doc = desc -> doc ;
10095 type -> tp_base = & PyTuple_Type ;
101- type -> tp_alloc = newType -> tp_alloc ;
10296 type -> tp_dealloc = (destructor )structseq_dealloc ;
10397
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-
11198 // now initialize the type
11299 if (PyType_Ready (type ) < 0 )
113100 return -1 ;
114101 Py_INCREF (type );
115102
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+ );
117126}
118127
128+ typedef PyTypeObject * (* structseq_newtype_fun_t )(void * , void * , void * , void * , int );
129+ UPCALL_TYPED_ID (PyStructSequence_NewType , structseq_newtype_fun_t );
119130PyTypeObject * 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 ;
121132 Py_ssize_t i ;
122133
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 * ));
126139 PyStructSequence_Field * fields = desc -> fields ;
140+ int j = 0 ;
127141 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+ }
130147 }
131148
132149 // 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+ );
139158}
140159
141160// taken from CPython "Objects/structseq.c"
0 commit comments