mirror of
https://github.com/xenia-project/SPIRV-Tools.git
synced 2024-11-27 05:00:26 +00:00
Use opaque context object to hold SPIR-V info tables.
Previously the opcode table is declared as an global array and we have spvOpcodeTableInitialize() modifying it. That can result in race condition. Now spvOpcodeTabelGet() copies the whole underlying array.
This commit is contained in:
parent
321c3e206b
commit
972788bf23
@ -126,6 +126,7 @@ set(SPIRV_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/opcode.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/operand.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/print.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/table.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/text.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/text_handler.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/source/validate.cpp
|
||||
|
@ -321,6 +321,10 @@ typedef struct spv_diagnostic_t {
|
||||
bool isTextSource;
|
||||
} spv_diagnostic_t;
|
||||
|
||||
// Opaque struct containing the context used to operate on a SPIR-V module.
|
||||
// Its object is used by various tranformation API functions.
|
||||
struct spv_context_t;
|
||||
|
||||
// Type Definitions
|
||||
|
||||
typedef spv_const_binary_t* spv_const_binary;
|
||||
@ -328,14 +332,23 @@ typedef spv_binary_t* spv_binary;
|
||||
typedef spv_text_t* spv_text;
|
||||
typedef spv_position_t* spv_position;
|
||||
typedef spv_diagnostic_t* spv_diagnostic;
|
||||
typedef const spv_context_t* spv_const_context;
|
||||
typedef spv_context_t* spv_context;
|
||||
|
||||
// Platform API
|
||||
|
||||
// Creates a context object.
|
||||
spv_context spvContextCreate();
|
||||
|
||||
// Destroys the given context object.
|
||||
void spvContextDestroy(spv_context context);
|
||||
|
||||
// Encodes the given SPIR-V assembly text to its binary representation. The
|
||||
// length parameter specifies the number of bytes for text. Encoded binary will
|
||||
// be stored into *binary. Any error will be written into *diagnostic.
|
||||
spv_result_t spvTextToBinary(const char* text, const size_t length,
|
||||
spv_binary* binary, spv_diagnostic* diagnostic);
|
||||
spv_result_t spvTextToBinary(const spv_const_context context, const char* text,
|
||||
const size_t length, spv_binary* binary,
|
||||
spv_diagnostic* diagnostic);
|
||||
|
||||
// @brief Frees an allocated text stream. This is a no-op if the text parameter
|
||||
// is a null pointer.
|
||||
@ -345,7 +358,8 @@ void spvTextDestroy(spv_text text);
|
||||
// word_count parameter specifies the number of words for binary. The options
|
||||
// parameter is a bit field of spv_binary_to_text_options_t. Decoded text will
|
||||
// be stored into *text. Any error will be written into *diagnostic.
|
||||
spv_result_t spvBinaryToText(const uint32_t* binary, const size_t word_count,
|
||||
spv_result_t spvBinaryToText(const spv_const_context context,
|
||||
const uint32_t* binary, const size_t word_count,
|
||||
const uint32_t options, spv_text* text,
|
||||
spv_diagnostic* diagnostic);
|
||||
|
||||
@ -355,7 +369,8 @@ void spvBinaryDestroy(spv_binary binary);
|
||||
|
||||
// Validates a SPIR-V binary for correctness. The options parameter is a bit
|
||||
// field of spv_validation_options_t.
|
||||
spv_result_t spvValidate(const spv_const_binary binary, const uint32_t options,
|
||||
spv_result_t spvValidate(const spv_const_context context,
|
||||
const spv_const_binary binary, const uint32_t options,
|
||||
spv_diagnostic* pDiagnostic);
|
||||
|
||||
// Creates a diagnostic object. The position parameter specifies the location in
|
||||
@ -396,8 +411,8 @@ typedef spv_result_t (*spv_parsed_instruction_fn_t)(
|
||||
// returns SPV_ERROR_INVALID_BINARY and emits a diagnostic. If a callback
|
||||
// returns anything other than SPV_SUCCESS, then that error code is returned
|
||||
// and parsing terminates early.
|
||||
spv_result_t spvBinaryParse(void* user_data, const uint32_t* words,
|
||||
const size_t num_words,
|
||||
spv_result_t spvBinaryParse(const spv_const_context context, void* user_data,
|
||||
const uint32_t* words, const size_t num_words,
|
||||
spv_parsed_header_fn_t parse_header,
|
||||
spv_parsed_instruction_fn_t parse_instruction,
|
||||
spv_diagnostic* diagnostic);
|
||||
|
@ -86,30 +86,6 @@ spv_result_t spvTextParseMaskOperand(const spv_operand_table operandTable,
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
// Returns the operand table.
|
||||
spv_operand_table GetDefaultOperandTable() {
|
||||
spv_operand_table result = nullptr;
|
||||
spvOperandTableGet(&result);
|
||||
assert(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns the opcode table.
|
||||
spv_opcode_table GetDefaultOpcodeTable() {
|
||||
spv_opcode_table result = nullptr;
|
||||
spvOpcodeTableGet(&result);
|
||||
assert(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns the extended instruction table.
|
||||
spv_ext_inst_table GetDefaultExtInstTable() {
|
||||
spv_ext_inst_table result = nullptr;
|
||||
spvExtInstTableGet(&result);
|
||||
assert(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Associates an opcode with its name.
|
||||
struct SpecConstantOpcodeEntry {
|
||||
SpvOp opcode;
|
||||
@ -197,12 +173,6 @@ const size_t kNumOpSpecConstantOpcodes =
|
||||
|
||||
namespace libspirv {
|
||||
|
||||
AssemblyGrammar::AssemblyGrammar()
|
||||
: AssemblyGrammar(GetDefaultOperandTable(), GetDefaultOpcodeTable(),
|
||||
GetDefaultExtInstTable()) {
|
||||
assert(isValid());
|
||||
}
|
||||
|
||||
bool AssemblyGrammar::isValid() const {
|
||||
return operandTable_ && opcodeTable_ && extInstTable_;
|
||||
}
|
||||
|
@ -37,15 +37,10 @@ namespace libspirv {
|
||||
// Contains methods to query for valid instructions and operands.
|
||||
class AssemblyGrammar {
|
||||
public:
|
||||
AssemblyGrammar(const spv_operand_table operand_table,
|
||||
const spv_opcode_table opcode_table,
|
||||
const spv_ext_inst_table ext_inst_table)
|
||||
: operandTable_(operand_table),
|
||||
opcodeTable_(opcode_table),
|
||||
extInstTable_(ext_inst_table) {}
|
||||
|
||||
// Constructor that gets the required data itself.
|
||||
AssemblyGrammar();
|
||||
AssemblyGrammar(const spv_const_context context)
|
||||
: operandTable_(context->operand_table),
|
||||
opcodeTable_(context->opcode_table),
|
||||
extInstTable_(context->ext_inst_table) {}
|
||||
|
||||
// Returns true if the internal tables have been initialized with valid data.
|
||||
bool isValid() const;
|
||||
|
@ -108,9 +108,11 @@ namespace {
|
||||
class Parser {
|
||||
public:
|
||||
// The user_data value is provided to the callbacks as context.
|
||||
Parser(void* user_data, spv_parsed_header_fn_t parsed_header_fn,
|
||||
Parser(const spv_const_context context, void* user_data,
|
||||
spv_parsed_header_fn_t parsed_header_fn,
|
||||
spv_parsed_instruction_fn_t parsed_instruction_fn)
|
||||
: user_data_(user_data),
|
||||
: grammar_(context),
|
||||
user_data_(user_data),
|
||||
parsed_header_fn_(parsed_header_fn),
|
||||
parsed_instruction_fn_(parsed_instruction_fn) {}
|
||||
|
||||
@ -672,12 +674,12 @@ void Parser::recordNumberType(const spv_parsed_instruction_t* inst) {
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
spv_result_t spvBinaryParse(void* user_data, const uint32_t* code,
|
||||
const size_t num_words,
|
||||
spv_result_t spvBinaryParse(const spv_const_context context, void* user_data,
|
||||
const uint32_t* code, const size_t num_words,
|
||||
spv_parsed_header_fn_t parsed_header,
|
||||
spv_parsed_instruction_fn_t parsed_instruction,
|
||||
spv_diagnostic* diagnostic) {
|
||||
Parser parser(user_data, parsed_header, parsed_instruction);
|
||||
Parser parser(context, user_data, parsed_header, parsed_instruction);
|
||||
return parser.parse(code, num_words, diagnostic);
|
||||
}
|
||||
|
||||
|
@ -370,19 +370,20 @@ spv_result_t DisassembleInstruction(
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
spv_result_t spvBinaryToText(const uint32_t* code, const size_t wordCount,
|
||||
spv_result_t spvBinaryToText(const spv_const_context context,
|
||||
const uint32_t* code, const size_t wordCount,
|
||||
const uint32_t options, spv_text* pText,
|
||||
spv_diagnostic* pDiagnostic) {
|
||||
// Invalid arguments return error codes, but don't necessarily generate
|
||||
// diagnostics. These are programmer errors, not user errors.
|
||||
if (!pDiagnostic) return SPV_ERROR_INVALID_DIAGNOSTIC;
|
||||
const libspirv::AssemblyGrammar grammar;
|
||||
const libspirv::AssemblyGrammar grammar(context);
|
||||
if (!grammar.isValid()) return SPV_ERROR_INVALID_TABLE;
|
||||
|
||||
Disassembler disassembler(grammar, code, wordCount, options);
|
||||
if (auto error =
|
||||
spvBinaryParse(&disassembler, code, wordCount, DisassembleHeader,
|
||||
DisassembleInstruction, pDiagnostic)) {
|
||||
if (auto error = spvBinaryParse(context, &disassembler, code, wordCount,
|
||||
DisassembleHeader, DisassembleInstruction,
|
||||
pDiagnostic)) {
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,8 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include "endian.h"
|
||||
#include "instruction.h"
|
||||
#include "libspirv/libspirv.h"
|
||||
@ -46,7 +48,7 @@ namespace {
|
||||
//
|
||||
// TODO(dneto): Some of the macros are quite unreadable. We could make
|
||||
// good use of constexpr functions, but some compilers don't support that yet.
|
||||
spv_opcode_desc_t opcodeTableEntries[] = {
|
||||
const spv_opcode_desc_t opcodeTableEntries[] = {
|
||||
#define EmptyList \
|
||||
{}
|
||||
#define List(...) \
|
||||
@ -71,10 +73,6 @@ spv_opcode_desc_t opcodeTableEntries[] = {
|
||||
#undef Instruction
|
||||
};
|
||||
|
||||
// Has the opcodeTableEntries table been fully elaborated?
|
||||
// That is, are the operandTypes fields initialized?
|
||||
bool opcodeTableInitialized = false;
|
||||
|
||||
// Opcode API
|
||||
|
||||
// Converts the given operand class enum (from the SPIR-V document generation
|
||||
@ -244,9 +242,11 @@ spv_operand_type_t convertOperandClassToType(SpvOp opcode,
|
||||
} // anonymous namespace
|
||||
|
||||
// Finish populating the opcodeTableEntries array.
|
||||
void spvOpcodeTableInitialize() {
|
||||
void spvOpcodeTableInitialize(spv_opcode_desc_t* entries,
|
||||
uint32_t num_entries) {
|
||||
// Compute the operandTypes field for each entry.
|
||||
for (auto& opcode : opcodeTableEntries) {
|
||||
for (uint32_t i = 0; i < num_entries; ++i) {
|
||||
spv_opcode_desc_t& opcode = entries[i];
|
||||
opcode.numTypes = 0;
|
||||
// Type ID always comes first, if present.
|
||||
if (opcode.hasType)
|
||||
@ -282,7 +282,6 @@ void spvOpcodeTableInitialize() {
|
||||
"Operand class list is too long. Expand "
|
||||
"spv_opcode_desc_t.operandClass");
|
||||
}
|
||||
opcodeTableInitialized = true;
|
||||
}
|
||||
|
||||
const char* spvGeneratorStr(uint32_t generator) {
|
||||
@ -320,15 +319,18 @@ void spvOpcodeSplit(const uint32_t word, uint16_t* pWordCount, SpvOp* pOpcode) {
|
||||
spv_result_t spvOpcodeTableGet(spv_opcode_table* pInstTable) {
|
||||
if (!pInstTable) return SPV_ERROR_INVALID_POINTER;
|
||||
|
||||
static spv_opcode_table_t table = {
|
||||
sizeof(opcodeTableEntries) / sizeof(spv_opcode_desc_t),
|
||||
opcodeTableEntries};
|
||||
const uint32_t size = sizeof(opcodeTableEntries);
|
||||
spv_opcode_desc_t* copied_entries =
|
||||
static_cast<spv_opcode_desc_t*>(::malloc(size));
|
||||
if (!copied_entries) return SPV_ERROR_OUT_OF_MEMORY;
|
||||
::memcpy(copied_entries, opcodeTableEntries, size);
|
||||
|
||||
// TODO(dneto): Consider thread safety of initialization.
|
||||
// That is, ordering effects of the flag vs. the table updates.
|
||||
if (!opcodeTableInitialized) spvOpcodeTableInitialize();
|
||||
const uint32_t count = sizeof(opcodeTableEntries) / sizeof(spv_opcode_desc_t);
|
||||
spv_opcode_table_t* table = new spv_opcode_table_t{count, copied_entries};
|
||||
|
||||
*pInstTable = &table;
|
||||
spvOpcodeTableInitialize(copied_entries, count);
|
||||
|
||||
*pInstTable = table;
|
||||
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
47
source/table.cpp
Normal file
47
source/table.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright (c) 2015 The Khronos Group Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and/or associated documentation files (the
|
||||
// "Materials"), to deal in the Materials without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
// permit persons to whom the Materials are furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Materials.
|
||||
//
|
||||
// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
|
||||
// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
|
||||
// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
|
||||
// https://www.khronos.org/registry/
|
||||
//
|
||||
// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
|
||||
#include "table.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
spv_context spvContextCreate() {
|
||||
spv_opcode_table opcode_table;
|
||||
spv_operand_table operand_table;
|
||||
spv_ext_inst_table ext_inst_table;
|
||||
|
||||
spvOpcodeTableGet(&opcode_table);
|
||||
spvOperandTableGet(&operand_table);
|
||||
spvExtInstTableGet(&ext_inst_table);
|
||||
|
||||
return new spv_context_t{opcode_table, operand_table, ext_inst_table};
|
||||
}
|
||||
|
||||
void spvContextDestroy(spv_context context) {
|
||||
::free(context->opcode_table->entries);
|
||||
delete context->opcode_table;
|
||||
delete context;
|
||||
}
|
@ -76,7 +76,7 @@ typedef struct spv_ext_inst_group_t {
|
||||
|
||||
typedef struct spv_opcode_table_t {
|
||||
const uint32_t count;
|
||||
const spv_opcode_desc_t* entries;
|
||||
spv_opcode_desc_t* entries;
|
||||
} spv_opcode_table_t;
|
||||
|
||||
typedef struct spv_operand_table_t {
|
||||
@ -97,6 +97,12 @@ typedef const spv_opcode_table_t* spv_opcode_table;
|
||||
typedef const spv_operand_table_t* spv_operand_table;
|
||||
typedef const spv_ext_inst_table_t* spv_ext_inst_table;
|
||||
|
||||
struct spv_context_t {
|
||||
const spv_opcode_table opcode_table;
|
||||
const spv_operand_table operand_table;
|
||||
const spv_ext_inst_table ext_inst_table;
|
||||
};
|
||||
|
||||
/// @brief Populate the Opcode table
|
||||
///
|
||||
/// @param[out] pOpcodeTable table to be populated
|
||||
|
@ -735,11 +735,12 @@ spv_result_t spvTextToBinaryInternal(const libspirv::AssemblyGrammar& grammar,
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
spv_result_t spvTextToBinary(const char* input_text,
|
||||
spv_result_t spvTextToBinary(const spv_const_context context,
|
||||
const char* input_text,
|
||||
const size_t input_text_size, spv_binary* pBinary,
|
||||
spv_diagnostic* pDiagnostic) {
|
||||
spv_text_t text = {input_text, input_text_size};
|
||||
libspirv::AssemblyGrammar grammar;
|
||||
libspirv::AssemblyGrammar grammar(context);
|
||||
|
||||
spv_result_t result =
|
||||
spvTextToBinaryInternal(grammar, &text, pBinary, pDiagnostic);
|
||||
|
@ -261,20 +261,10 @@ spv_result_t spvValidateIDs(const spv_instruction_t* pInsts,
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
spv_result_t spvValidate(const spv_const_binary binary, const uint32_t options,
|
||||
spv_result_t spvValidate(const spv_const_context context,
|
||||
const spv_const_binary binary, const uint32_t options,
|
||||
spv_diagnostic* pDiagnostic) {
|
||||
if (!pDiagnostic) return SPV_ERROR_INVALID_DIAGNOSTIC;
|
||||
spv_opcode_table opcode_table = nullptr;
|
||||
spvOpcodeTableGet(&opcode_table);
|
||||
assert(opcode_table);
|
||||
|
||||
spv_operand_table operand_table = nullptr;
|
||||
spvOperandTableGet(&operand_table);
|
||||
assert(operand_table);
|
||||
|
||||
spv_ext_inst_table ext_inst_table = nullptr;
|
||||
spvExtInstTableGet(&ext_inst_table);
|
||||
assert(ext_inst_table);
|
||||
|
||||
spv_endianness_t endian;
|
||||
spv_position_t position = {};
|
||||
@ -306,9 +296,9 @@ spv_result_t spvValidate(const spv_const_binary binary, const uint32_t options,
|
||||
if (spvIsInBitfield(SPV_VALIDATE_BASIC_BIT, options)) {
|
||||
position.index = SPV_INDEX_INSTRUCTION;
|
||||
// TODO: Imcomplete implementation
|
||||
spvCheckReturn(spvValidateBasic(instructions.data(), instructions.size(),
|
||||
opcode_table, operand_table, &position,
|
||||
pDiagnostic));
|
||||
spvCheckReturn(spvValidateBasic(
|
||||
instructions.data(), instructions.size(), context->opcode_table,
|
||||
context->operand_table, &position, pDiagnostic));
|
||||
}
|
||||
|
||||
if (spvIsInBitfield(SPV_VALIDATE_LAYOUT_BIT, options)) {
|
||||
@ -318,9 +308,10 @@ spv_result_t spvValidate(const spv_const_binary binary, const uint32_t options,
|
||||
|
||||
if (spvIsInBitfield(SPV_VALIDATE_ID_BIT, options)) {
|
||||
position.index = SPV_INDEX_INSTRUCTION;
|
||||
spvCheckReturn(spvValidateIDs(instructions.data(), instructions.size(),
|
||||
header.bound, opcode_table, operand_table,
|
||||
ext_inst_table, &position, pDiagnostic));
|
||||
spvCheckReturn(
|
||||
spvValidateIDs(instructions.data(), instructions.size(), header.bound,
|
||||
context->opcode_table, context->operand_table,
|
||||
context->ext_inst_table, &position, pDiagnostic));
|
||||
}
|
||||
|
||||
if (spvIsInBitfield(SPV_VALIDATE_RULES_BIT, options)) {
|
||||
|
@ -32,8 +32,9 @@ using spvtest::TextToBinaryTest;
|
||||
|
||||
TEST_F(TextToBinaryTest, NotPlacingResultIDAtTheBeginning) {
|
||||
SetText("OpTypeMatrix %1 %2 1000");
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_TEXT,
|
||||
spvTextToBinary(text.str, text.length, &binary, &diagnostic));
|
||||
EXPECT_EQ(
|
||||
SPV_ERROR_INVALID_TEXT,
|
||||
spvTextToBinary(context, text.str, text.length, &binary, &diagnostic));
|
||||
ASSERT_NE(nullptr, diagnostic);
|
||||
EXPECT_STREQ(
|
||||
"Expected <result-id> at the beginning of an instruction, found "
|
||||
|
@ -40,13 +40,15 @@ using BinaryDestroySomething = spvtest::TextToBinaryTest;
|
||||
|
||||
// Checks safety of destroying a validly constructed binary.
|
||||
TEST_F(BinaryDestroySomething, Default) {
|
||||
spv_context context = spvContextCreate();
|
||||
// Use a binary object constructed by the API instead of rolling our own.
|
||||
SetText("OpSource OpenCL_C 120");
|
||||
spv_binary my_binary = nullptr;
|
||||
ASSERT_EQ(SPV_SUCCESS,
|
||||
spvTextToBinary(text.str, text.length, &my_binary, &diagnostic));
|
||||
ASSERT_EQ(SPV_SUCCESS, spvTextToBinary(context, text.str, text.length,
|
||||
&my_binary, &diagnostic));
|
||||
ASSERT_NE(nullptr, my_binary);
|
||||
spvBinaryDestroy(my_binary);
|
||||
spvContextDestroy(context);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
@ -40,6 +40,9 @@ using spvtest::TextToBinaryTest;
|
||||
namespace {
|
||||
class BinaryToText : public ::testing::Test {
|
||||
public:
|
||||
BinaryToText() : context(spvContextCreate()) {}
|
||||
~BinaryToText() { spvContextDestroy(context); }
|
||||
|
||||
virtual void SetUp() {
|
||||
const char* textStr = R"(
|
||||
OpSource OpenCL_C 12
|
||||
@ -65,7 +68,7 @@ class BinaryToText : public ::testing::Test {
|
||||
spv_text_t text = {textStr, strlen(textStr)};
|
||||
spv_diagnostic diagnostic = nullptr;
|
||||
spv_result_t error =
|
||||
spvTextToBinary(text.str, text.length, &binary, &diagnostic);
|
||||
spvTextToBinary(context, text.str, text.length, &binary, &diagnostic);
|
||||
if (error) {
|
||||
spvDiagnosticPrint(diagnostic);
|
||||
spvDiagnosticDestroy(diagnostic);
|
||||
@ -78,19 +81,21 @@ class BinaryToText : public ::testing::Test {
|
||||
// Compiles the given assembly text, and saves it into 'binary'.
|
||||
void CompileSuccessfully(std::string text) {
|
||||
spv_diagnostic diagnostic = nullptr;
|
||||
EXPECT_EQ(SPV_SUCCESS,
|
||||
spvTextToBinary(text.c_str(), text.size(), &binary, &diagnostic));
|
||||
EXPECT_EQ(SPV_SUCCESS, spvTextToBinary(context, text.c_str(), text.size(),
|
||||
&binary, &diagnostic));
|
||||
}
|
||||
|
||||
spv_context context;
|
||||
spv_binary binary;
|
||||
};
|
||||
|
||||
TEST_F(BinaryToText, Default) {
|
||||
spv_text text = nullptr;
|
||||
spv_diagnostic diagnostic = nullptr;
|
||||
ASSERT_EQ(SPV_SUCCESS, spvBinaryToText(binary->code, binary->wordCount,
|
||||
SPV_BINARY_TO_TEXT_OPTION_NONE, &text,
|
||||
&diagnostic));
|
||||
ASSERT_EQ(
|
||||
SPV_SUCCESS,
|
||||
spvBinaryToText(context, binary->code, binary->wordCount,
|
||||
SPV_BINARY_TO_TEXT_OPTION_NONE, &text, &diagnostic));
|
||||
printf("%s", text->str);
|
||||
spvTextDestroy(text);
|
||||
}
|
||||
@ -98,9 +103,10 @@ TEST_F(BinaryToText, Default) {
|
||||
TEST_F(BinaryToText, MissingModule) {
|
||||
spv_text text;
|
||||
spv_diagnostic diagnostic = nullptr;
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_BINARY,
|
||||
spvBinaryToText(nullptr, 42, SPV_BINARY_TO_TEXT_OPTION_NONE, &text,
|
||||
&diagnostic));
|
||||
EXPECT_EQ(
|
||||
SPV_ERROR_INVALID_BINARY,
|
||||
spvBinaryToText(context, nullptr, 42, SPV_BINARY_TO_TEXT_OPTION_NONE,
|
||||
&text, &diagnostic));
|
||||
EXPECT_THAT(diagnostic->error, Eq(std::string("Missing module.")));
|
||||
if (diagnostic) {
|
||||
spvDiagnosticPrint(diagnostic);
|
||||
@ -118,8 +124,8 @@ TEST_F(BinaryToText, TruncatedModule) {
|
||||
spv_diagnostic diagnostic = nullptr;
|
||||
EXPECT_EQ(
|
||||
SPV_ERROR_INVALID_BINARY,
|
||||
spvBinaryToText(binary->code, length, SPV_BINARY_TO_TEXT_OPTION_NONE,
|
||||
&text, &diagnostic));
|
||||
spvBinaryToText(context, binary->code, length,
|
||||
SPV_BINARY_TO_TEXT_OPTION_NONE, &text, &diagnostic));
|
||||
ASSERT_NE(nullptr, diagnostic);
|
||||
std::stringstream expected;
|
||||
expected << "Module has incomplete header: only " << length
|
||||
@ -139,7 +145,7 @@ TEST_F(BinaryToText, InvalidMagicNumber) {
|
||||
spv_text text;
|
||||
EXPECT_EQ(
|
||||
SPV_ERROR_INVALID_BINARY,
|
||||
spvBinaryToText(damaged_binary.data(), damaged_binary.size(),
|
||||
spvBinaryToText(context, damaged_binary.data(), damaged_binary.size(),
|
||||
SPV_BINARY_TO_TEXT_OPTION_NONE, &text, &diagnostic));
|
||||
ASSERT_NE(nullptr, diagnostic);
|
||||
std::stringstream expected;
|
||||
@ -152,7 +158,7 @@ TEST_F(BinaryToText, InvalidMagicNumber) {
|
||||
TEST_F(BinaryToText, InvalidDiagnostic) {
|
||||
spv_text text;
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DIAGNOSTIC,
|
||||
spvBinaryToText(binary->code, binary->wordCount,
|
||||
spvBinaryToText(context, binary->code, binary->wordCount,
|
||||
SPV_BINARY_TO_TEXT_OPTION_NONE, &text, nullptr));
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,7 @@ struct ExtInstContext {
|
||||
using ExtInstGLSLstd450RoundTripTest = ::testing::TestWithParam<ExtInstContext>;
|
||||
|
||||
TEST_P(ExtInstGLSLstd450RoundTripTest, ParameterizedExtInst) {
|
||||
spv_context context = spvContextCreate();
|
||||
const std::string spirv = R"(
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
@ -71,8 +72,8 @@ OpFunctionEnd
|
||||
; Schema: 0)";
|
||||
spv_binary binary;
|
||||
spv_diagnostic diagnostic;
|
||||
spv_result_t error =
|
||||
spvTextToBinary(spirv.c_str(), spirv.size(), &binary, &diagnostic);
|
||||
spv_result_t error = spvTextToBinary(context, spirv.c_str(), spirv.size(),
|
||||
&binary, &diagnostic);
|
||||
if (error) {
|
||||
spvDiagnosticPrint(diagnostic);
|
||||
spvDiagnosticDestroy(diagnostic);
|
||||
@ -98,7 +99,7 @@ OpFunctionEnd
|
||||
|
||||
// Check round trip gives the same text.
|
||||
spv_text output_text = nullptr;
|
||||
error = spvBinaryToText(binary->code, binary->wordCount,
|
||||
error = spvBinaryToText(context, binary->code, binary->wordCount,
|
||||
SPV_BINARY_TO_TEXT_OPTION_NONE, &output_text,
|
||||
&diagnostic);
|
||||
|
||||
@ -109,6 +110,7 @@ OpFunctionEnd
|
||||
}
|
||||
EXPECT_EQ(spirv_header + spirv, output_text->str);
|
||||
spvTextDestroy(output_text);
|
||||
spvContextDestroy(context);
|
||||
}
|
||||
|
||||
static const char* kF32Type = R"(%4 = OpTypeFloat 32)";
|
||||
|
@ -46,8 +46,8 @@ using ::testing::StrEq;
|
||||
|
||||
TEST_F(TextToBinaryTest, ImmediateIntOpCode) {
|
||||
SetText("!0x00FF00FF");
|
||||
ASSERT_EQ(SPV_SUCCESS,
|
||||
spvTextToBinary(text.str, text.length, &binary, &diagnostic));
|
||||
ASSERT_EQ(SPV_SUCCESS, spvTextToBinary(context, text.str, text.length,
|
||||
&binary, &diagnostic));
|
||||
EXPECT_EQ(0x00FF00FF, binary->code[5]);
|
||||
if (diagnostic) {
|
||||
spvDiagnosticPrint(diagnostic);
|
||||
@ -56,8 +56,8 @@ TEST_F(TextToBinaryTest, ImmediateIntOpCode) {
|
||||
|
||||
TEST_F(TextToBinaryTest, ImmediateIntOperand) {
|
||||
SetText("OpCapability !0x00FF00FF");
|
||||
EXPECT_EQ(SPV_SUCCESS,
|
||||
spvTextToBinary(text.str, text.length, &binary, &diagnostic));
|
||||
EXPECT_EQ(SPV_SUCCESS, spvTextToBinary(context, text.str, text.length,
|
||||
&binary, &diagnostic));
|
||||
EXPECT_EQ(0x00FF00FF, binary->code[6]);
|
||||
if (diagnostic) {
|
||||
spvDiagnosticPrint(diagnostic);
|
||||
|
@ -32,6 +32,7 @@
|
||||
namespace {
|
||||
|
||||
TEST(NamedId, Default) {
|
||||
spv_context context = spvContextCreate();
|
||||
const char* spirv = R"(
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical Simple
|
||||
@ -48,7 +49,7 @@ TEST(NamedId, Default) {
|
||||
spv_binary binary = nullptr;
|
||||
spv_diagnostic diagnostic;
|
||||
spv_result_t error =
|
||||
spvTextToBinary(text.str, text.length, &binary, &diagnostic);
|
||||
spvTextToBinary(context, text.str, text.length, &binary, &diagnostic);
|
||||
if (error) {
|
||||
spvDiagnosticPrint(diagnostic);
|
||||
spvDiagnosticDestroy(diagnostic);
|
||||
@ -56,7 +57,7 @@ TEST(NamedId, Default) {
|
||||
ASSERT_EQ(SPV_SUCCESS, error);
|
||||
}
|
||||
error = spvBinaryToText(
|
||||
binary->code, binary->wordCount,
|
||||
context, binary->code, binary->wordCount,
|
||||
SPV_BINARY_TO_TEXT_OPTION_PRINT | SPV_BINARY_TO_TEXT_OPTION_COLOR,
|
||||
nullptr, &diagnostic);
|
||||
if (error) {
|
||||
@ -66,6 +67,7 @@ TEST(NamedId, Default) {
|
||||
ASSERT_EQ(SPV_SUCCESS, error);
|
||||
}
|
||||
spvBinaryDestroy(binary);
|
||||
spvContextDestroy(context);
|
||||
}
|
||||
|
||||
struct IdCheckCase {
|
||||
|
@ -42,7 +42,11 @@ class TextToBinaryTestBase : public T {
|
||||
// Offset into a SpirvVector at which the first instruction starts.
|
||||
const SpirvVector::size_type kFirstInstruction = 5;
|
||||
|
||||
TextToBinaryTestBase() : diagnostic(nullptr), text(), binary(nullptr) {
|
||||
TextToBinaryTestBase()
|
||||
: context(spvContextCreate()),
|
||||
diagnostic(nullptr),
|
||||
text(),
|
||||
binary(nullptr) {
|
||||
char textStr[] = "substitute the text member variable with your test";
|
||||
text = {textStr, strlen(textStr)};
|
||||
}
|
||||
@ -50,6 +54,7 @@ class TextToBinaryTestBase : public T {
|
||||
virtual ~TextToBinaryTestBase() {
|
||||
DestroyBinary();
|
||||
if (diagnostic) spvDiagnosticDestroy(diagnostic);
|
||||
spvContextDestroy(context);
|
||||
}
|
||||
|
||||
// Returns subvector v[from:end).
|
||||
@ -61,8 +66,8 @@ class TextToBinaryTestBase : public T {
|
||||
// Compiles SPIR-V text in the given assembly syntax format, asserting
|
||||
// compilation success. Returns the compiled code.
|
||||
SpirvVector CompileSuccessfully(const std::string& text) {
|
||||
spv_result_t status =
|
||||
spvTextToBinary(text.c_str(), text.size(), &binary, &diagnostic);
|
||||
spv_result_t status = spvTextToBinary(context, text.c_str(), text.size(),
|
||||
&binary, &diagnostic);
|
||||
EXPECT_EQ(SPV_SUCCESS, status) << text;
|
||||
SpirvVector code_copy;
|
||||
if (status == SPV_SUCCESS) {
|
||||
@ -77,8 +82,8 @@ class TextToBinaryTestBase : public T {
|
||||
// Compiles SPIR-V text with the given format, asserting compilation failure.
|
||||
// Returns the error message(s).
|
||||
std::string CompileFailure(const std::string& text) {
|
||||
EXPECT_NE(SPV_SUCCESS,
|
||||
spvTextToBinary(text.c_str(), text.size(), &binary, &diagnostic))
|
||||
EXPECT_NE(SPV_SUCCESS, spvTextToBinary(context, text.c_str(), text.size(),
|
||||
&binary, &diagnostic))
|
||||
<< text;
|
||||
DestroyBinary();
|
||||
return diagnostic->error;
|
||||
@ -95,8 +100,8 @@ class TextToBinaryTestBase : public T {
|
||||
std::string EncodeAndDecodeSuccessfully(const std::string& text,
|
||||
uint32_t disassemble_options) {
|
||||
DestroyBinary();
|
||||
spv_result_t error =
|
||||
spvTextToBinary(text.c_str(), text.size(), &binary, &diagnostic);
|
||||
spv_result_t error = spvTextToBinary(context, text.c_str(), text.size(),
|
||||
&binary, &diagnostic);
|
||||
if (error) {
|
||||
spvDiagnosticPrint(diagnostic);
|
||||
spvDiagnosticDestroy(diagnostic);
|
||||
@ -105,7 +110,7 @@ class TextToBinaryTestBase : public T {
|
||||
if (!binary) return "";
|
||||
|
||||
spv_text decoded_text;
|
||||
error = spvBinaryToText(binary->code, binary->wordCount,
|
||||
error = spvBinaryToText(context, binary->code, binary->wordCount,
|
||||
disassemble_options, &decoded_text, &diagnostic);
|
||||
if (error) {
|
||||
spvDiagnosticPrint(diagnostic);
|
||||
@ -132,7 +137,7 @@ class TextToBinaryTestBase : public T {
|
||||
spvtest::Concatenate({CompileSuccessfully(text), words_to_append});
|
||||
|
||||
spv_text decoded_text;
|
||||
EXPECT_NE(SPV_SUCCESS, spvBinaryToText(code.data(), code.size(),
|
||||
EXPECT_NE(SPV_SUCCESS, spvBinaryToText(context, code.data(), code.size(),
|
||||
SPV_BINARY_TO_TEXT_OPTION_NONE,
|
||||
&decoded_text, &diagnostic));
|
||||
if (diagnostic) {
|
||||
@ -169,6 +174,7 @@ class TextToBinaryTestBase : public T {
|
||||
binary = nullptr;
|
||||
}
|
||||
|
||||
spv_context context;
|
||||
spv_diagnostic diagnostic;
|
||||
|
||||
std::string textString;
|
||||
|
@ -31,6 +31,7 @@ namespace {
|
||||
TEST(TextDestroy, DestroyNull) { spvBinaryDestroy(nullptr); }
|
||||
|
||||
TEST(TextDestroy, Default) {
|
||||
spv_context context = spvContextCreate();
|
||||
char textStr[] = R"(
|
||||
OpSource OpenCL_C 12
|
||||
OpMemoryModel Physical64 OpenCL
|
||||
@ -55,8 +56,8 @@ TEST(TextDestroy, Default) {
|
||||
|
||||
spv_binary binary = nullptr;
|
||||
spv_diagnostic diagnostic = nullptr;
|
||||
EXPECT_EQ(SPV_SUCCESS,
|
||||
spvTextToBinary(textStr, strlen(textStr), &binary, &diagnostic));
|
||||
EXPECT_EQ(SPV_SUCCESS, spvTextToBinary(context, textStr, strlen(textStr),
|
||||
&binary, &diagnostic));
|
||||
EXPECT_NE(nullptr, binary);
|
||||
EXPECT_NE(nullptr, binary->code);
|
||||
EXPECT_NE(0, binary->wordCount);
|
||||
@ -66,8 +67,9 @@ TEST(TextDestroy, Default) {
|
||||
}
|
||||
|
||||
spv_text resultText = nullptr;
|
||||
EXPECT_EQ(SPV_SUCCESS, spvBinaryToText(binary->code, binary->wordCount, 0,
|
||||
&resultText, &diagnostic));
|
||||
EXPECT_EQ(SPV_SUCCESS,
|
||||
spvBinaryToText(context, binary->code, binary->wordCount, 0,
|
||||
&resultText, &diagnostic));
|
||||
spvBinaryDestroy(binary);
|
||||
if (diagnostic) {
|
||||
spvDiagnosticPrint(diagnostic);
|
||||
@ -77,6 +79,7 @@ TEST(TextDestroy, Default) {
|
||||
EXPECT_NE(nullptr, resultText->str);
|
||||
EXPECT_NE(0, resultText->length);
|
||||
spvTextDestroy(resultText);
|
||||
spvContextDestroy(context);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
@ -71,14 +71,15 @@ struct MaskCase {
|
||||
using GoodMaskParseTest = ::testing::TestWithParam<MaskCase>;
|
||||
|
||||
TEST_P(GoodMaskParseTest, GoodMaskExpressions) {
|
||||
spv_operand_table operandTable;
|
||||
ASSERT_EQ(SPV_SUCCESS, spvOperandTableGet(&operandTable));
|
||||
spv_context context = spvContextCreate();
|
||||
|
||||
uint32_t value;
|
||||
EXPECT_EQ(SPV_SUCCESS, AssemblyGrammar(operandTable, nullptr, nullptr)
|
||||
.parseMaskOperand(GetParam().which_enum,
|
||||
GetParam().expression, &value));
|
||||
EXPECT_EQ(SPV_SUCCESS,
|
||||
AssemblyGrammar(context).parseMaskOperand(
|
||||
GetParam().which_enum, GetParam().expression, &value));
|
||||
EXPECT_EQ(GetParam().expected_value, value);
|
||||
|
||||
spvContextDestroy(context);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
@ -115,14 +116,14 @@ INSTANTIATE_TEST_CASE_P(
|
||||
using BadFPFastMathMaskParseTest = ::testing::TestWithParam<const char*>;
|
||||
|
||||
TEST_P(BadFPFastMathMaskParseTest, BadMaskExpressions) {
|
||||
spv_operand_table operandTable;
|
||||
ASSERT_EQ(SPV_SUCCESS, spvOperandTableGet(&operandTable));
|
||||
spv_context context = spvContextCreate();
|
||||
|
||||
uint32_t value;
|
||||
EXPECT_NE(SPV_SUCCESS,
|
||||
AssemblyGrammar(operandTable, nullptr, nullptr)
|
||||
.parseMaskOperand(SPV_OPERAND_TYPE_FP_FAST_MATH_MODE,
|
||||
GetParam(), &value));
|
||||
AssemblyGrammar(context).parseMaskOperand(
|
||||
SPV_OPERAND_TYPE_FP_FAST_MATH_MODE, GetParam(), &value));
|
||||
|
||||
spvContextDestroy(context);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(ParseMask, BadFPFastMathMaskParseTest,
|
||||
@ -141,7 +142,7 @@ union char_word_t {
|
||||
TEST_F(TextToBinaryTest, InvalidText) {
|
||||
spv_binary binary;
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_TEXT,
|
||||
spvTextToBinary(nullptr, 0, &binary, &diagnostic));
|
||||
spvTextToBinary(context, nullptr, 0, &binary, &diagnostic));
|
||||
EXPECT_NE(nullptr, diagnostic);
|
||||
EXPECT_THAT(diagnostic->error, Eq(std::string("Missing assembly text.")));
|
||||
}
|
||||
@ -149,8 +150,9 @@ TEST_F(TextToBinaryTest, InvalidText) {
|
||||
TEST_F(TextToBinaryTest, InvalidPointer) {
|
||||
SetText(
|
||||
"OpEntryPoint Kernel 0 \"\"\nOpExecutionMode 0 LocalSizeHint 1 1 1\n");
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_POINTER,
|
||||
spvTextToBinary(text.str, text.length, nullptr, &diagnostic));
|
||||
ASSERT_EQ(
|
||||
SPV_ERROR_INVALID_POINTER,
|
||||
spvTextToBinary(context, text.str, text.length, nullptr, &diagnostic));
|
||||
}
|
||||
|
||||
TEST_F(TextToBinaryTest, InvalidDiagnostic) {
|
||||
@ -158,7 +160,7 @@ TEST_F(TextToBinaryTest, InvalidDiagnostic) {
|
||||
"OpEntryPoint Kernel 0 \"\"\nOpExecutionMode 0 LocalSizeHint 1 1 1\n");
|
||||
spv_binary binary;
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DIAGNOSTIC,
|
||||
spvTextToBinary(text.str, text.length, &binary, nullptr));
|
||||
spvTextToBinary(context, text.str, text.length, &binary, nullptr));
|
||||
}
|
||||
|
||||
TEST_F(TextToBinaryTest, InvalidPrefix) {
|
||||
|
@ -30,11 +30,13 @@ namespace {
|
||||
|
||||
class Validate : public ::testing::Test {
|
||||
public:
|
||||
Validate() : binary() {}
|
||||
Validate() : context(spvContextCreate()), binary() {}
|
||||
~Validate() { spvContextDestroy(context); }
|
||||
|
||||
virtual void TearDown() { spvBinaryDestroy(binary); }
|
||||
spv_const_binary get_const_binary() { return spv_const_binary(binary); }
|
||||
|
||||
spv_context context;
|
||||
spv_binary binary;
|
||||
};
|
||||
|
||||
@ -52,9 +54,9 @@ OpFunctionEnd
|
||||
)";
|
||||
spv_diagnostic diagnostic = nullptr;
|
||||
ASSERT_EQ(SPV_SUCCESS,
|
||||
spvTextToBinary(str, strlen(str), &binary, &diagnostic));
|
||||
ASSERT_EQ(SPV_SUCCESS,
|
||||
spvValidate(get_const_binary(), SPV_VALIDATE_ALL, &diagnostic));
|
||||
spvTextToBinary(context, str, strlen(str), &binary, &diagnostic));
|
||||
ASSERT_EQ(SPV_SUCCESS, spvValidate(context, get_const_binary(),
|
||||
SPV_VALIDATE_ALL, &diagnostic));
|
||||
if (diagnostic) {
|
||||
spvDiagnosticPrint(diagnostic);
|
||||
spvDiagnosticDestroy(diagnostic);
|
||||
@ -75,9 +77,9 @@ OpFunctionEnd
|
||||
)";
|
||||
spv_diagnostic diagnostic = nullptr;
|
||||
ASSERT_EQ(SPV_SUCCESS,
|
||||
spvTextToBinary(str, strlen(str), &binary, &diagnostic));
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_ID,
|
||||
spvValidate(get_const_binary(), SPV_VALIDATE_ALL, &diagnostic));
|
||||
spvTextToBinary(context, str, strlen(str), &binary, &diagnostic));
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_ID, spvValidate(context, get_const_binary(),
|
||||
SPV_VALIDATE_ALL, &diagnostic));
|
||||
ASSERT_NE(nullptr, diagnostic);
|
||||
spvDiagnosticPrint(diagnostic);
|
||||
spvDiagnosticDestroy(diagnostic);
|
||||
@ -97,10 +99,10 @@ OpFunctionEnd
|
||||
)";
|
||||
spv_diagnostic diagnostic = nullptr;
|
||||
ASSERT_EQ(SPV_SUCCESS,
|
||||
spvTextToBinary(str, strlen(str), &binary, &diagnostic));
|
||||
spvTextToBinary(context, str, strlen(str), &binary, &diagnostic));
|
||||
// TODO: Fix setting of bound in spvTextTo, then remove this!
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_ID,
|
||||
spvValidate(get_const_binary(), SPV_VALIDATE_ALL, &diagnostic));
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_ID, spvValidate(context, get_const_binary(),
|
||||
SPV_VALIDATE_ALL, &diagnostic));
|
||||
ASSERT_NE(nullptr, diagnostic);
|
||||
spvDiagnosticPrint(diagnostic);
|
||||
spvDiagnosticDestroy(diagnostic);
|
||||
|
@ -41,22 +41,24 @@ class ValidateID : public ::testing::Test {
|
||||
spv_binary binary;
|
||||
};
|
||||
|
||||
#define CHECK(str, expected) \
|
||||
spv_diagnostic diagnostic; \
|
||||
spv_result_t error = \
|
||||
spvTextToBinary(str, strlen(str), &binary, &diagnostic); \
|
||||
if (error) { \
|
||||
spvDiagnosticPrint(diagnostic); \
|
||||
spvDiagnosticDestroy(diagnostic); \
|
||||
ASSERT_EQ(SPV_SUCCESS, error); \
|
||||
} \
|
||||
spv_result_t result = \
|
||||
spvValidate(get_const_binary(), SPV_VALIDATE_ID_BIT, &diagnostic); \
|
||||
if (SPV_SUCCESS != result) { \
|
||||
spvDiagnosticPrint(diagnostic); \
|
||||
spvDiagnosticDestroy(diagnostic); \
|
||||
} \
|
||||
ASSERT_EQ(expected, result);
|
||||
#define CHECK(str, expected) \
|
||||
spv_diagnostic diagnostic; \
|
||||
spv_context context = spvContextCreate(); \
|
||||
spv_result_t error = \
|
||||
spvTextToBinary(context, str, strlen(str), &binary, &diagnostic); \
|
||||
if (error) { \
|
||||
spvDiagnosticPrint(diagnostic); \
|
||||
spvDiagnosticDestroy(diagnostic); \
|
||||
ASSERT_EQ(SPV_SUCCESS, error); \
|
||||
} \
|
||||
spv_result_t result = spvValidate(context, get_const_binary(), \
|
||||
SPV_VALIDATE_ID_BIT, &diagnostic); \
|
||||
if (SPV_SUCCESS != result) { \
|
||||
spvDiagnosticPrint(diagnostic); \
|
||||
spvDiagnosticDestroy(diagnostic); \
|
||||
} \
|
||||
ASSERT_EQ(expected, result); \
|
||||
spvContextDestroy(context);
|
||||
|
||||
// TODO: OpUndef
|
||||
|
||||
|
@ -94,8 +94,10 @@ int main(int argc, char** argv) {
|
||||
|
||||
spv_binary binary;
|
||||
spv_diagnostic diagnostic = nullptr;
|
||||
spv_result_t error =
|
||||
spvTextToBinary(contents.data(), contents.size(), &binary, &diagnostic);
|
||||
spv_context context = spvContextCreate();
|
||||
spv_result_t error = spvTextToBinary(context, contents.data(),
|
||||
contents.size(), &binary, &diagnostic);
|
||||
spvContextDestroy(context);
|
||||
if (error) {
|
||||
spvDiagnosticPrint(diagnostic);
|
||||
spvDiagnosticDestroy(diagnostic);
|
||||
|
@ -146,8 +146,11 @@ int main(int argc, char** argv) {
|
||||
spv_text text;
|
||||
spv_text* textOrNull = print_to_stdout ? nullptr : &text;
|
||||
spv_diagnostic diagnostic = nullptr;
|
||||
spv_result_t error = spvBinaryToText(contents.data(), contents.size(),
|
||||
options, textOrNull, &diagnostic);
|
||||
spv_context context = spvContextCreate();
|
||||
spv_result_t error =
|
||||
spvBinaryToText(context, contents.data(), contents.size(), options,
|
||||
textOrNull, &diagnostic);
|
||||
spvContextDestroy(context);
|
||||
if (error) {
|
||||
spvDiagnosticPrint(diagnostic);
|
||||
spvDiagnosticDestroy(diagnostic);
|
||||
|
@ -99,7 +99,9 @@ int main(int argc, char** argv) {
|
||||
spv_const_binary_t binary = {contents.data(), contents.size()};
|
||||
|
||||
spv_diagnostic diagnostic = nullptr;
|
||||
spv_result_t error = spvValidate(&binary, options, &diagnostic);
|
||||
spv_context context = spvContextCreate();
|
||||
spv_result_t error = spvValidate(context, &binary, options, &diagnostic);
|
||||
spvContextDestroy(context);
|
||||
if (error) {
|
||||
spvDiagnosticPrint(diagnostic);
|
||||
spvDiagnosticDestroy(diagnostic);
|
||||
|
Loading…
Reference in New Issue
Block a user