1 /** 2 * Copyright (c) 2023-2024 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 PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_ETS_PROXY_SHARED_REFERENCE_H_ 17 #define PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_ETS_PROXY_SHARED_REFERENCE_H_ 18 19 #include "plugins/ets/runtime/interop_js/ets_proxy/ets_class_wrapper.h" 20 #include "plugins/ets/runtime/interop_js/ets_proxy/ets_object_reference.h" 21 22 #include <node_api.h> 23 24 namespace ark::mem { 25 class Reference; 26 } // namespace ark::mem 27 28 namespace ark::ets::interop::js { 29 class InteropCtx; 30 // Forward declarations to avoid cyclic deps. 31 inline mem::GlobalObjectStorage *RefstorFromInteropCtx(InteropCtx *ctx); 32 } // namespace ark::ets::interop::js 33 34 namespace ark::ets::interop::js::ets_proxy { 35 36 class SharedReference { 37 private: 38 using FlagsStart = BitField<uint8_t, 0, 0>; 39 40 public: 41 static constexpr size_t MAX_MARK_BITS = MarkWord::MarkWordRepresentation::HASH_SIZE; 42 43 // Actual state of shared object is contained in ETS 44 bool InitETSObject(InteropCtx *ctx, EtsObject *etsObject, napi_value jsObject, uint32_t refIdx); 45 46 // Actual state of shared object is contained in JS 47 bool InitJSObject(InteropCtx *ctx, EtsObject *etsObject, napi_value jsObject, uint32_t refIdx); 48 49 // State of object is shared between ETS and JS 50 bool InitHybridObject(InteropCtx *ctx, EtsObject *etsObject, napi_value jsObject, uint32_t refIdx); 51 52 using InitFn = decltype(&SharedReference::InitHybridObject); 53 GetEtsObject(InteropCtx * ctx)54 EtsObject *GetEtsObject(InteropCtx *ctx) const 55 { 56 ASSERT_MANAGED_CODE(); 57 ASSERT(etsRef_ != nullptr); 58 return EtsObject::FromCoreType(RefstorFromInteropCtx(ctx)->Get(etsRef_)); 59 } 60 GetJsObject(napi_env env)61 napi_value GetJsObject(napi_env env) const 62 { 63 napi_value jsValue; 64 NAPI_CHECK_FATAL(napi_get_reference_value(env, jsRef_, &jsValue)); 65 return jsValue; 66 } 67 ExtractMaybeReference(napi_env env,napi_value jsObject)68 static void *ExtractMaybeReference(napi_env env, napi_value jsObject) 69 { 70 void *data; 71 if (UNLIKELY(napi_unwrap(env, jsObject, &data) != napi_ok)) { 72 return nullptr; 73 } 74 return data; 75 } 76 HasReference(EtsObject * etsObject)77 static bool HasReference(EtsObject *etsObject) 78 { 79 return etsObject->IsHashed(); 80 } 81 ExtractMaybeIndex(EtsObject * etsObject)82 static uint32_t ExtractMaybeIndex(EtsObject *etsObject) 83 { 84 ASSERT(HasReference(etsObject)); 85 return etsObject->GetInteropHash(); 86 } 87 88 using FlagsType = FlagsStart::ValueType; 89 90 template <typename F> GetField()91 typename F::ValueType GetField() const 92 { 93 return F::Get(flags_); 94 } 95 96 template <typename F> SetField(typename F::ValueType value)97 void SetField(typename F::ValueType value) 98 { 99 F::Set(value, &flags_); 100 } 101 SetFlags(FlagsType flags)102 void SetFlags(FlagsType flags) 103 { 104 flags_ = flags; 105 } 106 107 using HasETSObject = FlagsStart::NextFlag; 108 using HasJSObject = FlagsStart::NextFlag; 109 110 static void FinalizeETSWeak(InteropCtx *ctx, EtsObject *cbarg); 111 112 private: 113 friend class SharedReferenceSanity; 114 static void FinalizeJSWeak(napi_env env, void *data, void *hint); 115 116 /* Possible values: 117 * ets_proxy: {instance, proxy} 118 * extensible ets_proxy: {proxy-base, extender-proxy} 119 * js_proxy: {proxy, instance} 120 * extensible js_proxy: {extender-proxy, proxy-base} 121 */ 122 mem::Reference *etsRef_ {}; 123 napi_ref jsRef_ {}; 124 125 FlagsType flags_ {}; 126 }; 127 128 } // namespace ark::ets::interop::js::ets_proxy 129 130 #endif // !PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_ETS_PROXY_SHARED_REFERENCE_H_ 131