/* * Copyright (c) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ECMASCRIPT_COMPILER_STUB_H #define ECMASCRIPT_COMPILER_STUB_H #include "ecmascript/compiler/circuit.h" #include "ecmascript/compiler/circuit_builder.h" #include "ecmascript/compiler/circuit_builder-inl.h" #include "ecmascript/compiler/gate.h" #include "ecmascript/compiler/variable_type.h" #include "ecmascript/compiler/call_signature.h" #include "ecmascript/global_env_constants.h" namespace panda::ecmascript::kungfu { using namespace panda::ecmascript; // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define DEFVARIABLE(varname, type, val) Stub::Variable varname(GetEnvironment(), type, NextVariableId(), val) #define NOGC_RTSTUB_CSIGNS_BEGIN (CommonStubCSigns::NUM_OF_STUBS + BytecodeStubCSigns::NUM_OF_VALID_STUBS) class Stub { public: class Environment; class Label; class Variable; class Label { public: class LabelImpl { public: LabelImpl(Environment *env, GateRef control) : env_(env), control_(control), predeControl_(-1), isSealed_(false) { } ~LabelImpl() = default; NO_MOVE_SEMANTIC(LabelImpl); NO_COPY_SEMANTIC(LabelImpl); void Seal(); void WriteVariable(Variable *var, GateRef value); GateRef ReadVariable(Variable *var); void Bind(); void MergeAllControl(); void MergeAllDepend(); void AppendPredecessor(LabelImpl *predecessor); std::vector GetPredecessors() const { return localPreds_; } void SetControl(GateRef control) { control_ = control; } void SetPreControl(GateRef control) { predeControl_ = control; } void MergeControl(GateRef control) { if (predeControl_ == -1) { predeControl_ = control; control_ = predeControl_; } else { otherPredeControls_.push_back(control); } } GateRef GetControl() const { return control_; } void SetDepend(GateRef depend) { depend_ = depend; } GateRef GetDepend() const { return depend_; } private: bool IsNeedSeal() const; bool IsSealed() const { return isSealed_; } bool IsLoopHead() const; bool IsControlCase() const; GateRef ReadVariableRecursive(Variable *var); Environment *env_; GateRef control_; GateRef predeControl_ {-1}; GateRef dependRelay_ {-1}; GateRef depend_ {-1}; GateRef loopDepend_ {-1}; std::vector otherPredeControls_; bool isSealed_ {false}; std::map valueMap_; std::vector phies_; std::vector localPreds_; std::map incompletePhis_; }; explicit Label() = default; explicit Label(Environment *env); explicit Label(LabelImpl *impl) : impl_(impl) {} ~Label() = default; Label(Label const &label) = default; Label &operator=(Label const &label) = default; Label(Label &&label) = default; Label &operator=(Label &&label) = default; void Seal(); void WriteVariable(Variable *var, GateRef value); GateRef ReadVariable(Variable *var); void Bind(); void MergeAllControl(); void MergeAllDepend(); void AppendPredecessor(const Label *predecessor); std::vector