diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /third_party/wasm2c/src/binary-reader-opcnt.cc | |
parent | Initial commit. (diff) | |
download | thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/wasm2c/src/binary-reader-opcnt.cc')
-rw-r--r-- | third_party/wasm2c/src/binary-reader-opcnt.cc | 314 |
1 files changed, 314 insertions, 0 deletions
diff --git a/third_party/wasm2c/src/binary-reader-opcnt.cc b/third_party/wasm2c/src/binary-reader-opcnt.cc new file mode 100644 index 0000000000..3177dbb7eb --- /dev/null +++ b/third_party/wasm2c/src/binary-reader-opcnt.cc @@ -0,0 +1,314 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "wabt/binary-reader-opcnt.h" + +#include <cassert> +#include <cinttypes> +#include <cstdarg> +#include <cstdint> +#include <cstdio> + +#include "wabt/binary-reader-nop.h" +#include "wabt/common.h" +#include "wabt/literal.h" +#include "wabt/stream.h" + +namespace wabt { + +OpcodeInfo::OpcodeInfo(Opcode opcode, Kind kind) + : opcode_(opcode), kind_(kind) {} + +template <typename T> +OpcodeInfo::OpcodeInfo(Opcode opcode, Kind kind, T* data, size_t count) + : OpcodeInfo(opcode, kind) { + if (count > 0) { + data_.resize(sizeof(T) * count); + memcpy(data_.data(), data, data_.size()); + } +} + +template <typename T> +OpcodeInfo::OpcodeInfo(Opcode opcode, Kind kind, T* data, size_t count, T extra) + : OpcodeInfo(opcode, kind, data, count) { + data_.resize(data_.size() + sizeof(T)); + memcpy(data_.data() + data_.size() - sizeof(T), &extra, sizeof(T)); +} + +template <typename T> +std::pair<const T*, size_t> OpcodeInfo::GetDataArray() const { + if (data_.empty()) { + return std::pair<const T*, size_t>(nullptr, 0); + } + + assert(data_.size() % sizeof(T) == 0); + return std::make_pair(reinterpret_cast<const T*>(data_.data()), + data_.size() / sizeof(T)); +} + +template <typename T> +const T* OpcodeInfo::GetData(size_t expected_size) const { + auto [data, size] = GetDataArray<T>(); + assert(size == expected_size); + return data; +} + +template <typename T, typename F> +void OpcodeInfo::WriteArray(Stream& stream, F&& write_func) { + auto [data, size] = GetDataArray<T>(); + for (size_t i = 0; i < size; ++i) { + // Write an initial space (to separate from the opcode name) first, then + // comma-separate. + stream.Writef("%s", i == 0 ? " " : ", "); + write_func(data[i]); + } +} + +void OpcodeInfo::Write(Stream& stream) { + stream.Writef("%s", opcode_.GetName()); + + switch (kind_) { + case Kind::Bare: + break; + + case Kind::Uint32: + stream.Writef(" %u (0x%x)", *GetData<uint32_t>(), *GetData<uint32_t>()); + break; + + case Kind::Uint64: + stream.Writef(" %" PRIu64 " (0x%" PRIx64 ")", *GetData<uint64_t>(), + *GetData<uint64_t>()); + break; + + case Kind::Index: + stream.Writef(" %" PRIindex, *GetData<Index>()); + break; + + case Kind::Float32: { + stream.Writef(" %g", *GetData<float>()); + char buffer[WABT_MAX_FLOAT_HEX + 1]; + WriteFloatHex(buffer, sizeof(buffer), *GetData<uint32_t>()); + stream.Writef(" (%s)", buffer); + break; + } + + case Kind::Float64: { + stream.Writef(" %g", *GetData<double>()); + char buffer[WABT_MAX_DOUBLE_HEX + 1]; + WriteDoubleHex(buffer, sizeof(buffer), *GetData<uint64_t>()); + stream.Writef(" (%s)", buffer); + break; + } + + case Kind::V128: { + auto data = *GetData<v128>(); + auto l0 = data.u32(0); + auto l1 = data.u32(1); + auto l2 = data.u32(2); + auto l3 = data.u32(3); + stream.Writef(" %u %u %u %u (0x%x 0x%x 0x%x 0x%x)", l0, l1, l2, l3, l0, + l1, l2, l3); + break; + } + + case Kind::Uint32Uint32: + case Kind::Uint32Uint32Uint32: + case Kind::Uint32Uint32Uint32Uint32: + WriteArray<uint32_t>( + stream, [&stream](uint32_t value) { stream.Writef("%u", value); }); + break; + + case Kind::BlockSig: { + auto type = *GetData<Type>(); + if (type.IsIndex()) { + stream.Writef(" type:%d", type.GetIndex()); + } else if (type != Type::Void) { + stream.Writef(" %s", type.GetName().c_str()); + } + break; + } + + case Kind::BrTable: { + WriteArray<Index>(stream, [&stream](Index index) { + stream.Writef("%" PRIindex, index); + }); + break; + } + } +} + +bool operator==(const OpcodeInfo& lhs, const OpcodeInfo& rhs) { + return lhs.opcode_ == rhs.opcode_ && lhs.kind_ == rhs.kind_ && + lhs.data_ == rhs.data_; +} + +bool operator!=(const OpcodeInfo& lhs, const OpcodeInfo& rhs) { + return !(lhs == rhs); +} + +bool operator<(const OpcodeInfo& lhs, const OpcodeInfo& rhs) { + if (lhs.opcode_ < rhs.opcode_) { + return true; + } + if (lhs.opcode_ > rhs.opcode_) { + return false; + } + if (lhs.kind_ < rhs.kind_) { + return true; + } + if (lhs.kind_ > rhs.kind_) { + return false; + } + if (lhs.data_ < rhs.data_) { + return true; + } + if (lhs.data_ > rhs.data_) { + return false; + } + return false; +} + +bool operator<=(const OpcodeInfo& lhs, const OpcodeInfo& rhs) { + return lhs < rhs || lhs == rhs; +} + +bool operator>(const OpcodeInfo& lhs, const OpcodeInfo& rhs) { + return !(lhs <= rhs); +} + +bool operator>=(const OpcodeInfo& lhs, const OpcodeInfo& rhs) { + return !(lhs < rhs); +} + +namespace { + +class BinaryReaderOpcnt : public BinaryReaderNop { + public: + explicit BinaryReaderOpcnt(OpcodeInfoCounts* counts); + + Result OnOpcode(Opcode opcode) override; + Result OnOpcodeBare() override; + Result OnOpcodeUint32(uint32_t value) override; + Result OnOpcodeIndex(Index value) override; + Result OnOpcodeUint32Uint32(uint32_t value, uint32_t value2) override; + Result OnOpcodeUint32Uint32Uint32(uint32_t value, + uint32_t value2, + uint32_t value3) override; + Result OnOpcodeUint64(uint64_t value) override; + Result OnOpcodeF32(uint32_t value) override; + Result OnOpcodeF64(uint64_t value) override; + Result OnOpcodeV128(v128 value) override; + Result OnOpcodeBlockSig(Type sig_type) override; + Result OnBrTableExpr(Index num_targets, + Index* target_depths, + Index default_target_depth) override; + Result OnEndExpr() override; + + private: + template <typename... Args> + Result Emplace(Args&&... args); + + OpcodeInfoCounts* opcode_counts_; + Opcode current_opcode_; +}; + +template <typename... Args> +Result BinaryReaderOpcnt::Emplace(Args&&... args) { + auto pair = opcode_counts_->emplace( + std::piecewise_construct, std::make_tuple(std::forward<Args>(args)...), + std::make_tuple(0)); + + auto& count = pair.first->second; + count++; + return Result::Ok; +} + +BinaryReaderOpcnt::BinaryReaderOpcnt(OpcodeInfoCounts* counts) + : opcode_counts_(counts) {} + +Result BinaryReaderOpcnt::OnOpcode(Opcode opcode) { + current_opcode_ = opcode; + return Result::Ok; +} + +Result BinaryReaderOpcnt::OnOpcodeBare() { + return Emplace(current_opcode_, OpcodeInfo::Kind::Bare); +} + +Result BinaryReaderOpcnt::OnOpcodeUint32(uint32_t value) { + return Emplace(current_opcode_, OpcodeInfo::Kind::Uint32, &value); +} + +Result BinaryReaderOpcnt::OnOpcodeIndex(Index value) { + return Emplace(current_opcode_, OpcodeInfo::Kind::Index, &value); +} + +Result BinaryReaderOpcnt::OnOpcodeUint32Uint32(uint32_t value0, + uint32_t value1) { + uint32_t array[2] = {value0, value1}; + return Emplace(current_opcode_, OpcodeInfo::Kind::Uint32Uint32, array, 2); +} + +Result BinaryReaderOpcnt::OnOpcodeUint32Uint32Uint32(uint32_t value0, + uint32_t value1, + uint32_t value2) { + uint32_t array[3] = {value0, value1, value2}; + return Emplace(current_opcode_, OpcodeInfo::Kind::Uint32Uint32Uint32, array, + 3); +} + +Result BinaryReaderOpcnt::OnOpcodeUint64(uint64_t value) { + return Emplace(current_opcode_, OpcodeInfo::Kind::Uint64, &value); +} + +Result BinaryReaderOpcnt::OnOpcodeF32(uint32_t value) { + return Emplace(current_opcode_, OpcodeInfo::Kind::Float32, &value); +} + +Result BinaryReaderOpcnt::OnOpcodeF64(uint64_t value) { + return Emplace(current_opcode_, OpcodeInfo::Kind::Float64, &value); +} + +Result BinaryReaderOpcnt::OnOpcodeV128(v128 value) { + return Emplace(current_opcode_, OpcodeInfo::Kind::V128, &value); +} + +Result BinaryReaderOpcnt::OnOpcodeBlockSig(Type sig_type) { + return Emplace(current_opcode_, OpcodeInfo::Kind::BlockSig, &sig_type); +} + +Result BinaryReaderOpcnt::OnBrTableExpr(Index num_targets, + Index* target_depths, + Index default_target_depth) { + return Emplace(current_opcode_, OpcodeInfo::Kind::BrTable, target_depths, + num_targets, default_target_depth); +} + +Result BinaryReaderOpcnt::OnEndExpr() { + return Emplace(Opcode::End, OpcodeInfo::Kind::Bare); +} + +} // end anonymous namespace + +Result ReadBinaryOpcnt(const void* data, + size_t size, + const ReadBinaryOptions& options, + OpcodeInfoCounts* counts) { + BinaryReaderOpcnt reader(counts); + return ReadBinary(data, size, &reader, options); +} + +} // namespace wabt |