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