14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci#ifndef ECMASCRIPT_COMPILER_CIRCUIT_BUILDER_INL_H 164514f5e3Sopenharmony_ci#define ECMASCRIPT_COMPILER_CIRCUIT_BUILDER_INL_H 174514f5e3Sopenharmony_ci 184514f5e3Sopenharmony_ci#include "ecmascript/compiler/lcr_circuit_builder.h" 194514f5e3Sopenharmony_ci#include "ecmascript/compiler/mcr_circuit_builder.h" 204514f5e3Sopenharmony_ci#include "ecmascript/compiler/hcr_circuit_builder.h" 214514f5e3Sopenharmony_ci#include "ecmascript/compiler/circuit_builder.h" 224514f5e3Sopenharmony_ci#include "ecmascript/mem/region.h" 234514f5e3Sopenharmony_ci#include "ecmascript/method.h" 244514f5e3Sopenharmony_ci 254514f5e3Sopenharmony_cinamespace panda::ecmascript::kungfu { 264514f5e3Sopenharmony_ci// constant 274514f5e3Sopenharmony_ciGateRef CircuitBuilder::True() 284514f5e3Sopenharmony_ci{ 294514f5e3Sopenharmony_ci return Boolean(true); 304514f5e3Sopenharmony_ci} 314514f5e3Sopenharmony_ci 324514f5e3Sopenharmony_ciGateRef CircuitBuilder::False() 334514f5e3Sopenharmony_ci{ 344514f5e3Sopenharmony_ci return Boolean(false); 354514f5e3Sopenharmony_ci} 364514f5e3Sopenharmony_ci 374514f5e3Sopenharmony_ciGateRef CircuitBuilder::Undefined() 384514f5e3Sopenharmony_ci{ 394514f5e3Sopenharmony_ci return UndefineConstant(); 404514f5e3Sopenharmony_ci} 414514f5e3Sopenharmony_ci 424514f5e3Sopenharmony_ciGateRef CircuitBuilder::Hole() 434514f5e3Sopenharmony_ci{ 444514f5e3Sopenharmony_ci return HoleConstant(); 454514f5e3Sopenharmony_ci} 464514f5e3Sopenharmony_ci 474514f5e3Sopenharmony_ciGateRef CircuitBuilder::DoubleIsINF(GateRef x) 484514f5e3Sopenharmony_ci{ 494514f5e3Sopenharmony_ci GateRef infinity = Double(base::POSITIVE_INFINITY); 504514f5e3Sopenharmony_ci GateRef negativeInfinity = Double(-base::POSITIVE_INFINITY); 514514f5e3Sopenharmony_ci GateRef diff1 = DoubleEqual(x, infinity); 524514f5e3Sopenharmony_ci GateRef diff2 = DoubleEqual(x, negativeInfinity); 534514f5e3Sopenharmony_ci return BitOr(diff1, diff2); 544514f5e3Sopenharmony_ci} 554514f5e3Sopenharmony_ci 564514f5e3Sopenharmony_ciGateRef CircuitBuilder::DoubleIsNanOrInf(GateRef x) 574514f5e3Sopenharmony_ci{ 584514f5e3Sopenharmony_ci return BitOr(DoubleIsNAN(x), DoubleIsINF(x)); 594514f5e3Sopenharmony_ci} 604514f5e3Sopenharmony_ci 614514f5e3Sopenharmony_ci// Js World 624514f5e3Sopenharmony_ci// cast operation 634514f5e3Sopenharmony_ci 644514f5e3Sopenharmony_ciGateRef CircuitBuilder::GetGlobalConstantOffset(ConstantIndex index) 654514f5e3Sopenharmony_ci{ 664514f5e3Sopenharmony_ci return PtrMul(IntPtr(sizeof(JSTaggedValue)), IntPtr(static_cast<int>(index))); 674514f5e3Sopenharmony_ci} 684514f5e3Sopenharmony_ci 694514f5e3Sopenharmony_ciGateRef CircuitBuilder::GetExpectedNumOfArgs(GateRef method) 704514f5e3Sopenharmony_ci{ 714514f5e3Sopenharmony_ci GateRef callFieldOffset = IntPtr(Method::CALL_FIELD_OFFSET); 724514f5e3Sopenharmony_ci GateRef callfield = Load(VariableType::INT64(), method, callFieldOffset); 734514f5e3Sopenharmony_ci return Int64And( 744514f5e3Sopenharmony_ci Int64LSR(callfield, Int64(MethodLiteral::NumArgsBits::START_BIT)), 754514f5e3Sopenharmony_ci Int64((1LU << MethodLiteral::NumArgsBits::SIZE) - 1)); 764514f5e3Sopenharmony_ci} 774514f5e3Sopenharmony_ci 784514f5e3Sopenharmony_ciint CircuitBuilder::NextVariableId() 794514f5e3Sopenharmony_ci{ 804514f5e3Sopenharmony_ci return env_->NextVariableId(); 814514f5e3Sopenharmony_ci} 824514f5e3Sopenharmony_ci 834514f5e3Sopenharmony_civoid CircuitBuilder::HandleException(GateRef result, Label *success, Label *fail, Label *exit) 844514f5e3Sopenharmony_ci{ 854514f5e3Sopenharmony_ci BRANCH_CIR2(Equal(result, ExceptionConstant()), fail, success); 864514f5e3Sopenharmony_ci Bind(fail); 874514f5e3Sopenharmony_ci { 884514f5e3Sopenharmony_ci Jump(exit); 894514f5e3Sopenharmony_ci } 904514f5e3Sopenharmony_ci} 914514f5e3Sopenharmony_ci 924514f5e3Sopenharmony_civoid CircuitBuilder::HandleException(GateRef result, Label *success, Label *fail, Label *exit, GateRef exceptionVal) 934514f5e3Sopenharmony_ci{ 944514f5e3Sopenharmony_ci BRANCH_CIR2(Equal(result, exceptionVal), fail, success); 954514f5e3Sopenharmony_ci Bind(fail); 964514f5e3Sopenharmony_ci { 974514f5e3Sopenharmony_ci Jump(exit); 984514f5e3Sopenharmony_ci } 994514f5e3Sopenharmony_ci} 1004514f5e3Sopenharmony_ci 1014514f5e3Sopenharmony_civoid CircuitBuilder::SubCfgEntry(Label *entry) 1024514f5e3Sopenharmony_ci{ 1034514f5e3Sopenharmony_ci ASSERT(env_ != nullptr); 1044514f5e3Sopenharmony_ci env_->SubCfgEntry(entry); 1054514f5e3Sopenharmony_ci} 1064514f5e3Sopenharmony_ci 1074514f5e3Sopenharmony_civoid CircuitBuilder::SubCfgExit() 1084514f5e3Sopenharmony_ci{ 1094514f5e3Sopenharmony_ci ASSERT(env_ != nullptr); 1104514f5e3Sopenharmony_ci env_->SubCfgExit(); 1114514f5e3Sopenharmony_ci} 1124514f5e3Sopenharmony_ci 1134514f5e3Sopenharmony_ciGateRef CircuitBuilder::Return(GateRef value) 1144514f5e3Sopenharmony_ci{ 1154514f5e3Sopenharmony_ci auto control = GetCurrentLabel()->GetControl(); 1164514f5e3Sopenharmony_ci auto depend = GetCurrentLabel()->GetDepend(); 1174514f5e3Sopenharmony_ci return Return(control, depend, value); 1184514f5e3Sopenharmony_ci} 1194514f5e3Sopenharmony_ci 1204514f5e3Sopenharmony_ciGateRef CircuitBuilder::Return() 1214514f5e3Sopenharmony_ci{ 1224514f5e3Sopenharmony_ci auto control = GetCurrentLabel()->GetControl(); 1234514f5e3Sopenharmony_ci auto depend = GetCurrentLabel()->GetDepend(); 1244514f5e3Sopenharmony_ci return ReturnVoid(control, depend); 1254514f5e3Sopenharmony_ci} 1264514f5e3Sopenharmony_ci 1274514f5e3Sopenharmony_civoid CircuitBuilder::Bind(Label *label) 1284514f5e3Sopenharmony_ci{ 1294514f5e3Sopenharmony_ci label->Bind(); 1304514f5e3Sopenharmony_ci env_->SetCurrentLabel(label); 1314514f5e3Sopenharmony_ci} 1324514f5e3Sopenharmony_ci 1334514f5e3Sopenharmony_civoid CircuitBuilder::Bind(Label *label, bool justSlowPath) 1344514f5e3Sopenharmony_ci{ 1354514f5e3Sopenharmony_ci if (!justSlowPath) { 1364514f5e3Sopenharmony_ci label->Bind(); 1374514f5e3Sopenharmony_ci env_->SetCurrentLabel(label); 1384514f5e3Sopenharmony_ci } 1394514f5e3Sopenharmony_ci} 1404514f5e3Sopenharmony_ci 1414514f5e3Sopenharmony_ciGateRef CircuitBuilder::GetState() const 1424514f5e3Sopenharmony_ci{ 1434514f5e3Sopenharmony_ci return GetCurrentLabel()->GetControl(); 1444514f5e3Sopenharmony_ci} 1454514f5e3Sopenharmony_ci 1464514f5e3Sopenharmony_ciGateRef CircuitBuilder::GetDepend() const 1474514f5e3Sopenharmony_ci{ 1484514f5e3Sopenharmony_ci return GetCurrentLabel()->GetDepend(); 1494514f5e3Sopenharmony_ci} 1504514f5e3Sopenharmony_ci 1514514f5e3Sopenharmony_ciStateDepend CircuitBuilder::GetStateDepend() const 1524514f5e3Sopenharmony_ci{ 1534514f5e3Sopenharmony_ci return StateDepend(GetState(), GetDepend()); 1544514f5e3Sopenharmony_ci} 1554514f5e3Sopenharmony_ci 1564514f5e3Sopenharmony_civoid CircuitBuilder::SetDepend(GateRef depend) 1574514f5e3Sopenharmony_ci{ 1584514f5e3Sopenharmony_ci GetCurrentLabel()->SetDepend(depend); 1594514f5e3Sopenharmony_ci} 1604514f5e3Sopenharmony_ci 1614514f5e3Sopenharmony_civoid CircuitBuilder::SetState(GateRef state) 1624514f5e3Sopenharmony_ci{ 1634514f5e3Sopenharmony_ci GetCurrentLabel()->SetControl(state); 1644514f5e3Sopenharmony_ci} 1654514f5e3Sopenharmony_ci 1664514f5e3Sopenharmony_ciLabel *CircuitBuilder::GetCurrentLabel() const 1674514f5e3Sopenharmony_ci{ 1684514f5e3Sopenharmony_ci return GetCurrentEnvironment()->GetCurrentLabel(); 1694514f5e3Sopenharmony_ci} 1704514f5e3Sopenharmony_ci 1714514f5e3Sopenharmony_ciLogicAndBuilder::LogicAndBuilder(Environment *env) 1724514f5e3Sopenharmony_ci : env_(env), builder_(env_->GetBuilder()) 1734514f5e3Sopenharmony_ci{ 1744514f5e3Sopenharmony_ci subentry_ = new Label(env_); 1754514f5e3Sopenharmony_ci builder_->SubCfgEntry(subentry_); 1764514f5e3Sopenharmony_ci result_ = new Variable(env_, VariableType::BOOL(), builder_->NextVariableId(), builder_->False()); 1774514f5e3Sopenharmony_ci exit_ = new Label(env_); 1784514f5e3Sopenharmony_ci} 1794514f5e3Sopenharmony_ci 1804514f5e3Sopenharmony_ciLogicAndBuilder::~LogicAndBuilder() 1814514f5e3Sopenharmony_ci{ 1824514f5e3Sopenharmony_ci ASSERT(exit_ != nullptr); 1834514f5e3Sopenharmony_ci delete exit_; 1844514f5e3Sopenharmony_ci exit_ = nullptr; 1854514f5e3Sopenharmony_ci ASSERT(result_ != nullptr); 1864514f5e3Sopenharmony_ci delete result_; 1874514f5e3Sopenharmony_ci result_ = nullptr; 1884514f5e3Sopenharmony_ci ASSERT(subentry_ != nullptr); 1894514f5e3Sopenharmony_ci delete subentry_; 1904514f5e3Sopenharmony_ci subentry_ = nullptr; 1914514f5e3Sopenharmony_ci for (auto &label : labels_) { 1924514f5e3Sopenharmony_ci ASSERT(label != nullptr); 1934514f5e3Sopenharmony_ci delete label; 1944514f5e3Sopenharmony_ci label = nullptr; 1954514f5e3Sopenharmony_ci } 1964514f5e3Sopenharmony_ci} 1974514f5e3Sopenharmony_ci 1984514f5e3Sopenharmony_ciLogicAndBuilder &LogicAndBuilder::And(GateRef check) 1994514f5e3Sopenharmony_ci{ 2004514f5e3Sopenharmony_ci auto checkTrue = new Label(env_); 2014514f5e3Sopenharmony_ci labels_.push_back(checkTrue); 2024514f5e3Sopenharmony_ci builder_->Branch(check, checkTrue, exit_); 2034514f5e3Sopenharmony_ci builder_->Bind(checkTrue); 2044514f5e3Sopenharmony_ci return *this; 2054514f5e3Sopenharmony_ci} 2064514f5e3Sopenharmony_ci 2074514f5e3Sopenharmony_ciGateRef LogicAndBuilder::Done() 2084514f5e3Sopenharmony_ci{ 2094514f5e3Sopenharmony_ci *result_ = builder_->True(); 2104514f5e3Sopenharmony_ci builder_->Jump(exit_); 2114514f5e3Sopenharmony_ci builder_->Bind(exit_); 2124514f5e3Sopenharmony_ci auto ret = **result_; 2134514f5e3Sopenharmony_ci builder_->SubCfgExit(); 2144514f5e3Sopenharmony_ci return ret; 2154514f5e3Sopenharmony_ci} 2164514f5e3Sopenharmony_ci 2174514f5e3Sopenharmony_ciLogicOrBuilder::LogicOrBuilder(Environment *env) 2184514f5e3Sopenharmony_ci : env_(env), builder_(env_->GetBuilder()) 2194514f5e3Sopenharmony_ci{ 2204514f5e3Sopenharmony_ci subentry_ = new Label(env_); 2214514f5e3Sopenharmony_ci builder_->SubCfgEntry(subentry_); 2224514f5e3Sopenharmony_ci result_ = new Variable(env_, VariableType::BOOL(), builder_->NextVariableId(), builder_->True()); 2234514f5e3Sopenharmony_ci exit_ = new Label(env_); 2244514f5e3Sopenharmony_ci} 2254514f5e3Sopenharmony_ci 2264514f5e3Sopenharmony_ciLogicOrBuilder::~LogicOrBuilder() 2274514f5e3Sopenharmony_ci{ 2284514f5e3Sopenharmony_ci ASSERT(exit_ != nullptr); 2294514f5e3Sopenharmony_ci delete exit_; 2304514f5e3Sopenharmony_ci exit_ = nullptr; 2314514f5e3Sopenharmony_ci ASSERT(result_ != nullptr); 2324514f5e3Sopenharmony_ci delete result_; 2334514f5e3Sopenharmony_ci result_ = nullptr; 2344514f5e3Sopenharmony_ci ASSERT(subentry_ != nullptr); 2354514f5e3Sopenharmony_ci delete subentry_; 2364514f5e3Sopenharmony_ci subentry_ = nullptr; 2374514f5e3Sopenharmony_ci for (auto &label : labels_) { 2384514f5e3Sopenharmony_ci ASSERT(label != nullptr); 2394514f5e3Sopenharmony_ci delete label; 2404514f5e3Sopenharmony_ci label = nullptr; 2414514f5e3Sopenharmony_ci } 2424514f5e3Sopenharmony_ci} 2434514f5e3Sopenharmony_ci 2444514f5e3Sopenharmony_ciLogicOrBuilder &LogicOrBuilder::Or(GateRef check) 2454514f5e3Sopenharmony_ci{ 2464514f5e3Sopenharmony_ci auto checkFalse = new Label(env_); 2474514f5e3Sopenharmony_ci labels_.push_back(checkFalse); 2484514f5e3Sopenharmony_ci builder_->Branch(check, exit_, checkFalse); 2494514f5e3Sopenharmony_ci builder_->Bind(checkFalse); 2504514f5e3Sopenharmony_ci return *this; 2514514f5e3Sopenharmony_ci} 2524514f5e3Sopenharmony_ci 2534514f5e3Sopenharmony_ciGateRef LogicOrBuilder::Done() 2544514f5e3Sopenharmony_ci{ 2554514f5e3Sopenharmony_ci *result_ = builder_->False(); 2564514f5e3Sopenharmony_ci builder_->Jump(exit_); 2574514f5e3Sopenharmony_ci builder_->Bind(exit_); 2584514f5e3Sopenharmony_ci auto ret = **result_; 2594514f5e3Sopenharmony_ci builder_->SubCfgExit(); 2604514f5e3Sopenharmony_ci return ret; 2614514f5e3Sopenharmony_ci} 2624514f5e3Sopenharmony_ci} // namespace panda::ecmascript::kungfu 2634514f5e3Sopenharmony_ci 2644514f5e3Sopenharmony_ci#endif 265