Skip to content

Commit 70ad68e

Browse files
author
guido
committed
* bltinmodule.c: added built-in function cmp(a, b)
* flmodule.c: added {do,check}_only_forms to fl's list of functions; and don't print a message when an unknown object is returned. * pythonrun.c: catch SIGHUP and SIGTERM to do essential cleanup. * Made jpegmodule.c smaller by using getargs() and mkvalue() consistently. * Increased parser stack size to 500 in parser.h. * Implemented custom allocation of stack frames to frameobject.c and added dynamic stack overflow checks (value stack only) to ceval.c. (There seems to be a bug left: sometimes stack traces don't make sense.) git-svn-id: http://svn.python.org/projects/python/trunk@3243 6015fed2-1504-0410-9fe1-9d1591cc4771
1 parent 4e1c5b2 commit 70ad68e

7 files changed

Lines changed: 150 additions & 19 deletions

File tree

Include/frameobject.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,7 @@ frameobject * newframeobject PROTO(
8181

8282
void setup_block PROTO((frameobject *, int, int, int));
8383
block *pop_block PROTO((frameobject *));
84+
85+
/* Extend the value stack */
86+
87+
object **extend_stack PROTO((frameobject *, int, int));

Modules/flmodule.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2078,10 +2078,7 @@ forms_do_or_check_forms(dummy, args, func)
20782078
}
20792079
g = findgeneric(generic);
20802080
if (g == NULL) {
2081-
/* XXX What kind of weird object is this? */
2082-
/* XXX Maybe caused by a bug here */
2083-
fprintf(stderr, "weird object: class %d, label '%s'\n",
2084-
generic->objclass, generic->label);
2081+
/* Object not known to us (some dialogs cause this) */
20852082
continue; /* Ignore it */
20862083
}
20872084
if (g->ob_callback == NULL) {
@@ -2572,7 +2569,9 @@ static struct methodlist forms_methods[] = {
25722569
{"getmcolor", forms_getmcolor},
25732570
/* interaction */
25742571
{"do_forms", forms_do_forms},
2572+
{"do_only_forms", forms_do_only_forms},
25752573
{"check_forms", forms_check_forms},
2574+
{"check_only_forms", forms_check_only_forms},
25762575
{"set_event_call_back", forms_set_event_call_back},
25772576
/* goodies */
25782577
{"show_message", forms_show_message},

Objects/frameobject.c

Lines changed: 65 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,29 @@ frame_getattr(f, name)
5151
return getmember((char *)f, frame_memberlist, name);
5252
}
5353

54+
/* Stack frames are allocated and deallocated at a considerable rate.
55+
In an attempt to improve the speed of function calls, we maintain a
56+
separate free list of stack frames (just like integers are
57+
allocated in a special way -- see intobject.c). When a stack frame
58+
is on the free list, only the following members have a meaning:
59+
ob_type == &Frametype
60+
f_back next item on free list, or NULL
61+
f_nvalues size of f_valuestack
62+
f_valuestack array of (f_nvalues+1) object pointers, or NULL
63+
f_nblocks size of f_blockstack
64+
f_blockstack array of (f_nblocks+1) blocks, or NULL
65+
Note that the value and block stacks are preserved -- this can save
66+
another malloc() call or two (and two free() calls as well!).
67+
Also note that, unlike for integers, each frame object is a
68+
malloc'ed object in its own right -- it is only the actual calls to
69+
malloc() that we are trying to save here, not the administration.
70+
After all, while a typical program may make millions of calls, a
71+
call depth of more than 20 or 30 is probably already exceptional
72+
unless the program contains run-away recursion. I hope.
73+
*/
74+
75+
static frameobject *free_list = NULL;
76+
5477
static void
5578
frame_dealloc(f)
5679
frameobject *f;
@@ -59,9 +82,8 @@ frame_dealloc(f)
5982
XDECREF(f->f_code);
6083
XDECREF(f->f_globals);
6184
XDECREF(f->f_locals);
62-
XDEL(f->f_valuestack);
63-
XDEL(f->f_blockstack);
64-
DEL(f);
85+
f->f_back = free_list;
86+
free_list = f;
6587
}
6688

6789
typeobject Frametype = {
@@ -99,7 +121,17 @@ newframeobject(back, code, globals, locals, nvalues, nblocks)
99121
err_badcall();
100122
return NULL;
101123
}
102-
f = NEWOBJ(frameobject, &Frametype);
124+
if (free_list == NULL) {
125+
f = NEWOBJ(frameobject, &Frametype);
126+
f->f_nvalues = f->f_nblocks = 0;
127+
f->f_valuestack = NULL;
128+
f->f_blockstack = NULL;
129+
}
130+
else {
131+
f = free_list;
132+
free_list = free_list->f_back;
133+
NEWREF(f);
134+
}
103135
if (f != NULL) {
104136
if (back)
105137
INCREF(back);
@@ -110,22 +142,45 @@ newframeobject(back, code, globals, locals, nvalues, nblocks)
110142
f->f_globals = globals;
111143
INCREF(locals);
112144
f->f_locals = locals;
113-
f->f_valuestack = NEW(object *, nvalues+1);
114-
f->f_blockstack = NEW(block, nblocks+1);
115-
f->f_nvalues = nvalues;
116-
f->f_nblocks = nblocks;
145+
if (nvalues > f->f_nvalues || f->f_valuestack == NULL) {
146+
XDEL(f->f_valuestack);
147+
f->f_valuestack = NEW(object *, nvalues+1);
148+
f->f_nvalues = nvalues;
149+
}
150+
if (nblocks > f->f_nblocks || f->f_blockstack == NULL) {
151+
XDEL(f->f_blockstack);
152+
f->f_blockstack = NEW(block, nblocks+1);
153+
f->f_nblocks = nblocks;
154+
}
117155
f->f_iblock = 0;
156+
f->f_lasti = 0;
157+
f->f_lineno = -1;
118158
if (f->f_valuestack == NULL || f->f_blockstack == NULL) {
119159
err_nomem();
120160
DECREF(f);
121161
f = NULL;
122162
}
123-
f->f_lasti = 0;
124-
f->f_lineno = -1;
125163
}
126164
return f;
127165
}
128166

