diff --git a/compiler/optimizer/optimizations/expand_intrinsics.cpp b/compiler/optimizer/optimizations/expand_intrinsics.cpp index e628a7f117aef3b44eba1959d1da2e6f0141ed5c..664b52ab80b5ed265b455d3cecee3f7bbba4915c 100644 --- a/compiler/optimizer/optimizations/expand_intrinsics.cpp +++ b/compiler/optimizer/optimizations/expand_intrinsics.cpp @@ -54,6 +54,8 @@ bool ExpandIntrinsics::Expand(IntrinsicInst *inst) return ExpandLdLexVarDyn(inst); case RuntimeInterface::IntrinsicId::INTRINSIC_TRY_LD_GLOBAL_BY_NAME: return ExpandTryLdGlobalByName(inst); + case RuntimeInterface::IntrinsicId::INTRINSIC_LDLEXENV_DYN: + return ExpandLdlexenvDyn(inst); default: return false; } @@ -430,6 +432,18 @@ bool ExpandIntrinsics::ExpandLdLexVarDyn(IntrinsicInst *intrinsic) return true; } +bool ExpandIntrinsics::ExpandLdlexenvDyn([[maybe_unused]] IntrinsicInst *intrinsic) +{ + auto pc = intrinsic->GetPc(); + auto load_lexical_env = GetGraph()->CreateInstLoadLexicalEnv(DataType::ANY, pc); + auto func_obj = intrinsic->GetInput(0).GetInst(); + load_lexical_env->SetInput(0, func_obj); + intrinsic->InsertBefore(load_lexical_env); + intrinsic->ReplaceUsers(load_lexical_env); + intrinsic->GetBasicBlock()->RemoveInst(intrinsic); + return true; +} + bool ExpandIntrinsics::ExpandTryLdGlobalByName(IntrinsicInst *inst) { if (GetGraph()->IsAotMode()) { diff --git a/compiler/optimizer/optimizations/expand_intrinsics.h b/compiler/optimizer/optimizations/expand_intrinsics.h index 4866eb5e5de8588e1efa264ee266ca7085bcda75..d1f86c64c028c4295a746a19688a14e8405caddb 100644 --- a/compiler/optimizer/optimizations/expand_intrinsics.h +++ b/compiler/optimizer/optimizations/expand_intrinsics.h @@ -75,6 +75,7 @@ private: void BuildGuard(Inst *inst, uintptr_t target); bool ExpandLdLexDyn(IntrinsicInst *intrinsic); bool ExpandLdLexVarDyn(IntrinsicInst *intrinsic); + bool ExpandLdlexenvDyn(IntrinsicInst *intrinsic); bool ExpandTryLdGlobalByName(IntrinsicInst *inst); template @@ -85,4 +86,4 @@ private: } // namespace panda::compiler -#endif // _COMPILER_OPTIMIZER_OPTIMIZATIONS_EXPAND_INTRINSICS_H \ No newline at end of file +#endif // _COMPILER_OPTIMIZER_OPTIMIZATIONS_EXPAND_INTRINSICS_H diff --git a/tests/compiler/expand_intrinsics_ecma_test.cpp b/tests/compiler/expand_intrinsics_ecma_test.cpp index e8b26709870097d8db92c2e1f706772579e440ca..fa44bdd775ab8361bedabd6a57dfa9d9c448b88d 100644 --- a/tests/compiler/expand_intrinsics_ecma_test.cpp +++ b/tests/compiler/expand_intrinsics_ecma_test.cpp @@ -187,5 +187,39 @@ TEST_F(ExpandIntrinsicsTest, LdLexDyn) ASSERT_TRUE(GraphComparator().Compare(graph, graph_opt)); } + +TEST_F(ExpandIntrinsicsTest, ExpandLdlexenvDyn) +{ + auto graph = CreateGraphDynStubWithDefaultRuntime(); + GRAPH(graph) + { + PARAMETER(0, 0).any(); + BASIC_BLOCK(2, -1) + { + INST(4, Opcode::SaveState).NoVregs(); + INST(1, Opcode::Intrinsic) + .IntrinsicId(RuntimeInterface::IntrinsicId::INTRINSIC_LDLEXENV_DYN) + .any() + .Inputs({{DataType::ANY, 0}}) + .ClearFlag(inst_flags::REQUIRE_STATE); + INST(2, Opcode::Return).any().Inputs(1); + } + } + ASSERT_TRUE(graph->RunPass()); + ASSERT_TRUE(graph->RunPass()); + GraphChecker(graph).Check(); + auto graph_opt = CreateGraphDynStubWithDefaultRuntime(); + GRAPH(graph_opt) + { + PARAMETER(0, 0).any(); + BASIC_BLOCK(2, -1) + { + INST(1, Opcode::LoadLexicalEnv).any().Inputs(0); + INST(2, Opcode::Return).any().Inputs(1); + } + } + GraphChecker(graph_opt).Check(); + ASSERT_TRUE(GraphComparator().Compare(graph, graph_opt)); +} // NOLINTEND(readability-magic-numbers) } // namespace panda::compiler