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/local-decl-encoder.h"
6
7 #include "src/base/platform/wrappers.h"
8 #include "src/codegen/signature.h"
9 #include "src/wasm/leb-helper.h"
10
11 namespace v8 {
12 namespace internal {
13 namespace wasm {
14
15 // This struct is just a type tag for Zone::NewArray<T>(size_t) call.
16 struct LocalDeclEncoderBuffer {};
17
Prepend(Zone * zone,const byte ** start,const byte ** end) const18 void LocalDeclEncoder::Prepend(Zone* zone, const byte** start,
19 const byte** end) const {
20 size_t size = (*end - *start);
21 byte* buffer = zone->NewArray<byte, LocalDeclEncoderBuffer>(Size() + size);
22 size_t pos = Emit(buffer);
23 if (size > 0) {
24 memcpy(buffer + pos, *start, size);
25 }
26 pos += size;
27 *start = buffer;
28 *end = buffer + pos;
29 }
30
Emit(byte * buffer) const31 size_t LocalDeclEncoder::Emit(byte* buffer) const {
32 byte* pos = buffer;
33 LEBHelper::write_u32v(&pos, static_cast<uint32_t>(local_decls.size()));
34 for (auto& local_decl : local_decls) {
35 uint32_t locals_count = local_decl.first;
36 ValueType locals_type = local_decl.second;
37 LEBHelper::write_u32v(&pos, locals_count);
38 *pos = locals_type.value_type_code();
39 ++pos;
40 if (locals_type.is_rtt()) {
41 LEBHelper::write_u32v(&pos, locals_type.ref_index());
42 }
43 if (locals_type.encoding_needs_heap_type()) {
44 LEBHelper::write_i32v(&pos, locals_type.heap_type().code());
45 }
46 }
47 DCHECK_EQ(Size(), pos - buffer);
48 return static_cast<size_t>(pos - buffer);
49 }
50
AddLocals(uint32_t count,ValueType type)51 uint32_t LocalDeclEncoder::AddLocals(uint32_t count, ValueType type) {
52 uint32_t result =
53 static_cast<uint32_t>(total + (sig ? sig->parameter_count() : 0));
54 total += count;
55 if (local_decls.size() > 0 && local_decls.back().second == type) {
56 count += local_decls.back().first;
57 local_decls.pop_back();
58 }
59 local_decls.push_back(std::pair<uint32_t, ValueType>(count, type));
60 return result;
61 }
62
63 // Size = (size of locals count) +
64 // (for each local pair <reps, type>, (size of reps) + (size of type))
Size() const65 size_t LocalDeclEncoder::Size() const {
66 size_t size = LEBHelper::sizeof_u32v(local_decls.size());
67 for (auto p : local_decls) {
68 size +=
69 LEBHelper::sizeof_u32v(p.first) + // number of locals
70 1 + // Opcode
71 (p.second.encoding_needs_heap_type()
72 ? LEBHelper::sizeof_i32v(p.second.heap_type().code())
73 : 0) +
74 (p.second.is_rtt() ? LEBHelper::sizeof_u32v(p.second.ref_index()) : 0);
75 }
76 return size;
77 }
78
79 } // namespace wasm
80 } // namespace internal
81 } // namespace v8
82