From faabaef18cfd93ee5bd1a27ab51ff730d666963c Mon Sep 17 00:00:00 2001 From: zgy-ian Date: Tue, 2 Nov 2021 20:09:11 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0ts2abc.cpp=E7=9A=84UT?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E6=A1=86=E6=9E=B6=20Signed-off-by:=20zgy-ian?= =?UTF-8?q?=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ts2panda/BUILD.gn | 4 + ts2panda/scripts/run_tests.py | 5 - ts2panda/scripts/run_tests_executable.sh | 25 +++ ts2panda/tests/BUILD.gn | 1 - ts2panda/ts2abc/BUILD.gn | 11 +- ts2panda/ts2abc/main.cpp | 93 +++++++++++ ts2panda/ts2abc/tests/BUILD.gn | 41 +++++ ts2panda/ts2abc/tests/debuglog_test.cpp | 51 ++++++ ts2panda/ts2abc/tests/debugmode_test.cpp | 51 ++++++ ts2panda/ts2abc/tests/functions_test.cpp | 60 +++++++ ts2panda/ts2abc/tests/sources/add.json | 157 ++++++++++++++++++ ts2panda/ts2abc/tests/stringarr_test.cpp | 51 ++++++ ts2panda/ts2abc/ts2abc.cpp | 170 +++++-------------- ts2panda/ts2abc/ts2abc.h | 60 +++++++ ts2panda/ts2abc/ts2abc_options.h | 203 ++++++++++++++++++++--- ts2panda/ts2abc_config.gni | 34 ++++ 16 files changed, 861 insertions(+), 156 deletions(-) create mode 100755 ts2panda/scripts/run_tests_executable.sh create mode 100644 ts2panda/ts2abc/main.cpp create mode 100644 ts2panda/ts2abc/tests/BUILD.gn create mode 100644 ts2panda/ts2abc/tests/debuglog_test.cpp create mode 100644 ts2panda/ts2abc/tests/debugmode_test.cpp create mode 100644 ts2panda/ts2abc/tests/functions_test.cpp create mode 100644 ts2panda/ts2abc/tests/sources/add.json create mode 100644 ts2panda/ts2abc/tests/stringarr_test.cpp create mode 100644 ts2panda/ts2abc/ts2abc.h diff --git a/ts2panda/BUILD.gn b/ts2panda/BUILD.gn index fcde4bc32f..61969a13ce 100755 --- a/ts2panda/BUILD.gn +++ b/ts2panda/BUILD.gn @@ -324,5 +324,9 @@ ohos_copy("copy_ts2abc_tests") { } group("ts2abc_unittests") { + testonly = true deps = [ "tests:ts2abc_tests(${buildtool_linux})" ] + if (host_os == "linux") { + deps += [ "${ts2abc_root}/ts2abc/tests:unittest" ] + } } diff --git a/ts2panda/scripts/run_tests.py b/ts2panda/scripts/run_tests.py index 00c75458dd..7bba08388b 100755 --- a/ts2panda/scripts/run_tests.py +++ b/ts2panda/scripts/run_tests.py @@ -47,9 +47,6 @@ def parse_args(): parser.add_argument('--platform', default="linux", help='platform, as: linux, mac, win') - parser.add_argument('--gn-build', - action='store_true', - help='Whether it is GN compilation') parser.add_argument('--js-file', metavar='FILE', help='The name of the test use case file to execute') @@ -99,8 +96,6 @@ class Ts2abcTests(): run_command(['npm', 'install'], dist_dir) def copy_tests(self): - if self.args.gn_build: - return if os.path.exists(f'{self.dist_dir}/tests'): run_command(['rm', '-rf', f'{self.dist_dir}/tests']) run_command(['cp', '-rf', f'{self.src_dir}/tests', self.dist_dir]) diff --git a/ts2panda/scripts/run_tests_executable.sh b/ts2panda/scripts/run_tests_executable.sh new file mode 100755 index 0000000000..7b91c76a61 --- /dev/null +++ b/ts2panda/scripts/run_tests_executable.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# Copyright (c) 2021 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. + +set -e + +prog_name=$1 +${prog_name} + +if [ $? -ne 0 ]; then + echo "Run [" ${prog_name} "] failed!" + exit 1 +else + echo "Run [" ${prog_name} "] success!" +fi diff --git a/ts2panda/tests/BUILD.gn b/ts2panda/tests/BUILD.gn index b8a513f60c..e820285118 100644 --- a/ts2panda/tests/BUILD.gn +++ b/ts2panda/tests/BUILD.gn @@ -26,7 +26,6 @@ action("ts2abc_tests") { rebase_path(target_out_dir + "/.."), "--node-modules", rebase_path("${node_modules}"), - "--gn-build", ] if (host_toolchain == buildtool_linux) { diff --git a/ts2panda/ts2abc/BUILD.gn b/ts2panda/ts2abc/BUILD.gn index 77d34e3a71..138df5b0a8 100755 --- a/ts2panda/ts2abc/BUILD.gn +++ b/ts2panda/ts2abc/BUILD.gn @@ -21,6 +21,7 @@ config("ts2abc_config") { include_dirs = [ ".", "$jsoncpp_root/include", + "$ark_root/libpandabase", ] if (enable_bytecode_optimizer) { @@ -45,7 +46,7 @@ config("ts2abc_config") { } } -ohos_executable("ts2abc") { +ohos_static_library("ts2abc_static") { sources = [ "ts2abc.cpp" ] configs = [ ":ts2abc_config" ] @@ -89,6 +90,14 @@ ohos_executable("ts2abc") { libs = [ libcpp_static_lib ] } } +} + +ohos_executable("ts2abc") { + sources = [ "main.cpp" ] + + configs = [ ":ts2abc_config" ] + + deps = [ ":ts2abc_static" ] output_name = "js2abc" install_enable = true diff --git a/ts2panda/ts2abc/main.cpp b/ts2panda/ts2abc/main.cpp new file mode 100644 index 0000000000..9399475a3d --- /dev/null +++ b/ts2panda/ts2abc/main.cpp @@ -0,0 +1,93 @@ +/* * Copyright (c) 2021 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 "assembly-type.h" +#include "assembly-program.h" +#include "assembly-emitter.h" +#include "json/json.h" +#include "ts2abc_options.h" +#include "ts2abc.h" + +int main(int argc, const char *argv[]) +{ + panda::PandArgParser argParser; + panda::Span sp(argv, argc); + panda::ts2abc::Options options(sp[0]); + options.AddOptions(&argParser); + + if (!argParser.Parse(argc, argv)) { + std::cerr << argParser.GetErrorString(); + std::cerr << argParser.GetHelpString(); + return RETURN_FAILED; + } + + std::string usage = "Usage: ts2abc [OPTIONS]... [ARGS]..."; + if (options.GetHelpArg()) { + std::cout << usage << std::endl; + std::cout << argParser.GetHelpString(); + return RETURN_SUCCESS; + } + + if (options.GetBcVersionArg() || options.GetBcMinVersionArg()) { + std::string version = options.GetBcVersionArg() ? panda::panda_file::GetVersion(panda::panda_file::version) : + panda::panda_file::GetVersion(panda::panda_file::minVersion); + std::cout << version << std::endl; + return RETURN_SUCCESS; + } + + if ((options.GetOptLevelArg() < O_LEVEL0) || (options.GetOptLevelArg() > O_LEVEL2)) { + std::cerr << "Incorrect optimization level value" << std::endl; + std::cerr << usage << std::endl; + std::cerr << argParser.GetHelpString(); + return RETURN_FAILED; + } + + std::string input, output; + std::string data = ""; + + if (!options.GetCompileByPipeArg()) { + input = options.GetTailArg1(); + output = options.GetTailArg2(); + if (input.empty() || output.empty()) { + std::cerr << "Incorrect args number" << std::endl; + std::cerr << "Usage example: ts2abc test.json test.abc\n" + << std::endl; + std::cerr << usage << std::endl; + std::cerr << argParser.GetHelpString(); + return RETURN_FAILED; + } + + if (!HandleJsonFile(input, data)) { + return RETURN_FAILED; + } + } else { + output = options.GetTailArg1(); + if (output.empty()) { + std::cerr << usage << std::endl; + std::cerr << argParser.GetHelpString(); + return RETURN_FAILED; + } + + if (!ReadFromPipe(data)) { + return RETURN_FAILED; + } + } + + if (!GenerateProgram(data, output, options.GetOptLevelArg(), options.GetOptLogLevelArg())) { + std::cerr << "call GenerateProgram fail" << std::endl; + return RETURN_FAILED; + } + + return RETURN_SUCCESS; +} diff --git a/ts2panda/ts2abc/tests/BUILD.gn b/ts2panda/ts2abc/tests/BUILD.gn new file mode 100644 index 0000000000..fc8e1aa25e --- /dev/null +++ b/ts2panda/ts2abc/tests/BUILD.gn @@ -0,0 +1,41 @@ +# Copyright (c) 2021 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. + +import("//ark/runtime_core/ark_config.gni") +import("//ark/ts2abc/ts2panda/ts2abc_config.gni") + +ts2abc_unittest_action("DebugLogTest") { + sources = [ "debuglog_test.cpp" ] +} + +ts2abc_unittest_action("DebugModeTest") { + sources = [ "debugmode_test.cpp" ] +} + +ts2abc_unittest_action("StringArrTest") { + sources = [ "stringarr_test.cpp" ] +} + +ts2abc_unittest_action("FunctionsTest") { + sources = [ "functions_test.cpp" ] +} + +group("unittest") { + testonly = true + deps = [ + ":DebugLogTestAction", + ":DebugModeTestAction", + ":FunctionsTestAction", + ":StringArrTestAction", + ] +} diff --git a/ts2panda/ts2abc/tests/debuglog_test.cpp b/ts2panda/ts2abc/tests/debuglog_test.cpp new file mode 100644 index 0000000000..2c829cee4f --- /dev/null +++ b/ts2panda/ts2abc/tests/debuglog_test.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 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 "ts2abc.h" + +using namespace testing; +using namespace testing::ext; + +namespace ARK::Ts2Abc::Ts2Abc { + class DebugLogTest : public testing::Test { + public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); + }; + + void DebugLogTest::SetUpTestCase() {} + void DebugLogTest::TearDownTestCase() {} + void DebugLogTest::SetUp() {} + void DebugLogTest::TearDown() {} + + HWTEST_F(DebugLogTest, DebugLogTest_True, TestSize.Level0) + { + Json::Value rootValue; + rootValue["log_enabled"] = true; + ParseLogEnable(rootValue); + ASSERT_TRUE(GetDebugLog() == true); + } + + HWTEST_F(DebugLogTest, DebugLogTest_False, TestSize.Level0) + { + Json::Value rootValue; + rootValue["log_enabled"] = false; + ParseLogEnable(rootValue); + ASSERT_TRUE(GetDebugLog() == false); + } +} \ No newline at end of file diff --git a/ts2panda/ts2abc/tests/debugmode_test.cpp b/ts2panda/ts2abc/tests/debugmode_test.cpp new file mode 100644 index 0000000000..39b9099f53 --- /dev/null +++ b/ts2panda/ts2abc/tests/debugmode_test.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 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 "ts2abc.h" + +using namespace testing; +using namespace testing::ext; + +namespace ARK::Ts2Abc::Ts2Abc { + class DebugModeTest : public testing::Test { + public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); + }; + + void DebugModeTest::SetUpTestCase() {} + void DebugModeTest::TearDownTestCase() {} + void DebugModeTest::SetUp() {} + void DebugModeTest::TearDown() {} + + HWTEST_F(DebugModeTest, DebugModeTest_True, TestSize.Level0) + { + Json::Value rootValue; + rootValue["debug_mode"] = true; + ParseDebugMode(rootValue); + ASSERT_TRUE(GetDebugModeEnabled() == true); + } + + HWTEST_F(DebugModeTest, DebugModeTest_False, TestSize.Level0) + { + Json::Value rootValue; + rootValue["debug_mode"] = false; + ParseDebugMode(rootValue); + ASSERT_TRUE(GetDebugModeEnabled() == false); + } +} \ No newline at end of file diff --git a/ts2panda/ts2abc/tests/functions_test.cpp b/ts2panda/ts2abc/tests/functions_test.cpp new file mode 100644 index 0000000000..700b36d696 --- /dev/null +++ b/ts2panda/ts2abc/tests/functions_test.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2021 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 "gtest/gtest.h" +#include "ts2abc.h" + +using namespace testing; +using namespace testing::ext; +namespace fs = std::filesystem; + +namespace ARK::Ts2Abc::Ts2Abc { + class FunctionTest : public testing::Test { + public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); + }; + + Json::Value function = {}; + + void FunctionTest::SetUpTestCase() {} + void FunctionTest::TearDownTestCase() {} + void FunctionTest::SetUp() + { + std::string file = "../../ark/ts2abc/ts2panda/ts2abc/tests/sources/add.json"; + std::string data = ""; + int ret = HandleJsonFile(file, data); + EXPECT_EQ(ret, 1); + Json::Value rootValue; + ret = ParseJson(data, rootValue); + EXPECT_EQ(ret, RETURN_SUCCESS); + function = rootValue["func_body"]; + } + void FunctionTest::TearDown() {} + + HWTEST_F(FunctionTest, FunctionTest_GetFunctionDefintion, TestSize.Level0) + { + auto pandaFunc = GetFunctionDefintion(function); + EXPECT_EQ(pandaFunc.name, function["name"].asString()); + EXPECT_EQ(pandaFunc.return_type.GetName(), "any"); + auto signature = function["signature"]; + EXPECT_EQ(pandaFunc.params.size(), signature["params"].asUInt()); + EXPECT_EQ(pandaFunc.regs_num, function["regs_num"].asUInt()); + } +} \ No newline at end of file diff --git a/ts2panda/ts2abc/tests/sources/add.json b/ts2panda/ts2abc/tests/sources/add.json new file mode 100644 index 0000000000..a5328fd5b3 --- /dev/null +++ b/ts2panda/ts2abc/tests/sources/add.json @@ -0,0 +1,157 @@ +{ + "type": 0, + "func_body": { + "name": "Add", + "signature": { + "params": 5 + }, + "ins": [ + { + "op": "mov.dyn", + "regs": [ + 4, + 12 + ], + "debug_pos_info": { + "lineNum": 1, + "columnNum": 4 + } + }, + { + "op": "mov.dyn", + "regs": [ + 3, + 11 + ], + "debug_pos_info": { + "lineNum": 1, + "columnNum": 4 + } + }, + { + "op": "mov.dyn", + "regs": [ + 2, + 10 + ], + "debug_pos_info": { + "lineNum": 1, + "columnNum": 4 + } + }, + { + "op": "mov.dyn", + "regs": [ + 1, + 9 + ], + "debug_pos_info": { + "lineNum": 1, + "columnNum": 4 + } + }, + { + "op": "mov.dyn", + "regs": [ + 0, + 8 + ], + "debug_pos_info": { + "lineNum": 1, + "columnNum": 4 + } + }, + { + "op": "ecma.ldlexenvdyn", + "debug_pos_info": { + "lineNum": 1, + "columnNum": 4 + } + }, + { + "op": "sta.dyn", + "regs": [ + 7 + ], + "debug_pos_info": { + "lineNum": 1, + "columnNum": 4 + } + }, + { + "op": "lda.dyn", + "regs": [ + 3 + ], + "debug_pos_info": { + "lineNum": 1, + "columnNum": 11 + } + }, + { + "op": "sta.dyn", + "regs": [ + 6 + ], + "debug_pos_info": { + "lineNum": 1, + "columnNum": 11 + } + }, + { + "op": "lda.dyn", + "regs": [ + 4 + ], + "debug_pos_info": { + "lineNum": 1, + "columnNum": 13 + } + }, + { + "op": "ecma.add2dyn", + "regs": [ + 6 + ], + "debug_pos_info": { + "lineNum": 1, + "columnNum": 11 + } + }, + { + "op": "sta.dyn", + "regs": [ + 5 + ], + "debug_pos_info": { + "lineNum": 1, + "columnNum": 4 + } + }, + { + "op": "lda.dyn", + "regs": [ + 5 + ], + "debug_pos_info": { + "lineNum": 1, + "columnNum": 4 + } + }, + { + "op": "return.dyn", + "debug_pos_info": { + "lineNum": 1, + "columnNum": 4 + } + } + ], + "labels": [], + "regs_num": 8, + "metadata": { + "attribute": "" + }, + "catchTables": [], + "sourceFile": "test.js" + } +} \ No newline at end of file diff --git a/ts2panda/ts2abc/tests/stringarr_test.cpp b/ts2panda/ts2abc/tests/stringarr_test.cpp new file mode 100644 index 0000000000..bc08e8698e --- /dev/null +++ b/ts2panda/ts2abc/tests/stringarr_test.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 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 "ts2abc.h" + +using namespace testing; +using namespace testing::ext; + +namespace ARK::Ts2Abc::Ts2Abc { + class StringArrTest : public testing::Test { + public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); + }; + + void StringArrTest::SetUpTestCase() {} + void StringArrTest::TearDownTestCase() {} + void StringArrTest::SetUp() {} + void StringArrTest::TearDown() {} + + HWTEST_F(StringArrTest, StringArrTest_With0, TestSize.Level0) + { + std::string input = "Hello 000World"; + std::string expected = "Hello 000World"; + std::string output = ParseString(input); + EXPECT_EQ(output, expected); + } + + HWTEST_F(StringArrTest, StringArrTest_HalfUnicodeChar, TestSize.Level0) + { + std::string input = "Hello\\UD834World"; + std::string expected = "Hello\\UD834World"; + std::string output = ParseString(input); + EXPECT_EQ(output, expected); + } +} \ No newline at end of file diff --git a/ts2panda/ts2abc/ts2abc.cpp b/ts2panda/ts2abc/ts2abc.cpp index 8f131798fb..f95fb159c9 100644 --- a/ts2panda/ts2abc/ts2abc.cpp +++ b/ts2panda/ts2abc/ts2abc.cpp @@ -25,6 +25,7 @@ #include "json/json.h" #include "ts2abc_options.h" #include "securec.h" +#include "ts2abc.h" #ifdef ENABLE_BYTECODE_OPT #include "optimize_bytecode.h" @@ -52,22 +53,11 @@ namespace { constexpr bool IS_DEFINED = true; // Temprorary map to simplify debuging std::unordered_map g_opcodeMap = { -#define OPLIST(opcode, name, optype, width, flags, def_idx, use_idxs) { name, panda::pandasm::Opcode::opcode }, +#define OPLIST(opcode, name, optype, width, flags, def_idx, use_idxs) {name, panda::pandasm::Opcode::opcode}, PANDA_INSTRUCTION_LIST(OPLIST) #undef OPLIST - { "", panda::pandasm::Opcode::INVALID }, + {"", panda::pandasm::Opcode::INVALID}, }; - - enum JsonType { - FUNCTION = 0, - RECORD, - STRING, - LITERALBUFFER, - OPTIONS - }; - - const int RETURN_SUCCESS = 0; - const int RETURN_FAILED = 1; } // pandasm hellpers @@ -121,10 +111,30 @@ static bool IsValidInt32(double value) value >= static_cast(std::numeric_limits::min())); } +bool GetDebugLog() +{ + return g_debugLogEnabled; +} + +static void SetDebugLog(bool debugLog) +{ + g_debugLogEnabled = debugLog; +} + +bool GetDebugModeEnabled() +{ + return g_debugModeEnabled; +} + +static void SetDebugModeEnabled(bool value) +{ + g_debugModeEnabled = value; +} + // Unified interface for debug log print static void Logd(const char *format, ...) { - if (g_debugLogEnabled) { + if (GetDebugLog()) { va_list valist; va_start(valist, format); char logMsg[LOG_BUFFER_SIZE]; @@ -195,7 +205,7 @@ static std::string ParseUnicodeEscapeString(const std::string &data) return newData; } -static std::string ParseString(const std::string &data) +std::string ParseString(const std::string &data) { if (data.find("\\u") != std::string::npos) { return ParseUnicodeEscapeString(data); @@ -379,7 +389,7 @@ static void ParseInstructionDebugInfo(const Json::Value &ins, panda::pandasm::In panda::pandasm::debuginfo::Ins insDebug; if (ins.isMember("debug_pos_info") && ins["debug_pos_info"].isObject()) { auto debugPosInfo = ins["debug_pos_info"]; - if (g_debugModeEnabled) { + if (GetDebugModeEnabled()) { if (debugPosInfo.isMember("boundLeft") && debugPosInfo["boundLeft"].isInt()) { insDebug.bound_left = debugPosInfo["boundLeft"].asInt(); } @@ -415,7 +425,7 @@ static panda::pandasm::Ins ParseInstruction(const Json::Value &ins) static int ParseVariablesDebugInfo(const Json::Value &function, panda::pandasm::Function &pandaFunc) { - if (!g_debugModeEnabled) { + if (!GetDebugModeEnabled()) { return RETURN_SUCCESS; } @@ -464,7 +474,7 @@ static int ParseSourceFileDebugInfo(const Json::Value &function, panda::pandasm: pandaFunc.source_file = function["sourceFile"].asString(); } - if (g_debugModeEnabled) { + if (GetDebugModeEnabled()) { if (function.isMember("sourceCode") && function["sourceCode"].isString()) { pandaFunc.source_code = function["sourceCode"].asString(); } @@ -496,7 +506,7 @@ static panda::pandasm::Function::CatchBlock ParsecatchBlock(const Json::Value &c return pandaCatchBlock; } -static panda::pandasm::Function GetFunctionDefintion(const Json::Value &function) +panda::pandasm::Function GetFunctionDefintion(const Json::Value &function) { std::string funcName = ""; if (function.isMember("name") && function["name"].isString()) { @@ -627,7 +637,7 @@ static void GenrateESModuleModeRecord(panda::pandasm::Program &prog, bool module prog.record_table.emplace(ecmaModuleModeRecord.name, std::move(ecmaModuleModeRecord)); } -static int ParseJson(const std::string &data, Json::Value &rootValue) +int ParseJson(const std::string &data, Json::Value &rootValue) { JSONCPP_STRING errs; Json::CharReaderBuilder readerBuilder; @@ -658,18 +668,18 @@ static void ParseModuleMode(const Json::Value &rootValue, panda::pandasm::Progra GenrateESModuleModeRecord(prog, g_moduleModeEnabled); } -static void ParseLogEnable(const Json::Value &rootValue) +void ParseLogEnable(const Json::Value &rootValue) { if (rootValue.isMember("log_enabled") && rootValue["log_enabled"].isBool()) { - g_debugLogEnabled = rootValue["log_enabled"].asBool(); + SetDebugLog(rootValue["log_enabled"].asBool()); } } -static void ParseDebugMode(const Json::Value &rootValue) +void ParseDebugMode(const Json::Value &rootValue) { Logd("-----------------parse debug_mode-----------------"); if (rootValue.isMember("debug_mode") && rootValue["debug_mode"].isBool()) { - g_debugModeEnabled = rootValue["debug_mode"].asBool(); + SetDebugModeEnabled(rootValue["debug_mode"].asBool()); } } @@ -679,7 +689,7 @@ static void ParseOptLevel(const Json::Value &rootValue) if (rootValue.isMember("opt_level") && rootValue["opt_level"].isInt()) { g_optLevel = rootValue["opt_level"].asInt(); } - if (g_debugModeEnabled) { + if (GetDebugModeEnabled()) { g_optLevel = 0; } } @@ -821,9 +831,7 @@ static bool ParseData(const std::string &data, panda::pandasm::Program &prog) return true; } -static bool GenerateProgram(const std::string &data, std::string output, - panda::PandArg optLevelArg, - panda::PandArg optLogLevelArg) +bool GenerateProgram(const std::string &data, std::string output, int optLevel, std::string optLogLevel) { panda::pandasm::Program prog = panda::pandasm::Program(); prog.lang = panda::pandasm::extensions::Language::ECMASCRIPT; @@ -835,8 +843,8 @@ static bool GenerateProgram(const std::string &data, std::string output, Logd("parsing done, calling pandasm\n"); #ifdef ENABLE_BYTECODE_OPT - if (g_optLevel != O_LEVEL0 || optLevelArg.GetValue() != O_LEVEL0) { - std::string optLogLevel = (optLogLevelArg.GetValue() != "error") ? optLogLevelArg.GetValue() : g_optLogLevel; + if (g_optLevel != O_LEVEL0 || optLevel != O_LEVEL0) { + std::string optLogLevel = (optLogLevel != "error") ? optLogLevel : g_optLogLevel; const uint32_t componentMask = panda::Logger::Component::CLASS2PANDA | panda::Logger::Component::ASSEMBLER | panda::Logger::Component::BYTECODE_OPTIMIZER | panda::Logger::Component::COMPILER; @@ -870,7 +878,7 @@ static bool GenerateProgram(const std::string &data, std::string output, return true; } -static bool HandleJsonFile(const std::string &input, std::string &data) +bool HandleJsonFile(const std::string &input, std::string &data) { auto inputAbs = panda::os::file::File::GetAbsolutePath(input); if (!inputAbs) { @@ -904,7 +912,7 @@ static bool HandleJsonFile(const std::string &input, std::string &data) return true; } -static bool ReadFromPipe(std::string &data) +bool ReadFromPipe(std::string &data) { const size_t bufSize = 4096; const size_t fd = 3; @@ -929,101 +937,3 @@ static bool ReadFromPipe(std::string &data) Logd("finish reading from pipe"); return true; } - -int main(int argc, const char *argv[]) -{ - panda::PandArgParser argParser; - panda::Span sp(argv, argc); - panda::ts2abc::Options options(sp[0]); - options.AddOptions(&argParser); - - panda::PandArg sizeStatArg("size-stat", false, "Print panda file size statistic"); - argParser.Add(&sizeStatArg); - panda::PandArg helpArg("help", false, "Print this message and exit"); - argParser.Add(&helpArg); - panda::PandArg optLevelArg("opt-level", 0, - "Optimization level. Possible values: [0, 1, 2]. Default: 0\n 0: no optimizations\n " - "1: basic bytecode optimizations, including valueNumber, lowering, constantResolver, regAccAllocator\n " - "2: (experimental optimizations): Sta/Lda Peephole, Movi/Lda Peephole, Register Coalescing"); - argParser.Add(&optLevelArg); - panda::PandArg optLogLevelArg("opt-log-level", "error", - "Optimization log level. Possible values: ['error', 'debug', 'info', 'fatal']. Default: 'error' "); - argParser.Add(&optLogLevelArg); - panda::PandArg bcVersionArg("bc-version", false, "Print ark bytecode version"); - argParser.Add(&bcVersionArg); - panda::PandArg bcMinVersionArg("bc-min-version", false, "Print ark bytecode minimum supported version"); - argParser.Add(&bcMinVersionArg); - panda::PandArg compileByPipeArg("compile-by-pipe", false, "Compile a json file that is passed by pipe"); - argParser.Add(&compileByPipeArg); - - argParser.EnableTail(); - - panda::PandArg tailArg1("ARG_1", "", "Path to input(json file) or path to output(ark bytecode)" \ - " when 'compile-by-pipe' enabled"); - panda::PandArg tailArg2("ARG_2", "", "Path to output(ark bytecode) or ignore when 'compile-by-pipe'" \ - " enabled"); - argParser.PushBackTail(&tailArg1); - argParser.PushBackTail(&tailArg2); - - if (!argParser.Parse(argc, argv)) { - std::cerr << argParser.GetErrorString(); - std::cerr << argParser.GetHelpString(); - return RETURN_FAILED; - } - - std::string usage = "Usage: ts2abc [OPTIONS]... [ARGS]..."; - if (helpArg.GetValue()) { - std::cout << usage << std::endl; - std::cout << argParser.GetHelpString(); - return RETURN_SUCCESS; - } - - if (bcVersionArg.GetValue() || bcMinVersionArg.GetValue()) { - std::string version = bcVersionArg.GetValue() ? panda::panda_file::GetVersion(panda::panda_file::version) : - panda::panda_file::GetVersion(panda::panda_file::minVersion); - std::cout << version << std::endl; - return RETURN_SUCCESS; - } - - if ((optLevelArg.GetValue() < O_LEVEL0) || (optLevelArg.GetValue() > O_LEVEL2)) { - std::cerr << "Incorrect optimization level value" << std::endl; - std::cerr << usage << std::endl; - std::cerr << argParser.GetHelpString(); - return RETURN_FAILED; - } - - std::string input, output; - std::string data = ""; - - if (!compileByPipeArg.GetValue()) { - input = tailArg1.GetValue(); - output = tailArg2.GetValue(); - if (input.empty() || output.empty()) { - std::cerr << "Incorrect args number" << std::endl; - std::cerr << "Usage example: ts2abc test.json test.abc\n" << std::endl; - std::cerr << usage << std::endl; - std::cerr << argParser.GetHelpString(); - return RETURN_FAILED; - } - if (!HandleJsonFile(input, data)) { - return RETURN_FAILED; - } - } else { - output = tailArg1.GetValue(); - if (output.empty()) { - std::cerr << usage << std::endl; - std::cerr << argParser.GetHelpString(); - return RETURN_FAILED; - } - if (!ReadFromPipe(data)) { - return RETURN_FAILED; - } - } - - if (!GenerateProgram(data, output, optLevelArg, optLogLevelArg)) { - std::cerr << "call GenerateProgram fail" << std::endl; - return RETURN_FAILED; - } - - return RETURN_SUCCESS; -} diff --git a/ts2panda/ts2abc/ts2abc.h b/ts2panda/ts2abc/ts2abc.h new file mode 100644 index 0000000000..62f1ac7bf6 --- /dev/null +++ b/ts2panda/ts2abc/ts2abc.h @@ -0,0 +1,60 @@ +/* * Copyright (c) 2021 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. + */ + +#ifndef PANDA_TS2ABC_GEN_H_ +#define PANDA_TS2ABC_GEN_H_ + +#include +#include +#include +#include +#include +#include + +#include "assembly-type.h" +#include "assembly-program.h" +#include "assembly-emitter.h" +#include "json/json.h" + +enum class JsonType { + FUNCTION = 0, + RECORD, + STRING, + LITERALBUFFER, + OPTIONS +}; + +constexpr int RETURN_SUCCESS = 0; +constexpr int RETURN_FAILED = 1; + +enum class OptLevel { + O_LEVEL0 = 0, + O_LEVEL1, + O_LEVEL2 +}; + +bool HandleJsonFile(const std::string &input, std::string &data); +bool ReadFromPipe(std::string &data); +bool GenerateProgram(const std::string &data, std::string output, + int optLevel, + std::string optLogLevel); +bool GetDebugLog(); +void ParseLogEnable(const Json::Value &rootValue); +bool GetDebugModeEnabled(); +void ParseDebugMode(const Json::Value &rootValue); +std::string ParseString(const std::string &data); +int ParseJson(const std::string &data, Json::Value &rootValue); +panda::pandasm::Function GetFunctionDefintion(const Json::Value &function); + +#endif // PANDA_TS2ABC_GEN_H_ \ No newline at end of file diff --git a/ts2panda/ts2abc/ts2abc_options.h b/ts2panda/ts2abc/ts2abc_options.h index d1d9e9f8ef..4ec2d2adbf 100755 --- a/ts2panda/ts2abc/ts2abc_options.h +++ b/ts2panda/ts2abc/ts2abc_options.h @@ -23,30 +23,195 @@ #include namespace panda::ts2abc { -class Options { -public: + class Options { + public: + explicit Options(const std::string &exePath) : exe_dir_(GetExeDir(exePath)) {} - explicit Options(const std::string &exePath) : exe_dir_(GetExeDir(exePath)) {} + ~Options() = default; - ~Options() = default; + void AddOptions(PandArgParser *parser) + { + parser->Add(&size_stat_arg_); + parser->Add(&help_arg_); + parser->Add(&opt_level_arg_); + parser->Add(&opt_log_level_arg_); + parser->Add(&bc_version_arg_); + parser->Add(&bc_min_version_arg_); + parser->Add(&compile_by_pipe_arg_); + parser->EnableTail(); + parser->PushBackTail(&Tail_Arg1_arg_); + parser->PushBackTail(&Tail_Arg2_arg_); + } - void AddOptions(PandArgParser *parser) {} + bool GetSizeStatArg() const + { + return size_stat_arg_.GetValue(); + } -private: - static std::string GetExeDir(const std::string &exePath) - { - auto pos = exePath.find_last_of('/'); - return exePath.substr(0, pos); - } + void SetSizeStatArg(bool value) + { + size_stat_arg_.SetValue(value); + } - std::string exe_dir_; -}; -} // namespace panda::ts2abc + bool WasSetSizeStatArg() const + { + return size_stat_arg_.WasSet(); + } + + bool GetHelpArg() const + { + return help_arg_.GetValue(); + } + + void SetHelpArg(bool value) + { + help_arg_.SetValue(value); + } + + bool WasSetHelpArg() const + { + return help_arg_.WasSet(); + } + + int GetOptLevelArg() const + { + return opt_level_arg_.GetValue(); + } + + void SetOptLevelArg(int value) + { + opt_level_arg_.SetValue(value); + } + + bool WasSetOptLevelArg() const + { + return opt_level_arg_.WasSet(); + } + + std::string GetOptLogLevelArg() const + { + return opt_log_level_arg_.GetValue(); + } + + void SetOptLogLevelArg(std::string value) + { + opt_log_level_arg_.SetValue(value); + } + + bool WasSetOptLogLevelArg() const + { + return opt_log_level_arg_.WasSet(); + } + + bool GetBcVersionArg() const + { + return bc_version_arg_.GetValue(); + } + + void SetSetBcVersionArg(bool value) + { + bc_version_arg_.SetValue(value); + } + + bool WasBcVersionArg() const + { + return bc_version_arg_.WasSet(); + } + + bool GetBcMinVersionArg() const + { + return bc_min_version_arg_.GetValue(); + } -enum OptLevel { - O_LEVEL0 = 0, - O_LEVEL1, - O_LEVEL2 -}; + void SetBcMinVersionArg(bool value) + { + bc_min_version_arg_.SetValue(value); + } + + bool WasSetBcMinVersionArg() const + { + return bc_min_version_arg_.WasSet(); + } + + bool GetCompileByPipeArg() const + { + return compile_by_pipe_arg_.GetValue(); + } + + void SetCompileByPipeArg(bool value) + { + compile_by_pipe_arg_.SetValue(value); + } + + bool WasSetCompileByPipeArg() const + { + return compile_by_pipe_arg_.WasSet(); + } + + std::string GetTailArg1() const + { + return Tail_Arg1_arg_.GetValue(); + } + + void SetTailArg1(std::string value) + { + Tail_Arg1_arg_.SetValue(value); + } + + bool WasSetTailArg1() const + { + return Tail_Arg1_arg_.WasSet(); + } + + std::string GetTailArg2() const + { + return Tail_Arg2_arg_.GetValue(); + } + + void SetTailArg2(std::string value) + { + Tail_Arg2_arg_.SetValue(value); + } + + bool WasSetTailArg2() const + { + return Tail_Arg2_arg_.WasSet(); + } + + private: + static std::string GetExeDir(const std::string &exePath) + { + auto pos = exePath.find_last_of('/'); + return exePath.substr(0, pos); + } + + std::string exe_dir_; + panda::PandArg size_stat_arg_{ "size-stat", false, + R"(Print panda file size statistic)"}; + panda::PandArg help_arg_{ "help", false, + R"(Print this message and exit)"}; + panda::PandArg opt_level_arg_{ "opt-level", 0, + R"("Optimization level. Possible values: [0, 1, 2]. Default: 0\n" + "0: no optimizations\n " + "1: basic bytecode optimizations, including valueNumber," + "lowering, constantResolver, regAccAllocator\n " + "2: (experimental optimizations): Sta/Lda Peephole, " + "Movi/Lda Peephole, Register Coalescing")"}; + panda::PandArg opt_log_level_arg_{ "opt-log-level", "error", + R"(Optimization log level. Possible values: " + "['error', 'debug', 'info', 'fatal']. Default: 'error' )"}; + panda::PandArg bc_version_arg_{ "bc-version", false, + R"(Print ark bytecode version)"}; + panda::PandArg bc_min_version_arg_{ "bc-min-version", false, + R"(Print ark bytecode minimum supported version)"}; + panda::PandArg compile_by_pipe_arg_{ "compile-by-pipe", false, + R"(Compile a json file that is passed by pipe)"}; + panda::PandArg Tail_Arg1_arg_{ "ARG_1", "", + R"(Path to input(json file) or path to output(ark bytecode)" + " when 'compile-by-pipe' enabled)"}; + panda::PandArg Tail_Arg2_arg_{ "ARG_2", "", + R"(Path to output(ark bytecode) or ignore when 'compile-by-pipe' enabled)"}; + }; +} // namespace panda::ts2abc #endif // PANDA_TS2ABC_OPTIONS_GEN_H_ \ No newline at end of file diff --git a/ts2panda/ts2abc_config.gni b/ts2panda/ts2abc_config.gni index a86ae8032e..d18ae39cf4 100755 --- a/ts2panda/ts2abc_config.gni +++ b/ts2panda/ts2abc_config.gni @@ -12,6 +12,7 @@ # limitations under the License. import("//build/ohos.gni") +import("//build/test.gni") declare_args() { buildtool_linux = "//build/toolchain/linux:clang_x64" @@ -151,3 +152,36 @@ template("ts2abc_gen_abc") { outputs = invoker.out_puts } } + +template("ts2abc_unittest_action") { + _target_name_ = "${target_name}" + invoker.module_out_path = "ark/ts2abc" + + # unittest for phone running + ohos_unittest(_target_name_) { + configs = [ "${ts2abc_root}/ts2abc:ts2abc_config" ] + deps = [ "${ts2abc_root}/ts2abc:ts2abc_static" ] + forward_variables_from(invoker, "*") + } + + _module_out_path_ = invoker.module_out_path + + # unittest for host running + action("${_target_name_}Action") { + testonly = true + _host_test_target_ = ":${_target_name_}(${host_toolchain})" + _root_out_dir_ = get_label_info(_host_test_target_, "root_out_dir") + + deps = [ _host_test_target_ ] + + script = "${ts2abc_root}/scripts/run_tests_executable.sh" + + args = [ rebase_path(_root_out_dir_) + + "/tests/unittest/${_module_out_path_}/${_target_name_}" ] + + inputs = [ + "$_root_out_dir_/tests/unittest/${_module_out_path_}/${_target_name_}", + ] + outputs = [ "$target_out_dir/${_target_name_}/" ] + } +} -- Gitee