Add unit for module and fix unit for ECMAclass

Issue:I8M5FB

Signed-off-by: jiangkaiwen <jiangkaiwen2@huawei.com>
Change-Id: I06c09890b96e97ea3d370b619397a268db4a0771
This commit is contained in:
jiangkaiwen 2023-12-06 03:19:49 +00:00
parent 55c88d8d70
commit 8647b05160
10 changed files with 234 additions and 89 deletions

View File

@ -313,6 +313,7 @@ if (!ark_standalone_build) {
"$ark_root/assembler/tests:host_unittest",
"$ark_root/bytecode_optimizer/tests:host_unittest",
"$ark_root/compiler/tests:host_unittest",
"$ark_root/disassembler/tests:host_unittest",
"$ark_root/libpandabase/tests:host_unittest",
"$ark_root/libpandafile/tests:host_unittest",
"$ark_root/libziparchive/tests:host_unittest",

View File

@ -568,42 +568,48 @@ void Disassembler::AddAnnotationElement(pandasm::Function &method, const std::st
}
}
std::optional<uint32_t> Disassembler::GetMethodAnnotationByName(const std::string &method_name,
const std::string &annotation_name)
std::optional<std::vector<std::string>> Disassembler::GetAnnotationByMethodName(const std::string &method_name) const
{
const auto method_synonyms_iter = prog_.function_synonyms.find(method_name);
bool is_signature = method_synonyms_iter != prog_.function_synonyms.end();
if (is_signature) {
const auto method_iter = prog_.function_table.find(method_synonyms_iter->second.back());
bool is_method = method_iter != prog_.function_table.end();
const auto annotations = method_iter->second.metadata->GetAnnotations();
if (!is_method || annotations.empty()) {
return std::nullopt;
}
for (const auto &ann_data : annotations) {
if (ann_data.GetName() == annotation_name) {
return ann_data.GetElements().back().GetValue()->GetAsScalar()->GetValue<uint32_t>();
}
}
if (!is_signature) {
return std::nullopt;
}
return std::nullopt;
const auto method_iter = prog_.function_table.find(method_synonyms_iter->second.back());
bool is_method = method_iter != prog_.function_table.end();
const auto annotations = method_iter->second.metadata->GetAnnotations();
if (!is_method || annotations.empty()) {
return std::nullopt;
}
std::vector<std::string> ann;
for (const auto &ann_data : annotations) {
ann.emplace_back(ann_data.GetName());
}
return ann;
}
bool Disassembler::ValidateStringOffset(const panda_file::File::EntityId string_id, const std::string &str)
std::vector<std::string> Disassembler::GetStrings() const
{
if (!string_id.IsValid()) {
return false;
std::vector<std::string> strings;
for (auto &str_info : string_offset_to_name_) {
strings.emplace_back(str_info.second);
}
const auto str_iter = string_offset_to_name_.find(string_id);
const bool is_string = str_iter != string_offset_to_name_.end();
if (is_string) {
return str == str_iter->second;
return strings;
}
std::vector<std::string> Disassembler::GetModuleLiterals() const
{
std::vector<std::string> module_literals;
for (auto &module_array : modulearray_table_) {
for (auto &module : module_array.second) {
module_literals.emplace_back(module);
}
}
return false;
return module_literals;
}
void Disassembler::GetParams(pandasm::Function *method, const panda_file::File::EntityId &proto_id) const

View File

@ -67,9 +67,9 @@ public:
void AddMethodToTables(const panda_file::File::EntityId &method_id);
void GetMethod(pandasm::Function *method, const panda_file::File::EntityId &method_id);
void GetLiteralArray(pandasm::LiteralArray *lit_array, size_t index) const;
std::optional<uint32_t> GetMethodAnnotationByName(const std::string &method_name,
const std::string &annotation_name);
bool ValidateStringOffset(const panda_file::File::EntityId string_id, const std::string &str);
std::optional<std::vector<std::string>> GetAnnotationByMethodName(const std::string &method_name) const;
std::vector<std::string> GetStrings() const;
std::vector<std::string> GetModuleLiterals() const;
template <typename T>
void FillLiteralArrayData(pandasm::LiteralArray *lit_array, const panda_file::LiteralTag &tag,
const panda_file::LiteralDataAccessor::LiteralValue &value) const;

View File

@ -59,7 +59,15 @@ foreach(file, disasm_column_test_js_files) {
}
}
disasm_module_test_js_files = [ "module-requests-annotation-import" ]
disasm_module_test_js_files = [
"module-requests-annotation-import",
"module-regular-import",
"module-namespace-import",
"module-local-export",
"module-indirect-export",
"module-start-export",
]
module_test_js_path = "//arkcompiler/runtime_core/disassembler/tests/module/"
foreach(file, disasm_module_test_js_files) {
@ -103,7 +111,11 @@ script_sources = [
"disassembler_column_number_test.cpp",
"disassembler_string_test.cpp",
]
module_sources = [ "disassembler_annotations_test.cpp" ]
module_sources = [
"disassembler_annotations_test.cpp",
"disassembler_module_literal_test.cpp",
]
host_unittest_action("DisasmModuleTest") {
module_out_path = module_output_path

View File

@ -30,6 +30,17 @@ public:
static void TearDownTestCase(void) {};
void SetUp() {};
void TearDown() {};
bool ValidateAnnotation(std::optional<std::vector<std::string>> &annotations, const std::string &annotation_name)
{
std::vector<std::string> ann = annotations.value();
const auto ann_iter = std::find(ann.begin(), ann.end(), annotation_name);
if (ann_iter != ann.end()) {
return true;
}
return false;
}
};
/**
@ -42,12 +53,12 @@ HWTEST_F(DisassemblerAnnotationTest, disassembler_annotation_test_001, TestSize.
{
static const std::string METHOD_NAME = "module-requests-annotation-import.funcD";
static const std::string ANNOTATION_NAME = "L_ESConcurrentModuleRequestsAnnotation";
static const uint32_t EXPECT_REQUEST_INDEX = 0x0;
panda::disasm::Disassembler disasm {};
disasm.Disassemble(MODULE_REQUEST_FILE_NAME, false, false);
std::optional<uint32_t> request_index = disasm.GetMethodAnnotationByName(METHOD_NAME, ANNOTATION_NAME);
ASSERT_NE(request_index, std::nullopt);
EXPECT_EQ(EXPECT_REQUEST_INDEX, request_index.value());
std::optional<std::vector<std::string>> annotations = disasm.GetAnnotationByMethodName(METHOD_NAME);
ASSERT_NE(annotations, std::nullopt);
bool has_annotation = ValidateAnnotation(annotations, ANNOTATION_NAME);
EXPECT_TRUE(has_annotation);
}
/**
@ -60,11 +71,11 @@ HWTEST_F(DisassemblerAnnotationTest, disassembler_annotation_test_002, TestSize.
{
static const std::string METHOD_NAME = "funcA";
static const std::string ANNOTATION_NAME = "L_ESSlotNumberAnnotation";
static const uint32_t EXPECT_SLOT_NUMBER = 0x3;
panda::disasm::Disassembler disasm {};
disasm.Disassemble(SLOT_NUMBER_FILE_NAME, false, false);
std::optional<uint32_t> slot_number = disasm.GetMethodAnnotationByName(METHOD_NAME, ANNOTATION_NAME);
ASSERT_NE(slot_number, std::nullopt);
EXPECT_EQ(EXPECT_SLOT_NUMBER, slot_number.value());
std::optional<std::vector<std::string>> annotations = disasm.GetAnnotationByMethodName(METHOD_NAME);
ASSERT_NE(annotations, std::nullopt);
bool has_annotation = ValidateAnnotation(annotations, ANNOTATION_NAME);
EXPECT_TRUE(has_annotation);
}
};

View File

@ -41,7 +41,7 @@ HWTEST_F(DisasmTest, disassembler_column_number_test_001, TestSize.Level1)
disasm.Disassemble(file_name, false, false);
disasm.CollectInfo();
// The known column number in the abc file
std::vector<size_t> expectedColumnNumber = {10, 14, 10, 6, 2, 8, 4, 8, 4, 0};
std::vector<size_t> expectedColumnNumber = {10, 14, 10, 6, 8, 4, 8, 4, 0};
std::vector<size_t> columnNumber = disasm.GetColumnNumber();
EXPECT_TRUE(expectedColumnNumber.size() == columnNumber.size());
bool res = true;
@ -67,7 +67,7 @@ HWTEST_F(DisasmTest, disassembler_column_number_test_002, TestSize.Level1)
disasm.Disassemble(file_name, false, false);
disasm.CollectInfo();
// The known column number in the abc file
std::vector<size_t> expectedColumnNumber = {10, 6, 10, 6, 10, 6, 2, 0};
std::vector<size_t> expectedColumnNumber = {10, 6, 10, 6, 10, 6, 0};
std::vector<size_t> columnNumber = disasm.GetColumnNumber();
EXPECT_TRUE(expectedColumnNumber.size() == columnNumber.size());
bool res = true;
@ -93,7 +93,7 @@ HWTEST_F(DisasmTest, disassembler_column_number_test_003, TestSize.Level1)
disasm.Disassemble(file_name, false, false);
disasm.CollectInfo();
// The known column number in the abc file
std::vector<size_t> expectedColumnNumber = {4, 16, 4, 15, 4, 13, 4, 14, 6, 14, 6, 0};
std::vector<size_t> expectedColumnNumber = {4, 16, 4, 15, 4, 14, 6, 14, 6, 0};
std::vector<size_t> columnNumber = disasm.GetColumnNumber();
EXPECT_TRUE(expectedColumnNumber.size() == columnNumber.size());
bool res = true;
@ -144,7 +144,7 @@ HWTEST_F(DisasmTest, disassembler_column_number_test_005, TestSize.Level1)
disasm.Disassemble(file_name, false, false);
disasm.CollectInfo();
// The known column number in the abc file
std::vector<size_t> expectedColumnNumber = {4, 16, 4, 15, 4, 13, 4, 10, 6, 10, 6, 10, 14, 10, 6,
std::vector<size_t> expectedColumnNumber = {4, 16, 4, 15, 4, 10, 6, 10, 6, 10, 14, 10, 6,
10, 14, 10, 6, 9, 2, 2, 14, 6, 14, 6, 8, 4, 0};
std::vector<size_t> columnNumber = disasm.GetColumnNumber();
EXPECT_TRUE(expectedColumnNumber.size() == columnNumber.size());

View File

@ -0,0 +1,138 @@
/*
* Copyright (c) 2023 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 <gtest/gtest.h>
#include <string>
#include "disassembler.h"
using namespace testing::ext;
namespace panda::disasm {
class DisassemblerModuleLiteralTest : public testing::Test {
public:
static void SetUpTestCase(void) {};
static void TearDownTestCase(void) {};
void SetUp() {};
void TearDown() {};
bool ValidateModuleLiteral(const std::vector<std::string> &module_literals,
const std::vector<std::string> &expected_module_literals)
{
for (const auto &expected_module_literal : expected_module_literals) {
const auto module_iter = std::find(module_literals.begin(), module_literals.end(), expected_module_literal);
if (module_iter == module_literals.end()) {
return false;
}
}
return true;
}
};
/**
* @tc.name: disassembler_module_literal_test_001
* @tc.desc: get module literal of abc file.
* @tc.type: FUNC
* @tc.require: file path and name
*/
HWTEST_F(DisassemblerModuleLiteralTest, disassembler_module_literal_test_001, TestSize.Level1)
{
const std::string file_name = GRAPH_TEST_ABC_DIR "module-regular-import.abc";
std::vector<std::string> expected_module_literals = {
"ModuleTag: REGULAR_IMPORT, local_name: a, import_name: a, module_request: ./module-export-file.js"
};
panda::disasm::Disassembler disasm {};
disasm.Disassemble(file_name, false, false);
std::vector<std::string> module_literals = disasm.GetModuleLiterals();
bool has_module_literal = ValidateModuleLiteral(module_literals, expected_module_literals);
EXPECT_TRUE(has_module_literal);
}
/**
* @tc.name: disassembler_module_literal_test_002
* @tc.desc: get module literal of abc file.
* @tc.type: FUNC
* @tc.require: file path and name
*/
HWTEST_F(DisassemblerModuleLiteralTest, disassembler_module_literal_test_002, TestSize.Level1)
{
const std::string file_name = GRAPH_TEST_ABC_DIR "module-namespace-import.abc";
std::vector<std::string> expected_module_literals = {
"ModuleTag: NAMESPACE_IMPORT, local_name: ns, module_request: ./module-export-file.js"
};
panda::disasm::Disassembler disasm {};
disasm.Disassemble(file_name, false, false);
std::vector<std::string> module_literals = disasm.GetModuleLiterals();
bool has_module_literal = ValidateModuleLiteral(module_literals, expected_module_literals);
EXPECT_TRUE(has_module_literal);
}
/**
* @tc.name: disassembler_module_literal_test_003
* @tc.desc: get module literal of abc file.
* @tc.type: FUNC
* @tc.require: file path and name
*/
HWTEST_F(DisassemblerModuleLiteralTest, disassembler_module_literal_test_003, TestSize.Level1)
{
const std::string file_name = GRAPH_TEST_ABC_DIR "module-local-export.abc";
std::vector<std::string> expected_module_literals = {
"ModuleTag: LOCAL_EXPORT, local_name: c, export_name: c"
};
panda::disasm::Disassembler disasm {};
disasm.Disassemble(file_name, false, false);
std::vector<std::string> module_literals = disasm.GetModuleLiterals();
bool has_module_literal = ValidateModuleLiteral(module_literals, expected_module_literals);
EXPECT_TRUE(has_module_literal);
}
/**
* @tc.name: disassembler_module_literal_test_004
* @tc.desc: get module literal of abc file.
* @tc.type: FUNC
* @tc.require: file path and name
*/
HWTEST_F(DisassemblerModuleLiteralTest, disassembler_module_literal_test_004, TestSize.Level1)
{
const std::string file_name = GRAPH_TEST_ABC_DIR "module-indirect-export.abc";
std::vector<std::string> expected_module_literals = {
"ModuleTag: INDIRECT_EXPORT, export_name: a, import_name: a, module_request: ./module-import-file.js"
};
panda::disasm::Disassembler disasm {};
disasm.Disassemble(file_name, false, false);
std::vector<std::string> module_literals = disasm.GetModuleLiterals();
bool has_module_literal = ValidateModuleLiteral(module_literals, expected_module_literals);
EXPECT_TRUE(has_module_literal);
}
/**
* @tc.name: disassembler_module_literal_test_005
* @tc.desc: get module literal of abc file.
* @tc.type: FUNC
* @tc.require: file path and name
*/
HWTEST_F(DisassemblerModuleLiteralTest, disassembler_module_literal_test_005, TestSize.Level1)
{
const std::string file_name = GRAPH_TEST_ABC_DIR "module-start-export.abc";
std::vector<std::string> expected_module_literals = {
"ModuleTag: STAR_EXPORT, module_request: ./module-import-file.js"
};
panda::disasm::Disassembler disasm {};
disasm.Disassemble(file_name, false, false);
std::vector<std::string> module_literals = disasm.GetModuleLiterals();
bool has_module_literal = ValidateModuleLiteral(module_literals, expected_module_literals);
EXPECT_TRUE(has_module_literal);
}
}

View File

@ -30,6 +30,19 @@ public:
static void TearDownTestCase(void) {};
void SetUp() {};
void TearDown() {};
bool ValidateString(const std::vector<std::string> &strings,
const std::vector<std::string> &expected_strings)
{
for (const auto &expected_string : expected_strings) {
const auto string_iter = std::find(strings.begin(), strings.end(), expected_string);
if (string_iter == strings.end()) {
return false;
}
}
return true;
}
};
/**
@ -40,13 +53,12 @@ public:
*/
HWTEST_F(DisassemblerStringTest, disassembler_string_test_001, TestSize.Level1)
{
static const uint32_t STRING_OFFSET = 0xd2;
panda::panda_file::File::EntityId STRING_ID(STRING_OFFSET);
static const std::string EXPECT_STRING = "test";
std::vector<std::string> expected_strings = {"ClassA", "prototype", "str", "test"};
panda::disasm::Disassembler disasm {};
disasm.Disassemble(ANNOTATION_TEST_FILE_NAME_001, false, false);
bool is_exists_string = disasm.ValidateStringOffset(STRING_ID, EXPECT_STRING);
EXPECT_TRUE(is_exists_string);
std::vector<std::string> strings = disasm.GetStrings();
bool has_string = ValidateString(strings, expected_strings);
EXPECT_TRUE(has_string);
}
/**
@ -57,47 +69,12 @@ HWTEST_F(DisassemblerStringTest, disassembler_string_test_001, TestSize.Level1)
*/
HWTEST_F(DisassemblerStringTest, disassembler_string_test_002, TestSize.Level1)
{
static const uint32_t STRING_OFFSET = 0xba;
panda::panda_file::File::EntityId STRING_ID(STRING_OFFSET);
static const std::string EXPECT_STRING = "ClassA";
panda::disasm::Disassembler disasm {};
disasm.Disassemble(ANNOTATION_TEST_FILE_NAME_001, false, false);
bool is_exists_string = disasm.ValidateStringOffset(STRING_ID, EXPECT_STRING);
EXPECT_TRUE(is_exists_string);
}
/**
* @tc.name: disassembler_string_test_003
* @tc.desc: get not existed string.
* @tc.type: FUNC
* @tc.require: file path and name
*/
HWTEST_F(DisassemblerStringTest, disassembler_string_test_003, TestSize.Level1)
{
static const uint32_t STRING_OFFSET = 0xbf;
panda::panda_file::File::EntityId STRING_ID(STRING_OFFSET);
static const std::string EXPECT_STRING = "Student";
std::vector<std::string> expected_strings = {"Student", "name", "prototype", "student_name"};
panda::disasm::Disassembler disasm {};
disasm.Disassemble(ANNOTATION_TEST_FILE_NAME_002, false, false);
bool is_exists_string = disasm.ValidateStringOffset(STRING_ID, EXPECT_STRING);
EXPECT_TRUE(is_exists_string);
}
/**
* @tc.name: disassembler_string_test_004
* @tc.desc: get not existed string.
* @tc.type: FUNC
* @tc.require: file path and name
*/
HWTEST_F(DisassemblerStringTest, disassembler_string_test_004, TestSize.Level1)
{
static const uint32_t STRING_OFFSET = 0xd9;
panda::panda_file::File::EntityId STRING_ID(STRING_OFFSET);
static const std::string EXPECT_STRING = "student_name";
panda::disasm::Disassembler disasm {};
disasm.Disassemble(ANNOTATION_TEST_FILE_NAME_002, false, false);
bool is_exists_string = disasm.ValidateStringOffset(STRING_ID, EXPECT_STRING);
EXPECT_TRUE(is_exists_string);
std::vector<std::string> strings = disasm.GetStrings();
bool has_string = ValidateString(strings, expected_strings);
EXPECT_TRUE(has_string);
}
};

View File

@ -39,9 +39,9 @@ export let h = 9;
let i = 10;
let j = 11;
export class ClassB {
fun1(i, j) { return i + j; }
fun1(i, j) { return i + j; }
}
export function FunctionC() {
let l = 12;
let l = 12;
}

View File

@ -33,6 +33,6 @@ import { g , h as hh } from './module-multi-export.js';
import './module-multi-export.js';
class ClassA {
fun(a, b) { return a + b; }
str = 'test';
fun(a, b) { return a + b; }
str = 'test';
}