1 /*
2  * Copyright (c) 2001-2018 Stephen Williams (steve@icarus.com)
3  *
4  *    This source code is free software; you can redistribute it
5  *    and/or modify it in source code form under the terms of the GNU
6  *    General Public License as published by the Free Software
7  *    Foundation; either version 2 of the License, or (at your option)
8  *    any later version.
9  *
10  *    This program is distributed in the hope that it will be useful,
11  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *    GNU General Public License for more details.
14  *
15  *    You should have received a copy of the GNU General Public License
16  *    along with this program; if not, write to the Free Software
17  *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19 
20 # include  "vpi_priv.h"
21 # include  "compile.h"
22 # include  "config.h"
23 #ifdef CHECK_WITH_VALGRIND
24 # include  "vvp_cleanup.h"
25 #endif
26 # include  <cstdio>
27 # include  <cstdlib>
28 # include  <cstring>
29 # include  <cassert>
30 # include  "ivl_alloc.h"
31 
32 class __vpiStringConst : public __vpiHandle {
33     public:
34       explicit __vpiStringConst(char*val);
35       ~__vpiStringConst();
36       int get_type_code(void) const;
37       int vpi_get(int code);
38       void vpi_get_value(p_vpi_value val);
39 
40     private:
41       void process_string_();
42     private:
43       char*value_;
44       size_t value_len_;
45 };
46 
__vpiStringConst(char * v)47 inline __vpiStringConst::__vpiStringConst(char*v)
48 : value_(v)
49 {
50       process_string_();
51 }
52 
53 /*
54  * Strings are described at the level of the vvp source as a string
55  * with literal characters or octal escapes. No other escapes are
56  * included, they are processed already by the compiler that generated
57  * the vvp source.
58  */
process_string_(void)59 void __vpiStringConst::process_string_(void)
60 {
61       char*chr = value_;
62       char*dp = value_;
63 
64       while (*chr) {
65 	    char next_char = *chr;
66 
67 	      /* Process octal escapes that I might find. */
68 	    if (*chr == '\\') {
69 		  for (int idx = 1 ;  idx <= 3 ;  idx += 1) {
70 			assert(chr[idx] != 0);
71 			assert(chr[idx] < '8');
72 			assert(chr[idx] >= '0');
73 			next_char = next_char*8 + chr[idx] - '0';
74 		  }
75 		  chr += 3;
76 	    }
77 	    *dp++ = next_char;
78 	    chr += 1;
79       }
80       *dp = 0;
81       value_len_ = dp - value_;
82 }
83 
~__vpiStringConst()84 __vpiStringConst::~__vpiStringConst()
85 {
86       delete[] value_;
87 }
88 
get_type_code(void) const89 int __vpiStringConst::get_type_code(void) const
90 { return vpiConstant; }
91 
vpi_get(int code)92 int __vpiStringConst::vpi_get(int code)
93 {
94       switch (code) {
95           case vpiSize:
96 	    return strlen(value_)*8;
97 
98           case vpiSigned:
99 	      return 0;
100 
101 	  case vpiConstType:
102 	      return vpiStringConst;
103 
104           case vpiAutomatic:
105 	      return 0;
106 
107 #if defined(CHECK_WITH_VALGRIND) || defined(BR916_STOPGAP_FIX)
108           case _vpiFromThr:
109 	      return _vpiNoThr;
110 #endif
111 
112 	  default:
113 	      fprintf(stderr, "vvp error: get %d not supported "
114 		      "by vpiStringConst\n", code);
115 	      assert(0);
116 	      return 0;
117       }
118 }
119 
vpi_get_value(p_vpi_value vp)120 void __vpiStringConst::vpi_get_value(p_vpi_value vp)
121 {
122       unsigned uint_value;
123       p_vpi_vecval vecp;
124       unsigned size = strlen(value_);
125       char*rbuf = 0;
126       char*cp;
127 
128       switch (vp->format) {
129 	  case vpiObjTypeVal:
130 	      /* String parameters by default have vpiStringVal values. */
131 	    vp->format = vpiStringVal;
132 	    // fallthrough
133 	  case vpiStringVal:
134 	    rbuf = (char *) need_result_buf(size + 1, RBUF_VAL);
135 	    strcpy(rbuf, value_);
136 	    vp->value.str = rbuf;
137 	    break;
138 
139           case vpiDecStrVal:
140 	      if (size > 4){
141 		  // We only support standard integers. Ignore other bytes...
142 		  size = 4;
143 		  fprintf(stderr, "Warning (vpi_const.cc): %%d on constant strings only looks "
144 			  "at first 4 bytes!\n");
145 	      }
146 	      rbuf = (char *) need_result_buf(size + 1, RBUF_VAL);
147 	      uint_value = 0;
148 	      for(unsigned i=0; i<size; i += 1){
149 		  uint_value <<=8;
150 		  uint_value += (unsigned char)(value_[i]);
151 	      }
152 	      sprintf(rbuf, "%u", uint_value);
153 	      vp->value.str = rbuf;
154 	      break;
155 
156           case vpiBinStrVal:
157 	      rbuf = (char *) need_result_buf(8 * size + 1, RBUF_VAL);
158 	      cp = rbuf;
159 	      for(unsigned i=0; i<size; i += 1){
160 		  for(int bit=7; bit>=0; bit -= 1){
161 		      *cp++ = "01"[ (value_[i]>>bit)&1 ];
162 		  }
163 	      }
164 	      *cp = 0;
165 	      vp->value.str = rbuf;
166 	      break;
167 
168           case vpiHexStrVal:
169 	      rbuf = (char *) need_result_buf(2 * size + 1, RBUF_VAL);
170 	      cp = rbuf;
171 	      for(unsigned i=0; i<size; i += 1){
172 		  for(int nibble=1; nibble>=0; nibble -= 1){
173 		      *cp++ = "0123456789abcdef"[ (value_[i]>>(nibble*4))&15 ];
174 		  }
175 	      }
176 	      *cp = 0;
177 	      vp->value.str = rbuf;
178 	      break;
179 
180           case vpiOctStrVal:
181 	      fprintf(stderr, "ERROR (vpi_const.cc): %%o display of constant strings not yet implemented\n");
182 	      assert(0);
183 	      break;
184 
185           case vpiIntVal:
186 	      vp->value.integer = 0;
187 	      for(unsigned i=0; i<size; i += 1){
188 		  for(int bit=7; bit>=0; bit -= 1){
189 		      vp->value.integer <<= 1;
190 		      vp->value.integer += (value_[i]>>bit)&1;
191 		  }
192 	      }
193 	      break;
194 
195           case vpiVectorVal:
196               vp->value.vector = (p_vpi_vecval)
197                                  need_result_buf((size+3)/4*
198                                                   sizeof(s_vpi_vecval),
199                                                  RBUF_VAL);
200               uint_value = 0;
201               vecp = vp->value.vector;
202               vecp->aval = vecp->bval = 0;
203 	      for(unsigned i=0; i<size; i += 1){
204 		  vecp->aval |= value_[i] << uint_value*8;
205 		  uint_value += 1;
206 		  if (uint_value > 3) {
207 		      uint_value = 0;
208 		      vecp += 1;
209 		      vecp->aval = vecp->bval = 0;
210 		  }
211 	      }
212 	      break;
213 
214 
215 	  default:
216 	    fprintf(stderr, "ERROR (vpi_const.cc): vp->format: %d\n",
217 	            (int)vp->format);
218 	    assert(0);
219 
220 	    vp->format = vpiSuppressVal;
221 	    break;
222       }
223 }
224 
225 
226 struct __vpiStringConstTEMP : public __vpiStringConst {
__vpiStringConstTEMP__vpiStringConstTEMP227       explicit inline __vpiStringConstTEMP(char*v) : __vpiStringConst(v) { }
228       free_object_fun_t free_object_fun(void);
229 };
230 
free_temp_string(vpiHandle obj)231 static int free_temp_string(vpiHandle obj)
232 {
233       struct __vpiStringConstTEMP*rfp = dynamic_cast<__vpiStringConstTEMP*>(obj);
234       delete rfp;
235       return 1;
236 }
237 
free_object_fun(void)238 __vpiHandle::free_object_fun_t __vpiStringConstTEMP::free_object_fun(void)
239 { return &free_temp_string; }
240 
vpip_make_string_const(char * text,bool persistent_flag)241 vpiHandle vpip_make_string_const(char*text, bool persistent_flag)
242 {
243       __vpiStringConst*obj;
244 
245       obj = persistent_flag? new __vpiStringConst(text) : new __vpiStringConstTEMP(text);
246 
247       return obj;
248 }
249 
250 
251 class __vpiStringParam  : public __vpiStringConst {
252     public:
253       __vpiStringParam(char*txt, char*name);
254       ~__vpiStringParam();
255       int get_type_code(void) const;
256       int vpi_get(int code);
257       char*vpi_get_str(int code);
258       vpiHandle vpi_handle(int code);
259 
260       __vpiScope* scope;
261       bool     local_flag;
262       unsigned file_idx;
263       unsigned lineno;
264     private:
265       const char*basename_;
266 };
267 
__vpiStringParam(char * txt,char * nam)268 inline __vpiStringParam::__vpiStringParam(char*txt, char*nam)
269 : __vpiStringConst(txt)
270 {
271       basename_ = nam;
272 }
273 
~__vpiStringParam()274 __vpiStringParam::~__vpiStringParam()
275 {
276       delete[]basename_;
277 }
278 
get_type_code(void) const279 int __vpiStringParam::get_type_code(void) const
280 { return vpiParameter; }
281 
vpi_get(int code)282 int __vpiStringParam::vpi_get(int code)
283 {
284     switch (code) {
285        case vpiLineNo :
286          return lineno;
287 
288        case vpiLocalParam :
289          return local_flag;
290 
291        default :
292          return __vpiStringConst::vpi_get(code);
293     }
294 }
295 
296 
vpi_get_str(int code)297 char*__vpiStringParam::vpi_get_str(int code)
298 {
299       if (code == vpiFile) {
300 	    return simple_set_rbuf_str(file_names[file_idx]);
301       }
302 
303       return generic_get_str(code, scope, basename_, NULL);
304 }
305 
306 
vpi_handle(int code)307 vpiHandle __vpiStringParam::vpi_handle(int code)
308 {
309       switch (code) {
310 	  case vpiScope:
311 	    return scope;
312 
313 	  case vpiModule:
314 	    return vpip_module(scope);
315 
316 	  default:
317 	    return 0;
318       }
319 }
320 
vpip_make_string_param(char * name,char * text,bool local_flag,long file_idx,long lineno)321 vpiHandle vpip_make_string_param(char*name, char*text,
322                                   bool local_flag, long file_idx, long lineno)
323 {
324       __vpiStringParam*obj = new __vpiStringParam(text, name);
325       obj->scope = vpip_peek_current_scope();
326       obj->local_flag = local_flag;
327       obj->file_idx = (unsigned) file_idx;
328       obj->lineno = (unsigned) lineno;
329 
330       return obj;
331 }
332 
333 
334 
__vpiBinaryConst()335 inline __vpiBinaryConst::__vpiBinaryConst()
336 { }
337 
get_type_code(void) const338 int __vpiBinaryConst::get_type_code(void) const
339 { return vpiConstant; }
340 
vpi_get(int code)341 int __vpiBinaryConst::vpi_get(int code)
342 {
343       switch (code) {
344 	  case vpiConstType:
345 	    return vpiBinaryConst;
346 
347 	  case vpiLineNo:
348 	    return 0;  // Not implemented for now!
349 
350 	  case vpiSigned:
351 	    return signed_flag? 1 : 0;
352 
353 	  case vpiSize:
354 	    return bits.size();
355 
356           case vpiAutomatic:
357 	    return 0;
358 
359 #if defined(CHECK_WITH_VALGRIND) || defined(BR916_STOPGAP_FIX)
360           case _vpiFromThr:
361 	      return _vpiNoThr;
362 #endif
363 
364 	  default:
365 	    fprintf(stderr, "vvp error: get %d not supported "
366 		    "by vpiBinaryConst\n", code);
367 	    assert(0);
368 	    return 0;
369       }
370 }
371 
372 
vpi_get_value(p_vpi_value val)373 void __vpiBinaryConst::vpi_get_value(p_vpi_value val)
374 {
375       switch (val->format) {
376 
377 	  case vpiObjTypeVal:
378 	  case vpiBinStrVal:
379 	  case vpiDecStrVal:
380 	  case vpiOctStrVal:
381 	  case vpiHexStrVal:
382           case vpiScalarVal:
383 	  case vpiIntVal:
384 	  case vpiVectorVal:
385 	  case vpiStringVal:
386 	  case vpiRealVal:
387 	    vpip_vec4_get_value(bits, bits.size(), signed_flag, val);
388 	    break;
389 
390 	  default:
391 	    fprintf(stderr, "vvp error: format %d not supported "
392 		    "by vpiBinaryConst\n", (int)val->format);
393 	    val->format = vpiSuppressVal;
394 	    break;
395       }
396 }
397 
398 
399 /*
400  * Make a VPI constant from a vector string. The string is normally a
401  * ASCII string, with each letter a 4-value bit. The first character
402  * may be an 's' if the vector is signed.
403  */
vpip_make_binary_const(unsigned wid,const char * bits)404 vpiHandle vpip_make_binary_const(unsigned wid, const char*bits)
405 {
406       struct __vpiBinaryConst*obj = new __vpiBinaryConst;
407 
408       obj->signed_flag = 0;
409       obj->sized_flag = 0;
410 
411       const char*bp = bits;
412       if (*bp == 's') {
413 	    bp += 1;
414 	    obj->signed_flag = 1;
415       }
416 
417       obj->bits = vector4_from_text(bp, wid);
418 
419       return obj;
420 }
421 
vector4_from_text(const char * bits,unsigned wid)422 vvp_vector4_t vector4_from_text(const char*bits, unsigned wid)
423 {
424       vvp_vector4_t res (wid);
425 
426       for (unsigned idx = 0 ;  idx < wid ;  idx += 1) {
427 	    vvp_bit4_t val = BIT4_0;
428 	    switch (bits[wid-idx-1]) {
429 		case '0':
430 		  val = BIT4_0;
431 		  break;
432 		case '1':
433 		  val = BIT4_1;
434 		  break;
435 		case 'x':
436 		  val = BIT4_X;
437 		  break;
438 		case 'z':
439 		  val = BIT4_Z;
440 		  break;
441 	    }
442 
443 	    res.set_bit(idx, val);
444       }
445 
446       return res;
447 }
448 
449 struct __vpiBinaryParam  : public __vpiBinaryConst {
450       __vpiBinaryParam(const vvp_vector4_t&b, char*name);
451       ~__vpiBinaryParam();
452       int get_type_code(void) const;
453       int vpi_get(int code);
454       char*vpi_get_str(int code);
455       vpiHandle vpi_handle(int code);
456 
457       __vpiScope*scope;
458       unsigned file_idx;
459       unsigned lineno;
460       bool     local_flag;
461     private:
462       char*basename_;
463 };
464 
__vpiBinaryParam(const vvp_vector4_t & b,char * nam)465 inline __vpiBinaryParam::__vpiBinaryParam(const vvp_vector4_t&b, char*nam)
466 {
467       bits = b;
468       basename_ = nam;
469 }
470 
~__vpiBinaryParam()471 __vpiBinaryParam::~__vpiBinaryParam()
472 {
473       delete[]basename_;
474 }
475 
get_type_code(void) const476 int __vpiBinaryParam::get_type_code(void) const
477 { return vpiParameter; }
478 
vpi_get(int code)479 int __vpiBinaryParam::vpi_get(int code)
480 {
481     switch (code) {
482       case vpiLineNo :
483         return lineno;
484 
485       case vpiLocalParam :
486         return local_flag;
487 
488       default :
489         return __vpiBinaryConst::vpi_get(code);
490     }
491 }
492 
vpi_get_str(int code)493 char*__vpiBinaryParam::vpi_get_str(int code)
494 {
495       if (code == vpiFile)
496 	    return simple_set_rbuf_str(file_names[file_idx]);
497 
498       return generic_get_str(code, scope, basename_, NULL);
499 }
500 
501 
vpi_handle(int code)502 vpiHandle __vpiBinaryParam::vpi_handle(int code)
503 {
504       switch (code) {
505 	  case vpiScope:
506 	    return scope;
507 
508 	  case vpiModule:
509 	    return vpip_module(scope);
510 
511 	  default:
512 	    return 0;
513       }
514 }
515 
516 
vpip_make_binary_param(char * name,const vvp_vector4_t & bits,bool signed_flag,bool local_flag,long file_idx,long lineno)517 vpiHandle vpip_make_binary_param(char*name, const vvp_vector4_t&bits,
518 				 bool signed_flag, bool local_flag,
519 				 long file_idx, long lineno)
520 {
521       struct __vpiBinaryParam*obj = new __vpiBinaryParam(bits, name);
522 
523       obj->signed_flag = signed_flag? 1 : 0;
524       obj->sized_flag = 0;
525       obj->local_flag = local_flag;
526       obj->scope = vpip_peek_current_scope();
527       obj->file_idx = (unsigned) file_idx;
528       obj->lineno = (unsigned) lineno;
529 
530       return obj;
531 }
532 
533 
534 
__vpiDecConst(int val)535 __vpiDecConst::__vpiDecConst(int val)
536 {
537       value = val;
538 }
539 
__vpiDecConst(const __vpiDecConst & that)540 __vpiDecConst::__vpiDecConst(const __vpiDecConst&that)
541 : __vpiHandle(), value(that.value)
542 {
543 }
544 
545 
get_type_code(void) const546 int __vpiDecConst::get_type_code(void) const
547 { return vpiConstant; }
548 
vpi_get(int code)549 int __vpiDecConst::vpi_get(int code)
550 {
551       switch (code) {
552 	  case vpiConstType:
553 	    return vpiDecConst;
554 
555 	  case vpiSigned:
556 	    return 1;
557 
558 	  case vpiSize:
559 	    return 32;
560 
561           case vpiAutomatic:
562 	    return 0;
563 
564 #if defined(CHECK_WITH_VALGRIND) || defined(BR916_STOPGAP_FIX)
565           case _vpiFromThr:
566 	      return _vpiNoThr;
567 #endif
568 
569 	  default:
570 	    fprintf(stderr, "vvp error: get %d not supported "
571 		    "by vpiDecConst\n", code);
572 	    assert(0);
573 	    return 0;
574       }
575 }
576 
577 
vpi_get_value(p_vpi_value vp)578 void __vpiDecConst::vpi_get_value(p_vpi_value vp)
579 {
580       char*rbuf = (char *) need_result_buf(64 + 1, RBUF_VAL);
581       char*cp = rbuf;
582 
583       switch (vp->format) {
584 
585 	  case vpiObjTypeVal:
586 	  case vpiIntVal: {
587 		vp->value.integer = value;
588 		break;
589 	  }
590 
591           case vpiDecStrVal:
592 	      sprintf(rbuf, "%d", value);
593 
594 	      vp->value.str = rbuf;
595 	      break;
596 
597           case vpiBinStrVal:
598 	      for(int bit=31; bit>=0;bit--){
599 		  *cp++ = "01"[ (value>>bit)&1 ];
600 	      }
601 	      *cp = 0;
602 
603 	      vp->value.str = rbuf;
604 	      break;
605 
606           case vpiHexStrVal:
607 	      sprintf(rbuf, "%08x", value);
608 
609 	      vp->value.str = rbuf;
610 	      break;
611 
612           case vpiOctStrVal:
613 	      sprintf(rbuf, "%011x", value);
614 
615 	      vp->value.str = rbuf;
616 	      break;
617 
618 	  default:
619 	    fprintf(stderr, "vvp error (vpi_const.cc): format %d not supported "
620 		    "by vpiDecConst\n", (int)vp->format);
621 	    vp->format = vpiSuppressVal;
622 	    break;
623       }
624 }
625 
626 
__vpiRealConst(double val)627 inline __vpiRealConst::__vpiRealConst(double val)
628 : value(val)
629 { }
630 
get_type_code(void) const631 int __vpiRealConst::get_type_code(void) const
632 { return vpiConstant; }
633 
vpi_get(int code)634 int __vpiRealConst::vpi_get(int code)
635 {
636       switch (code) {
637 	  case vpiLineNo:
638 	    return 0;  // Not implemented for now!
639 
640 	  case vpiSize:
641 	    return 1;
642 
643 	  case vpiConstType:
644 	    return vpiRealConst;
645 
646 	  case vpiSigned:
647 	    return 1;
648 
649           case vpiAutomatic:
650 	    return 0;
651 
652 #if defined(CHECK_WITH_VALGRIND) || defined(BR916_STOPGAP_FIX)
653           case _vpiFromThr:
654 	      return _vpiNoThr;
655 #endif
656 
657 	  default:
658 	    fprintf(stderr, "vvp error: get %d not supported "
659 		    "by vpiRealConst\n", code);
660 	    assert(0);
661 	    return 0;
662       }
663 }
664 
665 
vpi_get_value(p_vpi_value val)666 void __vpiRealConst::vpi_get_value(p_vpi_value val)
667 {
668       vpip_real_get_value(value, val);
669 }
670 
671 
vpip_make_real_const(double value)672 vpiHandle vpip_make_real_const(double value)
673 {
674       __vpiRealConst*obj = new __vpiRealConst(value);
675       return obj;
676 }
677 
678 struct __vpiRealParam  : public __vpiRealConst {
679       __vpiRealParam(double val, char*name);
680       ~__vpiRealParam();
681       int get_type_code(void) const;
682       int vpi_get(int code);
683       char*vpi_get_str(int code);
684       vpiHandle vpi_handle(int code);
685 
686       __vpiScope* scope;
687       bool local_flag;
688       unsigned file_idx;
689       unsigned lineno;
690     private:
691       const char*basename_;
692 };
693 
694 
__vpiRealParam(double val,char * name)695 inline __vpiRealParam::__vpiRealParam(double val, char*name)
696 : __vpiRealConst(val)
697 {
698       basename_ = name;
699 }
700 
~__vpiRealParam()701 __vpiRealParam::~__vpiRealParam()
702 {
703       delete[]basename_;
704 }
705 
706 
get_type_code(void) const707 int __vpiRealParam::get_type_code(void) const
708 { return vpiParameter; }
709 
vpi_get(int code)710 int __vpiRealParam::vpi_get(int code)
711 {
712     switch (code) {
713       case vpiLineNo :
714         return lineno;
715 
716       case vpiLocalParam :
717         return local_flag;
718 
719       default :
720            return __vpiRealConst::vpi_get(code);
721     }
722 }
723 
vpi_get_str(int code)724 char* __vpiRealParam::vpi_get_str(int code)
725 {
726       if (code == vpiFile)
727             return simple_set_rbuf_str(file_names[file_idx]);
728 
729       return generic_get_str(code, scope, basename_, NULL);
730 }
731 
vpi_handle(int code)732 vpiHandle __vpiRealParam::vpi_handle(int code)
733 {
734       switch (code) {
735           case vpiScope:
736             return scope;
737 
738 	  case vpiModule:
739 	    return vpip_module(scope);
740 
741           default:
742             return 0;
743       }
744 }
745 
746 
vpip_make_real_param(char * name,double value,bool local_flag,long file_idx,long lineno)747 vpiHandle vpip_make_real_param(char*name, double value,
748                                 bool local_flag, long file_idx, long lineno)
749 {
750       struct __vpiRealParam*obj = new __vpiRealParam(value, name);
751 
752       obj->scope = vpip_peek_current_scope();
753       obj->local_flag = local_flag;
754       obj->file_idx = (unsigned) file_idx;
755       obj->lineno = (unsigned) lineno;
756 
757       return obj;
758 }
759 
760 #ifdef CHECK_WITH_VALGRIND
constant_delete(vpiHandle item)761 void constant_delete(vpiHandle item)
762 {
763       assert(item->get_type_code() == vpiConstant);
764       switch(vpi_get(vpiConstType, item)) {
765 	  case vpiStringConst:
766 	    delete dynamic_cast<__vpiStringConst*>(item);
767 	    break;
768 	  case vpiDecConst:
769 	    delete dynamic_cast<__vpiDecConst*>(item);
770 	    break;
771 	  case vpiBinaryConst:
772 	    delete dynamic_cast<__vpiBinaryConst*>(item);
773 	    break;
774 	  case vpiRealConst:
775 	    delete dynamic_cast<__vpiRealConst*>(item);
776 	    break;
777 	  default:
778 	    assert(0);
779       }
780 }
781 
parameter_delete(vpiHandle item)782 void parameter_delete(vpiHandle item)
783 {
784       switch(vpi_get(vpiConstType, item)) {
785 	  case vpiStringConst: {
786 	    struct __vpiStringParam*rfp = dynamic_cast<__vpiStringParam*>(item);
787 	    delete rfp;
788 	    break; }
789 	  case vpiBinaryConst: {
790 	    struct __vpiBinaryParam*rfp = dynamic_cast<__vpiBinaryParam*>(item);
791 	    delete rfp;
792 	    break; }
793 	  case vpiRealConst: {
794 	    struct __vpiRealParam*rfp = dynamic_cast<__vpiRealParam*>(item);
795 	    delete rfp;
796 	    break; }
797 	  default:
798 	    assert(0);
799       }
800 }
801 #endif
802