Add support for darrays as class properties.

This commit is contained in:
Stephen Williams 2013-01-27 12:30:38 -08:00
parent c49b21115a
commit 4568766cff
20 changed files with 358 additions and 20 deletions

View File

@ -518,6 +518,8 @@ class PENumber : public PExpr {
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode); width_mode_t&mode);
virtual NetEConst*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const;
virtual NetEConst*elaborate_expr(Design*des, NetScope*, virtual NetEConst*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid, unsigned) const; unsigned expr_wid, unsigned) const;
virtual NetAssign_* elaborate_lval(Design*des, virtual NetAssign_* elaborate_lval(Design*des,

View File

@ -144,6 +144,7 @@ NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, ivl_type_t, unsigned) cons
<< " elaborate (ivl_type_t) this expression. " << endl; << " elaborate (ivl_type_t) this expression. " << endl;
cerr << get_fileline() << ": : Expression is: " << *this cerr << get_fileline() << ": : Expression is: " << *this
<< endl; << endl;
cerr << get_fileline() << ": : Expression type: " << typeid(*this).name() << endl;
des->errors += 1; des->errors += 1;
return 0; return 0;
} }
@ -1091,11 +1092,13 @@ unsigned PECallFunction::test_width_method_(Design*des, NetScope*scope,
if (path_.size() < 2) if (path_.size() < 2)
return 0; return 0;
perm_string member_name;
ivl_type_t member_type = 0;
pform_name_t use_path = path_; pform_name_t use_path = path_;
perm_string method_name = peek_tail_name(use_path); perm_string method_name = peek_tail_name(use_path);
use_path.pop_back(); use_path.pop_back();
NetNet *net; NetNet *net = 0;
const NetExpr *par; const NetExpr *par;
NetEvent *eve; NetEvent *eve;
const NetExpr *ex1, *ex2; const NetExpr *ex1, *ex2;
@ -1103,13 +1106,54 @@ unsigned PECallFunction::test_width_method_(Design*des, NetScope*scope,
symbol_search(this, des, scope, use_path, symbol_search(this, des, scope, use_path,
net, par, eve, ex1, ex2); net, par, eve, ex1, ex2);
const netdarray_t*use_darray = 0;
if (net != 0)
use_darray = net->darray_type();
// Net is not found, but maybe it is a member of a
// struct or class. Try to locate net without the member
// name and test if it is a type that has members.
if (net == 0 && use_path.size() >= 2) {
pform_name_t tmp_path = use_path;
member_name = peek_tail_name(tmp_path);
tmp_path.pop_back();
net = 0;
symbol_search(this, des, scope, tmp_path,
net, par, eve, ex1, ex2);
if (net && net->class_type()) {
if (debug_elaborate) {
cerr << get_fileline() << ": PECallFunction::test_width_method_: "
<< "Found net=" << tmp_path
<< ", member_name=" << member_name
<< ", method_name=" << method_name
<< endl;
}
netclass_t* class_type = net->class_type();
member_type = class_type->get_property(member_name);
use_path = tmp_path;
use_darray = dynamic_cast<const netdarray_t*> (member_type);
} else {
member_name = perm_string();
net = 0;
}
}
// After all, no sign of a net match. Give up.
if (net == 0) if (net == 0)
return 0; return 0;
netdarray_t*darray = net->darray_type();
// function int size() // function int size()
if (darray && method_name == "size") { if (use_darray && method_name == "size") {
if (debug_elaborate) {
cerr << get_fileline() << ": PECallFunction::test_width_method_: "
<< "Match darray size() method." << endl;
}
expr_type_ = IVL_VT_BOOL; expr_type_ = IVL_VT_BOOL;
expr_width_ = 32; expr_width_ = 32;
min_width_ = expr_width_; min_width_ = expr_width_;
@ -1866,7 +1910,7 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
perm_string method_name = peek_tail_name(use_path); perm_string method_name = peek_tail_name(use_path);
use_path.pop_back(); use_path.pop_back();
NetNet *net; NetNet *net = 0;
const NetExpr *par; const NetExpr *par;
NetEvent *eve; NetEvent *eve;
const NetExpr *ex1, *ex2; const NetExpr *ex1, *ex2;
@ -2570,9 +2614,37 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
net, par, eve, net, par, eve,
ex1, ex2); ex1, ex2);
if (net == 0 && gn_system_verilog() && path_.size() >= 2) {
pform_name_t use_path = path_;
name_component_t member_comp = use_path.back();
use_path.pop_back();
ivl_assert(*this, net == 0);
symbol_search(this, des, scope, use_path, net, par, eve, ex1, ex2);
if (net == 0) {
// Nope, no struct/class with member.
} else if (net->struct_type() != 0) {
return check_for_struct_members(this, des, scope,
net, use_path.back().index,
member_comp);
} else if (net->class_type()!=0) {
if (debug_elaborate) {
cerr << get_fileline() << ": PEIdent::elaborate_expr: "
<< "Ident " << use_path
<< " look for property " << member_comp << endl;
}
return check_for_class_property(this, des, scope,
net, member_comp);
}
}
if (net == 0) { if (net == 0) {
cerr << get_fileline() << ": internal error: " cerr << get_fileline() << ": internal error: "
<< "Expecting idents wtih ntype to be signals." << endl; << "Expecting idents with ntype to be signals." << endl;
des->errors += 1; des->errors += 1;
return 0; return 0;
} }
@ -4192,6 +4264,27 @@ unsigned PENumber::test_width(Design*, NetScope*, width_mode_t&mode)
return expr_width_; return expr_width_;
} }
NetEConst* PENumber::elaborate_expr(Design*des, NetScope*, ivl_type_t ntype, unsigned) const
{
const netvector_t*use_type = dynamic_cast<const netvector_t*> (ntype);
if (use_type == 0) {
cerr << get_fileline() << ": internal error: "
<< "I don't know how cast numbers to this type."
<< endl;
des->errors += 1;
return 0;
}
verinum use_val = value();
use_val .has_sign( use_type->get_signed() );
use_val = cast_to_width(use_val, use_type->packed_width());
NetEConst*tmp = new NetEConst(use_val);
tmp->set_line(*this);
return tmp;
}
NetEConst* PENumber::elaborate_expr(Design*, NetScope*, NetEConst* PENumber::elaborate_expr(Design*, NetScope*,
unsigned expr_wid, unsigned) const unsigned expr_wid, unsigned) const
{ {

View File

@ -25,6 +25,7 @@
# include "netmisc.h" # include "netmisc.h"
# include "netstruct.h" # include "netstruct.h"
# include "netclass.h" # include "netclass.h"
# include "netdarray.h"
# include "compiler.h" # include "compiler.h"
# include <cstdlib> # include <cstdlib>
# include <iostream> # include <iostream>
@ -716,7 +717,7 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
return true; return true;
} }
bool PEIdent::elaborate_lval_net_class_member_(Design*des, NetScope*, bool PEIdent::elaborate_lval_net_class_member_(Design*des, NetScope*scope,
NetAssign_*lv, NetAssign_*lv,
const perm_string&method_name) const const perm_string&method_name) const
{ {
@ -740,6 +741,18 @@ bool PEIdent::elaborate_lval_net_class_member_(Design*des, NetScope*,
} }
lv->set_property(method_name); lv->set_property(method_name);
const netdarray_t*mtype = dynamic_cast<const netdarray_t*> (ptype);
if (mtype) {
const name_component_t&name_tail = path_.back();
if (name_tail.index.size() > 0) {
cerr << get_fileline() << ": sorry: "
<< "Array index of array properties not supported."
<< endl;
des->errors += 1;
}
}
return true; return true;
} }

