Changeset 16

Show
Ignore:
Timestamp:
04/25/07 02:06:48 (2 years ago)
Author:
hines
Message:

arg type errors as well as many other things can cause a
hoc_execerror when python is executing a hoc function.
Hoc error recovery is quite different from python and a hoc
error ends in exiting the program due to a longjmp. When
python uses the hocobj_call mechanism, we arrange the
longjmp to return to a place where we can set a python exception and
a NULL return. This may have to be turn-offable by the user if
the OcJump? causes too great a performance hit.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/pygetsetcall/src/ivoc/ocjump.cpp

    r1 r16  
    6868        boolean execute(Inst* p); 
    6969        boolean execute(const char*, Object* ob = nil); 
     70        void* fpycall(void*(*f)(void*, void*), void* a, void* b); 
    7071 
    7172/* jmpbuf is not portable and I can't figure out how get a pointer to one. 
     
    140141} 
    141142 
     143void* OcJump::fpycall(void*(*f)(void*, void*), void* a, void* b) { 
     144        return impl_->fpycall(f, a, b); 
     145} 
     146 
    142147//------------------------------------------------------------------- 
    143148 
     
    191196        finish(); 
    192197        return true; 
     198} 
     199 
     200void* OcJumpImpl::fpycall(void*(*f)(void*, void*), void* a, void* b) { 
     201        void* c = 0; 
     202        begin(); 
     203#if 1 
     204        if (setjmp(begin_)) { 
     205                restore(); 
     206                finish(); 
     207                return c; 
     208        }else 
     209#endif 
     210        { 
     211                c = (*f)(a, b); 
     212        } 
     213        finish(); 
     214        return c; 
    193215} 
    194216 
  • branches/pygetsetcall/src/ivoc/ocjump.h

    r1 r16  
    2828        boolean execute(Inst* p); 
    2929        boolean execute(const char*, Object* ob = nil); 
     30        void* fpycall(void*(*)(void*, void*), void*, void*); 
    3031        static void save_context(ObjectContext*); 
    3132        static void restore_context(ObjectContext*); 
  • branches/pygetsetcall/src/nrnpython/nrnpy_hoc.cpp

    r15 r16  
    44#include <nrnoc2iv.h> 
    55#include <ivoc.h> 
     6#include <ocjump.h> 
    67 
    78extern "C" { 
     
    262263} 
    263264 
     265static void* fcall(void* vself, void* vargs) { 
     266        PyHocObject* self = (PyHocObject*)vself; 
     267        if (self->ho_) { 
     268                hoc_push_object(self->ho_); 
     269        } 
     270        int narg = hocobj_pushargs((PyObject*)vargs); 
     271        if (self->ho_) { 
     272                self->nindex_ = narg; 
     273                component(self); 
     274                return (void*)get_final_from_stk(); 
     275        } 
     276        if (self->sym_->type == BLTIN) { 
     277                assert(narg == 1); 
     278                double d = hoc_call_func(self->sym_, 1); 
     279                hoc_pushx(d); 
     280        }else{ 
     281                Inst fc[2]; 
     282                fc[0].sym = self->sym_; 
     283                fc[1].i = narg; 
     284                Inst* pcsav = save_pc(fc); 
     285                hoc_call(); 
     286                hoc_pc = pcsav; 
     287        } 
     288        return (void*)get_final_from_stk();; 
     289} 
     290 
    264291static PyObject* hocobj_call(PyHocObject* self, PyObject* args) { 
    265292        if (self->type_ == 0) { 
    266293                return nrnexec((PyObject*)self, args); 
    267294        }else if (self->type_ == 2) { 
    268                 if (self->ho_) { 
    269                         hoc_push_object(self->ho_); 
    270                 } 
    271                 int narg = hocobj_pushargs(args); 
    272                 if (self->ho_) { 
    273                         self->nindex_ = narg; 
    274                         component(self); 
    275                         return get_final_from_stk(); 
    276                 } 
    277                 if (self->sym_->type == BLTIN) { 
    278                         assert(narg == 1); 
    279                         double d = hoc_call_func(self->sym_, 1); 
    280                         hoc_pushx(d); 
    281                 }else{ 
    282                         Inst fc[2]; 
    283                         fc[0].sym = self->sym_; 
    284                         fc[1].i = narg; 
    285                         Inst* pcsav = save_pc(fc); 
    286                         hoc_call(); 
    287                         hoc_pc = pcsav; 
    288                 } 
    289                 return get_final_from_stk();; 
     295                OcJump* oj; 
     296                oj = new OcJump(); 
     297                if (oj) { 
     298  PyObject* result = (PyObject*)oj->fpycall(fcall, (void*)self, (void*)args); 
     299                        if (result == NULL) { 
     300  PyErr_SetString(PyExc_RuntimeError, "hoc error"); 
     301                        } 
     302                        return result; 
     303                }else{           
     304                        return (PyObject*)fcall((void*)self, (void*)args); 
     305                } 
    290306        }else{ 
    291307                return NULL;