huangyu c658ccf319 Update runtime_core code
Issue: https://gitee.com/openharmony/arkcompiler_runtime_core/issues/I5G96F
Test: Test262 suit, ark unittest, rk3568 XTS, ark previewer demo

Signed-off-by: huangyu <huangyu76@huawei.com>
Change-Id: I3f63d129a07deaa27a390f556dcaa5651c098185
2022-07-17 10:20:32 +08:00

210 lines
9.4 KiB
C++

/**
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* 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 "utils/leb128.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
namespace panda::leb128::test {
template <class T>
struct TestData {
T value;
size_t size;
uint8_t data[10];
};
// clang-format off
static std::vector<TestData<uint64_t>> unsigned_test_data {
{0x00, 1, {0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{0x7f, 1, {0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{0xff, 2, {0xff, 0x01, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{0x2d7f, 2, {0xff, 0x5a, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{0xffff, 3, {0xff, 0xff, 0x03, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{0x192d7f, 3, {0xff, 0xda, 0x64, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{0x1592d7f, 4, {0xff, 0xda, 0xe4, 0x0a, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{0x11592d7f, 5, {0xff, 0xda, 0xe4, 0x8a, 0x01, 0x80, 0x80, 0x80, 0x80, 0x80}},
{0xffffffff, 5, {0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, 0x80, 0x80, 0x80, 0x80}},
{0x1011592d7f, 6, {0xff, 0xda, 0xe4, 0x8a, 0x81, 0x02, 0x80, 0x80, 0x80, 0x80}},
{0xc1011592d7f, 7, {0xff, 0xda, 0xe4, 0x8a, 0x81, 0x82, 0x03, 0x80, 0x80, 0x80}},
{0x80c1011592d7f, 8, {0xff, 0xda, 0xe4, 0x8a, 0x81, 0x82, 0x83, 0x04, 0x80, 0x80}},
{0xffffffffffffffff, 10, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01}}
};
static std::vector<TestData<uint64_t>> unsigned_partial_decoding_test_data {
{0xffffffffffffffff, 10, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03}},
};
static std::vector<TestData<int8_t>> signed_test_data8 {
{0x00, 1, {0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{0x01, 1, {0x01, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{-1, 1, {0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{0x40, 2, {0xc0, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{static_cast<int8_t>(0x80), 2, {0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{-0x40, 1, {0x40, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}}
};
static std::vector<TestData<int16_t>> signed_test_data16 {
{0x00, 1, {0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{0x0102, 2, {0x82, 0x02, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{-1, 1, {0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{-0x40, 1, {0x40, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{static_cast<int16_t>(0x8000), 3, {0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{static_cast<int16_t>(0x4001), 3, {0x81, 0x80, 0x01, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}}
};
static std::vector<TestData<int32_t>> signed_test_data32 {
{0x00, 1, {0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{0x01020304, 4, {0x84, 0x86, 0x88, 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{-1, 1, {0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{-0x40, 1, {0x40, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{static_cast<int32_t>(0x80000000), 5, {0x80, 0x80, 0x80, 0x80, 0x78, 0x80, 0x80, 0x80, 0x80, 0x80}},
{static_cast<int32_t>(0x40000001), 5, {0x81, 0x80, 0x80, 0x80, 0x04, 0x80, 0x80, 0x80, 0x80, 0x80}}
};
static std::vector<TestData<int64_t>> signed_test_data64 {
{0x00, 1, {0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{0x40, 2, {0xc0, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{0x7f, 2, {0xff, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{-1, 1, {0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{static_cast<int64_t>(0x8000000000000000), 10, {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f}},
{0x7000000000000001, 10, {0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xf0, 0x00}},
{0x100000000000000, 9, {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01, 0x00}},
{-0x40, 1, {0x40, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
{-0x1122, 2, {0xde, 0x5d, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}}
};
static std::vector<TestData<int8_t>> signed_partial_decoding_test_data8 {
{1, 10, {0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a}}
};
static std::vector<TestData<int16_t>> signed_partial_decoding_test_data16 {
{-0x3eff, 10, {0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a}}
};
static std::vector<TestData<int32_t>> signed_partial_decoding_test_data32 {
{0x5080c101, 10, {0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a}}
};
static std::vector<TestData<int64_t>> signed_partial_decoding_test_data64 {
{0x9101c305080c101, 10, {0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a}},
{static_cast<int64_t>(0x8000000000000000), 10, {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x5f}}
};
// clang-format on
template <class T>
static void TestDecodeUnsigned(const std::vector<TestData<uint64_t>> &data, bool is_partial = false)
{
for (auto &t : data) {
std::ostringstream ss;
ss << "Test unsigned decoding ";
ss << std::hex << t.value;
ss << " with sizeof(T) = ";
ss << sizeof(T);
constexpr size_t bitwidth = std::numeric_limits<T>::digits;
auto [value, size, is_full] = DecodeUnsigned<T>(t.data);
EXPECT_EQ(is_full, MinimumBitsToStore(t.value) <= bitwidth && !is_partial) << ss.str();
EXPECT_EQ(size, is_full ? t.size : (bitwidth + 6) / 7) << ss.str();
EXPECT_EQ(value, static_cast<T>(t.value)) << ss.str();
}
}
TEST(Leb128, DecodeUnsigned)
{
TestDecodeUnsigned<uint8_t>(unsigned_test_data);
TestDecodeUnsigned<uint16_t>(unsigned_test_data);
TestDecodeUnsigned<uint32_t>(unsigned_test_data);
TestDecodeUnsigned<uint64_t>(unsigned_test_data);
TestDecodeUnsigned<uint64_t>(unsigned_partial_decoding_test_data, true);
}
template <class T>
static void TestDecodeSigned(const std::vector<TestData<T>> &data, bool is_partial = false)
{
for (auto &t : data) {
std::ostringstream ss;
ss << "Test signed decoding ";
ss << std::hex << static_cast<int64_t>(t.value);
ss << " with sizeof(T) = ";
ss << sizeof(T);
constexpr size_t bitwidth = std::numeric_limits<std::make_unsigned_t<T>>::digits;
auto [value, size, is_full] = DecodeSigned<T>(t.data);
EXPECT_EQ(is_full, !is_partial) << ss.str();
EXPECT_EQ(size, is_full ? t.size : (bitwidth + 6) / 7) << ss.str();
EXPECT_EQ(value, t.value) << ss.str();
}
}
TEST(Leb128, DecodeSigned)
{
TestDecodeSigned(signed_test_data8);
TestDecodeSigned(signed_test_data16);
TestDecodeSigned(signed_test_data32);
TestDecodeSigned(signed_test_data64);
TestDecodeSigned(signed_partial_decoding_test_data8, true);
TestDecodeSigned(signed_partial_decoding_test_data16, true);
TestDecodeSigned(signed_partial_decoding_test_data32, true);
TestDecodeSigned(signed_partial_decoding_test_data64, true);
}
TEST(Leb128, EncodeUnsigned)
{
for (auto &t : unsigned_test_data) {
std::ostringstream ss;
ss << "Test unsigned encoding ";
ss << std::hex << t.value;
std::vector<uint8_t> data(t.size);
size_t n = EncodeUnsigned(t.value, data.data());
EXPECT_EQ(n, t.size) << ss.str();
EXPECT_EQ(UnsignedEncodingSize(t.value), t.size) << ss.str();
EXPECT_THAT(data, ::testing::ElementsAreArray(t.data, t.size)) << ss.str();
}
}
template <class T>
void TestEncodeSigned(const std::vector<TestData<T>> &data_vec)
{
for (auto &t : data_vec) {
std::ostringstream ss;
ss << "Test signed encoding ";
ss << std::hex << static_cast<int64_t>(t.value);
std::vector<uint8_t> data(t.size);
size_t n = EncodeSigned(t.value, data.data());
EXPECT_EQ(n, t.size) << ss.str();
EXPECT_EQ(SignedEncodingSize(t.value), t.size) << ss.str();
EXPECT_THAT(data, ::testing::ElementsAreArray(t.data, t.size)) << ss.str();
}
}
TEST(Leb128, EncodeSigned)
{
TestEncodeSigned(signed_test_data8);
TestEncodeSigned(signed_test_data16);
TestEncodeSigned(signed_test_data32);
TestEncodeSigned(signed_test_data64);
}
} // namespace panda::leb128::test