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 private:
83  void begin();
84  void restore();
85  void finish();
86 private:
88  jmp_buf begin_;
89 
90  // hoc_oop
93  int* o3;
94  int o4;
96 
97  // code
98  Inst* c1;
99  Inst* c2;
102  int c5;
103  int c6;
109  int c12;
110 
111  // input_info
112  char* i1;
113  int i2;
114  int i3;
116 
117 #if CABLE
118  // cabcode
119  int cc1;
120  int cc2;
121 #endif
122 };
123 
124 /** Return handle for the current longjump buffer info.
125  * Valid until finish is called on the oji_ instance.
126 **/
127 void* nrn_get_oji() {
128  return (void*)OcJumpImpl::oji_;
129 }
130 
131 //------------------------------------------------------------------
132 
133 #if HAVE_IV
134 bool Oc::valid_expr(Symbol* s) {
135  OcJump oj;
136  return oj.execute(s->u.u_proc->defn.in);
137 }
138 
139 bool Oc::valid_stmt(const char* stmt, Object* ob) {
140  return valid_stmt1(stmt, ob);
141 }
142 #endif
143 //------------------------------------------------------------------
144 
146  impl_ = new OcJumpImpl();
147 }
149  delete impl_;
150 }
152  return impl_->execute(p);
153 }
154 
155 bool OcJump::execute(const char* stmt, Object* ob) {
156  return impl_->execute(stmt, ob);
157 }
158 
159 void* OcJump::fpycall(void*(*f)(void*, void*), void* a, void* b) {
160  return impl_->fpycall(f, a, b);
161 }
162 
163 //-------------------------------------------------------------------
164 
167 
169  if (oji_) {
170  oji_->ljmp();
171  }
172 }
173 
175  longjmp(begin_, 1);
176 }
177 
179 
180 void hoc_execute(Inst*);
181 
183  begin();
184 #if 1
185  if (setjmp(begin_)) {
186  restore();
187  finish();
188  return false;
189  }else
190 #endif
191  {
192  hoc_execute(p);
193  }
194  finish();
195  return true;
196 }
197 
198 bool OcJumpImpl::execute(const char* stmt, Object* ob) {
199  begin();
200 #if 1
201  if (setjmp(begin_)) {
202  restore();
203  finish();
204  return false;
205  }else
206 #endif
207  {
208  hoc_obj_run(stmt, ob);
209  }
210  finish();
211  return true;
212 }
213 
214 void* OcJumpImpl::fpycall(void*(*f)(void*, void*), void* a, void* b) {
215  void* c = 0;
216  begin();
217 #if 1
218  if (setjmp(begin_)) {
219  restore();
220  finish();
221  return c;
222  }else
223 #endif
224  {
225  c = (*f)(a, b);
226  }
227  finish();
228  return c;
229 }
230 
231 
232  extern void (*oc_jump_target_)(void);
233  extern int hoc_intset;
234 // extern int hoc_pipeflag;
235 extern "C" {
236  void oc_save_hoc_oop(Object**, Objectdata**, int**, int*, Symlist**);
237  void oc_restore_hoc_oop(Object**, Objectdata**, int**, int*, Symlist**);
238  void oc_save_code(Inst **, Inst **, Datum **, OcFrame **, int *, int *,
239  Inst **, OcFrame **, Datum **, Symlist **, Inst **, int *);
240  void oc_restore_code(Inst **, Inst **, Datum **, OcFrame **, int *, int *,
241  Inst **, OcFrame **, Datum **, Symlist **, Inst **, int *);
242  void oc_save_input_info(char**, int*, int*, NrnFILEWrap**);
243  void oc_restore_input_info(char*, int, int, NrnFILEWrap*);
244 #if CABLE
245  void oc_save_cabcode(int*, int*);
246  void oc_restore_cabcode(int*, int*);
247 #endif
248 } // extern "C"
249 
251 // not complete but it is good for expressions and it can be improved
252  oc_save_hoc_oop(&o1, &o2, &o3, &o4, &o5);
253  oc_save_code(&c1, &c2, &c3, &c4, &c5, &c6, &c7, &c8, &c9, &c10, &c11, &c12);
254  oc_save_input_info(&i1, &i2, &i3, &i4);
255 #if CABLE
256  oc_save_cabcode(&cc1, &cc2);
257 #endif
258  // this may not be portable since it depends on the jmp_buf being
259  // an array of integers.
261  prev_ = oji_;
262  oji_ = this;
263 }
265  oc_restore_hoc_oop(&o1, &o2, &o3, &o4, &o5);
266  oc_restore_code(&c1, &c2, &c3, &c4, &c5, &c6, &c7, &c8, &c9, &c10, &c11, &c12);
268 #if CABLE
269  oc_restore_cabcode(&cc1, &cc2);
270 #endif
271 }
273  if (!prev_) {
275  }
276  oji_ = prev_;
277 #if 0
278  if (hoc_intset) {
279  hoc_execerror("interrupted in OcJump", 0);
280  }
281 #endif
282 }
283 
285  oc_save_hoc_oop(&a1, &a2, &a3, &a4, &a5);
286  hoc_thisobject = obj;
287  if (obj) {
288  hoc_objectdata = obj->u.dataspace;
289  hoc_symlist = obj->ctemplate->symtable;
290  }else{
292  hoc_symlist = hoc_top_level_symlist;
293  }
294  restored_ = false;
295 }
296 
298  if (!restored_) {
299  restore();
300  }
301 }
302 
304  oc_restore_hoc_oop(&a1, &a2, &a3, &a4, &a5);
305  restored_ = true;
306 }
void begin()
Definition: ocjump.cpp:250
NrnFILEWrap * i4
Definition: ocjump.cpp:115
int nrn_mpiabort_on_error_
Definition: hoc.cpp:77
int hoc_intset
void hoc_execute(Inst *)
Definition: hocdec.h:84
Datum * c3
Definition: ocjump.cpp:100
char * i1
Definition: ocjump.cpp:112
#define OcFrame
Definition: ocjump.cpp:65
Object * o1
Definition: ocjump.cpp:91
void finish()
Definition: ocjump.cpp:272
void(* oc_jump_target_)(void)
Definition: hoc.cpp:672
virtual ~OcJump()
Definition: ocjump.cpp:148
jmp_buf begin_
Definition: ocjump.cpp:88
Inst * c11
Definition: ocjump.cpp:108
Inst * c7
Definition: ocjump.cpp:104
void oc_save_hoc_oop(Object **, Objectdata **, int **, int *, Symlist **)
void
size_t p
int * o3
Definition: ocjump.cpp:93
Definition: hocdec.h:51
OcFrame * c8
Definition: ocjump.cpp:105
#define gargstr
Definition: hocdec.h:14
ObjectContext(Object *)
Definition: ocjump.cpp:284
void restore()
Definition: ocjump.cpp:303
void oc_restore_cabcode(int *a1, int *a2)
Definition: cabcode.cpp:88
bool hoc_valid_stmt(const char *stmt, Object *ob)
Definition: ocjump.cpp:35
bool execute(Inst *p)
Definition: ocjump.cpp:151
void hoc_ret()
OcFrame * c4
Definition: ocjump.cpp:101
void * nrn_get_oji()
Return handle for the current longjump buffer info.
Definition: ocjump.cpp:127
void oc_save_code(Inst **, Inst **, Datum **, OcFrame **, int *, int *, Inst **, OcFrame **, Datum **, Symlist **, Inst **, int *)
void oc_save_cabcode(int *a1, int *a2)
Definition: cabcode.cpp:82
int hoc_execerror_messages
Definition: hoc.cpp:666
virtual ~OcJumpImpl()
Definition: ocjump.cpp:166
_CONST char * s
Definition: system.cpp:74
Objectdata * hoc_objectdata
Definition: hoc_oop.cpp:133
Objectdata * dataspace
Definition: hocdec.h:230
Symlist * c10
Definition: ocjump.cpp:107
int val
Definition: dll.cpp:167
void oc_restore_hoc_oop(Object **, Objectdata **, int **, int *, Symlist **)
int
Definition: nrnmusic.cpp:71
static OcJumpImpl * oji_
Definition: ocjump.cpp:81
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:741
Symlist * hoc_symlist
Objectdata * hoc_top_level_data
Definition: hoc_oop.cpp:134
void oc_restore_input_info(char *, int, int, NrnFILEWrap *)
Proc * u_proc
Definition: hocdec.h:144
Inst defn
Definition: hocdec.h:76
Definition: model.h:57
Inst * c1
Definition: ocjump.cpp:98
Symlist * hoc_top_level_symlist
Definition: symbol.cpp:41
virtual ~ObjectContext()
Definition: ocjump.cpp:297
bool execute(Inst *p)
Definition: ocjump.cpp:182
int ifarg(int)
Definition: code.cpp:1562
void * fpycall(void *(*f)(void *, void *), void *a, void *b)
Definition: ocjump.cpp:214
Object * hoc_thisobject
Definition: hoc_oop.cpp:132
void hoc_pushx(double)
Datum * c9
Definition: ocjump.cpp:106
void * fpycall(void *(*)(void *, void *), void *, void *)
Definition: ocjump.cpp:159
Symlist * o5
Definition: ocjump.cpp:95
void hoc_execute1()
Definition: ocjump.cpp:39
static bool valid_stmt(const char *, Object *ob=NULL)
OcJump()
Definition: ocjump.cpp:145
Definition: hocdec.h:226
int hoc_obj_run(const char *, Object *)
Definition: hoc_oop.cpp:323
Objectdata * o2
Definition: ocjump.cpp:92
Definition: ocjump.h:24
void oc_save_input_info(char **, int *, int *, NrnFILEWrap **)
#define c
int o4
Definition: ocjump.cpp:94
Inst * c2
Definition: ocjump.cpp:99
OcJumpImpl()
Definition: ocjump.cpp:165
int hoc_is_object_arg(int narg)
Definition: code.cpp:745
static bool valid_stmt1(const char *stmt, Object *ob)
Definition: ocjump.cpp:25
union Symbol::@18 u
OcJumpImpl * prev_
Definition: ocjump.cpp:87
union Object::@54 u
Definition: hocdec.h:176
Object ** hoc_objgetarg(int)
Definition: code.cpp:1568
void oc_restore_code(Inst **, Inst **, Datum **, OcFrame **, int *, int *, Inst **, OcFrame **, Datum **, Symlist **, Inst **, int *)
return NULL
Definition: cabcode.cpp:461
double chkarg(int, double low, double high)
Definition: code2.cpp:608
#define NrnFILEWrap
Definition: nrnfilewrap.h:39
void ljmp()
Definition: ocjump.cpp:174
void restore()
Definition: ocjump.cpp:264
static bool valid_expr(Symbol *)
static void ljmptarget()
Definition: ocjump.cpp:168
HocUnion Inst * in
Definition: hocdec.h:60