5 #include "src/wasm/streaming-decoder.h" 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-code-manager.h" 16 #include "src/wasm/wasm-limits.h" 17 #include "src/wasm/wasm-objects.h" 18 #include "src/wasm/wasm-result.h" 20 #define TRACE_STREAMING(...) \ 22 if (FLAG_trace_wasm_streaming) PrintF(__VA_ARGS__); \ 29 void StreamingDecoder::OnBytesReceived(Vector<const uint8_t> bytes) {
30 if (deserializing()) {
31 wire_bytes_for_deserializing_.insert(wire_bytes_for_deserializing_.end(),
32 bytes.begin(), bytes.end());
36 TRACE_STREAMING(
"OnBytesReceived(%zu bytes)\n", bytes.size());
39 while (ok() && current < bytes.size()) {
41 state_->ReadBytes(
this, bytes.SubVector(current, bytes.size()));
43 module_offset_ += num_bytes;
44 if (state_->offset() == state_->buffer().size()) {
45 state_ = state_->Next(
this);
48 total_size_ += bytes.size();
50 processor_->OnFinishedChunk();
54 size_t StreamingDecoder::DecodingState::ReadBytes(StreamingDecoder* streaming,
55 Vector<const uint8_t> bytes) {
56 Vector<uint8_t> remaining_buf = buffer() + offset();
57 size_t num_bytes = std::min(bytes.size(), remaining_buf.size());
58 TRACE_STREAMING(
"ReadBytes(%zu bytes)\n", num_bytes);
59 memcpy(remaining_buf.start(), &bytes.first(), num_bytes);
60 set_offset(offset() + num_bytes);
64 void StreamingDecoder::Finish() {
65 TRACE_STREAMING(
"Finish\n");
68 if (deserializing()) {
69 Vector<const uint8_t> wire_bytes = VectorOf(wire_bytes_for_deserializing_);
71 if (processor_->Deserialize(compiled_module_bytes_, wire_bytes))
return;
74 compiled_module_bytes_ = {};
75 DCHECK(!deserializing());
76 OnBytesReceived(wire_bytes);
80 if (!state_->is_finishing_allowed()) {
82 Error(
"unexpected end of stream");
86 OwnedVector<uint8_t> bytes = OwnedVector<uint8_t>::New(total_size_);
87 uint8_t* cursor = bytes.start();
89 #define BYTES(x) (x & 0xFF), (x >> 8) & 0xFF, (x >> 16) & 0xFF, (x >> 24) & 0xFF 90 uint8_t module_header[]{BYTES(kWasmMagic), BYTES(kWasmVersion)};
92 memcpy(cursor, module_header, arraysize(module_header));
93 cursor += arraysize(module_header);
95 for (
const auto& buffer : section_buffers_) {
96 DCHECK_LE(cursor - bytes.start() + buffer->length(), total_size_);
97 memcpy(cursor, buffer->bytes().start(), buffer->length());
98 cursor += buffer->length();
100 processor_->OnFinishedStream(std::move(bytes));
103 void StreamingDecoder::Abort() {
104 TRACE_STREAMING(
"Abort\n");
106 processor_->OnAbort();
110 void StreamingDecoder::SetModuleCompiledCallback(
111 ModuleCompiledCallback callback) {
112 DCHECK_NULL(module_compiled_callback_);
113 module_compiled_callback_ = callback;
116 bool StreamingDecoder::SetCompiledModuleBytes(
117 Vector<const uint8_t> compiled_module_bytes) {
118 compiled_module_bytes_ = compiled_module_bytes;
128 : max_value_(max_value), field_name_(field_name) {}
130 Vector<uint8_t> buffer()
override {
return ArrayVector(byte_buffer_); }
137 virtual std::unique_ptr<DecodingState> NextWithValue(
141 uint8_t byte_buffer_[kMaxVarInt32Size];
144 const size_t max_value_;
145 const char*
const field_name_;
147 size_t bytes_consumed_ = 0;
152 Vector<uint8_t> buffer()
override {
return ArrayVector(byte_buffer_); }
158 void CheckHeader(
Decoder* decoder);
161 static constexpr
size_t kModuleHeaderSize = 8;
162 uint8_t byte_buffer_[kModuleHeaderSize];
168 : module_offset_(module_offset) {}
171 bool is_finishing_allowed()
const override {
return true; }
186 module_offset_(module_offset) {}
188 std::unique_ptr<DecodingState> NextWithValue(
192 const uint8_t section_id_;
200 : section_buffer_(section_buffer) {}
202 Vector<uint8_t> buffer()
override {
return section_buffer_->payload(); }
207 SectionBuffer*
const section_buffer_;
214 section_buffer_(section_buffer) {}
216 std::unique_ptr<DecodingState> NextWithValue(
220 SectionBuffer*
const section_buffer_;
226 size_t buffer_offset,
227 size_t num_remaining_functions)
229 section_buffer_(section_buffer),
230 buffer_offset_(buffer_offset),
232 num_remaining_functions_(num_remaining_functions - 1) {
233 DCHECK_GT(num_remaining_functions, 0);
236 std::unique_ptr<DecodingState> NextWithValue(
240 SectionBuffer*
const section_buffer_;
241 const size_t buffer_offset_;
242 const size_t num_remaining_functions_;
248 size_t buffer_offset,
size_t function_body_length,
249 size_t num_remaining_functions,
251 : section_buffer_(section_buffer),
252 buffer_offset_(buffer_offset),
253 function_body_length_(function_body_length),
254 num_remaining_functions_(num_remaining_functions),
255 module_offset_(module_offset) {}
259 section_buffer_->bytes() + buffer_offset_;
260 return remaining_buffer.SubVector(0, function_body_length_);
266 SectionBuffer*
const section_buffer_;
267 const size_t buffer_offset_;
268 const size_t function_body_length_;
269 const size_t num_remaining_functions_;
273 size_t StreamingDecoder::DecodeVarInt32::ReadBytes(
277 size_t new_bytes = std::min(bytes.size(), remaining_buf.size());
278 TRACE_STREAMING(
"ReadBytes of a VarInt\n");
279 memcpy(remaining_buf.start(), &bytes.first(), new_bytes);
280 buf.Truncate(offset() + new_bytes);
281 Decoder decoder(buf, streaming->module_offset());
282 value_ = decoder.consume_u32v(field_name_);
284 DCHECK_GT(decoder.pc(), buffer().start());
285 bytes_consumed_ =
static_cast<size_t>(decoder.pc() - buf.start());
286 TRACE_STREAMING(
" ==> %zu bytes consumed\n", bytes_consumed_);
288 if (decoder.failed()) {
289 if (new_bytes == remaining_buf.size()) {
291 streaming->Error(decoder.toResult(
nullptr));
293 set_offset(offset() + new_bytes);
298 DCHECK_GT(bytes_consumed_, offset());
299 new_bytes = bytes_consumed_ - offset();
302 set_offset(buffer().size());
306 std::unique_ptr<StreamingDecoder::DecodingState>
307 StreamingDecoder::DecodeVarInt32::Next(StreamingDecoder* streaming) {
308 if (!streaming->ok())
return nullptr;
310 if (value_ > max_value_) {
311 std::ostringstream oss;
312 oss <<
"function size > maximum function size: " << value_ <<
" < " 314 return streaming->Error(oss.str());
317 return NextWithValue(streaming);
320 std::unique_ptr<StreamingDecoder::DecodingState>
321 StreamingDecoder::DecodeModuleHeader::Next(StreamingDecoder* streaming) {
322 TRACE_STREAMING(
"DecodeModuleHeader\n");
323 streaming->ProcessModuleHeader();
324 if (!streaming->ok())
return nullptr;
325 return base::make_unique<DecodeSectionID>(streaming->module_offset());
328 std::unique_ptr<StreamingDecoder::DecodingState>
329 StreamingDecoder::DecodeSectionID::Next(StreamingDecoder* streaming) {
330 TRACE_STREAMING(
"DecodeSectionID: %s section\n",
331 SectionName(static_cast<SectionCode>(id_)));
332 return base::make_unique<DecodeSectionLength>(id_, module_offset_);
335 std::unique_ptr<StreamingDecoder::DecodingState>
336 StreamingDecoder::DecodeSectionLength::NextWithValue(
337 StreamingDecoder* streaming) {
338 TRACE_STREAMING(
"DecodeSectionLength(%zu)\n", value_);
340 streaming->CreateNewBuffer(module_offset_, section_id_, value_,
341 buffer().SubVector(0, bytes_consumed_));
342 if (!buf)
return nullptr;
344 if (section_id_ == SectionCode::kCodeSectionCode) {
345 return streaming->Error(
"Code section cannot have size 0");
347 streaming->ProcessSection(buf);
348 if (!streaming->ok())
return nullptr;
350 return base::make_unique<DecodeSectionID>(streaming->module_offset_);
352 if (section_id_ == SectionCode::kCodeSectionCode) {
355 return base::make_unique<DecodeNumberOfFunctions>(buf);
357 return base::make_unique<DecodeSectionPayload>(buf);
361 std::unique_ptr<StreamingDecoder::DecodingState>
362 StreamingDecoder::DecodeSectionPayload::Next(StreamingDecoder* streaming) {
363 TRACE_STREAMING(
"DecodeSectionPayload\n");
364 streaming->ProcessSection(section_buffer_);
365 if (!streaming->ok())
return nullptr;
366 return base::make_unique<DecodeSectionID>(streaming->module_offset());
369 std::unique_ptr<StreamingDecoder::DecodingState>
370 StreamingDecoder::DecodeNumberOfFunctions::NextWithValue(
371 StreamingDecoder* streaming) {
372 TRACE_STREAMING(
"DecodeNumberOfFunctions(%zu)\n", value_);
374 Vector<uint8_t> payload_buf = section_buffer_->payload();
375 if (payload_buf.size() < bytes_consumed_) {
376 return streaming->Error(
"Invalid code section length");
378 memcpy(payload_buf.start(), buffer().start(), bytes_consumed_);
382 if (payload_buf.size() != bytes_consumed_) {
383 return streaming->Error(
"not all code section bytes were consumed");
385 return base::make_unique<DecodeSectionID>(streaming->module_offset());
388 streaming->StartCodeSection(value_, streaming->section_buffers_.back());
389 if (!streaming->ok())
return nullptr;
390 return base::make_unique<DecodeFunctionLength>(
391 section_buffer_, section_buffer_->payload_offset() + bytes_consumed_,
395 std::unique_ptr<StreamingDecoder::DecodingState>
396 StreamingDecoder::DecodeFunctionLength::NextWithValue(
397 StreamingDecoder* streaming) {
398 TRACE_STREAMING(
"DecodeFunctionLength(%zu)\n", value_);
400 Vector<uint8_t> fun_length_buffer = section_buffer_->bytes() + buffer_offset_;
401 if (fun_length_buffer.size() < bytes_consumed_) {
402 return streaming->Error(
"Invalid code section length");
404 memcpy(fun_length_buffer.start(), buffer().start(), bytes_consumed_);
407 if (value_ == 0)
return streaming->Error(
"Invalid function length (0)");
409 if (buffer_offset_ + bytes_consumed_ + value_ > section_buffer_->length()) {
410 return streaming->Error(
"not enough code section bytes");
413 return base::make_unique<DecodeFunctionBody>(
414 section_buffer_, buffer_offset_ + bytes_consumed_, value_,
415 num_remaining_functions_, streaming->module_offset());
418 std::unique_ptr<StreamingDecoder::DecodingState>
419 StreamingDecoder::DecodeFunctionBody::Next(StreamingDecoder* streaming) {
420 TRACE_STREAMING(
"DecodeFunctionBody\n");
421 streaming->ProcessFunctionBody(buffer(), module_offset_);
422 if (!streaming->ok())
return nullptr;
424 size_t end_offset = buffer_offset_ + function_body_length_;
425 if (num_remaining_functions_ > 0) {
426 return base::make_unique<DecodeFunctionLength>(section_buffer_, end_offset,
427 num_remaining_functions_);
430 if (end_offset != section_buffer_->length()) {
431 return streaming->Error(
"not all code section bytes were used");
433 return base::make_unique<DecodeSectionID>(streaming->module_offset());
436 StreamingDecoder::StreamingDecoder(
437 std::unique_ptr<StreamingProcessor> processor)
438 : processor_(
std::move(processor)),
440 state_(new DecodeModuleHeader()) {}
442 StreamingDecoder::SectionBuffer* StreamingDecoder::CreateNewBuffer(
443 uint32_t module_offset, uint8_t section_id,
size_t length,
444 Vector<const uint8_t> length_bytes) {
446 if (section_id != kUnknownSectionCode) {
447 if (section_id < next_section_id_) {
448 Error(
"Unexpected section");
451 next_section_id_ = section_id + 1;
453 section_buffers_.emplace_back(std::make_shared<SectionBuffer>(
454 module_offset, section_id, length, length_bytes));
455 return section_buffers_.back().get();
462 #undef TRACE_STREAMING