Limit the use of spvCheck and spvCheckReturn to validator.

spvCheck is indeed just an if-statement. Defining such a macro
doesn't help much.
This commit is contained in:
Lei Zhang 2015-09-11 14:31:27 -04:00 коммит произвёл David Neto
Родитель 7114ffea06
Коммит 4005670363
12 изменённых файлов: 391 добавлений и 310 удалений

Просмотреть файл

@ -76,19 +76,6 @@ extern "C" {
// Helpers
#define spvCheck(condition, action) \
if (condition) { \
action; \
}
#define spvCheckReturn(expression) \
{ \
spv_result_t error = (expression); \
if (error) { \
return error; \
} \
}
#define spvIsInBitfield(value, bitfield) (value == (value & bitfield))
#define SPV_BIT(shift) (1 << (shift))

Просмотреть файл

@ -52,9 +52,8 @@ static const union {
spv_result_t spvBinaryEndianness(const spv_binary binary,
spv_endianness_t *pEndian) {
spvCheck(!binary->code || !binary->wordCount,
return SPV_ERROR_INVALID_BINARY);
spvCheck(!pEndian, return SPV_ERROR_INVALID_POINTER);
if (!binary->code || !binary->wordCount) return SPV_ERROR_INVALID_BINARY;
if (!pEndian) return SPV_ERROR_INVALID_POINTER;
uint8_t bytes[4];
memcpy(bytes, binary->code, sizeof(uint32_t));
@ -87,9 +86,8 @@ uint32_t spvFixWord(const uint32_t word, const spv_endianness_t endian) {
spv_result_t spvBinaryHeaderGet(const spv_binary binary,
const spv_endianness_t endian,
spv_header_t *pHeader) {
spvCheck(!binary->code || !binary->wordCount,
return SPV_ERROR_INVALID_BINARY);
spvCheck(!pHeader, return SPV_ERROR_INVALID_POINTER);
if (!binary->code || !binary->wordCount) return SPV_ERROR_INVALID_BINARY;
if (!pHeader) return SPV_ERROR_INVALID_POINTER;
// TODO: Validation checking?
pHeader->magic = spvFixWord(binary->code[SPV_INDEX_MAGIC_NUMBER], endian);
@ -104,9 +102,8 @@ spv_result_t spvBinaryHeaderGet(const spv_binary binary,
}
spv_result_t spvBinaryHeaderSet(spv_binary_t *binary, const uint32_t bound) {
spvCheck(!binary, return SPV_ERROR_INVALID_BINARY);
spvCheck(!binary->code || !binary->wordCount,
return SPV_ERROR_INVALID_BINARY);
if (!binary) return SPV_ERROR_INVALID_BINARY;
if (!binary->code || !binary->wordCount) return SPV_ERROR_INVALID_BINARY;
binary->code[SPV_INDEX_MAGIC_NUMBER] = SPV_MAGIC_NUMBER;
binary->code[SPV_INDEX_VERSION_NUMBER] = SPV_VERSION_NUMBER;
@ -120,10 +117,11 @@ spv_result_t spvBinaryHeaderSet(spv_binary_t *binary, const uint32_t bound) {
spv_result_t spvBinaryEncodeU32(const uint32_t value, spv_instruction_t *pInst,
const spv_position position,
spv_diagnostic *pDiagnostic) {
spvCheck(pInst->wordCount + 1 > SPV_LIMIT_INSTRUCTION_WORD_COUNT_MAX,
DIAGNOSTIC << "Instruction word count '"
<< SPV_LIMIT_INSTRUCTION_WORD_COUNT_MAX << "' exceeded.";
return SPV_ERROR_INVALID_TEXT);
if (pInst->wordCount + 1 > SPV_LIMIT_INSTRUCTION_WORD_COUNT_MAX) {
DIAGNOSTIC << "Instruction word count '"
<< SPV_LIMIT_INSTRUCTION_WORD_COUNT_MAX << "' exceeded.";
return SPV_ERROR_INVALID_TEXT;
}
pInst->words[pInst->wordCount++] = (uint32_t)value;
return SPV_SUCCESS;
@ -132,10 +130,11 @@ spv_result_t spvBinaryEncodeU32(const uint32_t value, spv_instruction_t *pInst,
spv_result_t spvBinaryEncodeU64(const uint64_t value, spv_instruction_t *pInst,
const spv_position position,
spv_diagnostic *pDiagnostic) {
spvCheck(pInst->wordCount + 2 > SPV_LIMIT_INSTRUCTION_WORD_COUNT_MAX,
DIAGNOSTIC << "Instruction word count '"
<< SPV_LIMIT_INSTRUCTION_WORD_COUNT_MAX << "' exceeded.";
return SPV_ERROR_INVALID_TEXT);
if (pInst->wordCount + 2 > SPV_LIMIT_INSTRUCTION_WORD_COUNT_MAX) {
DIAGNOSTIC << "Instruction word count '"
<< SPV_LIMIT_INSTRUCTION_WORD_COUNT_MAX << "' exceeded.";
return SPV_ERROR_INVALID_TEXT;
}
uint32_t low = (uint32_t)(0x00000000ffffffff & value);
uint32_t high = (uint32_t)((0xffffffff00000000 & value) >> 32);
@ -149,11 +148,12 @@ spv_result_t spvBinaryEncodeString(const char *str, spv_instruction_t *pInst,
spv_diagnostic *pDiagnostic) {
size_t length = strlen(str);
size_t wordCount = (length / 4) + 1;
spvCheck((sizeof(uint32_t) * pInst->wordCount) + length >
sizeof(uint32_t) * SPV_LIMIT_INSTRUCTION_WORD_COUNT_MAX,
DIAGNOSTIC << "Instruction word count '"
<< SPV_LIMIT_INSTRUCTION_WORD_COUNT_MAX << "'exceeded.";
return SPV_ERROR_INVALID_TEXT);
if ((sizeof(uint32_t) * pInst->wordCount) + length >
sizeof(uint32_t) * SPV_LIMIT_INSTRUCTION_WORD_COUNT_MAX) {
DIAGNOSTIC << "Instruction word count '"
<< SPV_LIMIT_INSTRUCTION_WORD_COUNT_MAX << "'exceeded.";
return SPV_ERROR_INVALID_TEXT;
}
char *dest = (char *)&pInst->words[pInst->wordCount];
strncpy(dest, str, length);
@ -209,8 +209,8 @@ spv_result_t spvBinaryDecodeOperand(
const spv_operand_table operandTable, const spv_ext_inst_table extInstTable,
spv_operand_pattern_t *pExpectedOperands, spv_ext_inst_type_t *pExtInstType,
out_stream &stream, spv_position position, spv_diagnostic *pDiagnostic) {
spvCheck(!words || !position, return SPV_ERROR_INVALID_POINTER);
spvCheck(!pDiagnostic, return SPV_ERROR_INVALID_DIAGNOSTIC);
if (!words || !position) return SPV_ERROR_INVALID_POINTER;
if (!pDiagnostic) return SPV_ERROR_INVALID_DIAGNOSTIC;
bool print = spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_PRINT, options);
bool color =
@ -248,11 +248,11 @@ spv_result_t spvBinaryDecodeOperand(
// NOTE: Special case for extended instruction use
if (OpExtInst == opcode) {
spv_ext_inst_desc extInst;
spvCheck(spvExtInstTableValueLookup(extInstTable, *pExtInstType,
words[0], &extInst),
DIAGNOSTIC << "Invalid extended instruction '" << words[0]
<< "'.";
return SPV_ERROR_INVALID_BINARY);
if (spvExtInstTableValueLookup(extInstTable, *pExtInstType, words[0],
&extInst)) {
DIAGNOSTIC << "Invalid extended instruction '" << words[0] << "'.";
return SPV_ERROR_INVALID_BINARY;
}
spvPrependOperandTypes(extInst->operandTypes, pExpectedOperands);
stream.get() << (color ? clr::red() : "");
stream.get() << extInst->name;
@ -273,10 +273,11 @@ spv_result_t spvBinaryDecodeOperand(
// NOTE: Special case for extended instruction import
if (OpExtInstImport == opcode) {
*pExtInstType = spvExtInstImportTypeGet(string);
spvCheck(SPV_EXT_INST_TYPE_NONE == *pExtInstType,
DIAGNOSTIC << "Invalid extended instruction import'" << string
<< "'.";
return SPV_ERROR_INVALID_BINARY);
if (SPV_EXT_INST_TYPE_NONE == *pExtInstType) {
DIAGNOSTIC << "Invalid extended instruction import'" << string
<< "'.";
return SPV_ERROR_INVALID_BINARY;
}
}
stream.get() << "\"";
@ -315,12 +316,12 @@ spv_result_t spvBinaryDecodeOperand(
case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO: {
spv_operand_desc entry;
spvCheck(
spvOperandTableValueLookup(operandTable, type,
spvFixWord(words[index], endian), &entry),
DIAGNOSTIC << "Invalid " << spvOperandTypeStr(type) << " operand '"
<< words[index] << "'.";
return SPV_ERROR_INVALID_TEXT);
if (spvOperandTableValueLookup(
operandTable, type, spvFixWord(words[index], endian), &entry)) {
DIAGNOSTIC << "Invalid " << spvOperandTypeStr(type) << " operand '"
<< words[index] << "'.";
return SPV_ERROR_INVALID_TEXT;
}
stream.get() << entry->name;
// Prepare to accept operands to this operand, if needed.
spvPrependOperandTypes(entry->operandTypes, pExpectedOperands);
@ -342,10 +343,10 @@ spv_result_t spvBinaryDecodeOpcode(
const spv_operand_table operandTable, const spv_ext_inst_table extInstTable,
spv_assembly_syntax_format_t format, out_stream &stream,
spv_position position, spv_diagnostic *pDiagnostic) {
spvCheck(!pInst || !position, return SPV_ERROR_INVALID_POINTER);
spvCheck(!opcodeTable || !operandTable || !extInstTable,
return SPV_ERROR_INVALID_TABLE);
spvCheck(!pDiagnostic, return SPV_ERROR_INVALID_DIAGNOSTIC);
if (!pInst || !position) return SPV_ERROR_INVALID_POINTER;
if (!opcodeTable || !operandTable || !extInstTable)
return SPV_ERROR_INVALID_TABLE;
if (!pDiagnostic) return SPV_ERROR_INVALID_DIAGNOSTIC;
spv_position_t instructionStart = *position;
@ -354,9 +355,10 @@ spv_result_t spvBinaryDecodeOpcode(
spvOpcodeSplit(spvFixWord(pInst->words[0], endian), &wordCount, &opcode);
spv_opcode_desc opcodeEntry;
spvCheck(spvOpcodeTableValueLookup(opcodeTable, opcode, &opcodeEntry),
DIAGNOSTIC << "Invalid Opcode '" << opcode << "'.";
return SPV_ERROR_INVALID_BINARY);
if (spvOpcodeTableValueLookup(opcodeTable, opcode, &opcodeEntry)) {
DIAGNOSTIC << "Invalid Opcode '" << opcode << "'.";
return SPV_ERROR_INVALID_BINARY;
}
// See if there are enough required words.
// Some operands in the operand types are optional or could be zero length.
@ -407,12 +409,13 @@ spv_result_t spvBinaryDecodeOpcode(
const uint64_t currentPosIndex = position->index;
const bool currentIsResultId = result_id_index == index - 1;
spvCheck(expectedOperands.empty(),
DIAGNOSTIC << "Invalid instruction Op" << opcodeEntry->name
<< " starting at word " << instructionStart.index
<< ": expected no more operands after " << index
<< " words, but word count is " << wordCount << ".";
return SPV_ERROR_INVALID_BINARY;);
if (expectedOperands.empty()) {
DIAGNOSTIC << "Invalid instruction Op" << opcodeEntry->name
<< " starting at word " << instructionStart.index
<< ": expected no more operands after " << index
<< " words, but word count is " << wordCount << ".";
return SPV_ERROR_INVALID_BINARY;
}
spv_operand_type_t type = spvTakeFirstMatchableOperand(&expectedOperands);
@ -421,26 +424,26 @@ spv_result_t spvBinaryDecodeOpcode(
} else {
stream.get() << " ";
}
spvCheck(
spvBinaryDecodeOperand(
if (spvBinaryDecodeOperand(
opcodeEntry->opcode, type, pInst->words + index, endian, options,
operandTable, extInstTable, &expectedOperands, &pInst->extInstType,
(isAssigmentFormat && !currentIsResultId ? no_result_id_stream
: stream),
position, pDiagnostic),
DIAGNOSTIC << "UNEXPLAINED ERROR";
return SPV_ERROR_INVALID_BINARY);
position, pDiagnostic)) {
DIAGNOSTIC << "UNEXPLAINED ERROR";
return SPV_ERROR_INVALID_BINARY;
}
if (isAssigmentFormat && currentIsResultId) stream.get() << " = ";
index += (uint16_t)(position->index - currentPosIndex - 1);
}
// TODO(dneto): There's an opportunity for a more informative message.
spvCheck(!expectedOperands.empty() &&
!spvOperandIsOptional(expectedOperands.front()),
DIAGNOSTIC << "Invalid instruction Op" << opcodeEntry->name
<< " starting at word " << instructionStart.index << ": "
<< " expected more operands after " << wordCount
<< " words.";
return SPV_ERROR_INVALID_BINARY;);
if (!expectedOperands.empty() &&
!spvOperandIsOptional(expectedOperands.front())) {
DIAGNOSTIC << "Invalid instruction Op" << opcodeEntry->name
<< " starting at word " << instructionStart.index
<< ": expected more operands after " << wordCount << " words.";
return SPV_ERROR_INVALID_BINARY;
}
stream.get() << no_result_id_strstream.str();
@ -466,27 +469,30 @@ spv_result_t spvBinaryToTextWithFormat(
spv_binary_t binary = {code, wordCount};
spv_position_t position = {};
spvCheck(!binary.code || !binary.wordCount, DIAGNOSTIC
<< "Binary stream is empty.";
return SPV_ERROR_INVALID_BINARY);
spvCheck(!opcodeTable || !operandTable || !extInstTable,
return SPV_ERROR_INVALID_TABLE);
spvCheck(pText && spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_PRINT, options),
return SPV_ERROR_INVALID_POINTER);
spvCheck(!pText && !spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_PRINT, options),
return SPV_ERROR_INVALID_POINTER);
spvCheck(!pDiagnostic, return SPV_ERROR_INVALID_DIAGNOSTIC);
if (!binary.code || !binary.wordCount) {
DIAGNOSTIC << "Binary stream is empty.";
return SPV_ERROR_INVALID_BINARY;
}
if (!opcodeTable || !operandTable || !extInstTable)
return SPV_ERROR_INVALID_TABLE;
if (pText && spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_PRINT, options))
return SPV_ERROR_INVALID_POINTER;
if (!pText && !spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_PRINT, options))
return SPV_ERROR_INVALID_POINTER;
if (!pDiagnostic) return SPV_ERROR_INVALID_DIAGNOSTIC;
spv_endianness_t endian;
spvCheck(spvBinaryEndianness(&binary, &endian),
DIAGNOSTIC << "Invalid SPIR-V magic number '" << std::hex
<< binary.code[0] << "'.";
return SPV_ERROR_INVALID_BINARY);
if (spvBinaryEndianness(&binary, &endian)) {
DIAGNOSTIC << "Invalid SPIR-V magic number '" << std::hex << binary.code[0]
<< "'.";
return SPV_ERROR_INVALID_BINARY;
}
spv_header_t header;
spvCheck(spvBinaryHeaderGet(&binary, endian, &header),
DIAGNOSTIC << "Invalid SPIR-V header.";
return SPV_ERROR_INVALID_BINARY);
if (spvBinaryHeaderGet(&binary, endian, &header)) {
DIAGNOSTIC << "Invalid SPIR-V header.";
return SPV_ERROR_INVALID_BINARY;
}
bool print = spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_PRINT, options);
bool color =
@ -525,15 +531,16 @@ spv_result_t spvBinaryToTextWithFormat(
spvInstructionCopy(&words[position.index], opcode, wordCount, endian,
&inst);
spvCheck(spvBinaryDecodeOpcode(&inst, endian, options, opcodeTable,
operandTable, extInstTable, format, stream,
&position, pDiagnostic),
return SPV_ERROR_INVALID_BINARY);
if (spvBinaryDecodeOpcode(&inst, endian, options, opcodeTable, operandTable,
extInstTable, format, stream, &position,
pDiagnostic))
return SPV_ERROR_INVALID_BINARY;
extInstType = inst.extInstType;
spvCheck((index + wordCount) != position.index,
DIAGNOSTIC << "Invalid word count.";
return SPV_ERROR_INVALID_BINARY);
if ((index + wordCount) != position.index) {
DIAGNOSTIC << "Invalid word count.";
return SPV_ERROR_INVALID_BINARY;
}
stream.get() << "\n";
}
@ -541,10 +548,10 @@ spv_result_t spvBinaryToTextWithFormat(
if (!print) {
size_t length = sstream.str().size();
char *str = new char[length + 1];
spvCheck(!str, return SPV_ERROR_OUT_OF_MEMORY);
if (!str) return SPV_ERROR_OUT_OF_MEMORY;
strncpy(str, sstream.str().c_str(), length + 1);
spv_text text = new spv_text_t();
spvCheck(!text, return SPV_ERROR_OUT_OF_MEMORY);
if (!text) return SPV_ERROR_OUT_OF_MEMORY;
text->str = str;
text->length = length;
*pText = text;
@ -554,7 +561,7 @@ spv_result_t spvBinaryToTextWithFormat(
}
void spvBinaryDestroy(spv_binary binary) {
spvCheck(!binary, return );
if (!binary) return;
if (binary->code) {
delete[] binary->code;
}

Просмотреть файл

@ -37,10 +37,13 @@
spv_diagnostic spvDiagnosticCreate(const spv_position position,
const char *message) {
spv_diagnostic diagnostic = new spv_diagnostic_t;
spvCheck(!diagnostic, return nullptr);
if (!diagnostic) return nullptr;
size_t length = strlen(message) + 1;
diagnostic->error = new char[length];
spvCheck(!diagnostic->error, delete diagnostic; return nullptr);
if (!diagnostic->error) {
delete diagnostic;
return nullptr;
}
diagnostic->position = *position;
diagnostic->isTextSource = false;
memset(diagnostic->error, 0, length);
@ -49,7 +52,7 @@ spv_diagnostic spvDiagnosticCreate(const spv_position position,
}
void spvDiagnosticDestroy(spv_diagnostic diagnostic) {
spvCheck(!diagnostic, return );
if (!diagnostic) return;
if (diagnostic->error) {
delete[] diagnostic->error;
}
@ -57,7 +60,7 @@ void spvDiagnosticDestroy(spv_diagnostic diagnostic) {
}
spv_result_t spvDiagnosticPrint(const spv_diagnostic diagnostic) {
spvCheck(!diagnostic, return SPV_ERROR_INVALID_DIAGNOSTIC);
if (!diagnostic) return SPV_ERROR_INVALID_DIAGNOSTIC;
if (diagnostic->isTextSource) {
// NOTE: This is a text position

Просмотреть файл

@ -124,7 +124,7 @@ static const spv_ext_inst_desc_t openclStd21Entries[] = {
};
spv_result_t spvExtInstTableGet(spv_ext_inst_table *pExtInstTable) {
spvCheck(!pExtInstTable, return SPV_ERROR_INVALID_POINTER);
if (!pExtInstTable) return SPV_ERROR_INVALID_POINTER;
static const spv_ext_inst_group_t groups[] = {
{SPV_EXT_INST_TYPE_GLSL_STD_450,
@ -169,8 +169,8 @@ spv_result_t spvExtInstTableNameLookup(const spv_ext_inst_table table,
const spv_ext_inst_type_t type,
const char *name,
spv_ext_inst_desc *pEntry) {
spvCheck(!table, return SPV_ERROR_INVALID_TABLE);
spvCheck(!pEntry, return SPV_ERROR_INVALID_POINTER);
if (!table) return SPV_ERROR_INVALID_TABLE;
if (!pEntry) return SPV_ERROR_INVALID_POINTER;
for (uint32_t groupIndex = 0; groupIndex < table->count; groupIndex++) {
auto &group = table->groups[groupIndex];
@ -192,8 +192,8 @@ spv_result_t spvExtInstTableValueLookup(const spv_ext_inst_table table,
const spv_ext_inst_type_t type,
const uint32_t value,
spv_ext_inst_desc *pEntry) {
spvCheck(!table, return SPV_ERROR_INVALID_TABLE);
spvCheck(!pEntry, return SPV_ERROR_INVALID_POINTER);
if (!table) return SPV_ERROR_INVALID_TABLE;
if (!pEntry) return SPV_ERROR_INVALID_POINTER;
for (uint32_t groupIndex = 0; groupIndex < table->count; groupIndex++) {
auto &group = table->groups[groupIndex];

Просмотреть файл

@ -73,13 +73,13 @@ bool opcodeTableInitialized = false;
// Converts the given operand class enum (from the SPIR-V document generation
// logic) to the operand type required by the parser.
// This only applies to logical operands.
spv_operand_type_t convertOperandClassToType(spv::Op opcode, spv::OperandClass operandClass) {
spv_operand_type_t convertOperandClassToType(spv::Op opcode,
spv::OperandClass operandClass) {
// The spec document generator uses OptionalOperandLiteral for several kinds
// of repeating values. Our parser needs more specific information about
// what is being repeated.
if (operandClass == OperandOptionalLiteral) {
switch(opcode) {
switch (opcode) {
case spv::OpLoad:
case spv::OpStore:
case spv::OpCopyMemory:
@ -217,7 +217,7 @@ void spvOpcodeSplit(const uint32_t word, uint16_t *pWordCount, Op *pOpcode) {
}
spv_result_t spvOpcodeTableGet(spv_opcode_table *pInstTable) {
spvCheck(!pInstTable, return SPV_ERROR_INVALID_POINTER);
if (!pInstTable) return SPV_ERROR_INVALID_POINTER;
static spv_opcode_table_t table = {
sizeof(opcodeTableEntries) / sizeof(spv_opcode_desc_t),
@ -225,8 +225,7 @@ spv_result_t spvOpcodeTableGet(spv_opcode_table *pInstTable) {
// TODO(dneto): Consider thread safety of initialization.
// That is, ordering effects of the flag vs. the table updates.
if (!opcodeTableInitialized)
spvOpcodeTableInitialize();
if (!opcodeTableInitialized) spvOpcodeTableInitialize();
*pInstTable = &table;
@ -236,8 +235,8 @@ spv_result_t spvOpcodeTableGet(spv_opcode_table *pInstTable) {
spv_result_t spvOpcodeTableNameLookup(const spv_opcode_table table,
const char *name,
spv_opcode_desc *pEntry) {
spvCheck(!name || !pEntry, return SPV_ERROR_INVALID_POINTER);
spvCheck(!table, return SPV_ERROR_INVALID_TABLE);
if (!name || !pEntry) return SPV_ERROR_INVALID_POINTER;
if (!table) return SPV_ERROR_INVALID_TABLE;
// TODO: This lookup of the Opcode table is suboptimal! Binary sort would be
// preferable but the table requires sorting on the Opcode name, but it's
@ -259,8 +258,8 @@ spv_result_t spvOpcodeTableNameLookup(const spv_opcode_table table,
spv_result_t spvOpcodeTableValueLookup(const spv_opcode_table table,
const Op opcode,
spv_opcode_desc *pEntry) {
spvCheck(!table, return SPV_ERROR_INVALID_TABLE);
spvCheck(!pEntry, return SPV_ERROR_INVALID_POINTER);
if (!table) return SPV_ERROR_INVALID_TABLE;
if (!pEntry) return SPV_ERROR_INVALID_POINTER;
// TODO: As above this lookup is not optimal.
for (uint64_t opcodeIndex = 0; opcodeIndex < table->count; ++opcodeIndex) {
@ -615,8 +614,8 @@ int32_t spvOpcodeIsComposite(const Op opcode) {
int32_t spvOpcodeAreTypesEqual(const spv_instruction_t *pTypeInst0,
const spv_instruction_t *pTypeInst1) {
spvCheck(pTypeInst0->opcode != pTypeInst1->opcode, return false);
spvCheck(pTypeInst0->words[1] != pTypeInst1->words[1], return false);
if (pTypeInst0->opcode != pTypeInst1->opcode) return false;
if (pTypeInst0->words[1] != pTypeInst1->words[1]) return false;
return true;
}
@ -766,16 +765,16 @@ int32_t spvOpcodeIsBasicTypeNullable(Op opcode) {
int32_t spvInstructionIsInBasicBlock(const spv_instruction_t *pFirstInst,
const spv_instruction_t *pInst) {
while (pFirstInst != pInst) {
spvCheck(OpFunction == pInst->opcode, break);
if (OpFunction == pInst->opcode) break;
pInst--;
}
spvCheck(OpFunction != pInst->opcode, return false);
if (OpFunction != pInst->opcode) return false;
return true;
}
int32_t spvOpcodeIsValue(Op opcode) {
spvCheck(spvOpcodeIsPointer(opcode), return true);
spvCheck(spvOpcodeIsConstant(opcode), return true);
if (spvOpcodeIsPointer(opcode)) return true;
if (spvOpcodeIsConstant(opcode)) return true;
switch (opcode) {
case OpLoad:
// TODO: Other Opcode's resulting in a value

Просмотреть файл

@ -1383,7 +1383,7 @@ static const spv_operand_desc_group_t opcodeEntryTypes[] = {
};
spv_result_t spvOperandTableGet(spv_operand_table *pOperandTable) {
spvCheck(!pOperandTable, return SPV_ERROR_INVALID_POINTER);
if (!pOperandTable) return SPV_ERROR_INVALID_POINTER;
static const spv_operand_table_t table = {
sizeof(opcodeEntryTypes) / sizeof(spv_operand_desc_group_t),
@ -1398,8 +1398,8 @@ spv_result_t spvOperandTableNameLookup(const spv_operand_table table,
const spv_operand_type_t type,
const char *name,
spv_operand_desc *pEntry) {
spvCheck(!table, return SPV_ERROR_INVALID_TABLE);
spvCheck(!name || !pEntry, return SPV_ERROR_INVALID_POINTER);
if (!table) return SPV_ERROR_INVALID_TABLE;
if (!name || !pEntry) return SPV_ERROR_INVALID_POINTER;
const uint64_t nameLength = strlen(name);
for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
@ -1424,8 +1424,8 @@ spv_result_t spvOperandTableValueLookup(const spv_operand_table table,
const spv_operand_type_t type,
const uint32_t value,
spv_operand_desc *pEntry) {
spvCheck(!table, return SPV_ERROR_INVALID_TABLE);
spvCheck(!pEntry, return SPV_ERROR_INVALID_POINTER);
if (!table) return SPV_ERROR_INVALID_TABLE;
if (!pEntry) return SPV_ERROR_INVALID_POINTER;
for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
if (type == table->types[typeIndex].type) {

Просмотреть файл

@ -69,7 +69,7 @@ std::string spvGetWord(const char *str) {
}
}
assert(0 && "Unreachable");
return ""; // Make certain compilers happy.
return ""; // Make certain compilers happy.
}
spv_named_id_table spvNamedIdTableCreate() {
@ -153,8 +153,8 @@ spv_result_t spvTextAdvance(const spv_text text, spv_position position) {
spv_result_t spvTextWordGet(const spv_text text,
const spv_position startPosition, std::string &word,
spv_position endPosition) {
spvCheck(!text->str || !text->length, return SPV_ERROR_INVALID_TEXT);
spvCheck(!startPosition || !endPosition, return SPV_ERROR_INVALID_POINTER);
if (!text->str || !text->length) return SPV_ERROR_INVALID_TEXT;
if (!startPosition || !endPosition) return SPV_ERROR_INVALID_POINTER;
*endPosition = *startPosition;
@ -231,11 +231,10 @@ bool spvTextIsStartOfNewInst(const spv_text text, const spv_position position) {
spv_result_t spvTextStringGet(const spv_text text,
const spv_position startPosition,
std::string &string, spv_position endPosition) {
spvCheck(!text->str || !text->length, return SPV_ERROR_INVALID_TEXT);
spvCheck(!startPosition || !endPosition, return SPV_ERROR_INVALID_POINTER);
if (!text->str || !text->length) return SPV_ERROR_INVALID_TEXT;
if (!startPosition || !endPosition) return SPV_ERROR_INVALID_POINTER;
spvCheck('"' != text->str[startPosition->index],
return SPV_ERROR_INVALID_TEXT);
if ('"' != text->str[startPosition->index]) return SPV_ERROR_INVALID_TEXT;
*endPosition = *startPosition;
@ -369,9 +368,10 @@ spv_result_t spvTextEncodeOperand(
uint32_t immediateInt = strtoul(begin, &end, 0);
size_t size = strlen(textValue);
size_t length = (end - begin);
spvCheck(size - 1 != length, DIAGNOSTIC << "Invalid immediate integer '"
<< textValue << "'.";
return SPV_ERROR_INVALID_TEXT);
if (size - 1 != length) {
DIAGNOSTIC << "Invalid immediate integer '" << textValue << "'.";
return SPV_ERROR_INVALID_TEXT;
}
position->column += size;
position->index += size;
pInst->words[pInst->wordCount] = immediateInt;
@ -413,11 +413,12 @@ spv_result_t spvTextEncodeOperand(
// NOTE: Special case for extension instruction lookup
if (OpExtInst == pInst->opcode) {
spv_ext_inst_desc extInst;
spvCheck(spvExtInstTableNameLookup(extInstTable, pInst->extInstType,
textValue, &extInst),
DIAGNOSTIC << "Invalid extended instruction name '"
<< textValue << "'.";
return SPV_ERROR_INVALID_TEXT);
if (spvExtInstTableNameLookup(extInstTable, pInst->extInstType,
textValue, &extInst)) {
DIAGNOSTIC << "Invalid extended instruction name '" << textValue
<< "'.";
return SPV_ERROR_INVALID_TEXT;
}
pInst->words[pInst->wordCount++] = extInst->ext_inst;
// Prepare to parse the operands for the extended instructions.
@ -430,9 +431,10 @@ spv_result_t spvTextEncodeOperand(
// includes integers and floating point numbers.
// TODO(dneto): Suggest using spvTextToLiteral and looking for an
// appropriate result type.
spvCheck(spvTextToUInt32(textValue, &pInst->words[pInst->wordCount++]),
DIAGNOSTIC << "Invalid literal number '" << textValue << "'.";
return SPV_ERROR_INVALID_TEXT);
if (spvTextToUInt32(textValue, &pInst->words[pInst->wordCount++])) {
DIAGNOSTIC << "Invalid literal number '" << textValue << "'.";
return SPV_ERROR_INVALID_TEXT;
}
} break;
case SPV_OPERAND_TYPE_LITERAL:
case SPV_OPERAND_TYPE_LITERAL_IN_OPTIONAL_TUPLE:
@ -450,39 +452,39 @@ spv_result_t spvTextEncodeOperand(
// We do not have to print diagnostics here because spvBinaryEncode*
// prints diagnostic messages on failure.
case SPV_LITERAL_TYPE_INT_32:
spvCheck(spvBinaryEncodeU32(BitwiseCast<uint32_t>(literal.value.i32),
pInst, position, pDiagnostic),
return SPV_ERROR_INVALID_TEXT);
if (spvBinaryEncodeU32(BitwiseCast<uint32_t>(literal.value.i32),
pInst, position, pDiagnostic))
return SPV_ERROR_INVALID_TEXT;
break;
case SPV_LITERAL_TYPE_INT_64: {
spvCheck(spvBinaryEncodeU64(BitwiseCast<uint64_t>(literal.value.i64),
pInst, position, pDiagnostic),
return SPV_ERROR_INVALID_TEXT);
if (spvBinaryEncodeU64(BitwiseCast<uint64_t>(literal.value.i64),
pInst, position, pDiagnostic))
return SPV_ERROR_INVALID_TEXT;
} break;
case SPV_LITERAL_TYPE_UINT_32: {
spvCheck(spvBinaryEncodeU32(literal.value.u32, pInst, position,
pDiagnostic),
return SPV_ERROR_INVALID_TEXT);
if (spvBinaryEncodeU32(literal.value.u32, pInst, position,
pDiagnostic))
return SPV_ERROR_INVALID_TEXT;
} break;
case SPV_LITERAL_TYPE_UINT_64: {
spvCheck(spvBinaryEncodeU64(BitwiseCast<uint64_t>(literal.value.u64),
pInst, position, pDiagnostic),
return SPV_ERROR_INVALID_TEXT);
if (spvBinaryEncodeU64(BitwiseCast<uint64_t>(literal.value.u64),
pInst, position, pDiagnostic))
return SPV_ERROR_INVALID_TEXT;
} break;
case SPV_LITERAL_TYPE_FLOAT_32: {
spvCheck(spvBinaryEncodeU32(BitwiseCast<uint32_t>(literal.value.f),
pInst, position, pDiagnostic),
return SPV_ERROR_INVALID_TEXT);
if (spvBinaryEncodeU32(BitwiseCast<uint32_t>(literal.value.f), pInst,
position, pDiagnostic))
return SPV_ERROR_INVALID_TEXT;
} break;
case SPV_LITERAL_TYPE_FLOAT_64: {
spvCheck(spvBinaryEncodeU64(BitwiseCast<uint64_t>(literal.value.d),
pInst, position, pDiagnostic),
return SPV_ERROR_INVALID_TEXT);
if (spvBinaryEncodeU64(BitwiseCast<uint64_t>(literal.value.d), pInst,
position, pDiagnostic))
return SPV_ERROR_INVALID_TEXT;
} break;
case SPV_LITERAL_TYPE_STRING: {
spvCheck(spvBinaryEncodeString(literal.value.str, pInst, position,
pDiagnostic),
return SPV_ERROR_INVALID_TEXT);
if (spvBinaryEncodeString(literal.value.str, pInst, position,
pDiagnostic))
return SPV_ERROR_INVALID_TEXT;
} break;
default:
DIAGNOSTIC << "Invalid literal '" << textValue << "'";
@ -492,11 +494,12 @@ spv_result_t spvTextEncodeOperand(
case SPV_OPERAND_TYPE_LITERAL_STRING:
case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING: {
size_t len = strlen(textValue);
spvCheck('"' != textValue[0] && '"' != textValue[len - 1],
if (spvOperandIsOptional(type)) return SPV_FAILED_MATCH;
DIAGNOSTIC << "Invalid literal string '" << textValue
<< "', expected quotes.";
return SPV_ERROR_INVALID_TEXT;);
if ('"' != textValue[0] && '"' != textValue[len - 1]) {
if (spvOperandIsOptional(type)) return SPV_FAILED_MATCH;
DIAGNOSTIC << "Invalid literal string '" << textValue
<< "', expected quotes.";
return SPV_ERROR_INVALID_TEXT;
}
// NOTE: Strip quotes
std::string text(textValue + 1, len - 2);
@ -505,9 +508,8 @@ spv_result_t spvTextEncodeOperand(
pInst->extInstType = spvExtInstImportTypeGet(text.c_str());
}
spvCheck(
spvBinaryEncodeString(text.c_str(), pInst, position, pDiagnostic),
return SPV_ERROR_INVALID_TEXT);
if (spvBinaryEncodeString(text.c_str(), pInst, position, pDiagnostic))
return SPV_ERROR_INVALID_TEXT;
} break;
case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
assert(0 && " Handle optional optional image operands");
@ -516,14 +518,16 @@ spv_result_t spvTextEncodeOperand(
// NOTE: All non literal operands are handled here using the operand
// table.
spv_operand_desc entry;
spvCheck(spvOperandTableNameLookup(operandTable, type, textValue, &entry),
DIAGNOSTIC << "Invalid " << spvOperandTypeStr(type) << " '"
<< textValue << "'.";
return SPV_ERROR_INVALID_TEXT;);
spvCheck(spvBinaryEncodeU32(entry->value, pInst, position, pDiagnostic),
DIAGNOSTIC << "Invalid " << spvOperandTypeStr(type) << " '"
<< textValue << "'.";
return SPV_ERROR_INVALID_TEXT;);
if (spvOperandTableNameLookup(operandTable, type, textValue, &entry)) {
DIAGNOSTIC << "Invalid " << spvOperandTypeStr(type) << " '" << textValue
<< "'.";
return SPV_ERROR_INVALID_TEXT;
}
if (spvBinaryEncodeU32(entry->value, pInst, position, pDiagnostic)) {
DIAGNOSTIC << "Invalid " << spvOperandTypeStr(type) << " '" << textValue
<< "'.";
return SPV_ERROR_INVALID_TEXT;
}
// Prepare to parse the operands for this logical operand.
spvPrependOperandTypes(entry->operandTypes, pExpectedOperands);
@ -547,15 +551,19 @@ spv_result_t encodeInstructionStartingWithImmediate(
std::string firstWord;
spv_position_t nextPosition = {};
auto error = spvTextWordGet(text, position, firstWord, &nextPosition);
spvCheck(error, DIAGNOSTIC << "Internal Error"; return error);
if (error) {
DIAGNOSTIC << "Internal Error";
return error;
}
assert(firstWord[0] == '!');
const char *begin = firstWord.data() + 1;
char *end = nullptr;
uint32_t immediateInt = strtoul(begin, &end, 0);
spvCheck((begin + firstWord.size() - 1) != end,
DIAGNOSTIC << "Invalid immediate integer '" << firstWord << "'.";
return SPV_ERROR_INVALID_TEXT);
if ((begin + firstWord.size() - 1) != end) {
DIAGNOSTIC << "Invalid immediate integer '" << firstWord << "'.";
return SPV_ERROR_INVALID_TEXT;
}
position->column += firstWord.size();
position->index += firstWord.size();
pInst->words[0] = immediateInt;
@ -590,7 +598,7 @@ spv_result_t encodeInstructionStartingWithImmediate(
<< operandValue;
}
}
spvCheck(error, return error);
if (error) return error;
*position = nextPosition;
}
return SPV_SUCCESS;
@ -624,7 +632,10 @@ spv_result_t spvTextEncodeOpcode(
std::string firstWord;
spv_position_t nextPosition = {};
spv_result_t error = spvTextWordGet(text, position, firstWord, &nextPosition);
spvCheck(error, DIAGNOSTIC << "Internal Error"; return error);
if (error) {
DIAGNOSTIC << "Internal Error";
return error;
}
std::string opcodeName;
std::string result_id;
@ -634,41 +645,50 @@ spv_result_t spvTextEncodeOpcode(
} else {
// If the first word of this instruction is not an opcode, we must be
// processing AAF now.
spvCheck(
SPV_ASSEMBLY_SYNTAX_FORMAT_ASSIGNMENT != format,
DIAGNOSTIC
<< "Expected <opcode> at the beginning of an instruction, found '"
<< firstWord << "'.";
return SPV_ERROR_INVALID_TEXT);
if (SPV_ASSEMBLY_SYNTAX_FORMAT_ASSIGNMENT != format) {
DIAGNOSTIC
<< "Expected <opcode> at the beginning of an instruction, found '"
<< firstWord << "'.";
return SPV_ERROR_INVALID_TEXT;
}
result_id = firstWord;
spvCheck('%' != result_id.front(),
DIAGNOSTIC << "Expected <opcode> or <result-id> at the beginning "
"of an instruction, found '"
<< result_id << "'.";
return SPV_ERROR_INVALID_TEXT);
if ('%' != result_id.front()) {
DIAGNOSTIC << "Expected <opcode> or <result-id> at the beginning "
"of an instruction, found '"
<< result_id << "'.";
return SPV_ERROR_INVALID_TEXT;
}
result_id_position = *position;
// The '=' sign.
*position = nextPosition;
spvCheck(spvTextAdvance(text, position),
DIAGNOSTIC << "Expected '=', found end of stream.";
return SPV_ERROR_INVALID_TEXT);
if (spvTextAdvance(text, position)) {
DIAGNOSTIC << "Expected '=', found end of stream.";
return SPV_ERROR_INVALID_TEXT;
}
std::string equal_sign;
error = spvTextWordGet(text, position, equal_sign, &nextPosition);
spvCheck("=" != equal_sign, DIAGNOSTIC << "'=' expected after result id.";
return SPV_ERROR_INVALID_TEXT);
if ("=" != equal_sign) {
DIAGNOSTIC << "'=' expected after result id.";
return SPV_ERROR_INVALID_TEXT;
}
// The <opcode> after the '=' sign.
*position = nextPosition;
spvCheck(spvTextAdvance(text, position),
DIAGNOSTIC << "Expected opcode, found end of stream.";
return SPV_ERROR_INVALID_TEXT);
if (spvTextAdvance(text, position)) {
DIAGNOSTIC << "Expected opcode, found end of stream.";
return SPV_ERROR_INVALID_TEXT;
}
error = spvTextWordGet(text, position, opcodeName, &nextPosition);
spvCheck(error, DIAGNOSTIC << "Internal Error"; return error);
spvCheck(!spvStartsWithOp(text, position),
DIAGNOSTIC << "Invalid Opcode prefix '" << opcodeName << "'.";
return SPV_ERROR_INVALID_TEXT);
if (error) {
DIAGNOSTIC << "Internal Error";
return error;
}
if (!spvStartsWithOp(text, position)) {
DIAGNOSTIC << "Invalid Opcode prefix '" << opcodeName << "'.";
return SPV_ERROR_INVALID_TEXT;
}
}
// NOTE: The table contains Opcode names without the "Op" prefix.
@ -676,16 +696,19 @@ spv_result_t spvTextEncodeOpcode(
spv_opcode_desc opcodeEntry;
error = spvOpcodeTableNameLookup(opcodeTable, pInstName, &opcodeEntry);
spvCheck(error, DIAGNOSTIC << "Invalid Opcode name '"
<< spvGetWord(text->str + position->index) << "'";
return error);
if (error) {
DIAGNOSTIC << "Invalid Opcode name '"
<< spvGetWord(text->str + position->index) << "'";
return error;
}
if (SPV_ASSEMBLY_SYNTAX_FORMAT_ASSIGNMENT == format) {
// If this instruction has <result-id>, check it follows AAF.
spvCheck(opcodeEntry->hasResult && result_id.empty(),
DIAGNOSTIC << "Expected <result-id> at the beginning of an "
"instruction, found '"
<< firstWord << "'.";
return SPV_ERROR_INVALID_TEXT);
if (opcodeEntry->hasResult && result_id.empty()) {
DIAGNOSTIC << "Expected <result-id> at the beginning of an "
"instruction, found '"
<< firstWord << "'.";
return SPV_ERROR_INVALID_TEXT;
}
}
pInst->opcode = opcodeEntry->opcode;
*position = nextPosition;
@ -717,7 +740,7 @@ spv_result_t spvTextEncodeOpcode(
result_id.c_str(), operandTable,
extInstTable, namedIdTable, pInst, nullptr,
pBound, &result_id_position, pDiagnostic);
spvCheck(error, return error);
if (error) return error;
} else {
// Find the next word.
error = spvTextAdvance(text, position);
@ -745,7 +768,10 @@ spv_result_t spvTextEncodeOpcode(
std::string operandValue;
error = spvTextWordGet(text, position, operandValue, &nextPosition);
spvCheck(error, DIAGNOSTIC << "Internal Error"; return error);
if (error) {
DIAGNOSTIC << "Internal Error";
return error;
}
error = spvTextEncodeOperand(
type, operandValue.c_str(), operandTable, extInstTable, namedIdTable,
@ -754,7 +780,7 @@ spv_result_t spvTextEncodeOpcode(
if (error == SPV_FAILED_MATCH && spvOperandIsOptional(type))
return SPV_SUCCESS;
spvCheck(error, return error);
if (error) return error;
*position = nextPosition;
}
@ -778,12 +804,14 @@ spv_result_t spvTextToBinaryInternal(const spv_text text,
spv_binary *pBinary,
spv_diagnostic *pDiagnostic) {
spv_position_t position = {};
spvCheck(!text->str || !text->length, DIAGNOSTIC << "Text stream is empty.";
return SPV_ERROR_INVALID_TEXT);
spvCheck(!opcodeTable || !operandTable || !extInstTable,
return SPV_ERROR_INVALID_TABLE);
spvCheck(!pBinary, return SPV_ERROR_INVALID_POINTER);
spvCheck(!pDiagnostic, return SPV_ERROR_INVALID_DIAGNOSTIC);
if (!text->str || !text->length) {
DIAGNOSTIC << "Text stream is empty.";
return SPV_ERROR_INVALID_TEXT;
}
if (!opcodeTable || !operandTable || !extInstTable)
return SPV_ERROR_INVALID_TABLE;
if (!pBinary) return SPV_ERROR_INVALID_POINTER;
if (!pDiagnostic) return SPV_ERROR_INVALID_DIAGNOSTIC;
// NOTE: Ensure diagnostic is zero initialised
*pDiagnostic = {};
@ -792,28 +820,30 @@ spv_result_t spvTextToBinaryInternal(const spv_text text,
std::vector<spv_instruction_t> instructions;
spvCheck(spvTextAdvance(text, &position), DIAGNOSTIC
<< "Text stream is empty.";
return SPV_ERROR_INVALID_TEXT);
if (spvTextAdvance(text, &position)) {
DIAGNOSTIC << "Text stream is empty.";
return SPV_ERROR_INVALID_TEXT;
}
spv_named_id_table namedIdTable = spvNamedIdTableCreate();
spvCheck(!namedIdTable, return SPV_ERROR_OUT_OF_MEMORY);
if (!namedIdTable) return SPV_ERROR_OUT_OF_MEMORY;
spv_ext_inst_type_t extInstType = SPV_EXT_INST_TYPE_NONE;
while (text->length > position.index) {
spv_instruction_t inst = {};
inst.extInstType = extInstType;
spvCheck(spvTextEncodeOpcode(text, format, opcodeTable, operandTable,
extInstTable, namedIdTable, &bound, &inst,
&position, pDiagnostic),
spvNamedIdTableDestory(namedIdTable);
return SPV_ERROR_INVALID_TEXT);
if (spvTextEncodeOpcode(text, format, opcodeTable, operandTable,
extInstTable, namedIdTable, &bound, &inst,
&position, pDiagnostic)) {
spvNamedIdTableDestory(namedIdTable);
return SPV_ERROR_INVALID_TEXT;
}
extInstType = inst.extInstType;
instructions.push_back(inst);
spvCheck(spvTextAdvance(text, &position), break);
if (spvTextAdvance(text, &position)) break;
}
spvNamedIdTableDestory(namedIdTable);
@ -824,7 +854,7 @@ spv_result_t spvTextToBinaryInternal(const spv_text text,
}
uint32_t *data = new uint32_t[totalSize];
spvCheck(!data, return SPV_ERROR_OUT_OF_MEMORY);
if (!data) return SPV_ERROR_OUT_OF_MEMORY;
uint64_t currentIndex = SPV_INDEX_INSTRUCTION;
for (auto &inst : instructions) {
memcpy(data + currentIndex, inst.words, sizeof(uint32_t) * inst.wordCount);
@ -832,12 +862,18 @@ spv_result_t spvTextToBinaryInternal(const spv_text text,
}
spv_binary binary = new spv_binary_t();
spvCheck(!binary, delete[] data; return SPV_ERROR_OUT_OF_MEMORY);
if (!binary) {
delete[] data;
return SPV_ERROR_OUT_OF_MEMORY;
}
binary->code = data;
binary->wordCount = totalSize;
spv_result_t error = spvBinaryHeaderSet(binary, bound);
spvCheck(error, spvBinaryDestroy(binary); return error);
if (error) {
spvBinaryDestroy(binary);
return error;
}
*pBinary = binary;
@ -873,7 +909,7 @@ spv_result_t spvTextWithFormatToBinary(
}
void spvTextDestroy(spv_text text) {
spvCheck(!text, return );
if (!text) return;
if (text->str) {
delete[] text->str;
}

Просмотреть файл

@ -37,16 +37,20 @@
#include <vector>
#define spvCheckReturn(expression) \
if (spv_result_t error = (expression)) return error;
spv_result_t spvValidateOperandsString(const uint32_t *words,
const uint16_t wordCount,
spv_position position,
spv_diagnostic *pDiagnostic) {
const char *str = (const char *)words;
uint64_t strWordCount = strlen(str) / sizeof(uint32_t) + 1;
spvCheck(strWordCount < wordCount, DIAGNOSTIC << "Instruction word count is "
"too short, string extends "
"past end of instruction.";
return SPV_WARNING);
if (strWordCount < wordCount) {
DIAGNOSTIC << "Instruction word count is too short, string extends past "
"end of instruction.";
return SPV_WARNING;
}
return SPV_SUCCESS;
}
@ -107,9 +111,11 @@ spv_result_t spvValidateOperandValue(const spv_operand_type_t type,
spv_operand_desc operandEntry = nullptr;
spv_result_t error =
spvOperandTableValueLookup(operandTable, type, word, &operandEntry);
spvCheck(error, DIAGNOSTIC << "Invalid '" << spvOperandTypeStr(type)
<< "' operand '" << word << "'.";
return error);
if (error) {
DIAGNOSTIC << "Invalid '" << spvOperandTypeStr(type) << "' operand '"
<< word << "'.";
return error;
}
} break;
default:
assert(0 && "Invalid operand types should already have been caught!");
@ -130,16 +136,18 @@ spv_result_t spvValidateBasic(const spv_instruction_t *pInsts,
spvOpcodeSplit(words[0], &wordCount, &opcode);
spv_opcode_desc opcodeEntry = nullptr;
spvCheck(spvOpcodeTableValueLookup(opcodeTable, opcode, &opcodeEntry),
DIAGNOSTIC << "Invalid Opcode '" << opcode << "'.";
return SPV_ERROR_INVALID_BINARY);
if (spvOpcodeTableValueLookup(opcodeTable, opcode, &opcodeEntry)) {
DIAGNOSTIC << "Invalid Opcode '" << opcode << "'.";
return SPV_ERROR_INVALID_BINARY;
}
position->index++;
spvCheck(opcodeEntry->numTypes > wordCount,
DIAGNOSTIC << "Instruction word count '" << wordCount
<< "' is not small, expected at least '"
<< opcodeEntry->numTypes << "'.";
return SPV_ERROR_INVALID_BINARY);
if (opcodeEntry->numTypes > wordCount) {
DIAGNOSTIC << "Instruction word count '" << wordCount
<< "' is not small, expected at least '"
<< opcodeEntry->numTypes << "'.";
return SPV_ERROR_INVALID_BINARY;
}
spv_operand_desc operandEntry = nullptr;
for (uint16_t index = 1; index < pInsts[instIndex].wordCount;
@ -188,9 +196,10 @@ spv_result_t spvValidateIDs(const spv_instruction_t *pInsts,
spvOpcodeSplit(words[0], nullptr, &opcode);
spv_opcode_desc opcodeEntry = nullptr;
spvCheck(spvOpcodeTableValueLookup(opcodeTable, opcode, &opcodeEntry),
DIAGNOSTIC << "Invalid Opcode '" << opcode << "'.";
return SPV_ERROR_INVALID_BINARY);
if (spvOpcodeTableValueLookup(opcodeTable, opcode, &opcodeEntry)) {
DIAGNOSTIC << "Invalid Opcode '" << opcode << "'.";
return SPV_ERROR_INVALID_BINARY;
}
spv_operand_desc operandEntry = nullptr;
position->index++; // NOTE: Account for Opcode word
@ -202,12 +211,15 @@ spv_result_t spvValidateIDs(const spv_instruction_t *pInsts,
word, index, opcodeEntry, operandTable, &operandEntry);
if (SPV_OPERAND_TYPE_RESULT_ID == type || SPV_OPERAND_TYPE_ID == type) {
spvCheck(0 == word, DIAGNOSTIC << "Invalid ID of '0' is not allowed.";
return SPV_ERROR_INVALID_ID);
spvCheck(bound < word, DIAGNOSTIC << "Invalid ID '" << word
<< "' exceeds the bound '" << bound
<< "'.";
return SPV_ERROR_INVALID_ID);
if (0 == word) {
DIAGNOSTIC << "Invalid ID of '0' is not allowed.";
return SPV_ERROR_INVALID_ID;
}
if (bound < word) {
DIAGNOSTIC << "Invalid ID '" << word << "' exceeds the bound '"
<< bound << "'.";
return SPV_ERROR_INVALID_ID;
}
}
if (SPV_OPERAND_TYPE_RESULT_ID == type) {
@ -236,11 +248,11 @@ spv_result_t spvValidateIDs(const spv_instruction_t *pInsts,
// NOTE: Validate ID usage, including use of undefined ID's
position->index = SPV_INDEX_INSTRUCTION;
spvCheck(spvValidateInstructionIDs(pInsts, count, idUses.data(),
idUses.size(), idDefs.data(),
idDefs.size(), opcodeTable, operandTable,
extInstTable, position, pDiagnostic),
return SPV_ERROR_INVALID_ID);
if (spvValidateInstructionIDs(pInsts, count, idUses.data(), idUses.size(),
idDefs.data(), idDefs.size(), opcodeTable,
operandTable, extInstTable, position,
pDiagnostic))
return SPV_ERROR_INVALID_ID;
return SPV_SUCCESS;
}
@ -250,19 +262,21 @@ spv_result_t spvValidate(const spv_binary binary,
const spv_operand_table operandTable,
const spv_ext_inst_table extInstTable,
const uint32_t options, spv_diagnostic *pDiagnostic) {
spvCheck(!opcodeTable || !operandTable, return SPV_ERROR_INVALID_TABLE);
spvCheck(!pDiagnostic, return SPV_ERROR_INVALID_DIAGNOSTIC);
if (!opcodeTable || !operandTable) return SPV_ERROR_INVALID_TABLE;
if (!pDiagnostic) return SPV_ERROR_INVALID_DIAGNOSTIC;
spv_endianness_t endian;
spv_position_t position = {};
spvCheck(spvBinaryEndianness(binary, &endian),
DIAGNOSTIC << "Invalid SPIR-V magic number.";
return SPV_ERROR_INVALID_BINARY);
if (spvBinaryEndianness(binary, &endian)) {
DIAGNOSTIC << "Invalid SPIR-V magic number.";
return SPV_ERROR_INVALID_BINARY;
}
spv_header_t header;
spvCheck(spvBinaryHeaderGet(binary, endian, &header),
DIAGNOSTIC << "Invalid SPIR-V header.";
return SPV_ERROR_INVALID_BINARY);
if (spvBinaryHeaderGet(binary, endian, &header)) {
DIAGNOSTIC << "Invalid SPIR-V header.";
return SPV_ERROR_INVALID_BINARY;
}
// NOTE: Copy each instruction for easier processing
std::vector<spv_instruction_t> instructions;

Просмотреть файл

@ -35,6 +35,11 @@
#include <unordered_map>
#include <vector>
#define spvCheck(condition, action) \
if (condition) { \
action; \
}
namespace {
class idUsage {
public:

Просмотреть файл

@ -94,7 +94,10 @@ int main(int argc, char **argv) {
outFile = "out.spv";
}
spvCheck(!inFile, fprintf(stderr, "error: input file is empty.\n"); return 1);
if (!inFile) {
fprintf(stderr, "error: input file is empty.\n");
return 1;
}
std::vector<char> contents;
if (FILE *fp = fopen(inFile, "r")) {
@ -109,25 +112,32 @@ int main(int argc, char **argv) {
spv_opcode_table opcodeTable;
spv_result_t error = spvOpcodeTableGet(&opcodeTable);
spvCheck(error, fprintf(stderr, "error: internal malfunction\n");
return error);
if (error) {
fprintf(stderr, "error: internal malfunction\n");
return error;
}
spv_operand_table operandTable;
error = spvOperandTableGet(&operandTable);
spvCheck(error, fprintf(stderr, "error: internal malfunction\n");
return error);
if (error) {
fprintf(stderr, "error: internal malfunction\n");
return error;
}
spv_ext_inst_table extInstTable;
error = spvExtInstTableGet(&extInstTable);
spvCheck(error, fprintf(stderr, "error: Internal malfunction.\n"));
if (error) fprintf(stderr, "error: Internal malfunction.\n");
spv_binary binary;
spv_diagnostic diagnostic = nullptr;
error = spvTextWithFormatToBinary(contents.data(), contents.size(), format,
opcodeTable, operandTable, extInstTable,
&binary, &diagnostic);
spvCheck(error, spvDiagnosticPrint(diagnostic);
spvDiagnosticDestroy(diagnostic); return error);
if (error) {
spvDiagnosticPrint(diagnostic);
spvDiagnosticDestroy(diagnostic);
return error;
}
if (FILE *fp = fopen(outFile, "wb")) {
size_t written =

Просмотреть файл

@ -104,7 +104,10 @@ int main(int argc, char **argv) {
outFile = "out.spvasm";
}
spvCheck(!inFile, fprintf(stderr, "error: input file is empty.\n"); return 1);
if (!inFile) {
fprintf(stderr, "error: input file is empty.\n");
return 1;
}
std::vector<uint32_t> contents;
if (FILE *fp = fopen(inFile, "rb")) {
@ -120,17 +123,21 @@ int main(int argc, char **argv) {
spv_opcode_table opcodeTable;
spv_result_t error = spvOpcodeTableGet(&opcodeTable);
spvCheck(error, fprintf(stderr, "error: internal malfunction\n");
return error);
if (error) {
fprintf(stderr, "error: internal malfunction\n");
return error;
}
spv_operand_table operandTable;
error = spvOperandTableGet(&operandTable);
spvCheck(error, fprintf(stderr, "error: internal malfunction\n");
return error);
if (error) {
fprintf(stderr, "error: internal malfunction\n");
return error;
}
spv_ext_inst_table extInstTable;
error = spvExtInstTableGet(&extInstTable);
spvCheck(error, fprintf(stderr, "error: Internal malfunction.\n"));
if (error) fprintf(stderr, "error: Internal malfunction.\n");
// If the printing option is turned on, then spvBinaryToText should
// do the printing. In particular, colour printing on Windows is
@ -147,8 +154,11 @@ int main(int argc, char **argv) {
error = spvBinaryToTextWithFormat(contents.data(), contents.size(), options,
opcodeTable, operandTable, extInstTable,
format, textOrNull, &diagnostic);
spvCheck(error, spvDiagnosticPrint(diagnostic);
spvDiagnosticDestroy(diagnostic); return error);
if (error) {
spvDiagnosticPrint(diagnostic);
spvDiagnosticDestroy(diagnostic);
return error;
}
// Output the result.
if (!printOptionOn) {

Просмотреть файл

@ -78,7 +78,10 @@ int main(int argc, char **argv) {
}
}
spvCheck(!inFile, fprintf(stderr, "error: input file is empty.\n"); return 1);
if (!inFile) {
fprintf(stderr, "error: input file is empty.\n");
return 1;
}
std::vector<uint32_t> contents;
if (FILE *fp = fopen(inFile, "rb")) {
@ -97,23 +100,30 @@ int main(int argc, char **argv) {
spv_opcode_table opcodeTable;
spv_result_t error = spvOpcodeTableGet(&opcodeTable);
spvCheck(error, fprintf(stderr, "error: internal malfunction\n");
return error);
if (error) {
fprintf(stderr, "error: internal malfunction\n");
return error;
}
spv_operand_table operandTable;
error = spvOperandTableGet(&operandTable);
spvCheck(error, fprintf(stderr, "error: internal malfunction\n");
return error);
if (error) {
fprintf(stderr, "error: internal malfunction\n");
return error;
}
spv_ext_inst_table extInstTable;
error = spvExtInstTableGet(&extInstTable);
spvCheck(error, fprintf(stderr, "error: Internal malfunction.\n"));
if (error) fprintf(stderr, "error: Internal malfunction.\n");
spv_diagnostic diagnostic = nullptr;
error = spvValidate(&binary, opcodeTable, operandTable, extInstTable, options,
&diagnostic);
spvCheck(error, spvDiagnosticPrint(diagnostic);
spvDiagnosticDestroy(diagnostic); return error);
if (error) {
spvDiagnosticPrint(diagnostic);
spvDiagnosticDestroy(diagnostic);
return error;
}
return 0;
}