]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
* bltinmodule.c: added built-in function cmp(a, b)
authorGuido van Rossum <guido@python.org>
Sun, 18 Oct 1992 18:53:57 +0000 (18:53 +0000)
committerGuido van Rossum <guido@python.org>
Sun, 18 Oct 1992 18:53:57 +0000 (18:53 +0000)
* 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.)

Include/frameobject.h
Modules/flmodule.c
Objects/frameobject.c
Parser/parser.h
Python/bltinmodule.c
Python/ceval.c
Python/pythonrun.c

index e1f819017ad2ca9890d1c52e83e45d75d7ee6aa6..dd36468ec166ea8bea3a7a3d9136a5c40394fc29 100644 (file)
@@ -81,3 +81,7 @@ frameobject * newframeobject PROTO(
 
 void setup_block PROTO((frameobject *, int, int, int));
 block *pop_block PROTO((frameobject *));
+
+/* Extend the value stack */
+
+object **extend_stack PROTO((frameobject *, int, int));
index 34f01218cdd71b27b430f92b90fb67b9d71a3450..dca39ad646b498056b5a2ff1dba5d42fc1aa229c 100644 (file)
@@ -2078,10 +2078,7 @@ forms_do_or_check_forms(dummy, args, func)
                }
                g = findgeneric(generic);
                if (g == NULL) {
-                       /* XXX What kind of weird object is this? */
-                       /* XXX Maybe caused by a bug here */
-                       fprintf(stderr, "weird object: class %d, label '%s'\n",
-                               generic->objclass, generic->label);
+                       /* Object not known to us (some dialogs cause this) */
                        continue; /* Ignore it */
                }
                if (g->ob_callback == NULL) {
@@ -2572,7 +2569,9 @@ static struct methodlist forms_methods[] = {
        {"getmcolor",           forms_getmcolor},
 /* interaction */
        {"do_forms",            forms_do_forms},
+       {"do_only_forms",       forms_do_only_forms},
        {"check_forms",         forms_check_forms},
+       {"check_only_forms",    forms_check_only_forms},
        {"set_event_call_back", forms_set_event_call_back},
 /* goodies */
        {"show_message",        forms_show_message},
index a68704ceedac0061ac23c2dc5365d3d04e53240b..c7b5ddf58ef7e64c56c22412b2c6a4a3094d0699 100644 (file)
@@ -51,6 +51,29 @@ frame_getattr(f, name)
        return getmember((char *)f, frame_memberlist, name);
 }
 
+/* Stack frames are allocated and deallocated at a considerable rate.
+   In an attempt to improve the speed of function calls, we maintain a
+   separate free list of stack frames (just like integers are
+   allocated in a special way -- see intobject.c).  When a stack frame
+   is on the free list, only the following members have a meaning:
+       ob_type         == &Frametype
+       f_back          next item on free list, or NULL
+       f_nvalues       size of f_valuestack
+       f_valuestack    array of (f_nvalues+1) object pointers, or NULL
+       f_nblocks       size of f_blockstack
+       f_blockstack    array of (f_nblocks+1) blocks, or NULL
+   Note that the value and block stacks are preserved -- this can save
+   another malloc() call or two (and two free() calls as well!).
+   Also note that, unlike for integers, each frame object is a
+   malloc'ed object in its own right -- it is only the actual calls to
+   malloc() that we are trying to save here, not the administration.
+   After all, while a typical program may make millions of calls, a
+   call depth of more than 20 or 30 is probably already exceptional
+   unless the program contains run-away recursion.  I hope.
+*/
+
+static frameobject *free_list = NULL;
+
 static void
 frame_dealloc(f)
        frameobject *f;
@@ -59,9 +82,8 @@ frame_dealloc(f)
        XDECREF(f->f_code);
        XDECREF(f->f_globals);
        XDECREF(f->f_locals);
-       XDEL(f->f_valuestack);
-       XDEL(f->f_blockstack);
-       DEL(f);
+       f->f_back = free_list;
+       free_list = f;
 }
 
 typeobject Frametype = {
@@ -99,7 +121,17 @@ newframeobject(back, code, globals, locals, nvalues, nblocks)
                err_badcall();
                return NULL;
        }
