blob: fe1b2b5497ef8e9a5cf53bec09af43bea174a157 [file] [log] [blame]
Lei Zhangabf8f642016-06-28 10:23:13 -04001// Copyright (c) 2016 Google Inc.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and/or associated documentation files (the
5// "Materials"), to deal in the Materials without restriction, including
6// without limitation the rights to use, copy, modify, merge, publish,
7// distribute, sublicense, and/or sell copies of the Materials, and to
8// permit persons to whom the Materials are furnished to do so, subject to
9// the following conditions:
10//
11// The above copyright notice and this permission notice shall be included
12// in all copies or substantial portions of the Materials.
13//
14// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
15// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
16// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
17// https://www.khronos.org/registry/
18//
19// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
26
27#include "libspirv.hpp"
28
29#include "ir_loader.h"
30
31namespace spvtools {
32
33namespace {
34
35// Sets the module header. Meets the interface requirement of spvBinaryParse().
36spv_result_t SetSpvHeader(void* builder, spv_endianness_t, uint32_t magic,
37 uint32_t version, uint32_t generator,
38 uint32_t id_bound, uint32_t reserved) {
39 reinterpret_cast<ir::IrLoader*>(builder)->SetModuleHeader(
40 magic, version, generator, id_bound, reserved);
41 return SPV_SUCCESS;
42};
43
44// Processes a parsed instruction. Meets the interface requirement of
45// spvBinaryParse().
46spv_result_t SetSpvInst(void* builder, const spv_parsed_instruction_t* inst) {
47 reinterpret_cast<ir::IrLoader*>(builder)->AddInstruction(inst);
48 return SPV_SUCCESS;
49};
50
51} // annoymous namespace
52
53spv_result_t SpvTools::Assemble(const std::string& text,
54 std::vector<uint32_t>* binary) {
55 spv_binary spvbinary = nullptr;
56 spv_diagnostic diagnostic = nullptr;
57
58 spv_result_t status = spvTextToBinary(context_, text.data(), text.size(),
59 &spvbinary, &diagnostic);
60 if (status == SPV_SUCCESS) {
61 binary->assign(spvbinary->code, spvbinary->code + spvbinary->wordCount);
62 }
63
64 spvDiagnosticDestroy(diagnostic);
65 spvBinaryDestroy(spvbinary);
66
67 return status;
68}
69
70spv_result_t SpvTools::Disassemble(const std::vector<uint32_t>& binary,
71 std::string* text) {
72 spv_text spvtext = nullptr;
73 spv_diagnostic diagnostic = nullptr;
74
75 spv_result_t status = spvBinaryToText(context_, binary.data(), binary.size(),
76 SPV_BINARY_TO_TEXT_OPTION_NO_HEADER,
77 &spvtext, &diagnostic);
78 if (status == SPV_SUCCESS) {
79 text->assign(spvtext->str, spvtext->str + spvtext->length);
80 }
81
82 spvDiagnosticDestroy(diagnostic);
83 spvTextDestroy(spvtext);
84
85 return status;
86}
87
88std::unique_ptr<ir::Module> SpvTools::BuildModule(
89 const std::vector<uint32_t>& binary) {
90 spv_diagnostic diagnostic = nullptr;
91
92 std::unique_ptr<ir::Module> module(new ir::Module);
93 ir::IrLoader loader(module.get());
94
95 spv_result_t status =
96 spvBinaryParse(context_, &loader, binary.data(), binary.size(),
97 SetSpvHeader, SetSpvInst, &diagnostic);
98
99 spvDiagnosticDestroy(diagnostic);
100
101 loader.EndModule();
102
103 if (status == SPV_SUCCESS) return module;
104 return nullptr;
105}
106
107std::unique_ptr<ir::Module> SpvTools::BuildModule(const std::string& text) {
108 std::vector<uint32_t> binary;
109 if (Assemble(text, &binary) != SPV_SUCCESS) return nullptr;
110 return BuildModule(binary);
111}
112
113} // namespace spvtools