• 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_engine.h"
17 
18 #include "jerryscript-ext/handler.h"
19 #include "jerryscript_native_deferred.h"
20 #include "jerryscript_native_reference.h"
21 
22 #include "native_value/jerryscript_native_array.h"
23 #include "native_value/jerryscript_native_array_buffer.h"
24 #include "native_value/jerryscript_native_big_int.h"
25 #include "native_value/jerryscript_native_boolean.h"
26 #include "native_value/jerryscript_native_buffer.h"
27 #include "native_value/jerryscript_native_data_view.h"
28 #include "native_value/jerryscript_native_date.h"
29 #include "native_value/jerryscript_native_external.h"
30 #include "native_value/jerryscript_native_function.h"
31 #include "native_value/jerryscript_native_number.h"
32 #include "native_value/jerryscript_native_object.h"
33 #include "native_value/jerryscript_native_string.h"
34 #include "native_value/jerryscript_native_typed_array.h"
35 #include "utils/log.h"
36 
JerryScriptNativeEngine(void * jsEngine)37 JerryScriptNativeEngine::JerryScriptNativeEngine(void* jsEngine) : NativeEngine(jsEngine)
38 {
39     HILOG_INFO("JerryScriptNativeEngine::JerryScriptNativeEngine begin");
40     jerry_add_external();
41     jerry_value_t global = jerry_get_global_object();
42     jerry_value_t require = jerry_create_external_function([](const jerry_value_t function, const jerry_value_t thisVal,
43                                                                const jerry_value_t args[],
44                                                                const jerry_length_t argc) -> jerry_value_t {
45         JerryScriptNativeEngine* that = nullptr;
46         jerry_get_object_native_pointer(function, (void**)&that, nullptr);
47         jerry_value_t result = jerry_create_undefined();
48 
49         if (!(argc >= 1 && jerry_value_is_string(args[0]))) {
50             return result;
51         }
52 
53         jerry_size_t moduleNameSize = jerry_get_utf8_string_size(args[0]);
54 
55         if (moduleNameSize == 0) {
56             return result;
57         }
58 
59         char* moduleName = new char[moduleNameSize + 1] { 0 };
60         uint32_t moduleNameLength = jerry_string_to_char_buffer(args[0], (jerry_char_t*)moduleName, moduleNameSize + 1);
61         moduleName[moduleNameLength] = '\0';
62         NativeModule* module = that->GetModuleManager()->LoadNativeModule(moduleName, nullptr, false);
63 
64         if (module != nullptr) {
65             NativeValue* value = that->CreateObject();
66             module->registerCallback(that, value);
67             result = jerry_acquire_value(*value);
68         }
69         return result;
70     });
71     jerry_set_object_native_pointer(require, this, nullptr);
72     jerryx_set_property_str(global, "requireNapi", require);
73 
74     jerry_release_value(require);
75     jerry_release_value(global);
76     HILOG_INFO("JerryScriptNativeEngine::JerryScriptNativeEngine end");
77     Init();
78 }
79 
~JerryScriptNativeEngine()80 JerryScriptNativeEngine::~JerryScriptNativeEngine()
81 {
82     Deinit();
83 }
84 
Loop(LoopMode mode,bool needSync)85 void JerryScriptNativeEngine::Loop(LoopMode mode, bool needSync)
86 {
87     NativeEngine::Loop(mode, needSync);
88     jerry_value_t retVal = jerry_run_all_enqueued_jobs();
89     jerry_release_value(retVal);
90 }
91 
GetGlobal()92 NativeValue* JerryScriptNativeEngine::GetGlobal()
93 {
94     return new JerryScriptNativeObject(this, jerry_get_global_object());
95 }
96 
CreateNull()97 NativeValue* JerryScriptNativeEngine::CreateNull()
98 {
99     return new JerryScriptNativeValue(this, jerry_create_null());
100 }
101 
CreateUndefined()102 NativeValue* JerryScriptNativeEngine::CreateUndefined()
103 {
104     return new JerryScriptNativeValue(this, jerry_create_undefined());
105 }
106 
CreateBoolean(bool value)107 NativeValue* JerryScriptNativeEngine::CreateBoolean(bool value)
108 {
109     return new JerryScriptNativeBoolean(this, value);
110 }
111 
CreateNumber(int32_t value)112 NativeValue* JerryScriptNativeEngine::CreateNumber(int32_t value)
113 {
114     return new JerryScriptNativeNumber(this, (double)value);
115 }
116 
CreateNumber(uint32_t value)117 NativeValue* JerryScriptNativeEngine::CreateNumber(uint32_t value)
118 {
119     return new JerryScriptNativeNumber(this, (double)value);
120 }
121 
CreateNumber(int64_t value)122 NativeValue* JerryScriptNativeEngine::CreateNumber(int64_t value)
123 {
124     return new JerryScriptNativeNumber(this, (double)value);
125 }
126 
CreateNumber(double value)127 NativeValue* JerryScriptNativeEngine::CreateNumber(double value)
128 {
129     return new JerryScriptNativeNumber(this, (double)value);
130 }
131 
CreateString(const char * value,size_t length)132 NativeValue* JerryScriptNativeEngine::CreateString(const char* value, size_t length)
133 {
134     return new JerryScriptNativeString(this, value, length);
135 }
136 
CreateSymbol(NativeValue * value)137 NativeValue* JerryScriptNativeEngine::CreateSymbol(NativeValue* value)
138 {
139     return new JerryScriptNativeValue(this, jerry_create_symbol(*value));
140 }
141 
CreateExternal(void * value,NativeFinalize callback,void * hint)142 NativeValue* JerryScriptNativeEngine::CreateExternal(void* value, NativeFinalize callback, void* hint)
143 {
144     return new JerryScriptNativeExternal(this, value, callback, hint);
145 }
146 
CreateObject()147 NativeValue* JerryScriptNativeEngine::CreateObject()
148 {
149     return new JerryScriptNativeObject(this);
150 }
151 
CreateFunction(const char * name,size_t length,NativeCallback cb,void * value)152 NativeValue* JerryScriptNativeEngine::CreateFunction(const char* name, size_t length, NativeCallback cb, void* value)
153 {
154     return new JerryScriptNativeFunction(this, name, cb, value);
155 }
156 
CreateArray(size_t length)157 NativeValue* JerryScriptNativeEngine::CreateArray(size_t length)
158 {
159     return new JerryScriptNativeArray(this, (int)length);
160 }
161 
CreateArrayBuffer(void ** value,size_t length)162 NativeValue* JerryScriptNativeEngine::CreateArrayBuffer(void** value, size_t length)
163 {
164     return new JerryScriptNativeArrayBuffer(this, value, length);
165 }
166 
CreateArrayBufferExternal(void * value,size_t length,NativeFinalize cb,void * hint)167 NativeValue* JerryScriptNativeEngine::CreateArrayBufferExternal(
168     void* value, size_t length, NativeFinalize cb, void* hint)
169 {
170     return new JerryScriptNativeArrayBuffer(this, (unsigned char*)value, length, cb, hint);
171 }
172 
CreateBuffer(void ** value,size_t length)173 NativeValue* JerryScriptNativeEngine::CreateBuffer(void** value, size_t length)
174 {
175     return new JerryScriptNativeBuffer(this, (uint8_t**)value, length);
176 }
177 
CreateBufferCopy(void ** value,size_t length,const void * data)178 NativeValue* JerryScriptNativeEngine::CreateBufferCopy(void** value, size_t length, const void* data)
179 {
180     return new JerryScriptNativeBuffer(this, (uint8_t**)value, length, (uint8_t*)data);
181 }
182 
CreateBufferExternal(void * value,size_t length,NativeFinalize cb,void * hint)183 NativeValue* JerryScriptNativeEngine::CreateBufferExternal(void* value, size_t length, NativeFinalize cb, void* hint)
184 {
185     return new JerryScriptNativeBuffer(this, (uint8_t*)value, length, cb, hint);
186 }
187 
CreateTypedArray(NativeTypedArrayType type,NativeValue * value,size_t length,size_t offset)188 NativeValue* JerryScriptNativeEngine::CreateTypedArray(
189     NativeTypedArrayType type, NativeValue* value, size_t length, size_t offset)
190 {
191     return new JerryScriptNativeTypedArray(this, type, value, length, offset);
192 }
193 
CreateDataView(NativeValue * value,size_t length,size_t offset)194 NativeValue* JerryScriptNativeEngine::CreateDataView(NativeValue* value, size_t length, size_t offset)
195 {
196     return new JerryScriptNativeDataView(this, value, length, offset);
197 }
198 
CreatePromise(NativeDeferred ** deferred)199 NativeValue* JerryScriptNativeEngine::CreatePromise(NativeDeferred** deferred)
200 {
201     jerry_value_t promise = jerry_create_promise();
202     *deferred = new JerryScriptNativeDeferred(promise);
203     return new JerryScriptNativeValue(this, promise);
204 }
205 
CreateError(NativeValue * code,NativeValue * message)206 NativeValue* JerryScriptNativeEngine::CreateError(NativeValue* code, NativeValue* message)
207 {
208     jerry_value_t jerror = 0;
209 
210     jerror = jerry_create_error_sz(JERRY_ERROR_COMMON, nullptr, 0);
211     jerror = jerry_get_value_from_error(jerror, true);
212 
213     if (message) {
214         jerry_value_t jreturn = jerryx_set_property_str(jerror, "message", *message);
215         jerry_release_value(jreturn);
216     }
217     if (code) {
218         jerry_value_t jreturn = jerryx_set_property_str(jerror, "code", *code);
219         jerry_release_value(jreturn);
220     }
221     jerror = jerry_create_error_from_value(jerror, true);
222 
223     return new JerryScriptNativeObject(this, jerror);
224 }
225 
CallFunction(NativeValue * thisVar,NativeValue * function,NativeValue * const * argv,size_t argc)226 NativeValue* JerryScriptNativeEngine::CallFunction(
227     NativeValue* thisVar, NativeValue* function, NativeValue* const* argv, size_t argc)
228 {
229     jerry_value_t* args = nullptr;
230     if (argc > 0) {
231         args = new jerry_value_t[argc];
232         for (size_t i = 0; i < argc; i++) {
233             if (argv[i] == nullptr) {
234                 args[i] = jerry_create_undefined();
235             } else {
236                 args[i] = *argv[i];
237             }
238         }
239     }
240     NativeScope* scope = scopeManager_->Open();
241     jerry_value_t result = jerry_call_function(*function, thisVar ? *thisVar : 0, (const jerry_value_t*)args, argc);
242     scopeManager_->Close(scope);
243     if (args != nullptr) {
244         delete[] args;
245     }
246 
247     if (jerry_value_is_error(result)) {
248         jerry_value_t errorObj = jerry_get_value_from_error(result, true);
249         jerry_value_t propName = jerry_create_string_from_utf8((const jerry_char_t*)"message");
250         jerry_property_descriptor_t propDescriptor = { 0 };
251         jerry_get_own_property_descriptor(errorObj, propName, &propDescriptor);
252         jerry_value_t setResult = jerry_set_property(errorObj, propName, propDescriptor.value);
253         jerry_release_value(propName);
254         jerry_release_value(setResult);
255         Throw(JerryValueToNativeValue(this, errorObj));
256         return JerryValueToNativeValue(this, jerry_create_undefined());
257     } else {
258         return JerryValueToNativeValue(this, result);
259     }
260 }
261 
RunScript(NativeValue * script)262 NativeValue* JerryScriptNativeEngine::RunScript(NativeValue* script)
263 {
264     NativeString* pscript = (NativeString*)script->GetInterface(NativeString::INTERFACE_ID);
265 
266     size_t length = pscript->GetLength();
267     if (length == 0) {
268         return nullptr;
269     }
270     char* strScript = new char[length] { 0 };
271     pscript->GetCString(strScript, length, &length);
272     jerry_value_t result = jerry_eval((const unsigned char*)strScript, pscript->GetLength(), JERRY_PARSE_NO_OPTS);
273     if (jerry_value_is_error(result)) {
274         result = jerry_get_value_from_error(result, true);
275     }
276     delete[] strScript;
277     return JerryValueToNativeValue(this, result);
278 }
279 
RunBufferScript(std::vector<uint8_t> & buffer)280 NativeValue* JerryScriptNativeEngine::RunBufferScript(std::vector<uint8_t>& buffer)
281 {
282     return nullptr;
283 }
284 
RunActor(std::vector<uint8_t> & buffer,const char * descriptor)285 NativeValue* JerryScriptNativeEngine::RunActor(std::vector<uint8_t>& buffer, const char *descriptor)
286 {
287     return RunBufferScript(buffer);
288 }
289 
DefineClass(const char * name,NativeCallback callback,void * data,const NativePropertyDescriptor * properties,size_t length)290 NativeValue* JerryScriptNativeEngine::DefineClass(
291     const char* name, NativeCallback callback, void* data, const NativePropertyDescriptor* properties, size_t length)
292 {
293     auto classConstructor = new JerryScriptNativeFunction(this, name, callback, data);
294     auto classProto = new JerryScriptNativeObject(this);
295 
296     jerryx_set_property_str(*classConstructor, "prototype", *classProto);
297 
298     for (size_t i = 0; i < length; ++i) {
299         if (properties[i].attributes & NATIVE_STATIC) {
300             classConstructor->DefineProperty(properties[i]);
301         } else {
302             classProto->DefineProperty(properties[i]);
303         }
304     }
305     return classConstructor;
306 }
307 
CreateInstance(NativeValue * constructor,NativeValue * const * argv,size_t argc)308 NativeValue* JerryScriptNativeEngine::CreateInstance(NativeValue* constructor, NativeValue* const* argv, size_t argc)
309 {
310     return JerryValueToNativeValue(this, jerry_construct_object(*constructor, (const jerry_value_t*)argv, argc));
311 }
312 
CreateReference(NativeValue * value,uint32_t initialRefcount,NativeFinalize callback,void * data,void * hint)313 NativeReference* JerryScriptNativeEngine::CreateReference(NativeValue* value, uint32_t initialRefcount,
314     NativeFinalize callback, void* data, void* hint)
315 {
316     return new JerryScriptNativeReference(this, value, initialRefcount, callback, data, hint);
317 }
318 
Throw(NativeValue * error)319 bool JerryScriptNativeEngine::Throw(NativeValue* error)
320 {
321     this->lastException_ = error;
322     return true;
323 }
324 
Throw(NativeErrorType type,const char * code,const char * message)325 bool JerryScriptNativeEngine::Throw(NativeErrorType type, const char* code, const char* message)
326 {
327     jerry_value_t jerror = 0;
328     jerry_error_t jtype;
329     switch (type) {
330         case NATIVE_COMMON_ERROR:
331             jtype = JERRY_ERROR_COMMON;
332             break;
333         case NATIVE_TYPE_ERROR:
334             jtype = JERRY_ERROR_TYPE;
335             break;
336         case NATIVE_RANGE_ERROR:
337             jtype = JERRY_ERROR_RANGE;
338             break;
339         default:
340             return false;
341     }
342     jerror = jerry_create_error(jtype, (const unsigned char*)message);
343     jerror = jerry_get_value_from_error(jerror, true);
344     if (code) {
345         jerry_value_t jcode = jerry_create_string_from_utf8((const unsigned char*)code);
346         jerryx_set_property_str(jerror, "code", jcode);
347     }
348     jerror = jerry_create_error_from_value(jerror, true);
349     this->lastException_ = new JerryScriptNativeObject(this, jerror);
350     return true;
351 }
352 
CreateRuntime()353 void* JerryScriptNativeEngine::CreateRuntime()
354 {
355     return nullptr;
356 }
357 
Serialize(NativeEngine * context,NativeValue * value,NativeValue * transfer)358 NativeValue* JerryScriptNativeEngine::Serialize(NativeEngine* context, NativeValue* value,
359     NativeValue* transfer)
360 {
361     return nullptr;
362 }
363 
Deserialize(NativeEngine * context,NativeValue * recorder)364 NativeValue* JerryScriptNativeEngine::Deserialize(NativeEngine* context, NativeValue* recorder)
365 {
366     return nullptr;
367 }
368 
GetExceptionForWorker() const369 ExceptionInfo* JerryScriptNativeEngine::GetExceptionForWorker() const
370 {
371     return nullptr;
372 }
373 
LoadModule(NativeValue * str,const std::string & fileName)374 NativeValue* JerryScriptNativeEngine::LoadModule(NativeValue* str, const std::string& fileName)
375 {
376     return nullptr;
377 }
378 
JerryValueToNativeValue(JerryScriptNativeEngine * engine,jerry_value_t value)379 NativeValue* JerryScriptNativeEngine::JerryValueToNativeValue(JerryScriptNativeEngine* engine, jerry_value_t value)
380 {
381     NativeValue* result = nullptr;
382     switch (jerry_value_get_type(value)) {
383         case JERRY_TYPE_NONE:
384             result = new JerryScriptNativeValue(engine, value);
385             break;
386         case JERRY_TYPE_UNDEFINED:
387             result = new JerryScriptNativeValue(engine, value);
388             break;
389         case JERRY_TYPE_NULL:
390             result = new JerryScriptNativeValue(engine, value);
391             break;
392         case JERRY_TYPE_BOOLEAN:
393             result = new JerryScriptNativeBoolean(engine, value);
394             break;
395         case JERRY_TYPE_NUMBER:
396             result = new JerryScriptNativeNumber(engine, value);
397             break;
398         case JERRY_TYPE_STRING:
399             result = new JerryScriptNativeString(engine, value);
400             break;
401         case JERRY_TYPE_OBJECT:
402             if (jerry_value_is_array(value)) {
403                 result = new JerryScriptNativeArray(engine, value);
404             } else if (jerry_value_is_arraybuffer(value)) {
405                 result = new JerryScriptNativeArrayBuffer(engine, value);
406             } else if (jerry_value_is_dataview(value)) {
407                 result = new JerryScriptNativeDataView(engine, value);
408             } else if (jerry_value_is_typedarray(value)) {
409                 result = new JerryScriptNativeTypedArray(engine, value);
410             } else if (jerry_value_is_external(value)) {
411                 result = new JerryScriptNativeExternal(engine, value);
412             } else if (jerry_is_date(value)) {
413                 result = new JerryScriptNativeDate(engine, value);
414             } else {
415                 result = new JerryScriptNativeObject(engine, value);
416             }
417             break;
418         case JERRY_TYPE_FUNCTION:
419             result = new JerryScriptNativeFunction(engine, value);
420             break;
421         case JERRY_TYPE_ERROR:
422             result = new JerryScriptNativeObject(engine, value);
423             break;
424         case JERRY_TYPE_SYMBOL:
425             result = new JerryScriptNativeValue(engine, value);
426             break;
427         case JERRY_TYPE_BIGINT:
428 #if JERRY_API_MINOR_VERSION > 3
429                 result = new JerryScriptNativeBigInt(engine, value);
430                 break;
431 #endif
432         default:;
433     }
434     return result;
435 }
436 
ValueToNativeValue(JSValueWrapper & value)437 NativeValue* JerryScriptNativeEngine::ValueToNativeValue(JSValueWrapper& value)
438 {
439     jerry_value_t jerryValue = value;
440     return JerryValueToNativeValue(this, jerryValue);
441 }
442 
TriggerFatalException(NativeValue * error)443 bool JerryScriptNativeEngine::TriggerFatalException(NativeValue* error)
444 {
445 
446     return false;
447 }
448 
AdjustExternalMemory(int64_t ChangeInBytes,int64_t * AdjustedValue)449 bool JerryScriptNativeEngine::AdjustExternalMemory(int64_t ChangeInBytes, int64_t* AdjustedValue)
450 {
451     HILOG_INFO("L1: napi_adjust_external_memory not supported!");
452     return true;
453 }
454 
CreateDate(double time)455 NativeValue* JerryScriptNativeEngine::CreateDate(double time)
456 {
457     jerry_value_t value = jerry_strict_date(time);
458     return JerryValueToNativeValue(this, value);
459 }
460 
SetPromiseRejectCallback(NativeReference * rejectCallbackRef,NativeReference * checkCallbackRef)461 void JerryScriptNativeEngine::SetPromiseRejectCallback(NativeReference* rejectCallbackRef,
462                                                        NativeReference* checkCallbackRef) {}
463 
464 
CreateBigWords(int sign_bit,size_t word_count,const uint64_t * words)465 NativeValue* JerryScriptNativeEngine::CreateBigWords(int sign_bit, size_t word_count, const uint64_t* words)
466 {
467 #if JERRY_API_MINOR_VERSION > 3 // jerryscript2.3: 3,  jerryscript2.4: 4
468     constexpr int bigintMod = 2;
469     bool sign = false;
470     if ((sign_bit % bigintMod) == 1) {
471         sign = true;
472     }
473     uint32_t size = (uint32_t)word_count;
474 
475     jerry_value_t jerryValue = jerry_create_bigint(words, size, sign);
476 
477     return new JerryScriptNativeBigInt(this, jerryValue);
478 #else
479     return nullptr;
480 #endif
481 }
482 
CreateBigInt(int64_t value)483 NativeValue* JerryScriptNativeEngine::CreateBigInt(int64_t value)
484 {
485     return new JerryScriptNativeBigInt(this, value);
486 }
487 
CreateBigInt(uint64_t value)488 NativeValue* JerryScriptNativeEngine::CreateBigInt(uint64_t value)
489 {
490 #if JERRY_API_MINOR_VERSION > 3 // jerryscript2.3: 3,  jerryscript2.4: 4
491     return new JerryScriptNativeBigInt(this, value, true);
492 #else
493     return nullptr;
494 #endif
495 }
496 
CreateString16(const char16_t * value,size_t length)497 NativeValue* JerryScriptNativeEngine::CreateString16(const char16_t* value, size_t length)
498 {
499 #if JERRY_API_MINOR_VERSION > 3 // jerryscript2.3: 3,  jerryscript2.4: 4
500     return new JerryScriptNativeString(this, value, length);
501 #else
502     return nullptr;
503 #endif
504 }
505