14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2023 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
164514f5e3Sopenharmony_ci#ifndef ECMASCRIPT_COMPILER_HCR_CIRCUIT_BUILDER_H
174514f5e3Sopenharmony_ci#define ECMASCRIPT_COMPILER_HCR_CIRCUIT_BUILDER_H
184514f5e3Sopenharmony_ci
194514f5e3Sopenharmony_ci#include "ecmascript/compiler/circuit_builder_helper.h"
204514f5e3Sopenharmony_ci#include "ecmascript/mem/region.h"
214514f5e3Sopenharmony_ci#include "ecmascript/js_function.h"
224514f5e3Sopenharmony_ci
234514f5e3Sopenharmony_cinamespace panda::ecmascript::kungfu {
244514f5e3Sopenharmony_ci
254514f5e3Sopenharmony_ciGateRef CircuitBuilder::IsSpecial(GateRef x, JSTaggedType type)
264514f5e3Sopenharmony_ci{
274514f5e3Sopenharmony_ci    auto specialValue = circuit_->GetConstantGate(
284514f5e3Sopenharmony_ci        MachineType::I64, type, GateType::TaggedValue());
294514f5e3Sopenharmony_ci
304514f5e3Sopenharmony_ci    return Equal(x, specialValue);
314514f5e3Sopenharmony_ci}
324514f5e3Sopenharmony_ci
334514f5e3Sopenharmony_ciinline GateRef CircuitBuilder::IsJSHClass(GateRef obj)
344514f5e3Sopenharmony_ci{
354514f5e3Sopenharmony_ci    return Int32Equal(GetObjectType(LoadHClass(obj)), Int32(static_cast<int32_t>(JSType::HCLASS)));
364514f5e3Sopenharmony_ci}
374514f5e3Sopenharmony_ci
384514f5e3Sopenharmony_ciinline GateRef CircuitBuilder::IsJSFunction(GateRef obj)
394514f5e3Sopenharmony_ci{
404514f5e3Sopenharmony_ci    GateRef objectType = GetObjectType(LoadHClass(obj));
414514f5e3Sopenharmony_ci    GateRef greater = Int32GreaterThanOrEqual(objectType,
424514f5e3Sopenharmony_ci        Int32(static_cast<int32_t>(JSType::JS_FUNCTION_FIRST)));
434514f5e3Sopenharmony_ci    GateRef less = Int32LessThanOrEqual(objectType,
444514f5e3Sopenharmony_ci        Int32(static_cast<int32_t>(JSType::JS_FUNCTION_LAST)));
454514f5e3Sopenharmony_ci    return BitAnd(greater, less);
464514f5e3Sopenharmony_ci}
474514f5e3Sopenharmony_ci
484514f5e3Sopenharmony_ciGateRef CircuitBuilder::IsJsType(GateRef obj, JSType type)
494514f5e3Sopenharmony_ci{
504514f5e3Sopenharmony_ci    GateRef objectType = GetObjectType(LoadHClass(obj));
514514f5e3Sopenharmony_ci    return Equal(objectType, Int32(static_cast<int32_t>(type)));
524514f5e3Sopenharmony_ci}
534514f5e3Sopenharmony_ci
544514f5e3Sopenharmony_ciGateRef CircuitBuilder::IsJSObject(GateRef obj)
554514f5e3Sopenharmony_ci{
564514f5e3Sopenharmony_ci    Label entryPass(env_);
574514f5e3Sopenharmony_ci    SubCfgEntry(&entryPass);
584514f5e3Sopenharmony_ci    DEFVALUE(result, env_, VariableType::BOOL(), False());
594514f5e3Sopenharmony_ci    Label heapObj(env_);
604514f5e3Sopenharmony_ci    Label exit(env_);
614514f5e3Sopenharmony_ci    GateRef isHeapObject = TaggedIsHeapObject(obj);
624514f5e3Sopenharmony_ci    BRANCH_CIR2(isHeapObject, &heapObj, &exit);
634514f5e3Sopenharmony_ci    Bind(&heapObj);
644514f5e3Sopenharmony_ci    {
654514f5e3Sopenharmony_ci        GateRef objectType = GetObjectType(LoadHClass(obj));
664514f5e3Sopenharmony_ci        result = BitAnd(
674514f5e3Sopenharmony_ci            Int32LessThanOrEqual(objectType, Int32(static_cast<int32_t>(JSType::JS_OBJECT_LAST))),
684514f5e3Sopenharmony_ci            Int32GreaterThanOrEqual(objectType, Int32(static_cast<int32_t>(JSType::JS_OBJECT_FIRST))));
694514f5e3Sopenharmony_ci        Jump(&exit);
704514f5e3Sopenharmony_ci    }
714514f5e3Sopenharmony_ci    Bind(&exit);
724514f5e3Sopenharmony_ci    auto ret = *result;
734514f5e3Sopenharmony_ci    SubCfgExit();
744514f5e3Sopenharmony_ci    return ret;
754514f5e3Sopenharmony_ci}
764514f5e3Sopenharmony_ci
774514f5e3Sopenharmony_ciGateRef CircuitBuilder::IsCallableFromBitField(GateRef bitfield)
784514f5e3Sopenharmony_ci{
794514f5e3Sopenharmony_ci    return NotEqual(
804514f5e3Sopenharmony_ci        Int32And(Int32LSR(bitfield, Int32(JSHClass::CallableBit::START_BIT)),
814514f5e3Sopenharmony_ci            Int32((1LU << JSHClass::CallableBit::SIZE) - 1)),
824514f5e3Sopenharmony_ci        Int32(0));
834514f5e3Sopenharmony_ci}
844514f5e3Sopenharmony_ci
854514f5e3Sopenharmony_ciGateRef CircuitBuilder::IsCallable(GateRef obj)
864514f5e3Sopenharmony_ci{
874514f5e3Sopenharmony_ci    GateRef hClass = LoadHClass(obj);
884514f5e3Sopenharmony_ci    GateRef bitfieldOffset = IntPtr(JSHClass::BIT_FIELD_OFFSET);
894514f5e3Sopenharmony_ci    GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
904514f5e3Sopenharmony_ci    return IsCallableFromBitField(bitfield);
914514f5e3Sopenharmony_ci}
924514f5e3Sopenharmony_ci
934514f5e3Sopenharmony_ciGateRef CircuitBuilder::IsProtoTypeHClass(GateRef hClass)
944514f5e3Sopenharmony_ci{
954514f5e3Sopenharmony_ci    GateRef bitfield = LoadConstOffset(VariableType::INT32(), hClass, JSHClass::BIT_FIELD_OFFSET);
964514f5e3Sopenharmony_ci    return TruncInt32ToInt1(Int32And(Int32LSR(bitfield,
974514f5e3Sopenharmony_ci        Int32(JSHClass::IsPrototypeBit::START_BIT)),
984514f5e3Sopenharmony_ci        Int32((1LU << JSHClass::IsPrototypeBit::SIZE) - 1)));
994514f5e3Sopenharmony_ci}
1004514f5e3Sopenharmony_ci
1014514f5e3Sopenharmony_ciGateRef CircuitBuilder::IsJsProxy(GateRef obj)
1024514f5e3Sopenharmony_ci{
1034514f5e3Sopenharmony_ci    GateRef objectType = GetObjectType(LoadHClass(obj));
1044514f5e3Sopenharmony_ci    return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_PROXY)));
1054514f5e3Sopenharmony_ci}
1064514f5e3Sopenharmony_ci
1074514f5e3Sopenharmony_ciGateRef CircuitBuilder::IsTreeString(GateRef obj)
1084514f5e3Sopenharmony_ci{
1094514f5e3Sopenharmony_ci    GateRef objectType = GetObjectType(LoadHClass(obj));
1104514f5e3Sopenharmony_ci    return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::TREE_STRING)));
1114514f5e3Sopenharmony_ci}
1124514f5e3Sopenharmony_ci
1134514f5e3Sopenharmony_ciGateRef CircuitBuilder::IsSlicedString(GateRef obj)
1144514f5e3Sopenharmony_ci{
1154514f5e3Sopenharmony_ci    GateRef objectType = GetObjectType(LoadHClass(obj));
1164514f5e3Sopenharmony_ci    return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::SLICED_STRING)));
1174514f5e3Sopenharmony_ci}
1184514f5e3Sopenharmony_ci
1194514f5e3Sopenharmony_ciGateRef CircuitBuilder::IsLineString(GateRef obj)
1204514f5e3Sopenharmony_ci{
1214514f5e3Sopenharmony_ci    GateRef objectType = GetObjectType(LoadHClass(obj));
1224514f5e3Sopenharmony_ci    return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::LINE_STRING)));
1234514f5e3Sopenharmony_ci}
1244514f5e3Sopenharmony_ci
1254514f5e3Sopenharmony_ciGateRef CircuitBuilder::IsConstantString(GateRef obj)
1264514f5e3Sopenharmony_ci{
1274514f5e3Sopenharmony_ci    GateRef objectType = GetObjectType(LoadHClass(obj));
1284514f5e3Sopenharmony_ci    return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::CONSTANT_STRING)));
1294514f5e3Sopenharmony_ci}
1304514f5e3Sopenharmony_ci
1314514f5e3Sopenharmony_ciGateRef CircuitBuilder::ComputeSizeUtf8(GateRef length)
1324514f5e3Sopenharmony_ci{
1334514f5e3Sopenharmony_ci    return PtrAdd(IntPtr(LineEcmaString::DATA_OFFSET), length);
1344514f5e3Sopenharmony_ci}
1354514f5e3Sopenharmony_ci
1364514f5e3Sopenharmony_ciGateRef CircuitBuilder::ComputeSizeUtf16(GateRef length)
1374514f5e3Sopenharmony_ci{
1384514f5e3Sopenharmony_ci    return PtrAdd(IntPtr(LineEcmaString::DATA_OFFSET), PtrMul(length, IntPtr(sizeof(uint16_t))));
1394514f5e3Sopenharmony_ci}
1404514f5e3Sopenharmony_ci
1414514f5e3Sopenharmony_ciGateRef CircuitBuilder::AlignUp(GateRef x, GateRef alignment)
1424514f5e3Sopenharmony_ci{
1434514f5e3Sopenharmony_ci    GateRef x1 = PtrAdd(x, PtrSub(alignment, IntPtr(1)));
1444514f5e3Sopenharmony_ci    return IntPtrAnd(x1, IntPtrNot(PtrSub(alignment, IntPtr(1))));
1454514f5e3Sopenharmony_ci}
1464514f5e3Sopenharmony_ci
1474514f5e3Sopenharmony_ciinline GateRef CircuitBuilder::IsDictionaryMode(GateRef object)
1484514f5e3Sopenharmony_ci{
1494514f5e3Sopenharmony_ci    GateRef type = GetObjectType(LoadHClass(object));
1504514f5e3Sopenharmony_ci    return Int32Equal(type, Int32(static_cast<int32_t>(JSType::TAGGED_DICTIONARY)));
1514514f5e3Sopenharmony_ci}
1524514f5e3Sopenharmony_ci
1534514f5e3Sopenharmony_ciGateRef CircuitBuilder::IsStableArguments(GateRef hClass)
1544514f5e3Sopenharmony_ci{
1554514f5e3Sopenharmony_ci    GateRef objectType = GetObjectType(hClass);
1564514f5e3Sopenharmony_ci    GateRef isJsArguments = Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_ARGUMENTS)));
1574514f5e3Sopenharmony_ci    GateRef isStableElements = IsStableElements(hClass);
1584514f5e3Sopenharmony_ci    return BitAnd(isStableElements, isJsArguments);
1594514f5e3Sopenharmony_ci}
1604514f5e3Sopenharmony_ci
1614514f5e3Sopenharmony_ciGateRef CircuitBuilder::IsStableArray(GateRef hClass)
1624514f5e3Sopenharmony_ci{
1634514f5e3Sopenharmony_ci    GateRef objectType = GetObjectType(hClass);
1644514f5e3Sopenharmony_ci    GateRef isJsArray = Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_ARRAY)));
1654514f5e3Sopenharmony_ci    GateRef isStableElements = IsStableElements(hClass);
1664514f5e3Sopenharmony_ci    return BitAnd(isStableElements, isJsArray);
1674514f5e3Sopenharmony_ci}
1684514f5e3Sopenharmony_ci
1694514f5e3Sopenharmony_ciGateRef CircuitBuilder::IsAOTLiteralInfo(GateRef x)
1704514f5e3Sopenharmony_ci{
1714514f5e3Sopenharmony_ci    GateRef objType = GetObjectType(LoadHClass(x));
1724514f5e3Sopenharmony_ci    GateRef isAOTLiteralInfoObj = Equal(objType,
1734514f5e3Sopenharmony_ci        Int32(static_cast<int32_t>(JSType::AOT_LITERAL_INFO)));
1744514f5e3Sopenharmony_ci    return isAOTLiteralInfoObj;
1754514f5e3Sopenharmony_ci}
1764514f5e3Sopenharmony_ci
1774514f5e3Sopenharmony_ciGateRef CircuitBuilder::LoadHClass(GateRef object)
1784514f5e3Sopenharmony_ci{
1794514f5e3Sopenharmony_ci    GateRef offset = IntPtr(TaggedObject::HCLASS_OFFSET);
1804514f5e3Sopenharmony_ci    return Load(VariableType::JS_POINTER(), object, offset);
1814514f5e3Sopenharmony_ci}
1824514f5e3Sopenharmony_ci
1834514f5e3Sopenharmony_ciGateRef CircuitBuilder::LoadHClassByConstOffset(GateRef object)
1844514f5e3Sopenharmony_ci{
1854514f5e3Sopenharmony_ci    return LoadConstOffset(VariableType::JS_POINTER(), object, TaggedObject::HCLASS_OFFSET);
1864514f5e3Sopenharmony_ci}
1874514f5e3Sopenharmony_ci
1884514f5e3Sopenharmony_ciGateRef CircuitBuilder::LoadPrototype(GateRef hclass)
1894514f5e3Sopenharmony_ci{
1904514f5e3Sopenharmony_ci    return LoadConstOffset(VariableType::JS_POINTER(), hclass, JSHClass::PROTOTYPE_OFFSET);
1914514f5e3Sopenharmony_ci}
1924514f5e3Sopenharmony_ci
1934514f5e3Sopenharmony_ciGateRef CircuitBuilder::LoadPrototypeHClass(GateRef object)
1944514f5e3Sopenharmony_ci{
1954514f5e3Sopenharmony_ci    GateRef objectHClass = LoadHClassByConstOffset(object);
1964514f5e3Sopenharmony_ci    GateRef objectPrototype = LoadPrototype(objectHClass);
1974514f5e3Sopenharmony_ci    return LoadHClass(objectPrototype);
1984514f5e3Sopenharmony_ci}
1994514f5e3Sopenharmony_ci
2004514f5e3Sopenharmony_ciGateRef CircuitBuilder::LoadPrototypeOfPrototypeHClass(GateRef object)
2014514f5e3Sopenharmony_ci{
2024514f5e3Sopenharmony_ci    GateRef objectHClass = LoadHClassByConstOffset(object);
2034514f5e3Sopenharmony_ci    GateRef objectPrototype = LoadPrototype(objectHClass);
2044514f5e3Sopenharmony_ci    GateRef objectPrototypeHClass = LoadHClassByConstOffset(objectPrototype);
2054514f5e3Sopenharmony_ci    GateRef objectPrototypeOfPrototype = LoadPrototype(objectPrototypeHClass);
2064514f5e3Sopenharmony_ci    return LoadHClass(objectPrototypeOfPrototype);
2074514f5e3Sopenharmony_ci}
2084514f5e3Sopenharmony_ci
2094514f5e3Sopenharmony_ciGateRef CircuitBuilder::GetObjectSizeFromHClass(GateRef hClass)
2104514f5e3Sopenharmony_ci{
2114514f5e3Sopenharmony_ci    // NOTE: check for special case of string and TAGGED_ARRAY
2124514f5e3Sopenharmony_ci    GateRef bitfield = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
2134514f5e3Sopenharmony_ci    GateRef objectSizeInWords = Int32And(Int32LSR(bitfield,
2144514f5e3Sopenharmony_ci        Int32(JSHClass::ObjectSizeInWordsBits::START_BIT)),
2154514f5e3Sopenharmony_ci        Int32((1LU << JSHClass::ObjectSizeInWordsBits::SIZE) - 1));
2164514f5e3Sopenharmony_ci    return PtrMul(ZExtInt32ToPtr(objectSizeInWords), IntPtr(JSTaggedValue::TaggedTypeSize()));
2174514f5e3Sopenharmony_ci}
2184514f5e3Sopenharmony_ci
2194514f5e3Sopenharmony_ciGateRef CircuitBuilder::IsDictionaryModeByHClass(GateRef hClass)
2204514f5e3Sopenharmony_ci{
2214514f5e3Sopenharmony_ci    GateRef bitfieldOffset = Int32(JSHClass::BIT_FIELD_OFFSET);
2224514f5e3Sopenharmony_ci    GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
2234514f5e3Sopenharmony_ci    return NotEqual(Int32And(Int32LSR(bitfield,
2244514f5e3Sopenharmony_ci        Int32(JSHClass::IsDictionaryBit::START_BIT)),
2254514f5e3Sopenharmony_ci        Int32((1LU << JSHClass::IsDictionaryBit::SIZE) - 1)),
2264514f5e3Sopenharmony_ci        Int32(0));
2274514f5e3Sopenharmony_ci}
2284514f5e3Sopenharmony_ci
2294514f5e3Sopenharmony_civoid CircuitBuilder::StoreHClass(GateRef glue, GateRef object, GateRef hClass)
2304514f5e3Sopenharmony_ci{
2314514f5e3Sopenharmony_ci    Store(VariableType::JS_POINTER(), glue, object, IntPtr(TaggedObject::HCLASS_OFFSET), hClass,
2324514f5e3Sopenharmony_ci          MemoryAttribute::NeedBarrier());
2334514f5e3Sopenharmony_ci}
2344514f5e3Sopenharmony_ci
2354514f5e3Sopenharmony_civoid CircuitBuilder::StoreHClassWithoutBarrier(GateRef glue, GateRef object, GateRef hClass)
2364514f5e3Sopenharmony_ci{
2374514f5e3Sopenharmony_ci    Store(VariableType::JS_POINTER(), glue, object, IntPtr(TaggedObject::HCLASS_OFFSET), hClass,
2384514f5e3Sopenharmony_ci          MemoryAttribute::NoBarrier());
2394514f5e3Sopenharmony_ci}
2404514f5e3Sopenharmony_ci
2414514f5e3Sopenharmony_civoid CircuitBuilder::StorePrototype(GateRef glue, GateRef hclass, GateRef prototype)
2424514f5e3Sopenharmony_ci{
2434514f5e3Sopenharmony_ci    Store(VariableType::JS_POINTER(), glue, hclass, IntPtr(JSHClass::PROTOTYPE_OFFSET), prototype);
2444514f5e3Sopenharmony_ci}
2454514f5e3Sopenharmony_ci
2464514f5e3Sopenharmony_ciGateRef CircuitBuilder::GetObjectType(GateRef hClass)
2474514f5e3Sopenharmony_ci{
2484514f5e3Sopenharmony_ci    GateRef bitfieldOffset = IntPtr(JSHClass::BIT_FIELD_OFFSET);
2494514f5e3Sopenharmony_ci    GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
2504514f5e3Sopenharmony_ci    return Int32And(bitfield, Int32((1LU << JSHClass::ObjectTypeBits::SIZE) - 1));
2514514f5e3Sopenharmony_ci}
2524514f5e3Sopenharmony_ci
2534514f5e3Sopenharmony_ciinline GateRef CircuitBuilder::CanFastCall(GateRef jsFunc)
2544514f5e3Sopenharmony_ci{
2554514f5e3Sopenharmony_ci    GateRef bitFieldOffset = IntPtr(JSFunctionBase::BIT_FIELD_OFFSET);
2564514f5e3Sopenharmony_ci    GateRef bitField = Load(VariableType::INT32(), jsFunc, bitFieldOffset);
2574514f5e3Sopenharmony_ci    return Int32NotEqual(
2584514f5e3Sopenharmony_ci        Int32And(
2594514f5e3Sopenharmony_ci            Int32LSR(bitField, Int32(JSFunctionBase::IsFastCallBit::START_BIT)),
2604514f5e3Sopenharmony_ci            Int32((1LU << JSFunctionBase::IsFastCallBit::SIZE) - 1)),
2614514f5e3Sopenharmony_ci        Int32(0));
2624514f5e3Sopenharmony_ci}
2634514f5e3Sopenharmony_ci
2644514f5e3Sopenharmony_ciGateRef CircuitBuilder::GetElementsKindByHClass(GateRef hClass)
2654514f5e3Sopenharmony_ci{
2664514f5e3Sopenharmony_ci    GateRef bitfieldOffset = IntPtr(JSHClass::BIT_FIELD_OFFSET);
2674514f5e3Sopenharmony_ci    GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
2684514f5e3Sopenharmony_ci    return Int32And(Int32LSR(bitfield,
2694514f5e3Sopenharmony_ci        Int32(JSHClass::ElementsKindBits::START_BIT)),
2704514f5e3Sopenharmony_ci        Int32((1LLU << JSHClass::ElementsKindBits::SIZE) - 1));
2714514f5e3Sopenharmony_ci}
2724514f5e3Sopenharmony_ci
2734514f5e3Sopenharmony_ciGateRef CircuitBuilder::HasConstructorByHClass(GateRef hClass)
2744514f5e3Sopenharmony_ci{
2754514f5e3Sopenharmony_ci    GateRef bitfieldOffset = Int32(JSHClass::BIT_FIELD_OFFSET);
2764514f5e3Sopenharmony_ci    GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
2774514f5e3Sopenharmony_ci    return NotEqual(Int32And(Int32LSR(bitfield,
2784514f5e3Sopenharmony_ci        Int32(JSHClass::HasConstructorBits::START_BIT)),
2794514f5e3Sopenharmony_ci        Int32((1LU << JSHClass::HasConstructorBits::SIZE) - 1)),
2804514f5e3Sopenharmony_ci        Int32(0));
2814514f5e3Sopenharmony_ci}
2824514f5e3Sopenharmony_ci
2834514f5e3Sopenharmony_ciGateRef CircuitBuilder::IsDictionaryElement(GateRef hClass)
2844514f5e3Sopenharmony_ci{
2854514f5e3Sopenharmony_ci    GateRef bitfieldOffset = Int32(JSHClass::BIT_FIELD_OFFSET);
2864514f5e3Sopenharmony_ci    GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
2874514f5e3Sopenharmony_ci    return NotEqual(Int32And(Int32LSR(bitfield,
2884514f5e3Sopenharmony_ci        Int32(JSHClass::DictionaryElementBits::START_BIT)),
2894514f5e3Sopenharmony_ci        Int32((1LU << JSHClass::DictionaryElementBits::SIZE) - 1)),
2904514f5e3Sopenharmony_ci        Int32(0));
2914514f5e3Sopenharmony_ci}
2924514f5e3Sopenharmony_ci
2934514f5e3Sopenharmony_ciGateRef CircuitBuilder::IsStableElements(GateRef hClass)
2944514f5e3Sopenharmony_ci{
2954514f5e3Sopenharmony_ci    GateRef bitfieldOffset = Int32(JSHClass::BIT_FIELD_OFFSET);
2964514f5e3Sopenharmony_ci    GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
2974514f5e3Sopenharmony_ci    return NotEqual(Int32And(Int32LSR(bitfield,
2984514f5e3Sopenharmony_ci        Int32(JSHClass::IsStableElementsBit::START_BIT)),
2994514f5e3Sopenharmony_ci        Int32((1LU << JSHClass::IsStableElementsBit::SIZE) - 1)),
3004514f5e3Sopenharmony_ci        Int32(0));
3014514f5e3Sopenharmony_ci}
3024514f5e3Sopenharmony_ci
3034514f5e3Sopenharmony_ciGateRef CircuitBuilder::HasConstructor(GateRef object)
3044514f5e3Sopenharmony_ci{
3054514f5e3Sopenharmony_ci    GateRef hClass = LoadHClass(object);
3064514f5e3Sopenharmony_ci    return HasConstructorByHClass(hClass);
3074514f5e3Sopenharmony_ci}
3084514f5e3Sopenharmony_ci
3094514f5e3Sopenharmony_ciGateRef CircuitBuilder::IsConstructor(GateRef object)
3104514f5e3Sopenharmony_ci{
3114514f5e3Sopenharmony_ci    GateRef hClass = LoadHClass(object);
3124514f5e3Sopenharmony_ci    GateRef bitfieldOffset = IntPtr(JSHClass::BIT_FIELD_OFFSET);
3134514f5e3Sopenharmony_ci    GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
3144514f5e3Sopenharmony_ci    // decode
3154514f5e3Sopenharmony_ci    return Int32NotEqual(
3164514f5e3Sopenharmony_ci        Int32And(Int32LSR(bitfield, Int32(JSHClass::ConstructorBit::START_BIT)),
3174514f5e3Sopenharmony_ci                 Int32((1LU << JSHClass::ConstructorBit::SIZE) - 1)),
3184514f5e3Sopenharmony_ci        Int32(0));
3194514f5e3Sopenharmony_ci}
3204514f5e3Sopenharmony_ci
3214514f5e3Sopenharmony_ciGateRef CircuitBuilder::IsClassConstructor(GateRef object)
3224514f5e3Sopenharmony_ci{
3234514f5e3Sopenharmony_ci    GateRef hClass = LoadHClass(object);
3244514f5e3Sopenharmony_ci    GateRef bitfieldOffset = Int32(JSHClass::BIT_FIELD_OFFSET);
3254514f5e3Sopenharmony_ci    GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
3264514f5e3Sopenharmony_ci    return IsClassConstructorWithBitField(bitfield);
3274514f5e3Sopenharmony_ci}
3284514f5e3Sopenharmony_ci
3294514f5e3Sopenharmony_ciGateRef CircuitBuilder::IsClassConstructorWithBitField(GateRef bitfield)
3304514f5e3Sopenharmony_ci{
3314514f5e3Sopenharmony_ci    auto classBitMask = 1LU << JSHClass::IsClassConstructorOrPrototypeBit::START_BIT;
3324514f5e3Sopenharmony_ci    auto ctorBitMask = 1LU << JSHClass::ConstructorBit::START_BIT;
3334514f5e3Sopenharmony_ci    auto mask = Int32(classBitMask | ctorBitMask);
3344514f5e3Sopenharmony_ci    auto classCtor = Int32And(bitfield, mask);
3354514f5e3Sopenharmony_ci    return Int32Equal(classCtor, mask);
3364514f5e3Sopenharmony_ci}
3374514f5e3Sopenharmony_ci
3384514f5e3Sopenharmony_ciGateRef CircuitBuilder::IsExtensible(GateRef object)
3394514f5e3Sopenharmony_ci{
3404514f5e3Sopenharmony_ci    GateRef hClass = LoadHClass(object);
3414514f5e3Sopenharmony_ci    GateRef bitfieldOffset = Int32(JSHClass::BIT_FIELD_OFFSET);
3424514f5e3Sopenharmony_ci    GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
3434514f5e3Sopenharmony_ci    return NotEqual(Int32And(Int32LSR(bitfield,
3444514f5e3Sopenharmony_ci        Int32(JSHClass::ExtensibleBit::START_BIT)),
3454514f5e3Sopenharmony_ci        Int32((1LU << JSHClass::ExtensibleBit::SIZE) - 1)),
3464514f5e3Sopenharmony_ci        Int32(0));
3474514f5e3Sopenharmony_ci}
3484514f5e3Sopenharmony_ci
3494514f5e3Sopenharmony_ciGateRef CircuitBuilder::IsClassPrototype(GateRef object)
3504514f5e3Sopenharmony_ci{
3514514f5e3Sopenharmony_ci    GateRef hClass = LoadHClass(object);
3524514f5e3Sopenharmony_ci    GateRef bitfieldOffset = IntPtr(JSHClass::BIT_FIELD_OFFSET);
3534514f5e3Sopenharmony_ci    GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
3544514f5e3Sopenharmony_ci    // decode
3554514f5e3Sopenharmony_ci    return IsClassPrototypeWithBitField(bitfield);
3564514f5e3Sopenharmony_ci}
3574514f5e3Sopenharmony_ci
3584514f5e3Sopenharmony_ciGateRef CircuitBuilder::IsClassPrototypeWithBitField(GateRef bitfield)
3594514f5e3Sopenharmony_ci{
3604514f5e3Sopenharmony_ci    auto classBitMask = 1LU << JSHClass::IsClassConstructorOrPrototypeBit::START_BIT;
3614514f5e3Sopenharmony_ci    auto ptBitMask = 1LU << JSHClass::IsPrototypeBit::START_BIT;
3624514f5e3Sopenharmony_ci    auto mask = Int32(classBitMask | ptBitMask);
3634514f5e3Sopenharmony_ci    auto classPt = Int32And(bitfield, mask);
3644514f5e3Sopenharmony_ci    return Int32Equal(classPt, mask);
3654514f5e3Sopenharmony_ci}
3664514f5e3Sopenharmony_ci
3674514f5e3Sopenharmony_ciGateRef CircuitBuilder::CreateWeakRef(GateRef x)
3684514f5e3Sopenharmony_ci{
3694514f5e3Sopenharmony_ci    return PtrAdd(x, IntPtr(JSTaggedValue::TAG_WEAK));
3704514f5e3Sopenharmony_ci}
3714514f5e3Sopenharmony_ci
3724514f5e3Sopenharmony_ciGateRef CircuitBuilder::LoadObjectFromWeakRef(GateRef x)
3734514f5e3Sopenharmony_ci{
3744514f5e3Sopenharmony_ci    return PtrAdd(x, IntPtr(-JSTaggedValue::TAG_WEAK));
3754514f5e3Sopenharmony_ci}
3764514f5e3Sopenharmony_ci
3774514f5e3Sopenharmony_ci// ctor is base but not builtin
3784514f5e3Sopenharmony_ciinline GateRef CircuitBuilder::IsBase(GateRef ctor)
3794514f5e3Sopenharmony_ci{
3804514f5e3Sopenharmony_ci    GateRef method = GetMethodFromFunction(ctor);
3814514f5e3Sopenharmony_ci    GateRef extraLiteralInfoOffset = IntPtr(Method::EXTRA_LITERAL_INFO_OFFSET);
3824514f5e3Sopenharmony_ci    GateRef bitfield = Load(VariableType::INT32(), method, extraLiteralInfoOffset);
3834514f5e3Sopenharmony_ci
3844514f5e3Sopenharmony_ci    GateRef kind = Int32And(Int32LSR(bitfield, Int32(MethodLiteral::FunctionKindBits::START_BIT)),
3854514f5e3Sopenharmony_ci                            Int32((1LU << MethodLiteral::FunctionKindBits::SIZE) - 1));
3864514f5e3Sopenharmony_ci    return Int32LessThanOrEqual(kind, Int32(static_cast<int32_t>(FunctionKind::CLASS_CONSTRUCTOR)));
3874514f5e3Sopenharmony_ci}
3884514f5e3Sopenharmony_ci
3894514f5e3Sopenharmony_ciinline GateRef CircuitBuilder::IsDerived(GateRef ctor)
3904514f5e3Sopenharmony_ci{
3914514f5e3Sopenharmony_ci    GateRef method = GetMethodFromFunction(ctor);
3924514f5e3Sopenharmony_ci    GateRef extraLiteralInfoOffset = IntPtr(Method::EXTRA_LITERAL_INFO_OFFSET);
3934514f5e3Sopenharmony_ci    GateRef bitfield = Load(VariableType::INT32(), method, extraLiteralInfoOffset);
3944514f5e3Sopenharmony_ci
3954514f5e3Sopenharmony_ci    GateRef kind = Int32And(Int32LSR(bitfield, Int32(MethodLiteral::FunctionKindBits::START_BIT)),
3964514f5e3Sopenharmony_ci                            Int32((1LU << MethodLiteral::FunctionKindBits::SIZE) - 1));
3974514f5e3Sopenharmony_ci    return Int32Equal(kind, Int32(static_cast<int32_t>(FunctionKind::DERIVED_CONSTRUCTOR)));
3984514f5e3Sopenharmony_ci}
3994514f5e3Sopenharmony_ci
4004514f5e3Sopenharmony_ciinline GateRef CircuitBuilder::GetMethodId(GateRef func)
4014514f5e3Sopenharmony_ci{
4024514f5e3Sopenharmony_ci    GateRef method = GetMethodFromFunction(func);
4034514f5e3Sopenharmony_ci    GateRef literalInfoOffset = IntPtr(Method::LITERAL_INFO_OFFSET);
4044514f5e3Sopenharmony_ci    GateRef literalInfo = Load(VariableType::INT64(), method, literalInfoOffset);
4054514f5e3Sopenharmony_ci    GateRef methodId = Int64And(Int64LSR(literalInfo, Int64(MethodLiteral::MethodIdBits::START_BIT)),
4064514f5e3Sopenharmony_ci        Int64((1LLU << MethodLiteral::MethodIdBits::SIZE) - 1));
4074514f5e3Sopenharmony_ci    return methodId;
4084514f5e3Sopenharmony_ci}
4094514f5e3Sopenharmony_ci
4104514f5e3Sopenharmony_ciinline GateRef CircuitBuilder::GetBuiltinsId(GateRef func)
4114514f5e3Sopenharmony_ci{
4124514f5e3Sopenharmony_ci    GateRef method = GetMethodFromFunction(func);
4134514f5e3Sopenharmony_ci    GateRef extraLiteralInfoOffset = IntPtr(Method::EXTRA_LITERAL_INFO_OFFSET);
4144514f5e3Sopenharmony_ci    GateRef extraLiteralInfo = Load(VariableType::INT64(), method, extraLiteralInfoOffset);
4154514f5e3Sopenharmony_ci    GateRef builtinsId = Int64And(Int64LSR(extraLiteralInfo, Int64(MethodLiteral::BuiltinIdBits::START_BIT)),
4164514f5e3Sopenharmony_ci        Int64((1LLU << MethodLiteral::BuiltinIdBits::SIZE) - 1));
4174514f5e3Sopenharmony_ci    return builtinsId;
4184514f5e3Sopenharmony_ci}
4194514f5e3Sopenharmony_ci}
4204514f5e3Sopenharmony_ci#endif  // ECMASCRIPT_COMPILER_HCR_CIRCUIT_BUILDER_H
421