From 8647b05160d8cfa891b298c3c8c53890434356fb Mon Sep 17 00:00:00 2001 From: jiangkaiwen Date: Wed, 6 Dec 2023 03:19:49 +0000 Subject: [PATCH] Add unit for module and fix unit for ECMAclass Issue:I8M5FB Signed-off-by: jiangkaiwen Change-Id: I06c09890b96e97ea3d370b619397a268db4a0771 --- BUILD.gn | 1 + disassembler/disassembler.cpp | 54 ++++--- disassembler/disassembler.h | 6 +- disassembler/tests/BUILD.gn | 16 +- .../tests/disassembler_annotations_test.cpp | 27 +++- .../tests/disassembler_column_number_test.cpp | 8 +- .../disassembler_module_literal_test.cpp | 138 ++++++++++++++++++ .../tests/disassembler_string_test.cpp | 65 +++------ .../tests/module/module-multi-export.js | 4 +- .../tests/module/module-multi-import.js | 4 +- 10 files changed, 234 insertions(+), 89 deletions(-) create mode 100644 disassembler/tests/disassembler_module_literal_test.cpp diff --git a/BUILD.gn b/BUILD.gn index e9a9cfcd90..769d59ba4f 100755 --- a/BUILD.gn +++ b/BUILD.gn @@ -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", diff --git a/disassembler/disassembler.cpp b/disassembler/disassembler.cpp index 969a524dd3..90afa17572 100755 --- a/disassembler/disassembler.cpp +++ b/disassembler/disassembler.cpp @@ -568,42 +568,48 @@ void Disassembler::AddAnnotationElement(pandasm::Function &method, const std::st } } -std::optional Disassembler::GetMethodAnnotationByName(const std::string &method_name, - const std::string &annotation_name) +std::optional> 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(); - } - } + 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 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 Disassembler::GetStrings() const { - if (!string_id.IsValid()) { - return false; + std::vector 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 Disassembler::GetModuleLiterals() const +{ + std::vector 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 diff --git a/disassembler/disassembler.h b/disassembler/disassembler.h index 21456620b6..7bec9703eb 100755 --- a/disassembler/disassembler.h +++ b/disassembler/disassembler.h @@ -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 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> GetAnnotationByMethodName(const std::string &method_name) const; + std::vector GetStrings() const; + std::vector GetModuleLiterals() const; template void FillLiteralArrayData(pandasm::LiteralArray *lit_array, const panda_file::LiteralTag &tag, const panda_file::LiteralDataAccessor::LiteralValue &value) const; diff --git a/disassembler/tests/BUILD.gn b/disassembler/tests/BUILD.gn index d0c4138736..e7839e707c 100644 --- a/disassembler/tests/BUILD.gn +++ b/disassembler/tests/BUILD.gn @@ -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 diff --git a/disassembler/tests/disassembler_annotations_test.cpp b/disassembler/tests/disassembler_annotations_test.cpp index 16c381653a..a1bbdbe359 100755 --- a/disassembler/tests/disassembler_annotations_test.cpp +++ b/disassembler/tests/disassembler_annotations_test.cpp @@ -30,6 +30,17 @@ public: static void TearDownTestCase(void) {}; void SetUp() {}; void TearDown() {}; + + bool ValidateAnnotation(std::optional> &annotations, const std::string &annotation_name) + { + std::vector 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 request_index = disasm.GetMethodAnnotationByName(METHOD_NAME, ANNOTATION_NAME); - ASSERT_NE(request_index, std::nullopt); - EXPECT_EQ(EXPECT_REQUEST_INDEX, request_index.value()); + std::optional> 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 slot_number = disasm.GetMethodAnnotationByName(METHOD_NAME, ANNOTATION_NAME); - ASSERT_NE(slot_number, std::nullopt); - EXPECT_EQ(EXPECT_SLOT_NUMBER, slot_number.value()); + std::optional> annotations = disasm.GetAnnotationByMethodName(METHOD_NAME); + ASSERT_NE(annotations, std::nullopt); + bool has_annotation = ValidateAnnotation(annotations, ANNOTATION_NAME); + EXPECT_TRUE(has_annotation); } }; diff --git a/disassembler/tests/disassembler_column_number_test.cpp b/disassembler/tests/disassembler_column_number_test.cpp index cf217d8552..2380194d3d 100644 --- a/disassembler/tests/disassembler_column_number_test.cpp +++ b/disassembler/tests/disassembler_column_number_test.cpp @@ -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 expectedColumnNumber = {10, 14, 10, 6, 2, 8, 4, 8, 4, 0}; + std::vector expectedColumnNumber = {10, 14, 10, 6, 8, 4, 8, 4, 0}; std::vector 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 expectedColumnNumber = {10, 6, 10, 6, 10, 6, 2, 0}; + std::vector expectedColumnNumber = {10, 6, 10, 6, 10, 6, 0}; std::vector 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 expectedColumnNumber = {4, 16, 4, 15, 4, 13, 4, 14, 6, 14, 6, 0}; + std::vector expectedColumnNumber = {4, 16, 4, 15, 4, 14, 6, 14, 6, 0}; std::vector 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 expectedColumnNumber = {4, 16, 4, 15, 4, 13, 4, 10, 6, 10, 6, 10, 14, 10, 6, + std::vector 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 columnNumber = disasm.GetColumnNumber(); EXPECT_TRUE(expectedColumnNumber.size() == columnNumber.size()); diff --git a/disassembler/tests/disassembler_module_literal_test.cpp b/disassembler/tests/disassembler_module_literal_test.cpp new file mode 100644 index 0000000000..0cf2cf80fa --- /dev/null +++ b/disassembler/tests/disassembler_module_literal_test.cpp @@ -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 +#include +#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 &module_literals, + const std::vector &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 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 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 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 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 expected_module_literals = { + "ModuleTag: LOCAL_EXPORT, local_name: c, export_name: c" + }; + panda::disasm::Disassembler disasm {}; + disasm.Disassemble(file_name, false, false); + std::vector 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 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 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 expected_module_literals = { + "ModuleTag: STAR_EXPORT, module_request: ./module-import-file.js" + }; + panda::disasm::Disassembler disasm {}; + disasm.Disassemble(file_name, false, false); + std::vector module_literals = disasm.GetModuleLiterals(); + bool has_module_literal = ValidateModuleLiteral(module_literals, expected_module_literals); + EXPECT_TRUE(has_module_literal); +} +} diff --git a/disassembler/tests/disassembler_string_test.cpp b/disassembler/tests/disassembler_string_test.cpp index bb72bb058e..341961da74 100755 --- a/disassembler/tests/disassembler_string_test.cpp +++ b/disassembler/tests/disassembler_string_test.cpp @@ -30,6 +30,19 @@ public: static void TearDownTestCase(void) {}; void SetUp() {}; void TearDown() {}; + + bool ValidateString(const std::vector &strings, + const std::vector &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 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 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 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 strings = disasm.GetStrings(); + bool has_string = ValidateString(strings, expected_strings); + EXPECT_TRUE(has_string); } }; diff --git a/disassembler/tests/module/module-multi-export.js b/disassembler/tests/module/module-multi-export.js index 1ad8c30373..c8a168b45b 100644 --- a/disassembler/tests/module/module-multi-export.js +++ b/disassembler/tests/module/module-multi-export.js @@ -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; } \ No newline at end of file diff --git a/disassembler/tests/module/module-multi-import.js b/disassembler/tests/module/module-multi-import.js index 6fff557a6b..ebecf8e9b0 100644 --- a/disassembler/tests/module/module-multi-import.js +++ b/disassembler/tests/module/module-multi-import.js @@ -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'; } \ No newline at end of file