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