[PD-cvs] pd/src kernel.c,1.1.2.52,1.1.2.53

Mathieu Bouchard matju at users.sourceforge.net
Sun Jul 15 00:47:13 CEST 2007


Update of /cvsroot/pure-data/pd/src
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27844

Modified Files:
      Tag: desiredata
	kernel.c 
Log Message:
stack overflow detector now in inlets instead of outlets


Index: kernel.c
===================================================================
RCS file: /cvsroot/pure-data/pd/src/Attic/kernel.c,v
retrieving revision 1.1.2.52
retrieving revision 1.1.2.53
diff -C2 -d -r1.1.2.52 -r1.1.2.53
*** kernel.c	12 Jul 2007 19:29:45 -0000	1.1.2.52
--- kernel.c	14 Jul 2007 22:47:11 -0000	1.1.2.53
***************
*** 467,486 ****
  }
  
! void pd_bang(t_pd *x)                    {x->_class->bangmethod(x);}
! void pd_float(t_pd *x, t_float f)        {x->_class->floatmethod(x, f);}
! void pd_pointer(t_pd *x, t_gpointer *gp) {x->_class->pointermethod(x, gp);}
! void pd_symbol(t_pd *x, t_symbol *s)     {x->_class->symbolmethod(x, s);}
! void pd_list(t_pd *x, t_symbol *s, int ac, t_atom *av) {x->_class->listmethod(x, &s_list, ac, av);}
! 
! /* this file handles Max-style patchable objects, i.e., objects which
! can interconnect via inlets and outlets; also, the (terse) generic
! behavior for "gobjs" appears at the end of this file.  */
  
  /* T.Grill - define for a modified, more portable method to detect stack overflows */
  /* tb: threadsafe stack overflow detection */
! 
! #define ENTER STACK_INC; if(stackcount >= STACKITER) {outlet_stackerror(x); LEAVE; return;}
  #define LEAVE STACK_DEC;
- 
  #ifdef ATOMIC
  #include "m_atomic.h"
--- 467,476 ----
  }
  
! static void stackerror(t_pd *x) {pd_error(x,"stack overflow");}
  
  /* T.Grill - define for a modified, more portable method to detect stack overflows */
  /* tb: threadsafe stack overflow detection */
! #define ENTER STACK_INC; if(stackcount >= STACKITER) {stackerror(x); LEAVE; return;}
  #define LEAVE STACK_DEC;
  #ifdef ATOMIC
  #include "m_atomic.h"
***************
*** 493,496 ****
--- 483,503 ----
  /* tb: } */
  
