* Copyright (c) 2026 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_ARKSTEED_GRAPH_BUILDER_NEW_H
#define ECMASCRIPT_ARKSTEED_GRAPH_BUILDER_NEW_H
#include "ecmascript/arksteed/arksteed_bytecode_analysis_new.h"
#include "ecmascript/arksteed/arksteed_bytecode_preprocessor_new.h"
#include "ecmascript/arksteed/arksteed_framestate_new.h"
#include "ecmascript/arksteed/arksteed_graph.h"
#include "ecmascript/compiler/common_stub_csigns.h"
namespace panda::ecmascript::arksteed {
using CallSignature = kungfu::CallSignature;
using CommonStubCSigns = kungfu::CommonStubCSigns;
using RuntimeStubCSigns = kungfu::RuntimeStubCSigns;
class GraphBuilderNew {
public:
GraphBuilderNew(Graph *destGraph,
uintptr_t glueAddr,
BytecodePreprocessorNew *preproc,
BytecodeAnalysisNew *analysis);
bool Run();
Chunk *GetChunk() const
{
return preproc_->GetChunk();
}
uint32_t GetNumLocalVRegs() const
{
return preproc_->GetNumLocalVRegs();
}
uint32_t GetNumParamVRegs() const
{
return preproc_->GetNumParamVRegs();
}
uint32_t GetNumVRegs() const
{
return preproc_->GetNumVRegs();
}
private:
using BasicBlockInfo = BytecodePreprocessorNew::BasicBlockInfo;
using BytecodeInfo = BytecodePreprocessorNew::BytecodeInfo;
using CommonStubID = CommonStubCSigns::ID;
using RuntimeStubID = RuntimeStubCSigns::ID;
struct CatchBlockInputData;
struct BytecodeVisitor;
void DebugLog();
void InitializeBasicBlocks();
void InitializeGlobalsAndParameters();
void FinalizeStartBasicBlock(BCFrameState &frameState);
void ProcessBasicBlock(BCFrameState &frameState, uint32_t rpoIndex);
void ProcessCatchBlockHead(BCFrameState &frameState, uint32_t rpoIndex);
void VisitBytecode(uint32_t rpoIndex, BCFrameState *frameState, const BytecodeInfo *bcInfo);
void FinalizeBasicBlockRelations();
void InitFrameState(BCFrameState &framestate, uint32_t rpoIndex);
void InitFrameStateForLoopHeader(BCFrameState &framestate, uint32_t rpoIndex);
void InitFrameStateForCatchBlockHeader(BCFrameState &framestate, uint32_t rpoIndex);
void WriteBackFrameStateToLoopHeader(BCFrameState ¤t, uint32_t rpoIndex);
void MergeFrameState(BCFrameState &dest, uint32_t rpoIndex, uint32_t predecessorIndex);
uint32_t AppendCatchBlockInputs(const BCFrameState ¤t, uint32_t catchBlockIndex);
template <class VertexT, class... Args>
VertexT *NewVertex(BB *owner, std::initializer_list<ValueVertex *> inputs, Args &&...args);
template <class VertexT, class... Args>
VertexT *NewVertex(BB *owner, const ChunkVector<ValueVertex *> &inputs, Args &&...args);
template <class VertexT, class... Args>
VertexT *NewVertexNoInput(BB *owner, Args &&...args);
PhiVertex *NewPhiVertex(BB *owner, uint32_t numPredecessors, VRegIDType vreg);
template <class VertexT, class... Args>
VertexT *NewControlVertex(BB *owner, std::initializer_list<ValueVertex *> inputs, Args &&...args);
template <class VertexT>
VertexT *FinalizeNonControlVertex(BB *owner, VertexT *vertex);
template <class VertexT>
VertexT *FinalizeControlVertex(BB *owner, VertexT *vertex);
ValueVertex *GetGlue() const;
ValueVertex *GetUndefinedValue() const;
Graph *graph_;
uintptr_t glueAddr_;
BytecodePreprocessorNew *preproc_;
BytecodeAnalysisNew *analysis_;
ValueVertex *glue_ = nullptr;
ValueVertex *undefinedValue_ = nullptr;
ChunkVector<BB *> blocks_;
ChunkVector<CondensedBCFrameState> frameStates_;
ChunkVector<CatchBlockInputData *> catchBlockInputs_;
};
}
#endif