blob: 6da3929ee5bb64b3f3baf0868c91620ead00a2d4 [file] [log] [blame]
Guido van Rossum3f5da241990-12-20 15:06:42 +00001/* Frame object implementation */
2
3#include "allobjects.h"
4
5#include "compile.h"
6#include "frameobject.h"
7#include "opcode.h"
8#include "structmember.h"
9
10#define OFF(x) offsetof(frameobject, x)
11
12static struct memberlist frame_memberlist[] = {
13 {"f_back", T_OBJECT, OFF(f_back)},
14 {"f_code", T_OBJECT, OFF(f_code)},
15 {"f_globals", T_OBJECT, OFF(f_globals)},
16 {"f_locals", T_OBJECT, OFF(f_locals)},
17 {NULL} /* Sentinel */
18};
19
20static object *
21frame_getattr(f, name)
22 frameobject *f;
23 char *name;
24{
25 return getmember((char *)f, frame_memberlist, name);
26}
27
28static void
29frame_dealloc(f)
30 frameobject *f;
31{
32 XDECREF(f->f_back);
33 XDECREF(f->f_code);
34 XDECREF(f->f_globals);
35 XDECREF(f->f_locals);
36 XDEL(f->f_valuestack);
37 XDEL(f->f_blockstack);
38 DEL(f);
39}
40
41typeobject Frametype = {
42 OB_HEAD_INIT(&Typetype)
43 0,
44 "frame",
45 sizeof(frameobject),
46 0,
47 frame_dealloc, /*tp_dealloc*/
48 0, /*tp_print*/
49 frame_getattr, /*tp_getattr*/
50 0, /*tp_setattr*/
51 0, /*tp_compare*/
52 0, /*tp_repr*/
53 0, /*tp_as_number*/
54 0, /*tp_as_sequence*/
55 0, /*tp_as_mapping*/
56};
57
58frameobject *
59newframeobject(back, code, globals, locals, nvalues, nblocks)
60 frameobject *back;
61 codeobject *code;
62 object *globals;
63 object *locals;
64 int nvalues;
65 int nblocks;
66{
67 frameobject *f;
68 if ((back != NULL && !is_frameobject(back)) ||
69 code == NULL || !is_codeobject(code) ||
70 globals == NULL || !is_dictobject(globals) ||
71 locals == NULL || !is_dictobject(locals) ||
72 nvalues < 0 || nblocks < 0) {
73 err_badcall();
74 return NULL;
75 }
76 f = NEWOBJ(frameobject, &Frametype);
77 if (f != NULL) {
78 if (back)
79 INCREF(back);
80 f->f_back = back;
81 INCREF(code);
82 f->f_code = code;
83 INCREF(globals);
84 f->f_globals = globals;
85 INCREF(locals);
86 f->f_locals = locals;
87 f->f_valuestack = NEW(object *, nvalues+1);
88 f->f_blockstack = NEW(block, nblocks+1);
89 f->f_nvalues = nvalues;
90 f->f_nblocks = nblocks;
91 f->f_iblock = 0;
92 if (f->f_valuestack == NULL || f->f_blockstack == NULL) {
93 err_nomem();
94 DECREF(f);
95 f = NULL;
96 }
97 }
98 return f;
99}
100
101/* Block management */
102
103void
104setup_block(f, type, handler, level)
105 frameobject *f;
106 int type;
107 int handler;
108 int level;
109{
110 block *b;
111 if (f->f_iblock >= f->f_nblocks) {
112 fprintf(stderr, "XXX block stack overflow\n");
113 abort();
114 }
115 b = &f->f_blockstack[f->f_iblock++];
116 b->b_type = type;
117 b->b_level = level;
118 b->b_handler = handler;
119}
120
121block *
122pop_block(f)
123 frameobject *f;
124{
125 block *b;
126 if (f->f_iblock <= 0) {
127 fprintf(stderr, "XXX block stack underflow\n");
128 abort();
129 }
130 b = &f->f_blockstack[--f->f_iblock];
131 return b;
132}