From d6fca81058c6c5f6a27ecd66d0f756edbe50e576 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sat, 21 Jan 2012 11:59:49 -0800 Subject: [PATCH] More cleanup of __vpiHandle classes. --- vvp/array.cc | 30 +++---- vvp/compile.cc | 1 + vvp/delay.cc | 13 ++- vvp/vpi_callback.cc | 14 --- vvp/vpi_const.cc | 208 ++++++++++++++++++++++++++------------------ vvp/vpi_priv.cc | 16 ++-- vvp/vpi_priv.h | 23 ++--- 7 files changed, 161 insertions(+), 144 deletions(-) diff --git a/vvp/array.cc b/vvp/array.cc index a478dcae4..b952347e2 100644 --- a/vvp/array.cc +++ b/vvp/array.cc @@ -298,10 +298,8 @@ struct __vpiArrayWord { static void array_make_vals_words(struct __vpiArray*parent); static vpiHandle array_iterator_scan(vpiHandle ref, int); -static int array_iterator_free_object(vpiHandle ref); static vpiHandle array_index_scan(vpiHandle ref, int); -static int array_index_free_object(vpiHandle ref); static int vpi_array_var_word_get(int code, vpiHandle); static char*vpi_array_var_word_get_str(int code, vpiHandle); @@ -442,6 +440,13 @@ vpiHandle __vpiArrayIterator::vpi_index(int) } +static int array_iterator_free_object(vpiHandle ref) +{ + struct __vpiArrayIterator*obj = dynamic_cast<__vpiArrayIterator*>(ref); + delete obj; + return 1; +} + __vpiHandle::free_object_fun_t __vpiArrayIterator::free_object_fun(void) { return &array_iterator_free_object; } @@ -457,6 +462,13 @@ vpiHandle __vpiArrayIndex::vpi_iterate(int code) vpiHandle __vpiArrayIndex::vpi_index(int idx) { return array_index_scan(this, idx); } +static int array_index_free_object(vpiHandle ref) +{ + struct __vpiArrayIndex*obj = dynamic_cast<__vpiArrayIndex*>(ref); + delete obj; + return 1; +} + __vpiHandle::free_object_fun_t __vpiArrayIndex::free_object_fun(void) { return &array_index_free_object; } @@ -703,13 +715,6 @@ static void vpi_array_var_index_get_value(vpiHandle ref, p_vpi_value vp) vp->value.integer = index; } -static int array_iterator_free_object(vpiHandle ref) -{ - struct __vpiArrayIterator*obj = dynamic_cast<__vpiArrayIterator*>(ref); - free(obj); - return 1; -} - vpiHandle array_index_iterate(int code, vpiHandle ref) { struct __vpiDecConst*obj = dynamic_cast<__vpiDecConst*>(ref); @@ -738,13 +743,6 @@ static vpiHandle array_index_scan(vpiHandle ref, int) return 0; } -static int array_index_free_object(vpiHandle ref) -{ - struct __vpiArrayIndex*obj = dynamic_cast<__vpiArrayIndex*>(ref); - free(obj); - return 1; -} - static int vpi_array_vthr_A_get(int code, vpiHandle ref) { struct __vpiArrayVthrA*obj = dynamic_cast<__vpiArrayVthrA*>(ref); diff --git a/vvp/compile.cc b/vvp/compile.cc index a424b20e8..5fc1ba667 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -1822,6 +1822,7 @@ void compile_param_logic(char*label, char*name, char*value, bool signed_flag, void compile_param_string(char*label, char*name, char*value, long file_idx, long lineno) { + // name and value become owned bi vpip_make_string_param vpiHandle obj = vpip_make_string_param(name, value, file_idx, lineno); compile_vpi_symbol(label, obj); vpip_attach_to_current_scope(obj); diff --git a/vvp/delay.cc b/vvp/delay.cc index 856481fcf..0b46cf1ab 100644 --- a/vvp/delay.cc +++ b/vvp/delay.cc @@ -819,13 +819,6 @@ static vpiHandle modpath_src_index ( vpiHandle ref, int) } -static int modpath_src_free_object( vpiHandle ref ) -{ - assert( ref->get_type_code() == vpiModPathIn ); - free ( ref ) ; - return 1 ; -} - /* * This routine will put specific dimension of delay[] values * into a vpiHandle. In this case, we will put @@ -1001,6 +994,12 @@ void __vpiModPathSrc::vpi_get_delays(p_vpi_delay del) void __vpiModPathSrc::vpi_put_delays(p_vpi_delay del) { modpath_src_put_delays(this, del); } +static int modpath_src_free_object( vpiHandle ref ) +{ + delete ref; + return 1 ; +} + __vpiHandle::free_object_fun_t __vpiModPathSrc::free_object_fun(void) { return &modpath_src_free_object; } diff --git a/vvp/vpi_callback.cc b/vvp/vpi_callback.cc index e8e79c5c6..089f0a5f8 100644 --- a/vvp/vpi_callback.cc +++ b/vvp/vpi_callback.cc @@ -35,17 +35,6 @@ # include # include -/* -* The vpi_free_object() call to a callback doesn't actually delete -* anything, we instead allow the object to run its course and delete -* itself. The semantics of vpi_free_object for a callback is that it -* deletes the *handle*, and not the object itself, so given the vvp -* implementation, there is nothing to do here. -*/ -static int free_simple_callback(vpiHandle) -{ - return 1; -} inline __vpiCallback::__vpiCallback() { } @@ -53,9 +42,6 @@ inline __vpiCallback::__vpiCallback() int __vpiCallback::get_type_code(void) const { return vpiCallback; } -__vpiHandle::free_object_fun_t __vpiCallback::free_object_fun(void) -{ return &free_simple_callback; } - /* * Callback handles are created when the VPI function registers a diff --git a/vvp/vpi_const.cc b/vvp/vpi_const.cc index 7b9b94ebd..f7071de3b 100644 --- a/vvp/vpi_const.cc +++ b/vvp/vpi_const.cc @@ -29,9 +29,62 @@ # include # include "ivl_alloc.h" +class __vpiStringConst : public __vpiHandle { + public: + __vpiStringConst(char*val); + ~__vpiStringConst(); + int get_type_code(void) const; + int vpi_get(int code); + void vpi_get_value(p_vpi_value val); -inline __vpiStringConst::__vpiStringConst() -{ } + private: + void process_string_(); + private: + char*value_; + size_t value_len_; +}; + +inline __vpiStringConst::__vpiStringConst(char*v) +: value_(v) +{ + process_string_(); +} + +/* + * Strings are described at the level of the vvp source as a string + * with literal characters or octal escapes. No other escapes are + * included, they are processed already by the compiler that generated + * the vvp source. + */ +void __vpiStringConst::process_string_(void) +{ + char*chr = value_; + char*dp = value_; + + while (*chr) { + char next_char = *chr; + + /* Process octal escapes that I might find. */ + if (*chr == '\\') { + for (int idx = 1 ; idx <= 3 ; idx += 1) { + assert(chr[idx] != 0); + assert(chr[idx] < '8'); + assert(chr[idx] >= '0'); + next_char = next_char*8 + chr[idx] - '0'; + } + chr += 3; + } + *dp++ = next_char; + chr += 1; + } + *dp = 0; + value_len_ = dp - value_; +} + +__vpiStringConst::~__vpiStringConst() +{ + delete[]value_; +} int __vpiStringConst::get_type_code(void) const { return vpiConstant; } @@ -40,7 +93,7 @@ int __vpiStringConst::vpi_get(int code) { switch (code) { case vpiSize: - return strlen(value)*8; + return strlen(value_)*8; case vpiSigned: return 0; @@ -68,7 +121,7 @@ void __vpiStringConst::vpi_get_value(p_vpi_value vp) { unsigned uint_value; p_vpi_vecval vecp; - int size = strlen(value); + int size = strlen(value_); char*rbuf = 0; char*cp; @@ -79,7 +132,7 @@ void __vpiStringConst::vpi_get_value(p_vpi_value vp) case vpiStringVal: rbuf = need_result_buf(size + 1, RBUF_VAL); - strcpy(rbuf, (char*)value); + strcpy(rbuf, value_); vp->value.str = rbuf; break; @@ -94,7 +147,7 @@ void __vpiStringConst::vpi_get_value(p_vpi_value vp) uint_value = 0; for(int i=0; ivalue.str = rbuf; @@ -105,7 +158,7 @@ void __vpiStringConst::vpi_get_value(p_vpi_value vp) cp = rbuf; for(int i=0; i=0; bit--){ - *cp++ = "01"[ (value[i]>>bit)&1 ]; + *cp++ = "01"[ (value_[i]>>bit)&1 ]; } } *cp = 0; @@ -117,7 +170,7 @@ void __vpiStringConst::vpi_get_value(p_vpi_value vp) cp = rbuf; for(int i=0; i=0; nibble--){ - *cp++ = "0123456789abcdef"[ (value[i]>>(nibble*4))&15 ]; + *cp++ = "0123456789abcdef"[ (value_[i]>>(nibble*4))&15 ]; } } *cp = 0; @@ -134,7 +187,7 @@ void __vpiStringConst::vpi_get_value(p_vpi_value vp) for(int i=0; i=0; bit--){ vp->value.integer <<= 1; - vp->value.integer += (value[i]>>bit)&1; + vp->value.integer += (value_[i]>>bit)&1; } } break; @@ -148,7 +201,7 @@ void __vpiStringConst::vpi_get_value(p_vpi_value vp) vecp = vp->value.vector; vecp->aval = vecp->bval = 0; for(int i=0; iaval |= value[i] << uint_value*8; + vecp->aval |= value_[i] << uint_value*8; uint_value += 1; if (uint_value > 3) { uint_value = 0; @@ -171,81 +224,56 @@ void __vpiStringConst::vpi_get_value(p_vpi_value vp) struct __vpiStringConstTEMP : public __vpiStringConst { - inline __vpiStringConstTEMP() { } + inline __vpiStringConstTEMP(char*v) : __vpiStringConst(v) { } free_object_fun_t free_object_fun(void); }; static int free_temp_string(vpiHandle obj) { struct __vpiStringConstTEMP*rfp = dynamic_cast<__vpiStringConstTEMP*>(obj); - - delete [] rfp->value; - free(rfp); + delete rfp; return 1; } __vpiHandle::free_object_fun_t __vpiStringConstTEMP::free_object_fun(void) { return &free_temp_string; } -/* - * Strings are described at the level of the vvp source as a string - * with literal characters or octal escapes. No other escapes are - * included, they are processed already by the compiler that generated - * the vvp source. - */ -static void vpip_process_string(struct __vpiStringConst*obj) -{ - char*chr = obj->value; - char*dp = obj->value; - - while (*chr) { - char next_char = *chr; - - /* Process octal escapes that I might find. */ - if (*chr == '\\') { - for (int idx = 1 ; idx <= 3 ; idx += 1) { - assert(chr[idx] != 0); - assert(chr[idx] < '8'); - assert(chr[idx] >= '0'); - next_char = next_char*8 + chr[idx] - '0'; - } - chr += 3; - } - *dp++ = next_char; - chr += 1; - } - *dp = 0; - obj->value_len = dp - obj->value; -} - vpiHandle vpip_make_string_const(char*text, bool persistent_flag) { struct __vpiStringConst*obj; - obj = persistent_flag? new __vpiStringConst : new __vpiStringConstTEMP; - obj->value = text; - obj->value_len = 0; - vpip_process_string(obj); + obj = persistent_flag? new __vpiStringConst(text) : new __vpiStringConstTEMP(text); return obj; } -struct __vpiStringParam : public __vpiStringConst { - __vpiStringParam(); +class __vpiStringParam : public __vpiStringConst { + public: + __vpiStringParam(char*txt, char*name); + ~__vpiStringParam(); int get_type_code(void) const; int vpi_get(int code); char*vpi_get_str(int code); vpiHandle vpi_handle(int code); - const char*basename; struct __vpiScope* scope; unsigned file_idx; unsigned lineno; + private: + const char*basename_; }; -inline __vpiStringParam::__vpiStringParam() -{ } +inline __vpiStringParam::__vpiStringParam(char*txt, char*nam) +: __vpiStringConst(txt) +{ + basename_ = nam; +} + +__vpiStringParam::~__vpiStringParam() +{ + delete[]basename_; +} int __vpiStringParam::get_type_code(void) const { return vpiParameter; } @@ -265,7 +293,7 @@ char*__vpiStringParam::vpi_get_str(int code) return simple_set_rbuf_str(file_names[file_idx]); } - return generic_get_str(code, scope, basename, NULL); + return generic_get_str(code, scope, basename_, NULL); } @@ -286,16 +314,11 @@ vpiHandle __vpiStringParam::vpi_handle(int code) vpiHandle vpip_make_string_param(char*name, char*text, long file_idx, long lineno) { - struct __vpiStringParam*obj = new __vpiStringParam; - obj->value = text; - obj->value_len = 0; - obj->basename = name; + struct __vpiStringParam*obj = new __vpiStringParam(text, name); obj->scope = vpip_peek_current_scope(); obj->file_idx = (unsigned) file_idx; obj->lineno = (unsigned) lineno; - vpip_process_string(obj); - return obj; } @@ -416,20 +439,30 @@ vvp_vector4_t vector4_from_text(const char*bits, unsigned wid) } struct __vpiBinaryParam : public __vpiBinaryConst { - __vpiBinaryParam(); + __vpiBinaryParam(const vvp_vector4_t&b, char*name); + ~__vpiBinaryParam(); int get_type_code(void) const; int vpi_get(int code); char*vpi_get_str(int code); vpiHandle vpi_handle(int code); - const char*basename; struct __vpiScope*scope; unsigned file_idx; unsigned lineno; + private: + char*basename_; }; -inline __vpiBinaryParam::__vpiBinaryParam() -{ } +inline __vpiBinaryParam::__vpiBinaryParam(const vvp_vector4_t&b, char*nam) +{ + bits = b; + basename_ = nam; +} + +__vpiBinaryParam::~__vpiBinaryParam() +{ + delete[]basename_; +} int __vpiBinaryParam::get_type_code(void) const { return vpiParameter; } @@ -447,7 +480,7 @@ char*__vpiBinaryParam::vpi_get_str(int code) if (code == vpiFile) return simple_set_rbuf_str(file_names[file_idx]); - return generic_get_str(code, scope, basename, NULL); + return generic_get_str(code, scope, basename_, NULL); } @@ -470,12 +503,10 @@ vpiHandle vpip_make_binary_param(char*name, const vvp_vector4_t&bits, bool signed_flag, long file_idx, long lineno) { - struct __vpiBinaryParam*obj = new __vpiBinaryParam; + struct __vpiBinaryParam*obj = new __vpiBinaryParam(bits, name); - obj->bits = bits; obj->signed_flag = signed_flag? 1 : 0; obj->sized_flag = 0; - obj->basename = name; obj->scope = vpip_peek_current_scope(); obj->file_idx = (unsigned) file_idx; obj->lineno = (unsigned) lineno; @@ -571,7 +602,8 @@ void __vpiDecConst::vpi_get_value(p_vpi_value vp) } -inline __vpiRealConst::__vpiRealConst() +inline __vpiRealConst::__vpiRealConst(double val) +: value(val) { } int __vpiRealConst::get_type_code(void) const @@ -617,27 +649,37 @@ void __vpiRealConst::vpi_get_value(p_vpi_value val) vpiHandle vpip_make_real_const(double value) { - struct __vpiRealConst*obj = new __vpiRealConst; - obj->value = value; + struct __vpiRealConst*obj = new __vpiRealConst(value); return obj; } struct __vpiRealParam : public __vpiRealConst { - __vpiRealParam(); + __vpiRealParam(double val, char*name); + ~__vpiRealParam(); int get_type_code(void) const; int vpi_get(int code); char*vpi_get_str(int code); vpiHandle vpi_handle(int code); - const char*basename; struct __vpiScope* scope; unsigned file_idx; unsigned lineno; + private: + const char*basename_; }; -inline __vpiRealParam::__vpiRealParam() -{ } +inline __vpiRealParam::__vpiRealParam(double val, char*name) +: __vpiRealConst(val) +{ + basename_ = name; +} + +__vpiRealParam::~__vpiRealParam() +{ + delete[]basename_; +} + int __vpiRealParam::get_type_code(void) const { return vpiParameter; } @@ -655,7 +697,7 @@ char* __vpiRealParam::vpi_get_str(int code) if (code == vpiFile) return simple_set_rbuf_str(file_names[file_idx]); - return generic_get_str(code, scope, basename, NULL); + return generic_get_str(code, scope, basename_, NULL); } vpiHandle __vpiRealParam::vpi_handle(int code) @@ -676,10 +718,8 @@ vpiHandle __vpiRealParam::vpi_handle(int code) vpiHandle vpip_make_real_param(char*name, double value, long file_idx, long lineno) { - struct __vpiRealParam*obj = new __vpiRealParam; + struct __vpiRealParam*obj = new __vpiRealParam(value, name); - obj->value = value; - obj->basename = name; obj->scope = vpip_peek_current_scope(); obj->file_idx = (unsigned) file_idx; obj->lineno = (unsigned) lineno; @@ -719,19 +759,15 @@ void parameter_delete(vpiHandle item) switch(vpi_get(vpiConstType, item)) { case vpiStringConst: { struct __vpiStringParam*rfp = dynamic_cast<__vpiStringParam*>(item); - delete [] rfp->basename; - delete [] rfp->value; - free(rfp); + delete rfp; break; } case vpiBinaryConst: { struct __vpiBinaryParam*rfp = dynamic_cast<__vpiBinaryParam*>(item); - delete [] rfp->basename; delete rfp; break; } case vpiRealConst: { struct __vpiRealParam*rfp = dynamic_cast<__vpiRealParam*>(item); - delete [] rfp->basename; - free(rfp); + delete rfp; break; } default: assert(0); diff --git a/vvp/vpi_priv.cc b/vvp/vpi_priv.cc index 67dc6ba09..0d82b5575 100644 --- a/vvp/vpi_priv.cc +++ b/vvp/vpi_priv.cc @@ -64,8 +64,17 @@ void __vpiHandle::vpi_get_delays(p_vpi_delay) void __vpiHandle::vpi_put_delays(p_vpi_delay) { } +/* + * The default behavior for the vpi_free_object to an object is to + * suppress the actual operation. This is because handles are + * generally allocated semi-permanently within vvp context. Dynamic + * objects will override the free_object_fun method to return an + * appropriately effective function. + */ +static int suppress_free(vpiHandle) +{ return 1; } __vpiHandle::free_object_fun_t __vpiHandle::free_object_fun(void) -{ return 0; } +{ return &suppress_free; } /* * The vpip_string function creates a constant string from the pass @@ -234,10 +243,7 @@ PLI_INT32 vpi_free_object(vpiHandle ref) assert(ref); __vpiHandle::free_object_fun_t fun = ref->free_object_fun(); - if (fun) - rtn = fun (ref); - else - rtn = 1; + rtn = fun (ref); if (vpi_trace) fprintf(vpi_trace, " --> %d\n", rtn); diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index 1c1b53b30..615a5f6e0 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -148,7 +148,6 @@ extern vpiHandle vpip_make_iterator(unsigned nargs, vpiHandle*args, struct __vpiCallback : public __vpiHandle { __vpiCallback(); int get_type_code(void) const; - free_object_fun_t free_object_fun(void); // user supplied callback data struct t_cb_data cb_data; @@ -520,22 +519,13 @@ struct __vpiSysTaskCall : public __vpiHandle { extern struct __vpiSysTaskCall*vpip_cur_task; /* - * These are implemented in vpi_const.cc. These are vpiHandles for - * constants. - * * The persistent flag to vpip_make_string_const causes the created * handle to be persistent. This is necessary for cases where the * string handle may be reused, which is the normal case. + * + * When constructing with a string, the class takes possession of the + * text value string, and will delete it in the constructor. */ -struct __vpiStringConst : public __vpiHandle { - __vpiStringConst(); - int get_type_code(void) const; - int vpi_get(int code); - void vpi_get_value(p_vpi_value val); - - char*value; - size_t value_len; -}; vpiHandle vpip_make_string_const(char*text, bool persistent =true); vpiHandle vpip_make_string_param(char*name, char*value, @@ -568,12 +558,13 @@ struct __vpiDecConst : public __vpiHandle { int value; }; -struct __vpiRealConst : public __vpiHandle { - __vpiRealConst(); +class __vpiRealConst : public __vpiHandle { + public: + __vpiRealConst(double); int get_type_code(void) const; int vpi_get(int code); void vpi_get_value(p_vpi_value val); - + public: double value; };