blob: b951016855848177e191954e634b5032a2e71a4b [file] [log] [blame]
Francisco Jerezc6db1b32012-04-20 16:56:19 +02001//
2// Copyright 2012 Francisco Jerez
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Kenneth Graunkef0cb66b2013-04-21 13:52:08 -070017// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20// OTHER DEALINGS IN THE SOFTWARE.
Francisco Jerezc6db1b32012-04-20 16:56:19 +020021//
22
23#include <type_traits>
EdBd8f817a2015-04-23 20:13:51 +020024#include <iostream>
Francisco Jerezc6db1b32012-04-20 16:56:19 +020025
26#include "core/module.hpp"
27
28using namespace clover;
29
30namespace {
31 template<typename T, typename = void>
Francisco Jerez8e14b822013-09-17 23:13:48 -070032 struct _serializer;
Francisco Jerezc6db1b32012-04-20 16:56:19 +020033
34 /// Serialize the specified object.
35 template<typename T>
36 void
EdBd8f817a2015-04-23 20:13:51 +020037 _proc(std::ostream &os, const T &x) {
Francisco Jerez8e14b822013-09-17 23:13:48 -070038 _serializer<T>::proc(os, x);
Francisco Jerezc6db1b32012-04-20 16:56:19 +020039 }
40
41 /// Deserialize the specified object.
42 template<typename T>
43 void
EdBd8f817a2015-04-23 20:13:51 +020044 _proc(std::istream &is, T &x) {
Francisco Jerez8e14b822013-09-17 23:13:48 -070045 _serializer<T>::proc(is, x);
Francisco Jerezc6db1b32012-04-20 16:56:19 +020046 }
47
48 template<typename T>
49 T
EdBd8f817a2015-04-23 20:13:51 +020050 _proc(std::istream &is) {
Francisco Jerezc6db1b32012-04-20 16:56:19 +020051 T x;
Francisco Jerez8e14b822013-09-17 23:13:48 -070052 _serializer<T>::proc(is, x);
Francisco Jerezc6db1b32012-04-20 16:56:19 +020053 return x;
54 }
55
Francisco Jerez4a39e502014-06-14 21:03:02 +020056 /// Calculate the size of the specified object.
57 template<typename T>
58 void
59 _proc(module::size_t &sz, const T &x) {
60 _serializer<T>::proc(sz, x);
61 }
62
Francisco Jerezc6db1b32012-04-20 16:56:19 +020063 /// (De)serialize a scalar value.
64 template<typename T>
Francisco Jerez8e14b822013-09-17 23:13:48 -070065 struct _serializer<T, typename std::enable_if<
66 std::is_scalar<T>::value>::type> {
Francisco Jerezc6db1b32012-04-20 16:56:19 +020067 static void
EdBd8f817a2015-04-23 20:13:51 +020068 proc(std::ostream &os, const T &x) {
Francisco Jerezc6db1b32012-04-20 16:56:19 +020069 os.write(reinterpret_cast<const char *>(&x), sizeof(x));
70 }
71
72 static void
EdBd8f817a2015-04-23 20:13:51 +020073 proc(std::istream &is, T &x) {
Francisco Jerezc6db1b32012-04-20 16:56:19 +020074 is.read(reinterpret_cast<char *>(&x), sizeof(x));
75 }
Francisco Jerez4a39e502014-06-14 21:03:02 +020076
77 static void
78 proc(module::size_t &sz, const T &x) {
79 sz += sizeof(x);
80 }
Francisco Jerezc6db1b32012-04-20 16:56:19 +020081 };
82
83 /// (De)serialize a vector.
84 template<typename T>
EdBd8f817a2015-04-23 20:13:51 +020085 struct _serializer<std::vector<T>,
Francisco Jerezab023c22014-06-14 20:53:35 +020086 typename std::enable_if<
87 !std::is_scalar<T>::value>::type> {
Francisco Jerezc6db1b32012-04-20 16:56:19 +020088 static void
EdBd8f817a2015-04-23 20:13:51 +020089 proc(std::ostream &os, const std::vector<T> &v) {
Francisco Jerez8e14b822013-09-17 23:13:48 -070090 _proc<uint32_t>(os, v.size());
Francisco Jerezc6db1b32012-04-20 16:56:19 +020091
92 for (size_t i = 0; i < v.size(); i++)
Francisco Jerez8e14b822013-09-17 23:13:48 -070093 _proc<T>(os, v[i]);
Francisco Jerezc6db1b32012-04-20 16:56:19 +020094 }
95
96 static void
EdBd8f817a2015-04-23 20:13:51 +020097 proc(std::istream &is, std::vector<T> &v) {
Francisco Jerez7c1e6d52014-08-18 08:30:46 +030098 v.resize(_proc<uint32_t>(is));
Francisco Jerezc6db1b32012-04-20 16:56:19 +020099
100 for (size_t i = 0; i < v.size(); i++)
Francisco Jerez8e14b822013-09-17 23:13:48 -0700101 new(&v[i]) T(_proc<T>(is));
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200102 }
Francisco Jerez4a39e502014-06-14 21:03:02 +0200103
104 static void
EdBd8f817a2015-04-23 20:13:51 +0200105 proc(module::size_t &sz, const std::vector<T> &v) {
Francisco Jerez4a39e502014-06-14 21:03:02 +0200106 sz += sizeof(uint32_t);
107
108 for (size_t i = 0; i < v.size(); i++)
109 _proc<T>(sz, v[i]);
110 }
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200111 };
112
Francisco Jerezab023c22014-06-14 20:53:35 +0200113 template<typename T>
EdBd8f817a2015-04-23 20:13:51 +0200114 struct _serializer<std::vector<T>,
Francisco Jerezab023c22014-06-14 20:53:35 +0200115 typename std::enable_if<
116 std::is_scalar<T>::value>::type> {
117 static void
EdBd8f817a2015-04-23 20:13:51 +0200118 proc(std::ostream &os, const std::vector<T> &v) {
Francisco Jerezab023c22014-06-14 20:53:35 +0200119 _proc<uint32_t>(os, v.size());
EdBd8f817a2015-04-23 20:13:51 +0200120 os.write(reinterpret_cast<const char *>(&v[0]),
Francisco Jerezab023c22014-06-14 20:53:35 +0200121 v.size() * sizeof(T));
122 }
123
124 static void
EdBd8f817a2015-04-23 20:13:51 +0200125 proc(std::istream &is, std::vector<T> &v) {
Francisco Jerez7c1e6d52014-08-18 08:30:46 +0300126 v.resize(_proc<uint32_t>(is));
EdBd8f817a2015-04-23 20:13:51 +0200127 is.read(reinterpret_cast<char *>(&v[0]),
Francisco Jerezab023c22014-06-14 20:53:35 +0200128 v.size() * sizeof(T));
129 }
Francisco Jerez4a39e502014-06-14 21:03:02 +0200130
131 static void
EdBd8f817a2015-04-23 20:13:51 +0200132 proc(module::size_t &sz, const std::vector<T> &v) {
Francisco Jerez4a39e502014-06-14 21:03:02 +0200133 sz += sizeof(uint32_t) + sizeof(T) * v.size();
134 }
Francisco Jerezab023c22014-06-14 20:53:35 +0200135 };
136
EdB2d112ed2015-04-24 12:59:56 +0200137 /// (De)serialize a string.
138 template<>
139 struct _serializer<std::string> {
140 static void
EdBd8f817a2015-04-23 20:13:51 +0200141 proc(std::ostream &os, const std::string &s) {
EdB2d112ed2015-04-24 12:59:56 +0200142 _proc<uint32_t>(os, s.size());
143 os.write(&s[0], s.size() * sizeof(std::string::value_type));
144 }
145
146 static void
EdBd8f817a2015-04-23 20:13:51 +0200147 proc(std::istream &is, std::string &s) {
EdB2d112ed2015-04-24 12:59:56 +0200148 s.resize(_proc<uint32_t>(is));
149 is.read(&s[0], s.size() * sizeof(std::string::value_type));
150 }
151
152 static void
153 proc(module::size_t &sz, const std::string &s) {
154 sz += sizeof(uint32_t) + sizeof(std::string::value_type) * s.size();
155 }
156 };
157
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200158 /// (De)serialize a module::section.
159 template<>
Francisco Jerez8e14b822013-09-17 23:13:48 -0700160 struct _serializer<module::section> {
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200161 template<typename S, typename QT>
162 static void
163 proc(S &s, QT &x) {
Francisco Jerez8e14b822013-09-17 23:13:48 -0700164 _proc(s, x.id);
165 _proc(s, x.type);
166 _proc(s, x.size);
167 _proc(s, x.data);
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200168 }
169 };
170
171 /// (De)serialize a module::argument.
172 template<>
Francisco Jerez8e14b822013-09-17 23:13:48 -0700173 struct _serializer<module::argument> {
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200174 template<typename S, typename QT>
175 static void
176 proc(S &s, QT &x) {
Francisco Jerez8e14b822013-09-17 23:13:48 -0700177 _proc(s, x.type);
178 _proc(s, x.size);
Francisco Jerez5195f1d2014-01-14 21:53:57 +0100179 _proc(s, x.target_size);
180 _proc(s, x.target_align);
181 _proc(s, x.ext_type);
Tom Stellard8cf64822014-10-14 17:55:23 -0400182 _proc(s, x.semantic);
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200183 }
184 };
185
186 /// (De)serialize a module::symbol.
187 template<>
Francisco Jerez8e14b822013-09-17 23:13:48 -0700188 struct _serializer<module::symbol> {
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200189 template<typename S, typename QT>
190 static void
191 proc(S &s, QT &x) {
Francisco Jerez8e14b822013-09-17 23:13:48 -0700192 _proc(s, x.name);
Serge Martinaadd1342020-08-23 08:50:54 +0200193 _proc(s, x.attributes);
Serge Martinc04d5e72020-09-27 15:45:33 +0200194 _proc(s, x.reqd_work_group_size);
Francisco Jerez8e14b822013-09-17 23:13:48 -0700195 _proc(s, x.section);
196 _proc(s, x.offset);
197 _proc(s, x.args);
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200198 }
199 };
200
201 /// (De)serialize a module.
202 template<>
Francisco Jerez8e14b822013-09-17 23:13:48 -0700203 struct _serializer<module> {
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200204 template<typename S, typename QT>
205 static void
206 proc(S &s, QT &x) {
Francisco Jerez8e14b822013-09-17 23:13:48 -0700207 _proc(s, x.syms);
208 _proc(s, x.secs);
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200209 }
210 };
211};
212
213namespace clover {
214 void
EdBd8f817a2015-04-23 20:13:51 +0200215 module::serialize(std::ostream &os) const {
Francisco Jerez8e14b822013-09-17 23:13:48 -0700216 _proc(os, *this);
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200217 }
218
219 module
EdBd8f817a2015-04-23 20:13:51 +0200220 module::deserialize(std::istream &is) {
Francisco Jerez8e14b822013-09-17 23:13:48 -0700221 return _proc<module>(is);
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200222 }
Francisco Jerez4a39e502014-06-14 21:03:02 +0200223
224 module::size_t
225 module::size() const {
226 size_t sz = 0;
227 _proc(sz, *this);
228 return sz;
229 }
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200230}