diff --git a/ecmascript/compiler/BUILD.gn b/ecmascript/compiler/BUILD.gn index af841f72f9bd3ffe2a614193a9d6acb0434267b6..e598fadba79f5abeadc7da29c3d00794c905d655 100644 --- a/ecmascript/compiler/BUILD.gn +++ b/ecmascript/compiler/BUILD.gn @@ -160,6 +160,7 @@ libark_jsoptimizer_sources = [ "operations_stub_builder.cpp", "pass_manager.cpp", "post_schedule.cpp", + "precompile_checker.cpp", "profiler_stub_builder.cpp", "range_analysis.cpp", "range_guard.cpp", diff --git a/ecmascript/compiler/pass.h b/ecmascript/compiler/pass.h index 868ce8a3fdc5099ce7829490ac06659b8a388903..78b66a99ab808a7e85f9d1b31ae5973b2dd7e58c 100644 --- a/ecmascript/compiler/pass.h +++ b/ecmascript/compiler/pass.h @@ -41,6 +41,7 @@ #include "ecmascript/compiler/ntype_hcr_lowering.h" #include "ecmascript/compiler/number_speculative_runner.h" #include "ecmascript/compiler/post_schedule.h" +#include "ecmascript/compiler/precompile_checker.h" #include "ecmascript/compiler/scheduler.h" #include "ecmascript/compiler/string_builder_optimizer.h" #include "ecmascript/compiler/slowpath_lowering.h" @@ -276,6 +277,21 @@ private: T1* data_; }; +class PreCompileCheckPass { +public: + bool Run(PassData* data) + { + TimeScope timescope("PreCompileCheckPass", data->GetMethodName(), data->GetMethodOffset(), data->GetLog()); + bool enableLog = data->GetLog()->GetEnableMethodLog() && data->GetLog()->OutputType(); + PreCompileChecker preCompileChecker(data, data->GetCircuit(), data->GetMethodName(), enableLog); + if (!preCompileChecker.Run()) { + data->AbortCompilation(); + return false; + } + return true; + } +}; + class PGOTypeInferPass { public: bool Run(PassData* data) diff --git a/ecmascript/compiler/pass_manager.cpp b/ecmascript/compiler/pass_manager.cpp index 3455126b9459a6f02285c9b38bb741d2466f3268..dbc0b7c9ca06dc46c8249b920066cb71588764fc 100644 --- a/ecmascript/compiler/pass_manager.cpp +++ b/ecmascript/compiler/pass_manager.cpp @@ -282,8 +282,7 @@ bool PassManager::Compile(JSPandaFile *jsPandaFile, const std::string &fileName, compilationEnv_->GetNativeAreaAllocator(), decoder, passOptions_, optBCRange_); PassRunner pipeline(&data); - if (data.GetMethodLiteral()->HasDebuggerStmt()) { - data.AbortCompilation(); + if (!pipeline.RunPass()) { return; } pipeline.RunPass(); diff --git a/ecmascript/compiler/precompile_checker.cpp b/ecmascript/compiler/precompile_checker.cpp new file mode 100644 index 0000000000000000000000000000000000000000..934baa0ae8bfb007daaf276c6c43b0885c2d72de --- /dev/null +++ b/ecmascript/compiler/precompile_checker.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "ecmascript/compiler/pass.h" +#include "ecmascript/compiler/precompile_checker.h" + +namespace panda::ecmascript::kungfu { + +bool PreCompileChecker::Run() +{ + if (!HasReturnCheck()) { + PrintAbortInfo("HasReturnCheck"); + return false; + } + if (HasDebuggerStmt()) { + PrintAbortInfo("HasDebuggerStmt"); + return false; + } + return true; +} + +bool PreCompileChecker::HasReturnCheck() const +{ + std::vector returnList; + acc_.GetReturnOuts(returnList); + return returnList.size() != 0; +} + +bool PreCompileChecker::HasDebuggerStmt() const +{ + return data_->GetMethodLiteral()->HasDebuggerStmt(); +} + +void PreCompileChecker::PrintAbortInfo(const std::string& checkName) const +{ + if (enableLog_) { + LOG_COMPILER(INFO) << checkName << " check failed! Abort compiling method " + << methodName_; + } +} + +} // namespace panda::ecmascript::kungfu \ No newline at end of file diff --git a/ecmascript/compiler/precompile_checker.h b/ecmascript/compiler/precompile_checker.h new file mode 100644 index 0000000000000000000000000000000000000000..6bcf4ac81b76639bdf6f228f8c987e97281d9d17 --- /dev/null +++ b/ecmascript/compiler/precompile_checker.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ECMASCRIPT_COMPILER_PRECOMPILE_CHECKER_H +#define ECMASCRIPT_COMPILER_PRECOMPILE_CHECKER_H + +#include "ecmascript/compiler/gate_accessor.h" + +namespace panda::ecmascript::kungfu { +class PassData; +class PreCompileChecker { +public: + PreCompileChecker(PassData* data, Circuit* circuit, const std::string& methodName, bool enableLog) + : data_(data), acc_(circuit), methodName_(methodName), enableLog_(enableLog) {} + + bool Run(); + +private: + bool HasReturnCheck() const; + bool HasDebuggerStmt() const; + void PrintAbortInfo(const std::string& checkName) const; + PassData* data_; + GateAccessor acc_; + const std::string methodName_; + bool enableLog_; +}; +} + +#endif \ No newline at end of file