1 /*
2 * Copyright (c) 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 #include "ark_interop_napi.h"
17 #include "ark_interop_internal.h"
18 #include "ark_interop_log.h"
19
20 using namespace panda;
21 using namespace panda::ecmascript;
22
ARKTSInner_IsJSKey(ARKTS_Env env, ARKTS_Value value)23 ARKTS_INLINE bool ARKTSInner_IsJSKey(ARKTS_Env env, ARKTS_Value value)
24 {
25 auto tag = BIT_CAST(value, JSValueRef);
26 if (!tag.IsHeapObject()) {
27 return false;
28 }
29 tag = *P_CAST(value, JSValueRef*);
30 auto vm = P_CAST(env, EcmaVM*);
31 return tag.IsString(vm) || tag.IsSymbol(vm);
32 }
33
ARKTS_CreateObject(ARKTS_Env env)34 ARKTS_Value ARKTS_CreateObject(ARKTS_Env env)
35 {
36 ARKTS_ASSERT_P(env, "env is null");
37
38 auto vm = P_CAST(env, EcmaVM*);
39 auto result = ObjectRef::New(vm);
40
41 return BIT_CAST(result, ARKTS_Value);
42 }
43
ARKTS_IsHeapObject(ARKTS_Value value)44 bool ARKTS_IsHeapObject(ARKTS_Value value)
45 {
46 auto v = BIT_CAST(value, JSValueRef);
47 return v.IsHeapObject();
48 }
49
ARKTS_IsObject(ARKTS_Env env, ARKTS_Value value)50 bool ARKTS_IsObject(ARKTS_Env env, ARKTS_Value value)
51 {
52 auto v = BIT_CAST(value, JSValueRef);
53 if (!v.IsHeapObject()) {
54 return false;
55 }
56 v = *P_CAST(value, JSValueRef*);
57 auto vm = P_CAST(env, EcmaVM*);
58 return v.IsObject(vm);
59 }
60
ARKTS_HasOwnProperty(ARKTS_Env env, ARKTS_Value jobj, ARKTS_Value jkey)61 bool ARKTS_HasOwnProperty(ARKTS_Env env, ARKTS_Value jobj, ARKTS_Value jkey)
62 {
63 ARKTS_ASSERT_F(env, "env is null");
64 ARKTS_ASSERT_F(ARKTS_IsHeapObject(jobj), "object is not heap object");
65 ARKTS_ASSERT_F(ARKTSInner_IsJSKey(env, jkey), "key is not string or symbol");
66
67 auto vm = P_CAST(env, EcmaVM*);
68 auto object = BIT_CAST(jobj, Local<ObjectRef>);
69 auto key = BIT_CAST(jkey, Local<JSValueRef>);
70 return object->Has(vm, key);
71 }
72
ARKTS_EnumOwnProperties(ARKTS_Env env, ARKTS_Value jobj)73 ARKTS_Value ARKTS_EnumOwnProperties(ARKTS_Env env, ARKTS_Value jobj)
74 {
75 ARKTS_ASSERT_P(env, "env is null");
76 ARKTS_ASSERT_P(ARKTS_IsHeapObject(jobj), "object is not heap object");
77
78 auto vm = P_CAST(env, EcmaVM*);
79 auto object = BIT_CAST(jobj, Local<ObjectRef>);
80 auto result = object->GetOwnEnumerablePropertyNames(vm);
81
82 return BIT_CAST(result, ARKTS_Value);
83 }
84
ARKTS_DefineOwnProperty(ARKTS_Env env, ARKTS_Value jobj, ARKTS_Value jkey, ARKTS_Value jvalue, ARKTS_PropertyFlag attrs)85 void ARKTS_DefineOwnProperty(ARKTS_Env env, ARKTS_Value jobj, ARKTS_Value jkey, ARKTS_Value jvalue,
86 ARKTS_PropertyFlag attrs)
87 {
88 ARKTS_ASSERT_V(env, "env is null");
89 ARKTS_ASSERT_V(ARKTS_IsHeapObject(jobj), "object is not heap object");
90 ARKTS_ASSERT_V(ARKTSInner_IsJSKey(env, jkey), "key is not string or symbol");
91
92 auto vm = P_CAST(env, EcmaVM*);
93 auto object = BIT_CAST(jobj, Local<ObjectRef>);
94 auto key = BIT_CAST(jkey, Local<JSValueRef>);
95 auto value = ARKTS_ToHandle<JSValueRef>(jvalue);
96
97 PropertyAttribute attribute(value, attrs & N_WRITABLE, attrs & N_ENUMERABLE, attrs & N_CONFIGURABLE);
98 object->DefineProperty(vm, key, attribute);
99 }
100
ARKTS_DefineAccessors(ARKTS_Env env, ARKTS_Value jobj, ARKTS_Value jkey, ARKTS_Accessor accessor)101 void ARKTS_DefineAccessors(ARKTS_Env env, ARKTS_Value jobj, ARKTS_Value jkey, ARKTS_Accessor accessor)
102 {
103 ARKTS_ASSERT_V(env, "env is null");
104 ARKTS_ASSERT_V(ARKTS_IsHeapObject(jobj), "object is not heap object");
105 ARKTS_ASSERT_V(ARKTSInner_IsJSKey(env, jkey), "key is not string or symbol");
106
107 auto undefined = ARKTS_CreateUndefined();
108
109 ARKTS_ASSERT_V(accessor.setter == undefined || ARKTS_IsCallable(env, accessor.setter), "setter not callable");
110 ARKTS_ASSERT_V(accessor.getter == undefined || ARKTS_IsCallable(env, accessor.getter), "getter not callable");
111 ARKTS_ASSERT_V(accessor.getter != undefined || accessor.setter != undefined, "getter and setter is undefined");
112
113 auto vm = P_CAST(env, EcmaVM*);
114 auto object = BIT_CAST(jobj, Local<ObjectRef>);
115 auto key = BIT_CAST(jkey, Local<JSValueRef>);
116 auto handledUndef = ARKTS_ToHandle<JSValueRef>(undefined);
117 auto handledGetter = accessor.getter != undefined ? BIT_CAST(accessor.getter, Local<JSValueRef>) : handledUndef;
118 auto handledSetter = accessor.setter != undefined ? BIT_CAST(accessor.setter, Local<JSValueRef>) : handledUndef;
119
120 PropertyAttribute attribute(handledUndef,
121 accessor.attrs & N_WRITABLE,
122 accessor.attrs & N_ENUMERABLE,
123 accessor.attrs & N_CONFIGURABLE);
124 object->SetAccessorProperty(vm, key, handledGetter, handledSetter, attribute);
125 }
126
ARKTS_SetProperty(ARKTS_Env env, ARKTS_Value jobj, ARKTS_Value jkey, ARKTS_Value jvalue)127 void ARKTS_SetProperty(ARKTS_Env env, ARKTS_Value jobj, ARKTS_Value jkey, ARKTS_Value jvalue)
128 {
129 ARKTS_ASSERT_V(env, "env is null");
130 ARKTS_ASSERT_V(ARKTS_IsHeapObject(jobj), "object is not heap object");
131 ARKTS_ASSERT_V(ARKTSInner_IsJSKey(env, jkey), "key is not string or symbol");
132
133 auto vm = P_CAST(env, EcmaVM*);
134 auto object = BIT_CAST(jobj, Local<ObjectRef>);
135 auto key = BIT_CAST(jkey, Local<JSValueRef>);
136 auto value = ARKTS_ToHandle<JSValueRef>(jvalue);
137
138 object->Set(vm, key, value);
139 }
140
ARKTS_GetProperty(ARKTS_Env env, ARKTS_Value jobj, ARKTS_Value jkey)141 ARKTS_Value ARKTS_GetProperty(ARKTS_Env env, ARKTS_Value jobj, ARKTS_Value jkey)
142 {
143 ARKTS_ASSERT_P(env, "env is null");
144 ARKTS_ASSERT_P(ARKTS_IsHeapObject(jobj), "object is not heap object");
145 ARKTS_ASSERT_P(ARKTSInner_IsJSKey(env, jkey), "key is not string or symbol");
146
147 auto vm = P_CAST(env, EcmaVM*);
148 auto object = BIT_CAST(jobj, Local<ObjectRef>);
149 auto key = BIT_CAST(jkey, Local<JSValueRef>);
150
151 auto result = object->Get(vm, key);
152 return ARKTS_FromHandle(result);
153 }
154