Source code

Revision control

Other Tools

1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2
* vim: set ts=8 sts=2 et sw=2 tw=80:
3
*
4
* Copyright 2015 Mozilla Foundation
5
*
6
* Licensed under the Apache License, Version 2.0 (the "License");
7
* you may not use this file except in compliance with the License.
8
* You may obtain a copy of the License at
9
*
11
*
12
* Unless required by applicable law or agreed to in writing, software
13
* distributed under the License is distributed on an "AS IS" BASIS,
14
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
* See the License for the specific language governing permissions and
16
* limitations under the License.
17
*/
18
19
#ifndef wasm_serialize_h
20
#define wasm_serialize_h
21
22
#include <type_traits>
23
24
#include "js/Vector.h"
25
26
namespace js {
27
namespace wasm {
28
29
// Factor out common serialization, cloning and about:memory size-computation
30
// functions for reuse when serializing wasm and asm.js modules.
31
32
static inline uint8_t* WriteBytes(uint8_t* dst, const void* src,
33
size_t nbytes) {
34
if (nbytes) {
35
memcpy(dst, src, nbytes);
36
}
37
return dst + nbytes;
38
}
39
40
static inline const uint8_t* ReadBytes(const uint8_t* src, void* dst,
41
size_t nbytes) {
42
if (nbytes) {
43
memcpy(dst, src, nbytes);
44
}
45
return src + nbytes;
46
}
47
48
static inline const uint8_t* ReadBytesChecked(const uint8_t* src,
49
size_t* remain, void* dst,
50
size_t nbytes) {
51
if (*remain < nbytes) {
52
return nullptr;
53
}
54
memcpy(dst, src, nbytes);
55
*remain -= nbytes;
56
return src + nbytes;
57
}
58
59
template <class T>
60
static inline uint8_t* WriteScalar(uint8_t* dst, T t) {
61
memcpy(dst, &t, sizeof(t));
62
return dst + sizeof(t);
63
}
64
65
template <class T>
66
static inline const uint8_t* ReadScalar(const uint8_t* src, T* dst) {
67
memcpy(dst, src, sizeof(*dst));
68
return src + sizeof(*dst);
69
}
70
71
template <class T>
72
static inline const uint8_t* ReadScalarChecked(const uint8_t* src,
73
size_t* remain, T* dst) {
74
if (*remain < sizeof(*dst)) {
75
return nullptr;
76
}
77
memcpy(dst, src, sizeof(*dst));
78
*remain -= sizeof(*dst);
79
return src + sizeof(*dst);
80
}
81
82
template <class T, size_t N>
83
static inline size_t SerializedVectorSize(
84
const mozilla::Vector<T, N, SystemAllocPolicy>& vec) {
85
size_t size = sizeof(uint32_t);
86
for (size_t i = 0; i < vec.length(); i++) {
87
size += vec[i].serializedSize();
88
}
89
return size;
90
}
91
92
template <class T, size_t N>
93
static inline uint8_t* SerializeVector(
94
uint8_t* cursor, const mozilla::Vector<T, N, SystemAllocPolicy>& vec) {
95
cursor = WriteScalar<uint32_t>(cursor, vec.length());
96
for (size_t i = 0; i < vec.length(); i++) {
97
cursor = vec[i].serialize(cursor);
98
}
99
return cursor;
100
}
101
102
template <class T, size_t N>
103
static inline const uint8_t* DeserializeVector(
104
const uint8_t* cursor, mozilla::Vector<T, N, SystemAllocPolicy>* vec) {
105
uint32_t length;
106
cursor = ReadScalar<uint32_t>(cursor, &length);
107
if (!vec->resize(length)) {
108
return nullptr;
109
}
110
for (size_t i = 0; i < vec->length(); i++) {
111
if (!(cursor = (*vec)[i].deserialize(cursor))) {
112
return nullptr;
113
}
114
}
115
return cursor;
116
}
117
118
template <class T, size_t N>
119
static inline size_t SizeOfVectorExcludingThis(
120
const mozilla::Vector<T, N, SystemAllocPolicy>& vec,
121
MallocSizeOf mallocSizeOf) {
122
size_t size = vec.sizeOfExcludingThis(mallocSizeOf);
123
for (const T& t : vec) {
124
size += t.sizeOfExcludingThis(mallocSizeOf);
125
}
126
return size;
127
}
128
129
template <class T, size_t N>
130
static inline size_t SerializedPodVectorSize(
131
const mozilla::Vector<T, N, SystemAllocPolicy>& vec) {
132
return sizeof(uint32_t) + vec.length() * sizeof(T);
133
}
134
135
template <class T, size_t N>
136
static inline uint8_t* SerializePodVector(
137
uint8_t* cursor, const mozilla::Vector<T, N, SystemAllocPolicy>& vec) {
138
// This binary format must not change without taking into consideration the
139
// constraints in Assumptions::serialize.
140
141
cursor = WriteScalar<uint32_t>(cursor, vec.length());
142
cursor = WriteBytes(cursor, vec.begin(), vec.length() * sizeof(T));
143
return cursor;
144
}
145
146
template <class T, size_t N>
147
static inline const uint8_t* DeserializePodVector(
148
const uint8_t* cursor, mozilla::Vector<T, N, SystemAllocPolicy>* vec) {
149
uint32_t length;
150
cursor = ReadScalar<uint32_t>(cursor, &length);
151
if (!vec->initLengthUninitialized(length)) {
152
return nullptr;
153
}
154
cursor = ReadBytes(cursor, vec->begin(), length * sizeof(T));
155
return cursor;
156
}
157
158
template <class T, size_t N>
159
static inline const uint8_t* DeserializePodVectorChecked(
160
const uint8_t* cursor, size_t* remain,
161
mozilla::Vector<T, N, SystemAllocPolicy>* vec) {
162
uint32_t length;
163
cursor = ReadScalarChecked<uint32_t>(cursor, remain, &length);
164
if (!cursor || !vec->initLengthUninitialized(length)) {
165
return nullptr;
166
}
167
cursor = ReadBytesChecked(cursor, remain, vec->begin(), length * sizeof(T));
168
return cursor;
169
}
170
171
template <class T>
172
inline size_t SerializableRefPtr<T>::serializedSize() const {
173
return (*this)->serializedSize();
174
}
175
176
template <class T>
177
inline uint8_t* SerializableRefPtr<T>::serialize(uint8_t* cursor) const {
178
return (*this)->serialize(cursor);
179
}
180
181
template <class T>
182
inline const uint8_t* SerializableRefPtr<T>::deserialize(
183
const uint8_t* cursor) {
184
auto* t = js_new<std::remove_const_t<T>>();
185
*this = t;
186
return t->deserialize(cursor);
187
}
188
189
template <class T>
190
inline size_t SerializableRefPtr<T>::sizeOfExcludingThis(
191
mozilla::MallocSizeOf mallocSizeOf) const {
192
return (*this)->sizeOfExcludingThis(mallocSizeOf);
193
}
194
195
} // namespace wasm
196
} // namespace js
197
198
#endif // wasm_serialize_h