+ /* T.Grill - count iterations rather than watch the stack pointer */
+ static int stackcount = 0; /* iteration counter */
+ #define STACKITER 1000 /* maximum iterations allowed */
+ 
+ /* matju's 2007.07.14 inlet-based stack check needs to be implemented in:
+      pd_bang pd_float pd_pointer pd_symbol pd_string pd_list pd_typedmess */
+ void pd_bang(t_pd *x)                    {ENTER; x->_class->bangmethod(x);       LEAVE;}
+ void pd_float(t_pd *x, t_float f)        {ENTER; x->_class->floatmethod(x,f);    LEAVE;}
+ void pd_pointer(t_pd *x, t_gpointer *gp) {ENTER; x->_class->pointermethod(x,gp); LEAVE;}
+ void pd_symbol(t_pd *x, t_symbol *s)     {ENTER; x->_class->symbolmethod(x,s);   LEAVE;}
+ /* void pd_string(t_pd *x, const char *s){ENTER; x->_class->stringmethod(x,s);   LEAVE;} future use */
+ void pd_list(t_pd *x, t_symbol *s, int ac, t_atom *av) {ENTER; x->_class->listmethod(x,&s_list,ac,av); LEAVE;}
+ 
+ /* this file handles Max-style patchable objects, i.e., objects which
+ can interconnect via inlets and outlets; also, the (terse) generic
+ behavior for "gobjs" appears at the end of this file.  */
+ 
  union inletunion {
      t_symbol *symto;
***************
*** 584,589 ****
  
  static void inlet_list(t_inlet *x, t_symbol *s, int argc, t_atom *argv) {
!     if (x->symfrom == &s_list || x->symfrom == &s_float
!         || x->symfrom == &s_symbol || x->symfrom == &s_pointer)
              typedmess(x->dest, x->u.symto, argc, argv);
      else if (!x->symfrom) pd_list(x->dest, s, argc, argv);
--- 591,595 ----
  
  static void inlet_list(t_inlet *x, t_symbol *s, int argc, t_atom *argv) {
!     if (x->symfrom == &s_list || x->symfrom == &s_float || x->symfrom == &s_symbol || x->symfrom == &s_pointer)
              typedmess(x->dest, x->u.symto, argc, argv);
      else if (!x->symfrom) pd_list(x->dest, s, argc, argv);
***************
*** 599,609 ****
  void inlet_free(t_inlet *x) {
      t_object *y = x->owner;
-     t_inlet *x2;
      if (y->inlet == x) y->inlet = x->next;
!     else for (x2 = y->inlet; x2; x2 = x2->next) if (x2->next == x) {
          x2->next = x->next;
          break;
      }
!     pd_free((t_pd *)x);
  }
  
--- 605,614 ----
  void inlet_free(t_inlet *x) {
      t_object *y = x->owner;
      if (y->inlet == x) y->inlet = x->next;
!     else for (t_inlet *x2 = y->inlet; x2; x2 = x2->next) if (x2->next == x) {
          x2->next = x->next;
          break;
      }
!     pd_free(x);
  }
  
***************
*** 677,684 ****
  /* --------------------------- outlets ------------------------------ */
  
- /* T.Grill - count iterations rather than watch the stack pointer */
- static int stackcount = 0; /* iteration counter */
- #define STACKITER 1000 /* maximum iterations allowed */
- 
  /* this is fairly obsolete stuff, I think */
  static int outlet_eventno;
--- 682,685 ----
***************
*** 726,751 ****
  }
  
- static void outlet_stackerror(t_outlet *x) {pd_error(x->owner, "stack overflow");}
- 
  #define each_connect(oc,x) for (t_outconnect *oc = x->connections; oc; oc = oc->next)
! void outlet_bang(t_outlet *x) {ENTER{
! 	each_connect(oc,x) pd_bang(oc->oc_to);
! }LEAVE}
! void outlet_pointer(t_outlet *x, t_gpointer *gp) {ENTER{
! 	t_gpointer gpointer = *gp;
!         each_connect(oc,x) pd_pointer(oc->oc_to, &gpointer);
! }LEAVE}
! void outlet_float(t_outlet *x, t_float f) {ENTER{
! 	each_connect(oc,x) pd_float(oc->oc_to, f);
! }LEAVE}
! void outlet_symbol(t_outlet *x, t_symbol *s) {ENTER{
! 	each_connect(oc,x) pd_symbol(oc->oc_to, s);
! }LEAVE}
! void outlet_list(t_outlet *x, t_symbol *s, int argc, t_atom *argv) {ENTER{
! 	each_connect(oc,x) pd_list(oc->oc_to, s, argc, argv);
! }LEAVE}
! void outlet_anything(t_outlet *x, t_symbol *s, int argc, t_atom *argv) {ENTER{
! 	each_connect(oc,x) typedmess(oc->oc_to, s, argc, argv);
! }LEAVE}
  
  /* get the outlet's declared symbol */
--- 727,737 ----
  }
  
  #define each_connect(oc,x) for (t_outconnect *oc = x->connections; oc; oc = oc->next)
! void outlet_bang(t_outlet *x)                                          {each_connect(oc,x) pd_bang(oc->oc_to);}
! void outlet_pointer(t_outlet *x, t_gpointer *gp) {t_gpointer gpointer = *gp; each_connect(oc,x) pd_pointer(oc->oc_to, &gpointer);}
! void outlet_float(t_outlet *x, t_float f)                              {each_connect(oc,x) pd_float(oc->oc_to, f);}
! void outlet_symbol(t_outlet *x, t_symbol *s)                           {each_connect(oc,x) pd_symbol(oc->oc_to, s);}
! void outlet_list(t_outlet *x, t_symbol *s, int argc, t_atom *argv)     {each_connect(oc,x) pd_list(  oc->oc_to,s,argc,argv);}
! void outlet_anything(t_outlet *x, t_symbol *s, int argc, t_atom *argv) {each_connect(oc,x) typedmess(oc->oc_to,s,argc,argv);}
  
  /* get the outlet's declared symbol */
***************
*** 803,807 ****
      if (oc->oc_to == i) {
          o->connections = oc->next;
!         pd_free((t_pd *)oc);
          goto done;
      }
--- 789,793 ----
      if (oc->oc_to == i) {
          o->connections = oc->next;
!         pd_free(oc);
          goto done;
      }
***************
*** 809,813 ****
          if (oc2->oc_to == i) {
              oc->next = oc2->next;
!             pd_free((t_pd *)oc2);
              goto done;
          }
--- 795,799 ----
          if (oc2->oc_to == i) {
              oc->next = oc2->next;
!             pd_free(oc2);
              goto done;
          }
***************
*** 1287,1297 ****
      pthread_mutex_lock(&hash_lock);
      /* tb: maybe another thread added the symbol to the hash table; double check */
!     while (sym2 = *sym1) 
!     {
!         if (!strcmp(sym2->name, s)) 
! 		{
! 			pthread_mutex_unlock(&hash_lock);
! 			return sym2;
! 		}
          sym1 = &sym2->next;
      }
--- 1273,1281 ----
      pthread_mutex_lock(&hash_lock);
      /* tb: maybe another thread added the symbol to the hash table; double check */
!     while (sym2 = *sym1) {
!         if (!strcmp(sym2->name, s)) {
! 	    pthread_mutex_unlock(&hash_lock);
! 	    return sym2;
! 	}
          sym1 = &sym2->next;
      }
***************
*** 1427,1442 ****
  #undef REST
  
! void pd_typedmess(t_pd *x, t_symbol *s, int argc, t_atom *argv) {
      t_class *c = x->_class;
      t_methodentry *m;
      t_atomtype *wp, wanttype;
-     int i;
      t_int ai[MAXPDARG+1], *ap = ai;
      t_floatarg ad[MAXPDARG+1], *dp = ad;
      int narg = 0;
!     t_pd *bonzo;
!     /* check for messages that are handled by fixed slots in the class
!        structure.  We don't catch "pointer" though so that sending "pointer"
!        to pd_objectmaker doesn't require that we supply a pointer value. */
      if (s == &s_float) {
          if (!argc) c->floatmethod(x, 0.);
--- 1411,1423 ----
  #undef REST
  
! void pd_typedmess_2(t_pd *x, t_symbol *s, int argc, t_atom *argv) {
      t_class *c = x->_class;
      t_methodentry *m;
      t_atomtype *wp, wanttype;
      t_int ai[MAXPDARG+1], *ap = ai;
      t_floatarg ad[MAXPDARG+1], *dp = ad;
      int narg = 0;
!     /* check for messages that are handled by fixed slots in the class structure.  We don't catch "pointer"
!        though so that sending "pointer" to pd_objectmaker doesn't require that we supply a pointer value. */
      if (s == &s_float) {
          if (!argc) c->floatmethod(x, 0.);
***************
*** 1447,1459 ****
      if (s == &s_bang) {c->bangmethod(x); return;}
      if (s == &s_list) {c->listmethod(x,s,argc,argv); return;}
!     if (s == &s_symbol) {
! 	c->symbolmethod(x, argc && argv->a_type==A_SYMBOL ? argv->a_symbol : &s_);
!         return;
!     }
!     for (i = c->nmethod, m = c->methods; i--; m++) if (m->me_name == s) {
          wp = m->me_arg;
          if (*wp == A_GIMME) {
!             if (x == &pd_objectmaker) pd_set_newest(((t_newgimme)(m->me_fun))(s, argc, argv));
!             else                                ((t_messgimme)(m->me_fun))(x, s, argc, argv);
              return;
          }
--- 1428,1438 ----
      if (s == &s_bang) {c->bangmethod(x); return;}
      if (s == &s_list) {c->listmethod(x,s,argc,argv); return;}
!     if (s == &s_symbol) {c->symbolmethod(x, argc && argv->a_type==A_SYMBOL ? argv->a_symbol : &s_); return;}
!     m = c->methods;
!     for (int i = c->nmethod; i--; m++) if (m->me_name == s) {
          wp = m->me_arg;
          if (*wp == A_GIMME) {
!             if (x == &pd_objectmaker) pd_set_newest(((t_newgimme)(m->me_fun))(  s,argc,argv));
!             else                                   ((t_messgimme)(m->me_fun))(x,s,argc,argv);
              return;
          }
***************
*** 1466,1470 ****
                  else {
                      if (argv->a_type!=A_POINTER) goto badarg;
!                     *ap = (t_int)(argv->a_gpointer);
                      argc--;
                      argv++;
--- 1445,1449 ----
                  else {
                      if (argv->a_type!=A_POINTER) goto badarg;
!                     *ap = t_int(argv->a_gpointer);
                      argc--;
                      argv++;
***************
*** 1488,1501 ****
                  if (!argc) goto badarg;
              case A_DEFSYM:
!                 if (!argc) *ap = (t_int)(&s_);
                  else {
                      if (argv->a_type == A_SYMBOL) *ap = (t_int)(argv->a_symbol);
!                     /* if it's an unfilled "dollar" argument it appears
!                        as zero here; cheat and bash it to the null
!                        symbol.  Unfortunately, this lets real zeros
!                        pass as symbols too, which seems wrong... */
                      else if (x == &pd_objectmaker && argv->a_type == A_FLOAT
                          && argv->a_float == 0)
!                         *ap = (t_int)(&s_);
                      else goto badarg;
                      argc--;
--- 1467,1478 ----
                  if (!argc) goto badarg;
              case A_DEFSYM:
!                 if (!argc) *ap = t_int(&s_);
                  else {
                      if (argv->a_type == A_SYMBOL) *ap = (t_int)(argv->a_symbol);
!                     /* if it's an unfilled "dollar" argument it appears as zero here; cheat and bash it to the null
!                        symbol.  Unfortunately, this lets real zeros pass as symbols too, which seems wrong... */
                      else if (x == &pd_objectmaker && argv->a_type == A_FLOAT
                          && argv->a_float == 0)
!                         *ap = t_int(&s_);
                      else goto badarg;
                      argc--;
***************
*** 1507,1510 ****
--- 1484,1488 ----
              }
          }
+         t_pd *bonzo;
          switch (narg) {
  #define REST ad[0],ad[1],ad[2],ad[3],ad[4]
***************
*** 1527,1530 ****
--- 1505,1512 ----
  }
  
+ void pd_typedmess(t_pd *x, t_symbol *s, int argc, t_atom *argv) {
+ 	ENTER; pd_typedmess_2(x,s,argc,argv); LEAVE;
+ }
+ 
  void pd_vmess(t_pd *x, t_symbol *sel, char *fmt, ...) {
      va_list ap;
***************
*** 1539,1545 ****
          }
          switch(*fp++) {
!         case 'f': SETFLOAT(at, va_arg(ap, double)); break;
!         case 's': SETSYMBOL(at, va_arg(ap, t_symbol *)); break;
!         case 'i': SETFLOAT(at, va_arg(ap, t_int)); break;
          case 'p': SETPOINTER(at, va_arg(ap, t_gpointer *)); break;
          default: goto done;
--- 1521,1527 ----
          }
          switch(*fp++) {
!         case 'f': SETFLOAT(at,   va_arg(ap, double)); break;
!         case 's': SETSYMBOL(at,  va_arg(ap, t_symbol *)); break;
!         case 'i': SETFLOAT(at,   va_arg(ap, t_int)); break;
          case 'p': SETPOINTER(at, va_arg(ap, t_gpointer *)); break;
          default: goto done;





More information about the Pd-cvs mailing list