| Index: src/wasm/encoder.cc
|
| diff --git a/src/wasm/encoder.cc b/src/wasm/encoder.cc
|
| index a95171d0ae54b9ea6a7ac5ee8f70180252815036..2128505ac7dd9e9160dc2b268283ec53773f1ca3 100644
|
| --- a/src/wasm/encoder.cc
|
| +++ b/src/wasm/encoder.cc
|
| @@ -10,6 +10,7 @@
|
|
|
| #include "src/wasm/ast-decoder.h"
|
| #include "src/wasm/encoder.h"
|
| +#include "src/wasm/leb-helper.h"
|
| #include "src/wasm/wasm-macro-gen.h"
|
| #include "src/wasm/wasm-module.h"
|
| #include "src/wasm/wasm-opcodes.h"
|
| @@ -50,37 +51,18 @@ void EmitUint32(byte** b, uint32_t x) {
|
| *b += 4;
|
| }
|
|
|
| +void EmitVarInt(byte** b, size_t val) {
|
| + LEBHelper::write_u32v(b, static_cast<uint32_t>(val));
|
| +}
|
| +
|
| // Sections all start with a size, but it's unknown at the start.
|
| // We generate a large varint which we then fixup later when the size is known.
|
| //
|
| // TODO(jfb) Not strictly necessary since sizes are calculated ahead of time.
|
| const size_t padded_varint = 5;
|
|
|
| -void EmitVarInt(byte** b, size_t val) {
|
| - while (true) {
|
| - size_t next = val >> 7;
|
| - byte out = static_cast<byte>(val & 0x7f);
|
| - if (next) {
|
| - *((*b)++) = 0x80 | out;
|
| - val = next;
|
| - } else {
|
| - *((*b)++) = out;
|
| - break;
|
| - }
|
| - }
|
| -}
|
| -
|
| -size_t SizeOfVarInt(size_t value) {
|
| - size_t size = 0;
|
| - do {
|
| - size++;
|
| - value = value >> 7;
|
| - } while (value > 0);
|
| - return size;
|
| -}
|
| -
|
| void FixupSection(byte* start, byte* end) {
|
| - // Same as EmitVarInt, but fixed-width with zeroes in the MSBs.
|
| + // Same as LEBHelper::write_u32v, but fixed-width with zeroes in the MSBs.
|
| size_t val = end - start - padded_varint;
|
| TRACE(" fixup %u\n", (unsigned)val);
|
| for (size_t pos = 0; pos != padded_varint; ++pos) {
|
| @@ -126,6 +108,14 @@ WasmFunctionBuilder::WasmFunctionBuilder(Zone* zone)
|
| local_indices_(zone),
|
| name_(zone) {}
|
|
|
| +void WasmFunctionBuilder::EmitVarInt(uint32_t val) {
|
| + byte buffer[8];
|
| + byte* ptr = buffer;
|
| + LEBHelper::write_u32v(&ptr, val);
|
| + for (byte* p = buffer; p < ptr; p++) {
|
| + body_.push_back(*p);
|
| + }
|
| +}
|
|
|
| uint16_t WasmFunctionBuilder::AddParam(LocalType type) {
|
| return AddVar(type, true);
|
| @@ -193,10 +183,7 @@ void WasmFunctionBuilder::EmitWithU8U8(WasmOpcode opcode, const byte imm1,
|
| void WasmFunctionBuilder::EmitWithVarInt(WasmOpcode opcode,
|
| uint32_t immediate) {
|
| body_.push_back(static_cast<byte>(opcode));
|
| - size_t immediate_size = SizeOfVarInt(immediate);
|
| - body_.insert(body_.end(), immediate_size, 0);
|
| - byte* p = &body_[body_.size() - immediate_size];
|
| - EmitVarInt(&p, immediate);
|
| + EmitVarInt(immediate);
|
| }
|
|
|
| uint32_t WasmFunctionBuilder::EmitEditableVarIntImmediate() {
|
| @@ -208,7 +195,8 @@ uint32_t WasmFunctionBuilder::EmitEditableVarIntImmediate() {
|
|
|
| void WasmFunctionBuilder::EditVarIntImmediate(uint32_t offset,
|
| const uint32_t immediate) {
|
| - uint32_t immediate_size = static_cast<uint32_t>(SizeOfVarInt(immediate));
|
| + uint32_t immediate_size =
|
| + static_cast<uint32_t>(LEBHelper::sizeof_u32v(immediate));
|
| // In EmitEditableVarIntImmediate, we guessed that we'd only need one byte.
|
| // If we need more, shift everything down to make room for the larger
|
| // immediate.
|
| @@ -224,7 +212,7 @@ void WasmFunctionBuilder::EditVarIntImmediate(uint32_t offset,
|
| }
|
| DCHECK(offset + immediate_size <= body_.size());
|
| byte* p = &body_[offset];
|
| - EmitVarInt(&p, immediate);
|
| + v8::internal::wasm::EmitVarInt(&p, immediate);
|
| }
|
|
|
|
|
| @@ -252,20 +240,28 @@ WasmFunctionEncoder* WasmFunctionBuilder::Build(Zone* zone,
|
| if (body_.size() > 0) {
|
| // TODO(titzer): iterate over local indexes, not the bytes.
|
| const byte* start = &body_[0];
|
| - const byte* end = start + body_.size();
|
| size_t local_index = 0;
|
| for (size_t i = 0; i < body_.size();) {
|
| if (local_index < local_indices_.size() &&
|
| i == local_indices_[local_index]) {
|
| - int length = 0;
|
| - uint32_t index;
|
| - ReadUnsignedLEB128Operand(start + i, end, &length, &index);
|
| + // Read the old index.
|
| + uint32_t index = 0;
|
| + uint8_t b = 0;
|
| + uint32_t shift = 0;
|
| + while ((b = start[i++]) >= 0x80) {
|
| + index |= (b & 0x7F) << shift;
|
| + shift += 7;
|
| + }
|
| + index |= b << shift;
|
| +
|
| + // Write the new index.
|
| uint16_t new_index = var_index[index];
|
| - const std::vector<uint8_t>& index_vec = UnsignedLEB128From(new_index);
|
| - for (size_t j = 0; j < index_vec.size(); j++) {
|
| - e->body_.push_back(index_vec.at(j));
|
| + while (new_index >= 0x80) {
|
| + e->body_.push_back(new_index | 0x80);
|
| + new_index >>= 7;
|
| }
|
| - i += length;
|
| + e->body_.push_back(new_index);
|
| +
|
| local_index++;
|
| } else {
|
| e->body_.push_back(*(start + i));
|
| @@ -347,7 +343,8 @@ uint32_t WasmFunctionEncoder::HeaderSize() const {
|
| if (!external_) size += 2;
|
| if (HasName()) {
|
| uint32_t name_size = NameSize();
|
| - size += static_cast<uint32_t>(SizeOfVarInt(name_size)) + name_size;
|
| + size +=
|
| + static_cast<uint32_t>(LEBHelper::sizeof_u32v(name_size)) + name_size;
|
| }
|
| return size;
|
| }
|
| @@ -551,10 +548,11 @@ struct Sizes {
|
| }
|
|
|
| void AddSection(WasmSection::Code code, size_t other_size) {
|
| - Add(padded_varint + SizeOfVarInt(WasmSection::getNameLength(code)) +
|
| + Add(padded_varint +
|
| + LEBHelper::sizeof_u32v(WasmSection::getNameLength(code)) +
|
| WasmSection::getNameLength(code),
|
| 0);
|
| - if (other_size) Add(SizeOfVarInt(other_size), 0);
|
| + if (other_size) Add(LEBHelper::sizeof_u32v(other_size), 0);
|
| }
|
| };
|
|
|
| @@ -579,8 +577,9 @@ WasmModuleIndex* WasmModuleWriter::WriteTo(Zone* zone) const {
|
| if (signatures_.size() > 0) {
|
| sizes.AddSection(WasmSection::Code::Signatures, signatures_.size());
|
| for (auto sig : signatures_) {
|
| - sizes.Add(
|
| - 1 + SizeOfVarInt(sig->parameter_count()) + sig->parameter_count(), 0);
|
| + sizes.Add(1 + LEBHelper::sizeof_u32v(sig->parameter_count()) +
|
| + sig->parameter_count(),
|
| + 0);
|
| }
|
| TRACE("Size after signatures: %u, %u\n", (unsigned)sizes.header_size,
|
| (unsigned)sizes.body_size);
|
| @@ -598,7 +597,7 @@ WasmModuleIndex* WasmModuleWriter::WriteTo(Zone* zone) const {
|
|
|
| if (start_function_index_ >= 0) {
|
| sizes.AddSection(WasmSection::Code::StartFunction, 0);
|
| - sizes.Add(SizeOfVarInt(start_function_index_), 0);
|
| + sizes.Add(LEBHelper::sizeof_u32v(start_function_index_), 0);
|
| TRACE("Size after start: %u, %u\n", (unsigned)sizes.header_size,
|
| (unsigned)sizes.body_size);
|
| }
|
| @@ -616,7 +615,7 @@ WasmModuleIndex* WasmModuleWriter::WriteTo(Zone* zone) const {
|
| sizes.AddSection(WasmSection::Code::FunctionTable,
|
| indirect_functions_.size());
|
| for (auto function_index : indirect_functions_) {
|
| - sizes.Add(SizeOfVarInt(function_index), 0);
|
| + sizes.Add(LEBHelper::sizeof_u32v(function_index), 0);
|
| }
|
| TRACE("Size after indirect functions: %u, %u\n",
|
| (unsigned)sizes.header_size, (unsigned)sizes.body_size);
|
| @@ -727,22 +726,6 @@ WasmModuleIndex* WasmModuleWriter::WriteTo(Zone* zone) const {
|
|
|
| return new (zone) WasmModuleIndex(buffer, buffer + sizes.total());
|
| }
|
| -
|
| -
|
| -std::vector<uint8_t> UnsignedLEB128From(uint32_t result) {
|
| - std::vector<uint8_t> output;
|
| - uint8_t next = 0;
|
| - int shift = 0;
|
| - do {
|
| - next = static_cast<uint8_t>(result >> shift);
|
| - if (((result >> shift) & 0xFFFFFF80) != 0) {
|
| - next = next | 0x80;
|
| - }
|
| - output.push_back(next);
|
| - shift += 7;
|
| - } while ((next & 0x80) != 0);
|
| - return output;
|
| -}
|
| } // namespace wasm
|
| } // namespace internal
|
| } // namespace v8
|
|
|