-       f = NEWOBJ(frameobject, &Frametype);
+       if (free_list == NULL) {
+               f = NEWOBJ(frameobject, &Frametype);
+               f->f_nvalues = f->f_nblocks = 0;
+               f->f_valuestack = NULL;
+               f->f_blockstack = NULL;
+       }
+       else {
+               f = free_list;
+               free_list = free_list->f_back;
+               NEWREF(f);
+       }
        if (f != NULL) {
                if (back)
                        INCREF(back);
@@ -110,22 +142,45 @@ newframeobject(back, code, globals, locals, nvalues, nblocks)
                f->f_globals = globals;
                INCREF(locals);
                f->f_locals = locals;
-               f->f_valuestack = NEW(object *, nvalues+1);
-               f->f_blockstack = NEW(block, nblocks+1);
-               f->f_nvalues = nvalues;
-               f->f_nblocks = nblocks;
+               if (nvalues > f->f_nvalues || f->f_valuestack == NULL) {
+                       XDEL(f->f_valuestack);
+                       f->f_valuestack = NEW(object *, nvalues+1);
+                       f->f_nvalues = nvalues;
+               }
+               if (nblocks > f->f_nblocks || f->f_blockstack == NULL) {
+                       XDEL(f->f_blockstack);
+                       f->f_blockstack = NEW(block, nblocks+1);
+                       f->f_nblocks = nblocks;
+               }
                f->f_iblock = 0;
+               f->f_lasti = 0;
+               f->f_lineno = -1;
                if (f->f_valuestack == NULL || f->f_blockstack == NULL) {
                        err_nomem();
                        DECREF(f);
                        f = NULL;
                }
-               f->f_lasti = 0;
-               f->f_lineno = -1;
        }
        return f;
 }
 
+object **
+extend_stack(f, level, incr)
+       frameobject *f;
+       int level;
+       int incr;
+{
+       f->f_nvalues = level + incr + 10;
+       f->f_valuestack =
+               (object **) realloc((ANY *)f->f_valuestack,
+                                   sizeof(object *) * (f->f_nvalues + 1));
+       if (f->f_valuestack == NULL) {
+               err_nomem();
+               return NULL;
+       }
+       return f->f_valuestack + level;
+}
+
 /* Block management */
 
 void
index 72aa9277f19ece86789955b43909eaa5ea4e7572..2c0e327e0e1b0dbdcaaed6c64cb289b5c8dd1c1e 100644 (file)
@@ -24,7 +24,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 /* Parser interface */
 
-#define MAXSTACK 100
+#define MAXSTACK 500
 
 typedef struct _stackentry {
        int              s_state;       /* State in current DFA */
index 9ba07af3a42752eaabbc0865edbb11d79338ae43..18fae5ca75e3f3b3a6e8fa49ec8fa2878997436c 100644 (file)
@@ -77,6 +77,17 @@ builtin_chr(self, args)
        return newsizedstringobject(s, 1);
 }
 
+static object *
+builtin_cmp(self, args)
+       object *self;
+       object *args;
+{
+       object *a, *b;
+       if (!getargs(args, "(OO)", &a, &b))
+               return NULL;
+       return newintobject((long)cmpobject(a, b));
+}
+
 static object *
 builtin_coerce(self, args)
        object *self;
@@ -608,6 +619,7 @@ static struct methodlist builtin_methods[] = {
        {"abs",         builtin_abs},
        {"apply",       builtin_apply},
        {"chr",         builtin_chr},
+       {"cmp",         builtin_cmp},
        {"coerce",      builtin_coerce},
        {"dir",         builtin_dir},
        {"divmod",      builtin_divmod},
index 4637d35f7efc58049115d4216764314ee5d99e29..d3a732a62ee880172173df3cf572484027d11e73 100644 (file)
@@ -204,6 +204,9 @@ eval_code(co, globals, locals, arg)
 #define BASIC_PUSH(v)  (*stack_pointer++ = (v))
 #define BASIC_POP()    (*--stack_pointer)
 
+#define CHECK_STACK(n) (STACK_LEVEL() + (n) < f->f_nvalues || \
+                         (stack_pointer = extend_stack(f, STACK_LEVEL(), n)))
+
 #ifdef LLTRACE
 #define PUSH(v)                (BASIC_PUSH(v), lltrace && prtrace(TOP(), "push"))
 #define POP()          (lltrace && prtrace(TOP(), "pop"), BASIC_POP())
