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;