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 11namespace v8 { 12namespace internal { 13namespace wasm { 14 15// This struct is just a type tag for Zone::NewArray<T>(size_t) call. 16struct LocalDeclEncoderBuffer {}; 17 18void 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 31size_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 51uint32_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)) 65size_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