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