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:
Родитель
7114ffea06
Коммит
4005670363
|
@ -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) {
|
||||
|
|
266
source/text.cpp
266
source/text.cpp
|
@ -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;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче