From ad4e268dc820d50c839881fbb741b8c987940b5d Mon Sep 17 00:00:00 2001 From: changjiaxing Date: Mon, 4 Jul 2022 10:52:37 +0800 Subject: [PATCH 01/25] Add tonumeric instruction issue:Issuehttps://gitee.com/openharmony/ark_js_runtime/issues/I5F9F6?from=project-issue Signed-off-by: changjiaxing --- test262/es2021_tests.txt | 8 +++++++- ts2panda/src/compiler.ts | 2 +- ts2panda/src/pandagen.ts | 5 +++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/test262/es2021_tests.txt b/test262/es2021_tests.txt index 4b4c272279..e24c362d99 100644 --- a/test262/es2021_tests.txt +++ b/test262/es2021_tests.txt @@ -353,4 +353,10 @@ built-ins/Promise/prototype/finally/this-value-proxy.js built-ins/Promise/prototype/finally/this-value-then-poisoned.js built-ins/Promise/prototype/finally/this-value-then-throws.js built-ins/Promise/prototype/finally/this-value-thenable.js -built-ins/Promise/prototype/finally/this-value-then-not-callable.js \ No newline at end of file +built-ins/Promise/prototype/finally/this-value-then-not-callable.js +built-ins/JSON/stringify/value-bigint.js +built-ins/JSON/stringify/value-bigint-cross-realm.js +built-ins/JSON/stringify/value-bigint-order.js +built-ins/JSON/stringify/value-bigint-replacer.js +built-ins/JSON/stringify/value-bigint-tojson.js +built-ins/JSON/stringify/value-bigint-tojson-receiver.js \ No newline at end of file diff --git a/ts2panda/src/compiler.ts b/ts2panda/src/compiler.ts index 59cd1d776e..fcc8536e36 100644 --- a/ts2panda/src/compiler.ts +++ b/ts2panda/src/compiler.ts @@ -1210,7 +1210,7 @@ export class Compiler { // lvalue var = acc +/- 1 lref.setValue(); // acc = operand_old - pandaGen.toNumber(expr, operandReg); + pandaGen.toNumeric(expr, operandReg); pandaGen.freeTemps(operandReg); } diff --git a/ts2panda/src/pandagen.ts b/ts2panda/src/pandagen.ts index 0db314b6bd..65834994a5 100644 --- a/ts2panda/src/pandagen.ts +++ b/ts2panda/src/pandagen.ts @@ -163,6 +163,7 @@ import { EcmaSub2dyn, EcmaSuspendgenerator, EcmaTonumber, + EcmaTonumeric, EcmaTypeofdyn, EcmaXor2dyn, Imm, @@ -1002,6 +1003,10 @@ export class PandaGen { this.add(node, new EcmaTonumber(arg)); } + toNumeric(node: ts.Node, arg: VReg) { + this.add(node, new EcmaTonumeric(arg)); + } + createGeneratorObj(node: ts.Node, funcObj: VReg) { this.add(node, new EcmaCreategeneratorobj(funcObj)); } -- Gitee From 3fb0fa032a801d644c6bdca98449f93d30407f4b Mon Sep 17 00:00:00 2001 From: qiuyu Date: Tue, 12 Jul 2022 22:28:23 +0800 Subject: [PATCH 02/25] Remove the option enable-typeinfo Remove the option enable-typeinfo as the runtime adaption has been ready Signed-off-by: qiuyu Change-Id: Ic0ff22a1467608ae050809f13b91d8b6e883040b --- ts2panda/src/cmdOptions.ts | 8 -------- ts2panda/src/ts2panda.ts | 1 - ts2panda/ts2abc/ts2abc.cpp | 15 ++------------- 3 files changed, 2 insertions(+), 22 deletions(-) diff --git a/ts2panda/src/cmdOptions.ts b/ts2panda/src/cmdOptions.ts index 4e108670db..3cce689f48 100644 --- a/ts2panda/src/cmdOptions.ts +++ b/ts2panda/src/cmdOptions.ts @@ -45,7 +45,6 @@ const ts2pandaOptions = [ { name: 'dts-type-record', alias: 'q', type: Boolean, defaultValue: false, description: "Record type info for .d.ts files. Default: false" }, { name: 'debug-type', alias: 'g', type: Boolean, defaultValue: false, description: "Print type-related log. Default: false" }, { name: 'output-type', type: Boolean, defaultValue: false, description: "set output type."}, - { name: 'enable-typeinfo', type: Boolean, defaultValue: false, description: "Enable typeinfo of pairs of instruction orders and types" }, { name: 'display-typeinfo', type: Boolean, defaultValue: false, description: "Display typeinfo of pairs of instruction orders and types when enable-typeinfo is true" } ] @@ -55,13 +54,6 @@ export class CmdOptions { private static parsedResult: ts.ParsedCommandLine; private static options: commandLineArgs.CommandLineOptions; - static getEnableTypeinfo(): boolean { - if (!this.options) { - return false; - } - return this.options["enable-typeinfo"]; - } - static getDisplayTypeinfo(): boolean { if (!this.options) { return false; diff --git a/ts2panda/src/ts2panda.ts b/ts2panda/src/ts2panda.ts index 52c1823865..39c62abb7a 100644 --- a/ts2panda/src/ts2panda.ts +++ b/ts2panda/src/ts2panda.ts @@ -195,7 +195,6 @@ export class Ts2Panda { "log_enabled": CmdOptions.isEnableDebugLog(), "opt_level": CmdOptions.getOptLevel(), "opt_log_level": CmdOptions.getOptLogLevel(), - "enable_typeinfo": CmdOptions.getEnableTypeinfo(), "display_typeinfo": CmdOptions.getDisplayTypeinfo() }; let jsonOpt = JSON.stringify(options, null, 2); diff --git a/ts2panda/ts2abc/ts2abc.cpp b/ts2panda/ts2abc/ts2abc.cpp index f66e50ce9f..a457c79bbf 100644 --- a/ts2panda/ts2abc/ts2abc.cpp +++ b/ts2panda/ts2abc/ts2abc.cpp @@ -900,14 +900,6 @@ static void ParseOptLevel(const Json::Value &rootValue) } } -static void ParseEnableTypeinfo(const Json::Value &rootValue) -{ - Logd("-----------------parse enable_typeinfo-----------------"); - if (rootValue.isMember("enable_typeinfo") && rootValue["enable_typeinfo"].isBool()) { - g_enableTypeinfo = rootValue["enable_typeinfo"].asBool(); - } -} - static void ParseDisplayTypeinfo(const Json::Value &rootValue) { Logd("-----------------parse enable_typeinfo-----------------"); @@ -944,7 +936,6 @@ static void ParseOptions(const Json::Value &rootValue, panda::pandasm::Program & ParseLogEnable(rootValue); ParseDebugMode(rootValue); ParseOptLevel(rootValue); - ParseEnableTypeinfo(rootValue); ParseDisplayTypeinfo(rootValue); ParseOptLogLevel(rootValue); } @@ -1318,10 +1309,8 @@ bool GenerateProgram([[maybe_unused]] const std::string &data, const std::string Logd("parsing done, calling pandasm\n"); - if (g_enableTypeinfo) { - TypeAdapter ada(g_displayTypeinfo); - ada.AdaptTypeForProgram(&prog); - } + TypeAdapter ada(g_displayTypeinfo); + ada.AdaptTypeForProgram(&prog); #ifdef ENABLE_BYTECODE_OPT if (g_optLevel != static_cast(OptLevel::O_LEVEL0) || optLevel != static_cast(OptLevel::O_LEVEL0)) { -- Gitee From abe07382558f2d6169d67a2edce1efc19f150922 Mon Sep 17 00:00:00 2001 From: chenqy930 Date: Mon, 11 Jul 2022 16:19:42 +0800 Subject: [PATCH 03/25] Switch component ark_ts2abc to arkcompiler_ets_frontend Signed-off-by: chenqy930 --- bundle.json | 6 +++--- testTs/config.py | 2 +- ts2panda/BUILD.gn | 4 ++-- ts2panda/scripts/npm-install.sh | 2 +- ts2panda/scripts/run_tests.py | 2 +- ts2panda/tests/BUILD.gn | 2 +- ts2panda/ts2abc/BUILD.gn | 2 +- ts2panda/ts2abc/tests/BUILD.gn | 4 ++-- ts2panda/ts2abc/tests/type_adapter_test/BUILD.gn | 8 ++++---- ts2panda/ts2abc_config.gni | 13 ++++++++----- 10 files changed, 24 insertions(+), 21 deletions(-) diff --git a/bundle.json b/bundle.json index 36f2d2379d..e881bff9c3 100644 --- a/bundle.json +++ b/bundle.json @@ -1,10 +1,10 @@ { - "name": "@ohos/ark_ts2abc", + "name": "@ohos/arkcompiler_ets_frontend", "description": "支持应用TS/JS语言代码的编译,行为符合ArkUI框架需要的Strict模式的ES2015标准", "version": "3.1", "license": "Apache V2", "component": { - "name": "ark_frontend_tool", + "name": "ark_ts2abc", "subsystem": "ark", "syscap": [], "features": [], @@ -23,4 +23,4 @@ "test": [] } } -} \ No newline at end of file +} diff --git a/testTs/config.py b/testTs/config.py index 3412291c9d..14ec255458 100644 --- a/testTs/config.py +++ b/testTs/config.py @@ -34,7 +34,7 @@ IMPORT_FILE_PATH = os.path.join("testTs", "import_tests.json") CUR_FILE_DIR = os.path.dirname(__file__) CODE_ROOT = os.path.abspath(os.path.join(CUR_FILE_DIR, "../../..")) ARK_DIR = f"{CODE_ROOT}/out/hispark_taurus/clang_x64/ark/ark" -WORK_PATH = f'{CODE_ROOT}/ark/ts2abc' +WORK_PATH = f'{CODE_ROOT}/arkcompiler/ets_frontend' DEFAULT_ARK_FRONTEND_TOOL = os.path.join(ARK_DIR, "build", "src", "index.js") diff --git a/ts2panda/BUILD.gn b/ts2panda/BUILD.gn index 6ef40ce0df..b51922857a 100755 --- a/ts2panda/BUILD.gn +++ b/ts2panda/BUILD.gn @@ -11,8 +11,8 @@ # 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") +import("//arkcompiler/ets_frontend/ts2panda/ts2abc_config.gni") +import("//arkcompiler/runtime_core/ark_config.gni") import("//build/config/clang/clang.gni") import("//build/ohos.gni") diff --git a/ts2panda/scripts/npm-install.sh b/ts2panda/scripts/npm-install.sh index f669e0589b..479a7c40a7 100755 --- a/ts2panda/scripts/npm-install.sh +++ b/ts2panda/scripts/npm-install.sh @@ -37,4 +37,4 @@ if [ -d "${code_dir}/prebuilts/build-tools/common/ts2abc" ]; then fi mkdir -p ${code_dir}/prebuilts/build-tools/common/ts2abc -/bin/cp -rf ${code_dir}/ark/ts2abc/ts2panda/node_modules ${code_dir}/prebuilts/build-tools/common/ts2abc/ || echo "skip copying due to other thread" +/bin/cp -rf ${code_dir}/arkcompiler/ets_frontend/ts2panda/node_modules ${code_dir}/prebuilts/build-tools/common/ts2abc/ || echo "skip copying due to other thread" diff --git a/ts2panda/scripts/run_tests.py b/ts2panda/scripts/run_tests.py index ed38d57f99..5ef38c453a 100755 --- a/ts2panda/scripts/run_tests.py +++ b/ts2panda/scripts/run_tests.py @@ -27,7 +27,7 @@ CUR_FILE_DIR = os.path.dirname(__file__) TS2PANDA_DIR = os.path.abspath(os.path.join(CUR_FILE_DIR, "..")) CODE_ROOT = os.path.abspath(os.path.join(TS2PANDA_DIR, "../../..")) DEFAULT_TARGET_DIR = os.path.join( - CODE_ROOT, "out/hispark_taurus/clang_x64/obj/ark/ts2abc/ts2panda") + CODE_ROOT, "out/hispark_taurus/clang_x64/obj/arkcompiler/ets_frontend/ts2panda") DEFAULT_NODE_MODULE = os.path.join( CODE_ROOT, "prebuilts/build-tools/common/ts2abc/node_modules") diff --git a/ts2panda/tests/BUILD.gn b/ts2panda/tests/BUILD.gn index a08b272f0f..8f29fa2803 100644 --- a/ts2panda/tests/BUILD.gn +++ b/ts2panda/tests/BUILD.gn @@ -11,7 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//ark/ts2abc/ts2panda/ts2abc_config.gni") +import("//arkcompiler/ets_frontend/ts2panda/ts2abc_config.gni") import("//build/config/clang/clang.gni") import("//build/ohos.gni") diff --git a/ts2panda/ts2abc/BUILD.gn b/ts2panda/ts2abc/BUILD.gn index 54dffea651..7e723caf01 100755 --- a/ts2panda/ts2abc/BUILD.gn +++ b/ts2panda/ts2abc/BUILD.gn @@ -12,7 +12,7 @@ # limitations under the License. if (!defined(ark_independent_build)) { - import("//ark/runtime_core/ark_config.gni") + import("//arkcompiler/runtime_core/ark_config.gni") import("//build/ohos.gni") } else { import("//runtime_core/ark_config.gni") diff --git a/ts2panda/ts2abc/tests/BUILD.gn b/ts2panda/ts2abc/tests/BUILD.gn index f5b42a5d9d..0e58097477 100644 --- a/ts2panda/ts2abc/tests/BUILD.gn +++ b/ts2panda/ts2abc/tests/BUILD.gn @@ -11,8 +11,8 @@ # 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") +import("//arkcompiler/ets_frontend/ts2panda/ts2abc_config.gni") +import("//arkcompiler/runtime_core/ark_config.gni") # ts2abc_unittest_action("DebugLogTest") { # sources = [ "debuglog_test.cpp" ] diff --git a/ts2panda/ts2abc/tests/type_adapter_test/BUILD.gn b/ts2panda/ts2abc/tests/type_adapter_test/BUILD.gn index 117b88df4c..cf9904458c 100644 --- a/ts2panda/ts2abc/tests/type_adapter_test/BUILD.gn +++ b/ts2panda/ts2abc/tests/type_adapter_test/BUILD.gn @@ -11,16 +11,16 @@ # 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") +import("//arkcompiler/ets_frontend/ts2panda/ts2abc_config.gni") +import("//arkcompiler/runtime_core/ark_config.gni") ohos_executable("ts2abc_type_adapter_unit_tests") { sources = [ - "//ark/ts2abc/ts2panda/ts2abc/type_adapter.cpp", + "//arkcompiler/ets_frontend/ts2panda/ts2abc/type_adapter.cpp", "type_adapter_test.cpp", ] - configs = [ "//ark/ts2abc/ts2panda/ts2abc:ts2abc_config" ] + configs = [ "//arkcompiler/ets_frontend/ts2panda/ts2abc:ts2abc_config" ] cflags = [ "-Wno-c++20-designator", diff --git a/ts2panda/ts2abc_config.gni b/ts2panda/ts2abc_config.gni index e77f4a2714..99cc458e35 100755 --- a/ts2panda/ts2abc_config.gni +++ b/ts2panda/ts2abc_config.gni @@ -15,10 +15,10 @@ if (!defined(ark_independent_build)) { import("//build/ohos.gni") import("//build/test.gni") build_root = "//build" - ts2abc_root = "//ark/ts2abc/ts2panda" + ts2abc_root = "//arkcompiler/ets_frontend/ts2panda" } else { import("$build_root/ark.gni") - ts2abc_root = "//ts2abc/ts2panda" + ts2abc_root = "//arkcompiler/ets_frontend/ts2panda" } declare_args() { @@ -49,18 +49,21 @@ if (host_toolchain == buildtool_mac) { ts2abc_build_deps = [ "$ts2abc_root:ts2abc_build_mac($buildtool_mac)" ] ts2abc_build_path = get_label_info("$ts2abc_root:ts2abc_build_mac($buildtool_mac)", - "root_out_dir") + "/obj/ark/ts2abc/ts2panda/build-mac" + "root_out_dir") + + "/obj/arkcompiler/ets_frontend/ts2panda/build-mac" node_path = "${nodejs_dir}/node-v12.18.4-darwin-x64/bin/" } else if (host_toolchain == buildtool_win) { ts2abc_build_deps = [ "$ts2abc_root:ts2abc_build_win($buildtool_win)" ] ts2abc_build_path = get_label_info("$ts2abc_root:ts2abc_build_win($buildtool_win)", - "root_out_dir") + "/obj/ark/ts2abc/ts2panda/build_win" + "root_out_dir") + + "/obj/arkcompiler/ets_frontend/ts2panda/build_win" } else { ts2abc_build_deps = [ "$ts2abc_root:ts2abc_build($buildtool_linux)" ] ts2abc_build_path = get_label_info("$ts2abc_root:ts2abc_build($buildtool_linux)", - "root_out_dir") + "/obj/ark/ts2abc/ts2panda/build" + "root_out_dir") + + "/obj/arkcompiler/ets_frontend/ts2panda/build" node_path = "${nodejs_dir}/node-v12.18.4-linux-x64/bin/" } -- Gitee From 5542537937a44f5c33e9f9c8ac07c95c7afb6986 Mon Sep 17 00:00:00 2001 From: chenqy930 Date: Fri, 15 Jul 2022 10:03:30 +0800 Subject: [PATCH 04/25] update component name and path in readme Signed-off-by: chenqy930 Change-Id: I74bedef801121478f01cea6438987067c25d931b --- OAT.xml | 2 +- README.md | 16 ++++++++-------- README_zh.md | 18 +++++++++--------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/OAT.xml b/OAT.xml index d70eb7ebe4..4efd6e9cf0 100644 --- a/OAT.xml +++ b/OAT.xml @@ -53,7 +53,7 @@ Note:If the text contains special characters, please escape them according to th - + diff --git a/README.md b/README.md index 311ebb5c70..20dd9bce71 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# ts2abc +# ets_frontend -- [ts2abc ](#ts2abc-) +- [ets_frontend ](#ets_frontend-) - [Introduction](#introduction) - [Directory Structure](#directory-structure) - [Build](#Build) @@ -9,14 +9,14 @@ ## Introduction -ts2abc is a front-end tool in the ARK Runtime Subsystem. It converts JavaScript(JS) files into ARK bytecode files. +ets_frontend is a front-end tool in the ARK Runtime Subsystem. It converts JavaScript(JS) files into ARK bytecode files. For more information, see: [ARK Runtime Subsystem](https://gitee.com/openharmony/docs/blob/master/en/readme/ARK-Runtime-Subsystem.md). ## Directory Structure ``` -/ark/ts2abc/ +/arkcompiler/ets_frontend/ ├── test262 # scripts for configuration and running Test262 ├── testTs # system test cases ├── ts2panda @@ -31,7 +31,7 @@ For more information, see: [ARK Runtime Subsystem](https://gitee.com/openharmony ## Build -ts2abc uses the command line interaction mode and converts JS code into ARK bytecode files that can be run on an ARK runtime system. ts2abc supports Windows, Linux, and macOS. Front-end tools, converting JS source code into ARK bytecode, can be built by specifying the `--build-target` with `ark_ts2abc` on Linux. +ets_frontend uses the command line interaction mode and converts JS code into ARK bytecode files that can be run on an ARK runtime system. ets_frontend supports Windows, Linux, and macOS. Front-end tools, converting JS source code into ARK bytecode, can be built by specifying the `--build-target` with `ark_ts2abc` on Linux. ``` $ ./build.sh --product-name hispark_taurus_standard --build-target ark_ts2abc_build @@ -270,8 +270,8 @@ For more information, please see: [ARK-Runtime-Usage-Guide](https://gitee.com/op ## Repositories Involved -[ark\_runtime\_core](https://gitee.com/openharmony/ark_runtime_core) +[arkcompiler\_runtime\_core](https://gitee.com/openharmony/arkcompiler_runtime_core) -[ark\_js\_runtime](https://gitee.com/openharmony/ark_js_runtime) +[arkcompiler\_ets\_runtime](https://gitee.com/openharmony/arkcompiler_ets_runtime) -**[ark\_ts2abc](https://gitee.com/openharmony/ark_ts2abc)** +**[arkcompiler\_ets\_frontend](https://gitee.com/openharmony/arkcompiler_ets_frontend)** diff --git a/README_zh.md b/README_zh.md index 3cf2b8b5b1..37d31bd7e5 100644 --- a/README_zh.md +++ b/README_zh.md @@ -1,6 +1,6 @@ -# ts2abc组件 +# ets_frontend组件 -- [ts2abc组件](#ts2abc组件) +- [ets_frontend组件](#ets_frontend组件) - [简介](#简介) - [目录](#目录) - [编译构建](#编译构建) @@ -9,14 +9,14 @@ ## 简介 -ts2abc组件是方舟运行时子系统的前端工具,支持将JavaScript文件转换为方舟字节码文件。 +ets_frontend组件是方舟运行时子系统的前端工具,支持将JavaScript文件转换为方舟字节码文件。 更多信息请参考:[方舟运行时子系统](https://gitee.com/openharmony/docs/blob/master/zh-cn/readme/ARK-Runtime-Subsystem-zh.md) ## 目录 ``` -/ark/ts2abc/ +/arkcompiler/ets_frontend/ ├── test262 # test262测试配置和运行脚本 ├── testTs # 系统测试目录 ├── ts2panda @@ -31,7 +31,7 @@ ts2abc组件是方舟运行时子系统的前端工具,支持将JavaScript文 ## 编译构建 -ts2abc组件采用命令行交互方式,支持将JavaScript代码转换为方舟字节码文件,使其能够在方舟运行时上运行。支持Windows/Linux/MacOS平台。方舟前端工具在linux平台上可通过全量编译或指定编译前端工具链获取。 +ets_frontend组件采用命令行交互方式,支持将JavaScript代码转换为方舟字节码文件,使其能够在方舟运行时上运行。支持Windows/Linux/MacOS平台。方舟前端工具在linux平台上可通过全量编译或指定编译前端工具链获取。 ``` $ ./build.sh --product-name hispark_taurus_standard --build-target ark_ts2abc_build @@ -41,7 +41,7 @@ $ ./build.sh --product-name hispark_taurus_standard --build-target ark_ts2abc_bu 安装`node`和`npm` -使用ts2abc组件将JavaScript文件转换为方舟字节码文件 +使用ets_frontend组件将JavaScript文件转换为方舟字节码文件 ``` $ cd out/hispark_taurus/clang_x64/ark/ark/build @@ -271,8 +271,8 @@ $ node --expose-gc src/index.js [options] file.js ## 相关仓 -[ark\_runtime\_core](https://gitee.com/openharmony/ark_runtime_core) +[arkcompiler\_runtime\_core](https://gitee.com/openharmony/arkcompiler_runtime_core) -[ark\_js\_runtime](https://gitee.com/openharmony/ark_js_runtime) +[arkcompiler\_ets\_runtime](https://gitee.com/openharmony/arkcompiler_ets_runtime) -**[ark\_ts2abc](https://gitee.com/openharmony/ark_ts2abc)** +**[arkcompiler\_ets\_frontend](https://gitee.com/openharmony/arkcompiler_ets_frontend)** -- Gitee From 2a1be7826230a387b8f9ef6b75616b498de02f33 Mon Sep 17 00:00:00 2001 From: ctw-ian Date: Tue, 5 Jul 2022 20:43:15 +0800 Subject: [PATCH 05/25] Build es2panda for ark front-end Build es2panda for ark front-end with gn and code modification Signed-off-by: ctw-ian Change-Id: If17047a6c735318a9fc1efb20a8b2bfeb97bfe3d --- BUILD.gn | 22 + bundle.json | 4 +- es2panda/BUILD.gn | 480 +++++++++++++++++++ es2panda/aot/main.cpp | 8 +- es2panda/aot/options.cpp | 1 + es2panda/aot/options.h | 2 +- es2panda/compiler/base/condition.cpp | 5 - es2panda/compiler/base/destructuring.cpp | 10 +- es2panda/compiler/base/iterators.cpp | 1 - es2panda/compiler/core/emitter.cpp | 10 +- es2panda/compiler/core/pandagen.cpp | 145 +++--- es2panda/compiler/core/pandagen.h | 2 - es2panda/ir/expressions/binaryExpression.cpp | 1 - es2panda/ir/expressions/chainExpression.cpp | 2 +- es2panda/scripts/gen_isa.sh | 52 ++ es2panda/scripts/gen_keywords.sh | 46 ++ 16 files changed, 715 insertions(+), 76 deletions(-) create mode 100644 BUILD.gn create mode 100644 es2panda/BUILD.gn create mode 100755 es2panda/scripts/gen_isa.sh create mode 100755 es2panda/scripts/gen_keywords.sh diff --git a/BUILD.gn b/BUILD.gn new file mode 100644 index 0000000000..7bf72fa8da --- /dev/null +++ b/BUILD.gn @@ -0,0 +1,22 @@ +# 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. + +import("//ark/runtime_core/ark_config.gni") +import("//build/ohos.gni") + +group("ets_frontend") { + deps = [ + "./ts2panda:ark_ts2abc_build", + "./es2panda:es2panda_build", + ] +} \ No newline at end of file diff --git a/bundle.json b/bundle.json index e881bff9c3..9c1f1915f7 100644 --- a/bundle.json +++ b/bundle.json @@ -18,7 +18,9 @@ "third_party": [] }, "build": { - "sub_component": [], + "sub_component": [ + "//ark/ts2abc:ets_frontend" + ], "inner_kits": [], "test": [] } diff --git a/es2panda/BUILD.gn b/es2panda/BUILD.gn new file mode 100644 index 0000000000..5f6431512f --- /dev/null +++ b/es2panda/BUILD.gn @@ -0,0 +1,480 @@ +# 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. + +import("//ark/runtime_core/ark_config.gni") +import("//build/ohos.gni") + +es2panda_src = [ + "es2panda.cpp", + "binder/binder.cpp", + "binder/declaration.cpp", + "binder/scope.cpp", + "binder/variable.cpp", + "compiler/base/catchTable.cpp", + "compiler/base/condition.cpp", + "compiler/base/destructuring.cpp", + "compiler/base/hoisting.cpp", + "compiler/base/iterators.cpp", + "compiler/base/lexenv.cpp", + "compiler/base/literals.cpp", + "compiler/base/lreference.cpp", + "compiler/core/compileQueue.cpp", + "compiler/core/compilerContext.cpp", + "compiler/core/compilerImpl.cpp", + "compiler/core/dynamicContext.cpp", + "compiler/core/emitter.cpp", + "compiler/core/envScope.cpp", + "compiler/core/function.cpp", + "compiler/core/inlineCache.cpp", + "compiler/core/labelTarget.cpp", + "compiler/core/moduleContext.cpp", + "compiler/core/pandagen.cpp", + "compiler/core/regAllocator.cpp", + "compiler/core/regScope.cpp", + "compiler/core/switchBuilder.cpp", + "compiler/debugger/debuginfoDumper.cpp", + "compiler/function/asyncFunctionBuilder.cpp", + "compiler/function/asyncGeneratorFunctionBuilder.cpp", + "compiler/function/functionBuilder.cpp", + "compiler/function/generatorFunctionBuilder.cpp", + "ir/astDump.cpp", + "ir/base/catchClause.cpp", + "ir/base/classDefinition.cpp", + "ir/base/classProperty.cpp", + "ir/base/decorator.cpp", + "ir/base/metaProperty.cpp", + "ir/base/methodDefinition.cpp", + "ir/base/property.cpp", + "ir/base/scriptFunction.cpp", + "ir/base/spreadElement.cpp", + "ir/base/templateElement.cpp", + "ir/expression.cpp", + "ir/expressions/arrayExpression.cpp", + "ir/expressions/arrowFunctionExpression.cpp", + "ir/expressions/assignmentExpression.cpp", + "ir/expressions/awaitExpression.cpp", + "ir/expressions/binaryExpression.cpp", + "ir/expressions/callExpression.cpp", + "ir/expressions/chainExpression.cpp", + "ir/expressions/classExpression.cpp", + "ir/expressions/conditionalExpression.cpp", + "ir/expressions/functionExpression.cpp", + "ir/expressions/identifier.cpp", + "ir/expressions/importExpression.cpp", + "ir/expressions/literal.cpp", + "ir/expressions/literals/bigIntLiteral.cpp", + "ir/expressions/literals/booleanLiteral.cpp", + "ir/expressions/literals/nullLiteral.cpp", + "ir/expressions/literals/numberLiteral.cpp", + "ir/expressions/literals/regExpLiteral.cpp", + "ir/expressions/literals/stringLiteral.cpp", + "ir/expressions/literals/taggedLiteral.cpp", + "ir/expressions/memberExpression.cpp", + "ir/expressions/newExpression.cpp", + "ir/expressions/objectExpression.cpp", + "ir/expressions/omittedExpression.cpp", + "ir/expressions/sequenceExpression.cpp", + "ir/expressions/superExpression.cpp", + "ir/expressions/taggedTemplateExpression.cpp", + "ir/expressions/templateLiteral.cpp", + "ir/expressions/thisExpression.cpp", + "ir/expressions/unaryExpression.cpp", + "ir/expressions/updateExpression.cpp", + "ir/expressions/yieldExpression.cpp", + "ir/module/exportAllDeclaration.cpp", + "ir/module/exportDefaultDeclaration.cpp", + "ir/module/exportNamedDeclaration.cpp", + "ir/module/exportSpecifier.cpp", + "ir/module/importDeclaration.cpp", + "ir/module/importDefaultSpecifier.cpp", + "ir/module/importNamespaceSpecifier.cpp", + "ir/module/importSpecifier.cpp", + "ir/statement.cpp", + "ir/statements/blockStatement.cpp", + "ir/statements/breakStatement.cpp", + "ir/statements/classDeclaration.cpp", + "ir/statements/continueStatement.cpp", + "ir/statements/debuggerStatement.cpp", + "ir/statements/doWhileStatement.cpp", + "ir/statements/emptyStatement.cpp", + "ir/statements/expressionStatement.cpp", + "ir/statements/forInStatement.cpp", + "ir/statements/forOfStatement.cpp", + "ir/statements/forUpdateStatement.cpp", + "ir/statements/functionDeclaration.cpp", + "ir/statements/ifStatement.cpp", + "ir/statements/labelledStatement.cpp", + "ir/statements/loopStatement.cpp", + "ir/statements/returnStatement.cpp", + "ir/statements/switchCaseStatement.cpp", + "ir/statements/switchStatement.cpp", + "ir/statements/throwStatement.cpp", + "ir/statements/tryStatement.cpp", + "ir/statements/variableDeclaration.cpp", + "ir/statements/variableDeclarator.cpp", + "ir/statements/whileStatement.cpp", + "ir/ts/tsAnyKeyword.cpp", + "ir/ts/tsArrayType.cpp", + "ir/ts/tsAsExpression.cpp", + "ir/ts/tsBigintKeyword.cpp", + "ir/ts/tsBooleanKeyword.cpp", + "ir/ts/tsClassImplements.cpp", + "ir/ts/tsConditionalType.cpp", + "ir/ts/tsConstructorType.cpp", + "ir/ts/tsEnumDeclaration.cpp", + "ir/ts/tsEnumMember.cpp", + "ir/ts/tsExternalModuleReference.cpp", + "ir/ts/tsFunctionType.cpp", + "ir/ts/tsImportEqualsDeclaration.cpp", + "ir/ts/tsImportType.cpp", + "ir/ts/tsIndexSignature.cpp", + "ir/ts/tsIndexedAccessType.cpp", + "ir/ts/tsInferType.cpp", + "ir/ts/tsInterfaceBody.cpp", + "ir/ts/tsInterfaceDeclaration.cpp", + "ir/ts/tsInterfaceHeritage.cpp", + "ir/ts/tsIntersectionType.cpp", + "ir/ts/tsLiteralType.cpp", + "ir/ts/tsMappedType.cpp", + "ir/ts/tsMethodSignature.cpp", + "ir/ts/tsModuleBlock.cpp", + "ir/ts/tsModuleDeclaration.cpp", + "ir/ts/tsNamedTupleMember.cpp", + "ir/ts/tsNeverKeyword.cpp", + "ir/ts/tsNonNullExpression.cpp", + "ir/ts/tsNullKeyword.cpp", + "ir/ts/tsNumberKeyword.cpp", + "ir/ts/tsObjectKeyword.cpp", + "ir/ts/tsParameterProperty.cpp", + "ir/ts/tsParenthesizedType.cpp", + "ir/ts/tsPrivateIdentifier.cpp", + "ir/ts/tsPropertySignature.cpp", + "ir/ts/tsQualifiedName.cpp", + "ir/ts/tsSignatureDeclaration.cpp", + "ir/ts/tsStringKeyword.cpp", + "ir/ts/tsThisType.cpp", + "ir/ts/tsTupleType.cpp", + "ir/ts/tsTypeAliasDeclaration.cpp", + "ir/ts/tsTypeAssertion.cpp", + "ir/ts/tsTypeLiteral.cpp", + "ir/ts/tsTypeOperator.cpp", + "ir/ts/tsTypeParameter.cpp", + "ir/ts/tsTypeParameterDeclaration.cpp", + "ir/ts/tsTypeParameterInstantiation.cpp", + "ir/ts/tsTypePredicate.cpp", + "ir/ts/tsTypeQuery.cpp", + "ir/ts/tsTypeReference.cpp", + "ir/ts/tsUndefinedKeyword.cpp", + "ir/ts/tsUnionType.cpp", + "ir/ts/tsUnknownKeyword.cpp", + "ir/ts/tsVoidKeyword.cpp", + "lexer/keywordsUtil.cpp", + "lexer/lexer.cpp", + "lexer/regexp/regexp.cpp", + "lexer/token/sourceLocation.cpp", + "lexer/token/token.cpp", + "parser/context/parserContext.cpp", + "parser/expressionParser.cpp", + "parser/parserImpl.cpp", + "parser/program/program.cpp", + "parser/statementParser.cpp", + "typescript/checker.cpp", + "typescript/core/binaryLikeExpression.cpp", + "typescript/core/destructuring.cpp", + "typescript/core/function.cpp", + "typescript/core/generics.cpp", + "typescript/core/helpers.cpp", + "typescript/core/object.cpp", + "typescript/core/typeCreation.cpp", + "typescript/core/typeElaboration.cpp", + "typescript/core/typeRelation.cpp", + "typescript/core/util.cpp", + "typescript/types/anyType.cpp", + "typescript/types/arrayType.cpp", + "typescript/types/bigintLiteralType.cpp", + "typescript/types/bigintType.cpp", + "typescript/types/booleanLiteralType.cpp", + "typescript/types/booleanType.cpp", + "typescript/types/constructorType.cpp", + "typescript/types/enumLiteralType.cpp", + "typescript/types/enumType.cpp", + "typescript/types/functionType.cpp", + "typescript/types/globalTypesHolder.cpp", + "typescript/types/indexInfo.cpp", + "typescript/types/interfaceType.cpp", + "typescript/types/neverType.cpp", + "typescript/types/nonPrimitiveType.cpp", + "typescript/types/nullType.cpp", + "typescript/types/numberLiteralType.cpp", + "typescript/types/numberType.cpp", + "typescript/types/objectDescriptor.cpp", + "typescript/types/objectLiteralType.cpp", + "typescript/types/objectType.cpp", + "typescript/types/signature.cpp", + "typescript/types/stringLiteralType.cpp", + "typescript/types/stringType.cpp", + "typescript/types/tupleType.cpp", + "typescript/types/type.cpp", + "typescript/types/typeParameter.cpp", + "typescript/types/typeReference.cpp", + "typescript/types/typeRelation.cpp", + "typescript/types/undefinedType.cpp", + "typescript/types/unionType.cpp", + "typescript/types/unknownType.cpp", + "typescript/types/voidType.cpp", + "util/bitset.cpp", + "util/helpers.cpp", + "util/ustring.cpp" +] + +config("es2abc_config_src") { + include_dirs = [ + "./", + "./binder", + "./util", + "./compiler/base", + "./compiler/core", + "./compiler/debugger", + "./compiler/function", + "./ir", + "./ir/base", + "./ir/expressions", + "./ir/module", + "./ir/statements", + "./ir/ts", + "./parser", + "./parser/context", + "./lexer", + "./lexer/token", + "./lexer/regexp", + "./typescript", + "./typescript/types" + ] + + cflags = [ "-fexceptions" ] +} + +config("es2abc_config_common") { + + configs = [ + "$ark_root:ark_config", + "$sdk_libc_secshared_config", + "$ark_root/libpandafile:arkfile_public_config", + "$ark_root/libpandabase:arkbase_public_config", + "$ark_root/runtime:arkruntime_public_config", + "$ark_root/assembler:arkassembler_public_config", + ":es2abc_config_src", + ] + + if (enable_bytecode_optimizer) { + defines = [ "ENABLE_BYTECODE_OPT" ] + configs += [ + "$ark_root/compiler:arkcompiler_public_config", + "$ark_root/bytecode_optimizer:bytecodeopt_public_config", + ] + } +} + +# generate headers for es2panda parser +generated_header_dir = "${target_out_dir}/gen" +action_foreach("gen_keywords_headers") { + template_files = [ + "keywords.h.erb", + "keywordsMap.h.erb", + ] + keywords_templates_dir = "./lexer/templates" + keywords_generator = "./lexer/scripts/keywords.rb" + + sources = [] + foreach(file, template_files) { + sources += [ rebase_path("${keywords_templates_dir}/${file}") ] + } + outputs = [ "${generated_header_dir}/{{source_name_part}}" ] + + script = "scripts/gen_keywords.sh" + inputs = [ "${keywords_generator}" ] + args = [ + "-g", rebase_path("${keywords_generator}"), + "-t", "{{source}}", + "-o", "{{source_name_part}}", + "-d", rebase_path("${generated_header_dir}"), + ] +} + +# generate headers for es2panda compiler +isa_gen = "${ark_root}/isa/gen.rb" +isa_gen_data = "$root_gen_dir/isa/isa.yaml" +isa_gen_require = "${ark_root}/isa/isapi.rb" +action_foreach("gen_isa_headers") { + + deps = [ "//ark/runtime_core/isa:isa_combine" ] + + template_files = [ + "isa.h.erb", + "formats.h.erb", + ] + keywords_templates_dir = "./compiler/templates" + + sources = [] + foreach(file, template_files) { + sources += [ rebase_path("${keywords_templates_dir}/${file}") ] + } + outputs = [ "${generated_header_dir}/{{source_name_part}}" ] + + script = "scripts/gen_isa.sh" + inputs = [ + "${isa_gen}", + "${isa_gen_data}", + "${isa_gen_require}" + ] + args = [ + "-g", rebase_path("${isa_gen}"), + "-t", "{{source}}", + "-a", rebase_path("${isa_gen_data}"), + "-o", "{{source_name_part}}", + "-d", rebase_path("${generated_header_dir}"), + "-r", rebase_path("${isa_gen_require}"), + ] +} + +ohos_static_library("es2panda_lib") { + sources = es2panda_src + use_exceptions = true + + configs = [ ":es2abc_config_common" ] + + include_dirs = [ + "${target_out_dir}", + "//third_party/icu/icu4c/source/common", + "//third_party/icu/icu4c/source/i18n", + "//third_party/icu/icu4c/source ", + ] + + deps = [ + ":gen_keywords_headers", + ":gen_isa_headers", + "$ark_root/assembler:libarkassembler_frontend_static", + "$ark_root/libpandabase:libarkbase_frontend_static", + "$ark_root/libpandafile:libarkfile_frontend_static", + "$ark_root/libziparchive:libarkziparchive_frontend_static", + "//third_party/icu/icu4c:static_icuuc", + ] + + cflags = [ + "-Wno-implicit-fallthrough", + ] +} + +ohos_executable("es2panda") { + use_exceptions = true + sources = [ + "aot/options.cpp", + "aot/main.cpp", + ] + + include_dirs = [ "./aot" ] + + configs = [ ":es2abc_config_common" ] + + deps = [ + ":es2panda_lib", + ] + + if (is_linux) { + if (build_public_version) { + ldflags = [ "-static-libstdc++" ] + } else { + libs = [ libcpp_static_lib ] + } + } + + if (enable_bytecode_optimizer) { + deps += [ + "$ark_root/bytecode_optimizer:libarkbytecodeopt_frontend_static", + "$ark_root/compiler:libarkcompiler_frontend_static", + ] + } + + output_name = "es2abc" + install_enable = true + subsystem_name = "ark" +} + +if (is_linux) { + ohos_copy("es2abc_build") { + deps = [ ":es2panda" ] + sources = [ "${root_out_dir}/ark/ark/es2abc" ] + outputs = [ "${target_out_dir}/es2abc-tmp" ] + module_source_dir = "${root_out_dir}/ark/ark" + module_install_name = "es2abc" + } + + ohos_copy("es2abc_build_ets") { + deps = [ ":es2panda" ] + sources = [ "${root_out_dir}/ark/ark/es2abc" ] + outputs = [ "${root_out_dir}/ark/ark/es2abc-ets" ] + module_source_dir = "${root_out_dir}/ark/ark" + module_install_name = "es2abc" + } +} + +if (is_mingw) { + ohos_copy("es2abc_build_win") { + deps = [ ":es2panda" ] + sources = [ "${root_out_dir}/ark/ark/es2abc.exe" ] + outputs = [ "${target_out_dir}/es2abc-tmp" ] + module_source_dir = "${root_out_dir}/ark/ark" + module_install_name = "es2abc.exe" + } + + ohos_copy("es2abc_build_win_ets") { + deps = [ ":es2panda" ] + sources = [ "${root_out_dir}/ark/ark/es2abc.exe" ] + outputs = [ "${root_out_dir}/ark/ark/es2abc-win-ets" ] + module_source_dir = "${root_out_dir}/ark/ark" + module_install_name = "es2abc.exe" + } +} + +if (is_mac) { + ohos_copy("es2abc_build_mac") { + deps = [ ":es2panda" ] + sources = [ "${root_out_dir}/ark/ark/es2abc" ] + outputs = [ "${target_out_dir}/es2abc-tmp" ] + module_source_dir = "${root_out_dir}/ark/ark" + module_install_name = "es2abc" + } + + ohos_copy("es2abc_build_mac_ets") { + deps = [ ":es2panda" ] + sources = [ "${root_out_dir}/ark/ark/es2abc" ] + outputs = [ "${root_out_dir}/ark/ark/es2abc-mac-ets" ] + module_source_dir = "${root_out_dir}/ark/ark" + module_install_name = "es2abc" + } +} + +group("es2panda_build") { + build_tool_linux = "//build/toolchain/linux:clang_x64" + if (host_os == "linux") { + deps = [ ":es2panda(${build_tool_linux})" ] + } + + if (host_os == "mac") { + deps = [ ":es2panda(//build/toolchain/mac:clang_x64)" ] + } +} + +group("es2panda_build_win") { + deps = [ ":es2panda(//build/toolchain/mingw:mingw_x86_64)" ] +} diff --git a/es2panda/aot/main.cpp b/es2panda/aot/main.cpp index 8dbd680977..ad0dde48b4 100644 --- a/es2panda/aot/main.cpp +++ b/es2panda/aot/main.cpp @@ -14,12 +14,18 @@ */ #include +#ifdef ENABLE_BYTECODE_OPT #include #include +#else +#include +#include +#include +#endif #include #include #include -#include +#include #include #include diff --git a/es2panda/aot/options.cpp b/es2panda/aot/options.cpp index 9be3f001c5..9f72eac598 100644 --- a/es2panda/aot/options.cpp +++ b/es2panda/aot/options.cpp @@ -18,6 +18,7 @@ #include #include +#include namespace panda::es2panda::aot { diff --git a/es2panda/aot/options.h b/es2panda/aot/options.h index af8c8e3093..9b681e7f11 100644 --- a/es2panda/aot/options.h +++ b/es2panda/aot/options.h @@ -17,7 +17,7 @@ #define ES2PANDA_AOT_OPTIONS_H #include -#include +#include #include #include diff --git a/es2panda/compiler/base/condition.cpp b/es2panda/compiler/base/condition.cpp index 644e9195fe..577d8c63e4 100644 --- a/es2panda/compiler/base/condition.cpp +++ b/es2panda/compiler/base/condition.cpp @@ -51,11 +51,9 @@ void Condition::Compile(PandaGen *pg, const ir::Expression *expr, Label *falseLa } case lexer::TokenType::PUNCTUATOR_LOGICAL_AND: { binExpr->Left()->Compile(pg); - pg->ToBoolean(binExpr); pg->BranchIfFalse(binExpr, falseLabel); binExpr->Right()->Compile(pg); - pg->ToBoolean(binExpr); pg->BranchIfFalse(binExpr, falseLabel); return; } @@ -63,11 +61,9 @@ void Condition::Compile(PandaGen *pg, const ir::Expression *expr, Label *falseLa auto *endLabel = pg->AllocLabel(); binExpr->Left()->Compile(pg); - pg->ToBoolean(binExpr); pg->BranchIfTrue(binExpr, endLabel); binExpr->Right()->Compile(pg); - pg->ToBoolean(binExpr); pg->BranchIfFalse(binExpr, falseLabel); pg->SetLabel(binExpr, endLabel); return; @@ -87,7 +83,6 @@ void Condition::Compile(PandaGen *pg, const ir::Expression *expr, Label *falseLa // General case including some binExpr i.E.(a+b) expr->Compile(pg); - pg->ToBoolean(expr); pg->BranchIfFalse(expr, falseLabel); } diff --git a/es2panda/compiler/base/destructuring.cpp b/es2panda/compiler/base/destructuring.cpp index 7ff756529f..5b3ac2e0c1 100644 --- a/es2panda/compiler/base/destructuring.cpp +++ b/es2panda/compiler/base/destructuring.cpp @@ -223,9 +223,15 @@ static void GenObject(PandaGen *pg, const ir::ObjectExpression *object, VReg rhs if (properties.empty() || properties.back()->IsRestElement()) { auto *notNullish = pg->AllocLabel(); + auto *nullish = pg->AllocLabel(); - pg->LoadAccumulator(object, rhs); - pg->BranchIfCoercible(object, notNullish); + pg->LoadConst(object, Constant::JS_NULL); + pg->Condition(object, lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL, rhs, nullish); + pg->LoadConst(object, Constant::JS_UNDEFINED); + pg->Condition(object, lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL, rhs, nullish); + pg->Branch(object, notNullish); + + pg->SetLabel(object, nullish); pg->ThrowObjectNonCoercible(object); pg->SetLabel(object, notNullish); diff --git a/es2panda/compiler/base/iterators.cpp b/es2panda/compiler/base/iterators.cpp index 1bf7ad8887..8ba4d12a11 100644 --- a/es2panda/compiler/base/iterators.cpp +++ b/es2panda/compiler/base/iterators.cpp @@ -70,7 +70,6 @@ void Iterator::Next() const void Iterator::Complete() const { pg_->LoadObjByName(node_, nextResult_, "done"); - pg_->ToBoolean(node_); } void Iterator::Value() const diff --git a/es2panda/compiler/core/emitter.cpp b/es2panda/compiler/core/emitter.cpp index 6e617cb41f..c25c579fe2 100644 --- a/es2panda/compiler/core/emitter.cpp +++ b/es2panda/compiler/core/emitter.cpp @@ -119,11 +119,11 @@ void FunctionEmitter::GenBufferLiterals(const LiteralBuffer *buff) valueLit.value_ = literal->GetMethod().Mutf8(); break; } - case ir::LiteralTag::ASYNC_GENERATOR_METHOD: { - valueLit.tag_ = panda::panda_file::LiteralTag::ASYNCGENERATORMETHOD; - valueLit.value_ = literal->GetMethod().Mutf8(); - break; - } + // case ir::LiteralTag::ASYNC_GENERATOR_METHOD: { + // valueLit.tag_ = panda::panda_file::LiteralTag::ASYNCGENERATORMETHOD; + // valueLit.value_ = literal->GetMethod().Mutf8(); + // break; + // } case ir::LiteralTag::NULL_VALUE: { valueLit.tag_ = panda::panda_file::LiteralTag::NULLVALUE; valueLit.value_ = static_cast(0); diff --git a/es2panda/compiler/core/pandagen.cpp b/es2panda/compiler/core/pandagen.cpp index 7d58fa71c4..5c4ea92669 100644 --- a/es2panda/compiler/core/pandagen.cpp +++ b/es2panda/compiler/core/pandagen.cpp @@ -415,7 +415,7 @@ void PandaGen::StoreGlobalVar(const ir::AstNode *node, const util::StringView &n void PandaGen::StoreGlobalLet(const ir::AstNode *node, const util::StringView &name) { - sa_.Emit(node, name); + sa_.Emit(node, name); strings_.insert(name); } @@ -646,7 +646,7 @@ void PandaGen::Unary(const ir::AstNode *node, lexer::TokenType op, VReg operand) break; } case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK: { - sa_.Emit(node); + Negate(node); break; } case lexer::TokenType::PUNCTUATOR_PLUS_PLUS: { @@ -784,19 +784,25 @@ void PandaGen::Binary(const ir::AstNode *node, lexer::TokenType op, VReg lhs) void PandaGen::BranchIfUndefined(const ir::AstNode *node, Label *target) { - sa_.Emit(node); - BranchIfTrue(node, target); + VReg tmp = AllocReg(); + StoreAccumulator(node, tmp); + sa_.Emit(node); + ra_.Emit(node, tmp); + sa_.Emit(node, target); } void PandaGen::BranchIfNotUndefined(const ir::AstNode *node, Label *target) { - sa_.Emit(node); - BranchIfFalse(node, target); + VReg tmp = AllocReg(); + StoreAccumulator(node, tmp); + sa_.Emit(node); + ra_.Emit(node, tmp); + sa_.Emit(node, target); } void PandaGen::BranchIfTrue(const ir::AstNode *node, Label *target) { - sa_.Emit(node, target); + sa_.Emit(node, target); } void PandaGen::BranchIfNotTrue(const ir::AstNode *node, Label *target) @@ -807,13 +813,7 @@ void PandaGen::BranchIfNotTrue(const ir::AstNode *node, Label *target) void PandaGen::BranchIfFalse(const ir::AstNode *node, Label *target) { - sa_.Emit(node, target); -} - -void PandaGen::BranchIfCoercible(const ir::AstNode *node, Label *target) -{ - sa_.Emit(node); - BranchIfTrue(node, target); + sa_.Emit(node, target); } void PandaGen::EmitThrow(const ir::AstNode *node) @@ -823,12 +823,13 @@ void PandaGen::EmitThrow(const ir::AstNode *node) void PandaGen::EmitRethrow(const ir::AstNode *node) { - sa_.Emit(node); + // commented for compile workaround + // sa_.Emit(node); } void PandaGen::EmitReturn(const ir::AstNode *node) { - sa_.Emit(node); + sa_.Emit(node); } void PandaGen::EmitReturnUndefined(const ir::AstNode *node) @@ -888,25 +889,25 @@ void PandaGen::Call(const ir::AstNode *node, VReg startReg, size_t argCount) switch (argCount) { case 0: { // 0 args - ra_.Emit(node, callee); + ra_.Emit(node, callee); break; } case 1: { // 1 arg VReg arg0 = callee + 1; - ra_.Emit(node, callee, arg0); + ra_.Emit(node, callee, arg0); break; } case 2: { // 2 args VReg arg0 = callee + 1; VReg arg1 = arg0 + 1; - ra_.Emit(node, callee, arg0, arg1); + ra_.Emit(node, callee, arg0, arg1); break; } case 3: { // 3 args VReg arg0 = callee + 1; VReg arg1 = arg0 + 1; VReg arg2 = arg1 + 1; - ra_.Emit(node, callee, arg0, arg1, arg2); + ra_.Emit(node, callee, arg0, arg1, arg2); break; } default: { @@ -938,21 +939,22 @@ void PandaGen::LoadHomeObject(const ir::AstNode *node) void PandaGen::DefineFunction(const ir::AstNode *node, const ir::ScriptFunction *realNode, const util::StringView &name) { + auto formal_param_cnt = FormalParametersCount(); if (realNode->IsAsync()) { if (realNode->IsGenerator()) { - ra_.Emit(node, name, LexEnv()); + // TODO(): async generator } else { - ra_.Emit(node, name, LexEnv()); + ra_.Emit(node, name, static_cast(formal_param_cnt), LexEnv()); } } else if (realNode->IsGenerator()) { - ra_.Emit(node, name, LexEnv()); + ra_.Emit(node, name, static_cast(formal_param_cnt), LexEnv()); } else if (realNode->IsArrow()) { LoadHomeObject(node); - ra_.Emit(node, name, LexEnv()); + ra_.Emit(node, name, static_cast(formal_param_cnt), LexEnv()); } else if (realNode->IsMethod()) { - ra_.Emit(node, name, LexEnv()); + ra_.Emit(node, name, static_cast(formal_param_cnt), LexEnv()); } else { - ra_.Emit(node, name, LexEnv()); + ra_.Emit(node, name, static_cast(formal_param_cnt), LexEnv()); } strings_.insert(name); @@ -980,12 +982,14 @@ void PandaGen::GetUnmappedArgs(const ir::AstNode *node) void PandaGen::Negate(const ir::AstNode *node) { - sa_.Emit(node); -} - -void PandaGen::ToBoolean(const ir::AstNode *node) -{ - sa_.Emit(node); + auto *falseLabel = AllocLabel(); + auto *endLabel = AllocLabel(); + BranchIfTrue(node, falseLabel); + LoadConst(node, Constant::JS_TRUE); + Branch(node, endLabel); + SetLabel(node, falseLabel); + LoadConst(node, Constant::JS_FALSE); + SetLabel(node, endLabel); } void PandaGen::ToNumber(const ir::AstNode *node, VReg arg) @@ -995,8 +999,9 @@ void PandaGen::ToNumber(const ir::AstNode *node, VReg arg) void PandaGen::GetMethod(const ir::AstNode *node, VReg obj, const util::StringView &name) { - ra_.Emit(node, name, obj); - strings_.insert(name); + // commented for compile workaround + // ra_.Emit(node, name, obj); + // strings_.insert(name); } void PandaGen::CreateGeneratorObj(const ir::AstNode *node, VReg funcObj) @@ -1006,32 +1011,38 @@ void PandaGen::CreateGeneratorObj(const ir::AstNode *node, VReg funcObj) void PandaGen::CreateAsyncGeneratorObj(const ir::AstNode *node, VReg funcObj) { - ra_.Emit(node, funcObj); + // commented for compile workaround + // ra_.Emit(node, funcObj); } void PandaGen::CreateIterResultObject(const ir::AstNode *node, bool done) { - ra_.Emit(node, static_cast(done)); + // commented for compile workaround + // ra_.Emit(node, static_cast(done)); } void PandaGen::SuspendGenerator(const ir::AstNode *node, VReg genObj) { - ra_.Emit(node, genObj); + // commented for compile workaround + // ra_.Emit(node, genObj); } void PandaGen::SuspendAsyncGenerator(const ir::AstNode *node, VReg asyncGenObj) { - ra_.Emit(node, asyncGenObj); + // commented for compile workaround + // ra_.Emit(node, asyncGenObj); } void PandaGen::GeneratorYield(const ir::AstNode *node, VReg genObj) { - ra_.Emit(node, genObj, static_cast(GeneratorState::SUSPENDED_YIELD)); + // commented for compile workaround + // ra_.Emit(node, genObj, static_cast(GeneratorState::SUSPENDED_YIELD)); } void PandaGen::GeneratorComplete(const ir::AstNode *node, VReg genObj) { - ra_.Emit(node, genObj, static_cast(GeneratorState::COMPLETED)); + // commented for compile workaround + // ra_.Emit(node, genObj, static_cast(GeneratorState::COMPLETED)); } void PandaGen::ResumeGenerator(const ir::AstNode *node, VReg genObj) @@ -1051,27 +1062,32 @@ void PandaGen::AsyncFunctionEnter(const ir::AstNode *node) void PandaGen::AsyncFunctionAwait(const ir::AstNode *node, VReg asyncFuncObj) { - ra_.Emit(node, asyncFuncObj); + // commented for compile workaround + // ra_.Emit(node, asyncFuncObj); } void PandaGen::AsyncFunctionResolve(const ir::AstNode *node, VReg asyncFuncObj) { - ra_.Emit(node, asyncFuncObj); + // commented for compile workaround + // ra_.Emit(node, asyncFuncObj); } void PandaGen::AsyncFunctionReject(const ir::AstNode *node, VReg asyncFuncObj) { - ra_.Emit(node, asyncFuncObj); + // commented for compile workaround + // ra_.Emit(node, asyncFuncObj); } void PandaGen::AsyncGeneratorResolve(const ir::AstNode *node, VReg asyncGenObj) { - ra_.Emit(node, asyncGenObj); + // commented for compile workaround + // ra_.Emit(node, asyncGenObj); } void PandaGen::AsyncGeneratorReject(const ir::AstNode *node, VReg asyncGenObj) { - ra_.Emit(node, asyncGenObj); + // commented for compile workaround + // ra_.Emit(node, asyncGenObj); } void PandaGen::GetTemplateObject(const ir::AstNode *node, VReg value) @@ -1243,7 +1259,9 @@ void PandaGen::StoreArraySpread(const ir::AstNode *node, VReg array, VReg index) void PandaGen::ThrowIfNotObject(const ir::AstNode *node) { - ra_.Emit(node); + // commented for compile workaround + VReg value = AllocReg(); + ra_.Emit(node, value); } void PandaGen::ThrowThrowNotExist(const ir::AstNode *node) @@ -1258,7 +1276,8 @@ void PandaGen::GetIterator(const ir::AstNode *node) void PandaGen::GetAsyncIterator(const ir::AstNode *node) { - sa_.Emit(node); + // commented for compile workaround + // sa_.Emit(node); } void PandaGen::CreateObjectWithExcludedKeys(const ir::AstNode *node, VReg obj, VReg argStart, size_t argCount) @@ -1284,21 +1303,24 @@ void PandaGen::CloseIterator(const ir::AstNode *node, VReg iter) void PandaGen::ImportModule(const ir::AstNode *node, const util::StringView &name) { - sa_.Emit(node, name); - strings_.insert(name); + // commented for compile workaround + // sa_.Emit(node, name); + // strings_.insert(name); } void PandaGen::DefineClassWithBuffer(const ir::AstNode *node, const util::StringView &ctorId, int32_t litIdx, VReg lexenv, VReg base) { - ra_.Emit(node, ctorId, litIdx, lexenv, base); + auto formal_param_cnt = FormalParametersCount(); + ra_.Emit(node, ctorId, litIdx, static_cast(formal_param_cnt), lexenv, base); strings_.insert(ctorId); } void PandaGen::LoadModuleVariable(const ir::AstNode *node, VReg module, const util::StringView &name) { - ra_.Emit(node, name, module); - strings_.insert(name); + // commented for compile workaround + // ra_.Emit(node, name, module); + // strings_.insert(name); } void PandaGen::StoreModuleVar(const ir::AstNode *node, const util::StringView &name) @@ -1386,7 +1408,9 @@ void PandaGen::LoadLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t void PandaGen::StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot) { - ra_.Emit(node, level, slot); + VReg value = AllocReg(); + StoreAccumulator(node, value); + ra_.Emit(node, level, slot, value); } void PandaGen::ThrowIfSuperNotCorrectCall(const ir::AstNode *node, int64_t num) @@ -1396,13 +1420,21 @@ void PandaGen::ThrowIfSuperNotCorrectCall(const ir::AstNode *node, int64_t num) void PandaGen::ThrowUndefinedIfHole(const ir::AstNode *node, const util::StringView &name) { - ra_.Emit(node, name); + VReg hole_reg = AllocReg(); + StoreAccumulator(node, hole_reg); + LoadAccumulatorString(node, name); + VReg name_reg = AllocReg(); + StoreAccumulator(node, name_reg); + ra_.Emit(node, hole_reg, name_reg); strings_.insert(name); } void PandaGen::ThrowConstAssignment(const ir::AstNode *node, const util::StringView &name) { - ra_.Emit(node, name); + LoadAccumulatorString(node, name); + VReg nameReg = AllocReg(); + StoreAccumulator(node, nameReg); + ra_.Emit(node, nameReg); strings_.insert(name); } @@ -1413,7 +1445,8 @@ void PandaGen::PopLexEnv(const ir::AstNode *node) void PandaGen::CopyLexEnv(const ir::AstNode *node) { - sa_.Emit(node); + // commented for compile workaround + // sa_.Emit(node); } void PandaGen::NewLexEnv(const ir::AstNode *node, uint32_t num) diff --git a/es2panda/compiler/core/pandagen.h b/es2panda/compiler/core/pandagen.h index eefd2e4b24..77d127c423 100644 --- a/es2panda/compiler/core/pandagen.h +++ b/es2panda/compiler/core/pandagen.h @@ -255,7 +255,6 @@ public: void BranchIfTrue(const ir::AstNode *node, class Label *target); void BranchIfNotTrue(const ir::AstNode *node, class Label *target); void BranchIfFalse(const ir::AstNode *node, class Label *target); - void BranchIfCoercible(const ir::AstNode *node, class Label *target); void EmitThrow(const ir::AstNode *node); void EmitRethrow(const ir::AstNode *node); @@ -281,7 +280,6 @@ public: void GetUnmappedArgs(const ir::AstNode *node); void Negate(const ir::AstNode *node); - void ToBoolean(const ir::AstNode *node); void ToNumber(const ir::AstNode *node, VReg arg); void CreateGeneratorObj(const ir::AstNode *node, VReg funcObj); diff --git a/es2panda/ir/expressions/binaryExpression.cpp b/es2panda/ir/expressions/binaryExpression.cpp index 7423a2dfb2..5621dfe8e5 100644 --- a/es2panda/ir/expressions/binaryExpression.cpp +++ b/es2panda/ir/expressions/binaryExpression.cpp @@ -56,7 +56,6 @@ void BinaryExpression::CompileLogical(compiler::PandaGen *pg) const // left -> acc -> lhs -> toboolean -> acc -> bool_lhs left_->Compile(pg); pg->StoreAccumulator(this, lhs); - pg->ToBoolean(this); if (operator_ == lexer::TokenType::PUNCTUATOR_LOGICAL_AND) { pg->BranchIfFalse(this, skipRight); diff --git a/es2panda/ir/expressions/chainExpression.cpp b/es2panda/ir/expressions/chainExpression.cpp index 0869146030..16e2b3a299 100644 --- a/es2panda/ir/expressions/chainExpression.cpp +++ b/es2panda/ir/expressions/chainExpression.cpp @@ -1,4 +1,4 @@ -/** +/* * 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. diff --git a/es2panda/scripts/gen_isa.sh b/es2panda/scripts/gen_isa.sh new file mode 100755 index 0000000000..28ab703f1b --- /dev/null +++ b/es2panda/scripts/gen_isa.sh @@ -0,0 +1,52 @@ +#!/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 + +while getopts "g:t:a:o:d:r:h" arg +do + case "${arg}" in + "g") + GENERATOR=${OPTARG} + ;; + "t") + TEMPLATE=${OPTARG} + ;; + "a") + DATA=${OPTARG} + ;; + "o") + OUTPUT=${OPTARG} + ;; + "d") + OUTDIR=${OPTARG} + ;; + "r") + REQUIRE=${OPTARG} + ;; + "h") + echo "help" + ;; + ?) + echo "unkonw argument" + exit 1 + ;; + esac +done + +if [ ! -d ${OUTDIR} ]; then + mkdir -p ${OUTDIR} +fi +echo "${GENERATOR} --template ${TEMPLATE} --data ${DATA} --output ${OUTDIR}/${OUTPUT} --require ${REQUIRE}" +${GENERATOR} --template ${TEMPLATE} --data ${DATA} --output ${OUTDIR}/${OUTPUT} --require ${REQUIRE} diff --git a/es2panda/scripts/gen_keywords.sh b/es2panda/scripts/gen_keywords.sh new file mode 100755 index 0000000000..43f4069f46 --- /dev/null +++ b/es2panda/scripts/gen_keywords.sh @@ -0,0 +1,46 @@ +#!/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 + +while getopts "g:t:o:d:h" arg +do + case "${arg}" in + "g") + GENERATOR=${OPTARG} + ;; + "t") + TEMPLATE=${OPTARG} + ;; + "o") + OUTPUT=${OPTARG} + ;; + "d") + OUTDIR=${OPTARG} + ;; + "h") + echo "help" + ;; + ?) + echo "unkonw argument" + exit 1 + ;; + esac +done + +if [ ! -d ${OUTDIR} ]; then + mkdir -p ${OUTDIR} +fi + +ruby ${GENERATOR} ${TEMPLATE} ${OUTDIR}/${OUTPUT} -- Gitee From 40f3f027a4ed762ada6f77186ae796c3f97470fd Mon Sep 17 00:00:00 2001 From: ctw-ian Date: Mon, 11 Jul 2022 11:25:22 +0800 Subject: [PATCH 06/25] Add es2abc_gen_abc template for framework Add es2abc_gen_abc template to generate abc files for framework Signed-off-by: ctw-ian Change-Id: I4dbe56fcdeb6f98e8dc0ab58266334a3375a071d --- es2panda/es2abc_config.gni | 102 +++++++++++++++++++++++ es2panda/scripts/generate_js_bytecode.py | 72 ++++++++++++++++ 2 files changed, 174 insertions(+) create mode 100644 es2panda/es2abc_config.gni create mode 100755 es2panda/scripts/generate_js_bytecode.py diff --git a/es2panda/es2abc_config.gni b/es2panda/es2abc_config.gni new file mode 100644 index 0000000000..b785818b30 --- /dev/null +++ b/es2panda/es2abc_config.gni @@ -0,0 +1,102 @@ +# 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. + +if (defined(ark_independent_build)) { + import("$build_root/ark.gni") + es2abc_root = "//ts2abc/es2panda" +} else { + import("//build/ohos.gni") + build_root = "//build" + es2abc_root = "//ark/ts2abc/es2panda" +} + + +toolchain_linux = "$build_root/toolchain/linux:clang_x64" +if (host_cpu == "arm64") { + toolchain_mac = "$build_root/toolchain/mac:clang_arm64" +} else { + toolchain_mac = "$build_root/toolchain/mac:clang_x64" +} +toolchain_win = "$build_root/toolchain/mingw:mingw_x86_64" + +es2abc_build_path = "" +es2abc_build_deps = "" +es2abc_out_root = "" + +if (host_toolchain == toolchain_mac) { + es2abc_out_root = get_label_info("$es2abc_root:es2panda($toolchain_mac)", + "root_out_dir") + es2abc_build_deps = [ "$es2abc_root:es2panda($toolchain_mac)" ] +} else if (host_toolchain == toolchain_win) { + es2abc_out_root = get_label_info("$es2abc_root:es2panda($toolchain_win)", + "root_out_dir") + es2abc_build_deps = [ "$es2abc_root:es2panda($toolchain_win)" ] +} else { + es2abc_out_root = get_label_info("$es2abc_root:es2panda($toolchain_linux)", + "root_out_dir") + es2abc_build_deps = [ "$es2abc_root:es2panda($toolchain_linux)" ] +} +es2abc_build_path = es2abc_out_root + "/ark/ark" + +# Generate abc. +# +# Mandatory arguments: +# plugin_path -- plugin js file path +# plugin_name -- name of js file, ex: BatteryPlugin.js +# generat_file -- name of generated file +# package_name -- name of generated file's package +# extra_dependencies -- a list of files that should be considered as dependencies, must be label +# out_puts +template("es2abc_gen_abc") { + assert(defined(invoker.src_js), "src_js is required!") + assert(defined(invoker.dst_file), "dst_file is required!") + assert(defined(invoker.out_puts), "out_puts is required!") + + print("${es2abc_build_path}") + extra_dependencies = [] + if (defined(invoker.extra_dependencies)) { + extra_dependencies += invoker.extra_dependencies + } + + action("$target_name") { + if (defined(invoker.extra_visibility)) { + visibility = invoker.extra_visibility + } + + print() + + script = "${es2abc_root}/scripts/generate_js_bytecode.py" # need to write a new python script + + deps = extra_dependencies + deps += es2abc_build_deps + + args = [ + "--src-js", + invoker.src_js, + "--dst-file", + invoker.dst_file, + "--frontend-tool-path", + rebase_path("${es2abc_build_path}"), + ] + + if (defined(invoker.extra_args)) { + args += invoker.extra_args + } + + if (defined(invoker.in_puts)) { + inputs = invoker.in_puts + } + + outputs = invoker.out_puts + } +} \ No newline at end of file diff --git a/es2panda/scripts/generate_js_bytecode.py b/es2panda/scripts/generate_js_bytecode.py new file mode 100755 index 0000000000..78cebf940d --- /dev/null +++ b/es2panda/scripts/generate_js_bytecode.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +# coding: utf-8 + +""" +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. + +Description: Generate javascript byte code using es2abc +""" + +import os +import subprocess +import platform +import argparse + + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument('--src-js', + help = 'js source file') + parser.add_argument('--dst-file', + help = 'the converted target file') + parser.add_argument('--frontend-tool-path', + help = 'path of the frontend conversion tool') + parser.add_argument("--debug", action='store_true', + help='whether add debuginfo') + parser.add_argument("--module", action='store_true', + help='whether is module') + parser.add_argument("--commonjs", action='store_true', + help='whether is commonjs') + arguments = parser.parse_args() + return arguments + +def run_command(cmd, execution_path): + print(" ".join(cmd) + " | execution_path: " + execution_path) + proc = subprocess.Popen(cmd, cwd=execution_path) + proc.wait() + + +def gen_abc_info(input_arguments): + frontend_tool_path = input_arguments.frontend_tool_path + + (path, name) = os.path.split(frontend_tool_path) + + cmd = [os.path.join("./", name, "es2abc"), + '--output', input_arguments.dst_file, + input_arguments.src_js] + + if input_arguments.debug: + src_index = cmd.index(input_arguments.src_js) + cmd.insert(src_index, '--debug-info') + if input_arguments.module: + src_index = cmd.index(input_arguments.src_js) + cmd.insert(src_index, '--module') + if input_arguments.commonjs: + src_index = cmd.index(input_arguments.src_js) + # insert commonjs option to cmd later + run_command(cmd, path) + + +if __name__ == '__main__': + gen_abc_info(parse_args()) \ No newline at end of file -- Gitee From 1a4bdeb6c5063659e9ad919f37a17a6f6da55cbd Mon Sep 17 00:00:00 2001 From: qiuyu Date: Tue, 12 Jul 2022 16:59:40 +0800 Subject: [PATCH 07/25] Bytecode optimizer adaption and test adaption Disable bytecode optimizer by defalut. use --opt-level to enable it Remove deprecated code (class2panda log mask) Adapt function name change for type adapter unit test Signed-off-by: qiuyu Change-Id: I2bec65bff38913a41554b7ef415d5a5130872a6a --- ts2panda/src/cmdOptions.ts | 2 +- .../ts2abc/tests/type_adapter_test/type_adapter_test.cpp | 2 +- ts2panda/ts2abc/ts2abc.cpp | 8 +++++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ts2panda/src/cmdOptions.ts b/ts2panda/src/cmdOptions.ts index 4e108670db..d4049f6c37 100644 --- a/ts2panda/src/cmdOptions.ts +++ b/ts2panda/src/cmdOptions.ts @@ -34,7 +34,7 @@ const ts2pandaOptions = [ { name: 'timeout', alias: 't', type: Number, defaultValue: 0, description: "js to abc timeout threshold(unit: seconds)." }, { name: 'opt-log-level', type: String, defaultValue: "error", description: "specifie optimizer log level. Possible values: ['debug', 'info', 'error', 'fatal']" }, { - name: 'opt-level', type: Number, defaultValue: 1, description: "Optimization level. Possible values: [0, 1, 2]. Default: 0\n 0: no optimizations\n \ + name: 'opt-level', type: Number, defaultValue: 0, description: "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: other bytecode optimizations, unimplemented yet"}, { name: 'help', alias: 'h', type: Boolean, description: "Show usage guide." }, diff --git a/ts2panda/ts2abc/tests/type_adapter_test/type_adapter_test.cpp b/ts2panda/ts2abc/tests/type_adapter_test/type_adapter_test.cpp index 4e8bf2f9a2..9f989d125d 100644 --- a/ts2panda/ts2abc/tests/type_adapter_test/type_adapter_test.cpp +++ b/ts2panda/ts2abc/tests/type_adapter_test/type_adapter_test.cpp @@ -100,7 +100,7 @@ void TypeAdapterTest::TestVariablesArgsType() const panda::pandasm::Parser p; auto res = p.Parse(source); auto &program = res.Value(); - auto it = program.function_table.find("foo"); + auto it = program.function_table.find("foo:(any,any)"); TestAssertNotEqual(it, program.function_table.end()); auto &foo = it->second; diff --git a/ts2panda/ts2abc/ts2abc.cpp b/ts2panda/ts2abc/ts2abc.cpp index f66e50ce9f..fafa7ae825 100644 --- a/ts2panda/ts2abc/ts2abc.cpp +++ b/ts2panda/ts2abc/ts2abc.cpp @@ -1327,9 +1327,11 @@ bool GenerateProgram([[maybe_unused]] const std::string &data, const std::string if (g_optLevel != static_cast(OptLevel::O_LEVEL0) || optLevel != static_cast(OptLevel::O_LEVEL0)) { 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; - panda::Logger::InitializeStdLogging(panda::Logger::LevelFromString(optLogLevel), componentMask); + panda::Logger::ComponentMask mask; + mask.set(panda::Logger::Component::ASSEMBLER); + mask.set(panda::Logger::Component::BYTECODE_OPTIMIZER); + mask.set(panda::Logger::Component::COMPILER); + panda::Logger::InitializeStdLogging(panda::Logger::LevelFromString(optLogLevel), mask); bool emitDebugInfo = true; std::map stat; -- Gitee From 1b82dd0fa5700f12da12bd60fd701a58137356a1 Mon Sep 17 00:00:00 2001 From: qiuyu Date: Fri, 15 Jul 2022 11:48:53 +0800 Subject: [PATCH 08/25] Fix codecheck warning: mix signed and unsigned numbers Fix codecheck warning: mix signed and unsigned numbers Signed-off-by: qiuyu Change-Id: I54e25c9b2cda5c083b91b342ffb4a77f8b7d4023 --- ts2panda/ts2abc/type_adapter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ts2panda/ts2abc/type_adapter.cpp b/ts2panda/ts2abc/type_adapter.cpp index 1ab1e303fc..a0ae080162 100644 --- a/ts2panda/ts2abc/type_adapter.cpp +++ b/ts2panda/ts2abc/type_adapter.cpp @@ -92,7 +92,7 @@ void TypeAdapter::HandleTypeForFunction(panda::pandasm::Function *func, size_t a auto it = vreg_type_map.find(vreg); if (it != vreg_type_map.end()) { ASSERT(std::find(finished_vregs.begin(), finished_vregs.end(), vreg) == finished_vregs.end()); - int32_t arg_order = func->regs_num - arg - 1; + int32_t arg_order = static_cast(func->regs_num) - static_cast(arg) - 1; order_type_map.emplace(arg_order, it->second); finished_vregs.emplace_back(vreg); } -- Gitee From 292795a7fbb05ec4f1fa2b85b35d852ff8187fba Mon Sep 17 00:00:00 2001 From: ctw-ian Date: Tue, 12 Jul 2022 11:17:37 +0800 Subject: [PATCH 09/25] Declare common toolcahin names for ts2panda and es2panda 1. Declare common toolcahin names for ts2panda and es2panda in ets_frontend_config.gni 2. Fix of gn format and small modification Signed-off-by: ctw-ian Change-Id: I262c405fb9bf36be4aebf51770a16fbe825ac756 --- BUILD.gn | 12 +- bundle.json | 2 +- es2panda/BUILD.gn | 68 +++++------ es2panda/compiler/base/destructuring.cpp | 1 - es2panda/compiler/core/emitter.cpp | 12 +- es2panda/compiler/core/pandagen.cpp | 140 ++++++++++++++--------- es2panda/es2abc_config.gni | 35 ++---- es2panda/scripts/generate_js_bytecode.py | 2 +- ets_frontend_config.gni | 27 +++++ ts2panda/BUILD.gn | 16 +-- ts2panda/tests/BUILD.gn | 4 +- ts2panda/ts2abc_config.gni | 30 ++--- 12 files changed, 198 insertions(+), 151 deletions(-) create mode 100644 ets_frontend_config.gni diff --git a/BUILD.gn b/BUILD.gn index 7bf72fa8da..98f9ae49d2 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -11,12 +11,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//ark/runtime_core/ark_config.gni") +import("//arkcompiler/runtime_core/ark_config.gni") import("//build/ohos.gni") group("ets_frontend") { - deps = [ - "./ts2panda:ark_ts2abc_build", - "./es2panda:es2panda_build", - ] -} \ No newline at end of file + deps = [ + "./es2panda:es2panda_build", + "./ts2panda:ark_ts2abc_build", + ] +} diff --git a/bundle.json b/bundle.json index 9c1f1915f7..0b9bb4fba4 100644 --- a/bundle.json +++ b/bundle.json @@ -19,7 +19,7 @@ }, "build": { "sub_component": [ - "//ark/ts2abc:ets_frontend" + "//arkcompiler/ets_frontend:ets_frontend" ], "inner_kits": [], "test": [] diff --git a/es2panda/BUILD.gn b/es2panda/BUILD.gn index 5f6431512f..31eda11e1f 100644 --- a/es2panda/BUILD.gn +++ b/es2panda/BUILD.gn @@ -11,7 +11,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//ark/runtime_core/ark_config.gni") +import("//arkcompiler/ets_frontend/ets_frontend_config.gni") +import("//arkcompiler/runtime_core/ark_config.gni") import("//build/ohos.gni") es2panda_src = [ @@ -234,7 +235,7 @@ es2panda_src = [ "typescript/types/voidType.cpp", "util/bitset.cpp", "util/helpers.cpp", - "util/ustring.cpp" + "util/ustring.cpp", ] config("es2abc_config_src") { @@ -258,14 +259,13 @@ config("es2abc_config_src") { "./lexer/token", "./lexer/regexp", "./typescript", - "./typescript/types" + "./typescript/types", ] cflags = [ "-fexceptions" ] } config("es2abc_config_common") { - configs = [ "$ark_root:ark_config", "$sdk_libc_secshared_config", @@ -300,14 +300,18 @@ action_foreach("gen_keywords_headers") { sources += [ rebase_path("${keywords_templates_dir}/${file}") ] } outputs = [ "${generated_header_dir}/{{source_name_part}}" ] - + script = "scripts/gen_keywords.sh" inputs = [ "${keywords_generator}" ] args = [ - "-g", rebase_path("${keywords_generator}"), - "-t", "{{source}}", - "-o", "{{source_name_part}}", - "-d", rebase_path("${generated_header_dir}"), + "-g", + rebase_path("${keywords_generator}"), + "-t", + "{{source}}", + "-o", + "{{source_name_part}}", + "-d", + rebase_path("${generated_header_dir}"), ] } @@ -316,34 +320,39 @@ isa_gen = "${ark_root}/isa/gen.rb" isa_gen_data = "$root_gen_dir/isa/isa.yaml" isa_gen_require = "${ark_root}/isa/isapi.rb" action_foreach("gen_isa_headers") { - - deps = [ "//ark/runtime_core/isa:isa_combine" ] + deps = [ "//arkcompiler/runtime_core/isa:isa_combine" ] template_files = [ "isa.h.erb", "formats.h.erb", ] keywords_templates_dir = "./compiler/templates" - + sources = [] foreach(file, template_files) { sources += [ rebase_path("${keywords_templates_dir}/${file}") ] } outputs = [ "${generated_header_dir}/{{source_name_part}}" ] - + script = "scripts/gen_isa.sh" inputs = [ "${isa_gen}", "${isa_gen_data}", - "${isa_gen_require}" + "${isa_gen_require}", ] args = [ - "-g", rebase_path("${isa_gen}"), - "-t", "{{source}}", - "-a", rebase_path("${isa_gen_data}"), - "-o", "{{source_name_part}}", - "-d", rebase_path("${generated_header_dir}"), - "-r", rebase_path("${isa_gen_require}"), + "-g", + rebase_path("${isa_gen}"), + "-t", + "{{source}}", + "-a", + rebase_path("${isa_gen_data}"), + "-o", + "{{source_name_part}}", + "-d", + rebase_path("${generated_header_dir}"), + "-r", + rebase_path("${isa_gen_require}"), ] } @@ -361,8 +370,8 @@ ohos_static_library("es2panda_lib") { ] deps = [ - ":gen_keywords_headers", ":gen_isa_headers", + ":gen_keywords_headers", "$ark_root/assembler:libarkassembler_frontend_static", "$ark_root/libpandabase:libarkbase_frontend_static", "$ark_root/libpandafile:libarkfile_frontend_static", @@ -370,25 +379,21 @@ ohos_static_library("es2panda_lib") { "//third_party/icu/icu4c:static_icuuc", ] - cflags = [ - "-Wno-implicit-fallthrough", - ] + cflags = [ "-Wno-implicit-fallthrough" ] } ohos_executable("es2panda") { use_exceptions = true sources = [ - "aot/options.cpp", "aot/main.cpp", + "aot/options.cpp", ] include_dirs = [ "./aot" ] configs = [ ":es2abc_config_common" ] - deps = [ - ":es2panda_lib", - ] + deps = [ ":es2panda_lib" ] if (is_linux) { if (build_public_version) { @@ -465,16 +470,15 @@ if (is_mac) { } group("es2panda_build") { - build_tool_linux = "//build/toolchain/linux:clang_x64" if (host_os == "linux") { - deps = [ ":es2panda(${build_tool_linux})" ] + deps = [ ":es2panda(${toolchain_linux})" ] } if (host_os == "mac") { - deps = [ ":es2panda(//build/toolchain/mac:clang_x64)" ] + deps = [ ":es2panda(${toolchain_mac})" ] } } group("es2panda_build_win") { - deps = [ ":es2panda(//build/toolchain/mingw:mingw_x86_64)" ] + deps = [ ":es2panda(${toolchain_win})" ] } diff --git a/es2panda/compiler/base/destructuring.cpp b/es2panda/compiler/base/destructuring.cpp index 5b3ac2e0c1..70d9ef0754 100644 --- a/es2panda/compiler/base/destructuring.cpp +++ b/es2panda/compiler/base/destructuring.cpp @@ -71,7 +71,6 @@ static void GenRestElement(PandaGen *pg, const ir::SpreadElement *restElement, static void GenArray(PandaGen *pg, const ir::ArrayExpression *array) { - // RegScope rs(pg); DestructuringIterator iterator(pg, array); if (array->Elements().empty()) { diff --git a/es2panda/compiler/core/emitter.cpp b/es2panda/compiler/core/emitter.cpp index c25c579fe2..ac04127360 100644 --- a/es2panda/compiler/core/emitter.cpp +++ b/es2panda/compiler/core/emitter.cpp @@ -75,7 +75,8 @@ void FunctionEmitter::GenBufferLiterals(const LiteralBuffer *buff) { auto &[idx, array] = literalBuffers_.emplace_back(); idx = buff->Index(); - array.reserve(buff->Literals().size() * 2); + constexpr size_t ARRAY_EXPANSION = 2; + array.reserve(buff->Literals().size() * ARRAY_EXPANSION); for (const auto *literal : buff->Literals()) { panda::pandasm::LiteralArray::Literal valueLit; @@ -119,11 +120,7 @@ void FunctionEmitter::GenBufferLiterals(const LiteralBuffer *buff) valueLit.value_ = literal->GetMethod().Mutf8(); break; } - // case ir::LiteralTag::ASYNC_GENERATOR_METHOD: { - // valueLit.tag_ = panda::panda_file::LiteralTag::ASYNCGENERATORMETHOD; - // valueLit.value_ = literal->GetMethod().Mutf8(); - // break; - // } + // TODO: support ir::LiteralTag::ASYNC_GENERATOR_METHOD case ir::LiteralTag::NULL_VALUE: { valueLit.tag_ = panda::panda_file::LiteralTag::NULLVALUE; valueLit.value_ = static_cast(0); @@ -181,10 +178,11 @@ static size_t GetIRNodeWholeLength(const IRNode *node) } size_t len = 1; + constexpr size_t BIT_WIDTH = 8; const auto format = MatchFormat(node, formats); for (auto fi : format.GetFormatItem()) { - len += fi.Bitwidth() / 8; + len += fi.Bitwidth() / BIT_WIDTH; } return len; diff --git a/es2panda/compiler/core/pandagen.cpp b/es2panda/compiler/core/pandagen.cpp index 5c4ea92669..7cf1bb96f5 100644 --- a/es2panda/compiler/core/pandagen.cpp +++ b/es2panda/compiler/core/pandagen.cpp @@ -784,6 +784,7 @@ void PandaGen::Binary(const ir::AstNode *node, lexer::TokenType op, VReg lhs) void PandaGen::BranchIfUndefined(const ir::AstNode *node, Label *target) { + RegScope rs(this); VReg tmp = AllocReg(); StoreAccumulator(node, tmp); sa_.Emit(node); @@ -793,6 +794,7 @@ void PandaGen::BranchIfUndefined(const ir::AstNode *node, Label *target) void PandaGen::BranchIfNotUndefined(const ir::AstNode *node, Label *target) { + RegScope rs(this); VReg tmp = AllocReg(); StoreAccumulator(node, tmp); sa_.Emit(node); @@ -823,8 +825,7 @@ void PandaGen::EmitThrow(const ir::AstNode *node) void PandaGen::EmitRethrow(const ir::AstNode *node) { - // commented for compile workaround - // sa_.Emit(node); + // TODO: rethrow in try-catch } void PandaGen::EmitReturn(const ir::AstNode *node) @@ -939,22 +940,22 @@ void PandaGen::LoadHomeObject(const ir::AstNode *node) void PandaGen::DefineFunction(const ir::AstNode *node, const ir::ScriptFunction *realNode, const util::StringView &name) { - auto formal_param_cnt = FormalParametersCount(); + auto formalParamCnt = FormalParametersCount(); if (realNode->IsAsync()) { if (realNode->IsGenerator()) { // TODO(): async generator } else { - ra_.Emit(node, name, static_cast(formal_param_cnt), LexEnv()); + ra_.Emit(node, name, static_cast(formalParamCnt), LexEnv()); } } else if (realNode->IsGenerator()) { - ra_.Emit(node, name, static_cast(formal_param_cnt), LexEnv()); + ra_.Emit(node, name, static_cast(formalParamCnt), LexEnv()); } else if (realNode->IsArrow()) { LoadHomeObject(node); - ra_.Emit(node, name, static_cast(formal_param_cnt), LexEnv()); + ra_.Emit(node, name, static_cast(formalParamCnt), LexEnv()); } else if (realNode->IsMethod()) { - ra_.Emit(node, name, static_cast(formal_param_cnt), LexEnv()); + ra_.Emit(node, name, static_cast(formalParamCnt), LexEnv()); } else { - ra_.Emit(node, name, static_cast(formal_param_cnt), LexEnv()); + ra_.Emit(node, name, static_cast(formalParamCnt), LexEnv()); } strings_.insert(name); @@ -999,9 +1000,11 @@ void PandaGen::ToNumber(const ir::AstNode *node, VReg arg) void PandaGen::GetMethod(const ir::AstNode *node, VReg obj, const util::StringView &name) { - // commented for compile workaround - // ra_.Emit(node, name, obj); - // strings_.insert(name); + /** + * TODO + * ra_.Emit(node, name, obj); + * strings_.insert(name); + */ } void PandaGen::CreateGeneratorObj(const ir::AstNode *node, VReg funcObj) @@ -1011,38 +1014,50 @@ void PandaGen::CreateGeneratorObj(const ir::AstNode *node, VReg funcObj) void PandaGen::CreateAsyncGeneratorObj(const ir::AstNode *node, VReg funcObj) { - // commented for compile workaround - // ra_.Emit(node, funcObj); + /* + * TODO: async generator + * ra_.Emit(node, funcObj); + */ } void PandaGen::CreateIterResultObject(const ir::AstNode *node, bool done) { - // commented for compile workaround - // ra_.Emit(node, static_cast(done)); + /* + * TODO: create iter result + * ra_.Emit(node, static_cast(done)); + */ } void PandaGen::SuspendGenerator(const ir::AstNode *node, VReg genObj) { - // commented for compile workaround - // ra_.Emit(node, genObj); + /* + * TODO: suspend generator + * ra_.Emit(node, genObj); + */ } void PandaGen::SuspendAsyncGenerator(const ir::AstNode *node, VReg asyncGenObj) { - // commented for compile workaround - // ra_.Emit(node, asyncGenObj); + /* + * TODO: suspend async generator + * ra_.Emit(node, asyncGenObj); + */ } void PandaGen::GeneratorYield(const ir::AstNode *node, VReg genObj) { - // commented for compile workaround - // ra_.Emit(node, genObj, static_cast(GeneratorState::SUSPENDED_YIELD)); + /* + * TODO: set generator yield + * ra_.Emit(node, genObj, static_cast(GeneratorState::SUSPENDED_YIELD)); + */ } void PandaGen::GeneratorComplete(const ir::AstNode *node, VReg genObj) { - // commented for compile workaround - // ra_.Emit(node, genObj, static_cast(GeneratorState::COMPLETED)); + /* + * TODO: set generator complete + * ra_.Emit(node, genObj, static_cast(GeneratorState::COMPLETED)); + */ } void PandaGen::ResumeGenerator(const ir::AstNode *node, VReg genObj) @@ -1062,32 +1077,42 @@ void PandaGen::AsyncFunctionEnter(const ir::AstNode *node) void PandaGen::AsyncFunctionAwait(const ir::AstNode *node, VReg asyncFuncObj) { - // commented for compile workaround - // ra_.Emit(node, asyncFuncObj); + /* + * TODO: async function await + * ra_.Emit(node, asyncFuncObj); + */ } void PandaGen::AsyncFunctionResolve(const ir::AstNode *node, VReg asyncFuncObj) { - // commented for compile workaround - // ra_.Emit(node, asyncFuncObj); + /* + * TODO: async function resolve + * ra_.Emit(node, asyncFuncObj); + */ } void PandaGen::AsyncFunctionReject(const ir::AstNode *node, VReg asyncFuncObj) { - // commented for compile workaround - // ra_.Emit(node, asyncFuncObj); + /* + * TODO: async function reject + * ra_.Emit(node, asyncFuncObj); + */ } void PandaGen::AsyncGeneratorResolve(const ir::AstNode *node, VReg asyncGenObj) { - // commented for compile workaround - // ra_.Emit(node, asyncGenObj); + /* + * TODO: async generator resolve + * ra_.Emit(node, asyncGenObj); + */ } void PandaGen::AsyncGeneratorReject(const ir::AstNode *node, VReg asyncGenObj) { - // commented for compile workaround - // ra_.Emit(node, asyncGenObj); + /* + * TODO: async generator reject + * ra_.Emit(node, asyncGenObj); + */ } void PandaGen::GetTemplateObject(const ir::AstNode *node, VReg value) @@ -1259,7 +1284,8 @@ void PandaGen::StoreArraySpread(const ir::AstNode *node, VReg array, VReg index) void PandaGen::ThrowIfNotObject(const ir::AstNode *node) { - // commented for compile workaround + // TODO: implement this method correctly + RegScope rs(this); VReg value = AllocReg(); ra_.Emit(node, value); } @@ -1276,8 +1302,10 @@ void PandaGen::GetIterator(const ir::AstNode *node) void PandaGen::GetAsyncIterator(const ir::AstNode *node) { - // commented for compile workaround - // sa_.Emit(node); + /* + * TODO: async iterator + * sa_.Emit(node); + */ } void PandaGen::CreateObjectWithExcludedKeys(const ir::AstNode *node, VReg obj, VReg argStart, size_t argCount) @@ -1303,24 +1331,28 @@ void PandaGen::CloseIterator(const ir::AstNode *node, VReg iter) void PandaGen::ImportModule(const ir::AstNode *node, const util::StringView &name) { - // commented for compile workaround - // sa_.Emit(node, name); - // strings_.insert(name); + /* + * TODO: module + * sa_.Emit(node, name); + * strings_.insert(name); + */ } void PandaGen::DefineClassWithBuffer(const ir::AstNode *node, const util::StringView &ctorId, int32_t litIdx, VReg lexenv, VReg base) { - auto formal_param_cnt = FormalParametersCount(); - ra_.Emit(node, ctorId, litIdx, static_cast(formal_param_cnt), lexenv, base); + auto formalParamCnt = FormalParametersCount(); + ra_.Emit(node, ctorId, litIdx, static_cast(formalParamCnt), lexenv, base); strings_.insert(ctorId); } void PandaGen::LoadModuleVariable(const ir::AstNode *node, VReg module, const util::StringView &name) { - // commented for compile workaround - // ra_.Emit(node, name, module); - // strings_.insert(name); + /* + * TODO: module + * ra_.Emit(node, name, module); + * strings_.insert(name); + */ } void PandaGen::StoreModuleVar(const ir::AstNode *node, const util::StringView &name) @@ -1408,6 +1440,8 @@ void PandaGen::LoadLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t void PandaGen::StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot) { + // TODO: need to reconsider this part + RegScope rs(this); VReg value = AllocReg(); StoreAccumulator(node, value); ra_.Emit(node, level, slot, value); @@ -1420,17 +1454,19 @@ void PandaGen::ThrowIfSuperNotCorrectCall(const ir::AstNode *node, int64_t num) void PandaGen::ThrowUndefinedIfHole(const ir::AstNode *node, const util::StringView &name) { - VReg hole_reg = AllocReg(); - StoreAccumulator(node, hole_reg); + RegScope rs(this); + VReg holeReg = AllocReg(); + StoreAccumulator(node, holeReg); LoadAccumulatorString(node, name); - VReg name_reg = AllocReg(); - StoreAccumulator(node, name_reg); - ra_.Emit(node, hole_reg, name_reg); + VReg nameReg = AllocReg(); + StoreAccumulator(node, nameReg); + ra_.Emit(node, holeReg, nameReg); strings_.insert(name); } void PandaGen::ThrowConstAssignment(const ir::AstNode *node, const util::StringView &name) { + RegScope rs(this); LoadAccumulatorString(node, name); VReg nameReg = AllocReg(); StoreAccumulator(node, nameReg); @@ -1445,8 +1481,10 @@ void PandaGen::PopLexEnv(const ir::AstNode *node) void PandaGen::CopyLexEnv(const ir::AstNode *node) { - // commented for compile workaround - // sa_.Emit(node); + /* + * TODO: copy lexenv + * sa_.Emit(node); + */ } void PandaGen::NewLexEnv(const ir::AstNode *node, uint32_t num) diff --git a/es2panda/es2abc_config.gni b/es2panda/es2abc_config.gni index b785818b30..008466806f 100644 --- a/es2panda/es2abc_config.gni +++ b/es2panda/es2abc_config.gni @@ -11,39 +11,31 @@ # See the License for the specific language governing permissions and # limitations under the License. +import("//arkcompiler/ets_frontend/ets_frontend_config.gni") if (defined(ark_independent_build)) { import("$build_root/ark.gni") - es2abc_root = "//ts2abc/es2panda" + es2abc_root = "//ets_frontend/es2panda" } else { import("//build/ohos.gni") build_root = "//build" - es2abc_root = "//ark/ts2abc/es2panda" + es2abc_root = "//arkcompiler/ets_frontend/es2panda" } - -toolchain_linux = "$build_root/toolchain/linux:clang_x64" -if (host_cpu == "arm64") { - toolchain_mac = "$build_root/toolchain/mac:clang_arm64" -} else { - toolchain_mac = "$build_root/toolchain/mac:clang_x64" -} -toolchain_win = "$build_root/toolchain/mingw:mingw_x86_64" - es2abc_build_path = "" es2abc_build_deps = "" es2abc_out_root = "" if (host_toolchain == toolchain_mac) { - es2abc_out_root = get_label_info("$es2abc_root:es2panda($toolchain_mac)", - "root_out_dir") + es2abc_out_root = + get_label_info("$es2abc_root:es2panda($toolchain_mac)", "root_out_dir") es2abc_build_deps = [ "$es2abc_root:es2panda($toolchain_mac)" ] } else if (host_toolchain == toolchain_win) { - es2abc_out_root = get_label_info("$es2abc_root:es2panda($toolchain_win)", - "root_out_dir") + es2abc_out_root = + get_label_info("$es2abc_root:es2panda($toolchain_win)", "root_out_dir") es2abc_build_deps = [ "$es2abc_root:es2panda($toolchain_win)" ] } else { - es2abc_out_root = get_label_info("$es2abc_root:es2panda($toolchain_linux)", - "root_out_dir") + es2abc_out_root = + get_label_info("$es2abc_root:es2panda($toolchain_linux)", "root_out_dir") es2abc_build_deps = [ "$es2abc_root:es2panda($toolchain_linux)" ] } es2abc_build_path = es2abc_out_root + "/ark/ark" @@ -62,10 +54,9 @@ template("es2abc_gen_abc") { assert(defined(invoker.dst_file), "dst_file is required!") assert(defined(invoker.out_puts), "out_puts is required!") - print("${es2abc_build_path}") extra_dependencies = [] if (defined(invoker.extra_dependencies)) { - extra_dependencies += invoker.extra_dependencies + extra_dependencies += invoker.extra_dependencies } action("$target_name") { @@ -73,9 +64,7 @@ template("es2abc_gen_abc") { visibility = invoker.extra_visibility } - print() - - script = "${es2abc_root}/scripts/generate_js_bytecode.py" # need to write a new python script + script = "${es2abc_root}/scripts/generate_js_bytecode.py" deps = extra_dependencies deps += es2abc_build_deps @@ -99,4 +88,4 @@ template("es2abc_gen_abc") { outputs = invoker.out_puts } -} \ No newline at end of file +} diff --git a/es2panda/scripts/generate_js_bytecode.py b/es2panda/scripts/generate_js_bytecode.py index 78cebf940d..f3afc4dfc8 100755 --- a/es2panda/scripts/generate_js_bytecode.py +++ b/es2panda/scripts/generate_js_bytecode.py @@ -64,7 +64,7 @@ def gen_abc_info(input_arguments): cmd.insert(src_index, '--module') if input_arguments.commonjs: src_index = cmd.index(input_arguments.src_js) - # insert commonjs option to cmd later + # insert commonjs option to cmd later run_command(cmd, path) diff --git a/ets_frontend_config.gni b/ets_frontend_config.gni new file mode 100644 index 0000000000..b4a3c1928a --- /dev/null +++ b/ets_frontend_config.gni @@ -0,0 +1,27 @@ +# 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. + +if (defined(ark_independent_build)) { + ets_frontend_root = "//ets_frontend" +} else { + build_root = "//build" + ets_frontend_root = "//arkcompiler/ets_frontend" +} + +toolchain_linux = "$build_root/toolchain/linux:clang_x64" +if (host_cpu == "arm64") { + toolchain_mac = "$build_root/toolchain/mac:clang_arm64" +} else { + toolchain_mac = "$build_root/toolchain/mac:clang_x64" +} +toolchain_win = "$build_root/toolchain/mingw:mingw_x86_64" diff --git a/ts2panda/BUILD.gn b/ts2panda/BUILD.gn index b51922857a..815bcb1def 100755 --- a/ts2panda/BUILD.gn +++ b/ts2panda/BUILD.gn @@ -223,21 +223,21 @@ group("ark_ts2abc_build") { deps = [] if (host_os != "mac") { deps += [ - "${ts2abc_root}:ts2abc_build(${buildtool_linux})", - "${ts2abc_root}:ts2abc_build_ets(${buildtool_linux})", + "${ts2abc_root}:ts2abc_build(${toolchain_linux})", + "${ts2abc_root}:ts2abc_build_ets(${toolchain_linux})", ] } else { deps += [ - "${ts2abc_root}:ts2abc_build_mac(${buildtool_mac})", - "${ts2abc_root}:ts2abc_build_mac_ets(${buildtool_mac})", + "${ts2abc_root}:ts2abc_build_mac(${toolchain_mac})", + "${ts2abc_root}:ts2abc_build_mac_ets(${toolchain_mac})", ] } } group("ark_ts2abc_build_win") { deps = [ - "${ts2abc_root}:ts2abc_build_win(${buildtool_win})", - "${ts2abc_root}:ts2abc_build_win_ets(${buildtool_win})", + "${ts2abc_root}:ts2abc_build_win(${toolchain_win})", + "${ts2abc_root}:ts2abc_build_win_ets(${toolchain_win})", ] } @@ -252,13 +252,13 @@ ohos_copy("copy_ts2abc_tests") { group("ts2abc_unittests") { if (host_os == "linux") { testonly = true - deps = [ "tests:ts2abc_tests(${buildtool_linux})" ] + deps = [ "tests:ts2abc_tests(${toolchain_linux})" ] } } group("ts2abc_type_adapter_unit_tests") { if (host_os == "linux") { testonly = true - deps = [ "${ts2abc_root}/ts2abc/tests/type_adapter_test:ts2abc_type_adapter_unit_tests(${buildtool_linux})" ] + deps = [ "${ts2abc_root}/ts2abc/tests/type_adapter_test:ts2abc_type_adapter_unit_tests(${toolchain_linux})" ] } } diff --git a/ts2panda/tests/BUILD.gn b/ts2panda/tests/BUILD.gn index 8f29fa2803..1da6e41ffb 100644 --- a/ts2panda/tests/BUILD.gn +++ b/ts2panda/tests/BUILD.gn @@ -28,12 +28,12 @@ action("ts2abc_tests") { rebase_path("${node_modules}"), ] - if (host_toolchain == buildtool_linux) { + if (host_toolchain == toolchain_linux) { args += [ "--platform", "linux", ] - } else if (host_toolchain == buildtool_mac) { + } else if (host_toolchain == toolchain_mac) { args += [ "--platform", "mac", diff --git a/ts2panda/ts2abc_config.gni b/ts2panda/ts2abc_config.gni index 99cc458e35..01d9002487 100755 --- a/ts2panda/ts2abc_config.gni +++ b/ts2panda/ts2abc_config.gni @@ -10,7 +10,7 @@ # 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("//arkcompiler/ets_frontend/ets_frontend_config.gni") if (!defined(ark_independent_build)) { import("//build/ohos.gni") import("//build/test.gni") @@ -22,14 +22,6 @@ if (!defined(ark_independent_build)) { } declare_args() { - buildtool_linux = "$build_root/toolchain/linux:clang_x64" - if (host_cpu == "arm64") { - buildtool_mac = "$build_root/toolchain/mac:clang_arm64" - } else { - buildtool_mac = "$build_root/toolchain/mac:clang_x64" - } - buildtool_win = "$build_root/toolchain/mingw:mingw_x86_64" - nodejs_dir = "" node_path = "" node_modules = "" @@ -45,23 +37,23 @@ if (build_public_version) { nodejs_dir = "//prebuilts/ace-toolkit/nodejs" } -if (host_toolchain == buildtool_mac) { - ts2abc_build_deps = [ "$ts2abc_root:ts2abc_build_mac($buildtool_mac)" ] +if (host_toolchain == toolchain_mac) { + ts2abc_build_deps = [ "$ts2abc_root:ts2abc_build_mac($toolchain_mac)" ] ts2abc_build_path = - get_label_info("$ts2abc_root:ts2abc_build_mac($buildtool_mac)", + get_label_info("$ts2abc_root:ts2abc_build_mac($toolchain_mac)", "root_out_dir") + "/obj/arkcompiler/ets_frontend/ts2panda/build-mac" node_path = "${nodejs_dir}/node-v12.18.4-darwin-x64/bin/" -} else if (host_toolchain == buildtool_win) { - ts2abc_build_deps = [ "$ts2abc_root:ts2abc_build_win($buildtool_win)" ] +} else if (host_toolchain == toolchain_win) { + ts2abc_build_deps = [ "$ts2abc_root:ts2abc_build_win($toolchain_win)" ] ts2abc_build_path = - get_label_info("$ts2abc_root:ts2abc_build_win($buildtool_win)", + get_label_info("$ts2abc_root:ts2abc_build_win($toolchain_win)", "root_out_dir") + "/obj/arkcompiler/ets_frontend/ts2panda/build_win" } else { - ts2abc_build_deps = [ "$ts2abc_root:ts2abc_build($buildtool_linux)" ] + ts2abc_build_deps = [ "$ts2abc_root:ts2abc_build($toolchain_linux)" ] ts2abc_build_path = - get_label_info("$ts2abc_root:ts2abc_build($buildtool_linux)", + get_label_info("$ts2abc_root:ts2abc_build($toolchain_linux)", "root_out_dir") + "/obj/arkcompiler/ets_frontend/ts2panda/build" node_path = "${nodejs_dir}/node-v12.18.4-linux-x64/bin/" @@ -221,12 +213,12 @@ template("ts2abc_unittest") { "--gn-build", ] - if (host_toolchain == buildtool_linux) { + if (host_toolchain == toolchain_linux) { args += [ "--platform", "linux", ] - } else if (host_toolchain == buildtool_mac) { + } else if (host_toolchain == toolchain_mac) { args += [ "--platform", "mac", -- Gitee From 73433277425aa7eac413f44c540d408aabb33e72 Mon Sep 17 00:00:00 2001 From: chenqy930 Date: Tue, 19 Jul 2022 09:42:27 +0800 Subject: [PATCH 10/25] Switch component name to ets_frontend Signed-off-by: chenqy930 Change-Id: I8eabfd75c570938dfa1c4d38180e5046722ad0e3 --- BUILD.gn | 2 +- bundle.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/BUILD.gn b/BUILD.gn index 98f9ae49d2..f8c78ee6cc 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -14,7 +14,7 @@ import("//arkcompiler/runtime_core/ark_config.gni") import("//build/ohos.gni") -group("ets_frontend") { +group("ets_frontend_build") { deps = [ "./es2panda:es2panda_build", "./ts2panda:ark_ts2abc_build", diff --git a/bundle.json b/bundle.json index 0b9bb4fba4..4ea189cf70 100644 --- a/bundle.json +++ b/bundle.json @@ -4,7 +4,7 @@ "version": "3.1", "license": "Apache V2", "component": { - "name": "ark_ts2abc", + "name": "ets_frontend", "subsystem": "ark", "syscap": [], "features": [], @@ -19,7 +19,7 @@ }, "build": { "sub_component": [ - "//arkcompiler/ets_frontend:ets_frontend" + "//arkcompiler/ets_frontend:ets_frontend_build" ], "inner_kits": [], "test": [] -- Gitee From 7d328bb6d38c758fc4babe5cfa4acbdbade9cc00 Mon Sep 17 00:00:00 2001 From: ctw-ian Date: Tue, 19 Jul 2022 16:31:07 +0800 Subject: [PATCH 11/25] Using std:cerr to present the compilation error Using std:cerr to report the error so that 262 framework can capture it Signed-off-by: ctw-ian Change-Id: I883ef3f1b60a97be877815969d05d3739b7419d5 --- es2panda/aot/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/es2panda/aot/main.cpp b/es2panda/aot/main.cpp index ad0dde48b4..79c5131dec 100644 --- a/es2panda/aot/main.cpp +++ b/es2panda/aot/main.cpp @@ -130,8 +130,8 @@ int Run(int argc, const char **argv) return 0; } - std::cout << err.TypeString() << ": " << err.Message(); - std::cout << " [" << options->SourceFile() << ":" << err.Line() << ":" << err.Col() << "]" << std::endl; + std::cerr << err.TypeString() << ": " << err.Message(); + std::cerr << " [" << options->SourceFile() << ":" << err.Line() << ":" << err.Col() << "]" << std::endl; return err.ErrorCode(); } -- Gitee From b0535ffead7bf1f214bc84d578bab6f2be4d4358 Mon Sep 17 00:00:00 2001 From: zhangrengao Date: Wed, 20 Jul 2022 11:19:18 +0800 Subject: [PATCH 12/25] Fix UT, tonumber ins modified to toumeric ins Signed-off-by: zhangrengao Change-Id: I19f25740e10513ec199897aa3f44d90044f5051b --- ts2panda/tests/expression/cmpBinary.test.ts | 4 ++-- ts2panda/tests/expression/postfixOperations.test.ts | 6 +++--- ts2panda/tests/lexenv.test.ts | 4 ++-- ts2panda/tests/statements/for.test.ts | 6 +++--- ts2panda/tests/watch_expression/addWatch.test.ts | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ts2panda/tests/expression/cmpBinary.test.ts b/ts2panda/tests/expression/cmpBinary.test.ts index 55ad541245..9d9c6dd635 100644 --- a/ts2panda/tests/expression/cmpBinary.test.ts +++ b/ts2panda/tests/expression/cmpBinary.test.ts @@ -33,7 +33,7 @@ import { EcmaStlettoglobalrecord, EcmaStricteqdyn, EcmaStrictnoteqdyn, - EcmaTonumber, + EcmaTonumeric, EcmaTryldglobalbyname, EcmaTrystglobalbyname, EcmaXor2dyn, @@ -295,7 +295,7 @@ describe("CmpBinaryOperators", function () { new StaDyn(lhs), new EcmaIncdyn(lhs), new EcmaTrystglobalbyname('x'), - new EcmaTonumber(variable), + new EcmaTonumeric(variable), new StaDyn(rhs), new EcmaTryldglobalbyname('x'), new EcmaTrystglobalbyname('x'), diff --git a/ts2panda/tests/expression/postfixOperations.test.ts b/ts2panda/tests/expression/postfixOperations.test.ts index 355649dc9c..fdd7ad6d1c 100644 --- a/ts2panda/tests/expression/postfixOperations.test.ts +++ b/ts2panda/tests/expression/postfixOperations.test.ts @@ -22,7 +22,7 @@ import { EcmaIncdyn, EcmaReturnundefined, EcmaStlettoglobalrecord, - EcmaTonumber, + EcmaTonumeric, EcmaTryldglobalbyname, EcmaTrystglobalbyname, Imm, @@ -45,7 +45,7 @@ describe("PostfixOperationsTest", function () { new StaDyn(temp), new EcmaIncdyn(temp), new EcmaTrystglobalbyname('i'), - new EcmaTonumber(i), + new EcmaTonumeric(i), new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; @@ -62,7 +62,7 @@ describe("PostfixOperationsTest", function () { new StaDyn(temp), new EcmaDecdyn(temp), new EcmaTrystglobalbyname('i'), - new EcmaTonumber(i), + new EcmaTonumeric(i), new EcmaReturnundefined() ]; expect(checkInstructions(insns, expected)).to.be.true; diff --git a/ts2panda/tests/lexenv.test.ts b/ts2panda/tests/lexenv.test.ts index c54daff6d0..a2180a6a15 100644 --- a/ts2panda/tests/lexenv.test.ts +++ b/ts2panda/tests/lexenv.test.ts @@ -32,7 +32,7 @@ import { EcmaStlexvardyn, EcmaThrowconstassignment, EcmaThrowundefinedifhole, - EcmaTonumber, + EcmaTonumeric, EcmaTrystglobalbyname, Imm, IRNode, @@ -520,7 +520,7 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function () { new EcmaIncdyn(new VReg()), new StaDyn(new VReg()), ...MicroStoreLexVar(1, 0), - new EcmaTonumber(new VReg()), // this is redundant load varialbe + new EcmaTonumeric(new VReg()), // this is redundant load varialbe ...MicroLoadLexVar(1, 0), new StaDyn(new VReg), ...MicroLoadLexVar(1, 1), diff --git a/ts2panda/tests/statements/for.test.ts b/ts2panda/tests/statements/for.test.ts index de8617947f..47bfce8d47 100644 --- a/ts2panda/tests/statements/for.test.ts +++ b/ts2panda/tests/statements/for.test.ts @@ -21,7 +21,7 @@ import { EcmaIncdyn, EcmaLessdyn, EcmaReturnundefined, - EcmaTonumber, + EcmaTonumeric, Imm, Jeqz, Jmp, @@ -228,7 +228,7 @@ describe("LoopWithLabelTests", function () { new StaDyn(j), new EcmaIncdyn(j), new StaDyn(j), - new EcmaTonumber(j), + new EcmaTonumeric(j), // jump to the loop header new Jmp(labelPre1), labelPost1, @@ -299,7 +299,7 @@ describe("LoopWithLabelTests", function () { new StaDyn(j), new EcmaIncdyn(j), new StaDyn(j), - new EcmaTonumber(j), + new EcmaTonumeric(j), // jump to the loop header new Jmp(labelPre1), labelPost1, diff --git a/ts2panda/tests/watch_expression/addWatch.test.ts b/ts2panda/tests/watch_expression/addWatch.test.ts index 7eacad422c..53ccee3695 100644 --- a/ts2panda/tests/watch_expression/addWatch.test.ts +++ b/ts2panda/tests/watch_expression/addWatch.test.ts @@ -48,7 +48,7 @@ import { EcmaStricteqdyn, EcmaSuspendgenerator, EcmaThrowdyn, - EcmaTonumber, + EcmaTonumeric, EcmaTypeofdyn, FldaiDyn, Imm, @@ -661,7 +661,7 @@ describe("WatchExpressions", function () { new LdaStr('a'), new StaDyn(new VReg()), new EcmaCallargs2dyn(new VReg(), new VReg(), new VReg()), - new EcmaTonumber(new VReg()), + new EcmaTonumeric(new VReg()), new ReturnDyn() ]; -- Gitee From 9eb789815b435a5e6f02b9e4c112fba8f966d41c Mon Sep 17 00:00:00 2001 From: hufeng Date: Wed, 20 Jul 2022 15:34:40 +0800 Subject: [PATCH 13/25] Fix class exporting & importedVariable loading Signed-off-by: hufeng Change-Id: I324355cef4bb176e35ce1d4c4a27a9a3c0c8d520 --- ts2panda/src/scope.ts | 2 +- ts2panda/src/statement/classStatement.ts | 8 ++- ts2panda/tests/esmodule.test.ts | 78 ++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 ts2panda/tests/esmodule.test.ts diff --git a/ts2panda/src/scope.ts b/ts2panda/src/scope.ts index 24e7ebb468..3c8b01a1c5 100644 --- a/ts2panda/src/scope.ts +++ b/ts2panda/src/scope.ts @@ -420,7 +420,7 @@ export class ModuleScope extends VariableScope { setExportDecl(exportedLocalName: string) { let decl = this.getDecl(exportedLocalName); - if (decl) { + if (decl && decl.isModule != ModuleVarKind.IMPORTED) { decl.isModule = ModuleVarKind.EXPORTED; } } diff --git a/ts2panda/src/statement/classStatement.ts b/ts2panda/src/statement/classStatement.ts index ed9498afbf..4f6ba70520 100644 --- a/ts2panda/src/statement/classStatement.ts +++ b/ts2panda/src/statement/classStatement.ts @@ -137,8 +137,12 @@ export function compileClassDeclaration(compiler: Compiler, stmt: ts.ClassLikeDe pandaGen.stClassToGlobalRecord(stmt, className); } else { let classInfo = classScope.find(className); - (classInfo.v).initialize(); - pandaGen.storeAccToLexEnv(stmt, classInfo.scope!, classInfo.level, classInfo.v!, true); + (classInfo.v).initialize(); + if (classInfo.v instanceof ModuleVariable) { + pandaGen.storeModuleVariable(stmt, className); + } else { + pandaGen.storeAccToLexEnv(stmt, classInfo.scope!, classInfo.level, classInfo.v!, true); + } } } else { // throw SyntaxError in SyntaxChecker diff --git a/ts2panda/tests/esmodule.test.ts b/ts2panda/tests/esmodule.test.ts new file mode 100644 index 0000000000..e28b9b6db4 --- /dev/null +++ b/ts2panda/tests/esmodule.test.ts @@ -0,0 +1,78 @@ +/* + * 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 { + expect +} from 'chai'; +import 'mocha'; +import { checkInstructions, SnippetCompiler } from "./utils/base"; +import { + EcmaDefineclasswithbuffer, + EcmaLdmodulevar, + EcmaReturnundefined, + EcmaStmodulevar, + EcmaThrowundefinedifhole, + Imm, + LdaDyn, + LdaStr, + MovDyn, + StaDyn, + VReg +} from "../src/irnodes"; +import { CmdOptions } from '../src/cmdOptions'; + + +describe("ExportDeclaration", function () { + + it("exportClassTest ", function() { + CmdOptions.isModules = () => {return true}; + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile(`class C {}; export {C}`); + CmdOptions.isModules = () => {return false}; + let funcMainInsns = snippetCompiler.getGlobalInsns(); + let classReg = new VReg(); + let expected = [ + new MovDyn(new VReg(), new VReg()), + new EcmaDefineclasswithbuffer("#1#C", new Imm(0), new Imm(0), new VReg(), new VReg()), + new StaDyn(classReg), + new LdaDyn(classReg), + new EcmaStmodulevar('C'), + new EcmaReturnundefined(), + ]; + expect(checkInstructions(funcMainInsns, expected)).to.be.true; + }); + + it("Re-exportImportVarTest ", function() { + CmdOptions.isModules = () => {return true}; + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile(`import a from 'test.js'; let v = a; export {a};`); + CmdOptions.isModules = () => {return false}; + let funcMainInsns = snippetCompiler.getGlobalInsns(); + let a = new VReg(); + let v = new VReg(); + let name = new VReg(); + let expected = [ + new EcmaLdmodulevar("a", new Imm(0)), + new StaDyn(a), + new LdaStr("a"), + new StaDyn(name), + new EcmaThrowundefinedifhole(a, name), + new LdaDyn(a), + new StaDyn(v), + new EcmaReturnundefined(), + ]; + expect(checkInstructions(funcMainInsns, expected)).to.be.true; + }); +}); \ No newline at end of file -- Gitee From a717d9cc2a77dbbeeecca5c46b9aadfc4b9518f3 Mon Sep 17 00:00:00 2001 From: yinchuang Date: Thu, 21 Jul 2022 15:24:02 +0800 Subject: [PATCH 14/25] add --no-devtool for webpack Signed-off-by: yinchuang --- ts2panda/scripts/run.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ts2panda/scripts/run.py b/ts2panda/scripts/run.py index c405cf71ce..039c92e584 100755 --- a/ts2panda/scripts/run.py +++ b/ts2panda/scripts/run.py @@ -110,6 +110,8 @@ def npm_run_build(options): cmd = [webpack, '--config', 'webpack.config.js', '--progress', '--env', 'buildMode={}'.format(options.buildMode)] + if os.getenv("NO_DEVTOOL"): + cmd += ['--no-devtool'] run_command(cmd, options.dist_dir) if plat_form == "linux": per_platform_config(options, "build") -- Gitee From c7f361322cd1ba61305158ff1aa7e900ab4457e8 Mon Sep 17 00:00:00 2001 From: zhangrengao Date: Thu, 21 Jul 2022 16:14:40 +0800 Subject: [PATCH 15/25] Implement ignore error bigint syntaxerror and fix super error Signed-off-by: zhangrengao Change-Id: I3cc3cd8181d4e7010dd879eb6d78800617c7b47b --- ts2panda/src/ignoreSyntaxError.ts | 4 ++++ ts2panda/src/index.ts | 28 +++++++++++++++++++++++- ts2panda/src/statement/classStatement.ts | 9 ++++---- 3 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 ts2panda/src/ignoreSyntaxError.ts diff --git a/ts2panda/src/ignoreSyntaxError.ts b/ts2panda/src/ignoreSyntaxError.ts new file mode 100644 index 0000000000..de947ee61b --- /dev/null +++ b/ts2panda/src/ignoreSyntaxError.ts @@ -0,0 +1,4 @@ +const BigInt_literals_are_not_available_when_targeting_lower_than_ES2020: number = 2737; +export const IGNORE_ERROR_CODE: number[] = [ + BigInt_literals_are_not_available_when_targeting_lower_than_ES2020 +]; \ No newline at end of file diff --git a/ts2panda/src/index.ts b/ts2panda/src/index.ts index 866827b25d..e1b34e285c 100644 --- a/ts2panda/src/index.ts +++ b/ts2panda/src/index.ts @@ -24,6 +24,7 @@ import { LOGE } from "./log"; import { setGlobalDeclare, setGlobalStrict } from "./strictMode"; import { TypeChecker } from "./typeChecker"; import { setPos, isBase64Str, transformCommonjsModule } from "./base/util"; +import { IGNORE_ERROR_CODE } from './ignoreSyntaxError' function checkIsGlobalDeclaration(sourceFile: ts.SourceFile) { for (let statement of sourceFile.statements) { @@ -65,6 +66,10 @@ function main(fileNames: string[], options: ts.CompilerOptions) { } } + if (checkDiagnosticsError(program)) { + return; + } + let emitResult = program.emit( undefined, undefined, @@ -120,6 +125,10 @@ function main(fileNames: string[], options: ts.CompilerOptions) { .concat(emitResult.diagnostics); allDiagnostics.forEach(diagnostic => { + let ignoerErrorSet = new Set(IGNORE_ERROR_CODE); + if (ignoerErrorSet.has(diagnostic.code)) { + return; + } diag.printDiagnostic(diagnostic); }); } @@ -245,12 +254,29 @@ function keepWatchingFiles(filePath: string, parsed: ts.ParsedCommandLine | unde }); } +function checkDiagnosticsError(program: ts.Program) { + let diagnosticsFlag = false; + let allDiagnostics = ts + .getPreEmitDiagnostics(program); + allDiagnostics.forEach(diagnostic => { + let ignoerErrorSet = new Set(IGNORE_ERROR_CODE); + if (ignoerErrorSet.has(diagnostic.code)) { + diagnosticsFlag = false; + return; + } + diagnosticsFlag = true; + diag.printDiagnostic(diagnostic); + }); + + return diagnosticsFlag; +} + namespace Compiler { export namespace Options { export let Default: ts.CompilerOptions = { outDir: "../tmp/build", allowJs: true, - noEmitOnError: true, + noEmitOnError: false, noImplicitAny: true, target: ts.ScriptTarget.ES2017, module: ts.ModuleKind.ES2015, diff --git a/ts2panda/src/statement/classStatement.ts b/ts2panda/src/statement/classStatement.ts index ed9498afbf..3b816f6be6 100644 --- a/ts2panda/src/statement/classStatement.ts +++ b/ts2panda/src/statement/classStatement.ts @@ -416,10 +416,11 @@ function loadCtorObj(node: ts.CallExpression, compiler: Compiler) { return; } - let nearestFuncScope = recorder.getScopeOfNode(nearestFunc); - if (!nearestFuncScope) { - return; - } + // TODO the design needs to be reconsidered + // let nearestFuncScope = recorder.getScopeOfNode(nearestFunc); + // if (!nearestFuncScope) { + // return; + // } if (ts.isConstructorDeclaration(nearestFunc)) { pandaGen.loadAccumulator(node, getVregisterCache(pandaGen, CacheList.FUNC)); -- Gitee From 0fa1cc0662c8f196a8fc3a80d65f2d2acad6a830 Mon Sep 17 00:00:00 2001 From: gavin1012_hw Date: Mon, 18 Jul 2022 20:43:10 +0800 Subject: [PATCH 16/25] Support test262 tests 1. Support test262 2. Set es2abc as default test approach Signed-off-by: gavin1012_hw Change-Id: Ic3e3f6567612b66f36412eefe2dc88f619c7e839 --- test262/config.py | 10 +++++++- test262/run_sunspider.py | 50 +++++++++++++++++++++++++++------------- test262/run_test262.py | 44 ++++++++++++++++++++++++----------- 3 files changed, 73 insertions(+), 31 deletions(-) diff --git a/test262/config.py b/test262/config.py index a2f738b189..4ea7d7cefe 100755 --- a/test262/config.py +++ b/test262/config.py @@ -43,7 +43,6 @@ TEST_ES2021_DIR = os.path.join(DATA_DIR, "test_es2021") TEST_INTL_DIR = os.path.join(DATA_DIR, "test_intl") TEST_CI_DIR = os.path.join(DATA_DIR, "test_CI") -DEFAULT_ARK_FRONTEND_TOOL = os.path.join(ARK_DIR, "build", "src", "index.js") DEFAULT_ARK_TOOL = os.path.join(ARK_JS_RUNTIME_DIR, "ark_js_vm") DEFAULT_ARK_AOT_TOOL = os.path.join(ARK_JS_RUNTIME_DIR, "ark_aot_compiler") DEFAULT_LIBS_DIR = f"{ARK_DIR}:{ICUI_DIR}:{LLVM_DIR}:{ARK_JS_RUNTIME_DIR}" @@ -81,7 +80,14 @@ ARK_FRONTEND_LIST = [ "ts2panda", "es2panda" ] + +ARK_FRONTEND_BINARY_LIST = [ + os.path.join(ARK_DIR, "build", "src", "index.js"), + os.path.join(ARK_DIR, "es2abc") +] + DEFAULT_ARK_FRONTEND = ARK_FRONTEND_LIST[0] +DEFAULT_ARK_FRONTEND_BINARY = ARK_FRONTEND_BINARY_LIST[0] ARK_ARCH_LIST = [ "x64", @@ -90,3 +96,5 @@ ARK_ARCH_LIST = [ ] DEFAULT_ARK_ARCH = ARK_ARCH_LIST[0] +DEFAULT_OPT_LEVEL = 0 +DEFAULT_ES2ABC_THREAD_COUNT = 0 diff --git a/test262/run_sunspider.py b/test262/run_sunspider.py index 73e6228c93..5015f3b6cb 100755 --- a/test262/run_sunspider.py +++ b/test262/run_sunspider.py @@ -43,10 +43,6 @@ def parse_args(): default=DEFAULT_ARK_AOT_TOOL, required=False, help="ark's aot tool") - parser.add_argument('--ark-frontend-tool', - default=DEFAULT_ARK_FRONTEND_TOOL, - required=False, - help="ark frontend conversion tool") parser.add_argument("--libs-dir", default=DEFAULT_LIBS_DIR, required=False, @@ -59,6 +55,10 @@ def parse_args(): required=False, nargs='?', choices=ARK_FRONTEND_LIST, type=str, help="Choose one of them") + parser.add_argument('--ark-frontend-binary', + default=DEFAULT_ARK_FRONTEND_BINARY, + required=False, + help="ark frontend conversion binary tool") parser.add_argument('--module-list', required=True, help="module file list") @@ -71,6 +71,14 @@ def parse_args(): default=DEFAULT_ARK_ARCH, required=False, help="the root path for qemu-aarch64 or qemu-arm") + parser.add_argument('--opt-level', + default=DEFAULT_OPT_LEVEL, + required=False, + help="the opt level for es2abc") + parser.add_argument('--es2abc-thread-count', + default=DEFAULT_ES2ABC_THREAD_COUNT, + required=False, + help="the thread count for es2abc") arguments = parser.parse_args() return arguments @@ -79,10 +87,10 @@ ICU_PATH = f"--icu-data-path={CODE_ROOT}/third_party/icu/ohos_icu4j/data" if platform.system() == "Windows" : ICU_PATH = ICU_PATH.replace("/","\\") ARK_TOOL = DEFAULT_ARK_TOOL -ARK_FRONTEND_TOOL = DEFAULT_ARK_FRONTEND_TOOL LIBS_DIR = DEFAULT_LIBS_DIR ARK_AOT_TOOL = DEFAULT_ARK_AOT_TOOL ARK_FRONTEND = DEFAULT_ARK_FRONTEND +ARK_FRONTEND_BINARY = DEFAULT_ARK_FRONTEND_BINARY ARK_ARCH = DEFAULT_ARK_ARCH @@ -160,15 +168,17 @@ class ArkProgram(): self.ark_tool = ARK_TOOL self.ark_aot = False self.ark_aot_tool = ARK_AOT_TOOL - self.ark_frontend_tool = ARK_FRONTEND_TOOL self.libs_dir = LIBS_DIR self.ark_frontend = ARK_FRONTEND + self.ark_frontend_binary = ARK_FRONTEND_BINARY self.module_list = [] self.js_file = "" self.module = False self.abc_file = "" self.arch = ARK_ARCH self.arch_root = "" + self.opt_level = DEFAULT_OPT_LEVEL + self.es2abc_thread_count = DEFAULT_ES2ABC_THREAD_COUNT def proce_parameters(self): if self.args.ark_tool: @@ -180,8 +190,8 @@ class ArkProgram(): if self.args.ark_aot_tool: self.ark_aot_tool = self.args.ark_aot_tool - if self.args.ark_frontend_tool: - self.ark_frontend_tool = self.args.ark_frontend_tool + if self.args.ark_frontend_binary: + self.ark_frontend_binary = self.args.ark_frontend_binary if self.args.libs_dir: self.libs_dir = self.args.libs_dir @@ -189,6 +199,12 @@ class ArkProgram(): if self.args.ark_frontend: self.ark_frontend = self.args.ark_frontend + if self.args.opt_level: + self.opt_level = self.args.opt_level + + if self.args.es2abc_thread_count: + self.es2abc_thread_count = self.args.es2abc_thread_count + self.module_list = self.args.module_list.splitlines() self.js_file = self.args.js_file @@ -205,19 +221,21 @@ class ArkProgram(): self.abc_file = out_file mod_opt_index = 0 cmd_args = [] - frontend_tool = self.ark_frontend_tool + frontend_tool = self.ark_frontend_binary if self.ark_frontend == ARK_FRONTEND_LIST[0]: mod_opt_index = 3 cmd_args = ['node', '--expose-gc', frontend_tool, js_file, '-o', out_file] + if file_name in self.module_list: + cmd_args.insert(mod_opt_index, "-m") + self.module = True elif self.ark_frontend == ARK_FRONTEND_LIST[1]: mod_opt_index = 1 - cmd_args = [frontend_tool, '-c', - '-e', 'js', '-o', out_file, '-i', js_file] - - if file_name in self.module_list: - cmd_args.insert(mod_opt_index, "-m") - self.module = True + cmd_args = [frontend_tool, '--opt-level=' + str(self.opt_level), + '--thread=' + str(self.es2abc_thread_count), '--output', out_file, js_file] + if file_name in self.module_list: + cmd_args.insert(mod_opt_index, "--module") + self.module = True if self.ark_aot: os.system(f'''sed -i 's/;$262.destroy();/\/\/;$262.destroy();/g' {js_file}''') if self.module: @@ -308,7 +326,7 @@ class ArkProgram(): elif platform.system() == "Linux" : os.environ["LD_LIBRARY_PATH"] = self.libs_dir else : - sys.exit(f" test262 on {platform.system()} not supported"); + sys.exit(f" test262 on {platform.system()} not supported"); file_name_pre = os.path.splitext(self.js_file)[0] cmd_args = [] if self.arch == ARK_ARCH_LIST[1]: diff --git a/test262/run_test262.py b/test262/run_test262.py index f5dae7b018..8b6aac20d9 100755 --- a/test262/run_test262.py +++ b/test262/run_test262.py @@ -27,7 +27,7 @@ import sys import subprocess from multiprocessing import Pool import platform -from utils import * +from utils import * from config import * @@ -78,13 +78,13 @@ def parse_args(): help="Run test262 with aot") parser.add_argument('--ark-aot-tool', help="ark's aot tool") - parser.add_argument('--ark-frontend-tool', - help="ark frontend conversion tool") parser.add_argument("--libs-dir", help="The path collection of dependent so has been divided by':'") parser.add_argument('--ark-frontend', nargs='?', choices=ARK_FRONTEND_LIST, type=str, help="Choose one of them") + parser.add_argument('--ark-frontend-binary', + help="ark frontend conversion binary tool") parser.add_argument('--ark-arch', default=DEFAULT_ARK_ARCH, nargs='?', choices=ARK_ARCH_LIST, type=str, @@ -92,6 +92,12 @@ def parse_args(): parser.add_argument('--ark-arch-root', default=DEFAULT_ARK_ARCH, help="the root path for qemu-aarch64 or qemu-arm") + parser.add_argument('--opt-level', + default=DEFAULT_OPT_LEVEL, + help="the opt level for es2abc") + parser.add_argument('--es2abc-thread-count', + default=DEFAULT_ES2ABC_THREAD_COUNT, + help="the thread count for es2abc") return parser.parse_args() @@ -113,15 +119,15 @@ def excuting_npm_install(args): if args.ark_frontend: ark_frontend = args.ark_frontend - if ark_frontend != DEFAULT_ARK_FRONTEND: + if ark_frontend != ARK_FRONTEND_LIST[0]: return - ark_frontend_tool = os.path.join(DEFAULT_ARK_FRONTEND_TOOL) - if args.ark_frontend_tool: - ark_frontend_tool = os.path.join(args.ark_frontend_tool) + ark_frontend_binary = os.path.join(ARK_FRONTEND_BINARY_LIST[0]) + if args.ark_frontend_binary: + ark_frontend_binary = os.path.join(args.ark_frontend_binary) ts2abc_build_dir = os.path.join(os.path.dirname( - os.path.realpath(ark_frontend_tool)), "..") + os.path.realpath(ark_frontend_binary)), "..") if os.path.exists(os.path.join(ts2abc_build_dir, "package.json")): npm_install(ts2abc_build_dir) @@ -337,7 +343,7 @@ class TestPrepare(): if self.args.intl: files = self.get_tests_from_file(INTL_LIST_FILE) return files - + def prepare_es2015_tests(self): files = [] files = self.collect_tests() @@ -473,11 +479,13 @@ def get_host_args(args, host_type): host_args = "" ark_tool = DEFAULT_ARK_TOOL ark_aot_tool = DEFAULT_ARK_AOT_TOOL - ark_frontend_tool = DEFAULT_ARK_FRONTEND_TOOL libs_dir = DEFAULT_LIBS_DIR ark_frontend = DEFAULT_ARK_FRONTEND + ark_frontend_binary = DEFAULT_ARK_FRONTEND_BINARY ark_arch = DEFAULT_ARK_ARCH module_list = '' + opt_level = DEFAULT_OPT_LEVEL + es2abc_thread_count = DEFAULT_ES2ABC_THREAD_COUNT with open(MODULE_FILES_LIST) as fopen: module_list = fopen.read() @@ -490,25 +498,33 @@ def get_host_args(args, host_type): if args.ark_aot_tool: ark_aot_tool = args.ark_aot_tool - if args.ark_frontend_tool: - ark_frontend_tool = args.ark_frontend_tool - if args.libs_dir: libs_dir = args.libs_dir if args.ark_frontend: ark_frontend = args.ark_frontend + if args.ark_frontend_binary: + ark_frontend_binary = args.ark_frontend_binary + + if args.opt_level: + opt_level = args.opt_level + + if args.es2abc_thread_count: + es2abc_thread_count = args.es2abc_thread_count + if host_type == DEFAULT_HOST_TYPE: host_args = f"-B test262/run_sunspider.py " host_args += f"--ark-tool={ark_tool} " if args.ark_aot: host_args += f"--ark-aot " host_args += f"--ark-aot-tool={ark_aot_tool} " - host_args += f"--ark-frontend-tool={ark_frontend_tool} " host_args += f"--libs-dir={libs_dir} " host_args += f"--ark-frontend={ark_frontend} " + host_args += f"--ark-frontend-binary={ark_frontend_binary} " host_args += f"--module-list={module_list} " + host_args += f"--opt-level={opt_level} " + host_args += f"--es2abc-thread-count={es2abc_thread_count} " if args.ark_arch != ark_arch: host_args += f"--ark-arch={args.ark_arch} " -- Gitee From 29ac5a4f7977ed312e3d3398d3a99ced4c496964 Mon Sep 17 00:00:00 2001 From: gavin1012_hw Date: Tue, 19 Jul 2022 20:04:29 +0800 Subject: [PATCH 17/25] Fix syntax error 1. Fix syntax error found in test262 2. Fix syntax error found in break statement Issue: I5IH42 Signed-off-by: gavin1012_hw Change-Id: I929438b1dc8d9bae39cb26da27fbe2edfbafef28 --- es2panda/parser/statementParser.cpp | 63 ++++++++++++----------------- 1 file changed, 25 insertions(+), 38 deletions(-) diff --git a/es2panda/parser/statementParser.cpp b/es2panda/parser/statementParser.cpp index 2a06a84efb..57a680a862 100644 --- a/es2panda/parser/statementParser.cpp +++ b/es2panda/parser/statementParser.cpp @@ -388,7 +388,7 @@ ir::Statement *ParserImpl::ParseVarStatement(bool isDeclare) ir::Statement *ParserImpl::ParseLetStatement(StatementParsingFlags flags, bool isDeclare) { if (!(flags & StatementParsingFlags::ALLOW_LEXICAL)) { - ThrowSyntaxError("Lexical declaration is not allowed in single statement context"); + ThrowSyntaxError("The 'let' declarations can only be declared at the top level or inside a block."); } auto *variableDecl = ParseVariableDeclaration(VariableParsingFlags::LET, isDeclare); @@ -399,7 +399,7 @@ ir::Statement *ParserImpl::ParseLetStatement(StatementParsingFlags flags, bool i ir::Statement *ParserImpl::ParseConstStatement(StatementParsingFlags flags, bool isDeclare) { if (!(flags & StatementParsingFlags::ALLOW_LEXICAL)) { - ThrowSyntaxError("Lexical declaration is not allowed in single statement context"); + ThrowSyntaxError("The 'const' declarations can only be declared at the top level or inside a block."); } lexer::SourcePosition constVarStar = lexer_->GetToken().Start(); @@ -488,7 +488,7 @@ ir::ClassDeclaration *ParserImpl::ParseClassStatement(StatementParsingFlags flag ArenaVector &&decorators, bool isAbstract) { if (!(flags & StatementParsingFlags::ALLOW_LEXICAL)) { - ThrowSyntaxError("Lexical declaration is not allowed in single statement context"); + ThrowSyntaxError("Lexical 'class' declaration is not allowed in single statement context"); } return ParseClassDeclaration(true, std::move(decorators), isDeclare, isAbstract); @@ -671,23 +671,19 @@ ir::TSInterfaceDeclaration *ParserImpl::ParseTsInterfaceDeclaration() void ParserImpl::CheckFunctionDeclaration(StatementParsingFlags flags) { - if (flags & StatementParsingFlags::LABELLED) { - ThrowSyntaxError( - "In strict mode code, functions can only be " - "declared at top level, inside a block, " - "or " - "as the body of an if statement"); + if (flags & StatementParsingFlags::ALLOW_LEXICAL) { + return; } - if (!(flags & StatementParsingFlags::ALLOW_LEXICAL)) { - if (!(flags & (StatementParsingFlags::IF_ELSE | StatementParsingFlags::LABELLED))) { - ThrowSyntaxError("Lexical declaration is not allowed in single statement context"); - } - - if (lexer_->Lookahead() == LEX_CHAR_ASTERISK) { - ThrowSyntaxError("Generators can only be declared at the top level or inside a block"); - } + if (lexer_->Lookahead() == LEX_CHAR_ASTERISK) { + ThrowSyntaxError("Generators can only be declared at the top level or inside a block."); } + + ThrowSyntaxError( + "In strict mode code, functions can only be " + "declared at top level, inside a block, " + "or " + "as the body of an if statement"); } void ParserImpl::ConsumeSemicolon(ir::Statement *statement) @@ -790,11 +786,11 @@ ir::BreakStatement *ParserImpl::ParseBreakStatement() } lexer::SourcePosition startLoc = lexer_->GetToken().Start(); - lexer::SourcePosition endLoc = lexer_->GetToken().End(); lexer_->NextToken(); if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON || - lexer_->GetToken().Type() == lexer::TokenType::EOS || lexer_->GetToken().NewLine()) { + lexer_->GetToken().Type() == lexer::TokenType::EOS || lexer_->GetToken().NewLine() || + lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { if (!allowBreak) { if (Extension() == ScriptExtension::JS) { ThrowSyntaxError("Illegal break statement"); @@ -808,24 +804,10 @@ ir::BreakStatement *ParserImpl::ParseBreakStatement() auto *breakStatement = AllocNode(); breakStatement->SetRange({startLoc, lexer_->GetToken().End()}); - lexer_->NextToken(); - return breakStatement; - } - - if (lexer_->GetToken().NewLine() || lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { - if (!allowBreak) { - if (Extension() == ScriptExtension::JS) { - ThrowSyntaxError("Illegal break statement"); - } - if (Extension() == ScriptExtension::TS) { - ThrowSyntaxError( - "A 'break' statement can only be used within an " - "enclosing iteration or switch statement"); - } + if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) { + lexer_->NextToken(); } - auto *breakStatement = AllocNode(); - breakStatement->SetRange({startLoc, endLoc}); return breakStatement; } @@ -1019,7 +1001,7 @@ ir::Statement *ParserImpl::ParseExpressionStatement(StatementParsingFlags flags) if (lexer_->GetToken().Type() == lexer::TokenType::KEYW_FUNCTION && !lexer_->GetToken().NewLine()) { if (!(flags & StatementParsingFlags::ALLOW_LEXICAL)) { - ThrowSyntaxError("Lexical declaration is not allowed in single statement context"); + ThrowSyntaxError("Async functions can only be declared at the top level or inside a block."); } ir::FunctionDeclaration *functionDecl = ParseFunctionDeclaration(false, ParserStatus::ASYNC_FUNCTION); @@ -1341,7 +1323,7 @@ ir::IfStatement *ParserImpl::ParseIfStatement() } lexer_->NextToken(); - ir::Statement *consequent = ParseStatement(StatementParsingFlags::IF_ELSE | StatementParsingFlags::ALLOW_LEXICAL); + ir::Statement *consequent = ParseStatement(StatementParsingFlags::IF_ELSE); if (Extension() == ScriptExtension::TS && consequent->IsEmptyStatement()) { ThrowSyntaxError("The body of an if statement cannot be the empty statement"); @@ -1352,7 +1334,7 @@ ir::IfStatement *ParserImpl::ParseIfStatement() if (lexer_->GetToken().Type() == lexer::TokenType::KEYW_ELSE) { lexer_->NextToken(); // eat ELSE keyword - alternate = ParseStatement(StatementParsingFlags::IF_ELSE | StatementParsingFlags::ALLOW_LEXICAL); + alternate = ParseStatement(StatementParsingFlags::IF_ELSE); endLoc = alternate->End(); } @@ -1816,6 +1798,11 @@ ir::Statement *ParserImpl::ParseVariableDeclaration(VariableParsingFlags flags, lexer_->NextToken(); } + if ((flags & VariableParsingFlags::LET) && util::Helpers::IsGlobalIdentifier(lexer_->GetToken().Ident())) { + ThrowSyntaxError("Declaration name conflicts with built-in global identifier '" + + lexer_->GetToken().Ident().Mutf8() + "'."); + } + if (Extension() == ScriptExtension::TS && lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_ENUM) { if (!(flags & VariableParsingFlags::CONST)) { ThrowSyntaxError("Variable declaration expected."); -- Gitee From 3fd76105cd6b4c9f813a83e58655a1ffd4ef161b Mon Sep 17 00:00:00 2001 From: gavin1012_hw Date: Tue, 19 Jul 2022 16:03:46 +0800 Subject: [PATCH 18/25] Fix function name from 'func_name_idx' into '#idx#funcname' style Issue: I5IH16 Signed-off-by: gavin1012_hw Change-Id: I5db082280ae896bfaead96833654c6a765e12c97 --- es2panda/binder/binder.cpp | 17 +++++++++++++---- es2panda/binder/binder.h | 12 +++++++++++- es2panda/util/ustring.h | 5 +++++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/es2panda/binder/binder.cpp b/es2panda/binder/binder.cpp index d2a8b2ad39..de4a302447 100644 --- a/es2panda/binder/binder.cpp +++ b/es2panda/binder/binder.cpp @@ -80,7 +80,7 @@ void Binder::IdentifierAnalysis() ASSERT(program_->Ast()); ASSERT(scope_ == topScope_); - BuildFunction(topScope_, "main"); + BuildFunction(topScope_, MAIN_FUNC_NAME); ResolveReferences(program_->Ast()); AddMandatoryParams(); } @@ -160,13 +160,22 @@ void Binder::LookupIdentReference(ir::Identifier *ident) void Binder::BuildFunction(FunctionScope *funcScope, util::StringView name) { - uint32_t idx = functionScopes_.size(); functionScopes_.push_back(funcScope); + bool funcNameWithoutDot = (name.Find(".") == std::string::npos); + bool funcNameWithoutBackslash = (name.Find("\\") == std::string::npos); + if (name != ANONYMOUS_FUNC_NAME && funcNameWithoutDot && funcNameWithoutBackslash && !functionNames_.count(name)) { + functionNames_.insert(name); + funcScope->BindName(name, name); + return; + } std::stringstream ss; - ss << "func_" << name << "_" << std::to_string(idx); + uint32_t idx = functionNameIndex_++; + ss << "#" << std::to_string(idx) << "#"; + if (funcNameWithoutDot && funcNameWithoutBackslash) { + ss << name; + } util::UString internalName(ss.str(), Allocator()); - funcScope->BindName(name, internalName.View()); } diff --git a/es2panda/binder/binder.h b/es2panda/binder/binder.h index 28f4b038d2..90f06aebf7 100644 --- a/es2panda/binder/binder.h +++ b/es2panda/binder/binder.h @@ -41,7 +41,12 @@ class VariableScope; class Binder { public: - explicit Binder(parser::Program *program) : program_(program), functionScopes_(Allocator()->Adapter()) {} + explicit Binder(parser::Program *program) + : program_(program), + functionScopes_(Allocator()->Adapter()), + functionNames_(Allocator()->Adapter()) + { + } NO_COPY_SEMANTIC(Binder); DEFAULT_MOVE_SEMANTIC(Binder); ~Binder() = default; @@ -104,6 +109,9 @@ public: static constexpr std::string_view LEXICAL_MANDATORY_PARAM_NEW_TARGET = "!nt"; static constexpr std::string_view LEXICAL_MANDATORY_PARAM_THIS = "!t"; + static constexpr std::string_view MAIN_FUNC_NAME = "func_main_0"; + static constexpr std::string_view ANONYMOUS_FUNC_NAME = ""; + private: using MandatoryParams = std::array; @@ -138,6 +146,8 @@ private: GlobalScope *topScope_ {}; Scope *scope_ {}; ArenaVector functionScopes_; + ArenaSet functionNames_; + size_t functionNameIndex_ {1}; }; template diff --git a/es2panda/util/ustring.h b/es2panda/util/ustring.h index 1801234961..4114601087 100644 --- a/es2panda/util/ustring.h +++ b/es2panda/util/ustring.h @@ -109,6 +109,11 @@ public: return StringView(std::string_view(sv_.data() + begin, end - begin)); } + constexpr size_t Find(const char *str) + { + return sv_.find(str); + } + static bool IsHighSurrogate(char32_t cp) { return (cp >= Constants::SURROGATE_HIGH_MIN && cp < Constants::SURROGATE_HIGH_MAX); -- Gitee From 41501683d28f7df6f4646eabaef3ffe504102bf4 Mon Sep 17 00:00:00 2001 From: gavin1012_hw Date: Tue, 19 Jul 2022 10:16:07 +0800 Subject: [PATCH 19/25] Support Instructions for es2abc 1. Fix BranchIfTrue and BranchIfFalse instruction 2. Support BigInt instruction 3. Support stlettoglobalrecord/stconstttoglobalrecord/stclasstoglobalreocord instruction Issue: I5IH5V Signed-off-by: gavin1012_hw Change-Id: I60daaaf8f189c877551f663b77d6b7913f6ebbbc --- es2panda/binder/binder.cpp | 4 +- es2panda/binder/declaration.h | 14 +++++- es2panda/binder/scope.cpp | 2 +- es2panda/binder/variableFlags.h | 1 + es2panda/compiler/base/lexenv.cpp | 2 +- es2panda/compiler/core/pandagen.cpp | 48 ++++++++++++++++++- es2panda/compiler/core/pandagen.h | 6 +++ es2panda/ir/base/classDefinition.cpp | 3 -- .../ir/expressions/literals/bigIntLiteral.cpp | 4 +- es2panda/parser/statementParser.cpp | 2 +- 10 files changed, 73 insertions(+), 13 deletions(-) diff --git a/es2panda/binder/binder.cpp b/es2panda/binder/binder.cpp index d2a8b2ad39..44ef3b14e5 100644 --- a/es2panda/binder/binder.cpp +++ b/es2panda/binder/binder.cpp @@ -151,7 +151,7 @@ void Binder::LookupIdentReference(ir::Identifier *ident) return; } - if (res.variable->Declaration()->IsLetOrConstDecl() && !res.variable->HasFlag(VariableFlags::INITIALIZED)) { + if (res.variable->Declaration()->IsLetOrConstOrClassDecl() && !res.variable->HasFlag(VariableFlags::INITIALIZED)) { ident->SetTdz(); } @@ -245,7 +245,7 @@ void Binder::BuildClassDefinition(ir::ClassDefinition *classDef) if (classDef->Parent()->IsClassDeclaration()) { ScopeFindResult res = scope_->Find(classDef->Ident()->Name()); - ASSERT(res.variable && res.variable->Declaration()->IsLetDecl()); + ASSERT(res.variable && res.variable->Declaration()->IsClassDecl()); res.variable->AddFlag(VariableFlags::INITIALIZED); } diff --git a/es2panda/binder/declaration.h b/es2panda/binder/declaration.h index ab65a7579a..1e83a306e8 100644 --- a/es2panda/binder/declaration.h +++ b/es2panda/binder/declaration.h @@ -77,9 +77,9 @@ public: node_ = node; } - bool IsLetOrConstDecl() const + bool IsLetOrConstOrClassDecl() const { - return IsLetDecl() || IsConstDecl(); + return IsLetDecl() || IsConstDecl() || IsClassDecl(); } protected: @@ -234,6 +234,16 @@ public: } }; +class ClassDecl : public Decl { +public: + explicit ClassDecl(util::StringView name) : Decl(name) {} + + DeclType Type() const override + { + return DeclType::CLASS; + } +}; + class ParameterDecl : public Decl { public: explicit ParameterDecl(util::StringView name) : Decl(name) {} diff --git a/es2panda/binder/scope.cpp b/es2panda/binder/scope.cpp index 402bdd7a0c..e044f66c46 100644 --- a/es2panda/binder/scope.cpp +++ b/es2panda/binder/scope.cpp @@ -444,7 +444,7 @@ void LoopDeclarationScope::ConvertToVariableScope(ArenaAllocator *allocator) } for (auto &[name, var] : bindings_) { - if (!var->LexicalBound() || !var->Declaration()->IsLetOrConstDecl()) { + if (!var->LexicalBound() || !var->Declaration()->IsLetOrConstOrClassDecl()) { continue; } diff --git a/es2panda/binder/variableFlags.h b/es2panda/binder/variableFlags.h index dee8b14757..3a7f3a7138 100644 --- a/es2panda/binder/variableFlags.h +++ b/es2panda/binder/variableFlags.h @@ -24,6 +24,7 @@ namespace panda::es2panda::binder { _(VAR, VarDecl) \ _(LET, LetDecl) \ _(CONST, ConstDecl) \ + _(CLASS, ClassDecl) \ _(FUNC, FunctionDecl) \ _(PARAM, ParameterDecl) \ _(IMPORT, ImportDecl) \ diff --git a/es2panda/compiler/base/lexenv.cpp b/es2panda/compiler/base/lexenv.cpp index f3410f06c2..0ca34ca25e 100644 --- a/es2panda/compiler/base/lexenv.cpp +++ b/es2panda/compiler/base/lexenv.cpp @@ -91,7 +91,7 @@ static void ExpandStoreLexVar(PandaGen *pg, const ir::AstNode *node, const binde const auto *decl = result.variable->Declaration(); - if (decl->IsLetOrConstDecl() && !isDecl) { + if (decl->IsLetOrConstOrClassDecl() && !isDecl) { RegScope rs(pg); VReg valueReg = pg->AllocReg(); diff --git a/es2panda/compiler/core/pandagen.cpp b/es2panda/compiler/core/pandagen.cpp index 7cf1bb96f5..c95c4539d4 100644 --- a/es2panda/compiler/core/pandagen.cpp +++ b/es2panda/compiler/core/pandagen.cpp @@ -222,6 +222,12 @@ void PandaGen::LoadVar(const ir::Identifier *node, const binder::ScopeFindResult } ASSERT(var->IsLocalVariable()); + + if (var->Declaration()->IsLetOrConstOrClassDecl() && result.scope->IsGlobalScope()) { + TryLoadGlobalByName(node, result.name); + return; + } + LoadAccFromLexEnv(node, result); } @@ -245,6 +251,20 @@ void PandaGen::StoreVar(const ir::AstNode *node, const binder::ScopeFindResult & } ASSERT(var->IsLocalVariable()); + + if (var->Declaration()->IsLetOrConstOrClassDecl() && result.scope->IsGlobalScope()) { + if (!isDeclaration) { + TryStoreGlobalByName(node, var->Name()); + } else if (var->Declaration()->IsLetDecl()) { + StLetToGlobalRecord(node, var->Name()); + } else if (var->Declaration()->IsConstDecl()) { + StConstToGlobalRecord(node, var->Name()); + } else if (var->Declaration()->IsClassDecl()) { + StClassToGlobalRecord(node, var->Name()); + } + return; + } + StoreAccToLexEnv(node, result, isDeclaration); } @@ -455,6 +475,12 @@ void PandaGen::LoadAccumulatorInt(const ir::AstNode *node, size_t num) sa_.Emit(node, static_cast(num)); } +void PandaGen::LoadAccumulatorBigInt(const ir::AstNode *node, const util::StringView &num) +{ + sa_.Emit(node, num); + strings_.insert(num); +} + void PandaGen::StoreConst(const ir::AstNode *node, VReg reg, Constant id) { LoadConst(node, id); @@ -804,6 +830,7 @@ void PandaGen::BranchIfNotUndefined(const ir::AstNode *node, Label *target) void PandaGen::BranchIfTrue(const ir::AstNode *node, Label *target) { + sa_.Emit(node); sa_.Emit(node, target); } @@ -815,7 +842,8 @@ void PandaGen::BranchIfNotTrue(const ir::AstNode *node, Label *target) void PandaGen::BranchIfFalse(const ir::AstNode *node, Label *target) { - sa_.Emit(node, target); + sa_.Emit(node); + sa_.Emit(node, target); } void PandaGen::EmitThrow(const ir::AstNode *node) @@ -1594,4 +1622,22 @@ VReg PandaGen::LoadPropertyKey(const ir::Expression *prop, bool isComputed) return propReg; } +void PandaGen::StLetToGlobalRecord(const ir::AstNode *node, const util::StringView &name) +{ + sa_.Emit(node, name); + strings_.insert(name); +} + +void PandaGen::StConstToGlobalRecord(const ir::AstNode *node, const util::StringView &name) +{ + sa_.Emit(node, name); + strings_.insert(name); +} + +void PandaGen::StClassToGlobalRecord(const ir::AstNode *node, const util::StringView &name) +{ + sa_.Emit(node, name); + strings_.insert(name); +} + } // namespace panda::es2panda::compiler diff --git a/es2panda/compiler/core/pandagen.h b/es2panda/compiler/core/pandagen.h index 77d127c423..375c0e6de3 100644 --- a/es2panda/compiler/core/pandagen.h +++ b/es2panda/compiler/core/pandagen.h @@ -208,6 +208,10 @@ public: void LoadVar(const ir::Identifier *node, const binder::ScopeFindResult &result); void StoreVar(const ir::AstNode *node, const binder::ScopeFindResult &result, bool isDeclaration); + void StLetToGlobalRecord(const ir::AstNode *node, const util::StringView &name); + void StConstToGlobalRecord(const ir::AstNode *node, const util::StringView &name); + void StClassToGlobalRecord(const ir::AstNode *node, const util::StringView &name); + void StoreAccumulator(const ir::AstNode *node, VReg vreg); void LoadAccFromArgs(const ir::AstNode *node); void LoadObjProperty(const ir::AstNode *node, VReg obj, const Operand &prop); @@ -234,6 +238,7 @@ public: void LoadAccumulatorFloat(const ir::AstNode *node, double num); void LoadAccumulatorInt(const ir::AstNode *node, int32_t num); void LoadAccumulatorInt(const ir::AstNode *node, size_t num); + void LoadAccumulatorBigInt(const ir::AstNode *node, const util::StringView &num); void LoadConst(const ir::AstNode *node, Constant id); void StoreConst(const ir::AstNode *node, VReg reg, Constant id); @@ -255,6 +260,7 @@ public: void BranchIfTrue(const ir::AstNode *node, class Label *target); void BranchIfNotTrue(const ir::AstNode *node, class Label *target); void BranchIfFalse(const ir::AstNode *node, class Label *target); + void BranchIfNotFalse(const ir::AstNode *node, class Label *target); void EmitThrow(const ir::AstNode *node); void EmitRethrow(const ir::AstNode *node); diff --git a/es2panda/ir/base/classDefinition.cpp b/es2panda/ir/base/classDefinition.cpp index bd18a40d34..7eea3dab22 100644 --- a/es2panda/ir/base/classDefinition.cpp +++ b/es2panda/ir/base/classDefinition.cpp @@ -269,9 +269,6 @@ void ClassDefinition::Compile(compiler::PandaGen *pg) const int32_t bufIdx = CreateClassStaticProperties(pg, compiled); pg->DefineClassWithBuffer(this, ctorId, bufIdx, lexenv, baseReg); - if (scope_->Parent()->IsGlobalScope() && ident_) { - pg->StoreGlobalLet(this, ident_->Name()); - } pg->StoreAccumulator(this, classReg); InitializeClassName(pg); diff --git a/es2panda/ir/expressions/literals/bigIntLiteral.cpp b/es2panda/ir/expressions/literals/bigIntLiteral.cpp index 7d3a149f8f..19290522c6 100644 --- a/es2panda/ir/expressions/literals/bigIntLiteral.cpp +++ b/es2panda/ir/expressions/literals/bigIntLiteral.cpp @@ -30,8 +30,8 @@ void BigIntLiteral::Dump(ir::AstDumper *dumper) const void BigIntLiteral::Compile(compiler::PandaGen *pg) const { - // TODO() - pg->Unimplemented(); + util::StringView bigIntValue = src_.Substr(0, src_.Length()-1); + pg->LoadAccumulatorBigInt(this, bigIntValue); } checker::Type *BigIntLiteral::Check(checker::Checker *checker) const diff --git a/es2panda/parser/statementParser.cpp b/es2panda/parser/statementParser.cpp index 2a06a84efb..ca09b54cb2 100644 --- a/es2panda/parser/statementParser.cpp +++ b/es2panda/parser/statementParser.cpp @@ -501,7 +501,7 @@ ir::ClassDeclaration *ParserImpl::ParseClassDeclaration(bool idRequired, ArenaVe ir::ClassDefinition *classDefinition = ParseClassDefinition(true, idRequired, isDeclare, isAbstract); auto *decl = - Binder()->AddDecl(classDefinition->Ident()->Start(), classDefinition->Ident()->Name()); + Binder()->AddDecl(classDefinition->Ident()->Start(), classDefinition->Ident()->Name()); decl->BindNode(classDefinition); lexer::SourcePosition endLoc = classDefinition->End(); -- Gitee From 3f48f68586542f34cc3de4e245f8f14b67e17262 Mon Sep 17 00:00:00 2001 From: ctw-ian Date: Tue, 19 Jul 2022 19:45:45 +0800 Subject: [PATCH 20/25] Fix class compilation Fix class compilation of es2abc Issue:I5IHRG Signed-off-by: ctw-ian Change-Id: Ia7e171987e63aea9dc48a5db4c577743819ea042 --- es2panda/compiler/core/emitter.cpp | 5 ++ es2panda/compiler/core/pandagen.cpp | 54 +++++++++++++------ es2panda/compiler/core/pandagen.h | 7 +-- es2panda/ir/base/classDefinition.cpp | 28 +++++++--- es2panda/ir/base/methodDefinition.h | 5 ++ es2panda/ir/expressions/literal.cpp | 6 +++ es2panda/ir/expressions/literal.h | 6 ++- .../ir/expressions/literals/taggedLiteral.h | 12 +++++ 8 files changed, 93 insertions(+), 30 deletions(-) diff --git a/es2panda/compiler/core/emitter.cpp b/es2panda/compiler/core/emitter.cpp index ac04127360..94129c5446 100644 --- a/es2panda/compiler/core/emitter.cpp +++ b/es2panda/compiler/core/emitter.cpp @@ -115,6 +115,11 @@ void FunctionEmitter::GenBufferLiterals(const LiteralBuffer *buff) valueLit.value_ = literal->GetMethod().Mutf8(); break; } + case ir::LiteralTag::METHODAFFILIATE: { + valueLit.tag_ = panda::panda_file::LiteralTag::METHODAFFILIATE; + valueLit.value_ = literal->GetMethodAffiliate(); + break; + } case ir::LiteralTag::GENERATOR_METHOD: { valueLit.tag_ = panda::panda_file::LiteralTag::GENERATORMETHOD; valueLit.value_ = literal->GetMethod().Mutf8(); diff --git a/es2panda/compiler/core/pandagen.cpp b/es2panda/compiler/core/pandagen.cpp index c95c4539d4..17375d9a93 100644 --- a/es2panda/compiler/core/pandagen.cpp +++ b/es2panda/compiler/core/pandagen.cpp @@ -31,8 +31,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -320,10 +322,10 @@ void PandaGen::StoreObjProperty(const ir::AstNode *node, VReg obj, const Operand StoreObjByName(node, obj, std::get(prop)); } -void PandaGen::StoreOwnProperty(const ir::AstNode *node, VReg obj, const Operand &prop) +void PandaGen::StoreOwnProperty(const ir::AstNode *node, VReg obj, const Operand &prop, bool nameSetting) { if (std::holds_alternative(prop)) { - StOwnByValue(node, obj, std::get(prop)); + StOwnByValue(node, obj, std::get(prop), nameSetting); return; } @@ -333,7 +335,7 @@ void PandaGen::StoreOwnProperty(const ir::AstNode *node, VReg obj, const Operand } ASSERT(std::holds_alternative(prop)); - StOwnByName(node, obj, std::get(prop)); + StOwnByName(node, obj, std::get(prop), nameSetting); } void PandaGen::TryLoadGlobalByName(const ir::AstNode *node, const util::StringView &name) @@ -380,20 +382,22 @@ void PandaGen::StoreObjByIndex(const ir::AstNode *node, VReg obj, int64_t index) ra_.Emit(node, index, obj); } -void PandaGen::StOwnByName(const ir::AstNode *node, VReg obj, const util::StringView &prop) +void PandaGen::StOwnByName(const ir::AstNode *node, VReg obj, const util::StringView &prop, bool nameSetting) { - ra_.Emit(node, prop, obj); + nameSetting ? ra_.Emit(node, prop, obj) : + ra_.Emit(node, prop, obj); strings_.insert(prop); } -void PandaGen::StOwnByValue(const ir::AstNode *node, VReg obj, VReg prop) +void PandaGen::StOwnByValue(const ir::AstNode *node, VReg obj, VReg prop, bool nameSetting) { - ra_.Emit(node, obj, prop); + nameSetting ? ra_.Emit(node, obj, prop) : + ra_.Emit(node, obj, prop); } void PandaGen::StOwnByIndex(const ir::AstNode *node, VReg obj, int64_t index) { - ra_.Emit(node, index, obj); + ra_.Emit(node, obj, index); } void PandaGen::DeleteObjProperty(const ir::AstNode *node, VReg obj, const Operand &prop) @@ -828,6 +832,16 @@ void PandaGen::BranchIfNotUndefined(const ir::AstNode *node, Label *target) sa_.Emit(node, target); } +void PandaGen::BranchIfStrictNotUndefined(const ir::AstNode *node, class Label *target) +{ + RegScope rs(this); + VReg tmp = AllocReg(); + StoreAccumulator(node, tmp); + LoadConst(node, Constant::JS_UNDEFINED); + ra_.Emit(node, tmp); + sa_.Emit(node, target); +} + void PandaGen::BranchIfTrue(const ir::AstNode *node, Label *target) { sa_.Emit(node); @@ -891,7 +905,7 @@ void PandaGen::ValidateClassDirectReturn(const ir::AstNode *node) auto *notUndefined = AllocLabel(); auto *condEnd = AllocLabel(); - BranchIfNotUndefined(node, notUndefined); + BranchIfStrictNotUndefined(node, notUndefined); GetThis(func); ThrowIfSuperNotCorrectCall(func, 0); Branch(node, condEnd); @@ -968,7 +982,7 @@ void PandaGen::LoadHomeObject(const ir::AstNode *node) void PandaGen::DefineFunction(const ir::AstNode *node, const ir::ScriptFunction *realNode, const util::StringView &name) { - auto formalParamCnt = FormalParametersCount(); + auto formalParamCnt = realNode->FormalParamsLength(); if (realNode->IsAsync()) { if (realNode->IsGenerator()) { // TODO(): async generator @@ -1369,7 +1383,7 @@ void PandaGen::ImportModule(const ir::AstNode *node, const util::StringView &nam void PandaGen::DefineClassWithBuffer(const ir::AstNode *node, const util::StringView &ctorId, int32_t litIdx, VReg lexenv, VReg base) { - auto formalParamCnt = FormalParametersCount(); + auto formalParamCnt = node->AsClassDefinition()->Ctor()->Function()->FormalParamsLength(); ra_.Emit(node, ctorId, litIdx, static_cast(formalParamCnt), lexenv, base); strings_.insert(ctorId); } @@ -1558,11 +1572,15 @@ Operand PandaGen::ToNamedPropertyKey(const ir::Expression *prop, bool isComputed { VReg res {0}; - if (!isComputed) { - if (prop->IsIdentifier()) { - return prop->AsIdentifier()->Name(); - } - } else if (prop->IsStringLiteral()) { + if (isComputed) { + return res; + } + + if (prop->IsIdentifier()) { + return prop->AsIdentifier()->Name(); + } + + if (prop->IsStringLiteral()) { const util::StringView &str = prop->AsStringLiteral()->Str(); /* TODO(dbatyai): remove this when runtime handles __proto__ as property name correctly */ @@ -1576,7 +1594,9 @@ Operand PandaGen::ToNamedPropertyKey(const ir::Expression *prop, bool isComputed } return str; - } else if (prop->IsNumberLiteral()) { + } + + if (prop->IsNumberLiteral()) { auto num = prop->AsNumberLiteral()->Number(); if (util::Helpers::IsIndex(num)) { return static_cast(num); diff --git a/es2panda/compiler/core/pandagen.h b/es2panda/compiler/core/pandagen.h index 375c0e6de3..67582f92e3 100644 --- a/es2panda/compiler/core/pandagen.h +++ b/es2panda/compiler/core/pandagen.h @@ -219,7 +219,7 @@ public: void LoadObjByName(const ir::AstNode *node, VReg obj, const util::StringView &prop); void StoreObjProperty(const ir::AstNode *node, VReg obj, const Operand &prop); - void StoreOwnProperty(const ir::AstNode *node, VReg obj, const Operand &prop); + void StoreOwnProperty(const ir::AstNode *node, VReg obj, const Operand &prop, bool nameSetting = false); void DeleteObjProperty(const ir::AstNode *node, VReg obj, const Operand &prop); void LoadAccumulator(const ir::AstNode *node, VReg reg); void LoadGlobalVar(const ir::AstNode *node, const util::StringView &name); @@ -255,6 +255,7 @@ public: void Binary(const ir::AstNode *node, lexer::TokenType op, VReg lhs); void BranchIfUndefined(const ir::AstNode *node, class Label *target); + void BranchIfStrictNotUndefined(const ir::AstNode *node, class Label *target); void BranchIfNotUndefined(const ir::AstNode *node, class Label *target); void BranchIfHole(const ir::AstNode *node, class Label *target); void BranchIfTrue(const ir::AstNode *node, class Label *target); @@ -370,8 +371,8 @@ public: void StoreObjByIndex(const ir::AstNode *node, VReg obj, int64_t index); void StoreObjByValue(const ir::AstNode *node, VReg obj, VReg prop); - void StOwnByName(const ir::AstNode *node, VReg obj, const util::StringView &prop); - void StOwnByValue(const ir::AstNode *node, VReg obj, VReg prop); + void StOwnByName(const ir::AstNode *node, VReg obj, const util::StringView &prop, bool nameSetting = false); + void StOwnByValue(const ir::AstNode *node, VReg obj, VReg prop, bool nameSetting = false); void StOwnByIndex(const ir::AstNode *node, VReg obj, int64_t index); static Operand ToNamedPropertyKey(const ir::Expression *prop, bool isComputed); diff --git a/es2panda/ir/base/classDefinition.cpp b/es2panda/ir/base/classDefinition.cpp index 7eea3dab22..260910e252 100644 --- a/es2panda/ir/base/classDefinition.cpp +++ b/es2panda/ir/base/classDefinition.cpp @@ -120,6 +120,7 @@ int32_t ClassDefinition::CreateClassStaticProperties(compiler::PandaGen *pg, uti auto *buf = pg->NewLiteralBuffer(); compiler::LiteralBuffer staticBuf(pg->Allocator()); bool seenComputed = false; + uint32_t instancePropertyCount = 0; std::unordered_map propNameMap; std::unordered_map staticPropNameMap; @@ -131,12 +132,15 @@ int32_t ClassDefinition::CreateClassStaticProperties(compiler::PandaGen *pg, uti } const ir::MethodDefinition *prop = properties[i]->AsMethodDefinition(); - if (!util::Helpers::IsConstantPropertyKey(prop->Key(), prop->Computed()) || - (prop->Computed() && util::Helpers::IsSpecialPropertyKey(prop->Key()))) { + if (prop->Computed()) { seenComputed = true; continue; } + if (prop->IsAccessor()) { + break; + } + util::StringView name = util::Helpers::LiteralToPropName(prop->Key()); compiler::LiteralBuffer *literalBuf = prop->IsStatic() ? &staticBuf : buf; auto &nameMap = prop->IsStatic() ? staticPropNameMap : propNameMap; @@ -149,7 +153,8 @@ int32_t ClassDefinition::CreateClassStaticProperties(compiler::PandaGen *pg, uti } literalBuf->Add(pg->Allocator()->New(name)); - literalBuf->Add(nullptr); + literalBuf->Add(nullptr); // save for method internalname + literalBuf->Add(nullptr); // save for method affiliate } else { bufferPos = res.first->second; } @@ -162,12 +167,18 @@ int32_t ClassDefinition::CreateClassStaticProperties(compiler::PandaGen *pg, uti const util::StringView &internalName = func->Function()->Scope()->InternalName(); value = pg->Allocator()->New(LiteralTag::METHOD, internalName); + literalBuf->ResetLiteral(bufferPos + 1, value); + Literal *methodAffiliate = pg->Allocator()->New(LiteralTag::METHODAFFILIATE, + func->Function()->FormalParamsLength()); + literalBuf->ResetLiteral(bufferPos + 2, methodAffiliate); // bufferPos + 2 is saved for method affiliate compiled.Set(i); break; } + // TODO refactor this part later case ir::MethodDefinitionKind::GET: case ir::MethodDefinitionKind::SET: { value = pg->Allocator()->New(); + literalBuf->ResetLiteral(bufferPos + 1, value); break; } default: { @@ -175,17 +186,17 @@ int32_t ClassDefinition::CreateClassStaticProperties(compiler::PandaGen *pg, uti } } - literalBuf->ResetLiteral(bufferPos + 1, value); + if (!prop->IsStatic()) { + instancePropertyCount++; + } } - uint32_t litPairs = buf->Size() / 2; - /* Static items are stored at the end of the buffer */ buf->Insert(&staticBuf); /* The last literal item represents the offset of the first static property. The regular property literal count * is divided by 2 as key/value pairs count as one. */ - buf->Add(pg->Allocator()->New(litPairs)); + buf->Add(pg->Allocator()->New(instancePropertyCount)); return pg->AddLiteralBuffer(buf); } @@ -217,7 +228,7 @@ void ClassDefinition::CompileMissingProperties(compiler::PandaGen *pg, const uti const ir::FunctionExpression *func = prop->Value()->AsFunctionExpression(); func->Compile(pg); - pg->StoreOwnProperty(prop->Value()->Parent(), dest, key); + pg->StoreOwnProperty(prop->Value()->Parent(), dest, key, prop->Computed()); break; } case ir::MethodDefinitionKind::GET: @@ -269,6 +280,7 @@ void ClassDefinition::Compile(compiler::PandaGen *pg) const int32_t bufIdx = CreateClassStaticProperties(pg, compiled); pg->DefineClassWithBuffer(this, ctorId, bufIdx, lexenv, baseReg); + pg->StoreAccumulator(this, classReg); InitializeClassName(pg); diff --git a/es2panda/ir/base/methodDefinition.h b/es2panda/ir/base/methodDefinition.h index e304cd084e..1170e01693 100644 --- a/es2panda/ir/base/methodDefinition.h +++ b/es2panda/ir/base/methodDefinition.h @@ -80,6 +80,11 @@ public: return (modifiers_ & ModifierFlags::STATIC) != 0; } + bool IsAccessor() const + { + return (kind_ == MethodDefinitionKind::GET) || (kind_ == MethodDefinitionKind::SET); + } + bool IsOptional() const { return (modifiers_ & ModifierFlags::OPTIONAL) != 0; diff --git a/es2panda/ir/expressions/literal.cpp b/es2panda/ir/expressions/literal.cpp index 48cb9a94d4..4a021f470f 100644 --- a/es2panda/ir/expressions/literal.cpp +++ b/es2panda/ir/expressions/literal.cpp @@ -52,4 +52,10 @@ const util::StringView &Literal::GetMethod() const return AsTaggedLiteral()->Method(); } +uint16_t Literal::GetMethodAffiliate() const +{ + ASSERT(IsTaggedLiteral()); + return AsTaggedLiteral()->MethodAffiliate(); +} + } // namespace panda::es2panda::ir diff --git a/es2panda/ir/expressions/literal.h b/es2panda/ir/expressions/literal.h index ee6bc7af23..c38869152d 100644 --- a/es2panda/ir/expressions/literal.h +++ b/es2panda/ir/expressions/literal.h @@ -37,11 +37,12 @@ enum class LiteralTag { FLOAT, DOUBLE, STRING, - ACCESSOR, METHOD, GENERATOR_METHOD, + ACCESSOR, + METHODAFFILIATE, ASYNC_GENERATOR_METHOD, - NULL_VALUE, + NULL_VALUE = 255, }; class Literal : public Expression { @@ -58,6 +59,7 @@ public: double GetDouble() const; const util::StringView &GetString() const; const util::StringView &GetMethod() const; + uint16_t GetMethodAffiliate() const; protected: explicit Literal(AstNodeType type) : Expression(type) {} diff --git a/es2panda/ir/expressions/literals/taggedLiteral.h b/es2panda/ir/expressions/literals/taggedLiteral.h index 69a4b6486a..c8ecd27e70 100644 --- a/es2panda/ir/expressions/literals/taggedLiteral.h +++ b/es2panda/ir/expressions/literals/taggedLiteral.h @@ -37,6 +37,11 @@ public: { } + explicit TaggedLiteral(LiteralTag tag, uint16_t num) + : Literal(AstNodeType::TAGGED_LITERAL), num_(num), tag_(tag) + { + } + const util::StringView &Str() const { return str_; @@ -59,12 +64,19 @@ public: return str_; } + uint16_t MethodAffiliate() const + { + ASSERT(tag_ == LiteralTag::METHODAFFILIATE); + return num_; + } + void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; checker::Type *Check([[maybe_unused]] checker::Checker *checker) const override; private: + uint16_t num_ {}; util::StringView str_ {}; LiteralTag tag_ {LiteralTag::NULL_VALUE}; }; -- Gitee From 47e7cd4506216c275f0d15056710b6dc37633443 Mon Sep 17 00:00:00 2001 From: qiuyu Date: Sun, 24 Jul 2022 00:49:00 +0800 Subject: [PATCH 21/25] Enable bytecode optimizer by default Enable bytecode optimizer by default Disable log by default Issue: I5HYBL Signed-off-by: qiuyu Change-Id: I6f71a1d081bede6e1496e4329c555cf7468e346c --- test262/config.py | 2 +- ts2panda/src/cmdOptions.ts | 2 +- ts2panda/ts2abc/ts2abc.cpp | 12 +++++++----- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/test262/config.py b/test262/config.py index 4ea7d7cefe..f2a1d8836e 100755 --- a/test262/config.py +++ b/test262/config.py @@ -96,5 +96,5 @@ ARK_ARCH_LIST = [ ] DEFAULT_ARK_ARCH = ARK_ARCH_LIST[0] -DEFAULT_OPT_LEVEL = 0 +DEFAULT_OPT_LEVEL = 2 DEFAULT_ES2ABC_THREAD_COUNT = 0 diff --git a/ts2panda/src/cmdOptions.ts b/ts2panda/src/cmdOptions.ts index 980ec2c5d7..bd302d1ea3 100644 --- a/ts2panda/src/cmdOptions.ts +++ b/ts2panda/src/cmdOptions.ts @@ -34,7 +34,7 @@ const ts2pandaOptions = [ { name: 'timeout', alias: 't', type: Number, defaultValue: 0, description: "js to abc timeout threshold(unit: seconds)." }, { name: 'opt-log-level', type: String, defaultValue: "error", description: "specifie optimizer log level. Possible values: ['debug', 'info', 'error', 'fatal']" }, { - name: 'opt-level', type: Number, defaultValue: 0, description: "Optimization level. Possible values: [0, 1, 2]. Default: 0\n 0: no optimizations\n \ + name: 'opt-level', type: Number, defaultValue: 2, description: "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: other bytecode optimizations, unimplemented yet"}, { name: 'help', alias: 'h', type: Boolean, description: "Show usage guide." }, diff --git a/ts2panda/ts2abc/ts2abc.cpp b/ts2panda/ts2abc/ts2abc.cpp index 7226eea918..5f79472eaa 100644 --- a/ts2panda/ts2abc/ts2abc.cpp +++ b/ts2panda/ts2abc/ts2abc.cpp @@ -1316,11 +1316,13 @@ bool GenerateProgram([[maybe_unused]] const std::string &data, const std::string if (g_optLevel != static_cast(OptLevel::O_LEVEL0) || optLevel != static_cast(OptLevel::O_LEVEL0)) { optLogLevel = (optLogLevel != "error") ? optLogLevel : g_optLogLevel; - panda::Logger::ComponentMask mask; - mask.set(panda::Logger::Component::ASSEMBLER); - mask.set(panda::Logger::Component::BYTECODE_OPTIMIZER); - mask.set(panda::Logger::Component::COMPILER); - panda::Logger::InitializeStdLogging(panda::Logger::LevelFromString(optLogLevel), mask); + if (g_optLogLevel != "error") { + panda::Logger::ComponentMask mask; + mask.set(panda::Logger::Component::ASSEMBLER); + mask.set(panda::Logger::Component::BYTECODE_OPTIMIZER); + mask.set(panda::Logger::Component::COMPILER); + panda::Logger::InitializeStdLogging(panda::Logger::LevelFromString(optLogLevel), mask); + } bool emitDebugInfo = true; std::map stat; -- Gitee From 9dc2b3f8332729aac445e45c39b2d2623826f979 Mon Sep 17 00:00:00 2001 From: ctw-ian Date: Tue, 19 Jul 2022 22:01:18 +0800 Subject: [PATCH 22/25] Fix async and generator for es2abc Fix async and generator to meet with implementation of runtime Issue:I5IPC4 Signed-off-by: ctw-ian Change-Id: If4bba32935b92ce392979684a2f4683018ea9afb --- es2panda/compiler/base/iterators.cpp | 38 ++++++++++--- es2panda/compiler/core/pandagen.cpp | 57 +++++-------------- es2panda/compiler/core/pandagen.h | 13 ++--- .../function/asyncFunctionBuilder.cpp | 19 ++++++- .../compiler/function/asyncFunctionBuilder.h | 2 +- .../asyncGeneratorFunctionBuilder.cpp | 6 +- .../function/asyncGeneratorFunctionBuilder.h | 2 +- .../compiler/function/functionBuilder.cpp | 14 +++-- es2panda/compiler/function/functionBuilder.h | 2 +- .../function/generatorFunctionBuilder.cpp | 19 ++++--- .../function/generatorFunctionBuilder.h | 2 +- 11 files changed, 95 insertions(+), 79 deletions(-) diff --git a/es2panda/compiler/base/iterators.cpp b/es2panda/compiler/base/iterators.cpp index 8ba4d12a11..47d653b8ee 100644 --- a/es2panda/compiler/base/iterators.cpp +++ b/es2panda/compiler/base/iterators.cpp @@ -35,13 +35,11 @@ Iterator::Iterator(PandaGen *pg, const ir::AstNode *node, IteratorType type) pg_->StoreAccumulator(node, iterator_); pg_->LoadObjByName(node_, iterator_, "next"); pg_->StoreAccumulator(node_, method_); - - pg_->ThrowIfNotObject(node_); } void Iterator::GetMethod(util::StringView name) const { - pg_->GetMethod(node_, iterator_, name); + pg_->LoadObjByName(node_, iterator_, name); pg_->StoreAccumulator(node_, method_); } @@ -63,8 +61,8 @@ void Iterator::Next() const pg_->FuncBuilder()->Await(node_); } - pg_->ThrowIfNotObject(node_); pg_->StoreAccumulator(node_, nextResult_); + pg_->ThrowIfNotObject(node_, nextResult_); } void Iterator::Complete() const @@ -80,10 +78,34 @@ void Iterator::Value() const void Iterator::Close(bool abruptCompletion) const { if (type_ == IteratorType::SYNC) { - if (!abruptCompletion) { - pg_->LoadConst(node_, Constant::JS_HOLE); + RegScope rs(pg_); + VReg exception = pg_->AllocReg(); + VReg doneResult = pg_->AllocReg(); + VReg innerResult = pg_->AllocReg(); + Label *noReturn = pg_->AllocLabel(); + + if (abruptCompletion) { + pg_->StoreAccumulator(node_, exception); + } + + pg_->StoreConst(node_, doneResult, Constant::JS_TRUE); + Complete(); + pg_->Condition(node_, lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL, doneResult, noReturn); + + // close iterator + pg_->LoadObjByName(node_, iterator_, "return"); + pg_->StoreAccumulator(node_, method_); + pg_->LoadConst(node_, Constant::JS_UNDEFINED); + pg_->Condition(node_, lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL, method_, noReturn); + CallMethod(); + pg_->StoreAccumulator(node_, innerResult); + pg_->ThrowIfNotObject(node_, innerResult); + + pg_->SetLabel(node_, noReturn); + if (abruptCompletion) { + pg_->LoadAccumulator(node_, exception); + pg_->EmitThrow(node_); } - pg_->CloseIterator(node_, iterator_); return; } @@ -159,7 +181,7 @@ void Iterator::Close(bool abruptCompletion) const // 8. If Type(innerResult.[[Value]]) is not Object, throw a TypeError exception. pg_->LoadAccumulator(node_, innerResult); - pg_->ThrowIfNotObject(node_); + pg_->ThrowIfNotObject(node_, innerResult); } DestructuringIterator::DestructuringIterator(PandaGen *pg, const ir::AstNode *node) diff --git a/es2panda/compiler/core/pandagen.cpp b/es2panda/compiler/core/pandagen.cpp index 17375d9a93..21ca7cf585 100644 --- a/es2panda/compiler/core/pandagen.cpp +++ b/es2panda/compiler/core/pandagen.cpp @@ -983,7 +983,9 @@ void PandaGen::LoadHomeObject(const ir::AstNode *node) void PandaGen::DefineFunction(const ir::AstNode *node, const ir::ScriptFunction *realNode, const util::StringView &name) { auto formalParamCnt = realNode->FormalParamsLength(); - if (realNode->IsAsync()) { + if (realNode->IsMethod()) { + ra_.Emit(node, name, static_cast(formalParamCnt), LexEnv()); + } else if (realNode->IsAsync()) { if (realNode->IsGenerator()) { // TODO(): async generator } else { @@ -994,8 +996,6 @@ void PandaGen::DefineFunction(const ir::AstNode *node, const ir::ScriptFunction } else if (realNode->IsArrow()) { LoadHomeObject(node); ra_.Emit(node, name, static_cast(formalParamCnt), LexEnv()); - } else if (realNode->IsMethod()) { - ra_.Emit(node, name, static_cast(formalParamCnt), LexEnv()); } else { ra_.Emit(node, name, static_cast(formalParamCnt), LexEnv()); } @@ -1040,15 +1040,6 @@ void PandaGen::ToNumber(const ir::AstNode *node, VReg arg) ra_.Emit(node, arg); } -void PandaGen::GetMethod(const ir::AstNode *node, VReg obj, const util::StringView &name) -{ - /** - * TODO - * ra_.Emit(node, name, obj); - * strings_.insert(name); - */ -} - void PandaGen::CreateGeneratorObj(const ir::AstNode *node, VReg funcObj) { ra_.Emit(node, funcObj); @@ -1062,20 +1053,14 @@ void PandaGen::CreateAsyncGeneratorObj(const ir::AstNode *node, VReg funcObj) */ } -void PandaGen::CreateIterResultObject(const ir::AstNode *node, bool done) +void PandaGen::CreateIterResultObject(const ir::AstNode *node, VReg value, VReg done) { - /* - * TODO: create iter result - * ra_.Emit(node, static_cast(done)); - */ + ra_.Emit(node, value, done); } -void PandaGen::SuspendGenerator(const ir::AstNode *node, VReg genObj) +void PandaGen::SuspendGenerator(const ir::AstNode *node, VReg genObj, VReg iterResult) { - /* - * TODO: suspend generator - * ra_.Emit(node, genObj); - */ + ra_.Emit(node, genObj, iterResult); } void PandaGen::SuspendAsyncGenerator(const ir::AstNode *node, VReg asyncGenObj) @@ -1117,28 +1102,19 @@ void PandaGen::AsyncFunctionEnter(const ir::AstNode *node) sa_.Emit(node); } -void PandaGen::AsyncFunctionAwait(const ir::AstNode *node, VReg asyncFuncObj) +void PandaGen::AsyncFunctionAwait(const ir::AstNode *node, VReg asyncFuncObj, VReg retVal) { - /* - * TODO: async function await - * ra_.Emit(node, asyncFuncObj); - */ + ra_.Emit(node, asyncFuncObj, retVal); } -void PandaGen::AsyncFunctionResolve(const ir::AstNode *node, VReg asyncFuncObj) +void PandaGen::AsyncFunctionResolve(const ir::AstNode *node, VReg asyncFuncObj, VReg value, VReg canSuspend) { - /* - * TODO: async function resolve - * ra_.Emit(node, asyncFuncObj); - */ + ra_.Emit(node, asyncFuncObj, value, canSuspend); } -void PandaGen::AsyncFunctionReject(const ir::AstNode *node, VReg asyncFuncObj) +void PandaGen::AsyncFunctionReject(const ir::AstNode *node, VReg asyncFuncObj, VReg value, VReg canSuspend) { - /* - * TODO: async function reject - * ra_.Emit(node, asyncFuncObj); - */ + ra_.Emit(node, asyncFuncObj, value, canSuspend); } void PandaGen::AsyncGeneratorResolve(const ir::AstNode *node, VReg asyncGenObj) @@ -1324,12 +1300,9 @@ void PandaGen::StoreArraySpread(const ir::AstNode *node, VReg array, VReg index) ra_.Emit(node, array, index); } -void PandaGen::ThrowIfNotObject(const ir::AstNode *node) +void PandaGen::ThrowIfNotObject(const ir::AstNode *node, VReg obj) { - // TODO: implement this method correctly - RegScope rs(this); - VReg value = AllocReg(); - ra_.Emit(node, value); + ra_.Emit(node, obj); } void PandaGen::ThrowThrowNotExist(const ir::AstNode *node) diff --git a/es2panda/compiler/core/pandagen.h b/es2panda/compiler/core/pandagen.h index 67582f92e3..6086561b14 100644 --- a/es2panda/compiler/core/pandagen.h +++ b/es2panda/compiler/core/pandagen.h @@ -294,16 +294,15 @@ public: void GetResumeMode(const ir::AstNode *node, VReg genObj); void AsyncFunctionEnter(const ir::AstNode *node); - void AsyncFunctionAwait(const ir::AstNode *node, VReg asyncFuncObj); - void AsyncFunctionResolve(const ir::AstNode *node, VReg asyncFuncObj); - void AsyncFunctionReject(const ir::AstNode *node, VReg asyncFuncObj); + void AsyncFunctionAwait(const ir::AstNode *node, VReg asyncFuncObj, VReg retVal); + void AsyncFunctionResolve(const ir::AstNode *node, VReg asyncFuncObj, VReg value, VReg canSuspend); + void AsyncFunctionReject(const ir::AstNode *node, VReg asyncFuncObj, VReg value, VReg canSuspend); - void GetMethod(const ir::AstNode *node, VReg obj, const util::StringView &name); void GeneratorYield(const ir::AstNode *node, VReg genObj); void GeneratorComplete(const ir::AstNode *node, VReg genObj); void CreateAsyncGeneratorObj(const ir::AstNode *node, VReg funcObj); - void CreateIterResultObject(const ir::AstNode *node, bool done); - void SuspendGenerator(const ir::AstNode *node, VReg genObj); + void CreateIterResultObject(const ir::AstNode *node, VReg value, VReg done); + void SuspendGenerator(const ir::AstNode *node, VReg genObj, VReg iterResult); void SuspendAsyncGenerator(const ir::AstNode *node, VReg asyncGenObj); void AsyncGeneratorResolve(const ir::AstNode *node, VReg asyncGenObj); @@ -326,7 +325,7 @@ public: void CreateArrayWithBuffer(const ir::AstNode *node, uint32_t idx); void StoreArraySpread(const ir::AstNode *node, VReg array, VReg index); - void ThrowIfNotObject(const ir::AstNode *node); + void ThrowIfNotObject(const ir::AstNode *node, VReg obj); void ThrowThrowNotExist(const ir::AstNode *node); void GetIterator(const ir::AstNode *node); void GetAsyncIterator(const ir::AstNode *node); diff --git a/es2panda/compiler/function/asyncFunctionBuilder.cpp b/es2panda/compiler/function/asyncFunctionBuilder.cpp index acbbc790ab..170db32073 100644 --- a/es2panda/compiler/function/asyncFunctionBuilder.cpp +++ b/es2panda/compiler/function/asyncFunctionBuilder.cpp @@ -23,7 +23,15 @@ namespace panda::es2panda::compiler { void AsyncFunctionBuilder::DirectReturn(const ir::AstNode *node) const { - pg_->AsyncFunctionResolve(node, funcObj_); + RegScope rs(pg_); + VReg retVal = pg_->AllocReg(); + VReg canSuspend = pg_->AllocReg(); + + pg_->StoreAccumulator(node, retVal); + pg_->LoadConst(node, Constant::JS_TRUE); + pg_->StoreAccumulator(node, canSuspend); + pg_->AsyncFunctionResolve(node, funcObj_, retVal, canSuspend); + pg_->LoadAccumulator(node, retVal); pg_->EmitReturn(node); } @@ -33,7 +41,7 @@ void AsyncFunctionBuilder::ImplicitReturn(const ir::AstNode *node) const DirectReturn(node); } -void AsyncFunctionBuilder::Prepare(const ir::ScriptFunction *node) const +void AsyncFunctionBuilder::Prepare(const ir::ScriptFunction *node) { pg_->AsyncFunctionEnter(node); pg_->StoreAccumulator(node, funcObj_); @@ -42,11 +50,16 @@ void AsyncFunctionBuilder::Prepare(const ir::ScriptFunction *node) const void AsyncFunctionBuilder::CleanUp(const ir::ScriptFunction *node) const { + RegScope rs(pg_); const auto &labelSet = catchTable_->LabelSet(); pg_->SetLabel(node, labelSet.TryEnd()); pg_->SetLabel(node, labelSet.CatchBegin()); - pg_->AsyncFunctionReject(node, funcObj_); + VReg exception = pg_->AllocReg(); + VReg canSuspend = pg_->AllocReg(); + pg_->StoreAccumulator(node, exception); + pg_->StoreConst(node, canSuspend, Constant::JS_TRUE); + pg_->AsyncFunctionReject(node, funcObj_, exception, canSuspend); pg_->EmitReturn(node); pg_->SetLabel(node, labelSet.CatchEnd()); } diff --git a/es2panda/compiler/function/asyncFunctionBuilder.h b/es2panda/compiler/function/asyncFunctionBuilder.h index bd7f38a814..68bdd99433 100644 --- a/es2panda/compiler/function/asyncFunctionBuilder.h +++ b/es2panda/compiler/function/asyncFunctionBuilder.h @@ -30,7 +30,7 @@ public: NO_COPY_SEMANTIC(AsyncFunctionBuilder); NO_MOVE_SEMANTIC(AsyncFunctionBuilder); - void Prepare(const ir::ScriptFunction *node) const override; + void Prepare(const ir::ScriptFunction *node) override; void CleanUp(const ir::ScriptFunction *node) const override; void DirectReturn(const ir::AstNode *node) const override; diff --git a/es2panda/compiler/function/asyncGeneratorFunctionBuilder.cpp b/es2panda/compiler/function/asyncGeneratorFunctionBuilder.cpp index c4360cd87a..a74eea46df 100644 --- a/es2panda/compiler/function/asyncGeneratorFunctionBuilder.cpp +++ b/es2panda/compiler/function/asyncGeneratorFunctionBuilder.cpp @@ -20,13 +20,13 @@ #include namespace panda::es2panda::compiler { -void AsyncGeneratorFunctionBuilder::Prepare(const ir::ScriptFunction *node) const +void AsyncGeneratorFunctionBuilder::Prepare(const ir::ScriptFunction *node) { VReg callee = FunctionReg(node); pg_->CreateAsyncGeneratorObj(node, callee); pg_->StoreAccumulator(node, funcObj_); - pg_->SuspendGenerator(node, funcObj_); + // pg_->SuspendGenerator(node, funcObj_); TODO implement this part correctly while implementing async generator pg_->SetLabel(node, catchTable_->LabelSet().TryBegin()); } @@ -72,7 +72,7 @@ void AsyncGeneratorFunctionBuilder::Yield(const ir::AstNode *node) pg_->Condition(node, lexer::TokenType::PUNCTUATOR_EQUAL, completionType, notReturnCompletion); // 27.6.3.8.8.b. Let awaited be Await(resumptionValue.[[Value]]). pg_->LoadAccumulator(node, completionValue); - pg_->AsyncFunctionAwait(node, funcObj_); + pg_->AsyncFunctionAwait(node, funcObj_, completionValue); SuspendResumeExecution(node, completionType, completionValue); // 27.6.3.8.8.c. If awaited.[[Type]] is throw, return Completion(awaited). diff --git a/es2panda/compiler/function/asyncGeneratorFunctionBuilder.h b/es2panda/compiler/function/asyncGeneratorFunctionBuilder.h index f492da49d1..8ae591a79c 100644 --- a/es2panda/compiler/function/asyncGeneratorFunctionBuilder.h +++ b/es2panda/compiler/function/asyncGeneratorFunctionBuilder.h @@ -30,7 +30,7 @@ public: NO_COPY_SEMANTIC(AsyncGeneratorFunctionBuilder); NO_MOVE_SEMANTIC(AsyncGeneratorFunctionBuilder); - void Prepare(const ir::ScriptFunction *node) const override; + void Prepare(const ir::ScriptFunction *node) override; void CleanUp(const ir::ScriptFunction *node) const override; void DirectReturn(const ir::AstNode *node) const override; diff --git a/es2panda/compiler/function/functionBuilder.cpp b/es2panda/compiler/function/functionBuilder.cpp index eaba22a71a..47184ca1f5 100644 --- a/es2panda/compiler/function/functionBuilder.cpp +++ b/es2panda/compiler/function/functionBuilder.cpp @@ -68,7 +68,10 @@ void FunctionBuilder::SuspendResumeExecution(const ir::AstNode *node, VReg compl ASSERT(BuilderKind() == BuilderType::ASYNC || BuilderKind() == BuilderType::ASYNC_GENERATOR || BuilderKind() == BuilderType::GENERATOR); - pg_->SuspendGenerator(node, funcObj_); + RegScope rs(pg_); + VReg iterResult = pg_->AllocReg(); + pg_->StoreAccumulator(node, iterResult); + pg_->SuspendGenerator(node, funcObj_, iterResult); resumeGenerator(node, completionType, completionValue); } @@ -103,8 +106,10 @@ void FunctionBuilder::Await(const ir::AstNode *node) RegScope rs(pg_); VReg completionType = pg_->AllocReg(); VReg completionValue = pg_->AllocReg(); + VReg retVal = pg_->AllocReg(); - pg_->AsyncFunctionAwait(node, funcObj_); + pg_->StoreAccumulator(node, retVal); + pg_->AsyncFunctionAwait(node, funcObj_, retVal); SuspendResumeExecution(node, completionType, completionValue); HandleCompletion(node, completionType, completionValue); @@ -239,7 +244,7 @@ void FunctionBuilder::YieldStar(const ir::AstNode *node) // ii. If Type(innerResult) is not Object, throw a TypeError exception. // 4. If Type(innerResult) is not Object, throw a TypeError exception. // vi. If Type(innerReturnResult) is not Object, throw a TypeError exception. - pg_->ThrowIfNotObject(node); + pg_->ThrowIfNotObject(node, receivedValue); // iv. Let done be ? IteratorComplete(innerResult). // v. Let done be ? IteratorComplete(innerResult). @@ -264,8 +269,7 @@ void FunctionBuilder::YieldStar(const ir::AstNode *node) pg_->Condition(node, lexer::TokenType::PUNCTUATOR_EQUAL, receivedType, loopStart); // b. Let awaited be Await(resumptionValue.[[Value]]). - pg_->LoadAccumulator(node, receivedValue); - pg_->AsyncFunctionAwait(node, funcObj_); + pg_->AsyncFunctionAwait(node, funcObj_, receivedValue); SuspendResumeExecution(node, receivedType, receivedValue); // c. If awaited.[[Type]] is throw, return Completion(awaited). diff --git a/es2panda/compiler/function/functionBuilder.h b/es2panda/compiler/function/functionBuilder.h index 4147c49577..63abf6f78e 100644 --- a/es2panda/compiler/function/functionBuilder.h +++ b/es2panda/compiler/function/functionBuilder.h @@ -49,7 +49,7 @@ public: NO_COPY_SEMANTIC(FunctionBuilder); NO_MOVE_SEMANTIC(FunctionBuilder); - virtual void Prepare([[maybe_unused]] const ir::ScriptFunction *node) const {}; + virtual void Prepare([[maybe_unused]] const ir::ScriptFunction *node) {}; virtual void CleanUp([[maybe_unused]] const ir::ScriptFunction *node) const {}; virtual void DirectReturn(const ir::AstNode *node) const; diff --git a/es2panda/compiler/function/generatorFunctionBuilder.cpp b/es2panda/compiler/function/generatorFunctionBuilder.cpp index a4d71b3fd2..e302dfe984 100644 --- a/es2panda/compiler/function/generatorFunctionBuilder.cpp +++ b/es2panda/compiler/function/generatorFunctionBuilder.cpp @@ -21,14 +21,17 @@ namespace panda::es2panda::compiler { -void GeneratorFunctionBuilder::Prepare(const ir::ScriptFunction *node) const +void GeneratorFunctionBuilder::Prepare(const ir::ScriptFunction *node) { VReg callee = FunctionReg(node); + VReg completionType = pg_->AllocReg(); + VReg completionValue = pg_->AllocReg(); pg_->CreateGeneratorObj(node, callee); pg_->StoreAccumulator(node, funcObj_); - pg_->SuspendGenerator(node, funcObj_); - pg_->SetLabel(node, catchTable_->LabelSet().TryBegin()); + pg_->LoadConst(node, Constant::JS_UNDEFINED); + SuspendResumeExecution(node, completionType, completionValue); + HandleCompletion(node, completionType, completionValue); } void GeneratorFunctionBuilder::CleanUp(const ir::ScriptFunction *node) const @@ -44,8 +47,6 @@ void GeneratorFunctionBuilder::CleanUp(const ir::ScriptFunction *node) const void GeneratorFunctionBuilder::DirectReturn(const ir::AstNode *node) const { - pg_->GeneratorComplete(node, funcObj_); - pg_->CreateIterResultObject(node, true); pg_->EmitReturn(node); } @@ -58,11 +59,15 @@ void GeneratorFunctionBuilder::ImplicitReturn(const ir::AstNode *node) const void GeneratorFunctionBuilder::Yield(const ir::AstNode *node) { RegScope rs(pg_); + VReg value = pg_->AllocReg(); + VReg done = pg_->AllocReg(); VReg completionType = pg_->AllocReg(); VReg completionValue = pg_->AllocReg(); - pg_->CreateIterResultObject(node, false); - pg_->GeneratorYield(node, funcObj_); + pg_->StoreAccumulator(node, value); + pg_->LoadConst(node, Constant::JS_FALSE); + pg_->StoreAccumulator(node, done); + pg_->CreateIterResultObject(node, value, done); SuspendResumeExecution(node, completionType, completionValue); HandleCompletion(node, completionType, completionValue); diff --git a/es2panda/compiler/function/generatorFunctionBuilder.h b/es2panda/compiler/function/generatorFunctionBuilder.h index a1a1229565..6b3b96acb3 100644 --- a/es2panda/compiler/function/generatorFunctionBuilder.h +++ b/es2panda/compiler/function/generatorFunctionBuilder.h @@ -44,7 +44,7 @@ public: NO_COPY_SEMANTIC(GeneratorFunctionBuilder); NO_MOVE_SEMANTIC(GeneratorFunctionBuilder); - void Prepare(const ir::ScriptFunction *node) const override; + void Prepare(const ir::ScriptFunction *node) override; void CleanUp(const ir::ScriptFunction *node) const override; void DirectReturn(const ir::AstNode *node) const override; -- Gitee From 6ca00a97988edf8940fd660b26770c9198975ffb Mon Sep 17 00:00:00 2001 From: ctw-ian Date: Sat, 23 Jul 2022 18:14:57 +0800 Subject: [PATCH 23/25] Support column number on es2abc Add column number to debuginfo on es2abc Issue: I5IKMB Signed-off-by: ctw-ian Change-Id: I0dc4d12511c8cc34408b495ef267fa5ba2233d1b --- es2panda/compiler/core/emitter.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/es2panda/compiler/core/emitter.cpp b/es2panda/compiler/core/emitter.cpp index 94129c5446..d807dfc245 100644 --- a/es2panda/compiler/core/emitter.cpp +++ b/es2panda/compiler/core/emitter.cpp @@ -193,7 +193,7 @@ static size_t GetIRNodeWholeLength(const IRNode *node) return len; } -static std::string WholeLine(const util::StringView &source, lexer::SourceRange range) +[[maybe_unused]] static std::string WholeLine(const util::StringView &source, lexer::SourceRange range) { return source.Substr(range.start.index, range.end.index).EscapeSymbol(); } @@ -211,7 +211,7 @@ void FunctionEmitter::GenInstructionDebugInfo(const IRNode *ins, panda::pandasm: } } - pandaIns->ins_debug.line_number = astNode->Range().start.line + 1; + pandaIns->ins_debug.line_number = astNode->Range().start.line; if (pg_->IsDebug()) { size_t insLen = GetIRNodeWholeLength(ins); @@ -221,7 +221,8 @@ void FunctionEmitter::GenInstructionDebugInfo(const IRNode *ins, panda::pandasm: } offset_ += insLen; - pandaIns->ins_debug.whole_line = WholeLine(SourceCode(), astNode->Range()); + + pandaIns->ins_debug.column_number = astNode->Range().start.index; } } -- Gitee From 3112a975e1a4da0f9252a34eaafd68c0bf1af0cd Mon Sep 17 00:00:00 2001 From: ctw-ian Date: Tue, 19 Jul 2022 20:13:10 +0800 Subject: [PATCH 24/25] Fix several functions of es2abc Fix several functions under guidance of test262 and hap compilation Issue:I5IK2O Signed-off-by: ctw-ian Change-Id: I69ff2de52ec2a20eb837f743b400c96f4236d033 --- es2panda/binder/scope.cpp | 31 +++++++++++++++++++++++++++++ es2panda/binder/scope.h | 13 ++++++++++++ es2panda/compiler/base/hoisting.cpp | 5 +++++ es2panda/compiler/core/envScope.cpp | 17 +++++++++++++++- es2panda/compiler/core/pandagen.cpp | 20 ++++++++++++------- es2panda/compiler/core/pandagen.h | 1 + 6 files changed, 79 insertions(+), 8 deletions(-) diff --git a/es2panda/binder/scope.cpp b/es2panda/binder/scope.cpp index e044f66c46..90a0c64ceb 100644 --- a/es2panda/binder/scope.cpp +++ b/es2panda/binder/scope.cpp @@ -49,6 +49,20 @@ VariableScope *Scope::EnclosingVariableScope() return nullptr; } +FunctionScope *Scope::EnclosingFunctionVariableScope() +{ + Scope *iter = this; + while (iter) { + if (iter->IsFunctionVariableScope()) { + return iter->AsFunctionVariableScope(); + } + + iter = iter->Parent(); + } + + return nullptr; +} + Variable *Scope::FindLocal(const util::StringView &name, ResolveBindingOptions options) const { if (options & ResolveBindingOptions::INTERFACES) { @@ -78,6 +92,23 @@ ScopeFindResult Scope::Find(const util::StringView &name, ResolveBindingOptions uint32_t lexLevel = 0; const auto *iter = this; + if (iter->IsFunctionParamScope()) { + Variable *v = iter->FindLocal(name, options); + + if (v != nullptr) { + return {name, const_cast(iter), level, lexLevel, v}; + } + + level++; + auto *funcVariableScope = iter->AsFunctionParamScope()->GetFunctionScope(); + + if (funcVariableScope->NeedLexEnv()) { + lexLevel++; + } + + iter = iter->Parent(); + } + while (iter != nullptr) { Variable *v = iter->FindLocal(name, options); diff --git a/es2panda/binder/scope.h b/es2panda/binder/scope.h index 9621858f36..0dfda446f9 100644 --- a/es2panda/binder/scope.h +++ b/es2panda/binder/scope.h @@ -121,6 +121,8 @@ public: VariableScope *EnclosingVariableScope(); + FunctionScope *EnclosingFunctionVariableScope(); + const ArenaVector &Decls() const { return decls_; @@ -314,6 +316,17 @@ public: return params_; } + bool HasParam(util::StringView name) const + { + for (auto *param : params_) { + if (param->Name() == name) { + return true; + } + } + + return false; + } + std::tuple AddParamDecl(ArenaAllocator *allocator, const ir::AstNode *param); protected: diff --git a/es2panda/compiler/base/hoisting.cpp b/es2panda/compiler/base/hoisting.cpp index 07621e8d63..815bf147a8 100644 --- a/es2panda/compiler/base/hoisting.cpp +++ b/es2panda/compiler/base/hoisting.cpp @@ -31,6 +31,11 @@ static void HoistVar(PandaGen *pg, binder::Variable *var, const binder::VarDecl return; } + auto *funcScope = scope->EnclosingFunctionVariableScope(); + if (funcScope->ParamScope()->HasParam(decl->Name())) { + return; + } + binder::ScopeFindResult result(decl->Name(), scope, 0, var); pg->LoadConst(decl->Node(), Constant::JS_UNDEFINED); diff --git a/es2panda/compiler/core/envScope.cpp b/es2panda/compiler/core/envScope.cpp index 6e2fa13c78..93fa239666 100644 --- a/es2panda/compiler/core/envScope.cpp +++ b/es2panda/compiler/core/envScope.cpp @@ -77,8 +77,23 @@ void LoopEnvScope::CopyPetIterationCtx() return; } - pg_->CopyLexEnv(scope_->Node()); + auto num = scope_->LexicalSlots(); + RegScope rs(pg_); + std::vector lexicals; + lexicals.reserve(num); + for (uint32_t i = 0; i < num; i++) { + VReg lexical = pg_->AllocReg(); + pg_->LoadLexicalVar(scope_->Node(), 0, i); + pg_->StoreAccumulator(scope_->Node(), lexical); + lexicals.push_back(lexical); + } + pg_->PopLexEnv(scope_->Node()); + pg_->NewLexEnv(scope_->Node(), num); pg_->StoreAccumulator(scope_->Node(), lexEnv_); + + for (uint32_t i = 0; i < num; i++) { + pg_->StoreLexicalVar(scope_->Node(), 0, i, lexicals[i]); + } } } // namespace panda::es2panda::compiler diff --git a/es2panda/compiler/core/pandagen.cpp b/es2panda/compiler/core/pandagen.cpp index 17375d9a93..97e7983ee3 100644 --- a/es2panda/compiler/core/pandagen.cpp +++ b/es2panda/compiler/core/pandagen.cpp @@ -164,8 +164,7 @@ void PandaGen::CopyFunctionArguments(const ir::AstNode *node) for (const auto *param : topScope_->ParamScope()->Params()) { if (param->LexicalBound()) { - LoadAccumulator(node, targetReg++); - StoreLexicalVar(node, 0, param->LexIdx()); + StoreLexicalVar(node, 0, param->LexIdx(), targetReg++); } else { ra_.Emit(node, param->Vreg(), targetReg++); } @@ -1353,11 +1352,13 @@ void PandaGen::GetAsyncIterator(const ir::AstNode *node) void PandaGen::CreateObjectWithExcludedKeys(const ir::AstNode *node, VReg obj, VReg argStart, size_t argCount) { ASSERT(argStart == obj + 1); - if (argCount == 0) { // Do not emit undefined register - argStart = obj; + if (argCount == 0) { + LoadConst(node, Constant::JS_UNDEFINED); + StoreAccumulator(node, argStart); } - rra_.Emit(node, argStart, argCount, static_cast(argCount), obj, + size_t argRegCnt = (argCount == 0 ? argCount : argCount - 1); + rra_.Emit(node, argStart, argCount, static_cast(argRegCnt), obj, argStart); } @@ -1482,13 +1483,17 @@ void PandaGen::LoadLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t void PandaGen::StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot) { - // TODO: need to reconsider this part RegScope rs(this); VReg value = AllocReg(); StoreAccumulator(node, value); ra_.Emit(node, level, slot, value); } +void PandaGen::StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot, VReg value) +{ + ra_.Emit(node, level, slot, value); +} + void PandaGen::ThrowIfSuperNotCorrectCall(const ir::AstNode *node, int64_t num) { sa_.Emit(node, num); @@ -1503,6 +1508,7 @@ void PandaGen::ThrowUndefinedIfHole(const ir::AstNode *node, const util::StringV VReg nameReg = AllocReg(); StoreAccumulator(node, nameReg); ra_.Emit(node, holeReg, nameReg); + LoadAccumulator(node, holeReg); strings_.insert(name); } @@ -1524,7 +1530,7 @@ void PandaGen::PopLexEnv(const ir::AstNode *node) void PandaGen::CopyLexEnv(const ir::AstNode *node) { /* - * TODO: copy lexenv + * TODO: add copy lexenv to optimize the loop env creation * sa_.Emit(node); */ } diff --git a/es2panda/compiler/core/pandagen.h b/es2panda/compiler/core/pandagen.h index 67582f92e3..2236ffa5ca 100644 --- a/es2panda/compiler/core/pandagen.h +++ b/es2panda/compiler/core/pandagen.h @@ -355,6 +355,7 @@ public: void NewLexEnv(const ir::AstNode *node, uint32_t num); void LoadLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot); void StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot); + void StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot, VReg value); void ThrowIfSuperNotCorrectCall(const ir::AstNode *node, int64_t num); void ThrowUndefinedIfHole(const ir::AstNode *node, const util::StringView &name); -- Gitee From cef051b2144f6d3a37fb9a6957e7811009f540db Mon Sep 17 00:00:00 2001 From: jiangkaiwen Date: Tue, 26 Jul 2022 11:30:34 +0800 Subject: [PATCH 25/25] Fix codecheck warnings 1. 'subprocess.run' should be used instead of 'os.system' 2. string concatenation with '+' is not recommended Issue: I5IWDG Signed-off-by: jiangkaiwen Change-Id: I59af5bbb261c6cda35c7c9f4503fa8b75c635a7a --- test262/run_sunspider.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test262/run_sunspider.py b/test262/run_sunspider.py index 5015f3b6cb..f2802d8e9c 100755 --- a/test262/run_sunspider.py +++ b/test262/run_sunspider.py @@ -152,7 +152,7 @@ def exec_command(cmd_args, timeout=DEFAULT_TIMEOUT): def print_command(cmd_args): sys.stderr.write("\n") for arg in cmd_args: - sys.stderr.write(arg + " ") + sys.stderr.write("%s%s"%(arg, " ")) sys.stderr.write("\n") def run_command(cmd_args): @@ -160,7 +160,7 @@ def run_command(cmd_args): cmd = f"timeout {timeout} " for arg in cmd_args: cmd += f"{arg} " - return os.system(cmd) + return subprocess.run(cmd) class ArkProgram(): def __init__(self, args): @@ -237,7 +237,7 @@ class ArkProgram(): cmd_args.insert(mod_opt_index, "--module") self.module = True if self.ark_aot: - os.system(f'''sed -i 's/;$262.destroy();/\/\/;$262.destroy();/g' {js_file}''') + subprocess.run(f'''sed -i 's/;$262.destroy();/\/\/;$262.destroy();/g' {js_file}''') if self.module: js_dir = os.path.dirname(js_file) for line in fileinput.input(js_file): @@ -313,7 +313,7 @@ class ArkProgram(): retcode = run_command(cmd_args) if retcode: - os.system(f'cp {self.js_file} {BASE_OUT_DIR}/../') + subprocess.run(f'cp {self.js_file} {BASE_OUT_DIR}/../') print_command(cmd_args) return retcode -- Gitee