• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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