mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
Internals: Hoist vpi_put_value_array argument validation to entry point. (#8384)
This commit is contained in:
+40
-24
@@ -4083,7 +4083,7 @@ bool vl_check_array_format(const VerilatedVar* varp, const p_vpi_arrayvalue arra
|
||||
case VLVT_UINT8:
|
||||
case VLVT_UINT16:
|
||||
case VLVT_UINT32: return true;
|
||||
default:; // LCOV_EXCL_LINE
|
||||
default:;
|
||||
}
|
||||
break;
|
||||
case vpiRawTwoStateVal:
|
||||
@@ -4101,7 +4101,7 @@ bool vl_check_array_format(const VerilatedVar* varp, const p_vpi_arrayvalue arra
|
||||
switch (varp->vltype()) {
|
||||
case VLVT_UINT8:
|
||||
case VLVT_UINT16: return true;
|
||||
default:; // LCOV_EXCL_LINE
|
||||
default:;
|
||||
}
|
||||
break;
|
||||
case vpiLongIntVal:
|
||||
@@ -4110,7 +4110,7 @@ bool vl_check_array_format(const VerilatedVar* varp, const p_vpi_arrayvalue arra
|
||||
case VLVT_UINT16:
|
||||
case VLVT_UINT32:
|
||||
case VLVT_UINT64: return true;
|
||||
default:; // LCOV_EXCL_LINE
|
||||
default:;
|
||||
}
|
||||
break;
|
||||
default:;
|
||||
@@ -4486,17 +4486,8 @@ void vpi_get_value_array(vpiHandle object, p_vpi_arrayvalue arrayvalue_p, PLI_IN
|
||||
void vl_put_value_array(vpiHandle object, p_vpi_arrayvalue arrayvalue_p, const PLI_INT32* index_p,
|
||||
PLI_UINT32 num) {
|
||||
const VerilatedVpioVar* const vop = VerilatedVpioVar::castp(object);
|
||||
if (!vl_check_array_format(vop->varp(), arrayvalue_p, vop->fullname())) return;
|
||||
|
||||
const VerilatedVar* const varp = vop->varp();
|
||||
|
||||
const int size = vop->size();
|
||||
if (VL_UNCOVERABLE(num > size)) {
|
||||
VL_VPI_ERROR_(__FILE__, __LINE__,
|
||||
"%s: Requested elements to set (%u) exceed array size (%u)", __func__, num,
|
||||
size);
|
||||
return;
|
||||
}
|
||||
|
||||
const bool leftIsLow = vop->rangep()->left() == vop->rangep()->low();
|
||||
const int index
|
||||
@@ -4509,113 +4500,128 @@ void vl_put_value_array(vpiHandle object, p_vpi_arrayvalue arrayvalue_p, const P
|
||||
if (varp->vltype() == VLVT_UINT8) {
|
||||
vl_put_value_array_integrals(index, num, size, varp->entBits(), leftIsLow, shortintsp,
|
||||
vop->readCDatap());
|
||||
return;
|
||||
} else if (varp->vltype() == VLVT_UINT16) {
|
||||
vl_put_value_array_integrals(index, num, size, varp->entBits(), leftIsLow, shortintsp,
|
||||
vop->readSDatap());
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
} else if (arrayvalue_p->format == vpiIntVal) {
|
||||
const PLI_UINT32* integersp = reinterpret_cast<PLI_UINT32*>(arrayvalue_p->value.integers);
|
||||
|
||||
if (varp->vltype() == VLVT_UINT8) {
|
||||
vl_put_value_array_integrals(index, num, size, varp->entBits(), leftIsLow, integersp,
|
||||
vop->readCDatap());
|
||||
return;
|
||||
} else if (varp->vltype() == VLVT_UINT16) {
|
||||
vl_put_value_array_integrals(index, num, size, varp->entBits(), leftIsLow, integersp,
|
||||
vop->readSDatap());
|
||||
return;
|
||||
} else if (varp->vltype() == VLVT_UINT32) {
|
||||
vl_put_value_array_integrals(index, num, size, varp->entBits(), leftIsLow, integersp,
|
||||
vop->readIDatap());
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
} else if (arrayvalue_p->format == vpiLongIntVal) {
|
||||
const PLI_UINT64* longintsp = reinterpret_cast<PLI_UINT64*>(arrayvalue_p->value.longints);
|
||||
|
||||
if (varp->vltype() == VLVT_UINT8) {
|
||||
vl_put_value_array_integrals(index, num, size, varp->entBits(), leftIsLow, longintsp,
|
||||
vop->readCDatap());
|
||||
return;
|
||||
} else if (varp->vltype() == VLVT_UINT16) {
|
||||
vl_put_value_array_integrals(index, num, size, varp->entBits(), leftIsLow, longintsp,
|
||||
vop->readSDatap());
|
||||
return;
|
||||
} else if (varp->vltype() == VLVT_UINT32) {
|
||||
vl_put_value_array_integrals(index, num, size, varp->entBits(), leftIsLow, longintsp,
|
||||
vop->readIDatap());
|
||||
return;
|
||||
} else if (varp->vltype() == VLVT_UINT64) {
|
||||
vl_put_value_array_integrals(index, num, size, varp->entBits(), leftIsLow, longintsp,
|
||||
vop->readQDatap());
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
} else if (arrayvalue_p->format == vpiVectorVal) {
|
||||
const p_vpi_vecval vectorsp = arrayvalue_p->value.vectors;
|
||||
|
||||
if (varp->vltype() == VLVT_UINT8) {
|
||||
vl_put_value_array_vectors(index, num, size, varp->entBits(), leftIsLow, true,
|
||||
vectorsp, vop->readCDatap());
|
||||
return;
|
||||
} else if (varp->vltype() == VLVT_UINT16) {
|
||||
vl_put_value_array_vectors(index, num, size, varp->entBits(), leftIsLow, true,
|
||||
vectorsp, vop->readSDatap());
|
||||
return;
|
||||
} else if (varp->vltype() == VLVT_UINT32) {
|
||||
vl_put_value_array_vectors(index, num, size, varp->entBits(), leftIsLow, true,
|
||||
vectorsp, vop->readIDatap());
|
||||
return;
|
||||
} else if (varp->vltype() == VLVT_UINT64) {
|
||||
vl_put_value_array_vectors(index, num, size, varp->entBits(), leftIsLow, true,
|
||||
vectorsp, vop->readQDatap());
|
||||
return;
|
||||
} else if (varp->vltype() == VLVT_WDATA) {
|
||||
vl_put_value_array_vectors(index, num, size, varp->entBits(), leftIsLow, true,
|
||||
vectorsp, vop->readEDatap());
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
} else if (arrayvalue_p->format == vpiRawFourStateVal) {
|
||||
const PLI_UBYTE8* valuep = reinterpret_cast<PLI_UBYTE8*>(arrayvalue_p->value.rawvals);
|
||||
|
||||
if (varp->vltype() == VLVT_UINT8) {
|
||||
vl_put_value_array_rawvals(index, num, size, varp->entBits(), leftIsLow, true, valuep,
|
||||
vop->readCDatap());
|
||||
return;
|
||||
} else if (varp->vltype() == VLVT_UINT16) {
|
||||
vl_put_value_array_rawvals(index, num, size, varp->entBits(), leftIsLow, true, valuep,
|
||||
vop->readSDatap());
|
||||
return;
|
||||
} else if (varp->vltype() == VLVT_UINT32) {
|
||||
vl_put_value_array_rawvals(index, num, size, varp->entBits(), leftIsLow, true, valuep,
|
||||
vop->readIDatap());
|
||||
return;
|
||||
} else if (varp->vltype() == VLVT_UINT64) {
|
||||
vl_put_value_array_rawvals(index, num, size, varp->entBits(), leftIsLow, true, valuep,
|
||||
vop->readQDatap());
|
||||
return;
|
||||
} else if (varp->vltype() == VLVT_WDATA) {
|
||||
vl_put_value_array_rawvals(index, num, size, varp->entBits(), leftIsLow, true, valuep,
|
||||
vop->readEDatap());
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
} else if (arrayvalue_p->format == vpiRawTwoStateVal) {
|
||||
const PLI_UBYTE8* valuep = reinterpret_cast<PLI_UBYTE8*>(arrayvalue_p->value.rawvals);
|
||||
|
||||
if (varp->vltype() == VLVT_UINT8) {
|
||||
vl_put_value_array_rawvals(index, num, size, varp->entBits(), leftIsLow, false, valuep,
|
||||
vop->readCDatap());
|
||||
return;
|
||||
} else if (varp->vltype() == VLVT_UINT16) {
|
||||
vl_put_value_array_rawvals(index, num, size, varp->entBits(), leftIsLow, false, valuep,
|
||||
vop->readSDatap());
|
||||
return;
|
||||
} else if (varp->vltype() == VLVT_UINT32) {
|
||||
vl_put_value_array_rawvals(index, num, size, varp->entBits(), leftIsLow, false, valuep,
|
||||
vop->readIDatap());
|
||||
return;
|
||||
} else if (varp->vltype() == VLVT_UINT64) {
|
||||
vl_put_value_array_rawvals(index, num, size, varp->entBits(), leftIsLow, false, valuep,
|
||||
vop->readQDatap());
|
||||
return;
|
||||
} else if (varp->vltype() == VLVT_WDATA) {
|
||||
vl_put_value_array_rawvals(index, num, size, varp->entBits(), leftIsLow, false, valuep,
|
||||
vop->readEDatap());
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Reached only if vl_check_array_format and this dispatch drift apart
|
||||
// LCOV_EXCL_START
|
||||
VL_VPI_ERROR_(__FILE__, __LINE__, "%s: Unsupported format (%s) as requested for '%s'",
|
||||
__func__, VerilatedVpiError::strFromVpiVal(arrayvalue_p->format),
|
||||
vop->fullname());
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
void vpi_put_value_array(vpiHandle object, p_vpi_arrayvalue arrayvalue_p, PLI_INT32* index_p,
|
||||
@@ -4670,6 +4676,16 @@ void vpi_put_value_array(vpiHandle object, p_vpi_arrayvalue arrayvalue_p, PLI_IN
|
||||
return;
|
||||
}
|
||||
|
||||
if (!vl_check_array_format(vop->varp(), arrayvalue_p, vop->fullname())) return;
|
||||
|
||||
const unsigned size = vop->size();
|
||||
if (VL_UNLIKELY(num > size)) {
|
||||
VL_VPI_ERROR_(__FILE__, __LINE__,
|
||||
"%s: Requested elements to set (%u) exceed array size (%u)", __func__, num,
|
||||
size);
|
||||
return;
|
||||
}
|
||||
if (num == 0) return;
|
||||
vl_put_value_array(object, arrayvalue_p, index_p, num);
|
||||
}
|
||||
|
||||
|
||||
@@ -506,6 +506,7 @@ int mon_check_props(void) {
|
||||
1))
|
||||
return 1;
|
||||
if (test_vpiIntVal(write_bytes_rl_name, write_bytes, i, j, NUM_ELEMENTS, 1)) return 1;
|
||||
if (test_vpiIntVal(write_shorts_name, write_shorts, i, j, NUM_ELEMENTS, 2)) return 1;
|
||||
if (test_vpiIntVal(write_words_name, write_words, i, j, NUM_ELEMENTS, 4)) return 1;
|
||||
if (test_vpiIntVal(write_integers_name, write_words, i, j, NUM_ELEMENTS, 4)) return 1;
|
||||
|
||||
@@ -667,6 +668,51 @@ int mon_check_props(void) {
|
||||
TEST_CHECK_ERROR(true);
|
||||
}
|
||||
|
||||
{
|
||||
// test every remaining format & type combination the dispatch does not handle
|
||||
TestVpiHandle longs = vpi_handle_by_name((PLI_BYTE8*)"test.write_longs", NULL);
|
||||
CHECK_RESULT_NZ(longs);
|
||||
TestVpiHandle customs = vpi_handle_by_name((PLI_BYTE8*)"test.write_customs", NULL);
|
||||
CHECK_RESULT_NZ(customs);
|
||||
|
||||
PLI_INT16 shortdatap[4] = {0, 0, 0, 0};
|
||||
PLI_INT32 intdatap[4] = {0, 0, 0, 0};
|
||||
PLI_INT64 longdatap[4] = {0, 0, 0, 0};
|
||||
s_vpi_vecval vecdatap[12] = {};
|
||||
PLI_INT32 indexp[1] = {0};
|
||||
|
||||
s_vpi_arrayvalue arrayvalue;
|
||||
arrayvalue.flags = 0;
|
||||
|
||||
arrayvalue.format = vpiShortIntVal;
|
||||
arrayvalue.value.shortints = shortdatap;
|
||||
vpi_put_value_array(longs, &arrayvalue, indexp, 4);
|
||||
TEST_CHECK_ERROR(true);
|
||||
vpi_put_value_array(customs, &arrayvalue, indexp, 4);
|
||||
TEST_CHECK_ERROR(true);
|
||||
|
||||
arrayvalue.format = vpiIntVal;
|
||||
arrayvalue.value.integers = intdatap;
|
||||
vpi_put_value_array(longs, &arrayvalue, indexp, 4);
|
||||
TEST_CHECK_ERROR(true);
|
||||
vpi_put_value_array(customs, &arrayvalue, indexp, 4);
|
||||
TEST_CHECK_ERROR(true);
|
||||
|
||||
arrayvalue.format = vpiLongIntVal;
|
||||
arrayvalue.value.longints = longdatap;
|
||||
vpi_put_value_array(customs, &arrayvalue, indexp, 4);
|
||||
TEST_CHECK_ERROR(true);
|
||||
|
||||
// test num out of bounds is reported by the entry point for every format
|
||||
vpi_put_value_array(longs, &arrayvalue, indexp, 5);
|
||||
TEST_CHECK_ERROR(true);
|
||||
|
||||
arrayvalue.format = vpiVectorVal;
|
||||
arrayvalue.value.vectors = vecdatap;
|
||||
vpi_put_value_array(customs, &arrayvalue, indexp, 5);
|
||||
TEST_CHECK_ERROR(true);
|
||||
}
|
||||
|
||||
{
|
||||
// test num out of bounds
|
||||
TestVpiHandle object = vpi_handle_by_name((PLI_BYTE8*)"test.write_words", NULL);
|
||||
|
||||
@@ -11,7 +11,14 @@ vpi_chk_error: vl_check_array_format: Unsupported format (*undefined*) as reques
|
||||
vpi_chk_error: vpi_put_value_array: Unsupported flags (4000)
|
||||
vpi_chk_error: vl_check_array_format: Unsupported format (vpiShortIntVal) as requested for 'test.write_words'
|
||||
vpi_chk_error: vpi_put_value_array: Unsupported flags (4000)
|
||||
vpi_chk_error: vl_put_value_array: Requested elements to set (5) exceed array size (4)
|
||||
vpi_chk_error: vl_check_array_format: Unsupported format (vpiShortIntVal) as requested for 'test.write_longs'
|
||||
vpi_chk_error: vl_check_array_format: Unsupported format (vpiShortIntVal) as requested for 'test.write_customs'
|
||||
vpi_chk_error: vl_check_array_format: Unsupported format (vpiIntVal) as requested for 'test.write_longs'
|
||||
vpi_chk_error: vl_check_array_format: Unsupported format (vpiIntVal) as requested for 'test.write_customs'
|
||||
vpi_chk_error: vl_check_array_format: Unsupported format (vpiLongIntVal) as requested for 'test.write_customs'
|
||||
vpi_chk_error: vpi_put_value_array: Requested elements to set (5) exceed array size (4)
|
||||
vpi_chk_error: vpi_put_value_array: Requested elements to set (5) exceed array size (4)
|
||||
vpi_chk_error: vpi_put_value_array: Requested elements to set (5) exceed array size (4)
|
||||
vpi_chk_error: Ignoring vpi_get_value_array with null value pointer
|
||||
vpi_chk_error: Ignoring vpi_get_value_array with null index pointer
|
||||
*-* All Finished *-*
|
||||
|
||||
Reference in New Issue
Block a user