View File

@ -865,7 +865,7 @@ static bool evaluate_ranges(Design*des, NetScope*scope,
return bad_msb | bad_lsb; return bad_msb | bad_lsb;
} }
static netclass_t* locate_class_type(Design*des, NetScope*scope, static netclass_t* locate_class_type(Design*, NetScope*scope,
class_type_t*class_type) class_type_t*class_type)
{ {
netclass_t*use_class = scope->find_class(class_type->name); netclass_t*use_class = scope->find_class(class_type->name);
@ -928,7 +928,7 @@ static netparray_t* elaborate_parray_type(Design*des, NetScope*scope,
{ {
vector<netrange_t>packed_dimensions; vector<netrange_t>packed_dimensions;
bool bad_range = evaluate_ranges(des, scope, packed_dimensions, * data_type->packed_dims); bool bad_range = evaluate_ranges(des, scope, packed_dimensions, * data_type->dims);
ivl_assert(*data_type, !bad_range); ivl_assert(*data_type, !bad_range);
ivl_type_s*element_type = elaborate_type(des, scope, data_type->base_type); ivl_type_s*element_type = elaborate_type(des, scope, data_type->base_type);

View File

@ -19,6 +19,7 @@
# include "pform_types.h" # include "pform_types.h"
# include "netlist.h" # include "netlist.h"
# include "netdarray.h"
# include "netscalar.h" # include "netscalar.h"
# include "netvector.h" # include "netvector.h"
# include <typeinfo> # include <typeinfo>
@ -85,3 +86,15 @@ ivl_type_s* string_type_t::elaborate_type(Design*, NetScope*) const
{ {
return &netstring_t::type_string; return &netstring_t::type_string;
} }
ivl_type_s* uarray_type_t::elaborate_type(Design*des, NetScope*scope) const
{
ivl_type_t btype = base_type->elaborate_type(des, scope);
assert(dims->size() == 1);
list<pform_range_t>::const_iterator cur = dims->begin();
assert(cur->first == 0 && cur->second==0);
ivl_type_s*res = new netdarray_t(btype);
return res;
}

View File

@ -2381,6 +2381,14 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
NetExpr*rv; NetExpr*rv;
const ivl_type_s*lv_net_type = lv->net_type(); const ivl_type_s*lv_net_type = lv->net_type();
if (debug_elaborate) {
cerr << get_fileline() << ": PAssign::elaborate: ";
if (lv_net_type)
cerr << "lv_net_type=" << *lv_net_type << endl;
else
cerr << "lv_net_type=<nil>" << endl;
}
/* If the l-value is a compound type of some sort, then use /* If the l-value is a compound type of some sort, then use
the newer net_type form of the elaborate_rval_ method to the newer net_type form of the elaborate_rval_ method to
handle the new types. */ handle the new types. */
@ -2388,9 +2396,21 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
ivl_assert(*this, lv->more==0); ivl_assert(*this, lv->more==0);
rv = elaborate_rval_(des, scope, lv_net_type); rv = elaborate_rval_(des, scope, lv_net_type);
} else if (dynamic_cast<const netdarray_t*> (lv_net_type)) { } else if (const netdarray_t*dtype = dynamic_cast<const netdarray_t*> (lv_net_type)) {
ivl_assert(*this, lv->more==0); ivl_assert(*this, lv->more==0);
rv = elaborate_rval_(des, scope, lv_net_type); if (debug_elaborate) {
if (lv->word())
cerr << get_fileline() << ": PAssign::elaborate: "
<< "lv->word() = " << *lv->word() << endl;
else
cerr << get_fileline() << ": PAssign::elaborate: "
<< "lv->word() = <nil>" << endl;
}
ivl_type_t use_lv_type = lv_net_type;
if (lv->word())
use_lv_type = dtype->element_type();
rv = elaborate_rval_(des, scope, use_lv_type);
} else { } else {
/* Elaborate the r-value expression, then try to evaluate it. */ /* Elaborate the r-value expression, then try to evaluate it. */

View File

@ -154,6 +154,13 @@ void parray_type_t::pform_dump(ostream&out, unsigned indent) const
base_type->pform_dump(out, indent+4); base_type->pform_dump(out, indent+4);
} }
void uarray_type_t::pform_dump(ostream&out, unsigned indent) const
{
out << setw(indent) << "" << "Unpacked array " << "[...]"
<< " of:" << endl;
base_type->pform_dump(out, indent+4);
}
void struct_type_t::pform_dump(ostream&out, unsigned indent) const void struct_type_t::pform_dump(ostream&out, unsigned indent) const
{ {
out << setw(indent) << "" << "Struct " << (packed_flag?"packed":"unpacked") out << setw(indent) << "" << "Struct " << (packed_flag?"packed":"unpacked")

View File

@ -57,7 +57,18 @@ void pform_class_property(const struct vlltype&loc,
; cur != decls->end() ; ++cur) { ; cur != decls->end() ; ++cur) {
decl_assignment_t*curp = *cur; decl_assignment_t*curp = *cur;
pform_cur_class->type->properties[curp->name] = data_type; data_type_t*use_type = data_type;
if (curp->index.size() > 0) {
list<pform_range_t>*pd = new list<pform_range_t> (curp->index);
use_type = new uarray_type_t(use_type, pd);
}
if (curp->expr.get()) {
VLerror(loc, "sorry: Initialization expressions for properties not implemented.");
}
pform_cur_class->type->properties[curp->name] = use_type;
} }
} }

View File

@ -154,20 +154,39 @@ struct vector_type_t : public data_type_t {
std::auto_ptr< list<pform_range_t> > pdims; std::auto_ptr< list<pform_range_t> > pdims;
}; };
struct array_base_t : public data_type_t {
public:
inline explicit array_base_t(data_type_t*btype, std::list<pform_range_t>*pd)
: base_type(btype), dims(pd) { }
data_type_t*base_type;
std::auto_ptr< list<pform_range_t> > dims;
};
/* /*
* The array_type_t is a generalization of the vector_type_t in that * The parray_type_t is a generalization of the vector_type_t in that
* the base type is another general data type. Ultimately, the subtype * the base type is another general data type. Ultimately, the subtype
* must also be packed (as this is a packed array) but that may be * must also be packed (as this is a packed array) but that may be
* worked out during elaboration. * worked out during elaboration.
*/ */
struct parray_type_t : public data_type_t { struct parray_type_t : public array_base_t {
inline explicit parray_type_t(data_type_t*btype, std::list<pform_range_t>*pd) inline explicit parray_type_t(data_type_t*btype, std::list<pform_range_t>*pd)
: base_type(btype), packed_dims(pd) { } : array_base_t(btype, pd) { }
virtual ivl_variable_type_t figure_packed_base_type(void)const; virtual ivl_variable_type_t figure_packed_base_type(void)const;
virtual void pform_dump(std::ostream&out, unsigned indent) const; virtual void pform_dump(std::ostream&out, unsigned indent) const;
};
data_type_t*base_type; /*
std::auto_ptr< list<pform_range_t> > packed_dims; * The uarray_type_t represents unpacked array types.
*/
struct uarray_type_t : public array_base_t {
inline explicit uarray_type_t(data_type_t*btype, std::list<pform_range_t>*pd)
: array_base_t(btype, pd) { }
public:
virtual void pform_dump(std::ostream&out, unsigned indent) const;
virtual ivl_type_s* elaborate_type(Design*des, NetScope*scope) const;
}; };
struct real_type_t : public data_type_t { struct real_type_t : public data_type_t {

View File

@ -61,9 +61,13 @@ static void show_prop_type(ivl_type_t ptype)
case IVL_VT_LOGIC: case IVL_VT_LOGIC:
show_prop_type_vector(ptype); show_prop_type_vector(ptype);
break; break;
case IVL_VT_DARRAY:
case IVL_VT_CLASS:
fprintf(vvp_out, "\"o\"");
break;
default: default:
assert(0);
fprintf(vvp_out, "\"<ERROR-no-type>\""); fprintf(vvp_out, "\"<ERROR-no-type>\"");
assert(0);
break; break;
} }
} }

