• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "jerryscript_native_object.h"
17 
18 #include "jerryscript-ext/handler.h"
19 #include "jerryscript_native_array.h"
20 #include "jerryscript_native_function.h"
21 #include "utils/log.h"
22 
23 struct JerryScriptNativeObjectInfo {
24     NativeEngine* engine = nullptr;
25     NativeFinalize cb = nullptr;
26     void* data = nullptr;
27     void* hint = nullptr;
28 };
29 
30 namespace {
31 jerry_object_native_info_t g_freeCallback = {
__anon7924942d0202() 32     .free_cb = [](void* nativePointer) -> void {
33         auto info = (JerryScriptNativeObjectInfo*)nativePointer;
34         if (info != nullptr) {
35             info->cb(info->engine, info->data, info->hint);
36             delete info;
37         }
38     },
39 };
40 } // namespace
41 
JerryScriptNativeObject(JerryScriptNativeEngine * engine)42 JerryScriptNativeObject::JerryScriptNativeObject(JerryScriptNativeEngine* engine)
43     : JerryScriptNativeObject(engine, jerry_create_object())
44 {
45 }
46 
JerryScriptNativeObject(JerryScriptNativeEngine * engine,jerry_value_t value)47 JerryScriptNativeObject::JerryScriptNativeObject(JerryScriptNativeEngine* engine, jerry_value_t value)
48     : JerryScriptNativeValue(engine, value)
49 {
50 }
51 
~JerryScriptNativeObject()52 JerryScriptNativeObject::~JerryScriptNativeObject() {}
53 
ConvertToNativeBindingObject(void * engine,DetachCallback detach,AttachCallback attach,void * object,void * hint)54 bool JerryScriptNativeObject::ConvertToNativeBindingObject(
55     void* engine, DetachCallback detach, AttachCallback attach, void *object, void *hint)
56 {
57     return false;
58 }
59 
SetNativePointer(void * pointer,NativeFinalize cb,void * hint,NativeReference ** reference,size_t nativeBindingSize)60 void JerryScriptNativeObject::SetNativePointer(void* pointer, NativeFinalize cb,
61     void* hint, NativeReference** reference, [[maybe_unused]] size_t nativeBindingSize)
62 {
63     if (pointer == nullptr) {
64         jerry_delete_object_native_pointer(value_, &g_freeCallback);
65         return;
66     }
67 
68     JerryScriptNativeObjectInfo* info = new JerryScriptNativeObjectInfo;
69     if (info) {
70         info->engine = engine_;
71         info->cb = cb;
72         info->data = pointer;
73         info->hint = hint;
74     };
75 
76     jerry_set_object_native_pointer(value_, info, &g_freeCallback);
77 }
78 
GetNativePointer()79 void* JerryScriptNativeObject::GetNativePointer()
80 {
81     JerryScriptNativeObjectInfo* info = nullptr;
82     jerry_get_object_native_pointer(value_, (void**)&info, &g_freeCallback);
83     if (info != nullptr) {
84         return info->data;
85     } else {
86         return nullptr;
87     }
88 }
89 
SetNativeBindingPointer(void * enginePointer,void * objPointer,void * hint,void * detachData,void * attachData)90 void JerryScriptNativeObject::SetNativeBindingPointer(
91     void* enginePointer, void* objPointer, void* hint, void* detachData, void* attachData)
92 {
93 }
94 
GetNativeBindingPointer(uint32_t index)95 void* JerryScriptNativeObject::GetNativeBindingPointer(uint32_t index)
96 {
97     return nullptr;
98 }
99 
AddFinalizer(void * pointer,NativeFinalize cb,void * hint)100 void JerryScriptNativeObject::AddFinalizer(void* pointer, NativeFinalize cb, void* hint)
101 {
102     if (pointer == nullptr) {
103         jerry_delete_object_native_pointer(value_, &g_freeCallback);
104         return;
105     }
106 
107     JerryScriptNativeObjectInfo* info = new JerryScriptNativeObjectInfo;
108     if (info) {
109         info->engine = engine_;
110         info->cb = cb;
111         info->data = pointer;
112         info->hint = hint;
113     };
114 
115     jerry_set_object_native_pointer(value_, info, &g_freeCallback);
116 }
117 
GetInterface(int interfaceId)118 void* JerryScriptNativeObject::GetInterface(int interfaceId)
119 {
120     return (NativeObject::INTERFACE_ID == interfaceId) ? (NativeObject*)this : nullptr;
121 }
122 
GetPropertyNames()123 NativeValue* JerryScriptNativeObject::GetPropertyNames()
124 {
125     return new JerryScriptNativeArray(engine_, jerry_get_object_keys(value_));
126 }
127 
GetEnumerablePropertyNames()128 NativeValue* JerryScriptNativeObject::GetEnumerablePropertyNames()
129 {
130     return nullptr;
131 }
132 
GetPrototype()133 NativeValue* JerryScriptNativeObject::GetPrototype()
134 {
135     return JerryScriptNativeEngine::JerryValueToNativeValue(engine_, jerry_get_prototype(value_));
136 }
137 
DefineProperty(NativePropertyDescriptor propertyDescriptor)138 bool JerryScriptNativeObject::DefineProperty(NativePropertyDescriptor propertyDescriptor)
139 {
140     jerry_value_t propName = jerry_create_string_from_utf8((const unsigned char*)propertyDescriptor.utf8name);
141     jerry_property_descriptor_t prop = { 0 };
142 
143     jerry_init_property_descriptor_fields(&prop);
144 
145     prop.is_writable_defined = propertyDescriptor.attributes & NATIVE_WRITABLE;
146     prop.is_writable = propertyDescriptor.attributes & NATIVE_WRITABLE;
147 
148     prop.is_enumerable_defined = propertyDescriptor.attributes & NATIVE_ENUMERABLE;
149     prop.is_enumerable = propertyDescriptor.attributes & NATIVE_ENUMERABLE;
150 
151     prop.is_configurable_defined = propertyDescriptor.attributes & NATIVE_CONFIGURABLE;
152     prop.is_configurable = propertyDescriptor.attributes & NATIVE_CONFIGURABLE;
153 
154     if (propertyDescriptor.value != nullptr) {
155         prop.value = *propertyDescriptor.value;
156         prop.is_value_defined = true;
157     }
158 
159     if (propertyDescriptor.method != nullptr) {
160         prop.value = *(new JerryScriptNativeFunction(
161             engine_, propertyDescriptor.utf8name, propertyDescriptor.method, propertyDescriptor.data));
162         prop.is_value_defined = true;
163     }
164 
165     if (propertyDescriptor.getter != nullptr) {
166         prop.getter =
167             *(new JerryScriptNativeFunction(engine_, "getter", propertyDescriptor.getter, propertyDescriptor.data));
168         prop.is_get_defined = true;
169         prop.is_writable_defined = true;
170     }
171     if (propertyDescriptor.setter != nullptr) {
172         prop.setter =
173             *(new JerryScriptNativeFunction(engine_, "setter", propertyDescriptor.setter, propertyDescriptor.data));
174         prop.is_set_defined = true;
175         prop.is_writable_defined = true;
176     }
177 
178     jerry_value_t returnValue = jerry_define_own_property(value_, propName, &prop);
179     jerry_release_value(returnValue);
180     jerry_release_value(propName);
181 
182     return true;
183 }
184 
SetProperty(NativeValue * key,NativeValue * value)185 bool JerryScriptNativeObject::SetProperty(NativeValue* key, NativeValue* value)
186 {
187     jerry_value_t returnValue = jerry_set_property(value_, *key, *value);
188     jerry_release_value(returnValue);
189     return true;
190 }
191 
GetProperty(NativeValue * key)192 NativeValue* JerryScriptNativeObject::GetProperty(NativeValue* key)
193 {
194     jerry_value_t returnValue = jerry_get_property(value_, *key);
195     return JerryScriptNativeEngine::JerryValueToNativeValue(engine_, returnValue);
196 }
197 
HasProperty(NativeValue * key)198 bool JerryScriptNativeObject::HasProperty(NativeValue* key)
199 {
200     jerry_value_t returnValue = jerry_has_property(value_, *key);
201     bool result = jerry_value_to_boolean(returnValue);
202     jerry_release_value(returnValue);
203     return result;
204 }
205 
DeleteProperty(NativeValue * key)206 bool JerryScriptNativeObject::DeleteProperty(NativeValue* key)
207 {
208     return jerry_delete_property(value_, *key);
209 }
210 
SetProperty(const char * name,NativeValue * value)211 bool JerryScriptNativeObject::SetProperty(const char* name, NativeValue* value)
212 {
213     jerry_value_t returnValue = jerryx_set_property_str(value_, name, *value);
214     jerry_release_value(returnValue);
215     return true;
216 }
217 
GetProperty(const char * name)218 NativeValue* JerryScriptNativeObject::GetProperty(const char* name)
219 {
220     jerry_value_t returnValue = jerryx_get_property_str(value_, name);
221     return JerryScriptNativeEngine::JerryValueToNativeValue(engine_, returnValue);
222 }
223 
HasProperty(const char * name)224 bool JerryScriptNativeObject::HasProperty(const char* name)
225 {
226     bool result = jerryx_has_property_str(value_, name);
227     return result;
228 }
229 
DeleteProperty(const char * name)230 bool JerryScriptNativeObject::DeleteProperty(const char* name)
231 {
232     jerry_value_t key = jerry_create_string_from_utf8((const unsigned char*)name);
233     bool result = jerry_delete_property(value_, key);
234     jerry_release_value(key);
235     return result;
236 }
237 
SetPrivateProperty(const char * name,NativeValue * value)238 bool JerryScriptNativeObject::SetPrivateProperty(const char* name, NativeValue* value)
239 {
240     bool result = false;
241     jerry_value_t key = jerry_create_string_from_utf8((const unsigned char*)name);
242     result = jerry_set_property(value_, key, *value);
243     jerry_release_value(key);
244     return result;
245 }
246 
GetPrivateProperty(const char * name)247 NativeValue* JerryScriptNativeObject::GetPrivateProperty(const char* name)
248 {
249     jerry_value_t result = 0;
250     jerry_value_t key = jerry_create_string_from_utf8((const unsigned char*)name);
251     result = jerry_get_property(value_, key);
252     jerry_release_value(key);
253     return JerryScriptNativeEngine::JerryValueToNativeValue(engine_, result);
254 }
255 
HasPrivateProperty(const char * name)256 bool JerryScriptNativeObject::HasPrivateProperty(const char* name)
257 {
258     jerry_value_t key = jerry_create_string_from_utf8((const unsigned char*)name);
259     jerry_value_t returnValue = jerry_has_property(value_, key);
260     bool result = jerry_value_to_boolean(returnValue);
261     jerry_release_value(returnValue);
262     jerry_release_value(key);
263     return result;
264 }
265 
DeletePrivateProperty(const char * name)266 bool JerryScriptNativeObject::DeletePrivateProperty(const char* name)
267 {
268     bool result = false;
269     jerry_value_t key = jerry_create_string_from_utf8((const unsigned char*)name);
270     result = jerry_delete_property(value_, key);
271     jerry_release_value(key);
272     return result;
273 }
274 
Freeze()275 void JerryScriptNativeObject::Freeze()
276 {
277     jerry_freeze(value_);
278 }
279 
Seal()280 void JerryScriptNativeObject::Seal()
281 {
282     jerry_seal(value_);
283 }
284 
GetAllPropertyNames(napi_key_collection_mode keyMode,napi_key_filter keyFilter,napi_key_conversion keyConversion)285 NativeValue* JerryScriptNativeObject::GetAllPropertyNames(
286     napi_key_collection_mode keyMode, napi_key_filter keyFilter, napi_key_conversion keyConversion)
287 {
288 #if JERRY_API_MINOR_VERSION > 3 // jerryscript2.3: 3,  jerryscript2.4: 4
289     jerry_property_filter_t filter = JERRY_PROPERTY_FILTER_ALL;
290 
291     if (keyFilter & napi_key_writable) {
292         filter = static_cast<jerry_property_filter_t>(filter | JERRY_PROPERTY_FILTER_EXLCUDE_NON_WRITABLE);
293     }
294     if (keyFilter & napi_key_enumerable) {
295         filter = static_cast<jerry_property_filter_t>(filter | JERRY_PROPERTY_FILTER_EXLCUDE_NON_ENUMERABLE);
296     }
297     if (keyFilter & napi_key_configurable) {
298         filter = static_cast<jerry_property_filter_t>(filter | JERRY_PROPERTY_FILTER_EXLCUDE_NON_CONFIGURABLE);
299     }
300     if (keyFilter & napi_key_skip_strings) {
301         filter = static_cast<jerry_property_filter_t>(filter | JERRY_PROPERTY_FILTER_EXLCUDE_STRINGS);
302     }
303     if (keyFilter & napi_key_skip_symbols) {
304         filter = static_cast<jerry_property_filter_t>(filter | JERRY_PROPERTY_FILTER_EXLCUDE_SYMBOLS);
305     }
306 
307     switch (keyConversion) {
308         case napi_key_keep_numbers:
309             filter = static_cast<jerry_property_filter_t>(filter | JERRY_PROPERTY_FILTER_EXLCUDE_INTEGER_INDICES);
310             break;
311         case napi_key_numbers_to_strings:
312             filter = static_cast<jerry_property_filter_t>(filter | JERRY_PROPERTY_FILTER_INTEGER_INDICES_AS_NUMBER);
313             break;
314         default:
315             break;
316     }
317 
318     jerry_value_t result = jerry_object_get_property_names(value_, filter);
319 
320     return JerryScriptNativeEngine::JerryValueToNativeValue(engine_, result);
321 #else
322     return nullptr;
323 #endif
324 }
325 
AssociateTypeTag(NapiTypeTag * typeTag)326 bool JerryScriptNativeObject::AssociateTypeTag(NapiTypeTag* typeTag)
327 {
328 #if JERRY_API_MINOR_VERSION > 3 // jerryscript2.3: 3,  jerryscript2.4: 4
329     const char name[] = "ACENAPI_TYPETAG";
330     bool result = false;
331     bool hasPribate = false;
332     hasPribate = HasPrivateProperty(name);
333     if (!hasPribate) {
334         jerry_value_t key = jerry_create_string_from_utf8((const unsigned char*)name);
335         uint32_t size = 2;
336         jerry_value_t value = jerry_create_bigint((uint64_t*)typeTag, size, false);
337 
338         result = jerry_set_property(value_, key, value);
339         jerry_release_value(key);
340     }
341     return result;
342 #else
343     return true;
344 #endif
345 }
346 
CheckTypeTag(NapiTypeTag * typeTag)347 bool JerryScriptNativeObject::CheckTypeTag(NapiTypeTag* typeTag)
348 {
349 #if JERRY_API_MINOR_VERSION > 3 // jerryscript2.3: 3,  jerryscript2.4: 4
350     const char name[] = "ACENAPI_TYPETAG";
351     bool result = false;
352     result = HasPrivateProperty(name);
353     if (result) {
354         jerry_value_t key = jerry_create_string_from_utf8((const unsigned char*)name);
355         jerry_value_t value = jerry_get_property(value_, key);
356         jerry_release_value(key);
357 
358         NapiTypeTag typeTagOut;
359         uint32_t size = 2;
360         bool sign = false;
361 
362         jerry_get_bigint_digits(value, (uint64_t*)(&typeTagOut), size, &sign);
363         jerry_release_value(value);
364 
365         if ((typeTagOut.lower != typeTag->lower) || (typeTagOut.upper != typeTag->upper)) {
366             result = false;
367         }
368     }
369     return result;
370 #else
371     return true;
372 #endif
373 }
374