Line data Source code
1 : // Copyright 2017 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "src/wasm/streaming-decoder.h"
6 :
7 : #include "src/base/template-utils.h"
8 : #include "src/handles.h"
9 : #include "src/objects-inl.h"
10 : #include "src/objects/descriptor-array.h"
11 : #include "src/objects/dictionary.h"
12 : #include "src/wasm/decoder.h"
13 : #include "src/wasm/leb-helper.h"
14 : #include "src/wasm/module-decoder.h"
15 : #include "src/wasm/wasm-objects.h"
16 : #include "src/wasm/wasm-result.h"
17 :
18 : namespace v8 {
19 : namespace internal {
20 : namespace wasm {
21 :
22 14433 : void StreamingDecoder::OnBytesReceived(Vector<const uint8_t> bytes) {
23 : size_t current = 0;
24 14433 : while (ok() && current < bytes.size()) {
25 : size_t num_bytes =
26 17622 : state_->ReadBytes(this, bytes.SubVector(current, bytes.size()));
27 8811 : current += num_bytes;
28 8811 : module_offset_ += num_bytes;
29 8811 : if (state_->is_finished()) {
30 15884 : state_ = state_->Next(this);
31 : }
32 : }
33 2811 : total_size_ += bytes.size();
34 2811 : if (ok()) {
35 1666 : processor_->OnFinishedChunk();
36 : }
37 2811 : }
38 :
39 5688 : size_t StreamingDecoder::DecodingState::ReadBytes(StreamingDecoder* streaming,
40 11376 : Vector<const uint8_t> bytes) {
41 11376 : size_t num_bytes = std::min(bytes.size(), remaining());
42 11376 : memcpy(buffer() + offset(), &bytes.first(), num_bytes);
43 5688 : set_offset(offset() + num_bytes);
44 5688 : return num_bytes;
45 : }
46 :
47 1402 : void StreamingDecoder::Finish() {
48 1402 : if (!ok()) {
49 : return;
50 : }
51 :
52 431 : if (!state_->is_finishing_allowed()) {
53 : // The byte stream ended too early, we report an error.
54 261 : Error("unexpected end of stream");
55 87 : return;
56 : }
57 :
58 344 : std::unique_ptr<uint8_t[]> bytes(new uint8_t[total_size_]);
59 : uint8_t* cursor = bytes.get();
60 : {
61 : #define BYTES(x) (x & 0xff), (x >> 8) & 0xff, (x >> 16) & 0xff, (x >> 24) & 0xff
62 344 : uint8_t module_header[]{BYTES(kWasmMagic), BYTES(kWasmVersion)};
63 : #undef BYTES
64 : memcpy(cursor, module_header, arraysize(module_header));
65 344 : cursor += arraysize(module_header);
66 : }
67 1430 : for (auto&& buffer : section_buffers_) {
68 : DCHECK_LE(cursor - bytes.get() + buffer->length(), total_size_);
69 742 : memcpy(cursor, buffer->bytes(), buffer->length());
70 742 : cursor += buffer->length();
71 : }
72 1032 : processor_->OnFinishedStream(std::move(bytes), total_size_);
73 : }
74 :
75 72 : void StreamingDecoder::Abort() {
76 138 : if (ok()) processor_->OnAbort();
77 72 : }
78 :
79 : // An abstract class to share code among the states which decode VarInts. This
80 : // class takes over the decoding of the VarInt and then calls the actual decode
81 : // code with the decoded value.
82 3150 : class StreamingDecoder::DecodeVarInt32 : public DecodingState {
83 : public:
84 : explicit DecodeVarInt32(size_t max_value, const char* field_name)
85 3150 : : max_value_(max_value), field_name_(field_name) {}
86 15425 : uint8_t* buffer() override { return byte_buffer_; }
87 9369 : size_t size() const override { return kMaxVarInt32Size; }
88 :
89 : size_t ReadBytes(StreamingDecoder* streaming,
90 : Vector<const uint8_t> bytes) override;
91 :
92 : std::unique_ptr<DecodingState> Next(StreamingDecoder* streaming) override;
93 :
94 : virtual std::unique_ptr<DecodingState> NextWithValue(
95 : StreamingDecoder* streaming) = 0;
96 :
97 : size_t value() const { return value_; }
98 : size_t bytes_needed() const { return bytes_needed_; }
99 :
100 : private:
101 : uint8_t byte_buffer_[kMaxVarInt32Size];
102 : // The maximum valid value decoded in this state. {Next} returns an error if
103 : // this value is exceeded.
104 : size_t max_value_;
105 : const char* field_name_;
106 : size_t value_ = 0;
107 : size_t bytes_needed_ = 0;
108 : };
109 :
110 4422 : class StreamingDecoder::DecodeModuleHeader : public DecodingState {
111 : public:
112 5695 : size_t size() const override { return kModuleHeaderSize; }
113 3563 : uint8_t* buffer() override { return byte_buffer_; }
114 :
115 : std::unique_ptr<DecodingState> Next(StreamingDecoder* streaming) override;
116 :
117 : private:
118 : // Checks if the magic bytes of the module header are correct.
119 : void CheckHeader(Decoder* decoder);
120 :
121 : // The size of the module header.
122 : static constexpr size_t kModuleHeaderSize = 8;
123 : uint8_t byte_buffer_[kModuleHeaderSize];
124 : };
125 :
126 4092 : class StreamingDecoder::DecodeSectionID : public DecodingState {
127 : public:
128 : explicit DecodeSectionID(uint32_t module_offset)
129 2046 : : module_offset_(module_offset) {}
130 :
131 3344 : size_t size() const override { return 1; }
132 1672 : uint8_t* buffer() override { return &id_; }
133 344 : bool is_finishing_allowed() const override { return true; }
134 :
135 : uint8_t id() const { return id_; }
136 :
137 : uint32_t module_offset() const { return module_offset_; }
138 :
139 : std::unique_ptr<DecodingState> Next(StreamingDecoder* streaming) override;
140 :
141 : private:
142 : uint8_t id_ = 0;
143 : // The start offset of this section in the module.
144 : uint32_t module_offset_;
145 : };
146 :
147 3344 : class StreamingDecoder::DecodeSectionLength : public DecodeVarInt32 {
148 : public:
149 : explicit DecodeSectionLength(uint8_t id, uint32_t module_offset)
150 : : DecodeVarInt32(kV8MaxWasmModuleSize, "section length"),
151 : section_id_(id),
152 1672 : module_offset_(module_offset) {}
153 :
154 : uint8_t section_id() const { return section_id_; }
155 :
156 : uint32_t module_offset() const { return module_offset_; }
157 :
158 : std::unique_ptr<DecodingState> NextWithValue(
159 : StreamingDecoder* streaming) override;
160 :
161 : private:
162 : uint8_t section_id_;
163 : // The start offset of this section in the module.
164 : uint32_t module_offset_;
165 : };
166 :
167 1980 : class StreamingDecoder::DecodeSectionPayload : public DecodingState {
168 : public:
169 : explicit DecodeSectionPayload(SectionBuffer* section_buffer)
170 990 : : section_buffer_(section_buffer) {}
171 :
172 4208 : size_t size() const override { return section_buffer_->payload_length(); }
173 1052 : uint8_t* buffer() override {
174 2104 : return section_buffer_->bytes() + section_buffer_->payload_offset();
175 : }
176 :
177 : std::unique_ptr<DecodingState> Next(StreamingDecoder* streaming) override;
178 :
179 : SectionBuffer* section_buffer() const { return section_buffer_; }
180 :
181 : private:
182 : SectionBuffer* section_buffer_;
183 : };
184 :
185 1056 : class StreamingDecoder::DecodeNumberOfFunctions : public DecodeVarInt32 {
186 : public:
187 : explicit DecodeNumberOfFunctions(SectionBuffer* section_buffer)
188 : : DecodeVarInt32(kV8MaxWasmFunctions, "functions count"),
189 528 : section_buffer_(section_buffer) {}
190 :
191 : SectionBuffer* section_buffer() const { return section_buffer_; }
192 :
193 : std::unique_ptr<DecodingState> NextWithValue(
194 : StreamingDecoder* streaming) override;
195 :
196 : private:
197 : SectionBuffer* section_buffer_;
198 : };
199 :
200 1900 : class StreamingDecoder::DecodeFunctionLength : public DecodeVarInt32 {
201 : public:
202 : explicit DecodeFunctionLength(SectionBuffer* section_buffer,
203 : size_t buffer_offset,
204 : size_t num_remaining_functions)
205 : : DecodeVarInt32(kV8MaxWasmFunctionSize, "body size"),
206 : section_buffer_(section_buffer),
207 : buffer_offset_(buffer_offset),
208 : // We are reading a new function, so one function less is remaining.
209 950 : num_remaining_functions_(num_remaining_functions - 1) {
210 : DCHECK_GT(num_remaining_functions, 0);
211 : }
212 :
213 : size_t num_remaining_functions() const { return num_remaining_functions_; }
214 : size_t buffer_offset() const { return buffer_offset_; }
215 : SectionBuffer* section_buffer() const { return section_buffer_; }
216 :
217 : std::unique_ptr<DecodingState> NextWithValue(
218 : StreamingDecoder* streaming) override;
219 :
220 : private:
221 : SectionBuffer* section_buffer_;
222 : size_t buffer_offset_;
223 : size_t num_remaining_functions_;
224 : };
225 :
226 1582 : class StreamingDecoder::DecodeFunctionBody : public DecodingState {
227 : public:
228 : explicit DecodeFunctionBody(SectionBuffer* section_buffer,
229 : size_t buffer_offset, size_t function_length,
230 : size_t num_remaining_functions,
231 : uint32_t module_offset)
232 : : section_buffer_(section_buffer),
233 : buffer_offset_(buffer_offset),
234 : size_(function_length),
235 : num_remaining_functions_(num_remaining_functions),
236 791 : module_offset_(module_offset) {}
237 :
238 : size_t buffer_offset() const { return buffer_offset_; }
239 3246 : size_t size() const override { return size_; }
240 1623 : uint8_t* buffer() override {
241 3246 : return section_buffer_->bytes() + buffer_offset_;
242 : }
243 : size_t num_remaining_functions() const { return num_remaining_functions_; }
244 : uint32_t module_offset() const { return module_offset_; }
245 : SectionBuffer* section_buffer() const { return section_buffer_; }
246 :
247 : std::unique_ptr<DecodingState> Next(StreamingDecoder* streaming) override;
248 :
249 : private:
250 : SectionBuffer* section_buffer_;
251 : size_t buffer_offset_;
252 : size_t size_;
253 : size_t num_remaining_functions_;
254 : uint32_t module_offset_;
255 : };
256 :
257 3123 : size_t StreamingDecoder::DecodeVarInt32::ReadBytes(
258 3123 : StreamingDecoder* streaming, Vector<const uint8_t> bytes) {
259 18808 : size_t bytes_read = std::min(bytes.size(), remaining());
260 6246 : memcpy(buffer() + offset(), &bytes.first(), bytes_read);
261 6246 : Decoder decoder(buffer(), buffer() + offset() + bytes_read,
262 : streaming->module_offset());
263 6246 : value_ = decoder.consume_u32v(field_name_);
264 : // The number of bytes we actually needed to read.
265 : DCHECK_GT(decoder.pc(), buffer());
266 3123 : bytes_needed_ = static_cast<size_t>(decoder.pc() - buffer());
267 :
268 3123 : if (decoder.failed()) {
269 70 : if (offset() + bytes_read == size()) {
270 : // We only report an error if we read all bytes.
271 225 : streaming->Error(decoder.toResult(nullptr));
272 : }
273 70 : set_offset(offset() + bytes_read);
274 70 : return bytes_read;
275 : } else {
276 : DCHECK_GT(bytes_needed_, offset());
277 3053 : size_t result = bytes_needed_ - offset();
278 : // We read all the bytes we needed.
279 3053 : set_offset(size());
280 3053 : return result;
281 : }
282 : }
283 :
284 : std::unique_ptr<StreamingDecoder::DecodingState>
285 6199 : StreamingDecoder::DecodeVarInt32::Next(StreamingDecoder* streaming) {
286 3098 : if (!streaming->ok()) {
287 : return nullptr;
288 : }
289 3053 : if (value() > max_value_) {
290 48 : std::ostringstream oss;
291 96 : oss << "function size > maximum function size: " << value() << " < "
292 48 : << max_value_;
293 96 : return streaming->Error(oss.str());
294 : }
295 :
296 3005 : return NextWithValue(streaming);
297 : }
298 :
299 : std::unique_ptr<StreamingDecoder::DecodingState>
300 3697 : StreamingDecoder::DecodeModuleHeader::Next(StreamingDecoder* streaming) {
301 1431 : streaming->ProcessModuleHeader();
302 1431 : if (streaming->ok()) {
303 1670 : return base::make_unique<DecodeSectionID>(streaming->module_offset());
304 : }
305 : return nullptr;
306 : }
307 :
308 : std::unique_ptr<StreamingDecoder::DecodingState>
309 3344 : StreamingDecoder::DecodeSectionID::Next(StreamingDecoder* streaming) {
310 5016 : return base::make_unique<DecodeSectionLength>(id(), module_offset());
311 : }
312 :
313 : std::unique_ptr<StreamingDecoder::DecodingState>
314 1619 : StreamingDecoder::DecodeSectionLength::NextWithValue(
315 4888 : StreamingDecoder* streaming) {
316 : SectionBuffer* buf = streaming->CreateNewBuffer(
317 : module_offset(), section_id(), value(),
318 8052 : Vector<const uint8_t>(buffer(), static_cast<int>(bytes_needed())));
319 1619 : if (!buf) return nullptr;
320 1576 : if (value() == 0) {
321 58 : if (section_id() == SectionCode::kCodeSectionCode) {
322 42 : return streaming->Error("Code section cannot have size 0");
323 : } else {
324 37 : streaming->ProcessSection(buf);
325 37 : if (streaming->ok()) {
326 : // There is no payload, we go to the next section immediately.
327 74 : return base::make_unique<DecodeSectionID>(streaming->module_offset());
328 : } else {
329 : return nullptr;
330 : }
331 : }
332 : } else {
333 1518 : if (section_id() == SectionCode::kCodeSectionCode) {
334 : // We reached the code section. All functions of the code section are put
335 : // into the same SectionBuffer.
336 1056 : return base::make_unique<DecodeNumberOfFunctions>(buf);
337 : } else {
338 : return base::make_unique<DecodeSectionPayload>(buf);
339 : }
340 : }
341 : }
342 :
343 : std::unique_ptr<StreamingDecoder::DecodingState>
344 2822 : StreamingDecoder::DecodeSectionPayload::Next(StreamingDecoder* streaming) {
345 950 : streaming->ProcessSection(section_buffer());
346 950 : if (streaming->ok()) {
347 1844 : return base::make_unique<DecodeSectionID>(streaming->module_offset());
348 : }
349 : return nullptr;
350 : }
351 :
352 : std::unique_ptr<StreamingDecoder::DecodingState>
353 508 : StreamingDecoder::DecodeNumberOfFunctions::NextWithValue(
354 952 : StreamingDecoder* streaming) {
355 : // Copy the bytes we read into the section buffer.
356 2920 : if (section_buffer_->payload_length() >= bytes_needed()) {
357 968 : memcpy(section_buffer_->bytes() + section_buffer_->payload_offset(),
358 484 : buffer(), bytes_needed());
359 : } else {
360 48 : return streaming->Error("Invalid code section length");
361 : }
362 :
363 : // {value} is the number of functions.
364 484 : if (value() > 0) {
365 484 : streaming->StartCodeSection(value());
366 484 : if (!streaming->ok()) return nullptr;
367 : return base::make_unique<DecodeFunctionLength>(
368 936 : section_buffer(), section_buffer()->payload_offset() + bytes_needed(),
369 1404 : value());
370 : } else {
371 0 : return base::make_unique<DecodeSectionID>(streaming->module_offset());
372 : }
373 : }
374 :
375 : std::unique_ptr<StreamingDecoder::DecodingState>
376 878 : StreamingDecoder::DecodeFunctionLength::NextWithValue(
377 3196 : StreamingDecoder* streaming) {
378 : // Copy the bytes we read into the section buffer.
379 2515 : if (section_buffer_->length() >= buffer_offset_ + bytes_needed()) {
380 1660 : memcpy(section_buffer_->bytes() + buffer_offset_, buffer(), bytes_needed());
381 : } else {
382 96 : return streaming->Error("Invalid code section length");
383 : }
384 :
385 : // {value} is the length of the function.
386 830 : if (value() == 0) {
387 46 : return streaming->Error("Invalid function length (0)");
388 1614 : } else if (buffer_offset() + bytes_needed() + value() >
389 807 : section_buffer()->length()) {
390 48 : streaming->Error("not enough code section bytes");
391 : return nullptr;
392 : }
393 :
394 : return base::make_unique<DecodeFunctionBody>(
395 : section_buffer(), buffer_offset() + bytes_needed(), value(),
396 2373 : num_remaining_functions(), streaming->module_offset());
397 : }
398 :
399 : std::unique_ptr<StreamingDecoder::DecodingState>
400 4207 : StreamingDecoder::DecodeFunctionBody::Next(StreamingDecoder* streaming) {
401 : streaming->ProcessFunctionBody(
402 1582 : Vector<const uint8_t>(buffer(), static_cast<int>(size())),
403 791 : module_offset());
404 791 : if (!streaming->ok()) {
405 : return nullptr;
406 : }
407 791 : if (num_remaining_functions() != 0) {
408 : return base::make_unique<DecodeFunctionLength>(
409 1928 : section_buffer(), buffer_offset() + size(), num_remaining_functions());
410 : } else {
411 618 : if (buffer_offset() + size() != section_buffer()->length()) {
412 114 : return streaming->Error("not all code section bytes were used");
413 : }
414 504 : return base::make_unique<DecodeSectionID>(streaming->module_offset());
415 : }
416 : }
417 :
418 1474 : StreamingDecoder::StreamingDecoder(
419 : std::unique_ptr<StreamingProcessor> processor)
420 : : processor_(std::move(processor)),
421 : // A module always starts with a module header.
422 2948 : state_(new DecodeModuleHeader()) {}
423 : } // namespace wasm
424 : } // namespace internal
425 : } // namespace v8
|