Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sts=4 et sw=4 tw=99:
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 : *
10 : * http://www.apache.org/licenses/LICENSE-2.0
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 "js/Vector.h"
23 :
24 : namespace js {
25 : namespace wasm {
26 :
27 : // Factor out common serialization, cloning and about:memory size-computation
28 : // functions for reuse when serializing wasm and asm.js modules.
29 :
30 : static inline uint8_t*
31 0 : WriteBytes(uint8_t* dst, const void* src, size_t nbytes)
32 : {
33 0 : memcpy(dst, src, nbytes);
34 0 : return dst + nbytes;
35 : }
36 :
37 : static inline const uint8_t*
38 0 : ReadBytes(const uint8_t* src, void* dst, size_t nbytes)
39 : {
40 0 : memcpy(dst, src, nbytes);
41 0 : return src + nbytes;
42 : }
43 :
44 : static inline const uint8_t*
45 0 : ReadBytesChecked(const uint8_t* src, size_t* remain, void* dst, size_t nbytes)
46 : {
47 0 : if (*remain < nbytes)
48 0 : return nullptr;
49 0 : memcpy(dst, src, nbytes);
50 0 : *remain -= nbytes;
51 0 : return src + nbytes;
52 : }
53 :
54 : template <class T>
55 : static inline uint8_t*
56 0 : WriteScalar(uint8_t* dst, T t)
57 : {
58 0 : memcpy(dst, &t, sizeof(t));
59 0 : return dst + sizeof(t);
60 : }
61 :
62 : template <class T>
63 : static inline const uint8_t*
64 0 : ReadScalar(const uint8_t* src, T* dst)
65 : {
66 0 : memcpy(dst, src, sizeof(*dst));
67 0 : return src + sizeof(*dst);
68 : }
69 :
70 : template <class T>
71 : static inline const uint8_t*
72 0 : ReadScalarChecked(const uint8_t* src, size_t* remain, T* dst)
73 : {
74 0 : if (*remain < sizeof(*dst))
75 0 : return nullptr;
76 0 : memcpy(dst, src, sizeof(*dst));
77 0 : *remain -= sizeof(*dst);
78 0 : return src + sizeof(*dst);
79 : }
80 :
81 : template <class T, size_t N>
82 : static inline size_t
83 0 : SerializedVectorSize(const mozilla::Vector<T, N, SystemAllocPolicy>& vec)
84 : {
85 0 : size_t size = sizeof(uint32_t);
86 0 : for (size_t i = 0; i < vec.length(); i++)
87 0 : size += vec[i].serializedSize();
88 0 : return size;
89 : }
90 :
91 : template <class T, size_t N>
92 : static inline uint8_t*
93 0 : SerializeVector(uint8_t* cursor, const mozilla::Vector<T, N, SystemAllocPolicy>& vec)
94 : {
95 0 : cursor = WriteScalar<uint32_t>(cursor, vec.length());
96 0 : for (size_t i = 0; i < vec.length(); i++)
97 0 : cursor = vec[i].serialize(cursor);
98 0 : return cursor;
99 : }
100 :
101 : template <class T, size_t N>
102 : static inline const uint8_t*
103 0 : DeserializeVector(const uint8_t* cursor, mozilla::Vector<T, N, SystemAllocPolicy>* vec)
104 : {
105 : uint32_t length;
106 0 : cursor = ReadScalar<uint32_t>(cursor, &length);
107 0 : if (!vec->resize(length))
108 0 : return nullptr;
109 0 : for (size_t i = 0; i < vec->length(); i++) {
110 0 : if (!(cursor = (*vec)[i].deserialize(cursor)))
111 0 : return nullptr;
112 : }
113 0 : return cursor;
114 : }
115 :
116 : template <class T, size_t N>
117 : static inline size_t
118 0 : SizeOfVectorExcludingThis(const mozilla::Vector<T, N, SystemAllocPolicy>& vec,
119 : MallocSizeOf mallocSizeOf)
120 : {
121 0 : size_t size = vec.sizeOfExcludingThis(mallocSizeOf);
122 0 : for (const T& t : vec)
123 0 : size += t.sizeOfExcludingThis(mallocSizeOf);
124 0 : return size;
125 : }
126 :
127 : template <class T, size_t N>
128 : static inline size_t
129 0 : SerializedPodVectorSize(const mozilla::Vector<T, N, SystemAllocPolicy>& vec)
130 : {
131 : return sizeof(uint32_t) +
132 0 : vec.length() * sizeof(T);
133 : }
134 :
135 : template <class T, size_t N>
136 : static inline uint8_t*
137 0 : SerializePodVector(uint8_t* cursor, const mozilla::Vector<T, N, SystemAllocPolicy>& vec)
138 : {
139 : // This binary format must not change without taking into consideration the
140 : // constraints in Assumptions::serialize.
141 :
142 0 : cursor = WriteScalar<uint32_t>(cursor, vec.length());
143 0 : cursor = WriteBytes(cursor, vec.begin(), vec.length() * sizeof(T));
144 0 : return cursor;
145 : }
146 :
147 : template <class T, size_t N>
148 : static inline const uint8_t*
149 0 : DeserializePodVector(const uint8_t* cursor, mozilla::Vector<T, N, SystemAllocPolicy>* vec)
150 : {
151 : uint32_t length;
152 0 : cursor = ReadScalar<uint32_t>(cursor, &length);
153 0 : if (!vec->initLengthUninitialized(length))
154 0 : return nullptr;
155 0 : cursor = ReadBytes(cursor, vec->begin(), length * sizeof(T));
156 0 : return cursor;
157 : }
158 :
159 : template <class T, size_t N>
160 : static inline const uint8_t*
161 0 : DeserializePodVectorChecked(const uint8_t* cursor, size_t* remain, mozilla::Vector<T, N, SystemAllocPolicy>* vec)
162 : {
163 : uint32_t length;
164 0 : cursor = ReadScalarChecked<uint32_t>(cursor, remain, &length);
165 0 : if (!cursor || !vec->initLengthUninitialized(length))
166 0 : return nullptr;
167 0 : cursor = ReadBytesChecked(cursor, remain, vec->begin(), length * sizeof(T));
168 0 : return cursor;
169 : }
170 :
171 : } // namespace wasm
172 : } // namespace js
173 :
174 : #endif // wasm_serialize_h
|