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 #include "ecmascript/serializer/inter_op_value_serializer.h"
17
18 namespace panda::ecmascript {
SerializeObjectImpl(TaggedObject * object,bool isWeak)19 void InterOpValueSerializer::SerializeObjectImpl(TaggedObject *object, bool isWeak)
20 {
21 if (TrySerializeInterOpObject(object, isWeak)) {
22 return;
23 }
24 ValueSerializer::SerializeObjectImpl(object, isWeak);
25 }
26
TrySerializeInterOpObject(TaggedObject * object,bool isWeak)27 bool InterOpValueSerializer::TrySerializeInterOpObject(TaggedObject *object, bool isWeak)
28 {
29 [[maybe_unused]] EcmaHandleScope handleScope(thread_);
30 JSType type = object->GetClass()->GetObjectType();
31 JSHandle<JSTaggedValue> target(thread_, object);
32 switch (type) {
33 case JSType::JS_OBJECT:
34 case JSType::JS_FUNCTION:
35 break;
36 case JSType::JS_PROXY:
37 target = JSProxy::Cast(object)->GetSourceTarget(thread_);
38 break;
39 default:
40 return false;
41 }
42 JSHandle<JSObject> objHandle(target);
43 JSHandle<JSTaggedValue> keyHandle = thread_->GlobalConstants()->GetHandledProxyNapiWrapperString();
44 // Otherwise, before lookup key in JSObject will intern string, which may trigger GC
45 ASSERT(EcmaStringAccessor(keyHandle->GetTaggedObject()).IsInternString());
46 JSTaggedValue xRef = JSObject::GetProperty(thread_, objHandle, keyHandle).GetValue().GetTaggedValue();
47 if (xRef.IsUndefined()) {
48 return false;
49 }
50
51 SerializeInterOpObjectImpl(object, JSObject::Cast(xRef.GetTaggedObject()), isWeak);
52 return true;
53 }
54
SerializeInterOpObjectImpl(TaggedObject * proxyObject,JSObject * xRefObject,bool isWeak)55 void InterOpValueSerializer::SerializeInterOpObjectImpl(TaggedObject *proxyObject, JSObject *xRefObject, bool isWeak)
56 {
57 if (isWeak) {
58 data_->WriteEncodeFlag(EncodeFlag::WEAK);
59 }
60 if (SerializeReference(proxyObject)) {
61 return;
62 }
63
64 JSTaggedValue nativePointer = xRefObject->GetNativePointerByIndex(thread_, 0);
65 if (UNLIKELY(nativePointer.IsUndefined())) {
66 LOG_ECMA(ERROR) << "InterOpValueSerializer: SerializeInterOpObject XRefObject field is not JSNativePointer";
67 notSupport_ = true;
68 return;
69 }
70
71 ASSERT(nativePointer.IsNativePointer());
72 panda::JSNApi::XRefBindingInfo *info = reinterpret_cast<panda::JSNApi::XRefBindingInfo *>(
73 JSNativePointer::Cast(nativePointer.GetTaggedObject())->GetData());
74 if (info == nullptr) {
75 LOG_ECMA(ERROR) << "InterOpValueSerializer: SerializeInterOpObject XRefBindingInfo is nullptr";
76 notSupport_ = true;
77 return;
78 }
79
80 AttachXRefFunc attachXRefFunc = reinterpret_cast<AttachXRefFunc>(info->attachXRefFunc);
81 void *attachXRefData = info->attachXRefData;
82 data_->WriteEncodeFlag(EncodeFlag::XREF_BINDING_OBJECT);
83 data_->WriteJSTaggedType(reinterpret_cast<JSTaggedType>(attachXRefFunc));
84 data_->WriteJSTaggedType(reinterpret_cast<JSTaggedType>(attachXRefData));
85 }
86 } // namespace panda::ecmascript
87
88