167+
object **
168+
extend_stack(f, level, incr)
169+
frameobject *f;
170+
int level;
171+
int incr;
172+
{
173+
f->f_nvalues = level + incr + 10;
174+
f->f_valuestack =
175+
(object **) realloc((ANY *)f->f_valuestack,
176+
sizeof(object *) * (f->f_nvalues + 1));
177+
if (f->f_valuestack == NULL) {
178+
err_nomem();
179+
return NULL;
180+
}
181+
return f->f_valuestack + level;
182+
}
183+
129184
/* Block management */
130185

131186
void

Parser/parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2424

2525
/* Parser interface */
2626

27-
#define MAXSTACK 100
27+
#define MAXSTACK 500
2828

2929
typedef struct _stackentry {
3030
int s_state; /* State in current DFA */

Python/bltinmodule.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,17 @@ builtin_chr(self, args)
7777
return newsizedstringobject(s, 1);
7878
}
7979

80+
static object *
81+
builtin_cmp(self, args)
82+
object *self;
83+
object *args;
84+
{
85+
object *a, *b;
86+
if (!getargs(args, "(OO)", &a, &b))
87+
return NULL;
88+
return newintobject((long)cmpobject(a, b));
89+
}
90+
8091
static object *
8192
builtin_coerce(self, args)
8293
object *self;
@@ -608,6 +619,7 @@ static struct methodlist builtin_methods[] = {
608619
{"abs", builtin_abs},
609620
{"apply", builtin_apply},
610621
{"chr", builtin_chr},
622+
{"cmp", builtin_cmp},
611623
{"coerce", builtin_coerce},
612624
{"dir", builtin_dir},
613625
{"divmod", builtin_divmod},

Python/ceval.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,9 @@ eval_code(co, globals, locals, arg)
204204
#define BASIC_PUSH(v) (*stack_pointer++ = (v))
205205
#define BASIC_POP() (*--stack_pointer)
206206

207+
#define CHECK_STACK(n) (STACK_LEVEL() + (n) < f->f_nvalues || \
208+
(stack_pointer = extend_stack(f, STACK_LEVEL(), n)))
209+
207210
#ifdef LLTRACE
208211
#define PUSH(v) (BASIC_PUSH(v), lltrace && prtrace(TOP(), "push"))
209212
#define POP() (lltrace && prtrace(TOP(), "pop"), BASIC_POP())
@@ -324,6 +327,11 @@ eval_code(co, globals, locals, arg)
324327
}
325328
#endif
326329

