SystemVerilog: class darray property locator methods and VVP prop fixes
Add class dynamic-array property support for locator methods (find*, unique*, min/max, with predicates) by elaborating dynamic-array property method calls to queue-method sfuns. Extend VVP property paths to treat property values as queue-or-darray sources, not queue-only, and fix object-stack handling in property locator loops so temporary accumulator objects do not hide the class object. Add regression coverage for class dynamic-array property locators and update locator-method test documentation/listing. Made-with: Cursor
This commit is contained in:
parent
3ccba27edb
commit
8f18edd20d
272
elab_expr.cc
272
elab_expr.cc
|
|
@ -4023,6 +4023,8 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
|||
NetEProperty*prop = new NetEProperty(search_results.net, pidx, nullptr);
|
||||
prop->set_line(*this);
|
||||
perm_string method_name = search_results.path_tail.back().name;
|
||||
ivl_type_t element_type = ivl_type_element(ptype);
|
||||
ivl_type_t darray_rtype = ptype;
|
||||
if (method_name == "size") {
|
||||
if (parms_.size() != 0) {
|
||||
cerr << get_fileline() << ": error: size() method "
|
||||
|
|
@ -4034,6 +4036,276 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
|||
sys_expr->parm(0, prop);
|
||||
return sys_expr;
|
||||
}
|
||||
if (method_name == "unique") {
|
||||
if (parms_.size() != 0) {
|
||||
cerr << get_fileline() << ": error: unique() method "
|
||||
<< "takes no arguments" << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
if (!queue_method_element_is_integral_vec4(element_type)) {
|
||||
cerr << get_fileline() << ": sorry: dynamic array unique() for this "
|
||||
<< "element type is not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
if (with_expr_) {
|
||||
cerr << get_fileline() << ": sorry: dynamic array unique() with a "
|
||||
<< "`with` clause is not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
NetESFunc*sys_expr = new NetESFunc(
|
||||
"$ivl_queue_method$unique", darray_rtype, 1);
|
||||
sys_expr->set_line(*this);
|
||||
sys_expr->parm(0, prop);
|
||||
return sys_expr;
|
||||
}
|
||||
if (method_name == "unique_index") {
|
||||
if (parms_.size() != 0) {
|
||||
cerr << get_fileline() << ": error: unique_index() method "
|
||||
<< "takes no arguments" << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
if (!queue_method_element_is_integral_vec4(element_type)) {
|
||||
cerr << get_fileline() << ": sorry: dynamic array unique_index() for this "
|
||||
<< "element type is not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
if (with_expr_) {
|
||||
cerr << get_fileline() << ": sorry: dynamic array unique_index() with a "
|
||||
<< "`with` clause is not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
NetESFunc*sys_expr = new NetESFunc(
|
||||
"$ivl_queue_method$unique_index",
|
||||
static_cast<ivl_type_t>(&ivl_queue_unique_index_ret), 1);
|
||||
sys_expr->set_line(*this);
|
||||
sys_expr->parm(0, prop);
|
||||
return sys_expr;
|
||||
}
|
||||
if (method_name == "find") {
|
||||
if (!queue_method_element_is_integral_vec4(element_type)) {
|
||||
cerr << get_fileline() << ": sorry: dynamic array find() for this "
|
||||
<< "element type is not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
if (with_expr_) {
|
||||
if (!parms_.empty()) {
|
||||
cerr << get_fileline() << ": error: array locator "
|
||||
<< "`with` clause cannot be combined with a "
|
||||
<< "method argument." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
return elab_queue_locator_with_predicate(
|
||||
des, scope, *this, with_expr_, prop,
|
||||
element_type, darray_rtype, method_name);
|
||||
}
|
||||
NetExpr* cmp = elab_queue_locator_cmp_arg(
|
||||
des, scope, *this, parms_, element_type);
|
||||
if (!cmp)
|
||||
return 0;
|
||||
NetESFunc*sys_expr = new NetESFunc(
|
||||
"$ivl_queue_method$find", darray_rtype, 2);
|
||||
sys_expr->set_line(*this);
|
||||
sys_expr->parm(0, prop);
|
||||
sys_expr->parm(1, cmp);
|
||||
return sys_expr;
|
||||
}
|
||||
if (method_name == "find_index") {
|
||||
if (!queue_method_element_is_integral_vec4(element_type)) {
|
||||
cerr << get_fileline() << ": sorry: dynamic array find_index() for this "
|
||||
<< "element type is not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
if (with_expr_) {
|
||||
if (!parms_.empty()) {
|
||||
cerr << get_fileline() << ": error: array locator "
|
||||
<< "`with` clause cannot be combined with a "
|
||||
<< "method argument." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
return elab_queue_locator_with_predicate(
|
||||
des, scope, *this, with_expr_, prop,
|
||||
element_type,
|
||||
static_cast<ivl_type_t>(&ivl_queue_unique_index_ret),
|
||||
method_name);
|
||||
}
|
||||
NetExpr* cmp = elab_queue_locator_cmp_arg(
|
||||
des, scope, *this, parms_, element_type);
|
||||
if (!cmp)
|
||||
return 0;
|
||||
NetESFunc*sys_expr = new NetESFunc(
|
||||
"$ivl_queue_method$find_index",
|
||||
static_cast<ivl_type_t>(&ivl_queue_unique_index_ret), 2);
|
||||
sys_expr->set_line(*this);
|
||||
sys_expr->parm(0, prop);
|
||||
sys_expr->parm(1, cmp);
|
||||
return sys_expr;
|
||||
}
|
||||
if (method_name == "find_first") {
|
||||
if (!queue_method_element_is_integral_vec4(element_type)) {
|
||||
cerr << get_fileline() << ": sorry: dynamic array find_first() for this "
|
||||
<< "element type is not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
if (with_expr_) {
|
||||
if (!parms_.empty()) {
|
||||
cerr << get_fileline() << ": error: array locator "
|
||||
<< "`with` clause cannot be combined with a "
|
||||
<< "method argument." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
return elab_queue_locator_with_predicate(
|
||||
des, scope, *this, with_expr_, prop,
|
||||
element_type, darray_rtype, method_name);
|
||||
}
|
||||
NetExpr* cmp = elab_queue_locator_cmp_arg(
|
||||
des, scope, *this, parms_, element_type);
|
||||
if (!cmp)
|
||||
return 0;
|
||||
NetESFunc*sys_expr = new NetESFunc(
|
||||
"$ivl_queue_method$find_first", darray_rtype, 2);
|
||||
sys_expr->set_line(*this);
|
||||
sys_expr->parm(0, prop);
|
||||
sys_expr->parm(1, cmp);
|
||||
return sys_expr;
|
||||
}
|
||||
if (method_name == "find_first_index") {
|
||||
if (!queue_method_element_is_integral_vec4(element_type)) {
|
||||
cerr << get_fileline() << ": sorry: dynamic array find_first_index() for this "
|
||||
<< "element type is not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
if (with_expr_) {
|
||||
if (!parms_.empty()) {
|
||||
cerr << get_fileline() << ": error: array locator "
|
||||
<< "`with` clause cannot be combined with a "
|
||||
<< "method argument." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
return elab_queue_locator_with_predicate(
|
||||
des, scope, *this, with_expr_, prop,
|
||||
element_type,
|
||||
static_cast<ivl_type_t>(&ivl_queue_unique_index_ret),
|
||||
method_name);
|
||||
}
|
||||
NetExpr* cmp = elab_queue_locator_cmp_arg(
|
||||
des, scope, *this, parms_, element_type);
|
||||
if (!cmp)
|
||||
return 0;
|
||||
NetESFunc*sys_expr = new NetESFunc(
|
||||
"$ivl_queue_method$find_first_index",
|
||||
static_cast<ivl_type_t>(&ivl_queue_unique_index_ret), 2);
|
||||
sys_expr->set_line(*this);
|
||||
sys_expr->parm(0, prop);
|
||||
sys_expr->parm(1, cmp);
|
||||
return sys_expr;
|
||||
}
|
||||
if (method_name == "find_last") {
|
||||
if (!queue_method_element_is_integral_vec4(element_type)) {
|
||||
cerr << get_fileline() << ": sorry: dynamic array find_last() for this "
|
||||
<< "element type is not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
if (with_expr_) {
|
||||
if (!parms_.empty()) {
|
||||
cerr << get_fileline() << ": error: array locator "
|
||||
<< "`with` clause cannot be combined with a "
|
||||
<< "method argument." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
return elab_queue_locator_with_predicate(
|
||||
des, scope, *this, with_expr_, prop,
|
||||
element_type, darray_rtype, method_name);
|
||||
}
|
||||
NetExpr* cmp = elab_queue_locator_cmp_arg(
|
||||
des, scope, *this, parms_, element_type);
|
||||
if (!cmp)
|
||||
return 0;
|
||||
NetESFunc*sys_expr = new NetESFunc(
|
||||
"$ivl_queue_method$find_last", darray_rtype, 2);
|
||||
sys_expr->set_line(*this);
|
||||
sys_expr->parm(0, prop);
|
||||
sys_expr->parm(1, cmp);
|
||||
return sys_expr;
|
||||
}
|
||||
if (method_name == "find_last_index") {
|
||||
if (!queue_method_element_is_integral_vec4(element_type)) {
|
||||
cerr << get_fileline() << ": sorry: dynamic array find_last_index() for this "
|
||||
<< "element type is not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
if (with_expr_) {
|
||||
if (!parms_.empty()) {
|
||||
cerr << get_fileline() << ": error: array locator "
|
||||
<< "`with` clause cannot be combined with a "
|
||||
<< "method argument." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
return elab_queue_locator_with_predicate(
|
||||
des, scope, *this, with_expr_, prop,
|
||||
element_type,
|
||||
static_cast<ivl_type_t>(&ivl_queue_unique_index_ret),
|
||||
method_name);
|
||||
}
|
||||
NetExpr* cmp = elab_queue_locator_cmp_arg(
|
||||
des, scope, *this, parms_, element_type);
|
||||
if (!cmp)
|
||||
return 0;
|
||||
NetESFunc*sys_expr = new NetESFunc(
|
||||
"$ivl_queue_method$find_last_index",
|
||||
static_cast<ivl_type_t>(&ivl_queue_unique_index_ret), 2);
|
||||
sys_expr->set_line(*this);
|
||||
sys_expr->parm(0, prop);
|
||||
sys_expr->parm(1, cmp);
|
||||
return sys_expr;
|
||||
}
|
||||
if (method_name == "min" || method_name == "max") {
|
||||
if (parms_.size() != 0) {
|
||||
cerr << get_fileline() << ": error: " << method_name
|
||||
<< "() method takes no arguments" << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
if (!queue_method_element_is_integral_vec4(element_type)) {
|
||||
cerr << get_fileline() << ": sorry: dynamic array " << method_name
|
||||
<< "() for this element type is not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
if (with_expr_) {
|
||||
if (!parms_.empty()) {
|
||||
cerr << get_fileline() << ": error: array locator "
|
||||
<< "`with` clause cannot be combined with a "
|
||||
<< "method argument." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
return elab_queue_locator_with_predicate(
|
||||
des, scope, *this, with_expr_, prop,
|
||||
element_type, darray_rtype, method_name);
|
||||
}
|
||||
NetESFunc*sys_expr = new NetESFunc(
|
||||
method_name == "min" ? "$ivl_queue_method$min"
|
||||
: "$ivl_queue_method$max",
|
||||
darray_rtype, 1);
|
||||
sys_expr->set_line(*this);
|
||||
sys_expr->parm(0, prop);
|
||||
return sys_expr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,3 +45,4 @@ Regression tests (see ivtest/vvp_tests/*.json and regress-vvp.list):
|
|||
sv_darray_min_max.v min() and max() on dynamic array values.
|
||||
sv_queue_min_max_with.v min()/max() with predicate on queue values.
|
||||
sv_darray_min_max_with.v min()/max() with predicate on dynamic arrays.
|
||||
sv_class_darray_prop_locators.v locator methods on class dynamic-array properties.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
// Regression: class dynamic-array property locator methods.
|
||||
|
||||
module test;
|
||||
|
||||
bit failed = 1'b0;
|
||||
|
||||
`define check(val, exp) do if ((val) !== (exp)) begin $display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, `"val`", exp, val); failed = 1'b1; end while(0)
|
||||
|
||||
class C;
|
||||
int d[];
|
||||
endclass
|
||||
|
||||
C c;
|
||||
int tmp[];
|
||||
int r[$];
|
||||
|
||||
initial begin
|
||||
c = new;
|
||||
tmp = new[9];
|
||||
tmp = '{4, 7, 2, 5, 7, 1, 6, 3, 1};
|
||||
c.d = tmp;
|
||||
|
||||
r = c.d.find() with (item > 3);
|
||||
`check(r.size, 5);
|
||||
`check(r[0], 4);
|
||||
`check(r[4], 6);
|
||||
|
||||
r = c.d.find_first() with (item > 6);
|
||||
`check(r.size, 1);
|
||||
`check(r[0], 7);
|
||||
|
||||
r = c.d.find_last_index() with (item < 3);
|
||||
`check(r.size, 1);
|
||||
`check(r[0], 8);
|
||||
|
||||
r = c.d.unique();
|
||||
`check(r.size, 7);
|
||||
`check(r[0], 4);
|
||||
|
||||
r = c.d.unique_index();
|
||||
`check(r.size, 7);
|
||||
`check(r[0], 0);
|
||||
|
||||
r = c.d.min();
|
||||
`check(r.size, 2);
|
||||
`check(r[0], 1);
|
||||
`check(r[1], 1);
|
||||
|
||||
r = c.d.max() with (item < 7);
|
||||
`check(r.size, 1);
|
||||
`check(r[0], 6);
|
||||
|
||||
if (!failed)
|
||||
$display("PASSED");
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -231,6 +231,7 @@ sv_chained_constructor5 vvp_tests/sv_chained_constructor5.json
|
|||
sv_class_prop_assign_op1 vvp_tests/sv_class_prop_assign_op1.json
|
||||
sv_class_prop_assign_op2 vvp_tests/sv_class_prop_assign_op2.json
|
||||
sv_class_prop_logic vvp_tests/sv_class_prop_logic.json
|
||||
sv_class_darray_prop_locators vvp_tests/sv_class_darray_prop_locators.json
|
||||
sv_class_prop_nest_darray1 vvp_tests/sv_class_prop_nest_darray1.json
|
||||
sv_class_prop_nest_obj1 vvp_tests/sv_class_prop_nest_obj1.json
|
||||
sv_class_prop_nest_real1 vvp_tests/sv_class_prop_nest_str1.json
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"type" : "normal",
|
||||
"source" : "sv_class_darray_prop_locators.v",
|
||||
"iverilog-args" : [ "-g2005-sv" ],
|
||||
"vlog95" : {
|
||||
"__comment" : "Classes/dynamic arrays are not supported",
|
||||
"type" : "CE",
|
||||
"iverilog-args" : [ "-pallowsigned=1" ]
|
||||
}
|
||||
}
|
||||
|
|
@ -290,7 +290,7 @@ static int eval_queue_method_unique(ivl_expr_t expr)
|
|||
fprintf(vvp_out, " %%load/obj v%p_0;\n", cl);
|
||||
fprintf(vvp_out, " %%queue/unique/prop/v %u, %u;\n", pidx,
|
||||
elem_wid);
|
||||
fprintf(vvp_out, " %%pop/obj 1, 0;\n");
|
||||
fprintf(vvp_out, " %%pop/obj 1, 1;\n");
|
||||
} else {
|
||||
ivl_signal_t sig = ivl_expr_signal(arg);
|
||||
fprintf(vvp_out, " %%queue/unique/v v%p_0, %u;\n", sig,
|
||||
|
|
@ -306,7 +306,7 @@ static int eval_queue_method_unique(ivl_expr_t expr)
|
|||
fprintf(vvp_out, " %%load/obj v%p_0;\n", cl);
|
||||
fprintf(vvp_out, " %%queue/unique/index/prop/v %u, %u;\n",
|
||||
pidx, elem_wid);
|
||||
fprintf(vvp_out, " %%pop/obj 1, 0;\n");
|
||||
fprintf(vvp_out, " %%pop/obj 1, 1;\n");
|
||||
} else {
|
||||
ivl_signal_t sig = ivl_expr_signal(arg);
|
||||
fprintf(vvp_out, " %%queue/unique/index/v v%p_0, %u;\n",
|
||||
|
|
@ -326,7 +326,7 @@ static int eval_queue_method_unique(ivl_expr_t expr)
|
|||
fprintf(vvp_out, " %%load/obj v%p_0;\n", cl);
|
||||
fprintf(vvp_out, " %%queue/%s/prop/v %u, %u;\n", opname, pidx,
|
||||
elem_wid);
|
||||
fprintf(vvp_out, " %%pop/obj 1, 0;\n");
|
||||
fprintf(vvp_out, " %%pop/obj 1, 1;\n");
|
||||
} else {
|
||||
ivl_signal_t sig = ivl_expr_signal(arg);
|
||||
fprintf(vvp_out, " %%queue/%s/v v%p_0, %u;\n", opname, sig,
|
||||
|
|
@ -483,7 +483,8 @@ static int eval_queue_method_find_with(ivl_expr_t expr)
|
|||
fprintf(vvp_out, "T_%u.%u ; loop end (prop)\n", thread_count,
|
||||
lab_loop_end);
|
||||
if (mode == 0 || mode == 1) {
|
||||
fprintf(vvp_out, " %%pop/obj 1, 0;\n");
|
||||
/* Keep result queue object, drop class object beneath it. */
|
||||
fprintf(vvp_out, " %%pop/obj 1, 1;\n");
|
||||
} else if (mode == 6 || mode == 7) {
|
||||
fprintf(vvp_out, " %%queue/%s/obj/v %u;\n",
|
||||
mode == 6 ? "min" : "max", elem_wid);
|
||||
|
|
@ -614,7 +615,7 @@ static int eval_queue_method_find(ivl_expr_t expr)
|
|||
fprintf(vvp_out, " %%load/obj v%p_0;\n", cl);
|
||||
fprintf(vvp_out, " %%queue/find/prop/v %u, %u;\n", pidx,
|
||||
elem_wid);
|
||||
fprintf(vvp_out, " %%pop/obj 1, 0;\n");
|
||||
fprintf(vvp_out, " %%pop/obj 1, 1;\n");
|
||||
} else {
|
||||
ivl_signal_t sig = ivl_expr_signal(qarg);
|
||||
fprintf(vvp_out, " %%queue/find/v v%p_0, %u;\n", sig,
|
||||
|
|
@ -630,7 +631,7 @@ static int eval_queue_method_find(ivl_expr_t expr)
|
|||
fprintf(vvp_out, " %%load/obj v%p_0;\n", cl);
|
||||
fprintf(vvp_out, " %%queue/find/index/prop/v %u, %u;\n",
|
||||
pidx, elem_wid);
|
||||
fprintf(vvp_out, " %%pop/obj 1, 0;\n");
|
||||
fprintf(vvp_out, " %%pop/obj 1, 1;\n");
|
||||
} else {
|
||||
ivl_signal_t sig = ivl_expr_signal(qarg);
|
||||
fprintf(vvp_out, " %%queue/find/index/v v%p_0, %u;\n",
|
||||
|
|
@ -646,7 +647,7 @@ static int eval_queue_method_find(ivl_expr_t expr)
|
|||
fprintf(vvp_out, " %%load/obj v%p_0;\n", cl);
|
||||
fprintf(vvp_out, " %%queue/find_first/prop/v %u, %u;\n", pidx,
|
||||
elem_wid);
|
||||
fprintf(vvp_out, " %%pop/obj 1, 0;\n");
|
||||
fprintf(vvp_out, " %%pop/obj 1, 1;\n");
|
||||
} else {
|
||||
ivl_signal_t sig = ivl_expr_signal(qarg);
|
||||
fprintf(vvp_out, " %%queue/find_first/v v%p_0, %u;\n", sig,
|
||||
|
|
@ -661,7 +662,7 @@ static int eval_queue_method_find(ivl_expr_t expr)
|
|||
fprintf(vvp_out, " %%load/obj v%p_0;\n", cl);
|
||||
fprintf(vvp_out, " %%queue/find_first/index/prop/v %u, %u;\n",
|
||||
pidx, elem_wid);
|
||||
fprintf(vvp_out, " %%pop/obj 1, 0;\n");
|
||||
fprintf(vvp_out, " %%pop/obj 1, 1;\n");
|
||||
} else {
|
||||
ivl_signal_t sig = ivl_expr_signal(qarg);
|
||||
fprintf(vvp_out, " %%queue/find_first/index/v v%p_0, %u;\n",
|
||||
|
|
@ -676,7 +677,7 @@ static int eval_queue_method_find(ivl_expr_t expr)
|
|||
fprintf(vvp_out, " %%load/obj v%p_0;\n", cl);
|
||||
fprintf(vvp_out, " %%queue/find_last/prop/v %u, %u;\n", pidx,
|
||||
elem_wid);
|
||||
fprintf(vvp_out, " %%pop/obj 1, 0;\n");
|
||||
fprintf(vvp_out, " %%pop/obj 1, 1;\n");
|
||||
} else {
|
||||
ivl_signal_t sig = ivl_expr_signal(qarg);
|
||||
fprintf(vvp_out, " %%queue/find_last/v v%p_0, %u;\n", sig,
|
||||
|
|
@ -691,7 +692,7 @@ static int eval_queue_method_find(ivl_expr_t expr)
|
|||
fprintf(vvp_out, " %%load/obj v%p_0;\n", cl);
|
||||
fprintf(vvp_out, " %%queue/find_last/index/prop/v %u, %u;\n",
|
||||
pidx, elem_wid);
|
||||
fprintf(vvp_out, " %%pop/obj 1, 0;\n");
|
||||
fprintf(vvp_out, " %%pop/obj 1, 1;\n");
|
||||
} else {
|
||||
ivl_signal_t sig = ivl_expr_signal(qarg);
|
||||
fprintf(vvp_out, " %%queue/find_last/index/v v%p_0, %u;\n",
|
||||
|
|
|
|||
168
vvp/vthread.cc
168
vvp/vthread.cc
|
|
@ -540,6 +540,24 @@ static void get_queue_or_darray_vec4_from_net(vthread_t thr, vvp_net_t* net,
|
|||
dsrc = 0;
|
||||
}
|
||||
|
||||
static void get_queue_or_darray_vec4_from_object(vvp_object_t src_obj,
|
||||
vvp_queue_vec4*& qsrc,
|
||||
vvp_darray*& dsrc)
|
||||
{
|
||||
qsrc = src_obj.peek<vvp_queue_vec4>();
|
||||
if (qsrc) {
|
||||
dsrc = 0;
|
||||
return;
|
||||
}
|
||||
vvp_darray* dany = src_obj.peek<vvp_darray>();
|
||||
if (dany && dynamic_cast<vvp_queue*>(dany) == 0) {
|
||||
dsrc = dany;
|
||||
return;
|
||||
}
|
||||
qsrc = 0;
|
||||
dsrc = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following are used to allow a common template to be written for
|
||||
* queue real/string/vec4 operations
|
||||
|
|
@ -6428,12 +6446,11 @@ bool of_QUEUE_FIND_PROP_V(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
vvp_object_t qobj;
|
||||
cobj->get_object(pid, qobj, 0);
|
||||
vvp_queue_vec4* src = qobj.peek<vvp_queue_vec4>();
|
||||
if (src == 0) {
|
||||
thr->push_object(vvp_object_t(new vvp_queue_vec4()));
|
||||
return true;
|
||||
}
|
||||
vvp_queue_vec4* dst = queue_run_find_matches_src(src, wid, cmp, false);
|
||||
vvp_queue_vec4* qsrc = 0;
|
||||
vvp_darray* dsrc = 0;
|
||||
get_queue_or_darray_vec4_from_object(qobj, qsrc, dsrc);
|
||||
vvp_queue_vec4* dst = qsrc ? queue_run_find_matches_src(qsrc, wid, cmp, false)
|
||||
: queue_run_find_matches_src(dsrc, wid, cmp, false);
|
||||
thr->push_object(vvp_object_t(dst));
|
||||
return true;
|
||||
}
|
||||
|
|
@ -6474,12 +6491,11 @@ bool of_QUEUE_FIND_INDEX_PROP_V(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
vvp_object_t qobj;
|
||||
cobj->get_object(pid, qobj, 0);
|
||||
vvp_queue_vec4* src = qobj.peek<vvp_queue_vec4>();
|
||||
if (src == 0) {
|
||||
thr->push_object(vvp_object_t(new vvp_queue_vec4()));
|
||||
return true;
|
||||
}
|
||||
vvp_queue_vec4* dst = queue_run_find_matches_src(src, wid, cmp, true);
|
||||
vvp_queue_vec4* qsrc = 0;
|
||||
vvp_darray* dsrc = 0;
|
||||
get_queue_or_darray_vec4_from_object(qobj, qsrc, dsrc);
|
||||
vvp_queue_vec4* dst = qsrc ? queue_run_find_matches_src(qsrc, wid, cmp, true)
|
||||
: queue_run_find_matches_src(dsrc, wid, cmp, true);
|
||||
thr->push_object(vvp_object_t(dst));
|
||||
return true;
|
||||
}
|
||||
|
|
@ -6520,9 +6536,12 @@ bool of_QUEUE_FIND_FIRST_PROP_V(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
vvp_object_t qobj;
|
||||
cobj->get_object(pid, qobj, 0);
|
||||
vvp_queue_vec4* src = qobj.peek<vvp_queue_vec4>();
|
||||
vvp_queue_vec4* qsrc = 0;
|
||||
vvp_darray* dsrc = 0;
|
||||
get_queue_or_darray_vec4_from_object(qobj, qsrc, dsrc);
|
||||
vvp_queue_vec4* dst =
|
||||
queue_find_first_last_to_queue_src(src, wid, cmp, true, false);
|
||||
qsrc ? queue_find_first_last_to_queue_src(qsrc, wid, cmp, true, false)
|
||||
: queue_find_first_last_to_queue_src(dsrc, wid, cmp, true, false);
|
||||
thr->push_object(vvp_object_t(dst));
|
||||
return true;
|
||||
}
|
||||
|
|
@ -6563,9 +6582,12 @@ bool of_QUEUE_FIND_FIRST_INDEX_PROP_V(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
vvp_object_t qobj;
|
||||
cobj->get_object(pid, qobj, 0);
|
||||
vvp_queue_vec4* src = qobj.peek<vvp_queue_vec4>();
|
||||
vvp_queue_vec4* qsrc = 0;
|
||||
vvp_darray* dsrc = 0;
|
||||
get_queue_or_darray_vec4_from_object(qobj, qsrc, dsrc);
|
||||
vvp_queue_vec4* dst =
|
||||
queue_find_first_last_to_queue_src(src, wid, cmp, true, true);
|
||||
qsrc ? queue_find_first_last_to_queue_src(qsrc, wid, cmp, true, true)
|
||||
: queue_find_first_last_to_queue_src(dsrc, wid, cmp, true, true);
|
||||
thr->push_object(vvp_object_t(dst));
|
||||
return true;
|
||||
}
|
||||
|
|
@ -6606,9 +6628,12 @@ bool of_QUEUE_FIND_LAST_PROP_V(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
vvp_object_t qobj;
|
||||
cobj->get_object(pid, qobj, 0);
|
||||
vvp_queue_vec4* src = qobj.peek<vvp_queue_vec4>();
|
||||
vvp_queue_vec4* qsrc = 0;
|
||||
vvp_darray* dsrc = 0;
|
||||
get_queue_or_darray_vec4_from_object(qobj, qsrc, dsrc);
|
||||
vvp_queue_vec4* dst =
|
||||
queue_find_first_last_to_queue_src(src, wid, cmp, false, false);
|
||||
qsrc ? queue_find_first_last_to_queue_src(qsrc, wid, cmp, false, false)
|
||||
: queue_find_first_last_to_queue_src(dsrc, wid, cmp, false, false);
|
||||
thr->push_object(vvp_object_t(dst));
|
||||
return true;
|
||||
}
|
||||
|
|
@ -6649,9 +6674,12 @@ bool of_QUEUE_FIND_LAST_INDEX_PROP_V(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
vvp_object_t qobj;
|
||||
cobj->get_object(pid, qobj, 0);
|
||||
vvp_queue_vec4* src = qobj.peek<vvp_queue_vec4>();
|
||||
vvp_queue_vec4* qsrc = 0;
|
||||
vvp_darray* dsrc = 0;
|
||||
get_queue_or_darray_vec4_from_object(qobj, qsrc, dsrc);
|
||||
vvp_queue_vec4* dst =
|
||||
queue_find_first_last_to_queue_src(src, wid, cmp, false, true);
|
||||
qsrc ? queue_find_first_last_to_queue_src(qsrc, wid, cmp, false, true)
|
||||
: queue_find_first_last_to_queue_src(dsrc, wid, cmp, false, true);
|
||||
thr->push_object(vvp_object_t(dst));
|
||||
return true;
|
||||
}
|
||||
|
|
@ -6683,13 +6711,9 @@ bool of_QUEUE_MIN_OBJ_V(vthread_t thr, vvp_code_t cp)
|
|||
vvp_object_t src_obj;
|
||||
thr->pop_object(src_obj);
|
||||
|
||||
vvp_queue_vec4* qsrc = src_obj.peek<vvp_queue_vec4>();
|
||||
vvp_queue_vec4* qsrc = 0;
|
||||
vvp_darray* dsrc = 0;
|
||||
if (!qsrc) {
|
||||
vvp_darray* dany = src_obj.peek<vvp_darray>();
|
||||
if (dany && dynamic_cast<vvp_queue*>(dany) == 0)
|
||||
dsrc = dany;
|
||||
}
|
||||
get_queue_or_darray_vec4_from_object(src_obj, qsrc, dsrc);
|
||||
vvp_queue_vec4* dst = qsrc ? queue_run_min_max_src(qsrc, wid, false)
|
||||
: queue_run_min_max_src(dsrc, wid, false);
|
||||
thr->push_object(vvp_object_t(dst));
|
||||
|
|
@ -6707,13 +6731,9 @@ bool of_QUEUE_MIN_PROP_V(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
vvp_object_t qobj;
|
||||
cobj->get_object(pid, qobj, 0);
|
||||
vvp_queue_vec4* qsrc = qobj.peek<vvp_queue_vec4>();
|
||||
vvp_queue_vec4* qsrc = 0;
|
||||
vvp_darray* dsrc = 0;
|
||||
if (!qsrc) {
|
||||
vvp_darray* dany = qobj.peek<vvp_darray>();
|
||||
if (dany && dynamic_cast<vvp_queue*>(dany) == 0)
|
||||
dsrc = dany;
|
||||
}
|
||||
get_queue_or_darray_vec4_from_object(qobj, qsrc, dsrc);
|
||||
vvp_queue_vec4* dst = qsrc ? queue_run_min_max_src(qsrc, wid, false)
|
||||
: queue_run_min_max_src(dsrc, wid, false);
|
||||
thr->push_object(vvp_object_t(dst));
|
||||
|
|
@ -6747,13 +6767,9 @@ bool of_QUEUE_MAX_OBJ_V(vthread_t thr, vvp_code_t cp)
|
|||
vvp_object_t src_obj;
|
||||
thr->pop_object(src_obj);
|
||||
|
||||
vvp_queue_vec4* qsrc = src_obj.peek<vvp_queue_vec4>();
|
||||
vvp_queue_vec4* qsrc = 0;
|
||||
vvp_darray* dsrc = 0;
|
||||
if (!qsrc) {
|
||||
vvp_darray* dany = src_obj.peek<vvp_darray>();
|
||||
if (dany && dynamic_cast<vvp_queue*>(dany) == 0)
|
||||
dsrc = dany;
|
||||
}
|
||||
get_queue_or_darray_vec4_from_object(src_obj, qsrc, dsrc);
|
||||
vvp_queue_vec4* dst = qsrc ? queue_run_min_max_src(qsrc, wid, true)
|
||||
: queue_run_min_max_src(dsrc, wid, true);
|
||||
thr->push_object(vvp_object_t(dst));
|
||||
|
|
@ -6771,13 +6787,9 @@ bool of_QUEUE_MAX_PROP_V(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
vvp_object_t qobj;
|
||||
cobj->get_object(pid, qobj, 0);
|
||||
vvp_queue_vec4* qsrc = qobj.peek<vvp_queue_vec4>();
|
||||
vvp_queue_vec4* qsrc = 0;
|
||||
vvp_darray* dsrc = 0;
|
||||
if (!qsrc) {
|
||||
vvp_darray* dany = qobj.peek<vvp_darray>();
|
||||
if (dany && dynamic_cast<vvp_queue*>(dany) == 0)
|
||||
dsrc = dany;
|
||||
}
|
||||
get_queue_or_darray_vec4_from_object(qobj, qsrc, dsrc);
|
||||
vvp_queue_vec4* dst = qsrc ? queue_run_min_max_src(qsrc, wid, true)
|
||||
: queue_run_min_max_src(dsrc, wid, true);
|
||||
thr->push_object(vvp_object_t(dst));
|
||||
|
|
@ -6816,12 +6828,11 @@ bool of_QUEUE_UNIQUE_PROP_V(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
vvp_object_t qobj;
|
||||
cobj->get_object(pid, qobj, 0);
|
||||
vvp_queue_vec4* src = qobj.peek<vvp_queue_vec4>();
|
||||
if (src == 0) {
|
||||
thr->push_object(vvp_object_t(new vvp_queue_vec4()));
|
||||
return true;
|
||||
}
|
||||
vvp_queue_vec4* dst = queue_run_unique_src(src, wid, false);
|
||||
vvp_queue_vec4* qsrc = 0;
|
||||
vvp_darray* dsrc = 0;
|
||||
get_queue_or_darray_vec4_from_object(qobj, qsrc, dsrc);
|
||||
vvp_queue_vec4* dst = qsrc ? queue_run_unique_src(qsrc, wid, false)
|
||||
: queue_run_unique_src(dsrc, wid, false);
|
||||
thr->push_object(vvp_object_t(dst));
|
||||
return true;
|
||||
}
|
||||
|
|
@ -6858,12 +6869,11 @@ bool of_QUEUE_UNIQUE_INDEX_PROP_V(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
vvp_object_t qobj;
|
||||
cobj->get_object(pid, qobj, 0);
|
||||
vvp_queue_vec4* src = qobj.peek<vvp_queue_vec4>();
|
||||
if (src == 0) {
|
||||
thr->push_object(vvp_object_t(new vvp_queue_vec4()));
|
||||
return true;
|
||||
}
|
||||
vvp_queue_vec4* dst = queue_run_unique_src(src, wid, true);
|
||||
vvp_queue_vec4* qsrc = 0;
|
||||
vvp_darray* dsrc = 0;
|
||||
get_queue_or_darray_vec4_from_object(qobj, qsrc, dsrc);
|
||||
vvp_queue_vec4* dst = qsrc ? queue_run_unique_src(qsrc, wid, true)
|
||||
: queue_run_unique_src(dsrc, wid, true);
|
||||
thr->push_object(vvp_object_t(dst));
|
||||
return true;
|
||||
}
|
||||
|
|
@ -6878,9 +6888,11 @@ bool of_PROP_QUEUE_SIZE(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
vvp_object_t qobj;
|
||||
cobj->get_object(pid, qobj, 0);
|
||||
vvp_queue* queue = qobj.peek<vvp_queue>();
|
||||
vvp_queue_vec4* qsrc = 0;
|
||||
vvp_darray* dsrc = 0;
|
||||
get_queue_or_darray_vec4_from_object(qobj, qsrc, dsrc);
|
||||
|
||||
size_t sz = queue ? queue->get_size() : 0;
|
||||
size_t sz = qsrc ? qsrc->get_size() : (dsrc ? dsrc->get_size() : 0);
|
||||
|
||||
vvp_vector4_t val(32, BIT4_0);
|
||||
unsigned long ul = sz;
|
||||
|
|
@ -6975,19 +6987,51 @@ bool of_QUEUE_WORD_PROP_V(vthread_t thr, vvp_code_t cp)
|
|||
return true;
|
||||
}
|
||||
|
||||
vvp_object_t saved_top;
|
||||
bool popped_top = false;
|
||||
vvp_object_t& top = thr->peek_object();
|
||||
vvp_cobject*cobj = top.peek<vvp_cobject>();
|
||||
assert(cobj);
|
||||
if (cobj == 0) {
|
||||
// Array-locator with(property) keeps an accumulator queue on top.
|
||||
// Temporarily pop it to access the class object beneath.
|
||||
thr->pop_object(saved_top);
|
||||
popped_top = true;
|
||||
vvp_object_t& below = thr->peek_object();
|
||||
cobj = below.peek<vvp_cobject>();
|
||||
}
|
||||
if (cobj == 0) {
|
||||
if (popped_top)
|
||||
thr->push_object(saved_top);
|
||||
thr->push_vec4(vvp_vector4_t(wid));
|
||||
return true;
|
||||
}
|
||||
|
||||
vvp_object_t qobj;
|
||||
cobj->get_object(pid, qobj, 0);
|
||||
vvp_queue_vec4* src = qobj.peek<vvp_queue_vec4>();
|
||||
vvp_queue_vec4* qsrc = 0;
|
||||
vvp_darray* dsrc = 0;
|
||||
get_queue_or_darray_vec4_from_object(qobj, qsrc, dsrc);
|
||||
vvp_vector4_t out(wid);
|
||||
if (src == 0 || (size_t)adr >= src->get_size()) {
|
||||
if (qsrc) {
|
||||
if ((size_t)adr >= qsrc->get_size()) {
|
||||
thr->push_vec4(out);
|
||||
return true;
|
||||
}
|
||||
qsrc->get_word((unsigned)adr, out);
|
||||
} else if (dsrc) {
|
||||
if ((size_t)adr >= dsrc->get_size()) {
|
||||
thr->push_vec4(out);
|
||||
return true;
|
||||
}
|
||||
dsrc->get_word((unsigned)adr, out);
|
||||
} else {
|
||||
thr->push_vec4(out);
|
||||
if (popped_top)
|
||||
thr->push_object(saved_top);
|
||||
return true;
|
||||
}
|
||||
src->get_word((unsigned)adr, out);
|
||||
if (popped_top)
|
||||
thr->push_object(saved_top);
|
||||
thr->push_vec4(out);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue