Chromium Code Reviews| Index: src/wasm/encoder.h |
| diff --git a/src/wasm/encoder.h b/src/wasm/encoder.h |
| index 0f2118dd013cad493078f70eb74ff2e075fe26a8..5d2e6c8faea1b7843ed3adb79c71fa51558f1e7e 100644 |
| --- a/src/wasm/encoder.h |
| +++ b/src/wasm/encoder.h |
| @@ -10,6 +10,7 @@ |
| #include "src/base/smart-pointers.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" |
| @@ -19,14 +20,104 @@ namespace v8 { |
| namespace internal { |
| namespace wasm { |
| +class ZoneBuffer : public ZoneObject { |
|
bradnelson
2016/05/25 14:51:23
How about in a separate file? Or you leaning on th
titzer
2016/05/25 15:40:21
I think we can pull this out to its own header in
|
| + public: |
| + static const uint32_t kInitialSize = 4096; |
| + explicit ZoneBuffer(Zone* zone, size_t initial = kInitialSize) |
| + : zone_(zone), buffer_(reinterpret_cast<byte*>(zone->New(initial))) { |
| + pos_ = buffer_; |
| + end_ = buffer_ + initial; |
| + } |
| + |
| + void write_u8(uint8_t x) { |
| + EnsureSpace(1); |
| + *(pos_++) = x; |
| + } |
| + |
| + void write_u16(uint16_t x) { |
| + EnsureSpace(2); |
| + WriteUnalignedUInt16(pos_, x); |
| + pos_ += 2; |
| + } |
| + |
| + void write_u32(uint32_t x) { |
| + EnsureSpace(4); |
| + WriteUnalignedUInt32(pos_, x); |
| + pos_ += 4; |
| + } |
| + |
| + void write_u32v(uint32_t val) { |
| + EnsureSpace(kMaxVarInt32Size); |
| + LEBHelper::write_u32v(&pos_, val); |
| + } |
| + |
| + void write_size(size_t val) { |
| + EnsureSpace(kMaxVarInt32Size); |
| + DCHECK_EQ(val, static_cast<uint32_t>(val)); |
| + LEBHelper::write_u32v(&pos_, static_cast<uint32_t>(val)); |
| + } |
| + |
| + void write(const byte* data, size_t size) { |
| + EnsureSpace(size); |
| + memcpy(pos_, data, size); |
| + pos_ += size; |
| + } |
| + |
| + size_t reserve_u32v() { |
| + size_t off = offset(); |
| + EnsureSpace(kMaxVarInt32Size); |
| + pos_ += kMaxVarInt32Size; |
| + return off; |
| + } |
| + |
| + // Patch a (padded) u32v at the given offset to be the given value. |
| + void patch_u32v(size_t offset, uint32_t val) { |
| + byte* ptr = buffer_ + offset; |
| + for (size_t pos = 0; pos != kPaddedVarInt32Size; ++pos) { |
| + uint32_t next = val >> 7; |
| + byte out = static_cast<byte>(val & 0x7f); |
| + if (pos != kPaddedVarInt32Size - 1) { |
| + *(ptr++) = 0x80 | out; |
| + val = next; |
| + } else { |
| + *(ptr++) = out; |
| + } |
| + } |
| + } |
| + |
| + size_t offset() { return static_cast<size_t>(pos_ - buffer_); } |
| + size_t size() { return static_cast<size_t>(pos_ - buffer_); } |
| + const byte* begin() { return buffer_; } |
| + const byte* end() { return pos_; } |
| + |
| + void EnsureSpace(size_t size) { |
| + if ((pos_ + size) > end_) { |
| + size_t new_size = 4096 + (end_ - buffer_) * 3; |
|
bradnelson
2016/05/25 14:51:23
Are all the cool kids doing 3 instead of 2 these d
titzer
2016/05/25 15:40:21
Growth factors are hard. I always felt like 2x was
|
| + byte* new_buffer = reinterpret_cast<byte*>(zone_->New(new_size)); |
| + memcpy(new_buffer, buffer_, (pos_ - buffer_)); |
| + pos_ = new_buffer + (pos_ - buffer_); |
| + buffer_ = new_buffer; |
| + end_ = new_buffer + new_size; |
| + } |
| + } |
| + |
| + byte** pos_ptr() { return &pos_; } |
|
bradnelson
2016/05/25 14:51:23
That seems a rather leaky abstraction... reserve j
titzer
2016/05/25 15:40:21
Yeah, it's because of a special case with the loca
|
| + |
| + private: |
| + Zone* zone_; |
| + byte* buffer_; |
| + byte* pos_; |
| + byte* end_; |
| +}; |
| + |
| class WasmModuleBuilder; |
| class WasmFunctionEncoder : public ZoneObject { |
| public: |
| - uint32_t HeaderSize() const; |
| - uint32_t BodySize() const; |
| - uint32_t NameSize() const; |
| - void Serialize(byte* buffer, byte** header, byte** body) const; |
| + void WriteSignature(ZoneBuffer& buffer) const; |
| + void WriteExport(ZoneBuffer& buffer, uint32_t func_index) const; |
| + void WriteBody(ZoneBuffer& buffer) const; |
| + bool exported() const { return exported_; } |
| private: |
| WasmFunctionEncoder(Zone* zone, LocalDeclEncoder locals, bool exported); |
| @@ -71,28 +162,13 @@ class WasmDataSegmentEncoder : public ZoneObject { |
| public: |
| WasmDataSegmentEncoder(Zone* zone, const byte* data, uint32_t size, |
| uint32_t dest); |
| - uint32_t HeaderSize() const; |
| - uint32_t BodySize() const; |
| - void Serialize(byte* buffer, byte** header, byte** body) const; |
| + void Write(ZoneBuffer& buffer) const; |
| private: |
| ZoneVector<byte> data_; |
| uint32_t dest_; |
| }; |
| -class WasmModuleIndex : public ZoneObject { |
| - public: |
| - const byte* Begin() const { return begin_; } |
| - const byte* End() const { return end_; } |
| - |
| - private: |
| - friend class WasmModuleWriter; |
| - WasmModuleIndex(const byte* begin, const byte* end) |
| - : begin_(begin), end_(end) {} |
| - const byte* begin_; |
| - const byte* end_; |
| -}; |
| - |
| struct WasmFunctionImport { |
| uint32_t sig_index; |
| const char* name; |
| @@ -101,7 +177,7 @@ struct WasmFunctionImport { |
| class WasmModuleWriter : public ZoneObject { |
| public: |
| - WasmModuleIndex* WriteTo(Zone* zone) const; |
| + void WriteTo(ZoneBuffer& buffer) const; |
| private: |
| friend class WasmModuleBuilder; |