Add a new class gdb.Architecture which exposes GDB's
[platform/upstream/binutils.git] / gdb / python / py-frame.c
1 /* Python interface to stack frames
2
3    Copyright (C) 2008-2013 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 #include "defs.h"
21 #include "charset.h"
22 #include "block.h"
23 #include "frame.h"
24 #include "exceptions.h"
25 #include "symtab.h"
26 #include "stack.h"
27 #include "value.h"
28 #include "python-internal.h"
29 #include "symfile.h"
30 #include "objfiles.h"
31
32 typedef struct {
33   PyObject_HEAD
34   struct frame_id frame_id;
35   struct gdbarch *gdbarch;
36
37   /* Marks that the FRAME_ID member actually holds the ID of the frame next
38      to this, and not this frames' ID itself.  This is a hack to permit Python
39      frame objects which represent invalid frames (i.e., the last frame_info
40      in a corrupt stack).  The problem arises from the fact that this code
41      relies on FRAME_ID to uniquely identify a frame, which is not always true
42      for the last "frame" in a corrupt stack (it can have a null ID, or the same
43      ID as the  previous frame).  Whenever get_prev_frame returns NULL, we
44      record the frame_id of the next frame and set FRAME_ID_IS_NEXT to 1.  */
45   int frame_id_is_next;
46 } frame_object;
47
48 /* Require a valid frame.  This must be called inside a TRY_CATCH, or
49    another context in which a gdb exception is allowed.  */
50 #define FRAPY_REQUIRE_VALID(frame_obj, frame)           \
51     do {                                                \
52       frame = frame_object_to_frame_info (frame_obj);   \
53       if (frame == NULL)                                \
54         error (_("Frame is invalid."));                 \
55     } while (0)
56
57 /* Returns the frame_info object corresponding to the given Python Frame
58    object.  If the frame doesn't exist anymore (the frame id doesn't
59    correspond to any frame in the inferior), returns NULL.  */
60
61 struct frame_info *
62 frame_object_to_frame_info (PyObject *obj)
63 {
64   frame_object *frame_obj = (frame_object *) obj;  
65   struct frame_info *frame;
66
67   frame = frame_find_by_id (frame_obj->frame_id);
68   if (frame == NULL)
69     return NULL;
70
71   if (frame_obj->frame_id_is_next)
72     frame = get_prev_frame (frame);
73
74   return frame;
75 }
76
77 /* Called by the Python interpreter to obtain string representation
78    of the object.  */
79
80 static PyObject *
81 frapy_str (PyObject *self)
82 {
83   char *s;
84   PyObject *result;
85   struct ui_file *strfile;
86
87   strfile = mem_fileopen ();
88   fprint_frame_id (strfile, ((frame_object *) self)->frame_id);
89   s = ui_file_xstrdup (strfile, NULL);
90   result = PyString_FromString (s);
91   xfree (s);
92
93   return result;
94 }
95
96 /* Implementation of gdb.Frame.is_valid (self) -> Boolean.
97    Returns True if the frame corresponding to the frame_id of this
98    object still exists in the inferior.  */
99
100 static PyObject *
101 frapy_is_valid (PyObject *self, PyObject *args)
102 {
103   struct frame_info *frame = NULL;
104   volatile struct gdb_exception except;
105
106   TRY_CATCH (except, RETURN_MASK_ALL)
107     {
108       frame = frame_object_to_frame_info (self);
109     }
110   GDB_PY_HANDLE_EXCEPTION (except);
111
112   if (frame == NULL)
113     Py_RETURN_FALSE;
114
115   Py_RETURN_TRUE;
116 }
117
118 /* Implementation of gdb.Frame.name (self) -> String.
119    Returns the name of the function corresponding to this frame.  */
120
121 static PyObject *
122 frapy_name (PyObject *self, PyObject *args)
123 {
124   struct frame_info *frame;
125   const char *name;
126   enum language lang;
127   PyObject *result;
128   volatile struct gdb_exception except;
129
130   TRY_CATCH (except, RETURN_MASK_ALL)
131     {
132       FRAPY_REQUIRE_VALID (self, frame);
133
134       find_frame_funname (frame, &name, &lang, NULL);
135     }
136   GDB_PY_HANDLE_EXCEPTION (except);
137
138   if (name)
139     result = PyUnicode_Decode (name, strlen (name), host_charset (), NULL);
140   else
141     {
142       result = Py_None;
143       Py_INCREF (Py_None);
144     }
145
146   return result;
147 }
148
149 /* Implementation of gdb.Frame.type (self) -> Integer.
150    Returns the frame type, namely one of the gdb.*_FRAME constants.  */
151
152 static PyObject *
153 frapy_type (PyObject *self, PyObject *args)
154 {
155   struct frame_info *frame;
156   enum frame_type type = NORMAL_FRAME;/* Initialize to appease gcc warning.  */
157   volatile struct gdb_exception except;
158
159   TRY_CATCH (except, RETURN_MASK_ALL)
160     {
161       FRAPY_REQUIRE_VALID (self, frame);
162
163       type = get_frame_type (frame);
164     }
165   GDB_PY_HANDLE_EXCEPTION (except);
166
167   return PyInt_FromLong (type);
168 }
169
170 /* Implementation of gdb.Frame.architecture (self) -> gdb.Architecture.
171    Returns the frame's architecture as a gdb.Architecture object.  */
172
173 static PyObject *
174 frapy_arch (PyObject *self, PyObject *args)
175 {
176   struct frame_info *frame = NULL;    /* Initialize to appease gcc warning.  */
177   frame_object *obj = (frame_object *) self;
178   volatile struct gdb_exception except;
179
180   TRY_CATCH (except, RETURN_MASK_ALL)
181     {
182       FRAPY_REQUIRE_VALID (self, frame);
183     }
184   GDB_PY_HANDLE_EXCEPTION (except);
185
186   return gdbarch_to_arch_object (obj->gdbarch);
187 }
188
189 /* Implementation of gdb.Frame.unwind_stop_reason (self) -> Integer.
190    Returns one of the gdb.FRAME_UNWIND_* constants.  */
191
192 static PyObject *
193 frapy_unwind_stop_reason (PyObject *self, PyObject *args)
194 {
195   struct frame_info *frame = NULL;    /* Initialize to appease gcc warning.  */
196   volatile struct gdb_exception except;
197   enum unwind_stop_reason stop_reason;
198
199   TRY_CATCH (except, RETURN_MASK_ALL)
200     {
201       FRAPY_REQUIRE_VALID (self, frame);
202     }
203   GDB_PY_HANDLE_EXCEPTION (except);
204
205   stop_reason = get_frame_unwind_stop_reason (frame);
206
207   return PyInt_FromLong (stop_reason);
208 }
209
210 /* Implementation of gdb.Frame.pc (self) -> Long.
211    Returns the frame's resume address.  */
212
213 static PyObject *
214 frapy_pc (PyObject *self, PyObject *args)
215 {
216   CORE_ADDR pc = 0;           /* Initialize to appease gcc warning.  */
217   struct frame_info *frame;
218   volatile struct gdb_exception except;
219
220   TRY_CATCH (except, RETURN_MASK_ALL)
221     {
222       FRAPY_REQUIRE_VALID (self, frame);
223
224       pc = get_frame_pc (frame);
225     }
226   GDB_PY_HANDLE_EXCEPTION (except);
227
228   return gdb_py_long_from_ulongest (pc);
229 }
230
231 /* Implementation of gdb.Frame.block (self) -> gdb.Block.
232    Returns the frame's code block.  */
233
234 static PyObject *
235 frapy_block (PyObject *self, PyObject *args)
236 {
237   struct frame_info *frame;
238   struct block *block = NULL, *fn_block;
239   volatile struct gdb_exception except;
240
241   TRY_CATCH (except, RETURN_MASK_ALL)
242     {
243       FRAPY_REQUIRE_VALID (self, frame);
244       block = get_frame_block (frame, NULL);
245     }
246   GDB_PY_HANDLE_EXCEPTION (except);
247
248   for (fn_block = block;
249        fn_block != NULL && BLOCK_FUNCTION (fn_block) == NULL;
250        fn_block = BLOCK_SUPERBLOCK (fn_block))
251     ;
252
253   if (block == NULL || fn_block == NULL || BLOCK_FUNCTION (fn_block) == NULL)
254     {
255       PyErr_SetString (PyExc_RuntimeError,
256                        _("Cannot locate object file for block."));
257       return NULL;
258     }
259
260   if (block)
261     {
262       struct symtab *symt;
263
264       symt = SYMBOL_SYMTAB (BLOCK_FUNCTION (fn_block));
265       return block_to_block_object (block, symt->objfile);
266     }
267
268   Py_RETURN_NONE;
269 }
270
271
272 /* Implementation of gdb.Frame.function (self) -> gdb.Symbol.
273    Returns the symbol for the function corresponding to this frame.  */
274
275 static PyObject *
276 frapy_function (PyObject *self, PyObject *args)
277 {
278   struct symbol *sym = NULL;
279   struct frame_info *frame;
280   volatile struct gdb_exception except;
281
282   TRY_CATCH (except, RETURN_MASK_ALL)
283     {
284       FRAPY_REQUIRE_VALID (self, frame);
285
286       sym = find_pc_function (get_frame_address_in_block (frame));
287     }
288   GDB_PY_HANDLE_EXCEPTION (except);
289
290   if (sym)
291     return symbol_to_symbol_object (sym);
292
293   Py_RETURN_NONE;
294 }
295
296 /* Convert a frame_info struct to a Python Frame object.
297    Sets a Python exception and returns NULL on error.  */
298
299 PyObject *
300 frame_info_to_frame_object (struct frame_info *frame)
301 {
302   frame_object *frame_obj;
303   volatile struct gdb_exception except;
304
305   frame_obj = PyObject_New (frame_object, &frame_object_type);
306   if (frame_obj == NULL)
307     {
308       PyErr_SetString (PyExc_MemoryError, 
309                        _("Could not allocate frame object."));
310       return NULL;
311     }
312
313   TRY_CATCH (except, RETURN_MASK_ALL)
314     {
315
316       /* Try to get the previous frame, to determine if this is the last frame
317          in a corrupt stack.  If so, we need to store the frame_id of the next
318          frame and not of this one (which is possibly invalid).  */
319       if (get_prev_frame (frame) == NULL
320           && get_frame_unwind_stop_reason (frame) != UNWIND_NO_REASON
321           && get_next_frame (frame) != NULL)
322         {
323           frame_obj->frame_id = get_frame_id (get_next_frame (frame));
324           frame_obj->frame_id_is_next = 1;
325         }
326       else
327         {
328           frame_obj->frame_id = get_frame_id (frame);
329           frame_obj->frame_id_is_next = 0;
330         }
331       frame_obj->gdbarch = get_frame_arch (frame);
332     }
333   GDB_PY_HANDLE_EXCEPTION (except);
334
335   return (PyObject *) frame_obj;
336 }
337
338 /* Implementation of gdb.Frame.older (self) -> gdb.Frame.
339    Returns the frame immediately older (outer) to this frame, or None if
340    there isn't one.  */
341
342 static PyObject *
343 frapy_older (PyObject *self, PyObject *args)
344 {
345   struct frame_info *frame, *prev;
346   volatile struct gdb_exception except;
347   PyObject *prev_obj = NULL;   /* Initialize to appease gcc warning.  */
348
349   TRY_CATCH (except, RETURN_MASK_ALL)
350     {
351       FRAPY_REQUIRE_VALID (self, frame);
352
353       prev = get_prev_frame (frame);
354       if (prev)
355         prev_obj = (PyObject *) frame_info_to_frame_object (prev);
356       else
357         {
358           Py_INCREF (Py_None);
359           prev_obj = Py_None;
360         }
361     }
362   GDB_PY_HANDLE_EXCEPTION (except);
363
364   return prev_obj;
365 }
366
367 /* Implementation of gdb.Frame.newer (self) -> gdb.Frame.
368    Returns the frame immediately newer (inner) to this frame, or None if
369    there isn't one.  */
370
371 static PyObject *
372 frapy_newer (PyObject *self, PyObject *args)
373 {
374   struct frame_info *frame, *next;
375   volatile struct gdb_exception except;
376   PyObject *next_obj = NULL;   /* Initialize to appease gcc warning.  */
377
378   TRY_CATCH (except, RETURN_MASK_ALL)
379     {
380       FRAPY_REQUIRE_VALID (self, frame);
381
382       next = get_next_frame (frame);
383       if (next)
384         next_obj = (PyObject *) frame_info_to_frame_object (next);
385       else
386         {
387           Py_INCREF (Py_None);
388           next_obj = Py_None;
389         }
390     }
391   GDB_PY_HANDLE_EXCEPTION (except);
392
393   return next_obj;
394 }
395
396 /* Implementation of gdb.Frame.find_sal (self) -> gdb.Symtab_and_line.
397    Returns the frame's symtab and line.  */
398
399 static PyObject *
400 frapy_find_sal (PyObject *self, PyObject *args)
401 {
402   struct frame_info *frame;
403   struct symtab_and_line sal;
404   volatile struct gdb_exception except;
405   PyObject *sal_obj = NULL;   /* Initialize to appease gcc warning.  */
406
407   TRY_CATCH (except, RETURN_MASK_ALL)
408     {
409       FRAPY_REQUIRE_VALID (self, frame);
410
411       find_frame_sal (frame, &sal);
412       sal_obj = symtab_and_line_to_sal_object (sal);
413     }
414   GDB_PY_HANDLE_EXCEPTION (except);
415
416   return sal_obj;
417 }
418
419 /* Implementation of gdb.Frame.read_var_value (self, variable,
420    [block]) -> gdb.Value.  If the optional block argument is provided
421    start the search from that block, otherwise search from the frame's
422    current block (determined by examining the resume address of the
423    frame).  The variable argument must be a string or an instance of a
424    gdb.Symbol.  The block argument must be an instance of gdb.Block.  Returns
425    NULL on error, with a python exception set.  */
426 static PyObject *
427 frapy_read_var (PyObject *self, PyObject *args)
428 {
429   struct frame_info *frame;
430   PyObject *sym_obj, *block_obj = NULL;
431   struct symbol *var = NULL;    /* gcc-4.3.2 false warning.  */
432   struct value *val = NULL;
433   volatile struct gdb_exception except;
434
435   if (!PyArg_ParseTuple (args, "O|O", &sym_obj, &block_obj))
436     return NULL;
437
438   if (PyObject_TypeCheck (sym_obj, &symbol_object_type))
439     var = symbol_object_to_symbol (sym_obj);
440   else if (gdbpy_is_string (sym_obj))
441     {
442       char *var_name;
443       const struct block *block = NULL;
444       struct cleanup *cleanup;
445       volatile struct gdb_exception except;
446
447       var_name = python_string_to_target_string (sym_obj);
448       if (!var_name)
449         return NULL;
450       cleanup = make_cleanup (xfree, var_name);
451
452       if (block_obj)
453         {
454           block = block_object_to_block (block_obj);
455           if (!block)
456             {
457               PyErr_SetString (PyExc_RuntimeError,
458                                _("Second argument must be block."));
459               return NULL;
460             }
461         }
462
463       TRY_CATCH (except, RETURN_MASK_ALL)
464         {
465           FRAPY_REQUIRE_VALID (self, frame);
466
467           if (!block)
468             block = get_frame_block (frame, NULL);
469           var = lookup_symbol (var_name, block, VAR_DOMAIN, NULL);
470         }
471       GDB_PY_HANDLE_EXCEPTION (except);
472
473       if (!var)
474         {
475           PyErr_Format (PyExc_ValueError,
476                         _("Variable '%s' not found."), var_name);
477           do_cleanups (cleanup);
478
479           return NULL;
480         }
481
482       do_cleanups (cleanup);
483     }
484   else
485     {
486       PyErr_SetString (PyExc_TypeError,
487                        _("Argument must be a symbol or string."));
488       return NULL;
489     }
490
491   TRY_CATCH (except, RETURN_MASK_ALL)
492     {
493       FRAPY_REQUIRE_VALID (self, frame);
494
495       val = read_var_value (var, frame);
496     }
497   GDB_PY_HANDLE_EXCEPTION (except);
498
499   return value_to_value_object (val);
500 }
501
502 /* Select this frame.  */
503
504 static PyObject *
505 frapy_select (PyObject *self, PyObject *args)
506 {
507   struct frame_info *fi;
508   volatile struct gdb_exception except;
509
510   TRY_CATCH (except, RETURN_MASK_ALL)
511     {
512       FRAPY_REQUIRE_VALID (self, fi);
513
514       select_frame (fi);
515     }
516   GDB_PY_HANDLE_EXCEPTION (except);
517
518   Py_RETURN_NONE;
519 }
520
521 /* Implementation of gdb.newest_frame () -> gdb.Frame.
522    Returns the newest frame object.  */
523
524 PyObject *
525 gdbpy_newest_frame (PyObject *self, PyObject *args)
526 {
527   struct frame_info *frame;
528   PyObject *frame_obj = NULL;   /* Initialize to appease gcc warning.  */
529   volatile struct gdb_exception except;
530
531   TRY_CATCH (except, RETURN_MASK_ALL)
532     {
533       frame = get_current_frame ();
534       frame_obj = frame_info_to_frame_object (frame);
535     }
536   GDB_PY_HANDLE_EXCEPTION (except);
537
538   return frame_obj;
539 }
540
541 /* Implementation of gdb.selected_frame () -> gdb.Frame.
542    Returns the selected frame object.  */
543
544 PyObject *
545 gdbpy_selected_frame (PyObject *self, PyObject *args)
546 {
547   struct frame_info *frame;
548   PyObject *frame_obj = NULL;   /* Initialize to appease gcc warning.  */
549   volatile struct gdb_exception except;
550
551   TRY_CATCH (except, RETURN_MASK_ALL)
552     {
553       frame = get_selected_frame ("No frame is currently selected.");
554       frame_obj = frame_info_to_frame_object (frame);
555     }
556   GDB_PY_HANDLE_EXCEPTION (except);
557
558   return frame_obj;
559 }
560
561 /* Implementation of gdb.stop_reason_string (Integer) -> String.
562    Return a string explaining the unwind stop reason.  */
563
564 PyObject *
565 gdbpy_frame_stop_reason_string (PyObject *self, PyObject *args)
566 {
567   int reason;
568   const char *str;
569
570   if (!PyArg_ParseTuple (args, "i", &reason))
571     return NULL;
572
573   if (reason < UNWIND_FIRST || reason > UNWIND_LAST)
574     {
575       PyErr_SetString (PyExc_ValueError, 
576                        _("Invalid frame stop reason."));
577       return NULL;
578     }
579
580   str = frame_stop_reason_string (reason);
581   return PyUnicode_Decode (str, strlen (str), host_charset (), NULL);
582 }
583
584 /* Implements the equality comparison for Frame objects.
585    All other comparison operators will throw a TypeError Python exception,
586    as they aren't valid for frames.  */
587
588 static PyObject *
589 frapy_richcompare (PyObject *self, PyObject *other, int op)
590 {
591   int result;
592
593   if (!PyObject_TypeCheck (other, &frame_object_type)
594       || (op != Py_EQ && op != Py_NE))
595     {
596       Py_INCREF (Py_NotImplemented);
597       return Py_NotImplemented;
598     }
599
600   if (frame_id_eq (((frame_object *) self)->frame_id,
601                    ((frame_object *) other)->frame_id))
602     result = Py_EQ;
603   else
604     result = Py_NE;
605
606   if (op == result)
607     Py_RETURN_TRUE;
608   Py_RETURN_FALSE;
609 }
610
611 /* Sets up the Frame API in the gdb module.  */
612
613 void
614 gdbpy_initialize_frames (void)
615 {
616   frame_object_type.tp_new = PyType_GenericNew;
617   if (PyType_Ready (&frame_object_type) < 0)
618     return;
619
620   /* Note: These would probably be best exposed as class attributes of
621      Frame, but I don't know how to do it except by messing with the
622      type's dictionary.  That seems too messy.  */
623   PyModule_AddIntConstant (gdb_module, "NORMAL_FRAME", NORMAL_FRAME);
624   PyModule_AddIntConstant (gdb_module, "DUMMY_FRAME", DUMMY_FRAME);
625   PyModule_AddIntConstant (gdb_module, "INLINE_FRAME", INLINE_FRAME);
626   PyModule_AddIntConstant (gdb_module, "TAILCALL_FRAME", TAILCALL_FRAME);
627   PyModule_AddIntConstant (gdb_module, "SIGTRAMP_FRAME", SIGTRAMP_FRAME);
628   PyModule_AddIntConstant (gdb_module, "ARCH_FRAME", ARCH_FRAME);
629   PyModule_AddIntConstant (gdb_module, "SENTINEL_FRAME", SENTINEL_FRAME);
630
631 #define SET(name, description) \
632   PyModule_AddIntConstant (gdb_module, "FRAME_"#name, name);
633 #define FIRST_ERROR(name) \
634   PyModule_AddIntConstant (gdb_module, "FRAME_"#name, name);
635 #include "unwind_stop_reasons.def"
636 #undef SET
637
638   Py_INCREF (&frame_object_type);
639   PyModule_AddObject (gdb_module, "Frame", (PyObject *) &frame_object_type);
640 }
641
642 \f
643
644 static PyMethodDef frame_object_methods[] = {
645   { "is_valid", frapy_is_valid, METH_NOARGS,
646     "is_valid () -> Boolean.\n\
647 Return true if this frame is valid, false if not." },
648   { "name", frapy_name, METH_NOARGS,
649     "name () -> String.\n\
650 Return the function name of the frame, or None if it can't be determined." },
651   { "type", frapy_type, METH_NOARGS,
652     "type () -> Integer.\n\
653 Return the type of the frame." },
654   { "architecture", frapy_arch, METH_NOARGS,
655     "architecture () -> gdb.Architecture.\n\
656 Return the architecture of the frame." },
657   { "unwind_stop_reason", frapy_unwind_stop_reason, METH_NOARGS,
658     "unwind_stop_reason () -> Integer.\n\
659 Return the reason why it's not possible to find frames older than this." },
660   { "pc", frapy_pc, METH_NOARGS,
661     "pc () -> Long.\n\
662 Return the frame's resume address." },
663   { "block", frapy_block, METH_NOARGS,
664     "block () -> gdb.Block.\n\
665 Return the frame's code block." },
666   { "function", frapy_function, METH_NOARGS,
667     "function () -> gdb.Symbol.\n\
668 Returns the symbol for the function corresponding to this frame." },
669   { "older", frapy_older, METH_NOARGS,
670     "older () -> gdb.Frame.\n\
671 Return the frame that called this frame." },
672   { "newer", frapy_newer, METH_NOARGS,
673     "newer () -> gdb.Frame.\n\
674 Return the frame called by this frame." },
675   { "find_sal", frapy_find_sal, METH_NOARGS,
676     "find_sal () -> gdb.Symtab_and_line.\n\
677 Return the frame's symtab and line." },
678   { "read_var", frapy_read_var, METH_VARARGS,
679     "read_var (variable) -> gdb.Value.\n\
680 Return the value of the variable in this frame." },
681   { "select", frapy_select, METH_NOARGS,
682     "Select this frame as the user's current frame." },
683   {NULL}  /* Sentinel */
684 };
685
686 PyTypeObject frame_object_type = {
687   PyVarObject_HEAD_INIT (NULL, 0)
688   "gdb.Frame",                    /* tp_name */
689   sizeof (frame_object),          /* tp_basicsize */
690   0,                              /* tp_itemsize */
691   0,                              /* tp_dealloc */
692   0,                              /* tp_print */
693   0,                              /* tp_getattr */
694   0,                              /* tp_setattr */
695   0,                              /* tp_compare */
696   0,                              /* tp_repr */
697   0,                              /* tp_as_number */
698   0,                              /* tp_as_sequence */
699   0,                              /* tp_as_mapping */
700   0,                              /* tp_hash  */
701   0,                              /* tp_call */
702   frapy_str,                      /* tp_str */
703   0,                              /* tp_getattro */
704   0,                              /* tp_setattro */
705   0,                              /* tp_as_buffer */
706   Py_TPFLAGS_DEFAULT,             /* tp_flags */
707   "GDB frame object",             /* tp_doc */
708   0,                              /* tp_traverse */
709   0,                              /* tp_clear */
710   frapy_richcompare,              /* tp_richcompare */
711   0,                              /* tp_weaklistoffset */
712   0,                              /* tp_iter */
713   0,                              /* tp_iternext */
714   frame_object_methods,           /* tp_methods */
715   0,                              /* tp_members */
716   0,                              /* tp_getset */
717   0,                              /* tp_base */
718   0,                              /* tp_dict */
719   0,                              /* tp_descr_get */
720   0,                              /* tp_descr_set */
721   0,                              /* tp_dictoffset */
722   0,                              /* tp_init */
723   0,                              /* tp_alloc */
724 };