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 |