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;