1 /*
2  * Copyright (c) 2020-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 "wrapper/js.h"
17 #include "ace_mem_base.h"
18 #include "acelite_config.h"
19 #include "js_fwk_common.h"
20 
21 namespace OHOS {
22 namespace ACELite {
JSRelease(JSValue value)23 void JSRelease(JSValue value)
24 {
25     return jerry_release_value(value);
26 }
27 
Create(const char * const value)28 JSValue JSString::Create(const char * const value)
29 {
30     return jerry_create_string(reinterpret_cast<const jerry_char_t *>(value));
31 }
32 
Is(JSValue target)33 bool JSString::Is(JSValue target)
34 {
35     return jerry_value_is_string(target);
36 }
37 
Value(JSValue value)38 char *JSString::Value(JSValue value)
39 {
40     if (jerry_value_is_undefined(value)) {
41         return nullptr;
42     }
43 
44     jerry_value_t target;
45     if (jerry_value_is_symbol(value)) {
46         target = jerry_get_symbol_descriptive_string(value);
47     } else {
48         target = jerry_value_to_string(value);
49     }
50 
51     if (jerry_value_is_error(target)) {
52         jerry_release_value(target);
53         return nullptr;
54     }
55 
56     jerry_size_t size = jerry_get_string_size(target);
57     if (size == 0) {
58         jerry_release_value(target);
59         // return empty char instead of nullptr, so caller can free safely
60         char *emptyStr = static_cast<char *>(ace_malloc(sizeof(char)));
61         if (emptyStr == nullptr) {
62             return nullptr;
63         }
64         emptyStr[0] = '\0';
65         return emptyStr;
66     }
67     if (size >= UINT16_MAX) {
68         jerry_release_value(target);
69         return nullptr;
70     }
71     jerry_char_t *buffer = static_cast<jerry_char_t *>(ace_malloc(sizeof(jerry_char_t) * (size + 1)));
72     if (buffer == nullptr) {
73         jerry_release_value(target);
74         return nullptr;
75     }
76     jerry_size_t length = jerry_string_to_char_buffer(target, buffer, size);
77     if (length == 0) {
78         jerry_release_value(target);
79         ace_free(buffer);
80         buffer = nullptr;
81         return nullptr;
82     }
83     // end character
84     buffer[length] = '\0';
85     jerry_release_value(target);
86     return reinterpret_cast<char *>(buffer);
87 }
88 
Create(JSHandler handler)89 JSValue JSFunction::Create(JSHandler handler)
90 {
91     return jerry_create_external_function(handler);
92 }
93 
Call(JSValue func,JSValue context,JSValue args[],JSSize size)94 JSValue JSFunction::Call(JSValue func, JSValue context, JSValue args[], JSSize size)
95 {
96     return CallJSFunction(func, context, args, size);
97 }
98 
Is(JSValue target)99 bool JSFunction::Is(JSValue target)
100 {
101     return jerry_value_is_function(target);
102 }
103 
Create()104 JSValue JSObject::Create()
105 {
106     return jerry_create_object();
107 }
108 
Keys(JSValue target)109 JSValue JSObject::Keys(JSValue target)
110 {
111     return jerry_get_object_keys(target);
112 }
113 
Get(JSValue target,JSValue key)114 JSValue JSObject::Get(JSValue target, JSValue key)
115 {
116     return jerry_get_property(target, key);
117 }
118 
Get(JSValue target,const char * const prop)119 JSValue JSObject::Get(JSValue target, const char * const prop)
120 {
121     JSValue key = JSString::Create(prop);
122     JSValue value = jerry_get_property(target, key);
123     JSRelease(key);
124     return value;
125 }
126 
GetString(JSValue target,const char * const prop)127 char *JSObject::GetString(JSValue target, const char * const prop)
128 {
129     JSValue value = JSObject::Get(target, prop);
130     char *content = JSString::Value(value);
131     JSRelease(value);
132     return content;
133 }
GetNumber(JSValue target,const char * const prop)134 double JSObject::GetNumber(JSValue target, const char * const prop)
135 {
136     JSValue value = JSObject::Get(target, prop);
137     double number = JSNumber::Value(value);
138     JSRelease(value);
139     return number;
140 }
GetBoolean(JSValue target,const char * const prop)141 bool JSObject::GetBoolean(JSValue target, const char * const prop)
142 {
143     JSValue value = JSObject::Get(target, prop);
144     bool flag = JSBoolean::Value(value);
145     JSRelease(value);
146     return flag;
147 }
Set(JSValue target,const char * const prop,JSValue value)148 void JSObject::Set(JSValue target, const char * const prop, JSValue value)
149 {
150     JSValue key = JSString::Create(prop);
151     jerry_release_value(jerry_set_property(target, key, value));
152     JSRelease(key);
153 }
154 
SetString(JSValue target,const char * const prop,const char * const value)155 void JSObject::SetString(JSValue target, const char * const prop, const char * const value)
156 {
157     JSValue attr = JSString::Create(value);
158     JSObject::Set(target, prop, attr);
159     JSRelease(attr);
160 }
161 
SetNumber(JSValue target,const char * const prop,const double value)162 void JSObject::SetNumber(JSValue target, const char * const prop, const double value)
163 {
164     JSValue attr = JSNumber::Create(value);
165     JSObject::Set(target, prop, attr);
166     JSRelease(attr);
167 }
168 
SetBoolean(JSValue target,const char * const prop,const bool value)169 void JSObject::SetBoolean(JSValue target, const char * const prop, const bool value)
170 {
171     JSValue attr = JSBoolean::Create(value);
172     JSObject::Set(target, prop, attr);
173     JSRelease(attr);
174 }
175 
Set(JSValue target,const char * const prop,JSHandler handler)176 void JSObject::Set(JSValue target, const char * const prop, JSHandler handler)
177 {
178     JSValue func = JSFunction::Create(handler);
179     JSObject::Set(target, prop, func);
180     JSRelease(func);
181 }
182 
Del(JSValue target,const char * const prop)183 bool JSObject::Del(JSValue target, const char * const prop)
184 {
185     JSValue key = JSString::Create(prop);
186     bool result = jerry_delete_property(target, key);
187     JSRelease(key);
188     return result;
189 }
190 
GetNativePointer(JSValue target,void ** nativePointer)191 bool JSObject::GetNativePointer(JSValue target, void **nativePointer)
192 {
193     return jerry_get_object_native_pointer(target, nativePointer, nullptr);
194 }
195 
SetNativePointer(JSValue target,void * nativePointer)196 void JSObject::SetNativePointer(JSValue target, void *nativePointer)
197 {
198     return jerry_set_object_native_pointer(target, nativePointer, nullptr);
199 }
200 
DelNativePointer(JSValue target)201 bool JSObject::DelNativePointer(JSValue target)
202 {
203     return jerry_delete_object_native_pointer(target, nullptr);
204 }
205 
Call(JSValue target,const char * const prop,JSValue args[],JSSize size)206 JSValue JSObject::Call(JSValue target, const char * const prop, JSValue args[], JSSize size)
207 {
208     JSValue func = Get(target, prop);
209     JSValue value = JSFunction::Call(func, target, args, size);
210     JSRelease(func);
211     return value;
212 }
213 
Call(JSValue target,const char * const prop)214 JSValue JSObject::Call(JSValue target, const char * const prop)
215 {
216     return JSObject::Call(target, prop, nullptr, 0);
217 }
218 
Is(JSValue target)219 bool JSObject::Is(JSValue target)
220 {
221     return jerry_value_is_object(target);
222 }
223 
Has(JSValue target,const char * name)224 bool JSObject::Has(JSValue target, const char *name)
225 {
226     return jerryx_has_property_str(target, name);
227 }
228 
Get()229 JSValue JSGlobal::Get()
230 {
231     return jerry_get_global_object();
232 }
233 
Get(const char * const prop)234 JSValue JSGlobal::Get(const char * const prop)
235 {
236     JSValue global = JSGlobal::Get();
237     JSValue result = JSObject::Get(global, prop);
238     JSRelease(global);
239     return result;
240 }
241 
Set(const char * const prop,JSValue value)242 void JSGlobal::Set(const char * const prop, JSValue value)
243 {
244     JSValue global = JSGlobal::Get();
245     JSObject::Set(global, prop, value);
246     JSRelease(global);
247 }
248 
Del(const char * const props)249 void JSGlobal::Del(const char * const props)
250 {
251     JSValue global = JSGlobal::Get();
252     JSObject::Del(global, props);
253     JSRelease(global);
254 }
Call(const char * const prop,JSValue args[],JSSize size)255 JSValue JSGlobal::Call(const char * const prop, JSValue args[], JSSize size)
256 {
257     JSValue global = JSGlobal::Get();
258     JSValue result = JSObject::Call(global, prop, args, size);
259     JSRelease(global);
260     return result;
261 }
Call(const char * const prop)262 JSValue JSGlobal::Call(const char * const prop)
263 {
264     return JSGlobal::Call(prop, nullptr, 0);
265 }
266 
Create()267 JSValue JSUndefined::Create()
268 {
269     return jerry_create_undefined();
270 }
271 
Is(JSValue value)272 bool JSUndefined::Is(JSValue value)
273 {
274     return jerry_value_is_undefined(value);
275 }
276 
Create(double number)277 JSValue JSNumber::Create(double number)
278 {
279     return jerry_create_number(number);
280 }
281 
Is(JSValue target)282 bool JSNumber::Is(JSValue target)
283 {
284     return jerry_value_is_number(target);
285 }
286 
Value(JSValue value)287 double JSNumber::Value(JSValue value)
288 {
289     return jerry_get_number_value(value);
290 }
291 
Create(bool value)292 JSValue JSBoolean::Create(bool value)
293 {
294     return jerry_create_boolean(value);
295 }
296 
Is(JSValue target)297 bool JSBoolean::Is(JSValue target)
298 {
299     return jerry_value_is_boolean(target);
300 }
301 
Value(JSValue value)302 bool JSBoolean::Value(JSValue value)
303 {
304     return jerry_get_boolean_value(value);
305 }
306 
Create(uint32_t size)307 JSValue JSArray::Create(uint32_t size)
308 {
309     return jerry_create_array(size);
310 }
311 
Length(const JSValue array)312 uint32_t JSArray::Length(const JSValue array)
313 {
314     return jerry_get_array_length(array);
315 }
316 
Get(JSValue array,uint32_t index)317 JSValue JSArray::Get(JSValue array, uint32_t index)
318 {
319     return jerry_get_property_by_index(array, index);
320 }
321 
GetString(JSValue array,uint32_t index)322 char *JSArray::GetString(JSValue array, uint32_t index)
323 {
324     JSValue value = JSArray::Get(array, index);
325     char *content = JSString::Value(value);
326     JSRelease(value);
327     return content;
328 }
Map(JSValue array,JSValue func)329 JSValue JSArray::Map(JSValue array, JSValue func)
330 {
331     JSValue args[1] = {func};
332     return JSObject::Call(array, "map", args, 1);
333 }
334 
Push(JSValue array,JSValue element)335 void JSArray::Push(JSValue array, JSValue element)
336 {
337     JSValue args[1] = {element};
338     JSRelease(JSObject::Call(array, "push", args, 1));
339 }
Is(JSValue target)340 bool JSArray::Is(JSValue target)
341 {
342     return jerry_value_is_array(target);
343 }
Is(JSValue target)344 bool JSError::Is(JSValue target)
345 {
346     return jerry_value_is_error(target);
347 }
348 } // namespace ACELite
349 } // namespace OHOS
350