@@ -324,6 +327,11 @@ eval_code(co, globals, locals, arg)
                }
 #endif
 
+               if (!CHECK_STACK(3)) {
+                       x = NULL;
+                       break;
+               }
+
                /* Main switch on opcode */
                
                switch (opcode) {
@@ -763,6 +771,10 @@ eval_code(co, globals, locals, arg)
                                x = gettupleslice(v, oparg, gettuplesize(v));
                                if (x != NULL) {
                                        PUSH(x);
+                                       if (!CHECK_STACK(oparg)) {
+                                               x = NULL;
+                                               break;
+                                       }
                                        for (; --oparg >= 0; ) {
                                                w = gettupleitem(v, oparg);
                                                INCREF(w);
@@ -858,6 +870,10 @@ eval_code(co, globals, locals, arg)
                                why = WHY_EXCEPTION;
                        }
                        else {
+                               if (!CHECK_STACK(oparg)) {
+                                       x = NULL;
+                                       break;
+                               }
                                for (; --oparg >= 0; ) {
                                        w = gettupleitem(v, oparg);
                                        INCREF(w);
@@ -879,6 +895,10 @@ eval_code(co, globals, locals, arg)
                                why = WHY_EXCEPTION;
                        }
                        else {
+                               if (!CHECK_STACK(oparg)) {
+                                       x = NULL;
+                                       break;
+                               }
                                for (; --oparg >= 0; ) {
                                        w = getlistitem(v, oparg);
                                        INCREF(w);
index 90a429408c00a93c682db21d2d0069c909403852..1bcc083b61a47750d7af9b7387ef797daad40f7d 100644 (file)
@@ -38,10 +38,21 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include "pythonrun.h"
 #include "import.h"
 
+#ifdef unix
+#define HANDLE_SIGNALS
+#endif
+
+#ifdef HANDLE_SIGNALS
+#include <signal.h>
+#include "sigtype.h"
+#endif
+
 extern char *getpythonpath();
 
 extern grammar gram; /* From graminit.c */
 
+void initsigs(); /* Forward */
+
 int debugging; /* Needed by parser.c */
 int verbose; /* Needed by import.c */
 
@@ -67,10 +78,10 @@ initall()
        initsys();
        
        initcalls(); /* Configuration-dependent initializations */
-       
-       initintr(); /* For intrcheck() */
 
        setpythonpath(getpythonpath());
+
+       initsigs(); /* Signal handling stuff, including initintr() */
 }
 
 /* Parse input from a file and execute it */
@@ -372,8 +383,7 @@ extern int threads_started;
 #endif
 
 void
-goaway(sts)
-       int sts;
+cleanup()
 {
        object *exitfunc = sysget("exitfunc");
 
@@ -395,6 +405,13 @@ goaway(sts)
        }
 
        flushline();
+}
+
+void
+goaway(sts)
+       int sts;
+{
+       cleanup();
 
 #ifdef USE_THREAD
 
@@ -433,6 +450,30 @@ goaway(sts)
        /*NOTREACHED*/
 }
 
+#ifdef HANDLE_SIGNALS
+SIGTYPE
+sighandler(sig)
+       int sig;
+{
+       signal(sig, SIG_DFL); /* Don't catch recursive signals */
+       cleanup(); /* Do essential clean-up */
+       kill(getpid(), sig); /* Pretend the signal killed us */
+       /*NOTREACHED*/
+}
+#endif
+
+void
+initsigs()
+{
+       initintr();
+#ifdef HANDLE_SIGNALS
+       if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
+               signal(SIGHUP, sighandler);
+       if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
+               signal(SIGTERM, sighandler);
+#endif
+}
+
 #ifdef TRACE_REFS
 /* Ask a yes/no question */