• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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