View File

@ -80,6 +80,16 @@ static int eval_object_null(ivl_expr_t ex)
return 0; return 0;
} }
static int eval_object_property(ivl_expr_t expr)
{
ivl_signal_t sig = ivl_expr_signal(expr);
unsigned pidx = ivl_expr_property_idx(expr);
fprintf(vvp_out, " %%load/obj v%p_0;\n", sig);
fprintf(vvp_out, " %%prop/obj %u;\n", pidx);
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);
@ -106,6 +116,9 @@ int draw_eval_object(ivl_expr_t ex)
case IVL_EX_NULL: case IVL_EX_NULL:
return eval_object_null(ex); return eval_object_null(ex);
case IVL_EX_PROPERTY:
return eval_object_property(ex);
case IVL_EX_SIGNAL: case IVL_EX_SIGNAL:
return eval_object_signal(ex); return eval_object_signal(ex);

View File

@ -871,7 +871,7 @@ static int show_stmt_assign_sig_cobject(ivl_statement_t net)
} else if (ivl_type_base(prop_type) == IVL_VT_STRING) { } else if (ivl_type_base(prop_type) == IVL_VT_STRING) {
/* Calculate the real value into the real value /* Calculate the string value into the string value
stack. The %store/prop/r will pop the stack stack. The %store/prop/r will pop the stack
value. */ value. */
draw_eval_string(rval); draw_eval_string(rval);
@ -879,7 +879,19 @@ static int show_stmt_assign_sig_cobject(ivl_statement_t net)
fprintf(vvp_out, " %%store/prop/str %d;\n", prop_idx); fprintf(vvp_out, " %%store/prop/str %d;\n", prop_idx);
fprintf(vvp_out, " %%pop/obj 1;\n"); fprintf(vvp_out, " %%pop/obj 1;\n");
} else if (ivl_type_base(prop_type) == IVL_VT_DARRAY) {
/* The property is a darray, and there is no mux
expression to the assignment is of an entire
array object. */
fprintf(vvp_out, " %%load/obj v%p_0;\n", sig);
draw_eval_object(rval);
fprintf(vvp_out, " %%store/prop/obj %d;\n", prop_idx);
fprintf(vvp_out, " %%pop/obj 1;\n");
} else { } else {
fprintf(vvp_out, " ; ERROR: ivl_type_base(prop_type) = %d\n",
ivl_type_base(prop_type));
assert(0); assert(0);
} }