330+
if (!CHECK_STACK(3)) {
331+
x = NULL;
332+
break;
333+
}
334+
327335
/* Main switch on opcode */
328336

329337
switch (opcode) {
@@ -763,6 +771,10 @@ eval_code(co, globals, locals, arg)
763771
x = gettupleslice(v, oparg, gettuplesize(v));
764772
if (x != NULL) {
765773
PUSH(x);
774+
if (!CHECK_STACK(oparg)) {
775+
x = NULL;
776+
break;
777+
}
766778
for (; --oparg >= 0; ) {
767779
w = gettupleitem(v, oparg);
768780
INCREF(w);
@@ -858,6 +870,10 @@ eval_code(co, globals, locals, arg)
858870
why = WHY_EXCEPTION;
859871
}
860872
else {
873+
if (!CHECK_STACK(oparg)) {
874+
x = NULL;
875+
break;
876+
}
861877
for (; --oparg >= 0; ) {
862878
w = gettupleitem(v, oparg);
863879
INCREF(w);
@@ -879,6 +895,10 @@ eval_code(co, globals, locals, arg)
879895
why = WHY_EXCEPTION;
880896
}
881897
else {
898+
if (!CHECK_STACK(oparg)) {
899+
x = NULL;
900+
break;
901+
}
882902
for (; --oparg >= 0; ) {
883903
w = getlistitem(v, oparg);
884904
INCREF(w);

Python/pythonrun.c

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,21 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3838
#include "pythonrun.h"
3939
#include "import.h"
4040

41+
#ifdef unix
42+
#define HANDLE_SIGNALS
43+
#endif
44+
45+
#ifdef HANDLE_SIGNALS
46+
#include <signal.h>
47+
#include "sigtype.h"
48+
#endif
49+
4150
extern char *getpythonpath();
4251

4352
extern grammar gram; /* From graminit.c */
4453

54+
void initsigs(); /* Forward */
55+
4556
int debugging; /* Needed by parser.c */
4657
int verbose; /* Needed by import.c */
4758

@@ -67,10 +78,10 @@ initall()
6778
initsys();
6879

6980
initcalls(); /* Configuration-dependent initializations */
70-
71-
initintr(); /* For intrcheck() */
7281

7382
setpythonpath(getpythonpath());
83+
84+
initsigs(); /* Signal handling stuff, including initintr() */
7485
}
7586

7687
/* Parse input from a file and execute it */
@@ -372,8 +383,7 @@ extern int threads_started;
372383
#endif
373384

374385
void
375-
goaway(sts)
376-
int sts;
386+
cleanup()
377387
{
378388
object *exitfunc = sysget("exitfunc");
379389

@@ -395,6 +405,13 @@ goaway(sts)
395405
}
396406

397407
flushline();
408+
}
409+
410+
void
411+
goaway(sts)
412+
int sts;
413+
{
414+
cleanup();
398415

399416
#ifdef USE_THREAD
400417

@@ -433,6 +450,30 @@ goaway(sts)
433450
/*NOTREACHED*/
434451
}
435452

453+
#ifdef HANDLE_SIGNALS
454+
SIGTYPE
455+
sighandler(sig)
456+
int sig;
457+
{
458+
signal(sig, SIG_DFL); /* Don't catch recursive signals */
459+
cleanup(); /* Do essential clean-up */
460+
kill(getpid(), sig); /* Pretend the signal killed us */
461+
/*NOTREACHED*/
462+
}
463+
#endif
464+
465+
void
466+
initsigs()
467+
{
468+
initintr();
469+
#ifdef HANDLE_SIGNALS
470+
if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
471+
signal(SIGHUP, sighandler);
472+
if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
473+
signal(SIGTERM, sighandler);
474+
#endif
475+
}
476+
436477
#ifdef TRACE_REFS
437478
/* Ask a yes/no question */
438479

0 commit comments

Comments
 (0)