1 /* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef ECMASCRIPT_COMPILER_OBJECT_OPERATOR_STUB_BUILDER_H 17 #define ECMASCRIPT_COMPILER_OBJECT_OPERATOR_STUB_BUILDER_H 18 19 #include "ecmascript/compiler/stub_builder.h" 20 #include "ecmascript/object_operator.h" 21 #include "ecmascript/compiler/circuit_builder_helper.h" 22 23 namespace panda::ecmascript::kungfu { 24 class ObjectOperatorStubBuilder : public StubBuilder { 25 public: ObjectOperatorStubBuilder(StubBuilder * parent,GateRef globalEnv)26 ObjectOperatorStubBuilder(StubBuilder *parent, GateRef globalEnv) 27 : StubBuilder(parent, globalEnv) {} 28 ~ObjectOperatorStubBuilder() override = default; 29 NO_MOVE_SEMANTIC(ObjectOperatorStubBuilder); 30 NO_COPY_SEMANTIC(ObjectOperatorStubBuilder); GenerateCircuit()31 void GenerateCircuit() override {} 32 33 enum class LookupKind { 34 KIND_HAS_PROPERTY = 0, 35 KIND_GET_PROPERTY, 36 KIND_SET_PROPERTY, 37 }; 38 39 enum class StartLookupType { 40 HAS_RECEIVER = 0, 41 NO_RECEIVER, 42 }; 43 44 struct ObjectOperatorOptions { 45 LookupKind lookupKind = LookupKind::KIND_HAS_PROPERTY; 46 OperatorType type = OperatorType::PROTOTYPE_CHAIN; 47 }; 48 49 struct ObjectOperatorResult { 50 Variable *metaData { nullptr }; // INT_32 51 Variable *elemKey { nullptr }; // INT_32 52 Variable *propKey { nullptr }; // JS_ANY 53 Variable *index { nullptr }; // INT_32 54 Variable *value { nullptr }; // JS_ANY 55 Variable *holder { nullptr }; // JS_ANY 56 Variable *receiver { nullptr }; // JS_ANY 57 Variable *attr { nullptr }; // INT_64 58 GetHolderObjectOperatorResult59 GateRef GetHolder() const 60 { 61 return holder->ReadVariable(); 62 } 63 GetReceiverObjectOperatorResult64 GateRef GetReceiver() const 65 { 66 return receiver->ReadVariable(); 67 } 68 GetMetaDataObjectOperatorResult69 GateRef GetMetaData() const 70 { 71 return metaData->ReadVariable(); 72 } 73 GetPropKeyObjectOperatorResult74 GateRef GetPropKey() const 75 { 76 return propKey->ReadVariable(); 77 } 78 GetElemKeyObjectOperatorResult79 GateRef GetElemKey() const 80 { 81 return elemKey->ReadVariable(); 82 } 83 GetIndexObjectOperatorResult84 GateRef GetIndex() const 85 { 86 return index->ReadVariable(); 87 } 88 GetValueObjectOperatorResult89 GateRef GetValue() const 90 { 91 return value->ReadVariable(); 92 } 93 GetAttrObjectOperatorResult94 GateRef GetAttr() const 95 { 96 return attr->ReadVariable(); 97 } 98 }; 99 100 void TryFastHandleStringKey(GateRef key, Variable *propKey, Variable *elemKey, 101 Label *isProperty, Label *isElement, Label *tryFailed); 102 void HandleKey(GateRef glue, GateRef key, Variable *propKey, 103 Variable *elemKey, Label *isProperty, Label *isElement, 104 Label *hasException, GateRef hir = Circuit::NullGate()); 105 template <bool keyIsElement> 106 void UpdateHolder(GateRef glue, ObjectOperatorResult &results, GateRef key, 107 Label *holderUpdated); 108 template <StartLookupType startLookupType> 109 void StartLookup(GateRef glue, GateRef key, Label *exit, 110 const ObjectOperatorOptions &options, 111 ObjectOperatorResult &results, 112 GateRef hir = Circuit::NullGate()); 113 114 void InitializeOperatorResults(ObjectOperatorResult &result); 115 void FinalizeOperatorResults(ObjectOperatorResult &result); 116 117 GateRef IsFound(Variable *metaData); 118 GateRef IsElement(ObjectOperatorResult &opResult); 119 GateRef IsAccessorDescriptor(ObjectOperatorResult &opResult); 120 121 private: 122 static constexpr int32_t MAX_META_DATA = 0x7FFFFFFF; 123 static constexpr int32_t IS_FOUND_BIT = 0x1; 124 static constexpr int32_t IS_ON_PROTOTYPE_BIT = 0x2; 125 static constexpr int32_t HAS_RECEIVER_BIT = 0x3; 126 127 void SetFound(ObjectOperatorResult &opResult); 128 void SetFound(ObjectOperatorResult &opResult, GateRef value, GateRef index, GateRef attr); 129 void SetIsOnProtoType(ObjectOperatorResult &opResult); 130 void SetHasReceiver(ObjectOperatorResult &opResult); 131 132 template <bool keyIsElement> 133 void CheckValidIndexOrKeyIsLength(GateRef glue, GateRef key, GateRef holder, GateRef receiver, 134 Label *checkSucc, Label *checkFail); 135 136 template <bool keyIsElement> 137 void LookupProperty(GateRef glue, GateRef key, Label *exit, 138 const ObjectOperatorOptions &options, ObjectOperatorResult &results, 139 GateRef hir = Circuit::NullGate()); 140 141 template <bool keyIsElement> 142 void TryLookupInProtoChain(GateRef glue, GateRef key, Label *exit, 143 const ObjectOperatorOptions &options, ObjectOperatorResult &results, 144 GateRef hir = Circuit::NullGate()); 145 void LookupPropertyInlinedProps(GateRef glue, GateRef obj, GateRef key, Label *exit, 146 const ObjectOperatorOptions &options, ObjectOperatorResult &results, 147 GateRef hir = Circuit::NullGate()); 148 void LookupElementInlinedProps(GateRef glue, GateRef obj, GateRef elementIdx, Label *exit, 149 const ObjectOperatorOptions &options, ObjectOperatorResult &results, 150 GateRef hir = Circuit::NullGate()); 151 }; 152 } // namespace panda::ecmascript::kungfu 153 #endif // ECMASCRIPT_COMPILER_OBJECT_OPERATOR_STUB_BUILDER_H 154