Code generation and runtime for class shallow copy.
This commit is contained in:
parent
8e559e4e91
commit
ac78ba588f
|
|
@ -90,6 +90,23 @@ static int eval_object_property(ivl_expr_t expr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int eval_object_shallowcopy(ivl_expr_t ex)
|
||||||
|
{
|
||||||
|
ivl_expr_t dest = ivl_expr_oper1(ex);
|
||||||
|
ivl_expr_t src = ivl_expr_oper2(ex);
|
||||||
|
|
||||||
|
draw_eval_object(dest);
|
||||||
|
draw_eval_object(src);
|
||||||
|
|
||||||
|
/* The %scopy opcode pops the top of the object stack as the
|
||||||
|
source object, and shallow-copies it to the new top, the
|
||||||
|
destination object. The destination is left on the top of
|
||||||
|
the stack. */
|
||||||
|
fprintf(vvp_out, " %%scopy;\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int eval_object_signal(ivl_expr_t ex)
|
static int eval_object_signal(ivl_expr_t ex)
|
||||||
{
|
{
|
||||||
ivl_signal_t sig = ivl_expr_signal(ex);
|
ivl_signal_t sig = ivl_expr_signal(ex);
|
||||||
|
|
@ -125,6 +142,9 @@ int draw_eval_object(ivl_expr_t ex)
|
||||||
case IVL_EX_PROPERTY:
|
case IVL_EX_PROPERTY:
|
||||||
return eval_object_property(ex);
|
return eval_object_property(ex);
|
||||||
|
|
||||||
|
case IVL_EX_SHALLOWCOPY:
|
||||||
|
return eval_object_shallowcopy(ex);
|
||||||
|
|
||||||
case IVL_EX_SIGNAL:
|
case IVL_EX_SIGNAL:
|
||||||
return eval_object_signal(ex);
|
return eval_object_signal(ex);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,9 @@ class class_property_t {
|
||||||
virtual void set_object(char*buf, const vvp_object_t&val);
|
virtual void set_object(char*buf, const vvp_object_t&val);
|
||||||
virtual void get_object(char*buf, vvp_object_t&val);
|
virtual void get_object(char*buf, vvp_object_t&val);
|
||||||
|
|
||||||
|
// Implement polymorphic shallow copy.
|
||||||
|
virtual void copy(char*buf, char*src) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
size_t offset_;
|
size_t offset_;
|
||||||
};
|
};
|
||||||
|
|
@ -134,6 +137,8 @@ template <class T> class property_atom : public class_property_t {
|
||||||
|
|
||||||
void set_vec4(char*buf, const vvp_vector4_t&val);
|
void set_vec4(char*buf, const vvp_vector4_t&val);
|
||||||
void get_vec4(char*buf, vvp_vector4_t&val);
|
void get_vec4(char*buf, vvp_vector4_t&val);
|
||||||
|
|
||||||
|
void copy(char*dst, char*src);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T> class property_real : public class_property_t {
|
template <class T> class property_real : public class_property_t {
|
||||||
|
|
@ -151,6 +156,8 @@ template <class T> class property_real : public class_property_t {
|
||||||
|
|
||||||
void set_real(char*buf, double val);
|
void set_real(char*buf, double val);
|
||||||
double get_real(char*buf);
|
double get_real(char*buf);
|
||||||
|
|
||||||
|
void copy(char*dst, char*src);
|
||||||
};
|
};
|
||||||
|
|
||||||
class property_string : public class_property_t {
|
class property_string : public class_property_t {
|
||||||
|
|
@ -171,6 +178,8 @@ class property_string : public class_property_t {
|
||||||
|
|
||||||
void set_string(char*buf, const string&);
|
void set_string(char*buf, const string&);
|
||||||
string get_string(char*buf);
|
string get_string(char*buf);
|
||||||
|
|
||||||
|
void copy(char*dst, char*src);
|
||||||
};
|
};
|
||||||
|
|
||||||
class property_object : public class_property_t {
|
class property_object : public class_property_t {
|
||||||
|
|
@ -191,6 +200,8 @@ class property_object : public class_property_t {
|
||||||
|
|
||||||
void set_object(char*buf, const vvp_object_t&);
|
void set_object(char*buf, const vvp_object_t&);
|
||||||
void get_object(char*buf, vvp_object_t&);
|
void get_object(char*buf, vvp_object_t&);
|
||||||
|
|
||||||
|
void copy(char*dst, char*src);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T> void property_atom<T>::set_vec4(char*buf, const vvp_vector4_t&val)
|
template <class T> void property_atom<T>::set_vec4(char*buf, const vvp_vector4_t&val)
|
||||||
|
|
@ -216,6 +227,13 @@ template <class T> void property_atom<T>::get_vec4(char*buf, vvp_vector4_t&val)
|
||||||
val.setarray(0, val.size(), tmp);
|
val.setarray(0, val.size(), tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T> void property_atom<T>::copy(char*dst, char*src)
|
||||||
|
{
|
||||||
|
T*dst_obj = reinterpret_cast<T*> (dst+offset_);
|
||||||
|
T*src_obj = reinterpret_cast<T*> (src+offset_);
|
||||||
|
*dst_obj = *src_obj;
|
||||||
|
}
|
||||||
|
|
||||||
template <class T> void property_real<T>::set_real(char*buf, double val)
|
template <class T> void property_real<T>::set_real(char*buf, double val)
|
||||||
{
|
{
|
||||||
T*tmp = reinterpret_cast<T*>(buf+offset_);
|
T*tmp = reinterpret_cast<T*>(buf+offset_);
|
||||||
|
|
@ -228,6 +246,13 @@ template <class T> double property_real<T>::get_real(char*buf)
|
||||||
return *tmp;
|
return *tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T> void property_real<T>::copy(char*dst, char*src)
|
||||||
|
{
|
||||||
|
T*dst_obj = reinterpret_cast<T*> (dst+offset_);
|
||||||
|
T*src_obj = reinterpret_cast<T*> (src+offset_);
|
||||||
|
*dst_obj = *src_obj;
|
||||||
|
}
|
||||||
|
|
||||||
void property_string::set_string(char*buf, const string&val)
|
void property_string::set_string(char*buf, const string&val)
|
||||||
{
|
{
|
||||||
string*tmp = reinterpret_cast<string*>(buf+offset_);
|
string*tmp = reinterpret_cast<string*>(buf+offset_);
|
||||||
|
|
@ -240,6 +265,13 @@ string property_string::get_string(char*buf)
|
||||||
return *tmp;
|
return *tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void property_string::copy(char*dst, char*src)
|
||||||
|
{
|
||||||
|
string*dst_obj = reinterpret_cast<string*> (dst+offset_);
|
||||||
|
string*src_obj = reinterpret_cast<string*> (src+offset_);
|
||||||
|
*dst_obj = *src_obj;
|
||||||
|
}
|
||||||
|
|
||||||
void property_object::set_object(char*buf, const vvp_object_t&val)
|
void property_object::set_object(char*buf, const vvp_object_t&val)
|
||||||
{
|
{
|
||||||
vvp_object_t*tmp = reinterpret_cast<vvp_object_t*>(buf+offset_);
|
vvp_object_t*tmp = reinterpret_cast<vvp_object_t*>(buf+offset_);
|
||||||
|
|
@ -252,6 +284,12 @@ void property_object::get_object(char*buf, vvp_object_t&val)
|
||||||
val = *tmp;
|
val = *tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void property_object::copy(char*dst, char*src)
|
||||||
|
{
|
||||||
|
vvp_object_t*dst_obj = reinterpret_cast<vvp_object_t*>(dst);
|
||||||
|
vvp_object_t*src_obj = reinterpret_cast<vvp_object_t*>(src);
|
||||||
|
*dst_obj = *src_obj;
|
||||||
|
}
|
||||||
|
|
||||||
/* **** */
|
/* **** */
|
||||||
|
|
||||||
|
|
@ -404,6 +442,16 @@ void class_type::get_object(class_type::inst_t obj, size_t pid, vvp_object_t&val
|
||||||
properties_[pid].type->get_object(buf, val);
|
properties_[pid].type->get_object(buf, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void class_type::copy_property(class_type::inst_t dst, size_t pid, class_type::inst_t src) const
|
||||||
|
{
|
||||||
|
char*dst_buf = reinterpret_cast<char*> (dst);
|
||||||
|
char*src_buf = reinterpret_cast<char*> (src);
|
||||||
|
|
||||||
|
assert(pid < properties_.size());
|
||||||
|
|
||||||
|
properties_[pid].type->copy(dst_buf, src_buf);
|
||||||
|
}
|
||||||
|
|
||||||
int class_type::get_type_code(void) const
|
int class_type::get_type_code(void) const
|
||||||
{
|
{
|
||||||
return vpiClassDefn;
|
return vpiClassDefn;
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,8 @@ class class_type : public __vpiHandle {
|
||||||
void set_object(inst_t inst, size_t pid, const vvp_object_t&val) const;
|
void set_object(inst_t inst, size_t pid, const vvp_object_t&val) const;
|
||||||
void get_object(inst_t inst, size_t pid, vvp_object_t&val) const;
|
void get_object(inst_t inst, size_t pid, vvp_object_t&val) const;
|
||||||
|
|
||||||
|
void copy_property(inst_t dst, size_t idx, inst_t src) const;
|
||||||
|
|
||||||
public: // VPI related methods
|
public: // VPI related methods
|
||||||
int get_type_code(void) const;
|
int get_type_code(void) const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -176,6 +176,7 @@ extern bool of_PUTC_STR_V(vthread_t thr, vvp_code_t code);
|
||||||
extern bool of_RELEASE_NET(vthread_t thr, vvp_code_t code);
|
extern bool of_RELEASE_NET(vthread_t thr, vvp_code_t code);
|
||||||
extern bool of_RELEASE_REG(vthread_t thr, vvp_code_t code);
|
extern bool of_RELEASE_REG(vthread_t thr, vvp_code_t code);
|
||||||
extern bool of_RELEASE_WR(vthread_t thr, vvp_code_t code);
|
extern bool of_RELEASE_WR(vthread_t thr, vvp_code_t code);
|
||||||
|
extern bool of_SCOPY(vthread_t thr, vvp_code_t code);
|
||||||
extern bool of_SET_AV(vthread_t thr, vvp_code_t code);
|
extern bool of_SET_AV(vthread_t thr, vvp_code_t code);
|
||||||
extern bool of_SET_DAR(vthread_t thr, vvp_code_t code);
|
extern bool of_SET_DAR(vthread_t thr, vvp_code_t code);
|
||||||
extern bool of_SET_VEC(vthread_t thr, vvp_code_t code);
|
extern bool of_SET_VEC(vthread_t thr, vvp_code_t code);
|
||||||
|
|
|
||||||
|
|
@ -224,6 +224,7 @@ static const struct opcode_table_s opcode_table[] = {
|
||||||
{ "%release/net",of_RELEASE_NET,3,{OA_FUNC_PTR,OA_BIT1,OA_BIT2} },
|
{ "%release/net",of_RELEASE_NET,3,{OA_FUNC_PTR,OA_BIT1,OA_BIT2} },
|
||||||
{ "%release/reg",of_RELEASE_REG,3,{OA_FUNC_PTR,OA_BIT1,OA_BIT2} },
|
{ "%release/reg",of_RELEASE_REG,3,{OA_FUNC_PTR,OA_BIT1,OA_BIT2} },
|
||||||
{ "%release/wr",of_RELEASE_WR,2,{OA_FUNC_PTR,OA_BIT1,OA_NONE} },
|
{ "%release/wr",of_RELEASE_WR,2,{OA_FUNC_PTR,OA_BIT1,OA_NONE} },
|
||||||
|
{ "%scopy", of_SCOPY, 0, {OA_NONE, OA_NONE, OA_NONE} },
|
||||||
{ "%set/av", of_SET_AV, 3, {OA_ARR_PTR, OA_BIT1, OA_BIT2} },
|
{ "%set/av", of_SET_AV, 3, {OA_ARR_PTR, OA_BIT1, OA_BIT2} },
|
||||||
{ "%set/dar",of_SET_DAR,3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
|
{ "%set/dar",of_SET_DAR,3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
|
||||||
{ "%set/v", of_SET_VEC,3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
|
{ "%set/v", of_SET_VEC,3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
|
||||||
|
|
|
||||||
|
|
@ -4809,6 +4809,17 @@ bool of_RELEASE_WR(vthread_t, vvp_code_t cp)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool of_SCOPY(vthread_t thr, vvp_code_t)
|
||||||
|
{
|
||||||
|
vvp_object_t tmp;
|
||||||
|
thr->pop_object(tmp);
|
||||||
|
|
||||||
|
vvp_object_t&dest = thr->peek_object();
|
||||||
|
dest.shallow_copy(tmp);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This implements the "%set/av <label>, <bit>, <wid>" instruction. In
|
* This implements the "%set/av <label>, <bit>, <wid>" instruction. In
|
||||||
* this case, the <label> is an array label, and the <bit> and <wid>
|
* this case, the <label> is an array label, and the <bit> and <wid>
|
||||||
|
|
|
||||||
|
|
@ -74,3 +74,15 @@ void vvp_cobject::get_object(size_t pid, vvp_object_t&val)
|
||||||
{
|
{
|
||||||
return defn_->get_object(properties_, pid, val);
|
return defn_->get_object(properties_, pid, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vvp_cobject::shallow_copy(const vvp_object*obj)
|
||||||
|
{
|
||||||
|
const vvp_cobject*that = dynamic_cast<const vvp_cobject*>(obj);
|
||||||
|
assert(that);
|
||||||
|
|
||||||
|
assert(defn_ == that->defn_);
|
||||||
|
|
||||||
|
for (size_t idx = 0 ; idx < defn_->property_count() ; idx += 1)
|
||||||
|
defn_->copy_property(properties_, idx, that->properties_);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,8 @@ class vvp_cobject : public vvp_object {
|
||||||
void set_object(size_t pid, const vvp_object_t&val);
|
void set_object(size_t pid, const vvp_object_t&val);
|
||||||
void get_object(size_t pid, vvp_object_t&val);
|
void get_object(size_t pid, vvp_object_t&val);
|
||||||
|
|
||||||
|
void shallow_copy(const vvp_object*that);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const class_type* defn_;
|
const class_type* defn_;
|
||||||
// For now, only support 32bit bool signed properties.
|
// For now, only support 32bit bool signed properties.
|
||||||
|
|
|
||||||
|
|
@ -34,3 +34,8 @@ vvp_object::~vvp_object()
|
||||||
{
|
{
|
||||||
total_active_cnt_ -= 1;
|
total_active_cnt_ -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vvp_object::shallow_copy(const vvp_object*that)
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,8 @@ class vvp_object {
|
||||||
inline vvp_object() { ref_cnt_ = 0; total_active_cnt_ += 1; }
|
inline vvp_object() { ref_cnt_ = 0; total_active_cnt_ += 1; }
|
||||||
virtual ~vvp_object() =0;
|
virtual ~vvp_object() =0;
|
||||||
|
|
||||||
|
virtual void shallow_copy(const vvp_object*that);
|
||||||
|
|
||||||
static void cleanup(void);
|
static void cleanup(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -59,6 +61,8 @@ class vvp_object_t {
|
||||||
inline bool operator != (const vvp_object_t&that) const
|
inline bool operator != (const vvp_object_t&that) const
|
||||||
{ return ref_ != that.ref_; }
|
{ return ref_ != that.ref_; }
|
||||||
|
|
||||||
|
inline void shallow_copy(const vvp_object_t&that)
|
||||||
|
{ ref_->shallow_copy(that.ref_); }
|
||||||
template <class T> T*peek(void) const;
|
template <class T> T*peek(void) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue