nodejs/deps/v8/test/unittests/wasm/module-decoder-table64-unittest.cc
Michaël Zasso 918fe04351
deps: update V8 to 13.6.233.8
PR-URL: https://github.com/nodejs/node/pull/58070
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
2025-05-02 15:06:53 +02:00

178 lines
7.2 KiB
C++

// Copyright 2024 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/wasm/module-decoder.h"
#include "test/common/wasm/flag-utils.h"
#include "test/common/wasm/wasm-macro-gen.h"
#include "test/unittests/test-utils.h"
#include "testing/gmock-support.h"
using testing::HasSubstr;
namespace v8::internal::wasm {
namespace module_decoder_unittest {
#define EXPECT_NOT_OK(result, msg) \
do { \
EXPECT_FALSE(result.ok()); \
if (!result.ok()) { \
EXPECT_THAT(result.error().message(), HasSubstr(msg)); \
} \
} while (false)
#define WASM_INIT_EXPR_I32V_1(val) WASM_I32V_1(val), kExprEnd
#define WASM_INIT_EXPR_I64V_5(val) WASM_I64V_5(val), kExprEnd
#define WASM_INIT_EXPR_FUNC_REF_NULL WASM_REF_NULL(kFuncRefCode), kExprEnd
class Table64DecodingTest : public TestWithIsolateAndZone {
public:
// Table64 is part of the Memory64 proposal, enabled via WASM_FEATURE_SCOPE
// for individual tests.
WasmEnabledFeatures enabled_features_;
ModuleResult DecodeModule(std::initializer_list<uint8_t> module_body_bytes) {
// Add the wasm magic and version number automatically.
std::vector<uint8_t> module_bytes{WASM_MODULE_HEADER};
module_bytes.insert(module_bytes.end(), module_body_bytes);
bool kValidateFunctions = true;
WasmDetectedFeatures detected_features;
ModuleResult result =
DecodeWasmModule(enabled_features_, base::VectorOf(module_bytes),
kValidateFunctions, kWasmOrigin, &detected_features);
CHECK_EQ(WasmDetectedFeatures{{WasmDetectedFeature::memory64}},
detected_features);
return result;
}
};
TEST_F(Table64DecodingTest, TableLimitLEB64) {
// 2 bytes LEB (32-bit range), no maximum.
ModuleResult module = DecodeModule({SECTION(
Table, ENTRY_COUNT(1), kFuncRefCode, kMemory64NoMaximum, U32V_2(5))});
EXPECT_TRUE(module.ok()) << module.error().message();
ASSERT_EQ(1u, module.value()->tables.size());
const WasmTable* table = &module.value()->tables[0];
EXPECT_EQ(5u, table->initial_size);
EXPECT_FALSE(table->has_maximum_size);
EXPECT_TRUE(table->is_table64());
// 3 bytes LEB (32-bit range), with maximum.
module =
DecodeModule({SECTION(Table, ENTRY_COUNT(1), kExternRefCode,
kMemory64WithMaximum, U32V_3(12), U32V_3(123))});
EXPECT_TRUE(module.ok()) << module.error().message();
ASSERT_EQ(1u, module.value()->tables.size());
table = &module.value()->tables[0];
EXPECT_EQ(12u, table->initial_size);
EXPECT_TRUE(table->has_maximum_size);
EXPECT_EQ(123u, table->maximum_size);
EXPECT_TRUE(table->is_table64());
// 5 bytes LEB (32-bit range), no maximum.
module = DecodeModule({SECTION(Table, ENTRY_COUNT(1), kExternRefCode,
kMemory64NoMaximum, U64V_5(7))});
EXPECT_TRUE(module.ok()) << module.error().message();
ASSERT_EQ(1u, module.value()->tables.size());
table = &module.value()->tables[0];
EXPECT_EQ(7u, table->initial_size);
EXPECT_FALSE(table->has_maximum_size);
EXPECT_TRUE(table->is_table64());
// 10 bytes LEB (32-bit range), with maximum.
module =
DecodeModule({SECTION(Table, ENTRY_COUNT(1), kFuncRefCode,
kMemory64WithMaximum, U64V_10(4), U64V_10(1234))});
EXPECT_TRUE(module.ok()) << module.error().message();
ASSERT_EQ(1u, module.value()->tables.size());
table = &module.value()->tables[0];
EXPECT_EQ(4u, table->initial_size);
EXPECT_TRUE(table->has_maximum_size);
EXPECT_EQ(1234u, table->maximum_size);
EXPECT_TRUE(table->is_table64());
// 5 bytes LEB maximum, outside 32-bit range (2^32).
module = DecodeModule(
{SECTION(Table, ENTRY_COUNT(1), kFuncRefCode, kMemory64WithMaximum,
U64V_1(0), U64V_5(uint64_t{1} << 32))});
EXPECT_TRUE(module.ok()) << module.error().message();
ASSERT_EQ(1u, module.value()->tables.size());
table = &module.value()->tables[0];
EXPECT_EQ(0u, table->initial_size);
EXPECT_TRUE(table->has_maximum_size);
EXPECT_EQ(uint64_t{1} << 32, table->maximum_size);
EXPECT_TRUE(table->is_table64());
// 10 bytes LEB maximum, maximum 64-bit value.
module = DecodeModule(
{SECTION(Table, ENTRY_COUNT(1), kFuncRefCode, kMemory64WithMaximum,
U64V_1(0), U64V_10(kMaxUInt64))});
EXPECT_TRUE(module.ok()) << module.error().message();
ASSERT_EQ(1u, module.value()->tables.size());
table = &module.value()->tables[0];
EXPECT_EQ(0u, table->initial_size);
EXPECT_TRUE(table->has_maximum_size);
EXPECT_EQ(kMaxUInt64, table->maximum_size);
EXPECT_TRUE(table->is_table64());
}
TEST_F(Table64DecodingTest, InvalidTableLimits) {
const uint8_t kInvalidLimits = 0x15;
ModuleResult module = DecodeModule({SECTION(
Table, ENTRY_COUNT(1), kFuncRefCode, kInvalidLimits, U32V_2(5))});
EXPECT_NOT_OK(module, "invalid table limits flags");
}
TEST_F(Table64DecodingTest, ImportedTable64) {
// 10 bytes LEB (32-bit range), no maximum.
ModuleResult module = DecodeModule(
{SECTION(Import, ENTRY_COUNT(1), ADD_COUNT('m'), ADD_COUNT('t'),
kExternalTable, kFuncRefCode, kMemory64NoMaximum, U64V_10(5))});
EXPECT_TRUE(module.ok()) << module.error().message();
ASSERT_EQ(1u, module.value()->tables.size());
const WasmTable* table = &module.value()->tables[0];
EXPECT_EQ(5u, table->initial_size);
EXPECT_FALSE(table->has_maximum_size);
EXPECT_TRUE(table->is_table64());
// 5 bytes LEB (32-bit range), with maximum.
module = DecodeModule({SECTION(
Import, ENTRY_COUNT(1), ADD_COUNT('m'), ADD_COUNT('t'), kExternalTable,
kFuncRefCode, kMemory64WithMaximum, U64V_5(123), U64V_5(225))});
EXPECT_TRUE(module.ok()) << module.error().message();
ASSERT_EQ(1u, module.value()->tables.size());
table = &module.value()->tables[0];
EXPECT_EQ(123u, table->initial_size);
EXPECT_TRUE(table->has_maximum_size);
EXPECT_TRUE(table->is_table64());
EXPECT_EQ(225u, table->maximum_size);
// 5 bytes LEB maximum, outside 32-bit range.
module = DecodeModule(
{SECTION(Import, ENTRY_COUNT(1), ADD_COUNT('m'), ADD_COUNT('t'),
kExternalTable, kFuncRefCode, kMemory64WithMaximum, U64V_5(0),
U64V_5(uint64_t{1} << 32))});
EXPECT_TRUE(module.ok()) << module.error().message();
ASSERT_EQ(1u, module.value()->tables.size());
table = &module.value()->tables[0];
EXPECT_EQ(0u, table->initial_size);
EXPECT_TRUE(table->has_maximum_size);
EXPECT_TRUE(table->is_table64());
EXPECT_EQ(uint64_t{1} << 32, table->maximum_size);
// 10 bytes LEB maximum, maximum u64.
module = DecodeModule({SECTION(
Import, ENTRY_COUNT(1), ADD_COUNT('m'), ADD_COUNT('t'), kExternalTable,
kFuncRefCode, kMemory64WithMaximum, U64V_5(0), U64V_10(kMaxUInt64))});
EXPECT_TRUE(module.ok()) << module.error().message();
ASSERT_EQ(1u, module.value()->tables.size());
table = &module.value()->tables[0];
EXPECT_EQ(0u, table->initial_size);
EXPECT_TRUE(table->has_maximum_size);
EXPECT_TRUE(table->is_table64());
EXPECT_EQ(kMaxUInt64, table->maximum_size);
}
} // namespace module_decoder_unittest
} // namespace v8::internal::wasm