NEURON
ocjump.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 #include <InterViews/resource.h>
3 #include <setjmp.h>
4 #include <string.h>
5 #if CABLE
6 #include "nrnoc2iv.h"
7 #else
8 #include "oc2iv.h"
9 #endif
10 #include "ocjump.h"
11 #include "nrnfilewrap.h"
12 #if HAVE_IV
13 #include "ivoc.h"
14 #endif
15 
18 extern Symlist* hoc_symlist;
19 extern Object* hoc_thisobject;
20 extern void hoc_execute1();
21 extern bool hoc_valid_stmt(const char* stmt, Object* ob);
22 extern int hoc_execerror_messages;
23 void* nrn_get_oji();
24 
25 static bool valid_stmt1(const char* stmt, Object* ob) {
26  char* s = new char[strlen(stmt) + 2];
27  strcpy(s, stmt);
28  strcat(s, "\n");
29  OcJump oj;
30  bool val = oj.execute(s, ob);
31  delete[] s;
32  return val;
33 }
34 
35 bool hoc_valid_stmt(const char* stmt, Object* ob) {
36  return valid_stmt1(stmt, ob);
37 }
38 
39 void hoc_execute1() {
40  Object* ob = NULL;
41  int hem = 1, hemold;
42  if (ifarg(2)) {
43  if (hoc_is_object_arg(2)) {
44  ob = *hoc_objgetarg(2);
45  if (ifarg(3)) {
46  hem = (int) chkarg(3, 0., 1.);
47  }
48  } else {
49  hem = (int) chkarg(2, 0., 1.);
50  }
51  }
52 
53  hemold = hoc_execerror_messages;
55  int old_mpiabort_flag = nrn_mpiabort_on_error_;
57  bool b = valid_stmt1(gargstr(1), ob);
58  nrn_mpiabort_on_error_ = old_mpiabort_flag;
59  hoc_execerror_messages = hemold;
60  hoc_ret();
61  hoc_pushx(double(b));
62 }
63 
64 // safely? return from an execution even in the presence of an execerror
65 #define OcFrame void
66 
67 class OcJumpImpl {
68  public:
69  OcJumpImpl();
70  virtual ~OcJumpImpl();
71  bool execute(Inst* p);
72  bool execute(const char*, Object* ob = NULL);
73  void* fpycall(void* (*f)(void*, void*), void* a, void* b);
74 
75  /* jmpbuf is not portable and I can't figure out how get a pointer to one.
76  therefore hoc_execerror looks at a function pointer and if it's non-NULL
77  (ljmptarget) calls it instead of doing a longjump. That means we are back
78  here and can do an explicit longjump using the begin_ */
79  static void ljmptarget();
80  void ljmp();
81  static OcJumpImpl* oji_;
82 
83  private:
84  void begin();
85  void restore();
86  void finish();
87 
88  private:
90  jmp_buf begin_;
91 
92  // hoc_oop
95  int* o3;
96  int o4;
98 
99  // code
104  int c5;
105  int c6;
111  int c12;
112 
113  // input_info
114  char* i1;
115  int i2;
116  int i3;
118 
119 #if CABLE
120  // cabcode
121  int cc1;
122  int cc2;
123 #endif
124 };
125 
126 /** Return handle for the current longjump buffer info.
127  * Valid until finish is called on the oji_ instance.
128  **/
129 void* nrn_get_oji() {
130  return (void*) OcJumpImpl::oji_;
131 }
132 
133 //------------------------------------------------------------------
134 
135 #if HAVE_IV
136 bool Oc::valid_expr(Symbol* s) {
137  OcJump oj;
138  return oj.execute(s->u.u_proc->defn.in);
139 }
140 
141 bool Oc::valid_stmt(const char* stmt, Object* ob) {
142  return valid_stmt1(stmt, ob);
143 }
144 #endif
145 //------------------------------------------------------------------
146 
148  impl_ = new OcJumpImpl();
149 }
151  delete impl_;
152 }
154  return impl_->execute(p);
155 }
156 
157 bool OcJump::execute(const char* stmt, Object* ob) {
158  return impl_->execute(stmt, ob);
159 }
160 
161 void* OcJump::fpycall(void* (*f)(void*, void*), void* a, void* b) {
162  return impl_->fpycall(f, a, b);
163 }
164 
165 //-------------------------------------------------------------------
166 
169 
171  if (oji_) {
172  oji_->ljmp();
173  }
174 }
175 
177  longjmp(begin_, 1);
178 }
179 
181 
183 
185  begin();
186 #if 1
187  if (setjmp(begin_)) {
188  restore();
189  finish();
190  return false;
191  } else
192 #endif
193  {
194  hoc_execute(p);
195  }
196  finish();
197  return true;
198 }
199 
200 bool OcJumpImpl::execute(const char* stmt, Object* ob) {
201  begin();
202 #if 1
203  if (setjmp(begin_)) {
204  restore();
205  finish();
206  return false;
207  } else
208 #endif
209  {
210  hoc_obj_run(stmt, ob);
211  }
212  finish();
213  return true;
214 }
215 
216 void* OcJumpImpl::fpycall(void* (*f)(void*, void*), void* a, void* b) {
217  void* c = 0;
218  begin();
219 #if 1
220  if (setjmp(begin_)) {
221  restore();
222  finish();
223  return c;
224  } else
225 #endif
226  {
227  c = (*f)(a, b);
228  }
229  finish();
230  return c;
231 }
232 
233 
234 extern void (*oc_jump_target_)(void);
235 extern int hoc_intset;
236 // extern int hoc_pipeflag;
237 extern "C" {
238 void oc_save_hoc_oop(Object**, Objectdata**, int**, int*, Symlist**);
239 void oc_restore_hoc_oop(Object**, Objectdata**, int**, int*, Symlist**);
241  Inst**,
242  Datum**,
243  OcFrame**,
244  int*,
245  int*,
246  Inst**,
247  OcFrame**,
248  Datum**,
249  Symlist**,
250  Inst**,
251  int*);
253  Inst**,
254  Datum**,
255  OcFrame**,
256  int*,
257  int*,
258  Inst**,
259  OcFrame**,
260  Datum**,
261  Symlist**,
262  Inst**,
263  int*);
264 void oc_save_input_info(char**, int*, int*, NrnFILEWrap**);
265 void oc_restore_input_info(char*, int, int, NrnFILEWrap*);
266 #if CABLE
267 void oc_save_cabcode(int*, int*);
268 void oc_restore_cabcode(int*, int*);
269 #endif
270 } // extern "C"
271 
273  // not complete but it is good for expressions and it can be improved
274  oc_save_hoc_oop(&o1, &o2, &o3, &o4, &o5);
275  oc_save_code(&c1, &c2, &c3, &c4, &c5, &c6, &c7, &c8, &c9, &c10, &c11, &c12);
276  oc_save_input_info(&i1, &i2, &i3, &i4);
277 #if CABLE
278  oc_save_cabcode(&cc1, &cc2);
279 #endif
280  // this may not be portable since it depends on the jmp_buf being
281  // an array of integers.
283  prev_ = oji_;
284  oji_ = this;
285 }
287  oc_restore_hoc_oop(&o1, &o2, &o3, &o4, &o5);
288  oc_restore_code(&c1, &c2, &c3, &c4, &c5, &c6, &c7, &c8, &c9, &c10, &c11, &c12);
290 #if CABLE
291  oc_restore_cabcode(&cc1, &cc2);
292 #endif
293 }
295  if (!prev_) {
297  }
298  oji_ = prev_;
299 #if 0
300  if (hoc_intset) {
301  hoc_execerror("interrupted in OcJump", 0);
302  }
303 #endif
304 }
305 
307  oc_save_hoc_oop(&a1, &a2, &a3, &a4, &a5);
308  hoc_thisobject = obj;
309  if (obj) {
310  hoc_objectdata = obj->u.dataspace;
311  hoc_symlist = obj->ctemplate->symtable;
312  } else {
315  }
316  restored_ = false;
317 }
318 
320  if (!restored_) {
321  restore();
322  }
323 }
324 
326  oc_restore_hoc_oop(&a1, &a2, &a3, &a4, &a5);
327  restored_ = true;
328 }
void oc_save_cabcode(int *a1, int *a2)
Definition: cabcode.cpp:86
void oc_restore_cabcode(int *a1, int *a2)
Definition: cabcode.cpp:91
Symlist * a5
Definition: ocjump.h:21
Objectdata * a2
Definition: ocjump.h:18
void restore()
Definition: ocjump.cpp:325
int * a3
Definition: ocjump.h:19
Object * a1
Definition: ocjump.h:17
bool restored_
Definition: ocjump.h:22
virtual ~ObjectContext()
Definition: ocjump.cpp:319
ObjectContext(Object *)
Definition: ocjump.cpp:306
static bool valid_expr(Symbol *)
static bool valid_stmt(const char *, Object *ob=NULL)
Definition: ocjump.h:25
OcJumpImpl * impl_
Definition: ocjump.h:36
bool execute(Inst *p)
Definition: ocjump.cpp:153
OcJump()
Definition: ocjump.cpp:147
virtual ~OcJump()
Definition: ocjump.cpp:150
void * fpycall(void *(*)(void *, void *), void *, void *)
Definition: ocjump.cpp:161
virtual ~OcJumpImpl()
Definition: ocjump.cpp:168
void ljmp()
Definition: ocjump.cpp:176
int * o3
Definition: ocjump.cpp:95
Datum * c9
Definition: ocjump.cpp:108
OcFrame * c8
Definition: ocjump.cpp:107
Symlist * c10
Definition: ocjump.cpp:109
Symlist * o5
Definition: ocjump.cpp:97
int o4
Definition: ocjump.cpp:96
void begin()
Definition: ocjump.cpp:272
static void ljmptarget()
Definition: ocjump.cpp:170
OcFrame * c4
Definition: ocjump.cpp:103
jmp_buf begin_
Definition: ocjump.cpp:90
Objectdata * o2
Definition: ocjump.cpp:94
Inst * c11
Definition: ocjump.cpp:110
NrnFILEWrap * i4
Definition: ocjump.cpp:117
Inst * c2
Definition: ocjump.cpp:101
Object * o1
Definition: ocjump.cpp:93
Inst * c7
Definition: ocjump.cpp:106
char * i1
Definition: ocjump.cpp:114
void finish()
Definition: ocjump.cpp:294
OcJumpImpl * prev_
Definition: ocjump.cpp:89
Inst * c1
Definition: ocjump.cpp:100
bool execute(Inst *p)
Definition: ocjump.cpp:184
static OcJumpImpl * oji_
Definition: ocjump.cpp:81
OcJumpImpl()
Definition: ocjump.cpp:167
void restore()
Definition: ocjump.cpp:286
Datum * c3
Definition: ocjump.cpp:102
void * fpycall(void *(*f)(void *, void *), void *a, void *b)
Definition: ocjump.cpp:216
double chkarg(int, double low, double high)
Definition: code2.cpp:638
#define c
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:754
int hoc_is_object_arg(int narg)
Definition: code.cpp:756
Objectdata * hoc_objectdata
Definition: hoc_oop.cpp:123
void hoc_ret()
int nrn_mpiabort_on_error_
Definition: hoc.cpp:77
#define gargstr
Definition: hocdec.h:14
Object ** hoc_objgetarg(int)
Definition: code.cpp:1587
void
#define OcFrame
Definition: ocjump.cpp:65
int hoc_execerror_messages
Definition: hoc.cpp:680
void oc_save_hoc_oop(Object **, Objectdata **, int **, int *, Symlist **)
int hoc_intset
Symlist * hoc_top_level_symlist
Definition: symdir.cpp:23
void oc_save_code(Inst **, Inst **, Datum **, OcFrame **, int *, int *, Inst **, OcFrame **, Datum **, Symlist **, Inst **, int *)
void oc_restore_input_info(char *, int, int, NrnFILEWrap *)
bool hoc_valid_stmt(const char *stmt, Object *ob)
Definition: ocjump.cpp:35
void(* oc_jump_target_)(void)
Definition: hoc.cpp:686
void oc_restore_hoc_oop(Object **, Objectdata **, int **, int *, Symlist **)
void oc_save_input_info(char **, int *, int *, NrnFILEWrap **)
void oc_restore_code(Inst **, Inst **, Datum **, OcFrame **, int *, int *, Inst **, OcFrame **, Datum **, Symlist **, Inst **, int *)
static bool valid_stmt1(const char *stmt, Object *ob)
Definition: ocjump.cpp:25
void * nrn_get_oji()
Return handle for the current longjump buffer info.
Definition: ocjump.cpp:129
Symlist * hoc_symlist
Objectdata * hoc_top_level_data
Definition: hoc_oop.cpp:124
void hoc_execute(Inst *)
void hoc_execute1()
Definition: ocjump.cpp:39
Object * hoc_thisobject
Definition: hoc_oop.cpp:122
int hoc_obj_run(const char *, Object *)
Definition: hoc_oop.cpp:322
int ifarg(int)
Definition: code.cpp:1581
void hoc_pushx(double)
#define NrnFILEWrap
Definition: nrnfilewrap.h:39
size_t p
#define NULL
Definition: sptree.h:16
Definition: hocdec.h:227
Objectdata * dataspace
Definition: hocdec.h:231
union Object::@39 u
Inst defn
Definition: hocdec.h:76
Definition: model.h:57
Proc * u_proc
Definition: hocdec.h:145
union Symbol::@18 u
Definition: hocdec.h:84
Definition: hocdec.h:177
Definition: hocdec.h:51
HocUnion Inst * in
Definition: hocdec.h:60