Allow class properties to be arrayed.
This adds the runtime support for class properties that are classes to be arrayed. Add a means to define the dimensions of a property in the vvp format, and add functions for setting/extracting elements of a property.
This commit is contained in:
parent
ea4b000be6
commit
98799ff7fa
|
|
@ -203,6 +203,21 @@ ostream& ivl_type_s::debug_dump(ostream&o) const
|
|||
return o;
|
||||
}
|
||||
|
||||
ostream& netclass_t::debug_dump(ostream&fd) const
|
||||
{
|
||||
fd << "class " << name_ << "{";
|
||||
for (size_t idx = 0 ; idx < property_table_.size() ; idx += 1) {
|
||||
if (idx != 0) fd << "; ";
|
||||
if (property_table_[idx].type)
|
||||
property_table_[idx].type->debug_dump(fd);
|
||||
else
|
||||
fd << "NO_TYPE";
|
||||
fd << " " << property_table_[idx].name;
|
||||
}
|
||||
fd << "}";
|
||||
return fd;
|
||||
}
|
||||
|
||||
ostream& netdarray_t::debug_dump(ostream&o) const
|
||||
{
|
||||
o << "dynamic array of " << *element_type();
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ class netclass_t : public ivl_type_s {
|
|||
void emit_scope(struct target_t*tgt) const;
|
||||
bool emit_defs(struct target_t*tgt) const;
|
||||
|
||||
std::ostream& debug_dump(std::ostream&fd) const;
|
||||
void dump_scope(ostream&fd) const;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -65,3 +65,8 @@ vector<netrange_t> netparray_t::slice_dimensions() const
|
|||
netuarray_t::~netuarray_t()
|
||||
{
|
||||
}
|
||||
|
||||
vector<netrange_t> netuarray_t::slice_dimensions() const
|
||||
{
|
||||
return static_dimensions();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,6 +84,10 @@ class netuarray_t : public netsarray_t {
|
|||
explicit netuarray_t(const std::vector<netrange_t>&packed,
|
||||
ivl_type_t etype);
|
||||
~netuarray_t();
|
||||
|
||||
public:
|
||||
// Virtual methods from the ivl_type_s type...
|
||||
std::vector<netrange_t> slice_dimensions() const;
|
||||
};
|
||||
|
||||
inline netuarray_t::netuarray_t(const std::vector<netrange_t>&pd,
|
||||
|
|
|
|||
|
|
@ -70,6 +70,8 @@ class netarray_t : public ivl_type_s {
|
|||
|
||||
public:
|
||||
// Some virtual methods have a common implementation for arrays.
|
||||
|
||||
// The base_type() for arrays is the base_Typeof the element.
|
||||
ivl_variable_type_t base_type() const;
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ static void show_prop_type_vector(ivl_type_t ptype)
|
|||
static void show_prop_type(ivl_type_t ptype)
|
||||
{
|
||||
ivl_variable_type_t data_type = ivl_type_base(ptype);
|
||||
unsigned packed_dimensions = ivl_type_packed_dimensions(ptype);
|
||||
|
||||
switch (data_type) {
|
||||
case IVL_VT_REAL:
|
||||
|
|
@ -64,6 +65,15 @@ static void show_prop_type(ivl_type_t ptype)
|
|||
case IVL_VT_DARRAY:
|
||||
case IVL_VT_CLASS:
|
||||
fprintf(vvp_out, "\"o\"");
|
||||
if (packed_dimensions > 0) {
|
||||
unsigned idx;
|
||||
fprintf(vvp_out, " ");
|
||||
for (idx = 0 ; idx < packed_dimensions ; idx += 1) {
|
||||
fprintf(vvp_out, "[%d:%d]",
|
||||
ivl_type_packed_msb(ptype,idx),
|
||||
ivl_type_packed_lsb(ptype,idx));
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(vvp_out, "\"<ERROR-no-type>\"");
|
||||
|
|
|
|||
|
|
@ -172,9 +172,22 @@ static int eval_object_property(ivl_expr_t expr)
|
|||
ivl_signal_t sig = ivl_expr_signal(expr);
|
||||
unsigned pidx = ivl_expr_property_idx(expr);
|
||||
|
||||
int idx = 0;
|
||||
ivl_expr_t idx_expr = 0;
|
||||
|
||||
/* If there is an array index expression, then this is an
|
||||
array'ed property, and we need to calculate the index for
|
||||
the expression. */
|
||||
if ( (idx_expr = ivl_expr_oper1(expr)) ) {
|
||||
idx = allocate_word();
|
||||
draw_eval_expr_into_integer(idx_expr, idx);
|
||||
}
|
||||
|
||||
fprintf(vvp_out, " %%load/obj v%p_0;\n", sig);
|
||||
fprintf(vvp_out, " %%prop/obj %u;\n", pidx);
|
||||
fprintf(vvp_out, " %%prop/obj %u, %d; eval_object_property\n", pidx, idx);
|
||||
fprintf(vvp_out, " %%pop/obj 1, 1;\n");
|
||||
|
||||
if (idx != 0) clr_word(idx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -334,7 +334,11 @@ static ivl_type_t draw_lval_expr(ivl_lval_t lval)
|
|||
}
|
||||
|
||||
assert(ivl_type_base(sub_type) == IVL_VT_CLASS);
|
||||
fprintf(vvp_out, " %%prop/obj %d;\n", ivl_lval_property_idx(lval));
|
||||
if (ivl_lval_idx(lval)) {
|
||||
fprintf(vvp_out, " ; XXXX Don't know how to handle ivl_lval_idx values here.\n");
|
||||
}
|
||||
|
||||
fprintf(vvp_out, " %%prop/obj %d, 0; draw_lval_expr\n", ivl_lval_property_idx(lval));
|
||||
fprintf(vvp_out, " %%pop/obj 1, 1;\n");
|
||||
return ivl_type_prop_type(sub_type, ivl_lval_property_idx(lval));
|
||||
}
|
||||
|
|
@ -1063,22 +1067,33 @@ static int show_stmt_assign_sig_cobject(ivl_statement_t net)
|
|||
|
||||
} else if (ivl_type_base(prop_type) == IVL_VT_DARRAY) {
|
||||
|
||||
int idx = 0;
|
||||
|
||||
/* 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, " %%store/prop/obj %d, %d; IVL_VT_DARRAY\n", prop_idx, idx);
|
||||
fprintf(vvp_out, " %%pop/obj 1, 0;\n");
|
||||
|
||||
} else if (ivl_type_base(prop_type) == IVL_VT_CLASS) {
|
||||
|
||||
int idx = 0;
|
||||
ivl_expr_t idx_expr;
|
||||
if ( (idx_expr = ivl_lval_idx(lval)) ) {
|
||||
idx = allocate_word();
|
||||
}
|
||||
|
||||
/* The property is a class 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);
|
||||
if (idx_expr) draw_eval_expr_into_integer(idx_expr, idx);
|
||||
fprintf(vvp_out, " %%store/prop/obj %d, %d; IVL_VT_CLASS\n", prop_idx, idx);
|
||||
fprintf(vvp_out, " %%pop/obj 1, 0;\n");
|
||||
|
||||
if (idx_expr) clr_word(idx);
|
||||
|
||||
} else {
|
||||
fprintf(vvp_out, " ; ERROR: ivl_type_base(prop_type) = %d\n",
|
||||
ivl_type_base(prop_type));
|
||||
|
|
|
|||
|
|
@ -56,8 +56,8 @@ class class_property_t {
|
|||
virtual void set_string(char*buf, const std::string&val);
|
||||
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);
|
||||
virtual void set_object(char*buf, const vvp_object_t&val, uint64_t element);
|
||||
virtual void get_object(char*buf, vvp_object_t&val, uint64_t element);
|
||||
|
||||
// Implement polymorphic shallow copy.
|
||||
virtual void copy(char*buf, char*src) = 0;
|
||||
|
|
@ -110,12 +110,12 @@ string class_property_t::get_string(char*)
|
|||
return "";
|
||||
}
|
||||
|
||||
void class_property_t::set_object(char*, const vvp_object_t&)
|
||||
void class_property_t::set_object(char*, const vvp_object_t&, uint64_t)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void class_property_t::get_object(char*, vvp_object_t&)
|
||||
void class_property_t::get_object(char*, vvp_object_t&, uint64_t)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
|
@ -234,24 +234,23 @@ class property_string : public class_property_t {
|
|||
|
||||
class property_object : public class_property_t {
|
||||
public:
|
||||
inline explicit property_object(void) { }
|
||||
inline explicit property_object(uint64_t as): array_size_(as==0? 1 : as) { }
|
||||
~property_object() { }
|
||||
|
||||
size_t instance_size() const { return sizeof(vvp_object_t); }
|
||||
size_t instance_size() const { return array_size_ * sizeof(vvp_object_t); }
|
||||
|
||||
public:
|
||||
void construct(char*buf) const
|
||||
{ /* vvp_object_t*tmp = */ new (buf+offset_) vvp_object_t; }
|
||||
void construct(char*buf) const;
|
||||
|
||||
void destruct(char*buf) const
|
||||
{ vvp_object_t*tmp = reinterpret_cast<vvp_object_t*> (buf+offset_);
|
||||
tmp->~vvp_object_t();
|
||||
}
|
||||
void destruct(char*buf) const;
|
||||
|
||||
void set_object(char*buf, const vvp_object_t&);
|
||||
void get_object(char*buf, vvp_object_t&);
|
||||
void set_object(char*buf, const vvp_object_t&, uint64_t);
|
||||
void get_object(char*buf, vvp_object_t&, uint64_t);
|
||||
|
||||
void copy(char*dst, char*src);
|
||||
|
||||
private:
|
||||
size_t array_size_;
|
||||
};
|
||||
|
||||
template <class T> void property_atom<T>::set_vec4(char*buf, const vvp_vector4_t&val)
|
||||
|
|
@ -360,23 +359,39 @@ void property_string::copy(char*dst, char*src)
|
|||
*dst_obj = *src_obj;
|
||||
}
|
||||
|
||||
void property_object::set_object(char*buf, const vvp_object_t&val)
|
||||
void property_object::construct(char*buf) const
|
||||
{
|
||||
vvp_object_t*tmp = reinterpret_cast<vvp_object_t*>(buf+offset_);
|
||||
*tmp = val;
|
||||
for (size_t idx = 0 ; idx < array_size_ ; idx += 1)
|
||||
new (buf+offset_ + idx*sizeof(vvp_object_t)) vvp_object_t;
|
||||
}
|
||||
|
||||
void property_object::get_object(char*buf, vvp_object_t&val)
|
||||
void property_object::destruct(char*buf) const
|
||||
{
|
||||
vvp_object_t*tmp = reinterpret_cast<vvp_object_t*> (buf+offset_);
|
||||
val = *tmp;
|
||||
for (size_t idx = 0 ; idx < array_size_ ; idx += 1)
|
||||
(tmp+idx)->~vvp_object_t();
|
||||
}
|
||||
|
||||
void property_object::set_object(char*buf, const vvp_object_t&val, uint64_t idx)
|
||||
{
|
||||
assert(idx < array_size_);
|
||||
vvp_object_t*tmp = reinterpret_cast<vvp_object_t*>(buf+offset_);
|
||||
tmp[idx] = val;
|
||||
}
|
||||
|
||||
void property_object::get_object(char*buf, vvp_object_t&val, uint64_t idx)
|
||||
{
|
||||
assert(idx < array_size_);
|
||||
vvp_object_t*tmp = reinterpret_cast<vvp_object_t*>(buf+offset_);
|
||||
val = tmp[idx];
|
||||
}
|
||||
|
||||
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;
|
||||
for (size_t idx = 0 ; idx < array_size_ ; idx += 1)
|
||||
dst_obj[idx] = src_obj[idx];
|
||||
}
|
||||
|
||||
/* **** */
|
||||
|
|
@ -393,7 +408,7 @@ class_type::~class_type()
|
|||
delete properties_[idx].type;
|
||||
}
|
||||
|
||||
void class_type::set_property(size_t idx, const string&name, const string&type)
|
||||
void class_type::set_property(size_t idx, const string&name, const string&type, uint64_t array_size)
|
||||
{
|
||||
assert(idx < properties_.size());
|
||||
properties_[idx].name = name;
|
||||
|
|
@ -419,7 +434,7 @@ void class_type::set_property(size_t idx, const string&name, const string&type)
|
|||
else if (type == "S")
|
||||
properties_[idx].type = new property_string;
|
||||
else if (type == "o")
|
||||
properties_[idx].type = new property_object;
|
||||
properties_[idx].type = new property_object(array_size);
|
||||
else if (type[0] == 'b') {
|
||||
size_t wid = strtoul(type.c_str()+1, 0, 0);
|
||||
properties_[idx].type = new property_bit(wid);
|
||||
|
|
@ -529,18 +544,19 @@ string class_type::get_string(class_type::inst_t obj, size_t pid) const
|
|||
}
|
||||
|
||||
void class_type::set_object(class_type::inst_t obj, size_t pid,
|
||||
const vvp_object_t&val) const
|
||||
const vvp_object_t&val, size_t idx) const
|
||||
{
|
||||
char*buf = reinterpret_cast<char*> (obj);
|
||||
assert(pid < properties_.size());
|
||||
properties_[pid].type->set_object(buf, val);
|
||||
properties_[pid].type->set_object(buf, val, idx);
|
||||
}
|
||||
|
||||
void class_type::get_object(class_type::inst_t obj, size_t pid, vvp_object_t&val) const
|
||||
void class_type::get_object(class_type::inst_t obj, size_t pid,
|
||||
vvp_object_t&val, size_t idx) const
|
||||
{
|
||||
char*buf = reinterpret_cast<char*> (obj);
|
||||
assert(pid < properties_.size());
|
||||
properties_[pid].type->get_object(buf, val);
|
||||
properties_[pid].type->get_object(buf, val, idx);
|
||||
}
|
||||
|
||||
void class_type::copy_property(class_type::inst_t dst, size_t pid, class_type::inst_t src) const
|
||||
|
|
@ -569,10 +585,10 @@ void compile_class_start(char*lab, char*nam, unsigned ntype)
|
|||
delete[]nam;
|
||||
}
|
||||
|
||||
void compile_class_property(unsigned idx, char*nam, char*typ)
|
||||
void compile_class_property(unsigned idx, char*nam, char*typ, uint64_t array_size)
|
||||
{
|
||||
assert(compile_class);
|
||||
compile_class->set_property(idx, nam, typ);
|
||||
compile_class->set_property(idx, nam, typ, array_size);
|
||||
delete[]nam;
|
||||
delete[]typ;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ class class_type : public __vpiHandle {
|
|||
// Set the details about the property. This is used during
|
||||
// parse of the .vvp file to fill in the details of the
|
||||
// property for the class definition.
|
||||
void set_property(size_t idx, const std::string&name, const std::string&type);
|
||||
void set_property(size_t idx, const std::string&name, const std::string&type, uint64_t array_size);
|
||||
|
||||
// This method is called after all the properties are
|
||||
// defined. This calculates information about the definition.
|
||||
|
|
@ -66,8 +66,8 @@ class class_type : public __vpiHandle {
|
|||
double get_real(inst_t inst, size_t pid) 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;
|
||||
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 set_object(inst_t inst, size_t pid, const vvp_object_t&val, size_t idx) const;
|
||||
void get_object(inst_t inst, size_t pid, vvp_object_t&val, size_t idx) const;
|
||||
|
||||
void copy_property(inst_t dst, size_t idx, inst_t src) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ static const struct opcode_table_s opcode_table[] = {
|
|||
{ "%pow", of_POW, 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} },
|
||||
{ "%prop/obj",of_PROP_OBJ,1, {OA_NUMBER, OA_NONE, OA_NONE} },
|
||||
{ "%prop/obj",of_PROP_OBJ,2, {OA_NUMBER, OA_BIT1, 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/v", of_PROP_V, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
|
|
@ -248,7 +248,7 @@ static const struct opcode_table_s opcode_table[] = {
|
|||
{ "%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/obja", of_STORE_OBJA, 2, {OA_ARR_PTR, OA_BIT1, OA_NONE} },
|
||||
{ "%store/prop/obj",of_STORE_PROP_OBJ,1, {OA_NUMBER, OA_NONE, OA_NONE} },
|
||||
{ "%store/prop/obj",of_STORE_PROP_OBJ,2, {OA_NUMBER, OA_BIT1, 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/v", of_STORE_PROP_V, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
|
|
|
|||
|
|
@ -552,7 +552,7 @@ extern void compile_island_tranvp(char*island, char*ba, char*bb,
|
|||
extern void delete_udp_symbols(void);
|
||||
|
||||
extern void compile_class_start(char*lab, char*nam, unsigned nprop);
|
||||
extern void compile_class_property(unsigned idx, char*nam, char*typ);
|
||||
extern void compile_class_property(unsigned idx, char*nam, char*typ, uint64_t array_size);
|
||||
extern void compile_class_done(void);
|
||||
|
||||
#endif /* IVL_compile_H */
|
||||
|
|
|
|||
|
|
@ -892,7 +892,7 @@ This opcode raises the left operand by the right operand, and pushes
|
|||
the result.
|
||||
|
||||
* %prop/v <pid>, <base>, <wid>
|
||||
* %prop/obj <pid>
|
||||
* %prop/obj <pid>, <idx>
|
||||
* %prop/r <pid>
|
||||
* %prop/str <pid>
|
||||
|
||||
|
|
@ -901,6 +901,11 @@ the property number <pid> of the class object on the top of the
|
|||
object stack. Push the resulting value to the appropriate stack. The
|
||||
class object that is the source is NOT popped from the object stack.
|
||||
|
||||
The <idx> is the address of an index variable that selects the word of
|
||||
an arrayed property. If the <idx> value is 0, then use index value
|
||||
zero instead of reading index register zero. Use this form for
|
||||
non-arrayed properties.
|
||||
|
||||
* %pushi/real <mant>, <exp>
|
||||
|
||||
This opcode loads an immediate value, floating point, into the real
|
||||
|
|
@ -1048,18 +1053,21 @@ variable given by the label.
|
|||
|
||||
See also %load/obj.
|
||||
|
||||
* %store/prop/obj <index>
|
||||
* %store/prop/r <index>
|
||||
* %store/prop/str <index>
|
||||
* %store/prop/v <index>, <bit>, <wid>
|
||||
* %store/prop/obj <pid>, <idx>
|
||||
* %store/prop/r <pid>
|
||||
* %store/prop/str <pid>
|
||||
* %store/prop/v <pid>, <bit>, <wid>
|
||||
|
||||
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 <pid> of a cobject in the top of the
|
||||
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.
|
||||
then writes it to the property number <pid> of the cobject now on
|
||||
top of the object stack. The cobject is NOT popped. The <idx> argument
|
||||
is the index register to select an element. If the property is an
|
||||
array, this selects the element. If <idx> is 0, then use the value 0
|
||||
instead of index register zero. Use 0 for non-array properties.
|
||||
|
||||
* %store/real <var-label>
|
||||
* %store/reala <var-label>, <index>
|
||||
|
|
|
|||
29
vvp/parse.y
29
vvp/parse.y
|
|
@ -115,6 +115,7 @@ static struct __vpiModPath*modpath_dst = 0;
|
|||
%type <flag> local_flag
|
||||
%type <vpi_enum> port_type
|
||||
%type <numb> signed_t_number
|
||||
%type <numb> dimension dimensions dimensions_opt
|
||||
%type <symb> symbol symbol_opt
|
||||
%type <symbv> symbols symbols_net
|
||||
%type <numbv> numbers
|
||||
|
|
@ -898,8 +899,32 @@ class_properties
|
|||
;
|
||||
|
||||
class_property
|
||||
: T_NUMBER ':' T_STRING ',' T_STRING
|
||||
{ compile_class_property($1, $3, $5); }
|
||||
: T_NUMBER ':' T_STRING ',' T_STRING dimensions_opt
|
||||
{ compile_class_property($1, $3, $5, $6); }
|
||||
;
|
||||
|
||||
/*
|
||||
* The syntax for dimensions allows the code generator to give the
|
||||
* accurate dimensions for for the property, but for now we are only
|
||||
* interested in the total number of elements. So reduce the ranges
|
||||
* to a simple number, and scale the number.
|
||||
*/
|
||||
dimensions_opt
|
||||
: dimensions
|
||||
{ $$ = $1; }
|
||||
| { $$ = 0; }
|
||||
;
|
||||
|
||||
dimensions
|
||||
: dimensions dimension
|
||||
{ $$ = $1 * $2; }
|
||||
| dimension
|
||||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
dimension
|
||||
: '[' T_NUMBER ':' T_NUMBER ']'
|
||||
{ $$ = ($2 > $4? $2 - $4 : $4 - $2) + 1; }
|
||||
;
|
||||
|
||||
/* Enumeration types */
|
||||
|
|
|
|||
|
|
@ -94,6 +94,8 @@ using namespace std;
|
|||
* to reap the child immediately.
|
||||
*/
|
||||
|
||||
const size_t THR_MAX_WORDS = 16;
|
||||
|
||||
struct vthread_s {
|
||||
vthread_s();
|
||||
|
||||
|
|
@ -106,7 +108,7 @@ struct vthread_s {
|
|||
union {
|
||||
int64_t w_int;
|
||||
uint64_t w_uint;
|
||||
} words[16];
|
||||
} words[THR_MAX_WORDS];
|
||||
|
||||
private:
|
||||
vector<double> stack_real_;
|
||||
|
|
@ -4657,19 +4659,25 @@ bool of_POW_WR(vthread_t thr, vvp_code_t)
|
|||
}
|
||||
|
||||
/*
|
||||
* %prop/obj <pid>
|
||||
* %prop/obj <pid>, <idx>
|
||||
*
|
||||
* 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;
|
||||
unsigned idx = cp->bit_idx[0];
|
||||
|
||||
if (idx != 0) {
|
||||
assert(idx < THR_MAX_WORDS);
|
||||
idx = thr->words[idx].w_uint;
|
||||
}
|
||||
|
||||
vvp_object_t&obj = thr->peek_object();
|
||||
vvp_cobject*cobj = obj.peek<vvp_cobject>();
|
||||
|
||||
vvp_object_t val;
|
||||
cobj->get_object(pid, val);
|
||||
cobj->get_object(pid, val, idx);
|
||||
|
||||
thr->push_object(val);
|
||||
|
||||
|
|
@ -5479,7 +5487,7 @@ bool of_STORE_OBJA(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
|
||||
/*
|
||||
* %store/prop/obj <id>
|
||||
* %store/prop/obj <pid>, <idx>
|
||||
*
|
||||
* 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
|
||||
|
|
@ -5488,6 +5496,13 @@ bool of_STORE_OBJA(vthread_t thr, vvp_code_t cp)
|
|||
bool of_STORE_PROP_OBJ(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
size_t pid = cp->number;
|
||||
unsigned idx = cp->bit_idx[0];
|
||||
|
||||
if (idx != 0) {
|
||||
assert(idx < THR_MAX_WORDS);
|
||||
idx = thr->words[idx].w_uint;
|
||||
}
|
||||
|
||||
vvp_object_t val;
|
||||
thr->pop_object(val);
|
||||
|
||||
|
|
@ -5495,7 +5510,7 @@ bool of_STORE_PROP_OBJ(vthread_t thr, vvp_code_t cp)
|
|||
vvp_cobject*cobj = obj.peek<vvp_cobject>();
|
||||
assert(cobj);
|
||||
|
||||
cobj->set_object(pid, val);
|
||||
cobj->set_object(pid, val, idx);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,14 +65,14 @@ string vvp_cobject::get_string(size_t pid)
|
|||
return defn_->get_string(properties_, pid);
|
||||
}
|
||||
|
||||
void vvp_cobject::set_object(size_t pid, const vvp_object_t&val)
|
||||
void vvp_cobject::set_object(size_t pid, const vvp_object_t&val, size_t idx)
|
||||
{
|
||||
defn_->set_object(properties_, pid, val);
|
||||
defn_->set_object(properties_, pid, val, idx);
|
||||
}
|
||||
|
||||
void vvp_cobject::get_object(size_t pid, vvp_object_t&val)
|
||||
void vvp_cobject::get_object(size_t pid, vvp_object_t&val, size_t idx)
|
||||
{
|
||||
return defn_->get_object(properties_, pid, val);
|
||||
return defn_->get_object(properties_, pid, val, idx);
|
||||
}
|
||||
|
||||
void vvp_cobject::shallow_copy(const vvp_object*obj)
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ class vvp_cobject : public vvp_object {
|
|||
void set_string(size_t pid, const std::string&val);
|
||||
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);
|
||||
void set_object(size_t pid, const vvp_object_t&val, size_t idx);
|
||||
void get_object(size_t pid, vvp_object_t&val, size_t idx);
|
||||
|
||||
void shallow_copy(const vvp_object*that);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue