1 // Copyright (c) 2016 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "build_module.h"
16
17 #include "ir_loader.h"
18 #include "make_unique.h"
19 #include "table.h"
20
21 namespace spvtools {
22
23 namespace {
24
25 // Sets the module header for IrLoader. Meets the interface requirement of
26 // spvBinaryParse().
SetSpvHeader(void * builder,spv_endianness_t,uint32_t magic,uint32_t version,uint32_t generator,uint32_t id_bound,uint32_t reserved)27 spv_result_t SetSpvHeader(void* builder, spv_endianness_t, uint32_t magic,
28 uint32_t version, uint32_t generator,
29 uint32_t id_bound, uint32_t reserved) {
30 reinterpret_cast<ir::IrLoader*>(builder)
31 ->SetModuleHeader(magic, version, generator, id_bound, reserved);
32 return SPV_SUCCESS;
33 };
34
35 // Processes a parsed instruction for IrLoader. Meets the interface requirement
36 // of spvBinaryParse().
SetSpvInst(void * builder,const spv_parsed_instruction_t * inst)37 spv_result_t SetSpvInst(void* builder, const spv_parsed_instruction_t* inst) {
38 if (reinterpret_cast<ir::IrLoader*>(builder)->AddInstruction(inst)) {
39 return SPV_SUCCESS;
40 }
41 return SPV_ERROR_INVALID_BINARY;
42 };
43
44 } // annoymous namespace
45
BuildModule(spv_target_env env,MessageConsumer consumer,const uint32_t * binary,const size_t size)46 std::unique_ptr<ir::Module> BuildModule(spv_target_env env,
47 MessageConsumer consumer,
48 const uint32_t* binary,
49 const size_t size) {
50 auto context = spvContextCreate(env);
51 SetContextMessageConsumer(context, consumer);
52
53 auto module = MakeUnique<ir::Module>();
54 ir::IrLoader loader(context->consumer, module.get());
55
56 spv_result_t status = spvBinaryParse(context, &loader, binary, size,
57 SetSpvHeader, SetSpvInst, nullptr);
58 loader.EndModule();
59
60 spvContextDestroy(context);
61
62 return status == SPV_SUCCESS ? std::move(module) : nullptr;
63 }
64
BuildModule(spv_target_env env,MessageConsumer consumer,const std::string & text,uint32_t assemble_options)65 std::unique_ptr<ir::Module> BuildModule(spv_target_env env,
66 MessageConsumer consumer,
67 const std::string& text,
68 uint32_t assemble_options) {
69 SpirvTools t(env);
70 t.SetMessageConsumer(consumer);
71 std::vector<uint32_t> binary;
72 if (!t.Assemble(text, &binary, assemble_options)) return nullptr;
73 return BuildModule(env, consumer, binary.data(), binary.size());
74 }
75
76 } // namespace spvtools
77