/* * 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/accessor_data.h" #include "ecmascript/base/number_helper.h" #include "ecmascript/compiler/circuit.h" #include "ecmascript/compiler/circuit_builder.h" #include "ecmascript/compiler/gate.h" #include "ecmascript/compiler/stub_descriptor.h" #include "ecmascript/js_function.h" #include "ecmascript/js_object.h" #include "ecmascript/js_tagged_value.h" #include "ecmascript/layout_info.h" #include "ecmascript/tagged_dictionary.h" namespace kungfu { using namespace panda::ecmascript; // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define DEFVARIABLE(varname, type, val) Stub::Variable varname(GetEnvironment(), type, NextVariableId(), val) class Stub { public: class Environment; class Label; class Variable; class Label { public: class LabelImpl { public: LabelImpl(Environment *env, AddrShift 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, AddrShift value); AddrShift ReadVariable(Variable *var); void Bind(); void MergeAllControl(); void MergeAllDepend(); void AppendPredecessor(LabelImpl *predecessor); std::vector GetPredecessors() const { return predecessors_; } void SetControl(AddrShift control) { control_ = control; } void SetPreControl(AddrShift control) { predeControl_ = control; } void MergeControl(AddrShift control) { if (predeControl_ == -1) { predeControl_ = control; control_ = predeControl_; } else { otherPredeControls_.push_back(control); } } AddrShift GetControl() const { return control_; } void SetDepend(AddrShift depend) { depend_ = depend; } AddrShift GetDepend() const { return depend_; } private: bool IsNeedSeal() const; bool IsSealed() const { return isSealed_; } bool IsLoopHead() const; bool IsControlCase() const; AddrShift ReadVariableRecursive(Variable *var); Environment *env_; AddrShift control_; AddrShift predeControl_ {-1}; AddrShift dependRelay_ {-1}; AddrShift depend_ {-1}; AddrShift loopDepend_{-1}; std::vector otherPredeControls_; bool isSealed_ {false}; std::map valueMap_; std::vector phi; std::vector predecessors_; 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() { return impl_->Seal(); } void WriteVariable(Variable *var, AddrShift value) { impl_->WriteVariable(var, value); } AddrShift ReadVariable(Variable *var) { return impl_->ReadVariable(var); } void Bind() { impl_->Bind(); } void MergeAllControl() { impl_->MergeAllControl(); } void MergeAllDepend() { impl_->MergeAllDepend(); } void AppendPredecessor(const Label *predecessor) { impl_->AppendPredecessor(predecessor->GetRawLabel()); } std::vector