View File

@ -56,6 +56,9 @@ class class_property_t {
virtual void set_string(char*buf, const std::string&val); virtual void set_string(char*buf, const std::string&val);
virtual string get_string(char*buf); virtual string get_string(char*buf);
virtual void set_object(char*buf, const vvp_object_t&val);
virtual void get_object(char*buf, vvp_object_t&val);
protected: protected:
size_t offset_; size_t offset_;
}; };
@ -104,6 +107,16 @@ string class_property_t::get_string(char*)
return ""; return "";
} }
void class_property_t::set_object(char*, const vvp_object_t&)
{
assert(0);
}
void class_property_t::get_object(char*, vvp_object_t&)
{
assert(0);
}
/* /*
*/ */
template <class T> class property_atom : public class_property_t { template <class T> class property_atom : public class_property_t {
@ -160,6 +173,26 @@ class property_string : public class_property_t {
string get_string(char*buf); string get_string(char*buf);
}; };
class property_object : public class_property_t {
public:
inline explicit property_object(void) { }
~property_object() { }
size_t instance_size() const { return sizeof(vvp_object_t); }
public:
void construct(char*buf) const
{ /* vvp_object_t*tmp = */ new (buf+offset_) vvp_object_t; }
void destruct(char*buf) const
{ vvp_object_t*tmp = reinterpret_cast<vvp_object_t*> (buf+offset_);
tmp->~vvp_object_t();
}
void set_object(char*buf, const vvp_object_t&);
void get_object(char*buf, vvp_object_t&);
};
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)
{ {
T*tmp = reinterpret_cast<T*> (buf+offset_); T*tmp = reinterpret_cast<T*> (buf+offset_);
@ -204,6 +237,19 @@ string property_string::get_string(char*buf)
return *tmp; return *tmp;
} }
void property_object::set_object(char*buf, const vvp_object_t&val)
{
vvp_object_t*tmp = reinterpret_cast<vvp_object_t*>(buf+offset_);
*tmp = val;
}
void property_object::get_object(char*buf, vvp_object_t&val)
{
vvp_object_t*tmp = reinterpret_cast<vvp_object_t*>(buf+offset_);
val = *tmp;
}
/* **** */ /* **** */
class_type::class_type(const string&nam, size_t nprop) class_type::class_type(const string&nam, size_t nprop)
@ -237,6 +283,8 @@ void class_type::set_property(size_t idx, const string&name, const string&type)
properties_[idx].type = new property_real<double>; properties_[idx].type = new property_real<double>;
else if (type == "S") else if (type == "S")
properties_[idx].type = new property_string; properties_[idx].type = new property_string;
else if (type == "o")
properties_[idx].type = new property_object;
else else
properties_[idx].type = 0; properties_[idx].type = 0;
} }
@ -338,6 +386,21 @@ string class_type::get_string(class_type::inst_t obj, size_t pid) const
return properties_[pid].type->get_string(buf); return properties_[pid].type->get_string(buf);
} }
void class_type::set_object(class_type::inst_t obj, size_t pid,
const vvp_object_t&val) const
{
char*buf = reinterpret_cast<char*> (obj);
assert(pid < properties_.size());
properties_[pid].type->set_object(buf, val);
}
void class_type::get_object(class_type::inst_t obj, size_t pid, vvp_object_t&val) const
{
char*buf = reinterpret_cast<char*> (obj);
assert(pid < properties_.size());
properties_[pid].type->get_object(buf, val);
}
int class_type::get_type_code(void) const int class_type::get_type_code(void) const
{ {
return vpiClassDefn; return vpiClassDefn;

View File

@ -65,6 +65,8 @@ class class_type : public __vpiHandle {
double get_real(inst_t inst, size_t pid) const; double get_real(inst_t inst, size_t pid) const;
void set_string(inst_t inst, size_t pid, const std::string&val) const; void set_string(inst_t inst, size_t pid, const std::string&val) const;
std::string get_string(inst_t inst, size_t pid) const; std::string get_string(inst_t inst, size_t pid) 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;
public: // VPI related methods public: // VPI related methods
int get_type_code(void) const; int get_type_code(void) const;

View File

@ -165,6 +165,7 @@ extern bool of_POP_STR(vthread_t thr, vvp_code_t code);
extern bool of_POW(vthread_t thr, vvp_code_t code); extern bool of_POW(vthread_t thr, vvp_code_t code);
extern bool of_POW_S(vthread_t thr, vvp_code_t code); extern bool of_POW_S(vthread_t thr, vvp_code_t code);
extern bool of_POW_WR(vthread_t thr, vvp_code_t code); extern bool of_POW_WR(vthread_t thr, vvp_code_t code);
extern bool of_PROP_OBJ(vthread_t thr, vvp_code_t code);
extern bool of_PROP_R(vthread_t thr, vvp_code_t code); extern bool of_PROP_R(vthread_t thr, vvp_code_t code);
extern bool of_PROP_STR(vthread_t thr, vvp_code_t code); extern bool of_PROP_STR(vthread_t thr, vvp_code_t code);
extern bool of_PROP_V(vthread_t thr, vvp_code_t code); extern bool of_PROP_V(vthread_t thr, vvp_code_t code);
@ -186,6 +187,7 @@ extern bool of_SHIFTR_S_I0(vthread_t thr, vvp_code_t code);
extern bool of_STORE_DAR_R(vthread_t thr, vvp_code_t code); extern bool of_STORE_DAR_R(vthread_t thr, vvp_code_t code);
extern bool of_STORE_DAR_STR(vthread_t thr, vvp_code_t code); extern bool of_STORE_DAR_STR(vthread_t thr, vvp_code_t code);
extern bool of_STORE_OBJ(vthread_t thr, vvp_code_t code); extern bool of_STORE_OBJ(vthread_t thr, vvp_code_t code);
extern bool of_STORE_PROP_OBJ(vthread_t thr, vvp_code_t code);
extern bool of_STORE_PROP_R(vthread_t thr, vvp_code_t code); extern bool of_STORE_PROP_R(vthread_t thr, vvp_code_t code);
extern bool of_STORE_PROP_STR(vthread_t thr, vvp_code_t code); extern bool of_STORE_PROP_STR(vthread_t thr, vvp_code_t code);
extern bool of_STORE_PROP_V(vthread_t thr, vvp_code_t code); extern bool of_STORE_PROP_V(vthread_t thr, vvp_code_t code);

View File

@ -213,6 +213,7 @@ static const struct opcode_table_s opcode_table[] = {
{ "%pow", of_POW, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%pow", of_POW, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%pow/s", of_POW_S, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%pow/s", of_POW_S, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%pow/wr", of_POW_WR, 0, {OA_NONE, OA_NONE, OA_NONE} }, { "%pow/wr", of_POW_WR, 0, {OA_NONE, OA_NONE, OA_NONE} },
{ "%prop/obj",of_PROP_OBJ,1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%prop/r", of_PROP_R, 1, {OA_NUMBER, OA_NONE, OA_NONE} }, { "%prop/r", of_PROP_R, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%prop/str",of_PROP_STR,1, {OA_NUMBER, OA_NONE, OA_NONE} }, { "%prop/str",of_PROP_STR,1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%prop/v", of_PROP_V, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%prop/v", of_PROP_V, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
@ -233,6 +234,7 @@ static const struct opcode_table_s opcode_table[] = {
{ "%store/dar/r", of_STORE_DAR_R, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} }, { "%store/dar/r", of_STORE_DAR_R, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
{ "%store/dar/str",of_STORE_DAR_STR, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} }, { "%store/dar/str",of_STORE_DAR_STR, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
{ "%store/obj", of_STORE_OBJ, 1, {OA_FUNC_PTR,OA_NONE, OA_NONE} }, { "%store/obj", of_STORE_OBJ, 1, {OA_FUNC_PTR,OA_NONE, OA_NONE} },
{ "%store/prop/obj",of_STORE_PROP_OBJ,1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%store/prop/r", of_STORE_PROP_R, 1, {OA_NUMBER, OA_NONE, OA_NONE} }, { "%store/prop/r", of_STORE_PROP_R, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%store/prop/str",of_STORE_PROP_STR,1, {OA_NUMBER, OA_NONE, OA_NONE} }, { "%store/prop/str",of_STORE_PROP_STR,1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%store/prop/v", of_STORE_PROP_V, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%store/prop/v", of_STORE_PROP_V, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },

View File

@ -889,12 +889,13 @@ This opcode raises the left operand by the right operand, and pushes
the result. the result.
* %prop/v <pid>, <base>, <wid> * %prop/v <pid>, <base>, <wid>
* %prop/obj <pid>
* %prop/r <pid> * %prop/r <pid>
* %prop/str <pid> * %prop/str <pid>
Write the vector (/v) or real value (/r) or string (/str) into Write the vector (/v) or real value (/r) or string (/str) into
property number <pid> of the class object on the top of the object property number <pid> of the class object on the top of the object
stack. The real value is popped. stack.
The class object stack is NOT popped. The class object stack is NOT popped.
@ -1016,6 +1017,7 @@ variable given by the label.
See also %load/obj. See also %load/obj.
* %store/prop/obj <index>
* %store/prop/r <index> * %store/prop/r <index>
* %store/prop/str <index> * %store/prop/str <index>
* %store/prop/v <index>, <bit>, <wid> * %store/prop/v <index>, <bit>, <wid>
@ -1024,6 +1026,10 @@ The %store/prop/r pops a real value from the real stack and stores it
into the the property number <index> of a cobject in the top of the into the the property number <index> of a cobject in the top of the
object stack. The cobject is NOT popped. object stack. The cobject is NOT popped.
The %store/prop/obj pops an object from the top of the object stack,
then writes it to the property number <index> of the cobject now on
top of the object stack. The cobject is NOT popped.
* %store/real <var-label> * %store/real <var-label>
* %store/reala <var-label>, <index> * %store/reala <var-label>, <index>

View File

@ -3226,6 +3226,7 @@ bool of_LOAD_DAR(vthread_t thr, vvp_code_t cp)
darray->get_word(adr, word); darray->get_word(adr, word);
assert(word.size() == wid); assert(word.size() == wid);
thr_check_addr(thr, bit+word.size());
thr->bits4.set_vec(bit, word); thr->bits4.set_vec(bit, word);
return true; return true;
@ -4533,6 +4534,26 @@ bool of_POW_WR(vthread_t thr, vvp_code_t)
return true; return true;
} }
/*
* %prop/obj <pid>
*
* Load an object value from the cobject and push it onto the object stack.
*/
bool of_PROP_OBJ(vthread_t thr, vvp_code_t cp)
{
unsigned pid = cp->number;
vvp_object_t&obj = thr->peek_object();
vvp_cobject*cobj = obj.peek<vvp_cobject>();
vvp_object_t val;
cobj->get_object(pid, val);
thr->push_object(val);
return true;
}
/* /*
* %prop/r <pid> * %prop/r <pid>
* *
@ -5112,6 +5133,28 @@ bool of_STORE_OBJ(vthread_t thr, vvp_code_t cp)
return true; return true;
} }
/*
* %store/prop/obj <id>
*
* Pop an object value from the object stack, and store the value into
* the property of the object references by the top of the stack. Do NOT
* pop the object stack.
*/
bool of_STORE_PROP_OBJ(vthread_t thr, vvp_code_t cp)
{
size_t pid = cp->number;
vvp_object_t val;
thr->pop_object(val);
vvp_object_t&obj = thr->peek_object();
vvp_cobject*cobj = obj.peek<vvp_cobject>();
assert(cobj);
cobj->set_object(pid, val);
return true;
}
/* /*
* %store/prop/r <id> * %store/prop/r <id>
* *

View File

@ -64,3 +64,13 @@ string vvp_cobject::get_string(size_t pid)
{ {
return defn_->get_string(properties_, pid); return defn_->get_string(properties_, pid);
} }
void vvp_cobject::set_object(size_t pid, const vvp_object_t&val)
{
defn_->set_object(properties_, pid, val);
}
void vvp_cobject::get_object(size_t pid, vvp_object_t&val)
{
return defn_->get_object(properties_, pid, val);
}

View File

@ -41,6 +41,9 @@ class vvp_cobject : public vvp_object {
void set_string(size_t pid, const std::string&val); void set_string(size_t pid, const std::string&val);
std::string get_string(size_t pid); std::string get_string(size_t pid);
void set_object(size_t pid, const vvp_object_t&val);
void get_object(size_t pid, vvp_object_t&val);
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.