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.IsNumber()) {
27 return true;
28 }
29 if (!tag.IsHeapObject()) {
30 return false;
31 }
32 tag = *P_CAST(value, JSValueRef*);
33 auto vm = P_CAST(env, EcmaVM*);
34 return tag.IsString(vm) || tag.IsSymbol(vm);
35 }
36
ARKTS_CreateObject(ARKTS_Env env)37 ARKTS_Value ARKTS_CreateObject(ARKTS_Env env)
38 {
39 ARKTS_ASSERT_P(env, "env is null");
40
41 auto vm = P_CAST(env, EcmaVM*);
42 auto result = ObjectRef::New(vm);
43
44 return ARKTS_FromHandle(result);
45 }
46
ARKTS_IsHeapObject(ARKTS_Value value)47 bool ARKTS_IsHeapObject(ARKTS_Value value)
48 {
49 auto v = BIT_CAST(value, JSValueRef);
50 return v.IsHeapObject();
51 }
52
ARKTS_IsObject(ARKTS_Env env,ARKTS_Value value)53 bool ARKTS_IsObject(ARKTS_Env env, ARKTS_Value value)
54 {
55 ARKTS_ASSERT_F(env, "env is null");
56 auto v = BIT_CAST(value, JSValueRef);
57 if (!v.IsHeapObject()) {
58 return false;
59 }
60 auto handle = BIT_CAST(value, Local<JSValueRef>);
61 auto vm = P_CAST(env, EcmaVM*);
62 return handle->IsObject(vm);
63 }
64
ARKTS_HasOwnProperty(ARKTS_Env env,ARKTS_Value jobj,ARKTS_Value jkey)65 bool ARKTS_HasOwnProperty(ARKTS_Env env, ARKTS_Value jobj, ARKTS_Value jkey)
66 {
67 ARKTS_ASSERT_F(env, "env is null");
68 ARKTS_ASSERT_F(ARKTS_IsHeapObject(jobj), "object is not heap object");
69 ARKTS_ASSERT_F(ARKTSInner_IsJSKey(env, jkey), "key is not number、string or symbol");
70
71 auto vm = P_CAST(env, EcmaVM*);
72 auto object = BIT_CAST(jobj, Local<ObjectRef>);
73 auto key = ARKTS_ToHandle<JSValueRef>(jkey);
74 return object->Has(vm, key);
75 }
76
ARKTS_EnumOwnProperties(ARKTS_Env env,ARKTS_Value jobj)77 ARKTS_Value ARKTS_EnumOwnProperties(ARKTS_Env env, ARKTS_Value jobj)
78 {
79 ARKTS_ASSERT_P(env, "env is null");
80 ARKTS_ASSERT_P(ARKTS_IsHeapObject(jobj), "object is not heap object");
81
82 auto vm = P_CAST(env, EcmaVM*);
83 auto object = BIT_CAST(jobj, Local<ObjectRef>);
84 auto result = object->GetOwnEnumerablePropertyNames(vm);
85
86 return ARKTS_FromHandle(result);
87 }
88
ARKTS_DefineOwnProperty(ARKTS_Env env,ARKTS_Value jobj,ARKTS_Value jkey,ARKTS_Value jvalue,ARKTS_PropertyFlag attrs)89 void ARKTS_DefineOwnProperty(ARKTS_Env env, ARKTS_Value jobj, ARKTS_Value jkey, ARKTS_Value jvalue,
90 ARKTS_PropertyFlag attrs)
91 {
92 ARKTS_ASSERT_V(env, "env is null");
93 ARKTS_ASSERT_V(ARKTS_IsHeapObject(jobj), "object is not heap object");
94 ARKTS_ASSERT_V(ARKTSInner_IsJSKey(env, jkey), "key is not number、string or symbol");
95
96 auto vm = P_CAST(env, EcmaVM*);
97 auto object = BIT_CAST(jobj, Local<ObjectRef>);
98 auto key = ARKTS_ToHandle<JSValueRef>(jkey);
99 auto value = ARKTS_ToHandle<JSValueRef>(jvalue);
100
101 PropertyAttribute attribute(value, attrs & N_WRITABLE, attrs & N_ENUMERABLE, attrs & N_CONFIGURABLE);
102 object->DefineProperty(vm, key, attribute);
103 }
104
ARKTS_DefineOwnPropertyV2(ARKTS_Env env,ARKTS_Value jobj,ARKTS_Value jkey,ARKTS_Value jvalue,ARKTS_PropertyFlag attrs)105 bool ARKTS_DefineOwnPropertyV2(ARKTS_Env env, ARKTS_Value jobj, ARKTS_Value jkey, ARKTS_Value jvalue,
106 ARKTS_PropertyFlag attrs)
107 {
108 ARKTS_ASSERT_F(env, "env is null");
109 ARKTS_ASSERT_F(ARKTS_IsHeapObject(jobj), "object is not heap object");
110 ARKTS_ASSERT_F(ARKTSInner_IsJSKey(env, jkey), "key is not number、string or symbol");
111
112 auto vm = P_CAST(env, EcmaVM*);
113 auto object = BIT_CAST(jobj, Local<ObjectRef>);
114 auto key = ARKTS_ToHandle<JSValueRef>(jkey);
115 auto value = ARKTS_ToHandle<JSValueRef>(jvalue);
116
117 PropertyAttribute attribute(value, attrs & N_WRITABLE, attrs & N_ENUMERABLE, attrs & N_CONFIGURABLE);
118 auto result = object->DefineProperty(vm, key, attribute);
119 ARKTSInner_ReportJSErrors(env, false);
120 return result;
121 }
122
ARKTS_DefineAccessors(ARKTS_Env env,ARKTS_Value jobj,ARKTS_Value jkey,ARKTS_Accessor accessor)123 void ARKTS_DefineAccessors(ARKTS_Env env, ARKTS_Value jobj, ARKTS_Value jkey, ARKTS_Accessor accessor)
124 {
125 ARKTS_ASSERT_V(env, "env is null");
126 ARKTS_ASSERT_V(ARKTS_IsHeapObject(jobj), "object is not heap object");
127 ARKTS_ASSERT_V(ARKTSInner_IsJSKey(env, jkey), "key is not number、string or symbol");
128
129 auto undefined = ARKTS_CreateUndefined();
130
131 ARKTS_ASSERT_V(accessor.setter == undefined || ARKTS_IsCallable(env, accessor.setter), "setter not callable");
132 ARKTS_ASSERT_V(accessor.getter == undefined || ARKTS_IsCallable(env, accessor.getter), "getter not callable");
133 ARKTS_ASSERT_V(accessor.getter != undefined || accessor.setter != undefined, "getter and setter is undefined");
134
135 auto vm = P_CAST(env, EcmaVM*);
136 auto object = BIT_CAST(jobj, Local<ObjectRef>);
137 auto key = ARKTS_ToHandle<JSValueRef>(jkey);
138 auto handledUndef = ARKTS_ToHandle<JSValueRef>(undefined);
139 auto handledGetter = accessor.getter != undefined ? BIT_CAST(accessor.getter, Local<JSValueRef>) : handledUndef;
140 auto handledSetter = accessor.setter != undefined ? BIT_CAST(accessor.setter, Local<JSValueRef>) : handledUndef;
141
142 PropertyAttribute attribute(handledUndef,
143 accessor.attrs & N_WRITABLE,
144 accessor.attrs & N_ENUMERABLE,
145 accessor.attrs & N_CONFIGURABLE);
146 object->SetAccessorProperty(vm, key, handledGetter, handledSetter, attribute);
147 }
148
ARKTS_DefineAccessorsV2(ARKTS_Env env,ARKTS_Value jobj,ARKTS_Value jkey,ARKTS_Accessor accessor)149 bool ARKTS_DefineAccessorsV2(ARKTS_Env env, ARKTS_Value jobj, ARKTS_Value jkey, ARKTS_Accessor accessor)
150 {
151 ARKTS_ASSERT_F(env, "env is null");
152 ARKTS_ASSERT_F(ARKTS_IsHeapObject(jobj), "object is not heap object");
153 ARKTS_ASSERT_F(ARKTSInner_IsJSKey(env, jkey), "key is not number、string or symbol");
154
155 auto undefined = ARKTS_CreateUndefined();
156
157 ARKTS_ASSERT_F(accessor.setter == undefined || ARKTS_IsCallable(env, accessor.setter), "setter not callable");
158 ARKTS_ASSERT_F(accessor.getter == undefined || ARKTS_IsCallable(env, accessor.getter), "getter not callable");
159 ARKTS_ASSERT_F(accessor.getter != undefined || accessor.setter != undefined, "getter and setter is undefined");
160
161 auto vm = P_CAST(env, EcmaVM*);
162 auto object = BIT_CAST(jobj, Local<ObjectRef>);
163 auto key = ARKTS_ToHandle<JSValueRef>(jkey);
164 auto handledUndef = ARKTS_ToHandle<JSValueRef>(undefined);
165 auto handledGetter = accessor.getter != undefined ? BIT_CAST(accessor.getter, Local<JSValueRef>) : handledUndef;
166 auto handledSetter = accessor.setter != undefined ? BIT_CAST(accessor.setter, Local<JSValueRef>) : handledUndef;
167
168 PropertyAttribute attribute(handledUndef,
169 accessor.attrs & N_WRITABLE,
170 accessor.attrs & N_ENUMERABLE,
171 accessor.attrs & N_CONFIGURABLE);
172 auto result = object->SetAccessorProperty(vm, key, handledGetter, handledSetter, attribute);
173 ARKTSInner_ReportJSErrors(env, false);
174 return result;
175 }
176
ARKTS_SetProperty(ARKTS_Env env,ARKTS_Value jobj,ARKTS_Value jkey,ARKTS_Value jvalue)177 void ARKTS_SetProperty(ARKTS_Env env, ARKTS_Value jobj, ARKTS_Value jkey, ARKTS_Value jvalue)
178 {
179 ARKTS_ASSERT_V(env, "env is null");
180 ARKTS_ASSERT_V(ARKTS_IsHeapObject(jobj), "object is not heap object");
181 ARKTS_ASSERT_V(ARKTSInner_IsJSKey(env, jkey), "key is not number、string or symbol");
182
183 auto vm = P_CAST(env, EcmaVM*);
184 auto object = BIT_CAST(jobj, Local<ObjectRef>);
185 auto key = ARKTS_ToHandle<JSValueRef>(jkey);
186 auto value = ARKTS_ToHandle<JSValueRef>(jvalue);
187
188 object->Set(vm, key, value);
189 }
190
ARKTS_GetProperty(ARKTS_Env env,ARKTS_Value jobj,ARKTS_Value jkey)191 ARKTS_Value ARKTS_GetProperty(ARKTS_Env env, ARKTS_Value jobj, ARKTS_Value jkey)
192 {
193 ARKTS_ASSERT_P(env, "env is null");
194 ARKTS_ASSERT_P(ARKTS_IsHeapObject(jobj), "object is not heap object");
195 ARKTS_ASSERT_P(ARKTSInner_IsJSKey(env, jkey), "key is not number、string or symbol");
196
197 auto vm = P_CAST(env, EcmaVM*);
198 auto object = BIT_CAST(jobj, Local<ObjectRef>);
199 auto key = ARKTS_ToHandle<JSValueRef>(jkey);
200
201 auto result = object->Get(vm, key);
202 return ARKTS_FromHandle(result);
203 }
204