mirror of
https://github.com/openharmony/ace_napi.git
synced 2026-07-01 15:07:43 -04:00
Signed-off-by: zhongjianfei <zhongjianfei@huawei.com> Change-Id: Ic43ae2175fca333394f68d670ee60343cf63c278
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//ark/js_runtime/js_runtime_config.gni")
|
||||
import("//build/ohos.gni")
|
||||
|
||||
config("ace_napi_quickjs_config") {
|
||||
@@ -22,6 +23,14 @@ config("ace_napi_quickjs_config") {
|
||||
]
|
||||
}
|
||||
|
||||
config("ace_napi_ark_config") {
|
||||
include_dirs = [
|
||||
"//foundation/ace/napi",
|
||||
"//third_party/libuv/include",
|
||||
"//utils/native/base/include",
|
||||
]
|
||||
}
|
||||
|
||||
config("ace_napi_config") {
|
||||
include_dirs = [
|
||||
"//foundation/ace/napi",
|
||||
@@ -113,9 +122,62 @@ ohos_shared_library("ace_napi_quickjs") {
|
||||
part_name = "napi"
|
||||
}
|
||||
|
||||
ohos_shared_library("ace_napi_ark") {
|
||||
public_configs = [ ":ace_napi_ark_config" ]
|
||||
|
||||
configs = [ "//ark/js_runtime:ark_jsruntime_public_config" ]
|
||||
|
||||
include_dirs = [
|
||||
"//foundation/ace/napi",
|
||||
"//foundation/ace/napi/native_engine",
|
||||
"//foundation/ace/napi/native_engine/impl/ark",
|
||||
"//third_party/libuv/include",
|
||||
"//utils/native/base/include",
|
||||
]
|
||||
|
||||
defines = [ "USE_ARK_ENGINE" ]
|
||||
|
||||
if (target_cpu == "arm64") {
|
||||
defines += [ "APP_USE_ARM64" ]
|
||||
} else if (target_cpu == "arm") {
|
||||
defines += [ "APP_USE_ARM" ]
|
||||
}
|
||||
|
||||
sources = [
|
||||
"native_engine/impl/ark/ark_native_deferred.cpp",
|
||||
"native_engine/impl/ark/ark_native_engine.cpp",
|
||||
"native_engine/impl/ark/ark_native_reference.cpp",
|
||||
"native_engine/impl/ark/native_value/ark_native_array.cpp",
|
||||
"native_engine/impl/ark/native_value/ark_native_array_buffer.cpp",
|
||||
"native_engine/impl/ark/native_value/ark_native_boolean.cpp",
|
||||
"native_engine/impl/ark/native_value/ark_native_data_view.cpp",
|
||||
"native_engine/impl/ark/native_value/ark_native_external.cpp",
|
||||
"native_engine/impl/ark/native_value/ark_native_function.cpp",
|
||||
"native_engine/impl/ark/native_value/ark_native_number.cpp",
|
||||
"native_engine/impl/ark/native_value/ark_native_object.cpp",
|
||||
"native_engine/impl/ark/native_value/ark_native_string.cpp",
|
||||
"native_engine/impl/ark/native_value/ark_native_typed_array.cpp",
|
||||
"native_engine/impl/ark/native_value/ark_native_value.cpp",
|
||||
]
|
||||
deps = [
|
||||
":ace_napi",
|
||||
"//ark/js_runtime:libark_jsruntime",
|
||||
]
|
||||
|
||||
if (is_standard_system) {
|
||||
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
|
||||
} else {
|
||||
external_deps = [ "hilog:libhilog" ]
|
||||
}
|
||||
|
||||
subsystem_name = "ace"
|
||||
part_name = "napi"
|
||||
}
|
||||
|
||||
group("napi_packages") {
|
||||
deps = [
|
||||
":ace_napi",
|
||||
":ace_napi_ark",
|
||||
":ace_napi_quickjs",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<!-- OAT(OSS Audit Tool) configuration guide:
|
||||
basedir: Root dir, the basedir + project path is the real source file location.
|
||||
licensefile:
|
||||
1.If the project don't have "LICENSE" in root dir, please define all the license files in this project in , OAT will check license files according to this rule.
|
||||
|
||||
tasklist(only for batch mode):
|
||||
1. task: Define oat check thread, each task will start a new thread.
|
||||
2. task name: Only an name, no practical effect.
|
||||
3. task policy: Default policy for projects under this task, this field is required and the specified policy must defined in policylist.
|
||||
4. task filter: Default filefilter for projects under this task, this field is required and the specified filefilter must defined in filefilterlist.
|
||||
5. task project: Projects to be checked, the path field define the source root dir of the project.
|
||||
|
||||
|
||||
policyList:
|
||||
1. policy: All policyitems will be merged to default OAT.xml rules, the name of policy doesn't affect OAT check process.
|
||||
2. policyitem: The fields type, name, path, desc is required, and the fields rule, group, filefilter is optional,the default value is:
|
||||
<policyitem type="" name="" path="" desc="" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
|
||||
3. policyitem type:
|
||||
"compatibility" is used to check license compatibility in the specified path;
|
||||
"license" is used to check source license header in the specified path;
|
||||
"copyright" is used to check source copyright header in the specified path;
|
||||
"import" is used to check source dependency in the specified path, such as import ... ,include ...
|
||||
"filetype" is used to check file type in the specified path, supported file types: archive, binary
|
||||
"filename" is used to check whether the specified file exists in the specified path(support projectroot in default OAT.xml), supported file names: LICENSE, README, README.OpenSource
|
||||
|
||||
4. policyitem name: This field is used for define the license, copyright, "*" means match all, the "!" prefix means could not match this value. For example, "!GPL" means can not use GPL license.
|
||||
5. policyitem path: This field is used for define the source file scope to apply this policyitem, the "!" prefix means exclude the files. For example, "!.*/lib/.*" means files in lib dir will be exclude while process this policyitem.
|
||||
6. policyitem rule and group: These two fields are used together to merge policy results. "may" policyitems in the same group means any one in this group passed, the result will be passed.
|
||||
7. policyitem filefilter: Used to bind filefilter which define filter rules.
|
||||
8. filefilter: Filter rules, the type filename is used to filter file name, the type filepath is used to filter file path.
|
||||
|
||||
Note:If the text contains special characters, please escape them according to the following rules:
|
||||
" == >
|
||||
& == >
|
||||
' == >
|
||||
< == >
|
||||
> == >
|
||||
-->
|
||||
<configuration>
|
||||
<oatconfig>
|
||||
<licensefile></licensefile>
|
||||
<filefilterlist>
|
||||
<filefilter name="binaryFileTypePolicyFilter" desc="二进制文件校验策略的过滤条件" >
|
||||
<filteritem type="filepath" name="figures/en-us_image_0000001162437581.png" desc="自造的二进制文件"/>
|
||||
<filteritem type="filepath" name="figures/zh-cn_image_0000001162437581.png" desc="自造的二进制文件"/>
|
||||
</filefilter>
|
||||
</filefilterlist>
|
||||
|
||||
</oatconfig>
|
||||
</configuration>
|
||||
@@ -16,9 +16,10 @@
|
||||
#ifndef FOUNDATION_ACE_NAPI_INTERFACES_KITS_NAPI_NATIVE_API_H
|
||||
#define FOUNDATION_ACE_NAPI_INTERFACES_KITS_NAPI_NATIVE_API_H
|
||||
|
||||
#include <vector>
|
||||
#include "native_common.h"
|
||||
|
||||
#include <js_native_api.h>
|
||||
#include "js_native_api.h"
|
||||
|
||||
DEPRECATED napi_status napi_create_string_utf16(napi_env env, const char16_t* str, size_t length, napi_value* result);
|
||||
DEPRECATED napi_status napi_get_value_string_utf16(napi_env env,
|
||||
@@ -28,10 +29,12 @@ DEPRECATED napi_status napi_get_value_string_utf16(napi_env env,
|
||||
size_t* result);
|
||||
DEPRECATED napi_status napi_adjust_external_memory(napi_env env, int64_t change_in_bytes, int64_t* adjusted_value);
|
||||
napi_status napi_is_callable(napi_env env, napi_value value, bool* result);
|
||||
napi_status napi_create_runtime(napi_env env, napi_env* result_env);
|
||||
napi_status napi_serialize(napi_env env, napi_value object, napi_value transfer_list, napi_value* result);
|
||||
napi_status napi_deserialize(napi_env env, napi_value recorder, napi_value* object);
|
||||
napi_status napi_delete_serialization_data(napi_env env, napi_value value);
|
||||
napi_status napi_get_exception_info_for_worker(napi_env env, napi_value obj);
|
||||
napi_status napi_create_runtime(napi_env env, napi_env* result_env);
|
||||
napi_status napi_serialize(napi_env env, napi_value object, napi_value transfer_list, napi_value* result);
|
||||
napi_status napi_deserialize(napi_env env, napi_value recorder, napi_value* object);
|
||||
napi_status napi_delete_serialization_data(napi_env env, napi_value value);
|
||||
napi_status napi_get_exception_info_for_worker(napi_env env, napi_value obj);
|
||||
napi_status napi_get_jsEngine(napi_env env, void** pEngine);
|
||||
napi_status napi_run_buffer_script(napi_env env, std::vector<uint8_t>& buffer, napi_value* result);
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_INTERFACES_KITS_NAPI_NATIVE_API_H */
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#include "native_common.h"
|
||||
|
||||
#include <node_api.h>
|
||||
#include "node_api.h"
|
||||
|
||||
DEPRECATED napi_status napi_async_init(napi_env env,
|
||||
napi_value async_resource,
|
||||
|
||||
@@ -23,12 +23,17 @@
|
||||
#include <dirent.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
namespace {
|
||||
constexpr static int32_t NATIVE_PATH_NUMBER = 2;
|
||||
} // namespace
|
||||
|
||||
NativeModuleManager NativeModuleManager::instance_;
|
||||
|
||||
NativeModuleManager::NativeModuleManager()
|
||||
{
|
||||
firstNativeModule_ = nullptr;
|
||||
lastNativeModule_ = nullptr;
|
||||
appLibPath_ = nullptr;
|
||||
|
||||
pthread_mutex_init(&mutex_, nullptr);
|
||||
}
|
||||
@@ -42,6 +47,9 @@ NativeModuleManager::~NativeModuleManager()
|
||||
firstNativeModule_ = nativeModule;
|
||||
}
|
||||
firstNativeModule_ = lastNativeModule_ = nullptr;
|
||||
if (appLibPath_) {
|
||||
delete[] appLibPath_;
|
||||
}
|
||||
|
||||
pthread_mutex_destroy(&mutex_);
|
||||
}
|
||||
@@ -60,9 +68,18 @@ void NativeModuleManager::Register(NativeModule* nativeModule)
|
||||
|
||||
if (firstNativeModule_ == lastNativeModule_ && lastNativeModule_ == nullptr) {
|
||||
firstNativeModule_ = new NativeModule();
|
||||
if (firstNativeModule_ == nullptr) {
|
||||
HILOG_ERROR("first NativeModule create failed");
|
||||
return;
|
||||
}
|
||||
lastNativeModule_ = firstNativeModule_;
|
||||
} else {
|
||||
lastNativeModule_->next = new NativeModule();
|
||||
auto next = new NativeModule();
|
||||
if (next == nullptr) {
|
||||
HILOG_ERROR("next NativeModule create failed");
|
||||
return;
|
||||
}
|
||||
lastNativeModule_->next = next;
|
||||
lastNativeModule_ = lastNativeModule_->next;
|
||||
}
|
||||
|
||||
@@ -74,8 +91,26 @@ void NativeModuleManager::Register(NativeModule* nativeModule)
|
||||
lastNativeModule_->next = nullptr;
|
||||
}
|
||||
|
||||
NativeModule* NativeModuleManager::LoadNativeModule(const char* moduleName, const char* path, bool internal)
|
||||
void NativeModuleManager::SetAppLibPath(const char* appLibPath)
|
||||
{
|
||||
char* tmp = new char[PATH_MAX];
|
||||
errno_t err = EOK;
|
||||
err = memset_s(tmp, PATH_MAX, 0, PATH_MAX);
|
||||
if (err != EOK) {
|
||||
return;
|
||||
}
|
||||
err = strcpy_s(tmp, PATH_MAX, appLibPath);
|
||||
if (err != EOK) {
|
||||
delete[] tmp;
|
||||
return;
|
||||
}
|
||||
appLibPath_ = tmp;
|
||||
}
|
||||
|
||||
NativeModule* NativeModuleManager::LoadNativeModule(const char* moduleName,
|
||||
const char* path, bool isAppModule, bool internal, bool isArk)
|
||||
{
|
||||
HILOG_ERROR("Kee LoadNativeModule");
|
||||
if (moduleName == nullptr) {
|
||||
HILOG_ERROR("moduleName value is null");
|
||||
return nullptr;
|
||||
@@ -89,7 +124,7 @@ NativeModule* NativeModuleManager::LoadNativeModule(const char* moduleName, cons
|
||||
NativeModule* nativeModule = FindNativeModuleByCache(moduleName);
|
||||
if (nativeModule == nullptr) {
|
||||
HILOG_INFO("not in cache: moduleName: %{public}s", moduleName);
|
||||
nativeModule = FindNativeModuleByDisk(moduleName, internal, path);
|
||||
nativeModule = FindNativeModuleByDisk(moduleName, internal, isAppModule, isArk);
|
||||
}
|
||||
|
||||
if (pthread_mutex_unlock(&mutex_) != 0) {
|
||||
@@ -101,7 +136,7 @@ NativeModule* NativeModuleManager::LoadNativeModule(const char* moduleName, cons
|
||||
}
|
||||
|
||||
bool NativeModuleManager::GetNativeModulePath(
|
||||
const char* moduleName, const char* path, char* nativeModulePath, int32_t pathLength) const
|
||||
const char* moduleName, const bool isAppModule, char nativeModulePath[][PATH_MAX], int32_t pathLength) const
|
||||
{
|
||||
const char* soPostfix = ".so";
|
||||
#ifdef _ARM64_
|
||||
@@ -110,8 +145,8 @@ bool NativeModuleManager::GetNativeModulePath(
|
||||
const char* sysPrefix = "/system/lib/module";
|
||||
#endif
|
||||
const char* prefix = nullptr;
|
||||
if (path) {
|
||||
prefix = path;
|
||||
if (isAppModule && appLibPath_) {
|
||||
prefix = appLibPath_;
|
||||
} else {
|
||||
prefix = sysPrefix;
|
||||
}
|
||||
@@ -129,7 +164,7 @@ bool NativeModuleManager::GetNativeModulePath(
|
||||
int32_t lengthOfPostfix = strlen(soPostfix);
|
||||
if ((lengthOfModuleName > lengthOfPostfix) &&
|
||||
(strcmp(dupModuleName + lengthOfModuleName - lengthOfPostfix, soPostfix) == 0)) {
|
||||
if (sprintf_s(nativeModulePath, pathLength, "%s/%s", prefix, dupModuleName) == -1) {
|
||||
if (sprintf_s(nativeModulePath[0], pathLength, "%s/%s", prefix, dupModuleName) == -1) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -137,8 +172,17 @@ bool NativeModuleManager::GetNativeModulePath(
|
||||
|
||||
char* lastDot = strrchr(dupModuleName, '.');
|
||||
if (lastDot == nullptr) {
|
||||
if (sprintf_s(nativeModulePath, pathLength, "%s/lib%s.z.so", prefix, dupModuleName) == -1) {
|
||||
return false;
|
||||
if (strcmp(prefix, sysPrefix) == 0) {
|
||||
if (sprintf_s(nativeModulePath[0], pathLength, "%s/lib%s.z.so", prefix, dupModuleName) == -1) {
|
||||
return false;
|
||||
}
|
||||
if (sprintf_s(nativeModulePath[1], pathLength, "%s/lib%s_napi.z.so", prefix, dupModuleName) == -1) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (sprintf_s(nativeModulePath[0], pathLength, "%s/lib%s.so", prefix, dupModuleName) == -1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
char* afterDot = lastDot + 1;
|
||||
@@ -152,36 +196,71 @@ bool NativeModuleManager::GetNativeModulePath(
|
||||
*(dupModuleName + i) = '/';
|
||||
}
|
||||
}
|
||||
if (sprintf_s(nativeModulePath, pathLength, "%s/%s/lib%s.z.so", prefix, dupModuleName, afterDot) == -1) {
|
||||
return false;
|
||||
if (strcmp(prefix, sysPrefix) == 0) {
|
||||
if (sprintf_s(nativeModulePath[0], pathLength, "%s/%s/lib%s.z.so",
|
||||
prefix, dupModuleName, afterDot) == -1) {
|
||||
return false;
|
||||
}
|
||||
if (sprintf_s(nativeModulePath[1], pathLength, "%s/%s/lib%s_napi.z.so",
|
||||
prefix, dupModuleName, afterDot) == -1) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (sprintf_s(nativeModulePath[0], pathLength, "%s/%s/lib%s.so", prefix, dupModuleName, afterDot) == -1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
using NAPIGetJSCode = void (*)(const char** buf, int* bufLen);
|
||||
NativeModule* NativeModuleManager::FindNativeModuleByDisk(const char* moduleName, bool internal, const char* path)
|
||||
void* NativeModuleManager::LoadLibrary(const char* path) const
|
||||
{
|
||||
char nativeModulePath[PATH_MAX] = { 0 };
|
||||
if (!GetNativeModulePath(moduleName, path, nativeModulePath, sizeof(nativeModulePath))) {
|
||||
if (strlen(path) == 0) {
|
||||
HILOG_ERROR("primary module path is empty");
|
||||
return nullptr;
|
||||
}
|
||||
void* lib = dlopen(path, RTLD_LAZY);
|
||||
if (lib == nullptr) {
|
||||
HILOG_ERROR("dlopen failed: %{public}s", dlerror());
|
||||
}
|
||||
return lib;
|
||||
}
|
||||
|
||||
using NAPIGetJSCode = void (*)(const char** buf, int* bufLen);
|
||||
NativeModule* NativeModuleManager::FindNativeModuleByDisk(const char* moduleName, bool internal, const bool isAppModule,
|
||||
bool isArk)
|
||||
{
|
||||
char nativeModulePath[NATIVE_PATH_NUMBER][PATH_MAX] = { 0 };
|
||||
if (!GetNativeModulePath(moduleName, isAppModule, nativeModulePath, PATH_MAX)) {
|
||||
HILOG_ERROR("get module filed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
HILOG_INFO("get module path: %{public}s", nativeModulePath);
|
||||
if (strlen(nativeModulePath) <= 0) {
|
||||
return nullptr;
|
||||
}
|
||||
void* lib = dlopen(nativeModulePath, RTLD_LAZY);
|
||||
// load primary module path first
|
||||
char* loadPath = nativeModulePath[0];
|
||||
HILOG_INFO("get primary module path: %{public}s", loadPath);
|
||||
void* lib = LoadLibrary(loadPath);
|
||||
if (lib == nullptr) {
|
||||
HILOG_ERROR("dlopen failed: %{public}s", dlerror());
|
||||
return nullptr;
|
||||
loadPath = nativeModulePath[1];
|
||||
HILOG_WARN("primary module path load failed, try to load secondary module path: %{public}s", loadPath);
|
||||
lib = LoadLibrary(loadPath);
|
||||
if (lib == nullptr) {
|
||||
HILOG_ERROR("secondary module path load failed, load native module failed");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (!internal) {
|
||||
char symbol[PATH_MAX] = { 0 };
|
||||
if (sprintf_s(symbol, sizeof(symbol), "NAPI_%s_GetJSCode", moduleName) == -1) {
|
||||
return nullptr;
|
||||
if (!isArk) {
|
||||
if (sprintf_s(symbol, sizeof(symbol), "NAPI_%s_GetJSCode", moduleName) == -1) {
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
if (sprintf_s(symbol, sizeof(symbol), "NAPI_%s_GetABCCode", moduleName) == -1) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
auto getJSCode = reinterpret_cast<NAPIGetJSCode>(dlsym(lib, symbol));
|
||||
if (getJSCode != nullptr) {
|
||||
@@ -194,7 +273,7 @@ NativeModule* NativeModuleManager::FindNativeModuleByDisk(const char* moduleName
|
||||
lastNativeModule_->jsCodeLen = bufLen;
|
||||
}
|
||||
} else {
|
||||
HILOG_INFO("no %{public}s in %{public}s", symbol, nativeModulePath);
|
||||
HILOG_INFO("ignore: no %{public}s in %{public}s", symbol, loadPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define PATH_MAX 4096
|
||||
|
||||
class NativeValue;
|
||||
|
||||
class NativeEngine;
|
||||
@@ -42,19 +44,23 @@ public:
|
||||
static unsigned long Release();
|
||||
|
||||
void Register(NativeModule* nativeModule);
|
||||
NativeModule* LoadNativeModule(const char* moduleName, const char* path, bool internal = false);
|
||||
void SetAppLibPath(const char* appLibPath);
|
||||
NativeModule* LoadNativeModule(const char* moduleName, const char* path, bool isAppModule, bool internal = false,
|
||||
bool isArk = false);
|
||||
|
||||
private:
|
||||
NativeModuleManager();
|
||||
virtual ~NativeModuleManager();
|
||||
|
||||
bool GetNativeModulePath(
|
||||
const char* moduleName, const char* path, char* nativeModulePath, int32_t pathLength) const;
|
||||
NativeModule* FindNativeModuleByDisk(const char* moduleName, bool internal, const char* path);
|
||||
const char* moduleName, const bool isAppModule, char nativeModulePath[][PATH_MAX], int32_t pathLength) const;
|
||||
NativeModule* FindNativeModuleByDisk(const char* moduleName, bool internal, const bool isAppModule, bool isArk);
|
||||
NativeModule* FindNativeModuleByCache(const char* moduleName) const;
|
||||
void* LoadLibrary(const char* path) const;
|
||||
|
||||
NativeModule* firstNativeModule_;
|
||||
NativeModule* lastNativeModule_;
|
||||
char* appLibPath_;
|
||||
|
||||
static NativeModuleManager instance_;
|
||||
pthread_mutex_t mutex_;
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_ARK_ARK_HEADERS_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_ARK_ARK_HEADERS_H
|
||||
|
||||
//#include "ecmascript/ecma_vm.h"
|
||||
#include "ecmascript/napi/include/jsnapi.h"
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_ARK_ARK_HEADERS_H */
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ark_native_engine.h"
|
||||
|
||||
#include "ark_native_deferred.h"
|
||||
|
||||
using panda::Global;
|
||||
using panda::Local;
|
||||
using panda::JSValueRef;
|
||||
ArkNativeDeferred::ArkNativeDeferred(ArkNativeEngine* engine, Local<PromiseCapabilityRef> deferred)
|
||||
: engine_(engine), deferred_(engine->GetEcmaVm(), deferred)
|
||||
{
|
||||
}
|
||||
|
||||
ArkNativeDeferred::~ArkNativeDeferred()
|
||||
{
|
||||
// Addr of Global stored in ArkNativeDeferred should be released.
|
||||
deferred_.FreeGlobalHandleAddr();
|
||||
}
|
||||
|
||||
void ArkNativeDeferred::Resolve(NativeValue* data)
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<JSValueRef> value = *data;
|
||||
deferred_->Resolve(vm, value.ToLocal(vm));
|
||||
}
|
||||
|
||||
void ArkNativeDeferred::Reject(NativeValue* reason)
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<JSValueRef> value = *reason;
|
||||
deferred_->Reject(vm, value.ToLocal(vm));
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_ARK_NATIVE_DEFERRED_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_ARK_NATIVE_DEFERRED_H
|
||||
|
||||
#include "ark_headers.h"
|
||||
|
||||
#include "native_engine/native_deferred.h"
|
||||
|
||||
using panda::PromiseCapabilityRef;
|
||||
class ArkNativeDeferred : public NativeDeferred {
|
||||
public:
|
||||
ArkNativeDeferred(ArkNativeEngine* engine, Local<PromiseCapabilityRef> deferred);
|
||||
~ArkNativeDeferred();
|
||||
void Resolve(NativeValue* data) override;
|
||||
void Reject(NativeValue* reason) override;
|
||||
|
||||
private:
|
||||
ArkNativeEngine* engine_;
|
||||
panda::Global<PromiseCapabilityRef> deferred_;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_ARK_NATIVE_DEFERRED_H */
|
||||
@@ -0,0 +1,572 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ark_native_engine.h"
|
||||
|
||||
#include "ark_native_deferred.h"
|
||||
#include "ark_native_reference.h"
|
||||
|
||||
#include "native_engine/native_property.h"
|
||||
|
||||
#include "native_value/ark_native_array.h"
|
||||
#include "native_value/ark_native_array_buffer.h"
|
||||
#include "native_value/ark_native_boolean.h"
|
||||
#include "native_value/ark_native_data_view.h"
|
||||
#include "native_value/ark_native_external.h"
|
||||
#include "native_value/ark_native_function.h"
|
||||
#include "native_value/ark_native_number.h"
|
||||
#include "native_value/ark_native_object.h"
|
||||
#include "native_value/ark_native_string.h"
|
||||
#include "native_value/ark_native_typed_array.h"
|
||||
|
||||
#include "securec.h"
|
||||
#include "utils/log.h"
|
||||
|
||||
using panda::ObjectRef;
|
||||
using panda::StringRef;
|
||||
using panda::FunctionRef;
|
||||
using panda::PrimitiveRef;
|
||||
using panda::JSValueRef;
|
||||
using panda::ArrayBufferRef;
|
||||
using panda::TypedArrayRef;
|
||||
using panda::PromiseCapabilityRef;
|
||||
using panda::NativePointerRef;
|
||||
using panda::SymbolRef;
|
||||
|
||||
static constexpr auto PANDA_MAIN_FUNCTION = "_GLOBAL::func_main_0";
|
||||
|
||||
ArkNativeEngine::ArkNativeEngine(EcmaVM* vm, void* jsEngine) : NativeEngine(jsEngine), vm_(vm), topScope_(vm)
|
||||
{
|
||||
Local<StringRef> requireName = StringRef::NewFromUtf8(vm, "requireNapi");
|
||||
Local<StringRef> requireInternalName = StringRef::NewFromUtf8(vm, "requireInternal");
|
||||
void* requireData = static_cast<void*>(this);
|
||||
|
||||
Local<FunctionRef> requireNapi =
|
||||
FunctionRef::New(
|
||||
vm,
|
||||
[](EcmaVM *ecmaVm, Local<JSValueRef> thisObj, const Local<JSValueRef> argv[], // NOLINTNEXTLINE(modernize-avoid-c-arrays)
|
||||
int32_t length, void *data) -> Local<JSValueRef> {
|
||||
panda::EscapeLocalScope scope(ecmaVm);
|
||||
NativeModuleManager* moduleManager = NativeModuleManager::GetInstance();
|
||||
ArkNativeEngine* engine = static_cast<ArkNativeEngine*>(data);
|
||||
Local<StringRef> moduleName(argv[0]);
|
||||
NativeModule* module =
|
||||
moduleManager->LoadNativeModule(moduleName->ToString().c_str(), nullptr, false, false, true);
|
||||
Global<ObjectRef> exports(ecmaVm, JSValueRef::Undefined(ecmaVm));
|
||||
if (module != nullptr) {
|
||||
if (module->jsCode != nullptr) {
|
||||
HILOG_INFO("load js code");
|
||||
NativeValue* script = engine->CreateString(module->jsCode, module->jsCodeLen);
|
||||
char fileName[PATH_MAX] = { 0 };
|
||||
const char* name = module->name;
|
||||
if (sprintf_s(fileName, sizeof(fileName), "lib%s.z.so/%s.js", name, name) == -1) {
|
||||
HILOG_ERROR("sprintf_s file name failed");
|
||||
return scope.Escape(exports.ToLocal(ecmaVm));
|
||||
}
|
||||
HILOG_DEBUG("load js code from %{public}s", fileName);
|
||||
NativeValue* exportObject = engine->LoadModule(script, fileName);
|
||||
if (exportObject == nullptr) {
|
||||
HILOG_ERROR("load module failed");
|
||||
return scope.Escape(exports.ToLocal(ecmaVm));
|
||||
} else {
|
||||
exports = *exportObject;
|
||||
}
|
||||
} else if (module->registerCallback != nullptr) {
|
||||
NativeValue* exportObject = engine->CreateObject();
|
||||
module->registerCallback(engine, exportObject);
|
||||
exports = *exportObject;
|
||||
} else {
|
||||
HILOG_ERROR("init module failed");
|
||||
return scope.Escape(exports.ToLocal(ecmaVm));
|
||||
}
|
||||
}
|
||||
return scope.Escape(exports.ToLocal(ecmaVm));
|
||||
},
|
||||
requireData);
|
||||
|
||||
Local<FunctionRef> requireInternal =
|
||||
FunctionRef::New(
|
||||
vm,
|
||||
[](EcmaVM *ecmaVm, Local<JSValueRef> thisObj, const Local<JSValueRef> argv[], // NOLINTNEXTLINE(modernize-avoid-c-arrays)
|
||||
int32_t length, void *data) -> Local<JSValueRef> {
|
||||
panda::EscapeLocalScope scope(ecmaVm);
|
||||
NativeModuleManager* moduleManager = NativeModuleManager::GetInstance();
|
||||
ArkNativeEngine* engine = static_cast<ArkNativeEngine*>(data);
|
||||
Local<StringRef> moduleName(argv[0]);
|
||||
NativeModule* module = moduleManager->LoadNativeModule(moduleName->ToString().c_str(), nullptr, false);
|
||||
Global<ObjectRef> exports;
|
||||
if (module != nullptr) {
|
||||
NativeValue* exportObject = engine->CreateObject();
|
||||
module->registerCallback(engine, exportObject);
|
||||
exports = *exportObject;
|
||||
}
|
||||
return scope.Escape(exports.ToLocal(ecmaVm));
|
||||
},
|
||||
requireData);
|
||||
|
||||
Local<ObjectRef> global = panda::JSNApi::GetGlobalObject(vm);
|
||||
global->Set(vm, requireName, requireNapi);
|
||||
global->Set(vm, requireInternalName, requireInternal);
|
||||
}
|
||||
|
||||
ArkNativeEngine::~ArkNativeEngine() {}
|
||||
|
||||
void ArkNativeEngine::Loop(LoopMode mode, bool needSync)
|
||||
{
|
||||
LocalScope scope(vm_);
|
||||
NativeEngine::Loop(mode, needSync);
|
||||
//panda::JSNApi::ExecutePendingJob(vm_);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::GetGlobal()
|
||||
{
|
||||
Local<ObjectRef> value = panda::JSNApi::GetGlobalObject(vm_);
|
||||
return ArkValueToNativeValue(this, value);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::CreateNull()
|
||||
{
|
||||
Local<PrimitiveRef> value = JSValueRef::Null(vm_);
|
||||
return new ArkNativeValue(this, value);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::CreateUndefined()
|
||||
{
|
||||
Local<PrimitiveRef> value = JSValueRef::Undefined(vm_);
|
||||
return new ArkNativeValue(this, value);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::CreateBoolean(bool value)
|
||||
{
|
||||
return new ArkNativeBoolean(this, value);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::CreateNumber(int32_t value)
|
||||
{
|
||||
return new ArkNativeNumber(this, value);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::CreateNumber(uint32_t value)
|
||||
{
|
||||
return new ArkNativeNumber(this, value);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::CreateNumber(int64_t value)
|
||||
{
|
||||
return new ArkNativeNumber(this, value);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::CreateNumber(double value)
|
||||
{
|
||||
return new ArkNativeNumber(this, value);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::CreateString(const char* value, size_t length)
|
||||
{
|
||||
return new ArkNativeString(this, value, length);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::CreateSymbol(NativeValue* value)
|
||||
{
|
||||
LocalScope scope(vm_);
|
||||
Global<StringRef> str = *value;
|
||||
Local<SymbolRef> symbol = SymbolRef::New(vm_, str.ToLocal(vm_));
|
||||
return new ArkNativeValue(this, symbol);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::CreateExternal(void* value, NativeFinalize callback, void* hint)
|
||||
{
|
||||
return new ArkNativeExternal(this, value, callback, hint);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::CreateObject()
|
||||
{
|
||||
return new ArkNativeObject(this);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::CreateFunction(const char* name, size_t length, NativeCallback cb, void* value)
|
||||
{
|
||||
return new ArkNativeFunction(this, name, length, cb, value);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::CreateArray(size_t length)
|
||||
{
|
||||
return new ArkNativeArray(this, length);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::CreateArrayBuffer(void** value, size_t length)
|
||||
{
|
||||
return new ArkNativeArrayBuffer(this, (uint8_t**)value, length);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::CreateArrayBufferExternal(void* value, size_t length, NativeFinalize cb, void* hint)
|
||||
{
|
||||
return new ArkNativeArrayBuffer(this, (uint8_t*)value, length, cb, hint);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::CreateTypedArray(NativeTypedArrayType type,
|
||||
NativeValue* value,
|
||||
size_t length,
|
||||
size_t offset)
|
||||
{
|
||||
LocalScope scope(vm_);
|
||||
Global<ArrayBufferRef> globalBuffer = *value;
|
||||
Local<ArrayBufferRef> buffer = globalBuffer.ToLocal(vm_);
|
||||
Local<TypedArrayRef> typedArray(JSValueRef::Undefined(vm_));
|
||||
|
||||
switch (type) {
|
||||
case NATIVE_INT8_ARRAY:
|
||||
typedArray = panda::Int8ArrayRef::New(vm_, buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_UINT8_ARRAY:
|
||||
typedArray = panda::Uint8ArrayRef::New(vm_, buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_UINT8_CLAMPED_ARRAY:
|
||||
typedArray = panda::Uint8ClampedArrayRef::New(vm_, buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_INT16_ARRAY:
|
||||
typedArray = panda::Int16ArrayRef::New(vm_, buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_UINT16_ARRAY:
|
||||
typedArray = panda::Uint16ArrayRef::New(vm_, buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_INT32_ARRAY:
|
||||
typedArray = panda::Int32ArrayRef::New(vm_, buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_UINT32_ARRAY:
|
||||
typedArray = panda::Uint32ArrayRef::New(vm_, buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_FLOAT32_ARRAY:
|
||||
typedArray = panda::Float32ArrayRef::New(vm_, buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_FLOAT64_ARRAY:
|
||||
typedArray = panda::Float64ArrayRef::New(vm_, buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_BIGINT64_ARRAY:
|
||||
// not support yet
|
||||
return nullptr;
|
||||
case NATIVE_BIGUINT64_ARRAY:
|
||||
// not support yet
|
||||
return nullptr;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
return new ArkNativeTypedArray(this, typedArray);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::CreateDataView(NativeValue* value, size_t length, size_t offset)
|
||||
{
|
||||
return new ArkNativeDataView(this, value, length, offset);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::CreatePromise(NativeDeferred** deferred)
|
||||
{
|
||||
LocalScope scope(vm_);
|
||||
Local<PromiseCapabilityRef> capability = PromiseCapabilityRef::New(vm_);
|
||||
*deferred = new ArkNativeDeferred(this, capability);
|
||||
|
||||
return new ArkNativeValue(this, capability->GetPromise(vm_));
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::CreateError(NativeValue* code, NativeValue* message)
|
||||
{
|
||||
LocalScope scope(vm_);
|
||||
Local<JSValueRef> errorVal = panda::Exception::Error(vm_, *message);
|
||||
if (code != nullptr) {
|
||||
Local<StringRef> codeKey = StringRef::NewFromUtf8(vm_, "code");
|
||||
Local<ObjectRef> errorObj(errorVal);
|
||||
errorObj->Set(vm_, codeKey, *code);
|
||||
}
|
||||
return ArkValueToNativeValue(this, errorVal);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::CallFunction(NativeValue* thisVar,
|
||||
NativeValue* function,
|
||||
NativeValue* const* argv,
|
||||
size_t argc)
|
||||
{
|
||||
if (function == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
LocalScope scope(vm_);
|
||||
Global<JSValueRef> thisObj = (thisVar != nullptr) ? *thisVar : Global<JSValueRef>(vm_, JSValueRef::Undefined(vm_));
|
||||
Global<FunctionRef> funcObj = *function;
|
||||
|
||||
std::vector<Local<JSValueRef>> args;
|
||||
args.reserve(argc);
|
||||
for (size_t i = 0; i < argc; i++) {
|
||||
if (argv[i] != nullptr) {
|
||||
Global<JSValueRef> arg = *argv[i];
|
||||
args.emplace_back(arg.ToLocal(vm_));
|
||||
} else {
|
||||
args.emplace_back(JSValueRef::Undefined(vm_));
|
||||
}
|
||||
}
|
||||
|
||||
Local<JSValueRef> value = funcObj->Call(vm_, thisObj.ToLocal(vm_), args.data(), argc);
|
||||
Local<ObjectRef> excep = panda::JSNApi::GetUncaughtException(vm_);
|
||||
if (!excep.IsNull()) {
|
||||
Local<StringRef> exceptionMsg = excep->ToString(vm_);
|
||||
exceptionStr_ = exceptionMsg->ToString();
|
||||
}
|
||||
|
||||
return ArkValueToNativeValue(this, value);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::RunScript(NativeValue* script)
|
||||
{
|
||||
// not support yet
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::DefineClass(const char* name,
|
||||
NativeCallback callback,
|
||||
void* data,
|
||||
const NativePropertyDescriptor* properties,
|
||||
size_t length)
|
||||
{
|
||||
LocalScope scope(vm_);
|
||||
auto classConstructor = new ArkNativeFunction(this, name, callback, data);
|
||||
auto classPrototype = classConstructor->GetFunctionPrototype();
|
||||
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
if (properties[i].attributes & NATIVE_STATIC) {
|
||||
classConstructor->DefineProperty(properties[i]);
|
||||
} else {
|
||||
if (classPrototype == nullptr) {
|
||||
HILOG_ERROR("ArkNativeEngine::Class's prototype is null");
|
||||
continue;
|
||||
}
|
||||
static_cast<ArkNativeObject*>(classPrototype)->DefineProperty(properties[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return classConstructor;
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::CreateInstance(NativeValue* constructor, NativeValue* const* argv, size_t argc)
|
||||
{
|
||||
if (constructor == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
LocalScope scope(vm_);
|
||||
Global<FunctionRef> value = *constructor;
|
||||
|
||||
std::vector<Local<JSValueRef>> args;
|
||||
args.reserve(argc);
|
||||
for (size_t i = 0; i < argc; i++) {
|
||||
if (argv[i] != nullptr) {
|
||||
Global<JSValueRef> arg = *argv[i];
|
||||
args.emplace_back(arg.ToLocal(vm_));
|
||||
} else {
|
||||
args.emplace_back(JSValueRef::Undefined(vm_));
|
||||
}
|
||||
}
|
||||
|
||||
Local<JSValueRef> instance = value->Constructor(vm_, args.data(), argc);
|
||||
|
||||
return ArkValueToNativeValue(this, instance);
|
||||
}
|
||||
|
||||
NativeReference* ArkNativeEngine::CreateReference(NativeValue* value, uint32_t initialRefcount)
|
||||
{
|
||||
return new ArkNativeReference(this, value, initialRefcount);
|
||||
}
|
||||
|
||||
bool ArkNativeEngine::Throw(NativeValue* error)
|
||||
{
|
||||
LocalScope scope(vm_);
|
||||
Global<JSValueRef> errorVal = *error;
|
||||
panda::JSNApi::ThrowException(vm_, errorVal.ToLocal(vm_));
|
||||
lastException_ = error;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArkNativeEngine::Throw(NativeErrorType type, const char* code, const char* message)
|
||||
{
|
||||
LocalScope scope(vm_);
|
||||
Local<JSValueRef> error(JSValueRef::Undefined(vm_));
|
||||
switch (type) {
|
||||
case NATIVE_COMMON_ERROR:
|
||||
error = panda::Exception::Error(vm_, StringRef::NewFromUtf8(vm_, message));
|
||||
break;
|
||||
case NATIVE_TYPE_ERROR:
|
||||
error = panda::Exception::TypeError(vm_, StringRef::NewFromUtf8(vm_, message));
|
||||
break;
|
||||
case NATIVE_RANGE_ERROR:
|
||||
error = panda::Exception::RangeError(vm_, StringRef::NewFromUtf8(vm_, message));
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (code != nullptr) {
|
||||
Local<JSValueRef> codeKey = StringRef::NewFromUtf8(vm_, "code");
|
||||
Local<JSValueRef> codeValue = StringRef::NewFromUtf8(vm_, code);
|
||||
Local<ObjectRef> errorObj(error);
|
||||
errorObj->Set(vm_, codeKey, codeValue);
|
||||
}
|
||||
|
||||
panda::JSNApi::ThrowException(vm_, error);
|
||||
lastException_ = ArkValueToNativeValue(this, error);
|
||||
return true;
|
||||
}
|
||||
|
||||
void* ArkNativeEngine::CreateRuntime()
|
||||
{
|
||||
panda::RuntimeOption option;
|
||||
option.SetGcType(panda::RuntimeOption::GC_TYPE::GEN_GC);
|
||||
const int64_t poolSize = 0x1000000;
|
||||
option.SetGcPoolSize(poolSize);
|
||||
//option.SetPandaStdFile("pandastdlib/arkstdlib.abc");
|
||||
option.SetLogLevel(panda::RuntimeOption::LOG_LEVEL::ERROR);
|
||||
option.SetDebuggerLibraryPath("");
|
||||
EcmaVM* vm = panda::JSNApi::CreateJSVM(option);
|
||||
if (vm == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ArkNativeEngine* arkEngine = new ArkNativeEngine(vm, this);
|
||||
return reinterpret_cast<void*>(arkEngine);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::Serialize(NativeEngine* context, NativeValue* value, NativeValue* transfer)
|
||||
{
|
||||
const panda::ecmascript::EcmaVM* vm = reinterpret_cast<ArkNativeEngine*>(context)->GetEcmaVm();
|
||||
Local<JSValueRef> arkValue = *value;
|
||||
Local<JSValueRef> arkTransfer = *transfer;
|
||||
void* result = panda::JSNApi::SerializeValue(vm, arkValue, arkTransfer);
|
||||
return reinterpret_cast<NativeValue*>(result);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::Deserialize(NativeEngine* context, NativeValue* recorder)
|
||||
{
|
||||
const panda::ecmascript::EcmaVM* vm = reinterpret_cast<ArkNativeEngine*>(context)->GetEcmaVm();
|
||||
Local<JSValueRef> result = panda::JSNApi::DeserializeValue(vm, recorder);
|
||||
return ArkValueToNativeValue(this, result);
|
||||
}
|
||||
|
||||
ExceptionInfo* ArkNativeEngine::GetExceptionForWorker() const
|
||||
{
|
||||
if (exceptionStr_.empty()) {
|
||||
HILOG_ERROR("worker:: exception is null");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ExceptionInfo* exceptionInfo = new ExceptionInfo();
|
||||
int msgLength = exceptionStr_.length();
|
||||
char* exceptionMessage = new char[msgLength + 1] { 0 };
|
||||
if (memcpy_s(exceptionMessage, msgLength, exceptionStr_.c_str(), msgLength) != EOK) {
|
||||
HILOG_ERROR("worker:: memcpy_s error");
|
||||
delete exceptionInfo;
|
||||
delete[] exceptionMessage;
|
||||
return nullptr;
|
||||
}
|
||||
exceptionInfo->message_ = exceptionMessage;
|
||||
// need add colno, lineno when ark exception support
|
||||
return exceptionInfo;
|
||||
}
|
||||
|
||||
void ArkNativeEngine::DeleteSerializationData(NativeValue* value) const
|
||||
{
|
||||
void* data = reinterpret_cast<void*>(value);
|
||||
panda::JSNApi::DeleteSerializationData(data);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::RunBufferScript(std::vector<uint8_t>& buffer)
|
||||
{
|
||||
Local<StringRef> entryPoint = StringRef::NewFromUtf8(vm_, PANDA_MAIN_FUNCTION);
|
||||
//panda::JSNApi::EnableUserUncaughtErrorHandler(vm_);
|
||||
panda::JSExecutionScope executionScope(vm_);
|
||||
bool ret = panda::JSNApi::Execute(vm_, buffer.data(), buffer.size(), entryPoint);
|
||||
|
||||
Local<ObjectRef> excep = panda::JSNApi::GetUncaughtException(vm_);
|
||||
if (!excep.IsNull()) {
|
||||
Local<StringRef> exceptionMsg = excep->ToString(vm_);
|
||||
exceptionStr_ = exceptionMsg->ToString();
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
return nullptr;
|
||||
}
|
||||
return CreateUndefined();
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::LoadModule(NativeValue* str, const std::string& fileName)
|
||||
{
|
||||
HILOG_DEBUG("ArkNativeEngine::LoadModule start");
|
||||
if (str == nullptr || fileName.empty()) {
|
||||
HILOG_ERROR("fileName is nullptr or source code is nullptr");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Local<StringRef> source = *str;
|
||||
int32_t len = source->Length();
|
||||
char* buffer = new char[len];
|
||||
source->WriteUtf8(buffer, len);
|
||||
HILOG_DEBUG("Ark::LoadModule buffer = %{public}s", buffer);
|
||||
|
||||
bool res = JSNApi::ExecuteModuleFromBuffer(vm_, buffer, len, fileName);
|
||||
if (!res) {
|
||||
HILOG_ERROR("Execute module failed");
|
||||
delete[] buffer;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Local<ObjectRef> exportObj = JSNApi::GetExportObject(vm_, fileName, "default");
|
||||
if (exportObj->IsNull()) {
|
||||
HILOG_ERROR("Get export object failed");
|
||||
delete[] buffer;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
delete[] buffer;
|
||||
HILOG_DEBUG("ArkNativeEngine::LoadModule end");
|
||||
return ArkValueToNativeValue(this, exportObj);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::ArkValueToNativeValue(ArkNativeEngine* engine, Local<JSValueRef> value)
|
||||
{
|
||||
NativeValue* result = nullptr;
|
||||
if (value->IsNull() || value->IsUndefined() || value->IsSymbol() || value->IsPromise()) {
|
||||
result = new ArkNativeValue(engine, value);
|
||||
} else if (value->IsNumber()) {
|
||||
result = new ArkNativeNumber(engine, value);
|
||||
} else if (value->IsString()) {
|
||||
result = new ArkNativeString(engine, value);
|
||||
} else if (value->IsArray(engine->GetEcmaVm())) {
|
||||
result = new ArkNativeArray(engine, value);
|
||||
} else if (value->IsFunction()) {
|
||||
result = new ArkNativeFunction(engine, value);
|
||||
} else if (value->IsArrayBuffer()) {
|
||||
result = new ArkNativeArrayBuffer(engine, value);
|
||||
} else if (value->IsDataView()) {
|
||||
result = new ArkNativeDataView(engine, value);
|
||||
} else if (value->IsTypedArray()) {
|
||||
result = new ArkNativeTypedArray(engine, value);
|
||||
} else if (value->IsNativeObject() || value->IsNativePointer()) {
|
||||
result = new ArkNativeExternal(engine, value);
|
||||
} else if (value->IsObject()) {
|
||||
result = new ArkNativeObject(engine, value);
|
||||
} else if (value->IsBoolean()) {
|
||||
result = new ArkNativeBoolean(engine, value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeEngine::ValueToNativeValue(JSValueWrapper& value)
|
||||
{
|
||||
Global<JSValueRef> arkValue = value;
|
||||
return ArkValueToNativeValue(this, arkValue.ToLocal(vm_));
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_ARK_NATIVE_ENGINE_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_ARK_NATIVE_ENGINE_H
|
||||
|
||||
#include "ark_headers.h"
|
||||
#include "ecmascript/napi/include/jsnapi.h"
|
||||
#include "native_engine/native_engine.h"
|
||||
|
||||
using panda::ecmascript::EcmaVM;
|
||||
using panda::Local;
|
||||
using panda::LocalScope;
|
||||
using panda::JSValueRef;
|
||||
using panda::JSNApi;
|
||||
|
||||
class SerializationData {
|
||||
public:
|
||||
SerializationData() : data_(nullptr), size_(0) {}
|
||||
~SerializationData() = default;
|
||||
|
||||
uint8_t* GetData() const
|
||||
{
|
||||
return data_.get();
|
||||
}
|
||||
size_t GetSize() const
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
private:
|
||||
struct DataDeleter {
|
||||
void operator()(uint8_t* p) const
|
||||
{
|
||||
free(p);
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<uint8_t, DataDeleter> data_;
|
||||
size_t size_;
|
||||
};
|
||||
|
||||
class ArkNativeEngine : public NativeEngine {
|
||||
public:
|
||||
// ArkNativeEngine constructor
|
||||
ArkNativeEngine(EcmaVM* vm, void* jsEngine);
|
||||
// ArkNativeEngine destructor
|
||||
~ArkNativeEngine() override;
|
||||
|
||||
const EcmaVM* GetEcmaVm() const
|
||||
{
|
||||
return vm_;
|
||||
}
|
||||
|
||||
void Loop(LoopMode mode, bool needSync = false) override;
|
||||
|
||||
// Get global native object value
|
||||
NativeValue* GetGlobal() override;
|
||||
// Create native null value
|
||||
NativeValue* CreateNull() override;
|
||||
// Create native undefined value
|
||||
NativeValue* CreateUndefined() override;
|
||||
// Create native boolean value
|
||||
NativeValue* CreateBoolean(bool value) override;
|
||||
// Create number value by int32_t
|
||||
NativeValue* CreateNumber(int32_t value) override;
|
||||
// Create number value by uint32_t
|
||||
NativeValue* CreateNumber(uint32_t value) override;
|
||||
// Create native number value by int64_t
|
||||
NativeValue* CreateNumber(int64_t value) override;
|
||||
// Create native number value by double
|
||||
NativeValue* CreateNumber(double value) override;
|
||||
// Create native string value by const char pointer
|
||||
NativeValue* CreateString(const char* value, size_t length) override;
|
||||
// Create native symbol value
|
||||
NativeValue* CreateSymbol(NativeValue* value) override;
|
||||
// Create native value of external pointer
|
||||
NativeValue* CreateExternal(void* value, NativeFinalize callback, void* hint) override;
|
||||
// Create native object value
|
||||
NativeValue* CreateObject() override;
|
||||
// Create native function value
|
||||
NativeValue* CreateFunction(const char* name, size_t length, NativeCallback cb, void* value) override;
|
||||
// Create native array value
|
||||
NativeValue* CreateArray(size_t length) override;
|
||||
// Create native array buffer value
|
||||
NativeValue* CreateArrayBuffer(void** value, size_t length) override;
|
||||
// Create native array buffer value of external
|
||||
NativeValue* CreateArrayBufferExternal(void* value, size_t length, NativeFinalize cb, void* hint) override;
|
||||
// Create native typed array value
|
||||
NativeValue* CreateTypedArray(NativeTypedArrayType type,
|
||||
NativeValue* value,
|
||||
size_t length,
|
||||
size_t offset) override;
|
||||
// Create native data view value
|
||||
NativeValue* CreateDataView(NativeValue* value, size_t length, size_t offset) override;
|
||||
// Create native promise value
|
||||
NativeValue* CreatePromise(NativeDeferred** deferred) override;
|
||||
// Create native error value
|
||||
NativeValue* CreateError(NativeValue* code, NativeValue* message) override;
|
||||
// Call function
|
||||
NativeValue* CallFunction(NativeValue* thisVar,
|
||||
NativeValue* function,
|
||||
NativeValue* const* argv,
|
||||
size_t argc) override;
|
||||
// Run script
|
||||
NativeValue* RunScript(NativeValue* script) override;
|
||||
// Run buffer script
|
||||
NativeValue* RunBufferScript(std::vector<uint8_t>& buffer) override;
|
||||
// Define native class
|
||||
NativeValue* DefineClass(const char* name,
|
||||
NativeCallback callback,
|
||||
void* data,
|
||||
const NativePropertyDescriptor* properties,
|
||||
size_t length) override;
|
||||
// Create instance by defined class
|
||||
NativeValue* CreateInstance(NativeValue* constructor, NativeValue* const* argv, size_t argc) override;
|
||||
|
||||
// Create native reference
|
||||
NativeReference* CreateReference(NativeValue* value, uint32_t initialRefcount) override;
|
||||
// Throw exception
|
||||
bool Throw(NativeValue* error) override;
|
||||
// Throw exception
|
||||
bool Throw(NativeErrorType type, const char* code, const char* message) override;
|
||||
|
||||
void* CreateRuntime() override;
|
||||
NativeValue* Serialize(NativeEngine* context, NativeValue* value, NativeValue* transfer) override;
|
||||
NativeValue* Deserialize(NativeEngine* context, NativeValue* recorder) override;
|
||||
void DeleteSerializationData(NativeValue* value) const override;
|
||||
ExceptionInfo* GetExceptionForWorker() const override;
|
||||
NativeValue* LoadModule(NativeValue* str, const std::string& fileName) override;
|
||||
|
||||
static NativeValue* ArkValueToNativeValue(ArkNativeEngine* engine, Local<JSValueRef> value);
|
||||
|
||||
NativeValue* ValueToNativeValue(JSValueWrapper& value) override;
|
||||
|
||||
private:
|
||||
EcmaVM* vm_ = nullptr;
|
||||
std::string exceptionStr_;
|
||||
panda::LocalScope topScope_;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_ARK_NATIVE_ENGINE_H */
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ark_native_engine.h"
|
||||
|
||||
#include "ark_native_reference.h"
|
||||
|
||||
#include "utils/log.h"
|
||||
|
||||
ArkNativeReference::ArkNativeReference(ArkNativeEngine* engine, NativeValue* value, uint32_t initialRefcount)
|
||||
: engine_(engine),
|
||||
value_(Global<JSValueRef>(engine->GetEcmaVm(), JSValueRef::Undefined(engine->GetEcmaVm()))),
|
||||
refCount_(initialRefcount)
|
||||
{
|
||||
ASSERT(initialRefcount != 0);
|
||||
Global<JSValueRef> oldValue = *value;
|
||||
auto vm = engine->GetEcmaVm();
|
||||
Global<JSValueRef> newValue(vm, oldValue.ToLocal(vm));
|
||||
value_ = newValue;
|
||||
}
|
||||
|
||||
ArkNativeReference::~ArkNativeReference()
|
||||
{
|
||||
if (refCount_ != 0) {
|
||||
refCount_ = 0;
|
||||
// Addr of Global stored in ArkNativeReference should be released.
|
||||
value_.FreeGlobalHandleAddr();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ArkNativeReference::Ref()
|
||||
{
|
||||
if (refCount_ != 0) {
|
||||
++refCount_;
|
||||
}
|
||||
return refCount_;
|
||||
}
|
||||
|
||||
uint32_t ArkNativeReference::Unref()
|
||||
{
|
||||
if (refCount_ == 1) {
|
||||
refCount_ = 0;
|
||||
value_.FreeGlobalHandleAddr();
|
||||
} else if (refCount_ > 0) {
|
||||
--refCount_;
|
||||
}
|
||||
return refCount_;
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeReference::Get()
|
||||
{
|
||||
if (refCount_ == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Local<JSValueRef> value = value_.ToLocal(vm);
|
||||
return ArkNativeEngine::ArkValueToNativeValue(engine_, value);
|
||||
}
|
||||
|
||||
ArkNativeReference::operator NativeValue*()
|
||||
{
|
||||
return Get();
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_ARK_NATIVE_REFERENCE_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_ARK_NATIVE_REFERENCE_H
|
||||
|
||||
#include "native_engine/native_value.h"
|
||||
|
||||
#include "native_engine/native_reference.h"
|
||||
|
||||
class ArkNativeEngine;
|
||||
|
||||
using panda::Global;
|
||||
using panda::JSValueRef;
|
||||
using panda::Local;
|
||||
|
||||
class ArkNativeReference : public NativeReference {
|
||||
public:
|
||||
ArkNativeReference(ArkNativeEngine* engine, NativeValue* value, uint32_t initialRefcount);
|
||||
~ArkNativeReference() override;
|
||||
|
||||
uint32_t Ref() override;
|
||||
uint32_t Unref() override;
|
||||
NativeValue* Get() override;
|
||||
operator NativeValue*() override;
|
||||
|
||||
private:
|
||||
ArkNativeEngine* engine_;
|
||||
Global<JSValueRef> value_;
|
||||
uint32_t refCount_;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_ARK_NATIVE_REFERENCE_H */
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ark_native_array.h"
|
||||
|
||||
using panda::ObjectRef;
|
||||
using panda::ArrayRef;
|
||||
ArkNativeArray::ArkNativeArray(ArkNativeEngine* engine, Local<JSValueRef> value) : ArkNativeObject(engine, value) {}
|
||||
|
||||
ArkNativeArray::ArkNativeArray(ArkNativeEngine* engine, uint32_t length)
|
||||
: ArkNativeArray(engine, JSValueRef::Undefined(engine->GetEcmaVm()))
|
||||
{
|
||||
auto vm = engine->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Local<ArrayRef> object = ArrayRef::New(vm, length);
|
||||
value_ = Global<ArrayRef>(vm, object);
|
||||
}
|
||||
|
||||
ArkNativeArray::~ArkNativeArray() {}
|
||||
|
||||
void* ArkNativeArray::GetInterface(int interfaceId)
|
||||
{
|
||||
return (NativeArray::INTERFACE_ID == interfaceId) ? (NativeArray*)this
|
||||
: ArkNativeObject::GetInterface(interfaceId);
|
||||
}
|
||||
|
||||
bool ArkNativeArray::SetElement(uint32_t index, NativeValue* value)
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<ObjectRef> obj = value_;
|
||||
Global<JSValueRef> val = *value;
|
||||
return obj->Set(vm, index, val.ToLocal(vm));
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeArray::GetElement(uint32_t index)
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<ObjectRef> obj = value_;
|
||||
auto val = obj->Get(vm, index);
|
||||
return ArkNativeEngine::ArkValueToNativeValue(engine_, val);
|
||||
}
|
||||
|
||||
bool ArkNativeArray::HasElement(uint32_t index)
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<ObjectRef> obj = value_;
|
||||
return obj->Has(vm, index);
|
||||
}
|
||||
|
||||
bool ArkNativeArray::DeleteElement(uint32_t index)
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<ObjectRef> obj = value_;
|
||||
return obj->Delete(vm, index);
|
||||
}
|
||||
|
||||
uint32_t ArkNativeArray::GetLength()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<ArrayRef> obj = value_;
|
||||
return obj->Length(vm);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_ARRAY_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_ARRAY_H
|
||||
|
||||
#include "ark_native_object.h"
|
||||
|
||||
class ArkNativeArray : public ArkNativeObject, public NativeArray {
|
||||
public:
|
||||
explicit ArkNativeArray(ArkNativeEngine* engine, Local<JSValueRef> value);
|
||||
explicit ArkNativeArray(ArkNativeEngine* engine, uint32_t length);
|
||||
~ArkNativeArray() override;
|
||||
|
||||
void* GetInterface(int interfaceId) override;
|
||||
|
||||
bool SetElement(uint32_t index, NativeValue* value) override;
|
||||
NativeValue* GetElement(uint32_t index) override;
|
||||
bool HasElement(uint32_t index) override;
|
||||
bool DeleteElement(uint32_t index) override;
|
||||
|
||||
uint32_t GetLength() override;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_ARRAY_H */
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ark_native_array_buffer.h"
|
||||
|
||||
using panda::ArrayBufferRef;
|
||||
ArkNativeArrayBuffer::ArkNativeArrayBuffer(ArkNativeEngine* engine, Local<JSValueRef> value)
|
||||
: ArkNativeObject(engine, value)
|
||||
{
|
||||
}
|
||||
|
||||
ArkNativeArrayBuffer::ArkNativeArrayBuffer(ArkNativeEngine* engine, uint8_t** value, size_t length)
|
||||
: ArkNativeArrayBuffer(engine, JSValueRef::Undefined(engine->GetEcmaVm()))
|
||||
{
|
||||
auto vm = engine->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
value_ = Global<ArrayBufferRef>(vm, ArrayBufferRef::New(vm, length));
|
||||
if (value != nullptr) {
|
||||
Global<ArrayBufferRef> obj = value_;
|
||||
*value = reinterpret_cast<uint8_t*>(obj->GetBuffer());
|
||||
}
|
||||
}
|
||||
|
||||
ArkNativeArrayBuffer::ArkNativeArrayBuffer(ArkNativeEngine* engine,
|
||||
uint8_t* value,
|
||||
size_t length,
|
||||
NativeFinalize cb,
|
||||
void* hint)
|
||||
: ArkNativeArrayBuffer(engine, JSValueRef::Undefined(engine->GetEcmaVm()))
|
||||
{
|
||||
auto vm = engine->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
|
||||
NativeObjectInfo* cbinfo = NativeObjectInfo::CreateNewInstance();
|
||||
cbinfo->engine = engine_;
|
||||
cbinfo->callback = cb;
|
||||
cbinfo->hint = hint;
|
||||
|
||||
Local<ArrayBufferRef> object = ArrayBufferRef::New(vm, value, length,
|
||||
[](void* data, void* info) {
|
||||
auto externalInfo = reinterpret_cast<NativeObjectInfo*>(info);
|
||||
auto engine = externalInfo->engine;
|
||||
auto callback = externalInfo->callback;
|
||||
auto hint = externalInfo->hint;
|
||||
callback(engine, data, hint);
|
||||
delete externalInfo;
|
||||
},
|
||||
cbinfo);
|
||||
|
||||
value_ = Global<ArrayBufferRef>(vm, object);
|
||||
}
|
||||
|
||||
ArkNativeArrayBuffer::~ArkNativeArrayBuffer() {}
|
||||
|
||||
void* ArkNativeArrayBuffer::GetInterface(int interfaceId)
|
||||
{
|
||||
return (NativeArrayBuffer::INTERFACE_ID == interfaceId) ? (NativeArrayBuffer*)this
|
||||
: ArkNativeObject::GetInterface(interfaceId);
|
||||
}
|
||||
|
||||
void* ArkNativeArrayBuffer::GetBuffer()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<ArrayBufferRef> v = value_;
|
||||
return v->GetBuffer();
|
||||
}
|
||||
|
||||
size_t ArkNativeArrayBuffer::GetLength()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<ArrayBufferRef> v = value_;
|
||||
return v->ByteLength(vm);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_ARRAY_BUFFER_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_ARRAY_BUFFER_H
|
||||
|
||||
#include "ark_native_object.h"
|
||||
|
||||
class ArkNativeArrayBuffer : public ArkNativeObject, public NativeArrayBuffer {
|
||||
public:
|
||||
ArkNativeArrayBuffer(ArkNativeEngine* engine, Local<JSValueRef> value);
|
||||
ArkNativeArrayBuffer(ArkNativeEngine* engine, uint8_t** data, size_t length);
|
||||
ArkNativeArrayBuffer(ArkNativeEngine* engine, uint8_t* data, size_t length, NativeFinalize cb, void* hint);
|
||||
~ArkNativeArrayBuffer() override;
|
||||
|
||||
void* GetInterface(int interfaceId) override;
|
||||
|
||||
void* GetBuffer() override;
|
||||
size_t GetLength() override;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_ARRAY_BUFFER_H */
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ark_native_boolean.h"
|
||||
|
||||
using panda::BooleanRef;
|
||||
ArkNativeBoolean::ArkNativeBoolean(ArkNativeEngine* engine, Local<JSValueRef> value) : ArkNativeValue(engine, value) {}
|
||||
|
||||
ArkNativeBoolean::ArkNativeBoolean(ArkNativeEngine* engine, bool value)
|
||||
: ArkNativeBoolean(engine, JSValueRef::Undefined(engine->GetEcmaVm()))
|
||||
{
|
||||
auto vm = engine->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Local<BooleanRef> object = BooleanRef::New(vm, value);
|
||||
value_ = Global<JSValueRef>(vm, object);
|
||||
}
|
||||
|
||||
ArkNativeBoolean::~ArkNativeBoolean() {}
|
||||
|
||||
void* ArkNativeBoolean::GetInterface(int interfaceId)
|
||||
{
|
||||
return (NativeBoolean::INTERFACE_ID == interfaceId) ? (NativeBoolean*)this : nullptr;
|
||||
}
|
||||
|
||||
ArkNativeBoolean::operator bool()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<BooleanRef> value = value_;
|
||||
return value->Value();
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_BOOLEAN_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_BOOLEAN_H
|
||||
|
||||
#include "ark_native_value.h"
|
||||
|
||||
class ArkNativeBoolean : public ArkNativeValue, public NativeBoolean {
|
||||
public:
|
||||
ArkNativeBoolean(ArkNativeEngine* engine, Local<JSValueRef> value);
|
||||
ArkNativeBoolean(ArkNativeEngine* engine, bool value);
|
||||
~ArkNativeBoolean() override;
|
||||
|
||||
void* GetInterface(int interfaceId) override;
|
||||
|
||||
operator bool() override;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_BOOLEAN_H */
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ark_native_data_view.h"
|
||||
#include "ark_native_array_buffer.h"
|
||||
|
||||
using panda::DataViewRef;
|
||||
using panda::ArrayBufferRef;
|
||||
ArkNativeDataView::ArkNativeDataView(ArkNativeEngine* engine, Local<JSValueRef> value) : ArkNativeObject(engine, value)
|
||||
{
|
||||
}
|
||||
|
||||
ArkNativeDataView::ArkNativeDataView(ArkNativeEngine* engine, NativeValue* value, size_t length, size_t offset)
|
||||
: ArkNativeDataView(engine, JSValueRef::Undefined(engine->GetEcmaVm()))
|
||||
{
|
||||
auto vm = engine->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<ArrayBufferRef> arraybuffer = *value;
|
||||
Local<DataViewRef> dataView = DataViewRef::New(vm, arraybuffer.ToLocal(vm), offset, length);
|
||||
value_ = Global<DataViewRef>(vm, dataView);
|
||||
}
|
||||
|
||||
ArkNativeDataView::~ArkNativeDataView() {}
|
||||
|
||||
void* ArkNativeDataView::GetInterface(int interfaceId)
|
||||
{
|
||||
return (NativeDataView::INTERFACE_ID == interfaceId) ? (NativeDataView*)this
|
||||
: ArkNativeObject::GetInterface(interfaceId);
|
||||
}
|
||||
|
||||
void* ArkNativeDataView::GetBuffer()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<DataViewRef> value = value_;
|
||||
|
||||
return value->GetArrayBuffer(vm)->GetBuffer();
|
||||
}
|
||||
|
||||
size_t ArkNativeDataView::GetLength()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<DataViewRef> value = value_;
|
||||
|
||||
return value->ByteLength();
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeDataView::GetArrayBuffer()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<DataViewRef> value = value_;
|
||||
|
||||
return new ArkNativeArrayBuffer(engine_, value->GetArrayBuffer(vm));
|
||||
}
|
||||
|
||||
size_t ArkNativeDataView::GetOffset()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<DataViewRef> value = value_;
|
||||
|
||||
return value->ByteOffset();
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_DATA_VIEW_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_DATA_VIEW_H
|
||||
|
||||
#include "ark_native_object.h"
|
||||
|
||||
class ArkNativeDataView : public ArkNativeObject, public NativeDataView {
|
||||
public:
|
||||
ArkNativeDataView(ArkNativeEngine* engine, Local<JSValueRef> value);
|
||||
ArkNativeDataView(ArkNativeEngine* engine, NativeValue* value, size_t length, size_t offset);
|
||||
~ArkNativeDataView() override;
|
||||
|
||||
void* GetInterface(int interfaceId) override;
|
||||
|
||||
void* GetBuffer() override;
|
||||
size_t GetLength() override;
|
||||
NativeValue* GetArrayBuffer() override;
|
||||
size_t GetOffset() override;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_DATA_VIEW_H */
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ark_native_external.h"
|
||||
#include "ark_native_reference.h"
|
||||
|
||||
using panda::NativePointerRef;
|
||||
|
||||
ArkNativeExternal::ArkNativeExternal(ArkNativeEngine* engine, void* value, NativeFinalize callback, void* hint)
|
||||
: ArkNativeExternal(engine, JSValueRef::Undefined(engine->GetEcmaVm()))
|
||||
{
|
||||
auto vm = engine->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
|
||||
NativeObjectInfo* info = NativeObjectInfo::CreateNewInstance();
|
||||
info->engine = engine;
|
||||
info->nativeObject = nullptr;
|
||||
info->callback = callback;
|
||||
info->hint = hint;
|
||||
|
||||
Local<NativePointerRef> object = NativePointerRef::New(vm, value, ArkExternalDeleterCallback, info);
|
||||
value_ = Global<NativePointerRef>(vm, object);
|
||||
}
|
||||
|
||||
ArkNativeExternal::ArkNativeExternal(ArkNativeEngine* engine, Local<JSValueRef> value) : ArkNativeValue(engine, value) {}
|
||||
|
||||
ArkNativeExternal::~ArkNativeExternal()
|
||||
{
|
||||
}
|
||||
|
||||
void* ArkNativeExternal::GetInterface(int interfaceId)
|
||||
{
|
||||
return (NativeExternal::INTERFACE_ID == interfaceId) ? (NativeExternal*)this : nullptr;
|
||||
}
|
||||
|
||||
ArkNativeExternal::operator void*()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<NativePointerRef> value = value_;
|
||||
return value->Value();
|
||||
}
|
||||
|
||||
// static
|
||||
void ArkNativeExternal::ArkExternalDeleterCallback(void* data, void* info)
|
||||
{
|
||||
auto externalInfo = reinterpret_cast<NativeObjectInfo*>(info);
|
||||
auto engine = externalInfo->engine;
|
||||
auto callback = externalInfo->callback;
|
||||
auto hint = externalInfo->hint;
|
||||
callback(engine, data, hint);
|
||||
delete externalInfo;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_EXTERNAL_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_EXTERNAL_H
|
||||
|
||||
#include "ark_native_value.h"
|
||||
|
||||
class ArkNativeExternal : public ArkNativeValue, public NativeExternal {
|
||||
public:
|
||||
ArkNativeExternal(ArkNativeEngine* engine, void* value, NativeFinalize callback, void* hint);
|
||||
ArkNativeExternal(ArkNativeEngine* engine, Local<JSValueRef> value);
|
||||
~ArkNativeExternal() override;
|
||||
|
||||
void* GetInterface(int interfaceId) override;
|
||||
|
||||
operator void*() override;
|
||||
|
||||
private:
|
||||
static void ArkExternalDeleterCallback(void* data, void* info);
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_EXTERNAL_H */
|
||||
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ark_native_function.h"
|
||||
|
||||
#include "utils/log.h"
|
||||
|
||||
using panda::ArrayRef;
|
||||
using panda::NativePointerRef;
|
||||
using panda::FunctionRef;
|
||||
using panda::StringRef;
|
||||
ArkNativeFunction::ArkNativeFunction(ArkNativeEngine* engine, Local<JSValueRef> value) : ArkNativeObject(engine, value)
|
||||
{
|
||||
}
|
||||
|
||||
// common function
|
||||
ArkNativeFunction::ArkNativeFunction(ArkNativeEngine* engine,
|
||||
const char* name,
|
||||
size_t length,
|
||||
NativeCallback cb,
|
||||
void* value)
|
||||
: ArkNativeFunction(engine, JSValueRef::Undefined(engine->GetEcmaVm()))
|
||||
{
|
||||
auto vm = const_cast<EcmaVM*>(engine->GetEcmaVm());
|
||||
LocalScope scope(vm);
|
||||
|
||||
NativeFunctionInfo* funcInfo = NativeFunctionInfo::CreateNewInstance();
|
||||
funcInfo->engine = engine;
|
||||
funcInfo->callback = cb;
|
||||
funcInfo->data = value;
|
||||
|
||||
Local<FunctionRef> fn = FunctionRef::New(vm, NativeFunctionCallBack,
|
||||
[](void* data, void* hint) {
|
||||
auto info = reinterpret_cast<NativeFunctionInfo*>(data);
|
||||
if (info != nullptr) {
|
||||
delete info;
|
||||
}
|
||||
},
|
||||
reinterpret_cast<void*>(funcInfo));
|
||||
Local<StringRef> fnName = StringRef::NewFromUtf8(vm, name);
|
||||
fn->SetName(vm, fnName);
|
||||
|
||||
Global<JSValueRef> globalFn(vm, fn);
|
||||
value_ = globalFn;
|
||||
}
|
||||
|
||||
|
||||
// class function
|
||||
ArkNativeFunction::ArkNativeFunction(ArkNativeEngine* engine,
|
||||
const char* name,
|
||||
NativeCallback cb,
|
||||
void* value)
|
||||
: ArkNativeFunction(engine, JSValueRef::Undefined(engine->GetEcmaVm()))
|
||||
{
|
||||
auto vm = const_cast<EcmaVM*>(engine->GetEcmaVm());
|
||||
LocalScope scope(vm);
|
||||
|
||||
NativeFunctionInfo* funcInfo = NativeFunctionInfo::CreateNewInstance();
|
||||
funcInfo->engine = engine;
|
||||
funcInfo->callback = cb;
|
||||
funcInfo->data = value;
|
||||
|
||||
Local<FunctionRef> fn = FunctionRef::NewClassFunction(vm, NativeClassFunctionCallBack,
|
||||
[](void* data, void* hint) {
|
||||
auto info = reinterpret_cast<NativeFunctionInfo*>(data);
|
||||
if (info != nullptr) {
|
||||
delete info;
|
||||
}
|
||||
},
|
||||
reinterpret_cast<void*>(funcInfo));
|
||||
Local<StringRef> fnName = StringRef::NewFromUtf8(vm, name);
|
||||
fn->SetName(vm, fnName);
|
||||
|
||||
Global<JSValueRef> globalFn(vm, fn);
|
||||
value_ = globalFn;
|
||||
}
|
||||
|
||||
ArkNativeFunction::~ArkNativeFunction()
|
||||
{
|
||||
}
|
||||
|
||||
void* ArkNativeFunction::GetInterface(int interfaceId)
|
||||
{
|
||||
return (NativeFunction::INTERFACE_ID == interfaceId) ? (NativeFunction*)this
|
||||
: ArkNativeObject::GetInterface(interfaceId);
|
||||
}
|
||||
|
||||
Local<JSValueRef> ArkNativeFunction::NativeFunctionCallBack(EcmaVM* vm,
|
||||
Local<JSValueRef> thisObj,
|
||||
const Local<JSValueRef> argv[],
|
||||
int32_t length,
|
||||
void* data)
|
||||
{
|
||||
panda::EscapeLocalScope scope(vm);
|
||||
auto info = reinterpret_cast<NativeFunctionInfo*>(data);
|
||||
auto engine = reinterpret_cast<ArkNativeEngine*>(info->engine);
|
||||
auto cb = info->callback;
|
||||
if (engine == nullptr) {
|
||||
HILOG_ERROR("native engine is null");
|
||||
return JSValueRef::Undefined(vm);
|
||||
}
|
||||
|
||||
NativeCallbackInfo cbInfo = { 0 };
|
||||
NativeScopeManager* scopeManager = engine->GetScopeManager();
|
||||
if (scopeManager == nullptr) {
|
||||
HILOG_ERROR("scope manager is null");
|
||||
return JSValueRef::Undefined(vm);
|
||||
}
|
||||
NativeScope* nativeScope = scopeManager->Open();
|
||||
cbInfo.thisVar = ArkNativeEngine::ArkValueToNativeValue(engine, thisObj);
|
||||
cbInfo.function = nullptr;
|
||||
cbInfo.argc = length;
|
||||
cbInfo.argv = nullptr;
|
||||
cbInfo.functionInfo = info;
|
||||
if (cbInfo.argc > 0) {
|
||||
cbInfo.argv = new NativeValue* [cbInfo.argc];
|
||||
for (size_t i = 0; i < cbInfo.argc; i++) {
|
||||
cbInfo.argv[i] = ArkNativeEngine::ArkValueToNativeValue(engine, argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
NativeValue* result = nullptr;
|
||||
if (cb != nullptr) {
|
||||
result = cb(engine, &cbInfo);
|
||||
}
|
||||
|
||||
if (cbInfo.argv != nullptr) {
|
||||
delete[] cbInfo.argv;
|
||||
cbInfo.argv = nullptr;
|
||||
}
|
||||
|
||||
Global<JSValueRef> ret(vm, JSValueRef::Undefined(vm));
|
||||
if (result == nullptr) {
|
||||
if (engine->IsExceptionPending()) {
|
||||
NativeValue* error = engine->GetAndClearLastException();
|
||||
if (error != nullptr) {
|
||||
ret = *error;
|
||||
}
|
||||
} else {
|
||||
ret = Global<JSValueRef>(vm, JSValueRef::Undefined(vm));
|
||||
}
|
||||
} else {
|
||||
ret = *result;
|
||||
}
|
||||
auto localRet = ret.ToLocal(vm);
|
||||
scopeManager->Close(nativeScope);
|
||||
return scope.Escape(localRet);
|
||||
}
|
||||
|
||||
Local<JSValueRef> ArkNativeFunction::NativeClassFunctionCallBack(EcmaVM* vm,
|
||||
Local<JSValueRef> function,
|
||||
Local<JSValueRef> newTarget,
|
||||
const Local<JSValueRef> argv[],
|
||||
int32_t length,
|
||||
void* data)
|
||||
{
|
||||
panda::EscapeLocalScope scope(vm);
|
||||
auto info = reinterpret_cast<NativeFunctionInfo*>(data);
|
||||
auto engine = reinterpret_cast<ArkNativeEngine*>(info->engine);
|
||||
auto cb = info->callback;
|
||||
if (engine == nullptr) {
|
||||
HILOG_ERROR("native engine is null");
|
||||
return JSValueRef::Undefined(vm);
|
||||
}
|
||||
|
||||
NativeCallbackInfo cbInfo = { 0 };
|
||||
NativeScopeManager* scopeManager = engine->GetScopeManager();
|
||||
if (scopeManager == nullptr) {
|
||||
HILOG_ERROR("scope manager is null");
|
||||
return JSValueRef::Undefined(vm);
|
||||
}
|
||||
NativeScope* nativeScope = scopeManager->Open();
|
||||
cbInfo.thisVar = ArkNativeEngine::ArkValueToNativeValue(engine, function);
|
||||
cbInfo.function = ArkNativeEngine::ArkValueToNativeValue(engine, newTarget);
|
||||
cbInfo.argc = length;
|
||||
cbInfo.argv = nullptr;
|
||||
cbInfo.functionInfo = info;
|
||||
if (cbInfo.argc > 0) {
|
||||
cbInfo.argv = new NativeValue* [cbInfo.argc];
|
||||
for (size_t i = 0; i < cbInfo.argc; i++) {
|
||||
cbInfo.argv[i] = ArkNativeEngine::ArkValueToNativeValue(engine, argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
NativeValue* result = nullptr;
|
||||
if (cb != nullptr) {
|
||||
result = cb(engine, &cbInfo);
|
||||
}
|
||||
|
||||
if (cbInfo.argv != nullptr) {
|
||||
delete[] cbInfo.argv;
|
||||
cbInfo.argv = nullptr;
|
||||
}
|
||||
|
||||
Global<JSValueRef> ret(vm, JSValueRef::Undefined(vm));
|
||||
if (result == nullptr) {
|
||||
if (engine->IsExceptionPending()) {
|
||||
NativeValue* error = engine->GetAndClearLastException();
|
||||
if (error != nullptr) {
|
||||
ret = *error;
|
||||
}
|
||||
} else {
|
||||
ret = Global<JSValueRef>(vm, JSValueRef::Undefined(vm));
|
||||
}
|
||||
} else {
|
||||
ret = *result;
|
||||
}
|
||||
auto localRet = ret.ToLocal(vm);
|
||||
scopeManager->Close(nativeScope);
|
||||
return scope.Escape(localRet);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeFunction::GetFunctionPrototype()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<FunctionRef> func = value_;
|
||||
Local<JSValueRef> prototype = func->GetFunctionPrototype(vm);
|
||||
return ArkNativeEngine::ArkValueToNativeValue(engine_, prototype);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_FUNCTION_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_FUNCTION_H
|
||||
|
||||
#include "ark_native_object.h"
|
||||
|
||||
class ArkNativeFunction : public ArkNativeObject, public NativeFunction {
|
||||
public:
|
||||
ArkNativeFunction(ArkNativeEngine* engine, Local<JSValueRef> value);
|
||||
ArkNativeFunction(ArkNativeEngine* engine, const char* name, size_t length, NativeCallback cb, void* value);
|
||||
ArkNativeFunction(ArkNativeEngine* engine, const char* name, NativeCallback cb, void* value); // Used for class
|
||||
~ArkNativeFunction() override;
|
||||
|
||||
void* GetInterface(int interfaceId) override;
|
||||
|
||||
NativeValue* GetFunctionPrototype();
|
||||
|
||||
private:
|
||||
static Local<JSValueRef> NativeFunctionCallBack(EcmaVM* vm,
|
||||
Local<JSValueRef> thisObj,
|
||||
const Local<JSValueRef> argv[],
|
||||
int32_t length,
|
||||
void* data);
|
||||
static Local<JSValueRef> NativeClassFunctionCallBack(EcmaVM* vm,
|
||||
Local<JSValueRef> function,
|
||||
Local<JSValueRef> newTarget,
|
||||
const Local<JSValueRef> argv[],
|
||||
int32_t length,
|
||||
void* data);
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_FUNCTION_H */
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ark_native_number.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
using panda::NumberRef;
|
||||
ArkNativeNumber::ArkNativeNumber(ArkNativeEngine* engine, Local<JSValueRef> value) : ArkNativeValue(engine, value) {}
|
||||
|
||||
ArkNativeNumber::ArkNativeNumber(ArkNativeEngine* engine, int32_t value)
|
||||
: ArkNativeNumber(engine, JSValueRef::Undefined(engine->GetEcmaVm()))
|
||||
{
|
||||
auto vm = engine->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Local<NumberRef> object = NumberRef::New(vm, value);
|
||||
value_ = Global<NumberRef>(vm, object);
|
||||
}
|
||||
|
||||
ArkNativeNumber::ArkNativeNumber(ArkNativeEngine* engine, uint32_t value)
|
||||
: ArkNativeNumber(engine, JSValueRef::Undefined(engine->GetEcmaVm()))
|
||||
{
|
||||
auto vm = engine->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Local<NumberRef> object = NumberRef::New(vm, value);
|
||||
value_ = Global<NumberRef>(vm, object);
|
||||
}
|
||||
|
||||
ArkNativeNumber::ArkNativeNumber(ArkNativeEngine* engine, int64_t value)
|
||||
: ArkNativeNumber(engine, JSValueRef::Undefined(engine->GetEcmaVm()))
|
||||
{
|
||||
auto vm = engine->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Local<NumberRef> object = NumberRef::New(vm, value);
|
||||
value_ = Global<NumberRef>(vm, object);
|
||||
}
|
||||
|
||||
ArkNativeNumber::ArkNativeNumber(ArkNativeEngine* engine, double value)
|
||||
: ArkNativeNumber(engine, JSValueRef::Undefined(engine->GetEcmaVm()))
|
||||
{
|
||||
auto vm = engine->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Local<NumberRef> object = NumberRef::New(vm, value);
|
||||
value_ = Global<NumberRef>(vm, object);
|
||||
}
|
||||
|
||||
ArkNativeNumber::~ArkNativeNumber() {}
|
||||
|
||||
void* ArkNativeNumber::GetInterface(int interfaceId)
|
||||
{
|
||||
return (NativeNumber::INTERFACE_ID == interfaceId) ? (NativeNumber*)this : nullptr;
|
||||
}
|
||||
|
||||
ArkNativeNumber::operator int32_t()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<JSValueRef> value = value_;
|
||||
return value->Int32Value(vm);
|
||||
}
|
||||
|
||||
ArkNativeNumber::operator uint32_t()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<JSValueRef> value = value_;
|
||||
return value->Uint32Value(vm);
|
||||
}
|
||||
|
||||
ArkNativeNumber::operator int64_t()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<JSValueRef> value = value_;
|
||||
return value->IntegerValue(vm);
|
||||
}
|
||||
|
||||
ArkNativeNumber::operator double()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<JSValueRef> value = value_;
|
||||
Local<NumberRef> number(value.ToLocal(vm));
|
||||
return number->Value();
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_NUMBER_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_NUMBER_H
|
||||
|
||||
#include "ark_native_value.h"
|
||||
|
||||
class ArkNativeNumber : public ArkNativeValue, public NativeNumber {
|
||||
public:
|
||||
ArkNativeNumber(ArkNativeEngine* engine, Local<JSValueRef> value);
|
||||
ArkNativeNumber(ArkNativeEngine* engine, int32_t value);
|
||||
ArkNativeNumber(ArkNativeEngine* engine, uint32_t value);
|
||||
ArkNativeNumber(ArkNativeEngine* engine, int64_t value);
|
||||
ArkNativeNumber(ArkNativeEngine* engine, double value);
|
||||
~ArkNativeNumber() override;
|
||||
|
||||
void* GetInterface(int interfaceId) override;
|
||||
|
||||
operator int32_t() override;
|
||||
operator uint32_t() override;
|
||||
operator int64_t() override;
|
||||
operator double() override;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_NUMBER_H */
|
||||
@@ -0,0 +1,271 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ark_native_object.h"
|
||||
|
||||
#include "native_engine/native_property.h"
|
||||
#include "ark_headers.h"
|
||||
#include "ark_native_array.h"
|
||||
#include "ark_native_external.h"
|
||||
#include "ark_native_function.h"
|
||||
#include "ark_native_reference.h"
|
||||
|
||||
#include "utils/log.h"
|
||||
|
||||
using panda::ObjectRef;
|
||||
using panda::StringRef;
|
||||
using panda::NativePointerRef;
|
||||
using panda::ArrayRef;
|
||||
using panda::PropertyAttribute;
|
||||
ArkNativeObject::ArkNativeObject(ArkNativeEngine* engine)
|
||||
: ArkNativeObject(engine, JSValueRef::Undefined(engine->GetEcmaVm()))
|
||||
{
|
||||
auto vm = engine->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Local<ObjectRef> object = ObjectRef::New(vm);
|
||||
value_ = Global<ObjectRef>(vm, object);
|
||||
}
|
||||
|
||||
ArkNativeObject::ArkNativeObject(ArkNativeEngine* engine, Local<JSValueRef> value) : ArkNativeValue(engine, value) {}
|
||||
|
||||
ArkNativeObject::~ArkNativeObject() {}
|
||||
|
||||
void* ArkNativeObject::GetInterface(int interfaceId)
|
||||
{
|
||||
return (NativeObject::INTERFACE_ID == interfaceId) ? (NativeObject*)this : nullptr;
|
||||
}
|
||||
|
||||
void ArkNativeObject::SetNativePointer(void* pointer, NativeFinalize cb, void* hint)
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<ObjectRef> value = value_;
|
||||
|
||||
NativeObjectInfo* objInfo = NativeObjectInfo::CreateNewInstance();
|
||||
objInfo->engine = engine_;
|
||||
objInfo->nativeObject = nullptr;
|
||||
objInfo->callback = cb;
|
||||
objInfo->hint = hint;
|
||||
|
||||
Local<NativePointerRef> object = NativePointerRef::New(vm, pointer,
|
||||
[](void* data, void* info) {
|
||||
auto externalInfo = reinterpret_cast<NativeObjectInfo*>(info);
|
||||
auto engine = externalInfo->engine;
|
||||
auto callback = externalInfo->callback;
|
||||
auto hint = externalInfo->hint;
|
||||
callback(engine, data, hint);
|
||||
delete externalInfo;
|
||||
},
|
||||
objInfo);
|
||||
|
||||
Local<StringRef> key = StringRef::NewFromUtf8(vm, "_napiwrapper");
|
||||
bool has = value->Has(vm, key);
|
||||
if (!has) {
|
||||
value->Set(vm, key, object);
|
||||
}
|
||||
}
|
||||
|
||||
void* ArkNativeObject::GetNativePointer()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<ObjectRef> value = value_;
|
||||
Local<StringRef> key = StringRef::NewFromUtf8(vm, "_napiwrapper");
|
||||
Local<JSValueRef> val = value->Get(vm, key);
|
||||
void* result = nullptr;
|
||||
if (val->IsNativeObject() || val->IsNativePointer()) {
|
||||
Local<NativePointerRef> ext(val);
|
||||
result = ext->Value();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeObject::GetPropertyNames()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<ObjectRef> val = value_;
|
||||
Local<ArrayRef> arrayVal = val->GetOwnEnumerablePropertyNames(vm);
|
||||
|
||||
return new ArkNativeArray(engine_, arrayVal);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeObject::GetPrototype()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<ObjectRef> obj = value_;
|
||||
Local<JSValueRef> val = obj->GetPrototype(vm);
|
||||
|
||||
return ArkNativeEngine::ArkValueToNativeValue(engine_, val);
|
||||
}
|
||||
|
||||
bool ArkNativeObject::DefineProperty(NativePropertyDescriptor propertyDescriptor)
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<ObjectRef> obj = value_;
|
||||
bool result = false;
|
||||
Local<StringRef> propertyName = StringRef::NewFromUtf8(vm, propertyDescriptor.utf8name);
|
||||
|
||||
bool writable = (propertyDescriptor.attributes & NATIVE_WRITABLE) != 0;
|
||||
bool enumable = (propertyDescriptor.attributes & NATIVE_ENUMERABLE) != 0;
|
||||
bool configable = (propertyDescriptor.attributes & NATIVE_CONFIGURABLE) != 0;
|
||||
|
||||
NativeScopeManager* scopeManager = engine_->GetScopeManager();
|
||||
if (scopeManager == nullptr) {
|
||||
HILOG_ERROR("scope manager is null");
|
||||
return false;
|
||||
}
|
||||
NativeScope* nativeScope = scopeManager->Open();
|
||||
if (propertyDescriptor.getter != nullptr || propertyDescriptor.setter != nullptr) {
|
||||
Global<JSValueRef> localGetter(vm, JSValueRef::Undefined(vm));
|
||||
Global<JSValueRef> localSetter(vm, JSValueRef::Undefined(vm));
|
||||
|
||||
if (propertyDescriptor.getter != nullptr) {
|
||||
NativeValue* getter =
|
||||
new ArkNativeFunction(engine_, "getter", 0, propertyDescriptor.getter, propertyDescriptor.data);
|
||||
localGetter = *getter;
|
||||
}
|
||||
if (propertyDescriptor.setter != nullptr) {
|
||||
NativeValue* setter =
|
||||
new ArkNativeFunction(engine_, "setter", 0, propertyDescriptor.setter, propertyDescriptor.data);
|
||||
localSetter = *setter;
|
||||
}
|
||||
|
||||
PropertyAttribute attr(JSValueRef::Undefined(engine_->GetEcmaVm()), false, enumable, configable);
|
||||
result = obj->SetAccessorProperty(vm, propertyName, localGetter.ToLocal(vm), localSetter.ToLocal(vm), attr);
|
||||
} else if (propertyDescriptor.method != nullptr) {
|
||||
NativeValue* cb = new ArkNativeFunction(engine_, propertyDescriptor.utf8name, 0, propertyDescriptor.method,
|
||||
propertyDescriptor.data);
|
||||
Global<JSValueRef> globalCb = *cb;
|
||||
PropertyAttribute attr(globalCb.ToLocal(vm), writable, enumable, configable);
|
||||
result = obj->DefineProperty(vm, propertyName, attr);
|
||||
} else {
|
||||
Global<JSValueRef> value = *(propertyDescriptor.value);
|
||||
|
||||
PropertyAttribute attr(value.ToLocal(vm), writable, enumable, configable);
|
||||
result = obj->DefineProperty(vm, propertyName, attr);
|
||||
}
|
||||
scopeManager->Close(nativeScope);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ArkNativeObject::SetProperty(NativeValue* key, NativeValue* value)
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<ObjectRef> obj = value_;
|
||||
Global<JSValueRef> k = *key;
|
||||
Global<JSValueRef> val = *value;
|
||||
|
||||
return obj->Set(vm, k.ToLocal(vm), val.ToLocal(vm));
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeObject::GetProperty(NativeValue* key)
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<JSValueRef> k = *key;
|
||||
Global<ObjectRef> obj = value_;
|
||||
|
||||
Local<JSValueRef> val = obj->Get(vm, k.ToLocal(vm));
|
||||
return ArkNativeEngine::ArkValueToNativeValue(engine_, val);
|
||||
}
|
||||
|
||||
bool ArkNativeObject::HasProperty(NativeValue* key)
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<ObjectRef> obj = value_;
|
||||
Global<JSValueRef> k = *key;
|
||||
|
||||
return obj->Has(vm, k.ToLocal(vm));
|
||||
}
|
||||
|
||||
bool ArkNativeObject::DeleteProperty(NativeValue* key)
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<JSValueRef> k = *key;
|
||||
Global<ObjectRef> obj = value_;
|
||||
|
||||
return obj->Delete(vm, k.ToLocal(vm));
|
||||
}
|
||||
|
||||
bool ArkNativeObject::SetProperty(const char* name, NativeValue* value)
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
|
||||
Global<ObjectRef> obj = value_;
|
||||
Local<StringRef> key = StringRef::NewFromUtf8(vm, name);
|
||||
Global<JSValueRef> val = *value;
|
||||
|
||||
return obj->Set(vm, key, val.ToLocal(vm));
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeObject::GetProperty(const char* name)
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
|
||||
Local<StringRef> key = StringRef::NewFromUtf8(vm, name);
|
||||
Global<ObjectRef> obj = value_;
|
||||
Local<JSValueRef> val = obj->Get(vm, key);
|
||||
return ArkNativeEngine::ArkValueToNativeValue(engine_, val);
|
||||
}
|
||||
|
||||
bool ArkNativeObject::HasProperty(const char* name)
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
|
||||
Local<StringRef> key = StringRef::NewFromUtf8(vm, name);
|
||||
Global<ObjectRef> obj = value_;
|
||||
|
||||
return obj->Has(vm, key);
|
||||
}
|
||||
|
||||
bool ArkNativeObject::DeleteProperty(const char* name)
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
|
||||
Local<StringRef> key = StringRef::NewFromUtf8(vm, name);
|
||||
Global<ObjectRef> obj = value_;
|
||||
|
||||
return obj->Delete(vm, key);
|
||||
}
|
||||
|
||||
bool ArkNativeObject::SetPrivateProperty(const char* name, NativeValue* value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeObject::GetPrivateProperty(const char* name)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool ArkNativeObject::HasPrivateProperty(const char* name)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ArkNativeObject::DeletePrivateProperty(const char* name)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_OBJECT_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_OBJECT_H
|
||||
|
||||
#include "ark_native_value.h"
|
||||
|
||||
class ArkNativeObject : public ArkNativeValue, public NativeObject {
|
||||
public:
|
||||
explicit ArkNativeObject(ArkNativeEngine* engine);
|
||||
ArkNativeObject(ArkNativeEngine* engine, Local<JSValueRef> value);
|
||||
~ArkNativeObject() override;
|
||||
|
||||
void* GetInterface(int interfaceId) override;
|
||||
|
||||
void SetNativePointer(void* pointer, NativeFinalize cb, void* hint) override;
|
||||
void* GetNativePointer() override;
|
||||
|
||||
NativeValue* GetPropertyNames() override;
|
||||
|
||||
NativeValue* GetPrototype() override;
|
||||
|
||||
bool DefineProperty(NativePropertyDescriptor propertyDescriptor) override;
|
||||
|
||||
bool SetProperty(NativeValue* key, NativeValue* value) override;
|
||||
NativeValue* GetProperty(NativeValue* key) override;
|
||||
bool HasProperty(NativeValue* key) override;
|
||||
bool DeleteProperty(NativeValue* key) override;
|
||||
|
||||
bool SetProperty(const char* name, NativeValue* value) override;
|
||||
NativeValue* GetProperty(const char* name) override;
|
||||
bool HasProperty(const char* name) override;
|
||||
bool DeleteProperty(const char* name) override;
|
||||
|
||||
bool SetPrivateProperty(const char* name, NativeValue* value) override;
|
||||
NativeValue* GetPrivateProperty(const char* name) override;
|
||||
bool HasPrivateProperty(const char* name) override;
|
||||
bool DeletePrivateProperty(const char* name) override;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_OBJECT_H */
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ark_native_string.h"
|
||||
#include "securec.h"
|
||||
#include "utils/log.h"
|
||||
|
||||
#include <codecvt>
|
||||
#include <locale>
|
||||
#include <string>
|
||||
#include <uchar.h>
|
||||
|
||||
using panda::StringRef;
|
||||
ArkNativeString::ArkNativeString(ArkNativeEngine* engine, const char* value, size_t length)
|
||||
: ArkNativeString(engine, JSValueRef::Undefined(engine->GetEcmaVm()))
|
||||
{
|
||||
auto vm = engine->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Local<StringRef> object = StringRef::NewFromUtf8(vm, value, length);
|
||||
value_ = Global<StringRef>(vm, object);
|
||||
}
|
||||
ArkNativeString::ArkNativeString(ArkNativeEngine* engine, Local<JSValueRef> value) : ArkNativeValue(engine, value) {}
|
||||
|
||||
ArkNativeString::~ArkNativeString() {}
|
||||
|
||||
void* ArkNativeString::GetInterface(int interfaceId)
|
||||
{
|
||||
return (NativeString::INTERFACE_ID == interfaceId) ? (NativeString*)this : nullptr;
|
||||
}
|
||||
|
||||
void ArkNativeString::GetCString(char* buffer, size_t size, size_t* length)
|
||||
{
|
||||
if (length == nullptr) {
|
||||
return;
|
||||
}
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<StringRef> val = value_;
|
||||
if (buffer == nullptr) {
|
||||
*length = val->Length();
|
||||
} else if (size != 0) {
|
||||
int copied = val->WriteUtf8(buffer, size) - 1;
|
||||
buffer[copied] = '\0';
|
||||
*length = copied;
|
||||
} else {
|
||||
*length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t ArkNativeString::GetLength()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<StringRef> value = value_;
|
||||
return value->Length();
|
||||
}
|
||||
|
||||
size_t ArkNativeString::EncodeWriteUtf8(char* buffer, size_t bufferSize, int32_t* nchars)
|
||||
{
|
||||
if (buffer == nullptr || nchars == nullptr) {
|
||||
HILOG_ERROR("buffer is null or nchars is null");
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<StringRef> val = value_;
|
||||
std::string valString = val->ToString();
|
||||
std::u16string src = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.from_bytes(valString);
|
||||
char* oldLocale = setlocale(LC_CTYPE, "");
|
||||
setlocale(LC_CTYPE, "en_US.UTF-8");
|
||||
|
||||
mbstate_t state;
|
||||
size_t pos = 0;
|
||||
size_t writableSize = bufferSize;
|
||||
char u8Char[4] = {};
|
||||
uint32_t i = 0;
|
||||
for (; i < src.length(); i++) {
|
||||
size_t rc = c16rtomb(u8Char, src.at(i), &state);
|
||||
if (rc == -1 || rc > writableSize) {
|
||||
break;
|
||||
}
|
||||
|
||||
int ret = memcpy_s((buffer + pos), writableSize, u8Char, rc);
|
||||
if (ret != EOK) {
|
||||
HILOG_ERROR("memcpy_s failed");
|
||||
break;
|
||||
}
|
||||
writableSize -= rc;
|
||||
pos += rc;
|
||||
}
|
||||
|
||||
setlocale(LC_CTYPE, oldLocale);
|
||||
*nchars = i;
|
||||
buffer[bufferSize] = '\0';
|
||||
HILOG_DEBUG("EncodeWriteUtf8 the result of buffer: %{public}s", buffer);
|
||||
return pos;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_STRING_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_STRING_H
|
||||
|
||||
#include "ark_native_value.h"
|
||||
|
||||
class ArkNativeString : public ArkNativeValue, public NativeString {
|
||||
public:
|
||||
ArkNativeString(ArkNativeEngine* engine, const char* value, size_t length);
|
||||
ArkNativeString(ArkNativeEngine* engine, Local<JSValueRef> value);
|
||||
~ArkNativeString() override;
|
||||
|
||||
void* GetInterface(int interfaceId) override;
|
||||
|
||||
void GetCString(char* buffer, size_t size, size_t* length) override;
|
||||
size_t GetLength() override;
|
||||
size_t EncodeWriteUtf8(char* buffer, size_t bufferSize, int32_t* nchars) override;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_STRING_H */
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ark_native_typed_array.h"
|
||||
|
||||
ArkNativeTypedArray::ArkNativeTypedArray(ArkNativeEngine* engine, Local<JSValueRef> value)
|
||||
: ArkNativeObject(engine, value)
|
||||
{
|
||||
}
|
||||
|
||||
ArkNativeTypedArray::ArkNativeTypedArray(ArkNativeEngine* engine,
|
||||
NativeTypedArrayType type,
|
||||
NativeValue* value,
|
||||
size_t length,
|
||||
size_t offset)
|
||||
: ArkNativeTypedArray(engine, JSValueRef::Undefined(engine->GetEcmaVm()))
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
|
||||
Global<JSValueRef> globalValue = *value;
|
||||
Local<JSValueRef> localValue = globalValue.ToLocal(vm);
|
||||
Local<ArrayBufferRef> buffer(localValue);
|
||||
|
||||
Local<TypedArrayRef> typedArray(JSValueRef::Undefined(vm));
|
||||
switch (type) {
|
||||
case NATIVE_INT8_ARRAY:
|
||||
typedArray = panda::Int8ArrayRef::New(vm, buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_UINT8_ARRAY:
|
||||
typedArray = panda::Uint8ArrayRef::New(vm, buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_UINT8_CLAMPED_ARRAY:
|
||||
typedArray = panda::Uint8ClampedArrayRef::New(vm, buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_INT16_ARRAY:
|
||||
typedArray = panda::Int16ArrayRef::New(vm, buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_UINT16_ARRAY:
|
||||
typedArray = panda::Uint16ArrayRef::New(vm, buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_INT32_ARRAY:
|
||||
typedArray = panda::Int32ArrayRef::New(vm, buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_UINT32_ARRAY:
|
||||
typedArray = panda::Uint32ArrayRef::New(vm, buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_FLOAT32_ARRAY:
|
||||
typedArray = panda::Float32ArrayRef::New(vm, buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_FLOAT64_ARRAY:
|
||||
typedArray = panda::Float64ArrayRef::New(vm, buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_BIGINT64_ARRAY:
|
||||
// not support yet
|
||||
break;
|
||||
case NATIVE_BIGUINT64_ARRAY:
|
||||
// not support yet
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
Global<JSValueRef> globalTypedArray(vm, typedArray);
|
||||
value_ = globalTypedArray;
|
||||
}
|
||||
|
||||
ArkNativeTypedArray::~ArkNativeTypedArray() {}
|
||||
|
||||
void* ArkNativeTypedArray::GetInterface(int interfaceId)
|
||||
{
|
||||
return (NativeTypedArray::INTERFACE_ID == interfaceId) ? (NativeTypedArray*)this
|
||||
: ArkNativeObject::GetInterface(interfaceId);
|
||||
}
|
||||
|
||||
NativeTypedArrayType ArkNativeTypedArray::GetTypedArrayType()
|
||||
{
|
||||
Global<TypedArrayRef> value = value_;
|
||||
NativeTypedArrayType type = NATIVE_INT8_ARRAY;
|
||||
if (value->IsInt8Array()) {
|
||||
type = NATIVE_INT8_ARRAY;
|
||||
} else if (value->IsUint8Array()) {
|
||||
type = NATIVE_UINT8_ARRAY;
|
||||
} else if (value->IsUint8ClampedArray()) {
|
||||
type = NATIVE_UINT8_CLAMPED_ARRAY;
|
||||
} else if (value->IsInt16Array()) {
|
||||
type = NATIVE_INT16_ARRAY;
|
||||
} else if (value->IsUint16Array()) {
|
||||
type = NATIVE_UINT16_ARRAY;
|
||||
} else if (value->IsInt32Array()) {
|
||||
type = NATIVE_INT32_ARRAY;
|
||||
} else if (value->IsUint32Array()) {
|
||||
type = NATIVE_UINT32_ARRAY;
|
||||
} else if (value->IsFloat32Array()) {
|
||||
type = NATIVE_FLOAT32_ARRAY;
|
||||
} else if (value->IsFloat64Array()) {
|
||||
type = NATIVE_FLOAT64_ARRAY;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
size_t ArkNativeTypedArray::GetLength()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<TypedArrayRef> value = value_;
|
||||
|
||||
return value->ByteLength(vm);
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeTypedArray::GetArrayBuffer()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<TypedArrayRef> value = value_;
|
||||
|
||||
return ArkNativeEngine::ArkValueToNativeValue(engine_, value->GetArrayBuffer(vm));
|
||||
}
|
||||
|
||||
void* ArkNativeTypedArray::GetData()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<TypedArrayRef> value = value_;
|
||||
|
||||
return value->GetArrayBuffer(vm)->GetBuffer();
|
||||
}
|
||||
|
||||
size_t ArkNativeTypedArray::GetOffset()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<TypedArrayRef> value = value_;
|
||||
|
||||
return value->ByteOffset(vm);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_TYPED_ARRAY_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_TYPED_ARRAY_H
|
||||
|
||||
#include "ark_native_object.h"
|
||||
|
||||
using panda::TypedArrayRef;
|
||||
using panda::ArrayBufferRef;
|
||||
class ArkNativeTypedArray : public ArkNativeObject, public NativeTypedArray {
|
||||
public:
|
||||
ArkNativeTypedArray(ArkNativeEngine* engine, Local<JSValueRef> value);
|
||||
ArkNativeTypedArray(ArkNativeEngine* engine,
|
||||
NativeTypedArrayType type,
|
||||
NativeValue* value,
|
||||
size_t length,
|
||||
size_t offset);
|
||||
~ArkNativeTypedArray() override;
|
||||
|
||||
void* GetInterface(int interfaceId) override;
|
||||
|
||||
NativeTypedArrayType GetTypedArrayType() override;
|
||||
size_t GetLength() override;
|
||||
NativeValue* GetArrayBuffer() override;
|
||||
void* GetData() override;
|
||||
size_t GetOffset() override;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_TYPED_ARRAY_H */
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ark_native_value.h"
|
||||
|
||||
ArkNativeValue::ArkNativeValue(ArkNativeEngine* engine, Local<JSValueRef> value)
|
||||
{
|
||||
engine_ = engine;
|
||||
Global<JSValueRef> globalValue(engine->GetEcmaVm(), value);
|
||||
value_ = globalValue;
|
||||
|
||||
NativeScopeManager* scopeManager = engine_->GetScopeManager();
|
||||
if (scopeManager != nullptr) {
|
||||
scopeManager->CreateHandle(this);
|
||||
}
|
||||
}
|
||||
|
||||
ArkNativeValue::~ArkNativeValue()
|
||||
{
|
||||
// Addr of Global stored in ArkNativeValue should be released.
|
||||
Global<JSValueRef> oldValue = value_;
|
||||
oldValue.FreeGlobalHandleAddr();
|
||||
}
|
||||
|
||||
void* ArkNativeValue::GetInterface(int interfaceId)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ArkNativeValue::UpdateValue(Local<JSValueRef> value)
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
Global<JSValueRef> oldValue = value_;
|
||||
oldValue.FreeGlobalHandleAddr();
|
||||
|
||||
Global<JSValueRef> newValue(vm, value);
|
||||
value_ = newValue;
|
||||
}
|
||||
|
||||
NativeValueType ArkNativeValue::TypeOf()
|
||||
{
|
||||
Global<JSValueRef> value = value_;
|
||||
NativeValueType result;
|
||||
|
||||
// TODO: optimize it
|
||||
if (value->IsNumber()) {
|
||||
result = NATIVE_NUMBER;
|
||||
} else if (value->IsString()) {
|
||||
result = NATIVE_STRING;
|
||||
} else if (value->IsFunction()) {
|
||||
result = NATIVE_FUNCTION;
|
||||
} else if (value->IsNativeObject() || value->IsNativePointer()) {
|
||||
result = NATIVE_EXTERNAL;
|
||||
} else if (value->IsNull()) {
|
||||
result = NATIVE_NULL;
|
||||
} else if (value->IsBoolean()) {
|
||||
result = NATIVE_BOOLEAN;
|
||||
} else if (value->IsUndefined()) {
|
||||
result = NATIVE_UNDEFINED;
|
||||
} else if (value->IsSymbol()) {
|
||||
result = NATIVE_SYMBOL;
|
||||
} else if (value->IsObject()) {
|
||||
result = NATIVE_OBJECT;
|
||||
} else {
|
||||
result = NATIVE_UNDEFINED;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ArkNativeValue::InstanceOf(NativeValue* obj)
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<JSValueRef> value = value_;
|
||||
Global<JSValueRef> object = *obj;
|
||||
return value->InstanceOf(vm, object.ToLocal(vm));
|
||||
}
|
||||
|
||||
bool ArkNativeValue::IsArray()
|
||||
{
|
||||
Global<JSValueRef> value = value_;
|
||||
return value->IsArray(engine_->GetEcmaVm());
|
||||
}
|
||||
|
||||
bool ArkNativeValue::IsArrayBuffer()
|
||||
{
|
||||
Global<JSValueRef> value = value_;
|
||||
return value->IsArrayBuffer();
|
||||
}
|
||||
|
||||
bool ArkNativeValue::IsDate()
|
||||
{
|
||||
Global<JSValueRef> value = value_;
|
||||
return value->IsDate();
|
||||
}
|
||||
|
||||
bool ArkNativeValue::IsError()
|
||||
{
|
||||
Global<JSValueRef> value = value_;
|
||||
return value->IsError();
|
||||
}
|
||||
|
||||
bool ArkNativeValue::IsTypedArray()
|
||||
{
|
||||
Global<JSValueRef> value = value_;
|
||||
return value->IsTypedArray();
|
||||
}
|
||||
|
||||
bool ArkNativeValue::IsDataView()
|
||||
{
|
||||
Global<JSValueRef> value = value_;
|
||||
return value->IsDataView();
|
||||
}
|
||||
|
||||
bool ArkNativeValue::IsPromise()
|
||||
{
|
||||
Global<JSValueRef> value = value_;
|
||||
return value->IsPromise();
|
||||
}
|
||||
|
||||
bool ArkNativeValue::IsCallable()
|
||||
{
|
||||
Global<JSValueRef> value = value_;
|
||||
return value->IsFunction();
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeValue::ToBoolean()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<JSValueRef> value = value_;
|
||||
return ArkNativeEngine::ArkValueToNativeValue(engine_, value->ToBoolean(vm));
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeValue::ToNumber()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<JSValueRef> value = value_;
|
||||
return ArkNativeEngine::ArkValueToNativeValue(engine_, value->ToNumber(vm));
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeValue::ToString()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<JSValueRef> value = value_;
|
||||
return ArkNativeEngine::ArkValueToNativeValue(engine_, value->ToString(vm));
|
||||
}
|
||||
|
||||
NativeValue* ArkNativeValue::ToObject()
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<JSValueRef> value = value_;
|
||||
return ArkNativeEngine::ArkValueToNativeValue(engine_, value->ToObject(vm));
|
||||
}
|
||||
|
||||
bool ArkNativeValue::StrictEquals(NativeValue* value)
|
||||
{
|
||||
auto vm = engine_->GetEcmaVm();
|
||||
LocalScope scope(vm);
|
||||
Global<JSValueRef> value1 = value_;
|
||||
Global<JSValueRef> value2 = *value;
|
||||
return value1->IsStrictEquals(vm, value2.ToLocal(vm));
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_VALUE_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_VALUE_H
|
||||
|
||||
#include "ark_native_engine.h"
|
||||
|
||||
using panda::Local;
|
||||
using panda::LocalScope;
|
||||
using panda::Global;
|
||||
using panda::JSValueRef;
|
||||
class ArkNativeValue : public NativeValue {
|
||||
public:
|
||||
ArkNativeValue(ArkNativeEngine* engine, Local<JSValueRef> value);
|
||||
~ArkNativeValue() override;
|
||||
|
||||
void* GetInterface(int interfaceId) override;
|
||||
|
||||
NativeValueType TypeOf() override;
|
||||
bool InstanceOf(NativeValue* obj) override;
|
||||
|
||||
bool IsArray() override;
|
||||
bool IsArrayBuffer() override;
|
||||
bool IsDate() override;
|
||||
bool IsError() override;
|
||||
bool IsTypedArray() override;
|
||||
bool IsDataView() override;
|
||||
bool IsPromise() override;
|
||||
bool IsCallable() override;
|
||||
|
||||
NativeValue* ToBoolean() override;
|
||||
NativeValue* ToNumber() override;
|
||||
NativeValue* ToString() override;
|
||||
NativeValue* ToObject() override;
|
||||
|
||||
bool StrictEquals(NativeValue* value) override;
|
||||
|
||||
// value_ in NativeValue should not be replaced directly.
|
||||
// If you must replace it, you should use this method.
|
||||
void UpdateValue(Local<JSValueRef> value);
|
||||
|
||||
protected:
|
||||
ArkNativeEngine* engine_;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_NATIVE_VALUE_ARK_NATIVE_VALUE_H */
|
||||
@@ -15,9 +15,9 @@
|
||||
|
||||
#include "quickjs_native_array_buffer.h"
|
||||
#include "native_engine/native_engine.h"
|
||||
#include "utils/log.h"
|
||||
|
||||
struct QuickJsArrayCallback {
|
||||
static QuickJsArrayCallback* CreateNewInstance() { return new QuickJsArrayCallback(); }
|
||||
NativeEngine* engine = nullptr;
|
||||
NativeFinalize cb = nullptr;
|
||||
void* hint = nullptr;
|
||||
@@ -43,22 +43,22 @@ QuickJSNativeArrayBuffer::QuickJSNativeArrayBuffer(QuickJSNativeEngine* engine,
|
||||
void* hint)
|
||||
: QuickJSNativeObject(engine, JS_NULL)
|
||||
{
|
||||
auto cbinfo = new QuickJsArrayCallback();
|
||||
if (cbinfo) {
|
||||
auto cbinfo = QuickJsArrayCallback::CreateNewInstance();
|
||||
if (cbinfo != nullptr) {
|
||||
cbinfo->engine = engine_;
|
||||
cbinfo->cb = cb;
|
||||
cbinfo->hint = hint;
|
||||
value_ = JS_NewArrayBuffer(
|
||||
engine_->GetContext(), data, length,
|
||||
[](JSRuntime* rt, void* opaque, void* ptr) -> void {
|
||||
auto cbinfo = reinterpret_cast<QuickJsArrayCallback*>(opaque);
|
||||
}
|
||||
value_ = JS_NewArrayBuffer(
|
||||
engine_->GetContext(), data, length,
|
||||
[](JSRuntime* rt, void* opaque, void* ptr) -> void {
|
||||
auto cbinfo = reinterpret_cast<QuickJsArrayCallback*>(opaque);
|
||||
if (cbinfo != nullptr) {
|
||||
cbinfo->cb(cbinfo->engine, ptr, cbinfo->hint);
|
||||
delete cbinfo;
|
||||
},
|
||||
(void*)cbinfo, false);
|
||||
} else {
|
||||
HILOG_ERROR("QuickJsArrayCallback instance create fail.");
|
||||
}
|
||||
}
|
||||
},
|
||||
(void*)cbinfo, false);
|
||||
}
|
||||
|
||||
QuickJSNativeArrayBuffer::~QuickJSNativeArrayBuffer() {}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
*/
|
||||
|
||||
#include "quickjs_native_external.h"
|
||||
#include "utils/log.h"
|
||||
|
||||
QuickJSNativeExternal::QuickJSNativeExternal(QuickJSNativeEngine* engine,
|
||||
void* value,
|
||||
@@ -22,23 +21,24 @@ QuickJSNativeExternal::QuickJSNativeExternal(QuickJSNativeEngine* engine,
|
||||
void* hint)
|
||||
: QuickJSNativeValue(engine, JS_UNDEFINED)
|
||||
{
|
||||
NativeObjectInfo* info = new NativeObjectInfo();
|
||||
if (info) {
|
||||
NativeObjectInfo* info = NativeObjectInfo::CreateNewInstance();
|
||||
if (info != nullptr) {
|
||||
info->engine = engine;
|
||||
info->nativeObject = value;
|
||||
info->callback = callback;
|
||||
info->hint = hint;
|
||||
value_ = JS_NewExternal(
|
||||
engine->GetContext(), info,
|
||||
[](JSContext* context, void* data, void* hint) {
|
||||
auto info = reinterpret_cast<NativeObjectInfo*>(data);
|
||||
}
|
||||
|
||||
value_ = JS_NewExternal(
|
||||
engine->GetContext(), info,
|
||||
[](JSContext* context, void* data, void* hint) {
|
||||
auto info = reinterpret_cast<NativeObjectInfo*>(data);
|
||||
if (info != nullptr) {
|
||||
info->callback(info->engine, info->nativeObject, info->hint);
|
||||
delete info;
|
||||
},
|
||||
nullptr);
|
||||
} else {
|
||||
HILOG_ERROR("NativeObjectInfo instance create fail.");
|
||||
}
|
||||
}
|
||||
},
|
||||
nullptr);
|
||||
}
|
||||
|
||||
QuickJSNativeExternal::QuickJSNativeExternal(QuickJSNativeEngine* engine, JSValue value)
|
||||
@@ -57,4 +57,4 @@ QuickJSNativeExternal::operator void*()
|
||||
{
|
||||
NativeObjectInfo* info = (NativeObjectInfo*)JS_ExternalToNativeObject(engine_->GetContext(), value_);
|
||||
return (info != nullptr) ? info->nativeObject : nullptr;
|
||||
}
|
||||
}
|
||||
@@ -32,24 +32,24 @@ QuickJSNativeFunction::QuickJSNativeFunction(QuickJSNativeEngine* engine,
|
||||
void* value)
|
||||
: QuickJSNativeObject(engine, JS_UNDEFINED)
|
||||
{
|
||||
NativeFunctionInfo* info = new NativeFunctionInfo();
|
||||
if (info) {
|
||||
NativeFunctionInfo* info = NativeFunctionInfo::CreateNewInstance();
|
||||
if (info != nullptr) {
|
||||
info->engine = engine;
|
||||
info->callback = cb;
|
||||
info->data = value;
|
||||
JSValue functionContext = JS_NewExternal(engine_->GetContext(), info,
|
||||
[](JSContext* ctx, void* data, void* hint) {
|
||||
auto info = (NativeFunctionInfo*)data;
|
||||
if (info != nullptr) {
|
||||
delete info;
|
||||
}
|
||||
},
|
||||
nullptr);
|
||||
value_ = JS_NewCFunctionData(engine_->GetContext(), JSCFunctionData, 0, 0, 1, &functionContext);
|
||||
JS_DefinePropertyValueStr(engine_->GetContext(), value_, "_functionContext", functionContext, 0);
|
||||
} else {
|
||||
HILOG_ERROR("NativeFunctionInfo instance create fail.");
|
||||
}
|
||||
|
||||
JSValue functionContext = JS_NewExternal(engine_->GetContext(), info,
|
||||
[](JSContext* ctx, void* data, void* hint) {
|
||||
auto info = (NativeFunctionInfo*)data;
|
||||
if (info != nullptr) {
|
||||
delete info;
|
||||
}
|
||||
},
|
||||
nullptr);
|
||||
|
||||
value_ = JS_NewCFunctionData(engine_->GetContext(), JSCFunctionData, 0, 0, 1, &functionContext);
|
||||
JS_DefinePropertyValueStr(engine_->GetContext(), value_, "_functionContext", functionContext, 0);
|
||||
}
|
||||
|
||||
QuickJSNativeFunction::~QuickJSNativeFunction() {}
|
||||
@@ -68,6 +68,11 @@ JSValue QuickJSNativeFunction::JSCFunctionData(JSContext* ctx,
|
||||
JSValue* funcData)
|
||||
{
|
||||
auto info = (NativeFunctionInfo*)JS_ExternalToNativeObject(ctx, *funcData);
|
||||
if (info == nullptr) {
|
||||
HILOG_ERROR("info is null");
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
NativeValue* value = nullptr;
|
||||
NativeCallbackInfo callbackInfo = {0};
|
||||
|
||||
@@ -90,7 +95,7 @@ JSValue QuickJSNativeFunction::JSCFunctionData(JSContext* ctx,
|
||||
callbackInfo.functionInfo = info;
|
||||
if (callbackInfo.argc > 0) {
|
||||
callbackInfo.argv = new NativeValue*[argc];
|
||||
for (int i = 0; i < argc; i++) {
|
||||
for (int i = 0; i < argc && callbackInfo.argv != nullptr; i++) {
|
||||
callbackInfo.argv[i] = QuickJSNativeEngine::JSValueToNativeValue(engine, JS_DupValue(ctx, argv[i]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,17 +13,17 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "quickjs_native_object.h"
|
||||
|
||||
#include "native_engine/native_engine.h"
|
||||
#include "native_engine/native_property.h"
|
||||
|
||||
#include "quickjs_headers.h"
|
||||
|
||||
#include "quickjs_native_engine.h"
|
||||
|
||||
#include "quickjs_native_array.h"
|
||||
#include "quickjs_native_engine.h"
|
||||
#include "quickjs_native_function.h"
|
||||
#include "quickjs_native_object.h"
|
||||
#include "quickjs_native_string.h"
|
||||
#include "utils/log.h"
|
||||
|
||||
QuickJSNativeObject::QuickJSNativeObject(QuickJSNativeEngine* engine)
|
||||
: QuickJSNativeObject(engine, JS_NewObject(engine->GetContext()))
|
||||
@@ -41,10 +41,12 @@ void QuickJSNativeObject::SetNativePointer(void* pointer, NativeFinalize cb, voi
|
||||
NativeObjectInfo* info = (NativeObjectInfo*)JS_GetNativePointer(engine_->GetContext(), value_);
|
||||
if (info == nullptr) {
|
||||
info = new NativeObjectInfo();
|
||||
info->callback = cb;
|
||||
info->engine = engine_;
|
||||
info->nativeObject = pointer;
|
||||
info->hint = hint;
|
||||
if (info != nullptr) {
|
||||
info->callback = cb;
|
||||
info->engine = engine_;
|
||||
info->nativeObject = pointer;
|
||||
info->hint = hint;
|
||||
}
|
||||
JS_SetNativePointer(
|
||||
engine_->GetContext(), value_, info,
|
||||
[](JSContext* context, void* data, void* hint) {
|
||||
@@ -80,6 +82,10 @@ NativeValue* QuickJSNativeObject::GetPropertyNames()
|
||||
JS_GetOwnPropertyNames(engine_->GetContext(), &tab, &len, value_, JS_GPN_STRING_MASK | JS_GPN_ENUM_ONLY);
|
||||
|
||||
QuickJSNativeArray* propertyNames = new QuickJSNativeArray(engine_, (uint32_t)0);
|
||||
if (propertyNames == nullptr) {
|
||||
HILOG_ERROR("create property names failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
QuickJSNativeString* name = new QuickJSNativeString(engine_, tab[i].atom);
|
||||
@@ -107,17 +113,22 @@ bool QuickJSNativeObject::DefineProperty(NativePropertyDescriptor propertyDescri
|
||||
} else if (propertyDescriptor.method) {
|
||||
NativeValue* function = new QuickJSNativeFunction(engine_, propertyDescriptor.utf8name,
|
||||
propertyDescriptor.method, propertyDescriptor.data);
|
||||
result = JS_DefinePropertyValue(engine_->GetContext(), value_, jKey,
|
||||
JS_DupValue(engine_->GetContext(), *function),
|
||||
JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE);
|
||||
if (function != nullptr) {
|
||||
result = JS_DefinePropertyValue(engine_->GetContext(), value_, jKey,
|
||||
JS_DupValue(engine_->GetContext(), *function),
|
||||
JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE);
|
||||
}
|
||||
} else if (propertyDescriptor.getter || propertyDescriptor.setter) {
|
||||
NativeValue* getter =
|
||||
new QuickJSNativeFunction(engine_, nullptr, propertyDescriptor.getter, propertyDescriptor.data);
|
||||
NativeValue* setter =
|
||||
new QuickJSNativeFunction(engine_, nullptr, propertyDescriptor.setter, propertyDescriptor.data);
|
||||
result =
|
||||
JS_DefinePropertyGetSet(engine_->GetContext(), value_, jKey, JS_DupValue(engine_->GetContext(), *getter),
|
||||
JS_DupValue(engine_->GetContext(), *setter), JS_PROP_C_W_E);
|
||||
if (getter != nullptr && setter != nullptr) {
|
||||
result = JS_DefinePropertyGetSet(engine_->GetContext(), value_, jKey,
|
||||
JS_DupValue(engine_->GetContext(), *getter),
|
||||
JS_DupValue(engine_->GetContext(), *setter),
|
||||
JS_PROP_C_W_E);
|
||||
}
|
||||
}
|
||||
|
||||
JS_FreeAtom(engine_->GetContext(), jKey);
|
||||
|
||||
@@ -148,7 +148,7 @@ NativeValue* QuickJSNativeValue::ToObject()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool QuickJSNativeValue::operator==(NativeValue* value)
|
||||
bool QuickJSNativeValue::StrictEquals(NativeValue* value)
|
||||
{
|
||||
return JS_StrictEquals(engine_->GetContext(), value_, *value);
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
virtual NativeValue* ToString() override;
|
||||
virtual NativeValue* ToObject() override;
|
||||
|
||||
virtual bool operator==(NativeValue* value) override;
|
||||
virtual bool StrictEquals(NativeValue* value) override;
|
||||
|
||||
protected:
|
||||
QuickJSNativeEngine* engine_;
|
||||
|
||||
@@ -26,7 +26,7 @@ struct JSObjectInfo {
|
||||
void* hint = nullptr;
|
||||
};
|
||||
|
||||
JSClassID g_baseClassId = 1;
|
||||
JSClassID g_baseClassId = 0;
|
||||
|
||||
void AddIntrinsicExternal(JSContext* context)
|
||||
{
|
||||
@@ -64,11 +64,13 @@ JSValue JS_NewExternal(JSContext* context, void* value, JSFinalizer finalizer, v
|
||||
JSValue result = JS_CallConstructor(context, external, 0, nullptr);
|
||||
|
||||
auto info = new JSObjectInfo();
|
||||
info->context = context;
|
||||
info->finalizer = finalizer;
|
||||
info->data = value;
|
||||
info->hint = hint;
|
||||
JS_SetOpaque(result, info);
|
||||
if (info != nullptr) {
|
||||
info->context = context;
|
||||
info->finalizer = finalizer;
|
||||
info->data = value;
|
||||
info->hint = hint;
|
||||
JS_SetOpaque(result, info);
|
||||
}
|
||||
|
||||
JS_FreeValue(context, external);
|
||||
JS_FreeValue(context, global);
|
||||
@@ -117,10 +119,12 @@ void JS_SetNativePointer(JSContext* context, JSValue value, void* pointer, JSFin
|
||||
auto* info = reinterpret_cast<JSObjectInfo*>(JS_GetOpaque(value, GetBaseClassID()));
|
||||
if (info == nullptr) {
|
||||
info = new JSObjectInfo();
|
||||
info->context = context;
|
||||
info->finalizer = finalizer;
|
||||
info->data = pointer;
|
||||
info->hint = hint;
|
||||
if (info != nullptr) {
|
||||
info->context = context;
|
||||
info->finalizer = finalizer;
|
||||
info->data = pointer;
|
||||
info->hint = hint;
|
||||
}
|
||||
} else if (pointer == nullptr) {
|
||||
delete info;
|
||||
info = nullptr;
|
||||
|
||||
@@ -16,10 +16,8 @@
|
||||
#include "quickjs_native_deferred.h"
|
||||
|
||||
QuickJSNativeDeferred::QuickJSNativeDeferred(QuickJSNativeEngine* engine, JSValue values[2])
|
||||
: engine_(engine), resolve_(values[0]), reject_(values[1])
|
||||
{
|
||||
engine_ = engine;
|
||||
resolve_ = values[0];
|
||||
reject_ = values[1];
|
||||
}
|
||||
|
||||
QuickJSNativeDeferred::~QuickJSNativeDeferred()
|
||||
|
||||
@@ -29,15 +29,11 @@
|
||||
#include "native_value/quickjs_native_typed_array.h"
|
||||
#include "quickjs_native_deferred.h"
|
||||
#include "quickjs_native_reference.h"
|
||||
#include "securec.h"
|
||||
|
||||
#include "utils/assert.h"
|
||||
#include "utils/log.h"
|
||||
|
||||
const int JS_WRITE_OBJ = (1 << 2) | (1 << 3);
|
||||
const int JS_ATOM_MESSAGE = 51;
|
||||
|
||||
QuickJSNativeEngine::QuickJSNativeEngine(JSRuntime* runtime, JSContext* context)
|
||||
QuickJSNativeEngine::QuickJSNativeEngine(JSRuntime* runtime, JSContext* context, void* jsEngine)
|
||||
: NativeEngine(jsEngine)
|
||||
{
|
||||
runtime_ = runtime;
|
||||
context_ = context;
|
||||
@@ -63,7 +59,7 @@ QuickJSNativeEngine::QuickJSNativeEngine(JSRuntime* runtime, JSContext* context)
|
||||
}
|
||||
|
||||
NativeModuleManager* moduleManager = that->GetModuleManager();
|
||||
NativeModule* module = moduleManager->LoadNativeModule(moduleName, nullptr, true);
|
||||
NativeModule* module = moduleManager->LoadNativeModule(moduleName, nullptr, false, true);
|
||||
|
||||
if (module != nullptr && module->registerCallback != nullptr) {
|
||||
NativeValue* value = new QuickJSNativeObject(that);
|
||||
@@ -95,7 +91,7 @@ QuickJSNativeEngine::QuickJSNativeEngine(JSRuntime* runtime, JSContext* context)
|
||||
path = JS_ToCString(that->GetContext(), argv[1]);
|
||||
}
|
||||
NativeModuleManager* moduleManager = that->GetModuleManager();
|
||||
NativeModule* module = moduleManager->LoadNativeModule(moduleName, nullptr);
|
||||
NativeModule* module = moduleManager->LoadNativeModule(moduleName, nullptr, false);
|
||||
|
||||
if (module != nullptr) {
|
||||
if (module->jsCode != nullptr) {
|
||||
@@ -139,10 +135,10 @@ JSContext* QuickJSNativeEngine::GetContext()
|
||||
return context_;
|
||||
}
|
||||
|
||||
void QuickJSNativeEngine::Loop(LoopMode mode)
|
||||
void QuickJSNativeEngine::Loop(LoopMode mode, bool needSync)
|
||||
{
|
||||
JSContext* context = nullptr;
|
||||
NativeEngine::Loop(mode);
|
||||
NativeEngine::Loop(mode, needSync);
|
||||
int err = JS_ExecutePendingJob(runtime_, &context);
|
||||
if (err < 0) {
|
||||
js_std_dump_error(context);
|
||||
@@ -283,7 +279,7 @@ NativeValue* QuickJSNativeEngine::CreateInstance(NativeValue* constructor, Nativ
|
||||
JSValue* params = nullptr;
|
||||
if (argc > 0) {
|
||||
params = new JSValue[argc];
|
||||
for (size_t i = 0; i < argc; i++) {
|
||||
for (size_t i = 0; i < argc && params != nullptr; i++) {
|
||||
params[i] = *argv[i];
|
||||
}
|
||||
}
|
||||
@@ -319,7 +315,7 @@ NativeValue* QuickJSNativeEngine::CallFunction(NativeValue* thisVar,
|
||||
JSValue* args = nullptr;
|
||||
if (argc > 0) {
|
||||
args = new JSValue[argc];
|
||||
for (size_t i = 0; i < argc; i++) {
|
||||
for (size_t i = 0; i < argc && args != nullptr; i++) {
|
||||
if (argv[i] != nullptr) {
|
||||
args[i] = *argv[i];
|
||||
} else {
|
||||
@@ -337,10 +333,6 @@ NativeValue* QuickJSNativeEngine::CallFunction(NativeValue* thisVar,
|
||||
|
||||
scopeManager_->Close(scope);
|
||||
|
||||
if (JS_IsError(context_, result) || JS_IsException(result)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return JSValueToNativeValue(this, result);
|
||||
}
|
||||
|
||||
@@ -350,17 +342,19 @@ NativeValue* QuickJSNativeEngine::RunScript(NativeValue* script)
|
||||
const char* cScript = JS_ToCString(context_, *script);
|
||||
result = JS_Eval(context_, cScript, strlen(cScript), "<input>", JS_EVAL_TYPE_GLOBAL);
|
||||
JS_FreeCString(context_, cScript);
|
||||
if (JS_IsError(context_, result) || JS_IsException(result)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return JSValueToNativeValue(this, result);
|
||||
}
|
||||
|
||||
NativeValue* QuickJSNativeEngine::RunBufferScript(std::vector<uint8_t>& buffer)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NativeValue* QuickJSNativeEngine::LoadModule(NativeValue* str, const std::string& fileName)
|
||||
{
|
||||
if (str == nullptr || fileName.empty()) {
|
||||
HILOG_ERROR("Module name is nullptr or source code length is 0");
|
||||
HILOG_ERROR("moduleName is nullptr or source code length is 0");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -377,9 +371,7 @@ NativeValue* QuickJSNativeEngine::LoadModule(NativeValue* str, const std::string
|
||||
|
||||
JSValue evalRes = JS_EvalFunction(context_, moduleVal);
|
||||
if (JS_IsException(evalRes)) {
|
||||
HILOG_ERROR("Eval module exception");
|
||||
JS_FreeCString(context_, moduleSource);
|
||||
return nullptr;
|
||||
HILOG_ERROR("An exception occurred during Eval module");
|
||||
}
|
||||
|
||||
JSValue ns = JS_GetNameSpace(context_, moduleVal);
|
||||
@@ -410,6 +402,10 @@ NativeValue* QuickJSNativeEngine::DefineClass(const char* name,
|
||||
context_,
|
||||
[](JSContext* ctx, JSValueConst newTarget, int argc, JSValueConst* argv) -> JSValue {
|
||||
auto callbackInfo = new NativeCallbackInfo();
|
||||
if (callbackInfo == nullptr) {
|
||||
HILOG_ERROR("callbackInfo is nullptr");
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
JSValue prototype = JS_GetPropertyStr(ctx, newTarget, "prototype");
|
||||
JSValue classContext = JS_GetPropertyStr(ctx, newTarget, "_classContext");
|
||||
|
||||
@@ -441,7 +437,7 @@ NativeValue* QuickJSNativeEngine::DefineClass(const char* name,
|
||||
|
||||
if (callbackInfo->argc > 0) {
|
||||
callbackInfo->argv = new NativeValue*[argc];
|
||||
for (size_t i = 0; i < callbackInfo->argc; i++) {
|
||||
for (size_t i = 0; i < callbackInfo->argc && callbackInfo->argv != nullptr; i++) {
|
||||
callbackInfo->argv[i] = JSValueToNativeValue(engine, JS_DupValue(ctx, argv[i]));
|
||||
}
|
||||
}
|
||||
@@ -471,7 +467,17 @@ NativeValue* QuickJSNativeEngine::DefineClass(const char* name,
|
||||
JSValue proto = JS_NewObject(context_);
|
||||
|
||||
QuickJSNativeObject* nativeClass = new QuickJSNativeObject(this, JS_DupValue(context_, classConstructor));
|
||||
if (nativeClass == nullptr) {
|
||||
delete functionInfo;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QuickJSNativeObject* nativeClassProto = new QuickJSNativeObject(this, proto);
|
||||
if (nativeClassProto == nullptr) {
|
||||
delete functionInfo;
|
||||
delete nativeClass;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
if (properties[i].attributes & NATIVE_STATIC) {
|
||||
@@ -579,120 +585,32 @@ NativeValue* QuickJSNativeEngine::JSValueToNativeValue(QuickJSNativeEngine* engi
|
||||
return result;
|
||||
}
|
||||
|
||||
void* QuickJSNativeEngine::CreateRuntime()
|
||||
{
|
||||
JSRuntime* runtime = JS_NewRuntime();
|
||||
if (runtime == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
JSContext* context = JS_NewContext(runtime);
|
||||
if (context == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
auto qjsEngine = new QuickJSNativeEngine(runtime, context);
|
||||
if (qjsEngine) {
|
||||
return reinterpret_cast<void*>(qjsEngine);
|
||||
}
|
||||
void* QuickJSNativeEngine::CreateRuntime()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool QuickJSNativeEngine::CheckTransferList(JSValue transferList)
|
||||
{
|
||||
if (JS_IsUndefined(transferList)) {
|
||||
return true;
|
||||
}
|
||||
if (!JS_IsArray(context_, transferList)) {
|
||||
JS_ThrowTypeError(context_, "postMessage second parameter not a list or undefined");
|
||||
return false;
|
||||
}
|
||||
int64_t len = 0;
|
||||
js_get_length64(context_, &len, transferList);
|
||||
for (int64_t i = 0; i < len; i++) {
|
||||
JSValue tmp = JS_GetPropertyInt64(context_, transferList, i);
|
||||
if (!JS_IsException(tmp)) {
|
||||
if (!JS_IsArrayBuffer(context_, tmp)) {
|
||||
HILOG_ERROR("JS_ISArrayBuffer fail");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
HILOG_ERROR("JS_GetPropertyInt64 fail");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QuickJSNativeEngine::DetachTransferList(JSValue transferList)
|
||||
{
|
||||
if (JS_IsUndefined(transferList)) {
|
||||
return true;
|
||||
}
|
||||
int64_t len = 0;
|
||||
js_get_length64(context_, &len, transferList);
|
||||
for (int64_t i = 0; i < len; i++) {
|
||||
JSValue tmp = JS_GetPropertyInt64(context_, transferList, i);
|
||||
if (!JS_IsException(tmp)) {
|
||||
JS_DetachArrayBuffer(context_, tmp);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
NativeValue* QuickJSNativeEngine::Serialize(NativeEngine* context, NativeValue* value, NativeValue* transfer)
|
||||
{
|
||||
if (!CheckTransferList(*transfer)) {
|
||||
return nullptr;
|
||||
}
|
||||
size_t dataLen;
|
||||
uint8_t *data = JS_WriteObject(context_, &dataLen, *value, JS_WRITE_OBJ);
|
||||
DetachTransferList(*transfer);
|
||||
return reinterpret_cast<NativeValue*>(new SerializeData(dataLen, data));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
NativeValue* QuickJSNativeEngine::Deserialize(NativeEngine* context, NativeValue* recorder)
|
||||
{
|
||||
std::unique_ptr<SerializeData> data(reinterpret_cast<SerializeData*>(recorder));
|
||||
JSValue result = JS_ReadObject(context_, data->GetData(), data->GetSize(), JS_WRITE_OBJ);
|
||||
return JSValueToNativeValue(this, result);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void QuickJSNativeEngine::DeleteSerializationData(NativeValue* value) const
|
||||
{
|
||||
SerializeData* data = reinterpret_cast<SerializeData*>(value);
|
||||
delete data;
|
||||
}
|
||||
|
||||
|
||||
ExceptionInfo* QuickJSNativeEngine::GetExceptionForWorker() const
|
||||
{
|
||||
JSValue exception = JS_GetCurrentException(runtime_);
|
||||
ASSERT(JS_IsObject(exception));
|
||||
JSValue msg;
|
||||
ExceptionInfo* exceptionInfo = new ExceptionInfo();
|
||||
msg = JS_GetProperty(context_, exception, JS_ATOM_MESSAGE);
|
||||
ASSERT(JS_IsString(msg));
|
||||
const char* exceptionStr = reinterpret_cast<char *>(JS_GetStringFromObject(msg));
|
||||
const char* error = "Error: ";
|
||||
int len = strlen(exceptionStr) + strlen(error) + 1;
|
||||
if (len <= 0) {
|
||||
delete exceptionInfo;
|
||||
return nullptr;
|
||||
}
|
||||
char* exceptionMessage = new char[len] { 0 };
|
||||
if (memcpy_s(exceptionMessage, len, error, strlen(error)) != EOK) {
|
||||
HILOG_INFO("worker:: memcpy_s error");
|
||||
delete exceptionInfo;
|
||||
delete[] exceptionMessage;
|
||||
return nullptr;
|
||||
}
|
||||
if (memcpy_s(exceptionMessage + strlen(error), len, exceptionStr, strlen(exceptionStr)) != EOK) {
|
||||
HILOG_INFO("worker:: memcpy_s error");
|
||||
delete exceptionInfo;
|
||||
delete[] exceptionMessage;
|
||||
return nullptr;
|
||||
}
|
||||
exceptionInfo->message_ = exceptionMessage;
|
||||
return exceptionInfo;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NativeValue* QuickJSNativeEngine::ValueToNativeValue(JSValueWrapper& value)
|
||||
{
|
||||
JSValue quickValue = value;
|
||||
return JSValueToNativeValue(this, quickValue);
|
||||
}
|
||||
|
||||
@@ -19,41 +19,15 @@
|
||||
#include "native_engine/native_engine.h"
|
||||
#include "quickjs_headers.h"
|
||||
|
||||
class SerializeData {
|
||||
public:
|
||||
SerializeData(size_t size, uint8_t *data) : dataSize_(size), value_(data) {}
|
||||
~SerializeData() = default;
|
||||
|
||||
uint8_t* GetData() const
|
||||
{
|
||||
return value_.get();
|
||||
}
|
||||
size_t GetSize() const
|
||||
{
|
||||
return dataSize_;
|
||||
}
|
||||
|
||||
private:
|
||||
struct Deleter {
|
||||
void operator()(uint8_t* ptr) const
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
size_t dataSize_;
|
||||
std::unique_ptr<uint8_t, Deleter> value_;
|
||||
};
|
||||
|
||||
class QuickJSNativeEngine : public NativeEngine {
|
||||
public:
|
||||
QuickJSNativeEngine(JSRuntime* runtime, JSContext* context);
|
||||
QuickJSNativeEngine(JSRuntime* runtime, JSContext* contex, void* jsEngine);
|
||||
virtual ~QuickJSNativeEngine();
|
||||
|
||||
JSRuntime* GetRuntime();
|
||||
JSContext* GetContext();
|
||||
|
||||
virtual void Loop(LoopMode mode) override;
|
||||
virtual void Loop(LoopMode mode, bool needSync = false) override;
|
||||
|
||||
virtual NativeValue* GetGlobal() override;
|
||||
virtual NativeValue* CreateNull() override;
|
||||
@@ -99,22 +73,20 @@ public:
|
||||
size_t length) override;
|
||||
|
||||
virtual NativeValue* RunScript(NativeValue* script) override;
|
||||
virtual NativeValue* RunBufferScript(std::vector<uint8_t>& buffer) override;
|
||||
|
||||
virtual bool Throw(NativeValue* error) override;
|
||||
virtual bool Throw(NativeErrorType type, const char* code, const char* message) override;
|
||||
|
||||
virtual void* CreateRuntime() override;
|
||||
bool CheckTransferList(JSValue transferList);
|
||||
bool DetachTransferList(JSValue transferList);
|
||||
virtual NativeValue* Serialize(NativeEngine* context, NativeValue* value, NativeValue* transfer) override;
|
||||
virtual NativeValue* Deserialize(NativeEngine* context, NativeValue* recorder) override;
|
||||
virtual void DeleteSerializationData(NativeValue* value) const override;
|
||||
virtual ExceptionInfo* GetExceptionForWorker() const override;
|
||||
|
||||
virtual NativeValue* LoadModule(NativeValue* str, const std::string& fileName) override;
|
||||
|
||||
static NativeValue* JSValueToNativeValue(QuickJSNativeEngine* engine, JSValue value);
|
||||
|
||||
virtual NativeValue* ValueToNativeValue(JSValueWrapper& value) override;
|
||||
private:
|
||||
JSRuntime* runtime_;
|
||||
JSContext* context_;
|
||||
|
||||
@@ -18,14 +18,10 @@
|
||||
#include "native_value/quickjs_native_value.h"
|
||||
#include "quickjs_native_reference.h"
|
||||
|
||||
QuickJSNativeReference::QuickJSNativeReference(QuickJSNativeEngine* engine,
|
||||
NativeValue* value,
|
||||
uint32_t initialRefcount)
|
||||
QuickJSNativeReference::QuickJSNativeReference(
|
||||
QuickJSNativeEngine* engine, NativeValue* value, uint32_t initialRefcount)
|
||||
: engine_(engine), value_(*value), refCount_(initialRefcount)
|
||||
{
|
||||
engine_ = engine;
|
||||
value_ = *value;
|
||||
refCount_ = initialRefcount;
|
||||
|
||||
for (uint32_t i = 0; i < initialRefcount; i++) {
|
||||
JS_DupValue(engine_->GetContext(), value_);
|
||||
}
|
||||
@@ -59,7 +55,7 @@ uint32_t QuickJSNativeReference::Unref()
|
||||
|
||||
NativeValue* QuickJSNativeReference::Get()
|
||||
{
|
||||
return QuickJSNativeEngine::JSValueToNativeValue(engine_, JS_DupValue(engine_->GetContext(), value_));
|
||||
return new QuickJSNativeValue(engine_, JS_DupValue(engine_->GetContext(), value_));
|
||||
}
|
||||
|
||||
QuickJSNativeReference::operator NativeValue*()
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "v8_native_array.h"
|
||||
|
||||
V8NativeArray::V8NativeArray(V8NativeEngine* engine, v8::Local<v8::Value> value) : V8NativeObject(engine, value) {}
|
||||
|
||||
V8NativeArray::V8NativeArray(V8NativeEngine* engine, uint32_t length)
|
||||
: V8NativeArray(engine, v8::Array::New(engine->GetIsolate(), length))
|
||||
{
|
||||
}
|
||||
|
||||
V8NativeArray::~V8NativeArray() {}
|
||||
|
||||
void* V8NativeArray::GetInterface(int interfaceId)
|
||||
{
|
||||
return (NativeArray::INTERFACE_ID == interfaceId) ? (NativeArray*)this
|
||||
: V8NativeObject::GetInterface(interfaceId);
|
||||
}
|
||||
|
||||
bool V8NativeArray::SetElement(uint32_t index, NativeValue* value)
|
||||
{
|
||||
v8::Local<v8::Object> obj = value_;
|
||||
v8::Local<v8::Value> val = *value;
|
||||
auto setMaybe = obj->Set(engine_->GetContext(), index, val);
|
||||
return setMaybe.FromMaybe(false);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeArray::GetElement(uint32_t index)
|
||||
{
|
||||
v8::Local<v8::Object> obj = value_;
|
||||
auto getMaybe = obj->Get(engine_->GetContext(), index);
|
||||
return V8NativeEngine::V8ValueToNativeValue(engine_, getMaybe.ToLocalChecked());
|
||||
}
|
||||
|
||||
bool V8NativeArray::HasElement(uint32_t index)
|
||||
{
|
||||
v8::Local<v8::Object> obj = value_;
|
||||
v8::Maybe<bool> hasMaybe = obj->Has(engine_->GetContext(), index);
|
||||
return hasMaybe.FromMaybe(false);
|
||||
}
|
||||
|
||||
bool V8NativeArray::DeleteElement(uint32_t index)
|
||||
{
|
||||
v8::Local<v8::Object> obj = value_;
|
||||
v8::Maybe<bool> deleteMaybe = obj->Delete(engine_->GetContext(), index);
|
||||
return deleteMaybe.FromMaybe(false);
|
||||
}
|
||||
|
||||
uint32_t V8NativeArray::GetLength()
|
||||
{
|
||||
v8::Local<v8::Array> obj = value_;
|
||||
return obj->Length();
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_ARRAY_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_ARRAY_H
|
||||
|
||||
#include "v8_native_object.h"
|
||||
|
||||
class V8NativeArray : public V8NativeObject, public NativeArray {
|
||||
public:
|
||||
explicit V8NativeArray(V8NativeEngine* engine, v8::Local<v8::Value> value);
|
||||
explicit V8NativeArray(V8NativeEngine* engine, uint32_t length);
|
||||
virtual ~V8NativeArray();
|
||||
|
||||
void* GetInterface(int interfaceId) override;
|
||||
|
||||
virtual bool SetElement(uint32_t index, NativeValue* value) override;
|
||||
virtual NativeValue* GetElement(uint32_t index) override;
|
||||
virtual bool HasElement(uint32_t index) override;
|
||||
virtual bool DeleteElement(uint32_t index) override;
|
||||
|
||||
virtual uint32_t GetLength() override;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_ARRAY_H */
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "v8_native_array_buffer.h"
|
||||
|
||||
struct V8NativeArrayBufferInfo {
|
||||
static V8NativeArrayBufferInfo* CreateNewInstance() { return new V8NativeArrayBufferInfo(); }
|
||||
NativeEngine* engine = nullptr;
|
||||
NativeFinalize cb = nullptr;
|
||||
void* hint = nullptr;
|
||||
};
|
||||
|
||||
V8NativeArrayBuffer::V8NativeArrayBuffer(V8NativeEngine* engine, v8::Local<v8::Value> value)
|
||||
: V8NativeObject(engine, value)
|
||||
{
|
||||
}
|
||||
|
||||
V8NativeArrayBuffer::V8NativeArrayBuffer(V8NativeEngine* engine, uint8_t** value, size_t length)
|
||||
: V8NativeArrayBuffer(engine, v8::Local<v8::Value>())
|
||||
{
|
||||
value_ = v8::ArrayBuffer::New(engine->GetIsolate(), length);
|
||||
if (value != nullptr) {
|
||||
v8::Local<v8::ArrayBuffer> obj = value_;
|
||||
*value = (uint8_t*)obj->GetBackingStore()->Data();
|
||||
}
|
||||
}
|
||||
|
||||
V8NativeArrayBuffer::V8NativeArrayBuffer(V8NativeEngine* engine,
|
||||
uint8_t* value,
|
||||
size_t length,
|
||||
NativeFinalize cb,
|
||||
void* hint)
|
||||
: V8NativeArrayBuffer(engine, v8::Local<v8::Value>())
|
||||
{
|
||||
auto cbinfo = V8NativeArrayBufferInfo::CreateNewInstance();
|
||||
if (cbinfo != nullptr) {
|
||||
cbinfo->engine = engine_;
|
||||
cbinfo->cb = cb;
|
||||
cbinfo->hint = hint;
|
||||
}
|
||||
|
||||
auto backingStore = v8::ArrayBuffer::NewBackingStore(
|
||||
value, length,
|
||||
[](void* data, size_t length, void* deleterData) -> void {
|
||||
auto cbinfo = (V8NativeArrayBufferInfo*)deleterData;
|
||||
if (cbinfo != nullptr) {
|
||||
cbinfo->cb(cbinfo->engine, data, cbinfo->hint);
|
||||
delete cbinfo;
|
||||
}
|
||||
},
|
||||
cbinfo);
|
||||
|
||||
value_ = v8::ArrayBuffer::New(engine->GetIsolate(), std::shared_ptr<v8::BackingStore>(backingStore.release()));
|
||||
}
|
||||
|
||||
V8NativeArrayBuffer::~V8NativeArrayBuffer() {}
|
||||
|
||||
void* V8NativeArrayBuffer::GetInterface(int interfaceId)
|
||||
{
|
||||
return (NativeArrayBuffer::INTERFACE_ID == interfaceId) ? (NativeArrayBuffer*)this
|
||||
: V8NativeObject::GetInterface(interfaceId);
|
||||
}
|
||||
|
||||
void* V8NativeArrayBuffer::GetBuffer()
|
||||
{
|
||||
v8::Local<v8::ArrayBuffer> v = value_;
|
||||
return v->GetBackingStore()->Data();
|
||||
}
|
||||
|
||||
size_t V8NativeArrayBuffer::GetLength()
|
||||
{
|
||||
v8::Local<v8::ArrayBuffer> v = value_;
|
||||
return v->ByteLength();
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_ARRAY_BUFFER_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_ARRAY_BUFFER_H
|
||||
|
||||
#include "v8_native_object.h"
|
||||
|
||||
class V8NativeArrayBuffer : public V8NativeObject, public NativeArrayBuffer {
|
||||
public:
|
||||
V8NativeArrayBuffer(V8NativeEngine* engine, v8::Local<v8::Value> value);
|
||||
V8NativeArrayBuffer(V8NativeEngine* engine, uint8_t** data, size_t length);
|
||||
V8NativeArrayBuffer(V8NativeEngine* engine, uint8_t* data, size_t length, NativeFinalize cb, void* hint);
|
||||
virtual ~V8NativeArrayBuffer();
|
||||
|
||||
void* GetInterface(int interfaceId) override;
|
||||
|
||||
virtual void* GetBuffer() override;
|
||||
virtual size_t GetLength() override;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_ARRAY_BUFFER_H */
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "v8_native_boolean.h"
|
||||
|
||||
V8NativeBoolean::V8NativeBoolean(V8NativeEngine* engine, v8::Local<v8::Value> value) : V8NativeValue(engine, value) {}
|
||||
|
||||
V8NativeBoolean::V8NativeBoolean(V8NativeEngine* engine, bool value)
|
||||
: V8NativeBoolean(engine, v8::Boolean::New(engine->GetIsolate(), value))
|
||||
{
|
||||
}
|
||||
|
||||
V8NativeBoolean::~V8NativeBoolean() {}
|
||||
|
||||
void* V8NativeBoolean::GetInterface(int interfaceId)
|
||||
{
|
||||
return (NativeBoolean::INTERFACE_ID == interfaceId) ? (NativeBoolean*)this : nullptr;
|
||||
}
|
||||
|
||||
V8NativeBoolean::operator bool()
|
||||
{
|
||||
v8::Local<v8::Boolean> value = value_;
|
||||
return value->Value();
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_BOOLEAN_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_BOOLEAN_H
|
||||
|
||||
#include "v8_native_value.h"
|
||||
|
||||
class V8NativeBoolean : public V8NativeValue, public NativeBoolean {
|
||||
public:
|
||||
V8NativeBoolean(V8NativeEngine* engine, v8::Local<v8::Value> value);
|
||||
V8NativeBoolean(V8NativeEngine* engine, bool value);
|
||||
virtual ~V8NativeBoolean();
|
||||
|
||||
void* GetInterface(int interfaceId) override;
|
||||
|
||||
virtual operator bool() override;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_BOOLEAN_H */
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "v8_native_data_view.h"
|
||||
|
||||
#include "v8_native_array_buffer.h"
|
||||
|
||||
V8NativeDataView::V8NativeDataView(V8NativeEngine* engine, v8::Local<v8::Value> value) : V8NativeObject(engine, value)
|
||||
{
|
||||
}
|
||||
|
||||
V8NativeDataView::V8NativeDataView(V8NativeEngine* engine, NativeValue* value, size_t length, size_t offset)
|
||||
: V8NativeDataView(engine, v8::Local<v8::DataView>())
|
||||
{
|
||||
v8::Local<v8::ArrayBuffer> arrybuffer = *value;
|
||||
value_ = v8::DataView::New(arrybuffer, offset, length);
|
||||
}
|
||||
|
||||
V8NativeDataView::~V8NativeDataView() {}
|
||||
|
||||
void* V8NativeDataView::GetInterface(int interfaceId)
|
||||
{
|
||||
return (NativeDataView::INTERFACE_ID == interfaceId) ? (NativeDataView*)this
|
||||
: V8NativeObject::GetInterface(interfaceId);
|
||||
}
|
||||
|
||||
void* V8NativeDataView::GetBuffer()
|
||||
{
|
||||
v8::Local<v8::DataView> value = value_;
|
||||
|
||||
return value->Buffer()->GetBackingStore()->Data();
|
||||
}
|
||||
|
||||
size_t V8NativeDataView::GetLength()
|
||||
{
|
||||
v8::Local<v8::DataView> value = value_;
|
||||
|
||||
return value->ByteLength();
|
||||
}
|
||||
|
||||
NativeValue* V8NativeDataView::GetArrayBuffer()
|
||||
{
|
||||
v8::Local<v8::DataView> value = value_;
|
||||
|
||||
return new V8NativeArrayBuffer(engine_, value->Buffer());
|
||||
}
|
||||
|
||||
size_t V8NativeDataView::GetOffset()
|
||||
{
|
||||
v8::Local<v8::DataView> value = value_;
|
||||
|
||||
return value->ByteOffset();
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_DATA_VIEW_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_DATA_VIEW_H
|
||||
|
||||
#include "v8_native_object.h"
|
||||
|
||||
class V8NativeDataView : public V8NativeObject, public NativeDataView {
|
||||
public:
|
||||
V8NativeDataView(V8NativeEngine* engine, v8::Local<v8::Value> value);
|
||||
V8NativeDataView(V8NativeEngine* engine, NativeValue* value, size_t length, size_t offset);
|
||||
virtual ~V8NativeDataView();
|
||||
|
||||
void* GetInterface(int interfaceId) override;
|
||||
|
||||
virtual void* GetBuffer() override;
|
||||
virtual size_t GetLength() override;
|
||||
virtual NativeValue* GetArrayBuffer() override;
|
||||
virtual size_t GetOffset() override;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_DATA_VIEW_H */
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "v8_native_external.h"
|
||||
#include "v8_native_reference.h"
|
||||
|
||||
V8NativeExternal::V8NativeExternal(V8NativeEngine* engine, void* value, NativeFinalize callback, void* hint)
|
||||
: V8NativeExternal(engine, v8::External::New(engine->GetIsolate(), value))
|
||||
{
|
||||
}
|
||||
|
||||
V8NativeExternal::V8NativeExternal(V8NativeEngine* engine, v8::Local<v8::Value> value) : V8NativeValue(engine, value) {}
|
||||
|
||||
V8NativeExternal::~V8NativeExternal() {}
|
||||
|
||||
void* V8NativeExternal::GetInterface(int interfaceId)
|
||||
{
|
||||
return (NativeExternal::INTERFACE_ID == interfaceId) ? (NativeExternal*)this : nullptr;
|
||||
}
|
||||
|
||||
V8NativeExternal::operator void*()
|
||||
{
|
||||
v8::Local<v8::External> value = value_;
|
||||
return value->Value();
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_EXTERNAL_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_EXTERNAL_H
|
||||
|
||||
#include "v8_native_value.h"
|
||||
|
||||
class V8NativeExternal : public V8NativeValue, public NativeExternal {
|
||||
public:
|
||||
V8NativeExternal(V8NativeEngine* engine, void* value, NativeFinalize callback, void* hint);
|
||||
V8NativeExternal(V8NativeEngine* engine, v8::Local<v8::Value> value);
|
||||
virtual ~V8NativeExternal();
|
||||
|
||||
virtual void* GetInterface(int interfaceId) override;
|
||||
|
||||
virtual operator void*() override;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_EXTERNAL_H */
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "v8_native_function.h"
|
||||
|
||||
#include "utils/log.h"
|
||||
|
||||
V8NativeFunction::V8NativeFunction(V8NativeEngine* engine, v8::Local<v8::Value> value) : V8NativeObject(engine, value)
|
||||
{
|
||||
}
|
||||
|
||||
V8NativeFunction::V8NativeFunction(V8NativeEngine* engine,
|
||||
const char* name,
|
||||
size_t length,
|
||||
NativeCallback cb,
|
||||
void* value)
|
||||
: V8NativeFunction(engine, v8::Local<v8::Value>())
|
||||
{
|
||||
auto context = engine->GetContext();
|
||||
auto isolate = engine->GetIsolate();
|
||||
v8::Local<v8::Array> cbdata = v8::Array::New(isolate);
|
||||
|
||||
int32_t index = 0;
|
||||
cbdata->Set(context, index++, v8::External::New(isolate, (void*)engine)).FromJust();
|
||||
cbdata->Set(context, index++, v8::External::New(isolate, (void*)cb)).FromJust();
|
||||
cbdata->Set(context, index, v8::External::New(isolate, value)).FromJust();
|
||||
|
||||
v8::Local<v8::Function> fn =
|
||||
v8::Function::New(context, NativeFunctionCallback, cbdata).ToLocalChecked();
|
||||
|
||||
v8::Local<v8::String> fnName = v8::String::NewFromUtf8(isolate, name).ToLocalChecked();
|
||||
|
||||
fn->SetName(fnName);
|
||||
|
||||
value_ = fn;
|
||||
}
|
||||
|
||||
V8NativeFunction::~V8NativeFunction() {}
|
||||
|
||||
void* V8NativeFunction::GetInterface(int interfaceId)
|
||||
{
|
||||
return (NativeFunction::INTERFACE_ID == interfaceId) ? (NativeFunction*)this
|
||||
: V8NativeObject::GetInterface(interfaceId);
|
||||
}
|
||||
|
||||
void V8NativeFunction::NativeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
|
||||
{
|
||||
v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
|
||||
v8::Local<v8::Array> cbdata = info.Data().As<v8::Array>();
|
||||
|
||||
int32_t index = 0;
|
||||
V8NativeEngine* engine =
|
||||
(V8NativeEngine*)cbdata->Get(context, index++).ToLocalChecked().As<v8::External>()->Value();
|
||||
if (engine == nullptr) {
|
||||
HILOG_ERROR("engine is nullptr");
|
||||
return;
|
||||
}
|
||||
NativeCallback cb = (NativeCallback)cbdata->Get(context, index++).ToLocalChecked().As<v8::External>()->Value();
|
||||
void* data = cbdata->Get(context, index).ToLocalChecked().As<v8::External>()->Value();
|
||||
|
||||
auto funcinfo = new NativeFunctionInfo();
|
||||
if (funcinfo == nullptr) {
|
||||
HILOG_ERROR("create native function info failed");
|
||||
return;
|
||||
}
|
||||
|
||||
funcinfo->engine = engine;
|
||||
funcinfo->callback = cb;
|
||||
funcinfo->data = data;
|
||||
|
||||
NativeCallbackInfo cbinfo = { 0 };
|
||||
cbinfo.thisVar = V8NativeEngine::V8ValueToNativeValue(engine, info.This());
|
||||
cbinfo.function = V8NativeEngine::V8ValueToNativeValue(engine, info.NewTarget());
|
||||
cbinfo.argc = info.Length();
|
||||
cbinfo.argv = nullptr;
|
||||
cbinfo.functionInfo = funcinfo;
|
||||
if (cbinfo.argc > 0) {
|
||||
cbinfo.argv = new NativeValue* [cbinfo.argc];
|
||||
for (size_t i = 0; i < cbinfo.argc && cbinfo.argv != nullptr; i++) {
|
||||
cbinfo.argv[i] = V8NativeEngine::V8ValueToNativeValue(engine, info[i]);
|
||||
}
|
||||
}
|
||||
|
||||
NativeValue* result = nullptr;
|
||||
if (cb != nullptr) {
|
||||
result = cb(engine, &cbinfo);
|
||||
}
|
||||
|
||||
if (cbinfo.argv != nullptr) {
|
||||
delete []cbinfo.argv;
|
||||
}
|
||||
delete funcinfo;
|
||||
|
||||
v8::Local<v8::Value> v8Result;
|
||||
if (result == nullptr) {
|
||||
if (engine->IsExceptionPending()) {
|
||||
NativeValue* error = engine->GetAndClearLastException();
|
||||
if (error != nullptr) {
|
||||
v8Result = *error;
|
||||
}
|
||||
} else {
|
||||
v8Result = v8::Undefined(engine->GetIsolate());
|
||||
}
|
||||
} else {
|
||||
v8Result = *result;
|
||||
}
|
||||
|
||||
info.GetReturnValue().Set<v8::Value>(v8Result);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_FUNCTION_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_FUNCTION_H
|
||||
|
||||
#include "v8_native_object.h"
|
||||
|
||||
class V8NativeFunction : public V8NativeObject, public NativeFunction {
|
||||
public:
|
||||
V8NativeFunction(V8NativeEngine* engine, v8::Local<v8::Value> value);
|
||||
V8NativeFunction(V8NativeEngine* engine, const char* name, size_t length, NativeCallback cb, void* value);
|
||||
virtual ~V8NativeFunction();
|
||||
|
||||
virtual void* GetInterface(int interfaceId) override;
|
||||
|
||||
private:
|
||||
static void NativeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info);
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_FUNCTION_H */
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "v8_native_number.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
V8NativeNumber::V8NativeNumber(V8NativeEngine* engine, v8::Local<v8::Value> value) : V8NativeValue(engine, value) {}
|
||||
|
||||
V8NativeNumber::V8NativeNumber(V8NativeEngine* engine, int32_t value)
|
||||
: V8NativeNumber(engine, v8::Number::New(engine->GetIsolate(), value))
|
||||
{
|
||||
}
|
||||
|
||||
V8NativeNumber::V8NativeNumber(V8NativeEngine* engine, uint32_t value)
|
||||
: V8NativeNumber(engine, v8::Number::New(engine->GetIsolate(), value))
|
||||
{
|
||||
}
|
||||
|
||||
V8NativeNumber::V8NativeNumber(V8NativeEngine* engine, int64_t value)
|
||||
: V8NativeNumber(engine, v8::Number::New(engine->GetIsolate(), value))
|
||||
{
|
||||
}
|
||||
|
||||
V8NativeNumber::V8NativeNumber(V8NativeEngine* engine, double value)
|
||||
: V8NativeNumber(engine, v8::Number::New(engine->GetIsolate(), value))
|
||||
{
|
||||
}
|
||||
|
||||
V8NativeNumber::~V8NativeNumber() {}
|
||||
|
||||
void* V8NativeNumber::GetInterface(int interfaceId)
|
||||
{
|
||||
return (NativeNumber::INTERFACE_ID == interfaceId) ? (NativeNumber*)this : nullptr;
|
||||
}
|
||||
|
||||
V8NativeNumber::operator int32_t()
|
||||
{
|
||||
v8::Local<v8::Value> value = value_;
|
||||
int32_t result = 0;
|
||||
|
||||
if (value->IsInt32()) {
|
||||
result = value.As<v8::Int32>()->Value();
|
||||
}
|
||||
|
||||
double doubleValue = value.As<v8::Number>()->Value();
|
||||
if (isfinite(doubleValue)) {
|
||||
result = value->IntegerValue(engine_->GetContext()).FromJust();
|
||||
} else {
|
||||
result = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
V8NativeNumber::operator uint32_t()
|
||||
{
|
||||
v8::Local<v8::Value> value = value_;
|
||||
uint32_t result = 0;
|
||||
|
||||
if (value->IsUint32()) {
|
||||
result = value.As<v8::Uint32>()->Value();
|
||||
} else {
|
||||
result = value->Uint32Value(engine_->GetContext()).FromJust();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
V8NativeNumber::operator int64_t()
|
||||
{
|
||||
v8::Local<v8::Value> value = value_;
|
||||
int64_t result = 0;
|
||||
|
||||
if (value->IsInt32()) {
|
||||
result = value.As<v8::Int32>()->Value();
|
||||
}
|
||||
|
||||
double doubleValue = value.As<v8::Number>()->Value();
|
||||
if (isfinite(doubleValue)) {
|
||||
result = value->IntegerValue(engine_->GetContext()).FromJust();
|
||||
} else {
|
||||
result = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
V8NativeNumber::operator double()
|
||||
{
|
||||
v8::Local<v8::Value> value = value_;
|
||||
double result = 0.0;
|
||||
|
||||
result = value.As<v8::Number>()->Value();
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_NUMBER_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_NUMBER_H
|
||||
|
||||
#include "v8_native_value.h"
|
||||
|
||||
class V8NativeNumber : public V8NativeValue, public NativeNumber {
|
||||
public:
|
||||
V8NativeNumber(V8NativeEngine* engine, v8::Local<v8::Value> value);
|
||||
V8NativeNumber(V8NativeEngine* engine, int32_t value);
|
||||
V8NativeNumber(V8NativeEngine* engine, uint32_t value);
|
||||
V8NativeNumber(V8NativeEngine* engine, int64_t value);
|
||||
V8NativeNumber(V8NativeEngine* engine, double value);
|
||||
virtual ~V8NativeNumber();
|
||||
|
||||
virtual void* GetInterface(int interfaceId) override;
|
||||
|
||||
virtual operator int32_t() override;
|
||||
virtual operator uint32_t() override;
|
||||
virtual operator int64_t() override;
|
||||
virtual operator double() override;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_NUMBER_H */
|
||||
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "v8_native_object.h"
|
||||
|
||||
#include "native_engine/native_property.h"
|
||||
#include "v8_headers.h"
|
||||
#include "v8_native_array.h"
|
||||
#include "v8_native_function.h"
|
||||
#include "v8_native_reference.h"
|
||||
|
||||
V8NativeObject::V8NativeObject(V8NativeEngine* engine) : V8NativeObject(engine, v8::Object::New(engine->GetIsolate()))
|
||||
{
|
||||
}
|
||||
|
||||
V8NativeObject::V8NativeObject(V8NativeEngine* engine, v8::Local<v8::Value> value) : V8NativeValue(engine, value) {}
|
||||
|
||||
V8NativeObject::~V8NativeObject() {}
|
||||
|
||||
void* V8NativeObject::GetInterface(int interfaceId)
|
||||
{
|
||||
return (NativeObject::INTERFACE_ID == interfaceId) ? (NativeObject*)this : nullptr;
|
||||
}
|
||||
|
||||
void V8NativeObject::SetNativePointer(void* pointer, NativeFinalize cb, void* hint)
|
||||
{
|
||||
v8::Local<v8::Object> value = value_;
|
||||
v8::Local<v8::External> val = v8::External::New(engine_->GetIsolate(), pointer);
|
||||
v8::Local<v8::String> key = v8::String::NewFromUtf8(engine_->GetIsolate(), "_napiwrapper").ToLocalChecked();
|
||||
value->Set(engine_->GetContext(), key, val).FromJust();
|
||||
}
|
||||
|
||||
void* V8NativeObject::GetNativePointer()
|
||||
{
|
||||
v8::Local<v8::Object> value = value_;
|
||||
v8::Local<v8::String> key = v8::String::NewFromUtf8(engine_->GetIsolate(), "_napiwrapper").ToLocalChecked();
|
||||
v8::Local<v8::Value> val = value->Get(engine_->GetContext(), key).ToLocalChecked();
|
||||
void* result = nullptr;
|
||||
if (val->IsExternal()) {
|
||||
v8::Local<v8::External> ext = val.As<v8::External>();
|
||||
result = ext->Value();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
NativeValue* V8NativeObject::GetPropertyNames()
|
||||
{
|
||||
v8::Local<v8::Object> val = value_;
|
||||
v8::Local<v8::Array> arrayVal =
|
||||
val->GetPropertyNames(
|
||||
engine_->GetContext(), v8::KeyCollectionMode::kIncludePrototypes,
|
||||
static_cast<v8::PropertyFilter>(v8::PropertyFilter::ONLY_ENUMERABLE | v8::PropertyFilter::SKIP_SYMBOLS),
|
||||
v8::IndexFilter::kIncludeIndices, v8::KeyConversionMode::kConvertToString).ToLocalChecked();
|
||||
|
||||
return new V8NativeArray(engine_, arrayVal);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeObject::GetPrototype()
|
||||
{
|
||||
v8::Local<v8::Object> obj = value_;
|
||||
|
||||
v8::Local<v8::Value> val = obj->GetPrototype();
|
||||
return V8NativeEngine::V8ValueToNativeValue(engine_, val);
|
||||
}
|
||||
|
||||
bool V8NativeObject::DefineProperty(NativePropertyDescriptor propertyDescriptor)
|
||||
{
|
||||
v8::Local<v8::Object> obj = value_;
|
||||
|
||||
bool result = false;
|
||||
|
||||
v8::Local<v8::Name> propertyName =
|
||||
v8::String::NewFromUtf8(engine_->GetIsolate(), propertyDescriptor.utf8name, v8::NewStringType::kNormal)
|
||||
.ToLocalChecked();
|
||||
|
||||
if (propertyDescriptor.getter != nullptr || propertyDescriptor.setter != nullptr) {
|
||||
v8::Local<v8::Value> localGetter;
|
||||
v8::Local<v8::Value> localSetter;
|
||||
|
||||
if (propertyDescriptor.getter != nullptr) {
|
||||
NativeValue* getter =
|
||||
new V8NativeFunction(engine_, "getter", 0, propertyDescriptor.getter, propertyDescriptor.data);
|
||||
if (getter != nullptr) {
|
||||
localGetter = *getter;
|
||||
}
|
||||
}
|
||||
if (propertyDescriptor.setter != nullptr) {
|
||||
NativeValue* setter =
|
||||
new V8NativeFunction(engine_, "setter", 0, propertyDescriptor.setter, propertyDescriptor.data);
|
||||
if (setter != nullptr) {
|
||||
localSetter = *setter;
|
||||
}
|
||||
}
|
||||
|
||||
v8::PropertyDescriptor descriptor(localGetter, localSetter);
|
||||
descriptor.set_enumerable((propertyDescriptor.attributes & NATIVE_ENUMERABLE) != 0);
|
||||
descriptor.set_configurable((propertyDescriptor.attributes & NATIVE_CONFIGURABLE) != 0);
|
||||
|
||||
result = obj->DefineProperty(engine_->GetContext(), propertyName, descriptor).FromMaybe(false);
|
||||
} else if (propertyDescriptor.method != nullptr) {
|
||||
NativeValue* cb = new V8NativeFunction(engine_, propertyDescriptor.utf8name, 0, propertyDescriptor.method,
|
||||
propertyDescriptor.data);
|
||||
if (cb != nullptr) {
|
||||
v8::PropertyDescriptor descriptor(*cb, (propertyDescriptor.attributes & NATIVE_WRITABLE) != 0);
|
||||
descriptor.set_enumerable((propertyDescriptor.attributes & NATIVE_ENUMERABLE) != 0);
|
||||
descriptor.set_configurable((propertyDescriptor.attributes & NATIVE_CONFIGURABLE) != 0);
|
||||
result = obj->DefineProperty(engine_->GetContext(), propertyName, descriptor).FromMaybe(false);
|
||||
}
|
||||
} else {
|
||||
v8::Local<v8::Value> value = *(propertyDescriptor.value);
|
||||
|
||||
v8::PropertyDescriptor descriptor(value, (propertyDescriptor.attributes & NATIVE_WRITABLE) != 0);
|
||||
descriptor.set_enumerable((propertyDescriptor.attributes & NATIVE_ENUMERABLE) != 0);
|
||||
descriptor.set_configurable((propertyDescriptor.attributes & NATIVE_CONFIGURABLE) != 0);
|
||||
|
||||
result = obj->DefineProperty(engine_->GetContext(), propertyName, descriptor).FromMaybe(false);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool V8NativeObject::SetProperty(NativeValue* key, NativeValue* value)
|
||||
{
|
||||
v8::Local<v8::Object> obj = value_;
|
||||
|
||||
v8::Local<v8::Value> k = *key;
|
||||
v8::Local<v8::Value> val = *value;
|
||||
|
||||
v8::Maybe<bool> setMaybe = obj->Set(engine_->GetContext(), k, val);
|
||||
|
||||
return setMaybe.FromMaybe(false);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeObject::GetProperty(NativeValue* key)
|
||||
{
|
||||
v8::Local<v8::Value> k = *key;
|
||||
v8::Local<v8::Object> obj = value_;
|
||||
|
||||
auto getMaybe = obj->Get(engine_->GetContext(), k);
|
||||
v8::Local<v8::Value> val = getMaybe.ToLocalChecked();
|
||||
return V8NativeEngine::V8ValueToNativeValue(engine_, val);
|
||||
}
|
||||
|
||||
bool V8NativeObject::HasProperty(NativeValue* key)
|
||||
{
|
||||
v8::Local<v8::Object> obj = value_;
|
||||
v8::Local<v8::Value> k = *key;
|
||||
|
||||
v8::Maybe<bool> hasMaybe = obj->Has(engine_->GetContext(), k);
|
||||
|
||||
return hasMaybe.FromMaybe(false);
|
||||
}
|
||||
|
||||
bool V8NativeObject::DeleteProperty(NativeValue* key)
|
||||
{
|
||||
v8::Local<v8::Value> k = *key;
|
||||
v8::Local<v8::Object> obj = value_;
|
||||
|
||||
v8::Maybe<bool> deleteMaybe = obj->Delete(engine_->GetContext(), k);
|
||||
|
||||
return deleteMaybe.FromMaybe(false);
|
||||
}
|
||||
|
||||
bool V8NativeObject::SetProperty(const char* name, NativeValue* value)
|
||||
{
|
||||
v8::Local<v8::Object> obj = value_;
|
||||
|
||||
v8::Local<v8::Name> key = v8::String::NewFromUtf8(engine_->GetIsolate(), name).ToLocalChecked();
|
||||
|
||||
v8::Local<v8::Value> val = *value;
|
||||
|
||||
v8::Maybe<bool> setMaybe = obj->Set(engine_->GetContext(), key, val);
|
||||
|
||||
return setMaybe.FromMaybe(false);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeObject::GetProperty(const char* name)
|
||||
{
|
||||
v8::Local<v8::Name> key = v8::String::NewFromUtf8(engine_->GetIsolate(), name).ToLocalChecked();
|
||||
v8::Local<v8::Object> obj = value_;
|
||||
|
||||
auto getMaybe = obj->Get(engine_->GetContext(), key);
|
||||
|
||||
v8::Local<v8::Value> val = getMaybe.ToLocalChecked();
|
||||
|
||||
return V8NativeEngine::V8ValueToNativeValue(engine_, val);
|
||||
}
|
||||
|
||||
bool V8NativeObject::HasProperty(const char* name)
|
||||
{
|
||||
v8::Local<v8::Name> key = v8::String::NewFromUtf8(engine_->GetIsolate(), name).ToLocalChecked();
|
||||
v8::Local<v8::Object> obj = value_;
|
||||
|
||||
v8::Maybe<bool> hasMaybe = obj->Has(engine_->GetContext(), key);
|
||||
return hasMaybe.FromMaybe(false);
|
||||
}
|
||||
|
||||
bool V8NativeObject::DeleteProperty(const char* name)
|
||||
{
|
||||
v8::Local<v8::Name> key = v8::String::NewFromUtf8(engine_->GetIsolate(), name).ToLocalChecked();
|
||||
v8::Local<v8::Object> obj = value_;
|
||||
|
||||
v8::Maybe<bool> deleteMaybe = obj->Delete(engine_->GetContext(), key);
|
||||
|
||||
return deleteMaybe.FromMaybe(false);
|
||||
}
|
||||
|
||||
bool V8NativeObject::SetPrivateProperty(const char* name, NativeValue* value)
|
||||
{
|
||||
v8::Local<v8::String> key = v8::String::NewFromUtf8(engine_->GetIsolate(), name).ToLocalChecked();
|
||||
v8::Local<v8::Value> val = *value;
|
||||
v8::Local<v8::Object> obj = value_;
|
||||
|
||||
v8::Maybe<bool> setMaybe =
|
||||
obj->SetPrivate(engine_->GetContext(), v8::Private::New(engine_->GetIsolate(), key), val);
|
||||
|
||||
return setMaybe.FromMaybe(false);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeObject::GetPrivateProperty(const char* name)
|
||||
{
|
||||
v8::Local<v8::String> key = v8::String::NewFromUtf8(engine_->GetIsolate(), name).ToLocalChecked();
|
||||
v8::Local<v8::Object> obj = value_;
|
||||
|
||||
auto getMaybe = obj->GetPrivate(engine_->GetContext(), v8::Private::New(engine_->GetIsolate(), key));
|
||||
v8::Local<v8::Value> val = getMaybe.ToLocalChecked();
|
||||
|
||||
return V8NativeEngine::V8ValueToNativeValue(engine_, val);
|
||||
}
|
||||
|
||||
bool V8NativeObject::HasPrivateProperty(const char* name)
|
||||
{
|
||||
v8::Local<v8::String> key = v8::String::NewFromUtf8(engine_->GetIsolate(), name).ToLocalChecked();
|
||||
v8::Local<v8::Object> obj = value_;
|
||||
|
||||
v8::Maybe<bool> hasMaybe = obj->HasPrivate(engine_->GetContext(), v8::Private::New(engine_->GetIsolate(), key));
|
||||
|
||||
return hasMaybe.FromMaybe(false);
|
||||
}
|
||||
|
||||
bool V8NativeObject::DeletePrivateProperty(const char* name)
|
||||
{
|
||||
v8::Local<v8::String> key = v8::String::NewFromUtf8(engine_->GetIsolate(), name).ToLocalChecked();
|
||||
v8::Local<v8::Object> obj = value_;
|
||||
|
||||
v8::Maybe<bool> deleteMaybe =
|
||||
obj->DeletePrivate(engine_->GetContext(), v8::Private::New(engine_->GetIsolate(), key));
|
||||
|
||||
return deleteMaybe.FromMaybe(false);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_OBJECT_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_OBJECT_H
|
||||
|
||||
#include "v8_native_value.h"
|
||||
|
||||
class V8NativeObject : public V8NativeValue, public NativeObject {
|
||||
public:
|
||||
explicit V8NativeObject(V8NativeEngine* engine);
|
||||
V8NativeObject(V8NativeEngine* engine, v8::Local<v8::Value> value);
|
||||
virtual ~V8NativeObject();
|
||||
|
||||
void* GetInterface(int interfaceId) override;
|
||||
|
||||
virtual void SetNativePointer(void* pointer, NativeFinalize cb, void* hint) override;
|
||||
virtual void* GetNativePointer() override;
|
||||
|
||||
virtual NativeValue* GetPropertyNames() override;
|
||||
|
||||
virtual NativeValue* GetPrototype() override;
|
||||
|
||||
virtual bool DefineProperty(NativePropertyDescriptor propertyDescriptor) override;
|
||||
|
||||
virtual bool SetProperty(NativeValue* key, NativeValue* value) override;
|
||||
virtual NativeValue* GetProperty(NativeValue* key) override;
|
||||
virtual bool HasProperty(NativeValue* key) override;
|
||||
virtual bool DeleteProperty(NativeValue* key) override;
|
||||
|
||||
virtual bool SetProperty(const char* name, NativeValue* value) override;
|
||||
virtual NativeValue* GetProperty(const char* name) override;
|
||||
virtual bool HasProperty(const char* name) override;
|
||||
virtual bool DeleteProperty(const char* name) override;
|
||||
|
||||
virtual bool SetPrivateProperty(const char* name, NativeValue* value) override;
|
||||
virtual NativeValue* GetPrivateProperty(const char* name) override;
|
||||
virtual bool HasPrivateProperty(const char* name) override;
|
||||
virtual bool DeletePrivateProperty(const char* name) override;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_OBJECT_H */
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "v8_native_string.h"
|
||||
|
||||
#include "utils/log.h"
|
||||
|
||||
V8NativeString::V8NativeString(V8NativeEngine* engine, const char* value, size_t length)
|
||||
: V8NativeString(
|
||||
engine,
|
||||
v8::String::NewFromUtf8(engine->GetIsolate(), value, v8::NewStringType::kNormal, length).ToLocalChecked())
|
||||
{
|
||||
}
|
||||
V8NativeString::V8NativeString(V8NativeEngine* engine, v8::Local<v8::Value> value) : V8NativeValue(engine, value) {}
|
||||
|
||||
V8NativeString::~V8NativeString() {}
|
||||
|
||||
void* V8NativeString::GetInterface(int interfaceId)
|
||||
{
|
||||
return (NativeString::INTERFACE_ID == interfaceId) ? (NativeString*)this : nullptr;
|
||||
}
|
||||
|
||||
void V8NativeString::GetCString(char* buffer, size_t size, size_t* length)
|
||||
{
|
||||
if (length == nullptr) {
|
||||
HILOG_ERROR("length is nullptr");
|
||||
return;
|
||||
}
|
||||
|
||||
v8::Local<v8::String> val = value_;
|
||||
if (buffer == nullptr) {
|
||||
*length = val->Utf8Length(engine_->GetIsolate());
|
||||
} else if (size != 0) {
|
||||
int copied = val->WriteUtf8(engine_->GetIsolate(), buffer, size, nullptr,
|
||||
v8::String::REPLACE_INVALID_UTF8 | v8::String::NO_NULL_TERMINATION);
|
||||
buffer[copied] = '\0';
|
||||
*length = copied;
|
||||
} else {
|
||||
*length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t V8NativeString::GetLength()
|
||||
{
|
||||
v8::Local<v8::String> value = value_;
|
||||
return value->Utf8Length(engine_->GetIsolate());
|
||||
}
|
||||
|
||||
size_t V8NativeString::EncodeWriteUtf8(char* buffer, size_t bufferSize, int32_t* nchars)
|
||||
{
|
||||
if (nchars == nullptr) {
|
||||
HILOG_ERROR("nchars is nullptr");
|
||||
return 0;
|
||||
}
|
||||
|
||||
v8::Local<v8::String> val = value_;
|
||||
int32_t copied = 0;
|
||||
if (buffer == nullptr) {
|
||||
copied = val->Utf8Length(engine_->GetIsolate());
|
||||
} else {
|
||||
copied = val->WriteUtf8(engine_->GetIsolate(),
|
||||
buffer,
|
||||
static_cast<int32_t>(bufferSize),
|
||||
nchars,
|
||||
v8::String::REPLACE_INVALID_UTF8 | v8::String::NO_NULL_TERMINATION);
|
||||
buffer[copied] = '\0';
|
||||
}
|
||||
|
||||
return static_cast<size_t>(copied);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_STRING_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_STRING_H
|
||||
|
||||
#include "v8_native_value.h"
|
||||
|
||||
class V8NativeString : public V8NativeValue, public NativeString {
|
||||
public:
|
||||
V8NativeString(V8NativeEngine* engine, const char* value, size_t length);
|
||||
V8NativeString(V8NativeEngine* engine, v8::Local<v8::Value> value);
|
||||
virtual ~V8NativeString();
|
||||
|
||||
virtual void* GetInterface(int interfaceId) override;
|
||||
|
||||
virtual void GetCString(char* buffer, size_t size, size_t* length) override;
|
||||
virtual size_t GetLength() override;
|
||||
virtual size_t EncodeWriteUtf8(char* buffer, size_t bufferSize, int32_t* nchars) override;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_STRING_H */
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "v8_native_typed_array.h"
|
||||
|
||||
V8NativeTypedArray::V8NativeTypedArray(V8NativeEngine* engine, v8::Local<v8::Value> value)
|
||||
: V8NativeObject(engine, value)
|
||||
{
|
||||
}
|
||||
|
||||
V8NativeTypedArray::V8NativeTypedArray(V8NativeEngine* engine,
|
||||
NativeTypedArrayType type,
|
||||
NativeValue* value,
|
||||
size_t length,
|
||||
size_t offset)
|
||||
: V8NativeTypedArray(engine, v8::Local<v8::TypedArray>())
|
||||
{
|
||||
v8::Local<v8::Value> v8Value = *value;
|
||||
v8::Local<v8::ArrayBuffer> buffer = v8Value.As<v8::ArrayBuffer>();
|
||||
v8::Local<v8::TypedArray> typedArray;
|
||||
switch (type) {
|
||||
case NATIVE_INT8_ARRAY:
|
||||
typedArray = v8::Int8Array::New(buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_UINT8_ARRAY:
|
||||
typedArray = v8::Uint8Array::New(buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_UINT8_CLAMPED_ARRAY:
|
||||
typedArray = v8::Uint8ClampedArray::New(buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_INT16_ARRAY:
|
||||
typedArray = v8::Int16Array::New(buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_UINT16_ARRAY:
|
||||
typedArray = v8::Uint16Array::New(buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_INT32_ARRAY:
|
||||
typedArray = v8::Int32Array::New(buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_UINT32_ARRAY:
|
||||
typedArray = v8::Uint32Array::New(buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_FLOAT32_ARRAY:
|
||||
typedArray = v8::Float32Array::New(buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_FLOAT64_ARRAY:
|
||||
typedArray = v8::Float64Array::New(buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_BIGINT64_ARRAY:
|
||||
typedArray = v8::BigInt64Array::New(buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_BIGUINT64_ARRAY:
|
||||
typedArray = v8::BigUint64Array::New(buffer, offset, length);
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
value_ = typedArray;
|
||||
}
|
||||
|
||||
V8NativeTypedArray::~V8NativeTypedArray() {}
|
||||
|
||||
void* V8NativeTypedArray::GetInterface(int interfaceId)
|
||||
{
|
||||
return (NativeTypedArray::INTERFACE_ID == interfaceId) ? (NativeTypedArray*)this
|
||||
: V8NativeObject::GetInterface(interfaceId);
|
||||
}
|
||||
|
||||
NativeTypedArrayType V8NativeTypedArray::GetTypedArrayType()
|
||||
{
|
||||
v8::Local<v8::TypedArray> value = value_;
|
||||
|
||||
NativeTypedArrayType type = NATIVE_INT8_ARRAY;
|
||||
|
||||
if (value->IsInt8Array()) {
|
||||
type = NATIVE_INT8_ARRAY;
|
||||
} else if (value->IsUint8Array()) {
|
||||
type = NATIVE_UINT8_ARRAY;
|
||||
} else if (value->IsUint8ClampedArray()) {
|
||||
type = NATIVE_UINT8_CLAMPED_ARRAY;
|
||||
} else if (value->IsInt16Array()) {
|
||||
type = NATIVE_INT16_ARRAY;
|
||||
} else if (value->IsUint16Array()) {
|
||||
type = NATIVE_UINT16_ARRAY;
|
||||
} else if (value->IsInt32Array()) {
|
||||
type = NATIVE_INT32_ARRAY;
|
||||
} else if (value->IsUint32Array()) {
|
||||
type = NATIVE_UINT32_ARRAY;
|
||||
} else if (value->IsFloat32Array()) {
|
||||
type = NATIVE_FLOAT32_ARRAY;
|
||||
} else if (value->IsFloat64Array()) {
|
||||
type = NATIVE_FLOAT64_ARRAY;
|
||||
} else if (value->IsBigInt64Array()) {
|
||||
type = NATIVE_BIGINT64_ARRAY;
|
||||
} else if (value->IsBigUint64Array()) {
|
||||
type = NATIVE_BIGUINT64_ARRAY;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
size_t V8NativeTypedArray::GetLength()
|
||||
{
|
||||
v8::Local<v8::TypedArray> value = value_;
|
||||
|
||||
return value->ByteLength();
|
||||
}
|
||||
|
||||
NativeValue* V8NativeTypedArray::GetArrayBuffer()
|
||||
{
|
||||
v8::Local<v8::TypedArray> value = value_;
|
||||
|
||||
return V8NativeEngine::V8ValueToNativeValue(engine_, value->Buffer());
|
||||
}
|
||||
|
||||
void* V8NativeTypedArray::GetData()
|
||||
{
|
||||
v8::Local<v8::TypedArray> value = value_;
|
||||
|
||||
return value->Buffer()->GetBackingStore()->Data();
|
||||
}
|
||||
|
||||
size_t V8NativeTypedArray::GetOffset()
|
||||
{
|
||||
v8::Local<v8::TypedArray> value = value_;
|
||||
|
||||
return value->ByteOffset();
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_TYPED_ARRAY_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_TYPED_ARRAY_H
|
||||
|
||||
#include "v8_native_object.h"
|
||||
|
||||
class V8NativeTypedArray : public V8NativeObject, public NativeTypedArray {
|
||||
public:
|
||||
V8NativeTypedArray(V8NativeEngine* engine, v8::Local<v8::Value> value);
|
||||
V8NativeTypedArray(V8NativeEngine* engine,
|
||||
NativeTypedArrayType type,
|
||||
NativeValue* value,
|
||||
size_t length,
|
||||
size_t offset);
|
||||
virtual ~V8NativeTypedArray();
|
||||
|
||||
virtual void* GetInterface(int interfaceId) override;
|
||||
|
||||
virtual NativeTypedArrayType GetTypedArrayType() override;
|
||||
virtual size_t GetLength() override;
|
||||
virtual NativeValue* GetArrayBuffer() override;
|
||||
virtual void* GetData() override;
|
||||
virtual size_t GetOffset() override;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_TYPED_ARRAY_H */
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "v8_native_value.h"
|
||||
|
||||
V8NativeValue::V8NativeValue(V8NativeEngine* engine, v8::Local<v8::Value> value)
|
||||
{
|
||||
engine_ = engine;
|
||||
value_ = value;
|
||||
|
||||
NativeScopeManager* scopeManager = engine_->GetScopeManager();
|
||||
if (scopeManager != nullptr) {
|
||||
scopeManager->CreateHandle(this);
|
||||
}
|
||||
}
|
||||
|
||||
V8NativeValue::~V8NativeValue() {}
|
||||
|
||||
void* V8NativeValue::GetInterface(int interfaceId)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NativeValueType V8NativeValue::TypeOf()
|
||||
{
|
||||
v8::Local<v8::Value> value = value_;
|
||||
NativeValueType result;
|
||||
|
||||
if (value->IsNumber()) {
|
||||
result = NATIVE_NUMBER;
|
||||
} else if (value->IsBigInt()) {
|
||||
result = NATIVE_BIGINT;
|
||||
} else if (value->IsString()) {
|
||||
result = NATIVE_STRING;
|
||||
} else if (value->IsFunction()) {
|
||||
result = NATIVE_FUNCTION;
|
||||
} else if (value->IsExternal()) {
|
||||
result = NATIVE_EXTERNAL;
|
||||
} else if (value->IsObject()) {
|
||||
result = NATIVE_OBJECT;
|
||||
} else if (value->IsBoolean()) {
|
||||
result = NATIVE_BOOLEAN;
|
||||
} else if (value->IsUndefined()) {
|
||||
result = NATIVE_UNDEFINED;
|
||||
} else if (value->IsSymbol()) {
|
||||
result = NATIVE_SYMBOL;
|
||||
} else if (value->IsNull()) {
|
||||
result = NATIVE_NULL;
|
||||
} else {
|
||||
result = NATIVE_UNDEFINED;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool V8NativeValue::InstanceOf(NativeValue* obj)
|
||||
{
|
||||
v8::Local<v8::Value> value = value_;
|
||||
return value->InstanceOf(engine_->GetContext(), *obj).FromJust();
|
||||
}
|
||||
|
||||
bool V8NativeValue::IsArray()
|
||||
{
|
||||
v8::Local<v8::Value> value = value_;
|
||||
return value->IsArray();
|
||||
}
|
||||
|
||||
bool V8NativeValue::IsArrayBuffer()
|
||||
{
|
||||
v8::Local<v8::Value> value = value_;
|
||||
return value->IsArrayBuffer();
|
||||
}
|
||||
|
||||
bool V8NativeValue::IsDate()
|
||||
{
|
||||
v8::Local<v8::Value> value = value_;
|
||||
return value->IsDate();
|
||||
}
|
||||
|
||||
bool V8NativeValue::IsError()
|
||||
{
|
||||
v8::Local<v8::Value> value = value_;
|
||||
return value->IsNativeError();
|
||||
}
|
||||
|
||||
bool V8NativeValue::IsTypedArray()
|
||||
{
|
||||
v8::Local<v8::Value> value = value_;
|
||||
return value->IsTypedArray();
|
||||
}
|
||||
|
||||
bool V8NativeValue::IsDataView()
|
||||
{
|
||||
v8::Local<v8::Value> value = value_;
|
||||
return value->IsDataView();
|
||||
}
|
||||
|
||||
bool V8NativeValue::IsPromise()
|
||||
{
|
||||
v8::Local<v8::Value> value = value_;
|
||||
return value->IsPromise();
|
||||
}
|
||||
|
||||
bool V8NativeValue::IsCallable()
|
||||
{
|
||||
v8::Local<v8::Value> value = value_;
|
||||
return value->IsFunction();
|
||||
}
|
||||
|
||||
NativeValue* V8NativeValue::ToBoolean()
|
||||
{
|
||||
v8::Local<v8::Value> value = value_;
|
||||
return V8NativeEngine::V8ValueToNativeValue(engine_, value->ToBoolean(engine_->GetIsolate()));
|
||||
}
|
||||
|
||||
NativeValue* V8NativeValue::ToNumber()
|
||||
{
|
||||
v8::Local<v8::Value> value = value_;
|
||||
return V8NativeEngine::V8ValueToNativeValue(engine_, value->ToNumber(engine_->GetContext()).ToLocalChecked());
|
||||
}
|
||||
|
||||
NativeValue* V8NativeValue::ToString()
|
||||
{
|
||||
v8::Local<v8::Value> value = value_;
|
||||
return V8NativeEngine::V8ValueToNativeValue(engine_, value->ToString(engine_->GetContext()).ToLocalChecked());
|
||||
}
|
||||
|
||||
NativeValue* V8NativeValue::ToObject()
|
||||
{
|
||||
v8::Local<v8::Value> value = value_;
|
||||
return V8NativeEngine::V8ValueToNativeValue(engine_, value->ToObject(engine_->GetContext()).ToLocalChecked());
|
||||
}
|
||||
|
||||
bool V8NativeValue::StrictEquals(NativeValue* value)
|
||||
{
|
||||
v8::Local<v8::Value> v8Value = value_;
|
||||
return v8Value->StrictEquals(*value);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_VALUE_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_VALUE_H
|
||||
|
||||
#include "v8_native_engine.h"
|
||||
|
||||
class V8NativeValue : public NativeValue {
|
||||
public:
|
||||
V8NativeValue(V8NativeEngine* engine, v8::Local<v8::Value> value);
|
||||
virtual ~V8NativeValue();
|
||||
|
||||
virtual void* GetInterface(int interfaceId) override;
|
||||
|
||||
virtual NativeValueType TypeOf() override;
|
||||
virtual bool InstanceOf(NativeValue* obj) override;
|
||||
|
||||
virtual bool IsArray() override;
|
||||
virtual bool IsArrayBuffer() override;
|
||||
virtual bool IsDate() override;
|
||||
virtual bool IsError() override;
|
||||
virtual bool IsTypedArray() override;
|
||||
virtual bool IsDataView() override;
|
||||
virtual bool IsPromise() override;
|
||||
virtual bool IsCallable() override;
|
||||
|
||||
virtual NativeValue* ToBoolean() override;
|
||||
virtual NativeValue* ToNumber() override;
|
||||
virtual NativeValue* ToString() override;
|
||||
virtual NativeValue* ToObject() override;
|
||||
|
||||
virtual bool StrictEquals(NativeValue* value) override;
|
||||
|
||||
protected:
|
||||
V8NativeEngine* engine_;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_V8_NATIVE_VALUE_V8_NATIVE_VALUE_H */
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_V8_HEADERS_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_V8_HEADERS_H
|
||||
|
||||
#include "libplatform/libplatform.h"
|
||||
#include "v8.h"
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_V8_HEADERS_H */
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "v8_native_engine.h"
|
||||
|
||||
#include "v8_native_deferred.h"
|
||||
|
||||
V8NativeDeferred::V8NativeDeferred(V8NativeEngine* engine, v8::Local<v8::Promise::Resolver> deferred)
|
||||
: engine_(engine), deferred_(engine->GetIsolate(), deferred)
|
||||
{
|
||||
}
|
||||
|
||||
V8NativeDeferred::~V8NativeDeferred() {}
|
||||
|
||||
void V8NativeDeferred::Resolve(NativeValue* data)
|
||||
{
|
||||
v8::Local<v8::Context> context = engine_->GetContext();
|
||||
v8::Isolate* isolate = engine_->GetIsolate();
|
||||
|
||||
v8::Local<v8::Value> value = *data;
|
||||
auto v8Resolver = deferred_.Get(isolate);
|
||||
|
||||
v8Resolver->Resolve(context, value).ToChecked();
|
||||
}
|
||||
|
||||
void V8NativeDeferred::Reject(NativeValue* reason)
|
||||
{
|
||||
v8::Local<v8::Context> context = engine_->GetContext();
|
||||
v8::Isolate* isolate = engine_->GetIsolate();
|
||||
|
||||
v8::Local<v8::Value> value = *reason;
|
||||
auto v8Resolver = deferred_.Get(isolate);
|
||||
|
||||
v8Resolver->Reject(context, value).ToChecked();
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_V8_NATIVE_DEFERRED_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_V8_NATIVE_DEFERRED_H
|
||||
|
||||
#include "v8_headers.h"
|
||||
|
||||
#include "native_engine/native_deferred.h"
|
||||
|
||||
class V8NativeDeferred : public NativeDeferred {
|
||||
public:
|
||||
V8NativeDeferred(V8NativeEngine* engine, v8::Local<v8::Promise::Resolver> deferred);
|
||||
virtual ~V8NativeDeferred();
|
||||
virtual void Resolve(NativeValue* data) override;
|
||||
virtual void Reject(NativeValue* reason) override;
|
||||
|
||||
private:
|
||||
V8NativeEngine* engine_;
|
||||
v8::Global<v8::Promise::Resolver> deferred_;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_V8_NATIVE_DEFERRED_H */
|
||||
@@ -0,0 +1,861 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "v8_native_engine.h"
|
||||
|
||||
#include <js_native_api.h>
|
||||
|
||||
#include "native_engine/native_property.h"
|
||||
#include "native_value/v8_native_array.h"
|
||||
#include "native_value/v8_native_array_buffer.h"
|
||||
#include "native_value/v8_native_boolean.h"
|
||||
#include "native_value/v8_native_data_view.h"
|
||||
#include "native_value/v8_native_external.h"
|
||||
#include "native_value/v8_native_function.h"
|
||||
#include "native_value/v8_native_number.h"
|
||||
#include "native_value/v8_native_object.h"
|
||||
#include "native_value/v8_native_string.h"
|
||||
#include "native_value/v8_native_typed_array.h"
|
||||
#include "securec.h"
|
||||
#include "utils/log.h"
|
||||
#include "v8_native_deferred.h"
|
||||
#include "v8_native_reference.h"
|
||||
|
||||
V8NativeEngine::V8NativeEngine(v8::Platform* platform, v8::Isolate* isolate,
|
||||
v8::Persistent<v8::Context>& context, void* jsEngine)
|
||||
: NativeEngine(jsEngine),
|
||||
platform_(platform),
|
||||
isolate_(isolate),
|
||||
context_(isolate, context),
|
||||
isolateScope_(isolate),
|
||||
handleScope_(isolate_),
|
||||
contextScope_(context.Get(isolate_)),
|
||||
tryCatch_(isolate_)
|
||||
{
|
||||
v8::Local<v8::String> requireNapiName = v8::String::NewFromUtf8(isolate_, "requireNapi").ToLocalChecked();
|
||||
v8::Local<v8::String> requireInternalName = v8::String::NewFromUtf8(isolate_, "requireInternal").ToLocalChecked();
|
||||
|
||||
v8::Local<v8::Value> requireData = v8::External::New(isolate_, (void*)this).As<v8::Value>();
|
||||
|
||||
v8::Local<v8::Function> requireNapi =
|
||||
v8::Function::New(
|
||||
context_.Get(isolate_),
|
||||
[](const v8::FunctionCallbackInfo<v8::Value>& info) {
|
||||
V8NativeEngine* engine = (V8NativeEngine*)info.Data().As<v8::External>()->Value();
|
||||
if (engine == nullptr) {
|
||||
return;
|
||||
}
|
||||
v8::String::Utf8Value moduleName(info.GetIsolate(), info[0]);
|
||||
NativeModuleManager* moduleManager = NativeModuleManager::GetInstance();
|
||||
if (moduleManager == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool isAppModule = false;
|
||||
if (info.Length() == 2) {
|
||||
isAppModule = info[1]->ToBoolean(info.GetIsolate())->Value();
|
||||
}
|
||||
NativeModule* module = moduleManager->LoadNativeModule(*moduleName, nullptr, isAppModule);
|
||||
|
||||
if (module == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (module->jsCode != nullptr) {
|
||||
HILOG_INFO("load js code");
|
||||
NativeValue* script = engine->CreateString(module->jsCode, strlen(module->jsCode));
|
||||
NativeValue* exportObject = engine->LoadModule(script, "testjsnapi.js");
|
||||
if (exportObject == nullptr) {
|
||||
HILOG_ERROR("load module failed");
|
||||
return;
|
||||
}
|
||||
v8::Local<v8::Object> exports = *exportObject;
|
||||
info.GetReturnValue().Set(exports);
|
||||
HILOG_ERROR("load module succ");
|
||||
} else if (module->registerCallback != nullptr) {
|
||||
HILOG_INFO("load napi module");
|
||||
NativeValue* exportObject = new V8NativeObject(engine);
|
||||
if (exportObject == nullptr) {
|
||||
return;
|
||||
}
|
||||
module->registerCallback(engine, exportObject);
|
||||
v8::Local<v8::Object> exports = *exportObject;
|
||||
info.GetReturnValue().Set(exports);
|
||||
}
|
||||
},
|
||||
requireData, 1)
|
||||
.ToLocalChecked();
|
||||
|
||||
v8::Local<v8::Function> requireInternal =
|
||||
v8::Function::New(
|
||||
context_.Get(isolate_),
|
||||
[](const v8::FunctionCallbackInfo<v8::Value>& info) {
|
||||
V8NativeEngine* engine = (V8NativeEngine*)info.Data().As<v8::External>()->Value();
|
||||
if (engine == nullptr) {
|
||||
return;
|
||||
}
|
||||
v8::String::Utf8Value moduleName(info.GetIsolate(), info[0]);
|
||||
NativeModuleManager* moduleManager = NativeModuleManager::GetInstance();
|
||||
if (moduleManager == nullptr) {
|
||||
return;
|
||||
}
|
||||
NativeModule* module = moduleManager->LoadNativeModule(*moduleName, nullptr, false, true);
|
||||
if (module == nullptr) {
|
||||
return;
|
||||
}
|
||||
NativeValue* exportObject = new V8NativeObject(engine);
|
||||
if (exportObject == nullptr) {
|
||||
return;
|
||||
}
|
||||
module->registerCallback(engine, exportObject);
|
||||
v8::Local<v8::Object> exports = *exportObject;
|
||||
info.GetReturnValue().Set(exports);
|
||||
},
|
||||
requireData, 1)
|
||||
.ToLocalChecked();
|
||||
|
||||
v8::Local<v8::Object> global = context_.Get(isolate_)->Global();
|
||||
|
||||
global->Set(context_.Get(isolate_), requireNapiName, requireNapi).FromJust();
|
||||
global->Set(context_.Get(isolate_), requireInternalName, requireInternal).FromJust();
|
||||
}
|
||||
|
||||
V8NativeEngine::~V8NativeEngine() {}
|
||||
|
||||
v8::Local<v8::Object> V8NativeEngine::GetModuleFromName(
|
||||
const std::string& moduleName, bool isAppModule, const std::string& id, const std::string& param,
|
||||
const std::string& instanceName, void** instance)
|
||||
{
|
||||
HILOG_INFO("GetModuleFromName");
|
||||
v8::Isolate* isolate = this->GetContext()->GetIsolate();
|
||||
v8::HandleScope handleScope(isolate);
|
||||
|
||||
v8::Local<v8::Object> exports;
|
||||
NativeModuleManager* moduleManager = NativeModuleManager::GetInstance();
|
||||
NativeModule* module = moduleManager->LoadNativeModule(moduleName.c_str(), nullptr, isAppModule);
|
||||
if (module != nullptr) {
|
||||
NativeValue* idValue = new V8NativeString(this, id.c_str(), id.size());
|
||||
NativeValue* paramValue = new V8NativeString(this, param.c_str(), param.size());
|
||||
NativeValue* exportObject = new V8NativeObject(this);
|
||||
|
||||
NativePropertyDescriptor idProperty, paramProperty;
|
||||
idProperty.utf8name = "id";
|
||||
idProperty.value = idValue;
|
||||
paramProperty.utf8name = "param";
|
||||
paramProperty.value = paramValue;
|
||||
V8NativeObject* exportObj = reinterpret_cast<V8NativeObject*>(exportObject);
|
||||
exportObj->DefineProperty(idProperty);
|
||||
exportObj->DefineProperty(paramProperty);
|
||||
module->registerCallback(this, exportObject);
|
||||
|
||||
napi_value nExport = reinterpret_cast<napi_value>(exportObject);
|
||||
napi_value exportInstance = nullptr;
|
||||
napi_status status = napi_get_named_property(
|
||||
reinterpret_cast<napi_env>(this), nExport, instanceName.c_str(), &exportInstance);
|
||||
if (status != napi_ok) {
|
||||
HILOG_ERROR("GetModuleFromName napi_get_named_property status != napi_ok");
|
||||
}
|
||||
|
||||
status = napi_unwrap(reinterpret_cast<napi_env>(this), exportInstance, reinterpret_cast<void**>(instance));
|
||||
if (status != napi_ok) {
|
||||
HILOG_ERROR("GetModuleFromName napi_unwrap status != napi_ok");
|
||||
}
|
||||
|
||||
exports = *exportObject;
|
||||
}
|
||||
return exports;
|
||||
}
|
||||
|
||||
v8::Isolate* V8NativeEngine::GetIsolate()
|
||||
{
|
||||
return isolate_;
|
||||
}
|
||||
|
||||
v8::Local<v8::Context> V8NativeEngine::GetContext()
|
||||
{
|
||||
return *reinterpret_cast<v8::Local<v8::Context>*>(const_cast<v8::Global<v8::Context>*>(&context_));
|
||||
}
|
||||
|
||||
void V8NativeEngine::Loop(LoopMode mode, bool needSync)
|
||||
{
|
||||
NativeEngine::Loop(mode, needSync);
|
||||
v8::platform::PumpMessageLoop(platform_, isolate_);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::GetGlobal()
|
||||
{
|
||||
v8::Local<v8::Object> value = context_.Get(isolate_)->Global();
|
||||
return V8ValueToNativeValue(this, value);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::CreateNull()
|
||||
{
|
||||
v8::Local<v8::Primitive> value = v8::Null(isolate_);
|
||||
return new V8NativeValue(this, value);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::CreateUndefined()
|
||||
{
|
||||
v8::Local<v8::Primitive> value = v8::Undefined(isolate_);
|
||||
return new V8NativeValue(this, value);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::CreateBoolean(bool value)
|
||||
{
|
||||
return new V8NativeBoolean(this, value);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::CreateNumber(int32_t value)
|
||||
{
|
||||
return new V8NativeNumber(this, value);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::CreateNumber(uint32_t value)
|
||||
{
|
||||
return new V8NativeNumber(this, value);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::CreateNumber(int64_t value)
|
||||
{
|
||||
return new V8NativeNumber(this, value);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::CreateNumber(double value)
|
||||
{
|
||||
return new V8NativeNumber(this, value);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::CreateString(const char* value, size_t length)
|
||||
{
|
||||
return new V8NativeString(this, value, length);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::CreateSymbol(NativeValue* value)
|
||||
{
|
||||
return new V8NativeValue(this, v8::Symbol::New(isolate_, *value));
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::CreateExternal(void* value, NativeFinalize callback, void* hint)
|
||||
{
|
||||
return new V8NativeExternal(this, value, callback, hint);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::CreateObject()
|
||||
{
|
||||
return new V8NativeObject(this);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::CreateFunction(const char* name, size_t length, NativeCallback cb, void* value)
|
||||
{
|
||||
return new V8NativeFunction(this, name, length, cb, value);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::CreateArray(size_t length)
|
||||
{
|
||||
return new V8NativeArray(this, length);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::CreateArrayBuffer(void** value, size_t length)
|
||||
{
|
||||
return new V8NativeArrayBuffer(this, (uint8_t**)value, length);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::CreateArrayBufferExternal(void* value, size_t length, NativeFinalize cb, void* hint)
|
||||
{
|
||||
return new V8NativeArrayBuffer(this, (uint8_t*)value, length, cb, hint);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::CreateTypedArray(NativeTypedArrayType type,
|
||||
NativeValue* value,
|
||||
size_t length,
|
||||
size_t offset)
|
||||
{
|
||||
v8::Local<v8::ArrayBuffer> buffer = *value;
|
||||
v8::Local<v8::TypedArray> typedArray;
|
||||
|
||||
switch (type) {
|
||||
case NATIVE_INT8_ARRAY:
|
||||
typedArray = v8::Int8Array::New(buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_UINT8_ARRAY:
|
||||
typedArray = v8::Uint8Array::New(buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_UINT8_CLAMPED_ARRAY:
|
||||
typedArray = v8::Uint8ClampedArray::New(buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_INT16_ARRAY:
|
||||
typedArray = v8::Int16Array::New(buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_UINT16_ARRAY:
|
||||
typedArray = v8::Uint16Array::New(buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_INT32_ARRAY:
|
||||
typedArray = v8::Int32Array::New(buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_UINT32_ARRAY:
|
||||
typedArray = v8::Uint32Array::New(buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_FLOAT32_ARRAY:
|
||||
typedArray = v8::Float32Array::New(buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_FLOAT64_ARRAY:
|
||||
typedArray = v8::Float64Array::New(buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_BIGINT64_ARRAY:
|
||||
typedArray = v8::BigInt64Array::New(buffer, offset, length);
|
||||
break;
|
||||
case NATIVE_BIGUINT64_ARRAY:
|
||||
typedArray = v8::BigUint64Array::New(buffer, offset, length);
|
||||
break;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
return new V8NativeTypedArray(this, typedArray);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::CreateDataView(NativeValue* value, size_t length, size_t offset)
|
||||
{
|
||||
return new V8NativeDataView(this, value, length, offset);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::CreatePromise(NativeDeferred** deferred)
|
||||
{
|
||||
auto v8Resolver = v8::Promise::Resolver::New(context_.Get(isolate_)).ToLocalChecked();
|
||||
|
||||
*deferred = new V8NativeDeferred(this, v8Resolver);
|
||||
|
||||
return new V8NativeValue(this, v8Resolver->GetPromise());
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::CreateError(NativeValue* code, NativeValue* message)
|
||||
{
|
||||
v8::Local<v8::Value> errorObj = v8::Exception::Error(*message);
|
||||
if (code) {
|
||||
v8::Local<v8::Value> codeKey = v8::String::NewFromUtf8(isolate_, "code").ToLocalChecked();
|
||||
errorObj.As<v8::Object>()->Set(context_.Get(isolate_), codeKey, *code).FromJust();
|
||||
}
|
||||
return V8ValueToNativeValue(this, errorObj);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::CallFunction(NativeValue* thisVar,
|
||||
NativeValue* function,
|
||||
NativeValue* const* argv,
|
||||
size_t argc)
|
||||
{
|
||||
if (function == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
v8::Local<v8::Value> v8recv = (thisVar != nullptr) ? *thisVar : v8::Undefined(isolate_);
|
||||
v8::Local<v8::Function> v8func = *function;
|
||||
v8::Local<v8::Value>* args = nullptr;
|
||||
v8::Local<v8::Context> context = context_.Get(isolate_);
|
||||
if (argc > 0) {
|
||||
args = new v8::Local<v8::Value>[argc];
|
||||
for (size_t i = 0; i < argc && args != nullptr; i++) {
|
||||
if (argv[i] != nullptr) {
|
||||
args[i] = *argv[i];
|
||||
} else {
|
||||
args[i] = v8::Undefined(isolate_);
|
||||
}
|
||||
}
|
||||
}
|
||||
v8::MaybeLocal<v8::Value> maybeValue = v8func->Call(context, v8recv, argc, args);
|
||||
if (args != nullptr) {
|
||||
delete []args;
|
||||
}
|
||||
v8::Local<v8::Value> result;
|
||||
if (!maybeValue.ToLocal(&result)) {
|
||||
return nullptr;
|
||||
}
|
||||
return V8ValueToNativeValue(this, result);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::RunScript(NativeValue* script)
|
||||
{
|
||||
v8::Local<v8::Value> v8Script = *script;
|
||||
auto maybeScript = v8::Script::Compile(context_.Get(isolate_), v8Script.As<v8::String>());
|
||||
auto localScript = maybeScript.ToLocalChecked();
|
||||
auto scriptResult = localScript->Run(context_.Get(isolate_));
|
||||
|
||||
v8::Local<v8::Value> result;
|
||||
if (!scriptResult.ToLocal(&result)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return V8ValueToNativeValue(this, result);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::RunBufferScript(std::vector<uint8_t>& buffer)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
namespace {
|
||||
v8::MaybeLocal<v8::String> ReadFile(v8::Isolate* isolate, const char* path)
|
||||
{
|
||||
std::ifstream file(path);
|
||||
if (file.fail()) {
|
||||
file.close();
|
||||
return v8::MaybeLocal<v8::String>();
|
||||
}
|
||||
|
||||
std::string fileContent;
|
||||
fileContent.clear();
|
||||
file.seekg(0, std::ios::end);
|
||||
fileContent.reserve(static_cast<std::string::size_type>(file.tellg()));
|
||||
file.seekg(0, std::ios::beg);
|
||||
fileContent.assign(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>());
|
||||
file.close();
|
||||
|
||||
v8::MaybeLocal<v8::String> result = v8::String::NewFromUtf8(isolate, fileContent.c_str(),
|
||||
v8::NewStringType::kNormal, fileContent.size());
|
||||
return result;
|
||||
}
|
||||
|
||||
v8::MaybeLocal<v8::Module> ModuleResolveCallback(v8::Local<v8::Context> context,
|
||||
v8::Local<v8::String> specifier,
|
||||
v8::Local<v8::Module> referrer)
|
||||
{
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
int len = specifier->Length();
|
||||
char *buffer = new char[len + 1];
|
||||
specifier->WriteUtf8(isolate, buffer, len, nullptr,
|
||||
v8::String::REPLACE_INVALID_UTF8 | v8::String::NO_NULL_TERMINATION);
|
||||
auto maybeSourceCode = ReadFile(isolate, buffer);
|
||||
v8::Local<v8::String> sourceCode;
|
||||
if (!maybeSourceCode.ToLocal(&sourceCode)) {
|
||||
v8::ScriptOrigin origin(v8::String::NewFromUtf8(isolate, "moduleloader.js").ToLocalChecked(),
|
||||
v8::Local<v8::Integer>(), v8::Local<v8::Integer>(), v8::Local<v8::Boolean>(),
|
||||
v8::Local<v8::Integer>(), v8::Local<v8::Value>(), v8::Local<v8::Boolean>(),
|
||||
v8::Local<v8::Boolean>(), True(isolate));
|
||||
v8::ScriptCompiler::Source source(specifier, origin);
|
||||
delete[] buffer;
|
||||
return v8::ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
|
||||
}
|
||||
|
||||
v8::ScriptOrigin origin(specifier, v8::Local<v8::Integer>(), v8::Local<v8::Integer>(), v8::Local<v8::Boolean>(),
|
||||
v8::Local<v8::Integer>(), v8::Local<v8::Value>(), v8::Local<v8::Boolean>(),
|
||||
v8::Local<v8::Boolean>(), True(isolate));
|
||||
v8::ScriptCompiler::Source source(sourceCode, origin);
|
||||
auto result = v8::ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
|
||||
delete[] buffer;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::LoadModule(NativeValue* str, const std::string& fileName)
|
||||
{
|
||||
v8::Local<v8::Value> value = *str;
|
||||
auto source = value.As<v8::String>();
|
||||
if (source.IsEmpty() || fileName.empty()) {
|
||||
isolate_->ThrowException(
|
||||
v8::String::NewFromUtf8(isolate_, "Invalid input parameter", v8::NewStringType::kNormal).ToLocalChecked());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
v8::ScriptOrigin origin(v8::String::NewFromUtf8(isolate_, fileName.c_str()).ToLocalChecked(),
|
||||
v8::Local<v8::Integer>(), v8::Local<v8::Integer>(), v8::Local<v8::Boolean>(),
|
||||
v8::Local<v8::Integer>(), v8::Local<v8::Value>(), v8::Local<v8::Boolean>(),
|
||||
v8::Local<v8::Boolean>(), True(isolate_));
|
||||
v8::ScriptCompiler::Source moduleSource(source, origin);
|
||||
v8::Local<v8::Module> module = v8::ScriptCompiler::CompileModule(isolate_, &moduleSource).ToLocalChecked();
|
||||
|
||||
auto context = context_.Get(isolate_);
|
||||
if (!module->InstantiateModule(context, ModuleResolveCallback).FromJust()) {
|
||||
return nullptr;
|
||||
}
|
||||
auto maybeEvaluate = module->Evaluate(context);
|
||||
v8::Local<v8::Value> evaluate;
|
||||
if (!maybeEvaluate.ToLocal(&evaluate)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> moduleNameSpace = module->GetModuleNamespace();
|
||||
v8::Local<v8::Object> nameSpaceObject = moduleNameSpace->ToObject(context).ToLocalChecked();
|
||||
auto exportObj = nameSpaceObject->Get(context, v8::String::NewFromUtf8(isolate_, "default").ToLocalChecked());
|
||||
v8::Local<v8::Value> result;
|
||||
if (!exportObj.ToLocal(&result)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// can use return V8ValueToNativeValue(this, result) ?
|
||||
return new V8NativeObject(this, result);
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::DefineClass(const char* name,
|
||||
NativeCallback callback,
|
||||
void* data,
|
||||
const NativePropertyDescriptor* properties,
|
||||
size_t length)
|
||||
{
|
||||
auto classConstructor = new V8NativeFunction(this, name, 0, callback, data);
|
||||
if (classConstructor == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto classPrototype = new V8NativeObject(this);
|
||||
if (classPrototype == nullptr) {
|
||||
delete classConstructor;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
classConstructor->SetProperty("prototype", classPrototype);
|
||||
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
if (properties[i].attributes & NATIVE_STATIC) {
|
||||
classConstructor->DefineProperty(properties[i]);
|
||||
} else {
|
||||
classPrototype->DefineProperty(properties[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return classConstructor;
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::CreateInstance(NativeValue* constructor, NativeValue* const* argv, size_t argc)
|
||||
{
|
||||
v8::Local<v8::Object> value = *constructor;
|
||||
v8::Local<v8::Value>* args = new v8::Local<v8::Value>[argc];
|
||||
for (size_t i = 0; i < argc && args != nullptr; i++) {
|
||||
args[i] = *argv[i];
|
||||
}
|
||||
|
||||
v8::TryCatch tryCatch(isolate_);
|
||||
v8::MaybeLocal<v8::Value> maybeInstance = value->CallAsConstructor(context_.Get(isolate_), argc, args);
|
||||
delete[] args;
|
||||
|
||||
v8::Local<v8::Value> result;
|
||||
if (maybeInstance.IsEmpty()) {
|
||||
result = v8::Undefined(isolate_);
|
||||
} else {
|
||||
result = maybeInstance.ToLocalChecked();
|
||||
}
|
||||
|
||||
return V8ValueToNativeValue(this, result);
|
||||
}
|
||||
|
||||
NativeReference* V8NativeEngine::CreateReference(NativeValue* value, uint32_t initialRefcount)
|
||||
{
|
||||
return new V8NativeReference(this, value, initialRefcount, false);
|
||||
}
|
||||
|
||||
bool V8NativeEngine::Throw(NativeValue* error)
|
||||
{
|
||||
isolate_->ThrowException(*error);
|
||||
lastException_ = error;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool V8NativeEngine::Throw(NativeErrorType type, const char* code, const char* message)
|
||||
{
|
||||
v8::Local<v8::Value> error;
|
||||
|
||||
switch (type) {
|
||||
case NATIVE_COMMON_ERROR:
|
||||
error = v8::Exception::Error(v8::String::NewFromUtf8(isolate_, message).ToLocalChecked());
|
||||
break;
|
||||
case NATIVE_TYPE_ERROR:
|
||||
error = v8::Exception::TypeError(v8::String::NewFromUtf8(isolate_, message).ToLocalChecked());
|
||||
break;
|
||||
case NATIVE_RANGE_ERROR:
|
||||
error = v8::Exception::RangeError(v8::String::NewFromUtf8(isolate_, message).ToLocalChecked());
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (code) {
|
||||
v8::Local<v8::Value> codeKey = v8::String::NewFromUtf8(isolate_, "code").ToLocalChecked();
|
||||
v8::Local<v8::Value> codeValue = v8::String::NewFromUtf8(isolate_, code).ToLocalChecked();
|
||||
error.As<v8::Object>()->Set(context_.Get(isolate_), codeKey, codeValue).FromJust();
|
||||
}
|
||||
|
||||
isolate_->ThrowException(error);
|
||||
lastException_ = V8ValueToNativeValue(this, error);
|
||||
return true;
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::V8ValueToNativeValue(V8NativeEngine* engine, v8::Local<v8::Value> value)
|
||||
{
|
||||
NativeValue* result = nullptr;
|
||||
if (value->IsNull() || value->IsUndefined() || value->IsSymbol() || value->IsPromise()) {
|
||||
result = new V8NativeValue(engine, value);
|
||||
} else if (value->IsNumber()) {
|
||||
result = new V8NativeNumber(engine, value);
|
||||
} else if (value->IsString()) {
|
||||
result = new V8NativeString(engine, value);
|
||||
} else if (value->IsArray()) {
|
||||
result = new V8NativeArray(engine, value);
|
||||
} else if (value->IsFunction()) {
|
||||
result = new V8NativeFunction(engine, value);
|
||||
} else if (value->IsArrayBuffer()) {
|
||||
result = new V8NativeArrayBuffer(engine, value);
|
||||
} else if (value->IsDataView()) {
|
||||
result = new V8NativeDataView(engine, value);
|
||||
} else if (value->IsTypedArray()) {
|
||||
result = new V8NativeTypedArray(engine, value);
|
||||
} else if (value->IsExternal()) {
|
||||
result = new V8NativeExternal(engine, value);
|
||||
} else if (value->IsObject()) {
|
||||
result = new V8NativeObject(engine, value);
|
||||
} else if (value->IsBoolean()) {
|
||||
result = new V8NativeBoolean(engine, value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void* V8NativeEngine::CreateRuntime()
|
||||
{
|
||||
v8::Isolate::CreateParams createParams;
|
||||
createParams.array_buffer_allocator = isolate_->GetArrayBufferAllocator();
|
||||
v8::Isolate* isolate = v8::Isolate::New(createParams);
|
||||
v8::HandleScope handleScope(isolate);
|
||||
v8::Isolate::Scope isolateScope(isolate);
|
||||
v8::Local<v8::Context> context = v8::Context::New(isolate);
|
||||
v8::Persistent<v8::Context> persistContext;
|
||||
persistContext.Reset(isolate, context);
|
||||
if (context.IsEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
V8NativeEngine* v8Engine = new V8NativeEngine(platform_, isolate, persistContext, jsEngine_);
|
||||
v8Engine->MarkAutoDispose();
|
||||
return reinterpret_cast<void*>(v8Engine);
|
||||
}
|
||||
|
||||
class Serializer {
|
||||
public:
|
||||
explicit Serializer(v8::Isolate* isolate) : isolate_(isolate), v8Serializer_(isolate, nullptr) {}
|
||||
~Serializer() = default;
|
||||
|
||||
bool SerializeValue(v8::Local<v8::Value> value, v8::Local<v8::Value> transfer)
|
||||
{
|
||||
v8::Local<v8::Context> context = isolate_->GetCurrentContext();
|
||||
bool ok = false;
|
||||
DCHECK(!data_);
|
||||
data_.reset(new SerializationData);
|
||||
|
||||
// check transfer list is right
|
||||
if (!CheckTransferReliability(transfer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// serial value
|
||||
v8Serializer_.WriteHeader();
|
||||
if (!v8Serializer_.WriteValue(context, value).To(&ok)) {
|
||||
data_.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
// releasing Data Control Rights
|
||||
if (!DetachTransfer()) {
|
||||
data_.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
std::pair<uint8_t*, size_t> pair = v8Serializer_.Release();
|
||||
data_->data_.reset(pair.first);
|
||||
data_->size_ = pair.second;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<SerializationData> Release()
|
||||
{
|
||||
return std::move(data_);
|
||||
}
|
||||
|
||||
private:
|
||||
bool CheckTransferReliability(v8::Local<v8::Value> transfer)
|
||||
{
|
||||
if (transfer->IsUndefined()) {
|
||||
return true;
|
||||
}
|
||||
if (!transfer->IsArray()) {
|
||||
std::string msg = "Transfer list must be an Array or undefined";
|
||||
isolate_->ThrowException(
|
||||
v8::String::NewFromUtf8(isolate_, msg.c_str(), v8::NewStringType::kNormal).ToLocalChecked());
|
||||
return false;
|
||||
}
|
||||
|
||||
v8::Local<v8::Array> transferArray = v8::Local<v8::Array>::Cast(transfer);
|
||||
uint32_t length = transferArray->Length();
|
||||
uint32_t arrayBufferIdx = 0;
|
||||
v8::Local<v8::Context> context = isolate_->GetCurrentContext();
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
v8::Local<v8::Value> element;
|
||||
if (transferArray->Get(context, i).ToLocal(&element)) {
|
||||
if (!element->IsArrayBuffer()) {
|
||||
std::string msg = "Transfer array elements must be an ArrayBuffer";
|
||||
isolate_->ThrowException(
|
||||
v8::String::NewFromUtf8(isolate_, msg.c_str(), v8::NewStringType::kNormal).ToLocalChecked());
|
||||
return false;
|
||||
}
|
||||
|
||||
v8::Local<v8::ArrayBuffer> arrayBuffer = v8::Local<v8::ArrayBuffer>::Cast(element);
|
||||
auto iter = std::find(visitedTransfer_.begin(), visitedTransfer_.end(), arrayBuffer);
|
||||
if (iter != visitedTransfer_.end()) {
|
||||
std::string msg = "ArrayBuffer occurs in the transfer array more than once";
|
||||
isolate_->ThrowException(
|
||||
v8::String::NewFromUtf8(isolate_, msg.c_str(), v8::NewStringType::kNormal).ToLocalChecked());
|
||||
return false;
|
||||
}
|
||||
|
||||
v8Serializer_.TransferArrayBuffer(arrayBufferIdx++, arrayBuffer);
|
||||
visitedTransfer_.emplace_back(isolate_, arrayBuffer);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DetachTransfer()
|
||||
{
|
||||
for (const auto& item : visitedTransfer_) {
|
||||
v8::Local<v8::ArrayBuffer> arrayBuffer = v8::Local<v8::ArrayBuffer>::New(isolate_, item);
|
||||
if (!arrayBuffer->IsDetachable()) {
|
||||
std::string msg = "ArrayBuffer could not be transferred";
|
||||
isolate_->ThrowException(
|
||||
v8::String::NewFromUtf8(isolate_, msg.c_str(), v8::NewStringType::kNormal).ToLocalChecked());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto backingStore = arrayBuffer->GetBackingStore();
|
||||
data_->backingStores_.push_back(std::move(backingStore));
|
||||
arrayBuffer->Detach();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
v8::Isolate* isolate_ {nullptr};
|
||||
v8::ValueSerializer v8Serializer_;
|
||||
std::unique_ptr<SerializationData> data_;
|
||||
std::vector<v8::Global<v8::ArrayBuffer>> visitedTransfer_;
|
||||
std::vector<std::unique_ptr<v8::BackingStore>> backingStores_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Serializer);
|
||||
};
|
||||
|
||||
class Deserializer {
|
||||
public:
|
||||
explicit Deserializer(v8::Isolate* isolate, std::unique_ptr<SerializationData> data)
|
||||
: isolate_(isolate), v8Deserializer_(isolate, data->GetData(), data->GetSize(), nullptr), data_(std::move(data))
|
||||
{
|
||||
v8Deserializer_.SetSupportsLegacyWireFormat(true);
|
||||
}
|
||||
~Deserializer() = default;
|
||||
|
||||
v8::MaybeLocal<v8::Value> DeserializeValue()
|
||||
{
|
||||
v8::Local<v8::Context> context = isolate_->GetCurrentContext();
|
||||
bool readResult = false;
|
||||
if (!v8Deserializer_.ReadHeader(context).To(&readResult)) {
|
||||
return v8::MaybeLocal<v8::Value>();
|
||||
}
|
||||
|
||||
uint32_t index = 0;
|
||||
for (const auto& backingStore : data_->GetBackingStores()) {
|
||||
v8::Local<v8::ArrayBuffer> arrayBuffer = v8::ArrayBuffer::New(isolate_, std::move(backingStore));
|
||||
v8Deserializer_.TransferArrayBuffer(index++, arrayBuffer);
|
||||
}
|
||||
|
||||
return v8Deserializer_.ReadValue(context);
|
||||
}
|
||||
|
||||
private:
|
||||
v8::Isolate* isolate_ {nullptr};
|
||||
v8::ValueDeserializer v8Deserializer_;
|
||||
std::unique_ptr<SerializationData> data_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Deserializer);
|
||||
};
|
||||
|
||||
NativeValue* V8NativeEngine::Serialize(NativeEngine* context, NativeValue* value, NativeValue* transfer)
|
||||
{
|
||||
v8::Isolate* isolate = reinterpret_cast<V8NativeEngine*>(context)->GetIsolate();
|
||||
v8::Local<v8::Value> v8Value = *value;
|
||||
v8::Local<v8::Value> v8Transfer = *transfer;
|
||||
Serializer serializer(isolate);
|
||||
std::unique_ptr<SerializationData> data;
|
||||
if (serializer.SerializeValue(v8Value, v8Transfer)) {
|
||||
data = serializer.Release();
|
||||
}
|
||||
return reinterpret_cast<NativeValue*>(data.release());
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::Deserialize(NativeEngine* context, NativeValue* recorder)
|
||||
{
|
||||
v8::Isolate* isolate = reinterpret_cast<V8NativeEngine*>(context)->GetIsolate();
|
||||
std::unique_ptr<SerializationData> data(reinterpret_cast<SerializationData*>(recorder));
|
||||
Deserializer deserializer(isolate, std::move(data));
|
||||
v8::MaybeLocal<v8::Value> result = deserializer.DeserializeValue();
|
||||
return V8ValueToNativeValue(this, result.ToLocalChecked());
|
||||
}
|
||||
|
||||
void V8NativeEngine::DeleteSerializationData(NativeValue* value) const
|
||||
{
|
||||
SerializationData* data = reinterpret_cast<SerializationData*>(value);
|
||||
delete data;
|
||||
}
|
||||
|
||||
void V8NativeEngine::SetPackagePath(const std::string& packagePath)
|
||||
{
|
||||
auto moduleManager = NativeModuleManager::GetInstance();
|
||||
if (moduleManager) {
|
||||
moduleManager->SetAppLibPath(packagePath.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Extracts a C string from a V8 Utf8Value.
|
||||
const char* ToCString(const v8::String::Utf8Value& value)
|
||||
{
|
||||
return *value ? *value : "<string conversion failed>";
|
||||
}
|
||||
|
||||
ExceptionInfo* V8NativeEngine::GetExceptionForWorker() const
|
||||
{
|
||||
DCHECK(tryCatch_.HasCaught());
|
||||
v8::HandleScope handle_scope(isolate_);
|
||||
|
||||
ExceptionInfo* exceptionInfo = new ExceptionInfo();
|
||||
v8::String::Utf8Value exception(isolate_, tryCatch_.Exception());
|
||||
const char* exceptionString = ToCString(exception);
|
||||
char* exceptionMessage = new char[strlen(exceptionString) + 1] { 0 };
|
||||
if (memcpy_s(exceptionMessage, strlen(exceptionString) + 1, exceptionString, strlen(exceptionString)) != EOK) {
|
||||
HILOG_INFO("worker:: memcpy_s error");
|
||||
delete exceptionInfo;
|
||||
delete[] exceptionMessage;
|
||||
return nullptr;
|
||||
}
|
||||
exceptionInfo->message_ = exceptionMessage;
|
||||
|
||||
v8::Local<v8::Context> context = context_.Get(isolate_);
|
||||
v8::Context::Scope contextScope(context);
|
||||
v8::Local<v8::Message> message = tryCatch_.Message();
|
||||
if (!message.IsEmpty()) {
|
||||
int32_t lineno = message->GetLineNumber(context).FromJust();
|
||||
exceptionInfo->lineno_ = lineno;
|
||||
|
||||
int32_t colno = message->GetStartColumn(context).FromJust();
|
||||
exceptionInfo->colno_ = colno;
|
||||
}
|
||||
return exceptionInfo;
|
||||
}
|
||||
|
||||
NativeValue* V8NativeEngine::ValueToNativeValue(JSValueWrapper& value)
|
||||
{
|
||||
v8::Local<v8::Value> v8Value = value;
|
||||
return V8ValueToNativeValue(this, v8Value);
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_V8_NATIVE_ENGINE_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_V8_NATIVE_ENGINE_H
|
||||
|
||||
#include "v8_headers.h"
|
||||
|
||||
#include "native_engine/native_engine.h"
|
||||
|
||||
namespace {
|
||||
const int MB = 1024 * 1024;
|
||||
const int MAX_SERIALIZER_MEMORY_USAGE = 1 * MB;
|
||||
} // namespace
|
||||
|
||||
#define DCHECK(condition) assert(condition)
|
||||
#define DCHECK_NOT_NULL(val) DCHECK((val) != nullptr)
|
||||
|
||||
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
|
||||
TypeName(const TypeName&) = delete; \
|
||||
TypeName& operator=(const TypeName&) = delete
|
||||
|
||||
class SerializationData {
|
||||
public:
|
||||
SerializationData() : data_(nullptr), size_(0) {}
|
||||
~SerializationData() = default;
|
||||
|
||||
uint8_t* GetData() const
|
||||
{
|
||||
return data_.get();
|
||||
}
|
||||
size_t GetSize() const
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
const std::vector<std::shared_ptr<v8::BackingStore>>& GetBackingStores()
|
||||
{
|
||||
return backingStores_;
|
||||
}
|
||||
|
||||
private:
|
||||
struct DataDeleter {
|
||||
void operator()(uint8_t* p) const
|
||||
{
|
||||
free(p);
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<uint8_t, DataDeleter> data_;
|
||||
size_t size_;
|
||||
std::vector<std::shared_ptr<v8::BackingStore>> backingStores_;
|
||||
|
||||
private:
|
||||
friend class Serializer;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(SerializationData);
|
||||
};
|
||||
|
||||
class WorkerIsolateScope {
|
||||
public:
|
||||
WorkerIsolateScope() {}
|
||||
explicit WorkerIsolateScope(v8::Isolate* isolate) : isolate_(isolate) {}
|
||||
|
||||
void SetIsolate(v8::Isolate* isolate)
|
||||
{
|
||||
isolate_ = isolate;
|
||||
}
|
||||
|
||||
~WorkerIsolateScope()
|
||||
{
|
||||
if (isolate_ != nullptr) {
|
||||
isolate_->LowMemoryNotification();
|
||||
isolate_->Dispose();
|
||||
}
|
||||
}
|
||||
private:
|
||||
v8::Isolate* isolate_ { nullptr };
|
||||
};
|
||||
|
||||
class V8NativeEngine : public NativeEngine {
|
||||
public:
|
||||
// V8NativeEngine constructor
|
||||
V8NativeEngine(v8::Platform *platform, v8::Isolate* isolate, v8::Persistent<v8::Context>& context, void* jsEngine);
|
||||
// V8NativeEngine destructor
|
||||
virtual ~V8NativeEngine();
|
||||
|
||||
virtual void Loop(LoopMode mode, bool needSync = false) override;
|
||||
|
||||
v8::Isolate* GetIsolate();
|
||||
v8::Local<v8::Context> GetContext();
|
||||
void MarkAutoDispose()
|
||||
{
|
||||
workerIsolateScope_.SetIsolate(isolate_);
|
||||
}
|
||||
|
||||
// Get global native object value
|
||||
virtual NativeValue* GetGlobal() override;
|
||||
// Create native null value
|
||||
virtual NativeValue* CreateNull() override;
|
||||
// Create native undefined value
|
||||
virtual NativeValue* CreateUndefined() override;
|
||||
// Create native boolean value
|
||||
virtual NativeValue* CreateBoolean(bool value) override;
|
||||
// Create number value by int32_t
|
||||
virtual NativeValue* CreateNumber(int32_t value) override;
|
||||
// Create number value by uint32_t
|
||||
virtual NativeValue* CreateNumber(uint32_t value) override;
|
||||
// Create native number value by int64_t
|
||||
virtual NativeValue* CreateNumber(int64_t value) override;
|
||||
// Create native number value by double
|
||||
virtual NativeValue* CreateNumber(double value) override;
|
||||
// Create native string value by const char pointer
|
||||
virtual NativeValue* CreateString(const char* value, size_t length) override;
|
||||
// Create native symbol value
|
||||
virtual NativeValue* CreateSymbol(NativeValue* value) override;
|
||||
// Create native value of external pointer
|
||||
virtual NativeValue* CreateExternal(void* value, NativeFinalize callback, void* hint) override;
|
||||
// Create native object value
|
||||
virtual NativeValue* CreateObject() override;
|
||||
// Create native function value
|
||||
virtual NativeValue* CreateFunction(const char* name, size_t length, NativeCallback cb, void* value) override;
|
||||
// Create native array value
|
||||
virtual NativeValue* CreateArray(size_t length) override;
|
||||
// Create native array buffer value
|
||||
virtual NativeValue* CreateArrayBuffer(void** value, size_t length) override;
|
||||
// Create native array buffer value of external
|
||||
virtual NativeValue* CreateArrayBufferExternal(void* value, size_t length, NativeFinalize cb, void* hint) override;
|
||||
// Create native typed array value
|
||||
virtual NativeValue* CreateTypedArray(NativeTypedArrayType type,
|
||||
NativeValue* value,
|
||||
size_t length,
|
||||
size_t offset) override;
|
||||
// Create native data view value
|
||||
virtual NativeValue* CreateDataView(NativeValue* value, size_t length, size_t offset) override;
|
||||
// Create native promise value
|
||||
virtual NativeValue* CreatePromise(NativeDeferred** deferred) override;
|
||||
// Create native error value
|
||||
virtual NativeValue* CreateError(NativeValue* code, NativeValue* message) override;
|
||||
// Call function
|
||||
virtual NativeValue* CallFunction(NativeValue* thisVar,
|
||||
NativeValue* function,
|
||||
NativeValue* const* argv,
|
||||
size_t argc) override;
|
||||
// Run script
|
||||
virtual NativeValue* RunScript(NativeValue* script) override;
|
||||
// Run buffer script
|
||||
virtual NativeValue* RunBufferScript(std::vector<uint8_t>& buffer) override;
|
||||
// Define native class
|
||||
virtual NativeValue* DefineClass(const char* name,
|
||||
NativeCallback callback,
|
||||
void* data,
|
||||
const NativePropertyDescriptor* properties,
|
||||
size_t length) override;
|
||||
// Create instance by defined class
|
||||
virtual NativeValue* CreateInstance(NativeValue* constructor, NativeValue* const* argv, size_t argc) override;
|
||||
|
||||
// Create native reference
|
||||
virtual NativeReference* CreateReference(NativeValue* value, uint32_t initialRefcount) override;
|
||||
// Throw exception
|
||||
virtual bool Throw(NativeValue* error) override;
|
||||
// Throw exception
|
||||
virtual bool Throw(NativeErrorType type, const char* code, const char* message) override;
|
||||
|
||||
virtual void* CreateRuntime() override;
|
||||
virtual NativeValue* Serialize(NativeEngine* context, NativeValue* value, NativeValue* transfer) override;
|
||||
virtual NativeValue* Deserialize(NativeEngine* context, NativeValue* recorder) override;
|
||||
virtual ExceptionInfo* GetExceptionForWorker() const override;
|
||||
virtual void DeleteSerializationData(NativeValue* value) const override;
|
||||
void SetPackagePath(const std::string& packagePath);
|
||||
|
||||
static NativeValue* V8ValueToNativeValue(V8NativeEngine* engine, v8::Local<v8::Value> value);
|
||||
virtual NativeValue* LoadModule(NativeValue* str, const std::string& fileName) override;
|
||||
virtual NativeValue* ValueToNativeValue(JSValueWrapper& value) override;
|
||||
|
||||
v8::Local<v8::Object> GetModuleFromName(
|
||||
const std::string& moduleName, bool isAppModule, const std::string& id, const std::string& param,
|
||||
const std::string& instanceName, void** instance);
|
||||
|
||||
private:
|
||||
v8::Platform* platform_;
|
||||
v8::Isolate* isolate_;
|
||||
WorkerIsolateScope workerIsolateScope_;
|
||||
v8::Global<v8::Context> context_;
|
||||
v8::Isolate::Scope isolateScope_;
|
||||
v8::HandleScope handleScope_;
|
||||
v8::Context::Scope contextScope_;
|
||||
v8::TryCatch tryCatch_ { NULL };
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_V8_NATIVE_ENGINE_H */
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "v8_native_engine.h"
|
||||
|
||||
#include "v8_native_reference.h"
|
||||
|
||||
V8NativeReference::V8NativeReference(V8NativeEngine* engine,
|
||||
NativeValue* value,
|
||||
uint32_t initialRefcount,
|
||||
bool deleteSelf,
|
||||
NativeFinalize callback,
|
||||
void* data,
|
||||
void* hint)
|
||||
: engine_(engine),
|
||||
value_(),
|
||||
refCount_(initialRefcount),
|
||||
deleteSelf_(deleteSelf),
|
||||
callback_(callback),
|
||||
data_(data),
|
||||
hint_(hint)
|
||||
{
|
||||
deleteSelf_ = false;
|
||||
v8::Local<v8::Value> v8Value = *value;
|
||||
value_.Reset(engine->GetIsolate(), v8Value);
|
||||
if (initialRefcount == 0) {
|
||||
value_.SetWeak(this, FinalizeCallback, v8::WeakCallbackType::kParameter);
|
||||
}
|
||||
}
|
||||
|
||||
V8NativeReference::~V8NativeReference()
|
||||
{
|
||||
if (callback_) {
|
||||
callback_(engine_, data_, hint_);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t V8NativeReference::Ref()
|
||||
{
|
||||
++refCount_;
|
||||
if (refCount_ == 1) {
|
||||
value_.ClearWeak();
|
||||
}
|
||||
return refCount_;
|
||||
}
|
||||
|
||||
uint32_t V8NativeReference::Unref()
|
||||
{
|
||||
--refCount_;
|
||||
uint32_t refCount = refCount_;
|
||||
if (refCount == 0) {
|
||||
value_.SetWeak(this, FinalizeCallback, v8::WeakCallbackType::kParameter);
|
||||
}
|
||||
return refCount;
|
||||
}
|
||||
|
||||
NativeValue* V8NativeReference::Get()
|
||||
{
|
||||
v8::Local<v8::Value> value = value_.Get(engine_->GetIsolate());
|
||||
return V8NativeEngine::V8ValueToNativeValue(engine_, value);
|
||||
}
|
||||
|
||||
V8NativeReference::operator NativeValue*()
|
||||
{
|
||||
return Get();
|
||||
}
|
||||
|
||||
void V8NativeReference::FinalizeCallback(const v8::WeakCallbackInfo<V8NativeReference>& data)
|
||||
{
|
||||
V8NativeReference* that = data.GetParameter();
|
||||
that->value_.Reset();
|
||||
data.SetSecondPassCallback(SecondPassCallback);
|
||||
}
|
||||
|
||||
void V8NativeReference::SecondPassCallback(const v8::WeakCallbackInfo<V8NativeReference>& data)
|
||||
{
|
||||
V8NativeReference* that = data.GetParameter();
|
||||
that->callback_(that->engine_, that->data_, that->hint_);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_V8_NATIVE_REFERENCE_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_V8_NATIVE_REFERENCE_H
|
||||
|
||||
#include "native_engine/native_value.h"
|
||||
|
||||
#include "native_engine/native_reference.h"
|
||||
|
||||
class V8NativeEngine;
|
||||
|
||||
class V8NativeReference : public NativeReference {
|
||||
public:
|
||||
V8NativeReference(V8NativeEngine* engine,
|
||||
NativeValue* value,
|
||||
uint32_t initialRefcount,
|
||||
bool deleteSelf,
|
||||
NativeFinalize callback = nullptr,
|
||||
void* data = nullptr,
|
||||
void* hint = nullptr);
|
||||
virtual ~V8NativeReference();
|
||||
|
||||
virtual uint32_t Ref() override;
|
||||
virtual uint32_t Unref() override;
|
||||
virtual NativeValue* Get() override;
|
||||
virtual operator NativeValue*() override;
|
||||
|
||||
private:
|
||||
static void FinalizeCallback(const v8::WeakCallbackInfo<V8NativeReference> &data);
|
||||
static void SecondPassCallback(const v8::WeakCallbackInfo<V8NativeReference> &data);
|
||||
|
||||
V8NativeEngine* engine_;
|
||||
v8::Global<v8::Value> value_;
|
||||
uint32_t refCount_;
|
||||
bool deleteSelf_;
|
||||
NativeFinalize callback_;
|
||||
void *data_;
|
||||
void *hint_;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_V8_NATIVE_REFERENCE_H */
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
#include "native_engine/native_property.h"
|
||||
#include "native_engine/native_value.h"
|
||||
|
||||
#include "securec.h"
|
||||
#include "utils/log.h"
|
||||
|
||||
NAPI_EXTERN napi_status napi_get_last_error_info(napi_env env, const napi_extended_error_info** result)
|
||||
@@ -798,7 +798,7 @@ NAPI_EXTERN napi_status napi_strict_equals(napi_env env, napi_value lhs, napi_va
|
||||
auto nativeLhs = reinterpret_cast<NativeValue*>(lhs);
|
||||
auto nativeRhs = reinterpret_cast<NativeValue*>(rhs);
|
||||
|
||||
*result = *nativeLhs == nativeRhs;
|
||||
*result = nativeLhs->StrictEquals(nativeRhs);
|
||||
return napi_clear_last_error(env);
|
||||
}
|
||||
|
||||
@@ -1240,7 +1240,7 @@ NAPI_EXTERN napi_status napi_throw(napi_env env, napi_value error)
|
||||
RETURN_STATUS_IF_FALSE(env, nativeValue->IsError(), napi_invalid_arg);
|
||||
|
||||
engine->Throw(nativeValue);
|
||||
return napi_generic_failure;
|
||||
return napi_clear_last_error(env);
|
||||
}
|
||||
|
||||
NAPI_EXTERN napi_status napi_throw_error(napi_env env, const char* code, const char* msg)
|
||||
@@ -1251,7 +1251,7 @@ NAPI_EXTERN napi_status napi_throw_error(napi_env env, const char* code, const c
|
||||
auto engine = reinterpret_cast<NativeEngine*>(env);
|
||||
|
||||
engine->Throw(NativeErrorType::NATIVE_COMMON_ERROR, code, msg);
|
||||
return napi_generic_failure;
|
||||
return napi_clear_last_error(env);
|
||||
}
|
||||
|
||||
NAPI_EXTERN napi_status napi_throw_type_error(napi_env env, const char* code, const char* msg)
|
||||
@@ -1578,11 +1578,20 @@ NAPI_EXTERN napi_status napi_run_script(napi_env env, napi_value script, napi_va
|
||||
|
||||
auto engine = reinterpret_cast<NativeEngine*>(env);
|
||||
auto scriptValue = reinterpret_cast<NativeValue*>(script);
|
||||
|
||||
RETURN_STATUS_IF_FALSE(env, scriptValue->TypeOf() == NATIVE_STRING, napi_status::napi_string_expected);
|
||||
|
||||
auto resultValue = engine->RunScript(scriptValue);
|
||||
*result = reinterpret_cast<napi_value>(resultValue);
|
||||
return napi_clear_last_error(env);
|
||||
}
|
||||
|
||||
// Runnint a buffer script, only used in ark
|
||||
NAPI_EXTERN napi_status napi_run_buffer_script(napi_env env, std::vector<uint8_t>& buffer, napi_value* result)
|
||||
{
|
||||
CHECK_ENV(env);
|
||||
CHECK_ARG(env, result);
|
||||
|
||||
auto engine = reinterpret_cast<NativeEngine*>(env);
|
||||
auto resultValue = engine->RunBufferScript(buffer);
|
||||
*result = reinterpret_cast<napi_value>(resultValue);
|
||||
return napi_clear_last_error(env);
|
||||
}
|
||||
@@ -1603,8 +1612,8 @@ NAPI_EXTERN napi_status napi_is_callable(napi_env env, napi_value value, bool* r
|
||||
CHECK_ARG(env, result);
|
||||
|
||||
auto nativeValue = reinterpret_cast<NativeValue*>(value);
|
||||
*result = nativeValue->IsCallable();
|
||||
|
||||
*result = nativeValue->IsCallable();
|
||||
return napi_clear_last_error(env);
|
||||
}
|
||||
|
||||
@@ -1660,7 +1669,6 @@ NAPI_EXTERN napi_status napi_delete_serialization_data(napi_env env, napi_value
|
||||
|
||||
auto engine = reinterpret_cast<NativeEngine*>(env);
|
||||
auto nativeValue = reinterpret_cast<NativeValue*>(value);
|
||||
|
||||
engine->DeleteSerializationData(nativeValue);
|
||||
|
||||
return napi_clear_last_error(env);
|
||||
@@ -1670,7 +1678,6 @@ NAPI_EXTERN napi_status napi_get_exception_info_for_worker(napi_env env, napi_va
|
||||
{
|
||||
CHECK_ENV(env);
|
||||
CHECK_ARG(env, obj);
|
||||
|
||||
auto engine = reinterpret_cast<NativeEngine*>(env);
|
||||
ExceptionInfo* exceptionInfo = engine->GetExceptionForWorker();
|
||||
if (exceptionInfo == nullptr) {
|
||||
@@ -1683,7 +1690,7 @@ NAPI_EXTERN napi_status napi_get_exception_info_for_worker(napi_env env, napi_va
|
||||
napi_set_named_property(env, obj, "lineno", lineno);
|
||||
|
||||
napi_value colno = nullptr;
|
||||
napi_create_int32(env, exceptionInfo->colno_, &lineno);
|
||||
napi_create_int32(env, exceptionInfo->colno_, &colno);
|
||||
napi_set_named_property(env, obj, "colno", colno);
|
||||
|
||||
if (exceptionInfo->message_ != nullptr) {
|
||||
@@ -1695,4 +1702,13 @@ NAPI_EXTERN napi_status napi_get_exception_info_for_worker(napi_env env, napi_va
|
||||
|
||||
delete exceptionInfo;
|
||||
return napi_clear_last_error(env);
|
||||
}
|
||||
|
||||
napi_status napi_get_jsEngine(napi_env env, void** pEngine)
|
||||
{
|
||||
CHECK_ENV(env);
|
||||
auto engine = reinterpret_cast<NativeEngine*>(env);
|
||||
*pEngine = engine->GetJsEngine();
|
||||
return napi_clear_last_error(env);
|
||||
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "native_async_work.h"
|
||||
|
||||
#include "napi/native_api.h"
|
||||
#include "native_engine.h"
|
||||
#include "utils/log.h"
|
||||
|
||||
@@ -22,14 +23,9 @@ NativeAsyncWork::NativeAsyncWork(NativeEngine* engine,
|
||||
NativeAsyncExecuteCallback execute,
|
||||
NativeAsyncCompleteCallback complete,
|
||||
void* data)
|
||||
: work_({ 0 }), engine_(engine), execute_(execute), complete_(complete), data_(data)
|
||||
{
|
||||
work_ = { 0 };
|
||||
work_.data = this;
|
||||
engine_ = engine;
|
||||
status_ = 0;
|
||||
execute_ = execute;
|
||||
complete_ = complete;
|
||||
data_ = data;
|
||||
}
|
||||
|
||||
NativeAsyncWork::~NativeAsyncWork() {}
|
||||
@@ -139,6 +135,22 @@ void NativeAsyncWork::AsyncAfterWorkCallback(uv_work_t* req, int status)
|
||||
return;
|
||||
}
|
||||
|
||||
that->complete_(that->engine_, status, that->data_);
|
||||
napi_status nstatus = napi_generic_failure;
|
||||
|
||||
switch (status) {
|
||||
case 0:
|
||||
nstatus = napi_ok;
|
||||
break;
|
||||
case (int)UV_EINVAL:
|
||||
nstatus = napi_invalid_arg;
|
||||
break;
|
||||
case (int)UV_ECANCELED:
|
||||
nstatus = napi_cancelled;
|
||||
break;
|
||||
default:
|
||||
nstatus = napi_generic_failure;
|
||||
}
|
||||
|
||||
that->complete_(that->engine_, nstatus, that->data_);
|
||||
scopeManager->Close(scope);
|
||||
}
|
||||
|
||||
@@ -68,8 +68,6 @@ private:
|
||||
uv_work_t work_;
|
||||
uv_async_t workAsyncHandler_;
|
||||
NativeEngine* engine_;
|
||||
|
||||
int status_;
|
||||
NativeAsyncExecuteCallback execute_;
|
||||
NativeAsyncCompleteCallback complete_;
|
||||
void* data_;
|
||||
|
||||
@@ -14,10 +14,12 @@
|
||||
*/
|
||||
|
||||
#include "native_engine.h"
|
||||
#include "utils/log.h"
|
||||
|
||||
#include <sys/epoll.h>
|
||||
#include <uv.h>
|
||||
|
||||
#include "utils/log.h"
|
||||
|
||||
namespace {
|
||||
const char* g_errorMessages[] = {
|
||||
nullptr,
|
||||
@@ -44,22 +46,31 @@ const char* g_errorMessages[] = {
|
||||
};
|
||||
} // namespace
|
||||
|
||||
NativeEngine::NativeEngine()
|
||||
NativeEngine::NativeEngine(void* jsEngine) : jsEngine_(jsEngine)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
void NativeEngine::Init()
|
||||
{
|
||||
moduleManager_ = NativeModuleManager::GetInstance();
|
||||
scopeManager_ = new NativeScopeManager();
|
||||
if (scopeManager_) {
|
||||
loop_ = uv_loop_new();
|
||||
lastException_ = nullptr;
|
||||
} else {
|
||||
HILOG_ERROR("contruct NativeEngine error.");
|
||||
loop_ = uv_loop_new();
|
||||
if (loop_ == nullptr) {
|
||||
return;
|
||||
}
|
||||
uv_async_init(loop_, &uvAsync_, nullptr);
|
||||
uv_sem_init(&uvSem_, 0);
|
||||
lastException_ = nullptr;
|
||||
}
|
||||
|
||||
NativeEngine::~NativeEngine()
|
||||
{
|
||||
uv_close((uv_handle_t*)&uvAsync_, nullptr);
|
||||
uv_loop_close(loop_);
|
||||
delete scopeManager_;
|
||||
if (scopeManager_ != nullptr) {
|
||||
delete scopeManager_;
|
||||
}
|
||||
}
|
||||
|
||||
NativeScopeManager* NativeEngine::GetScopeManager()
|
||||
@@ -77,7 +88,7 @@ uv_loop_t* NativeEngine::GetUVLoop() const
|
||||
return loop_;
|
||||
}
|
||||
|
||||
void NativeEngine::Loop(LoopMode mode)
|
||||
void NativeEngine::Loop(LoopMode mode, bool needSync)
|
||||
{
|
||||
bool more = true;
|
||||
switch (mode) {
|
||||
@@ -96,13 +107,14 @@ void NativeEngine::Loop(LoopMode mode)
|
||||
if (more == false) {
|
||||
more = uv_loop_alive(loop_);
|
||||
}
|
||||
|
||||
if (needSync) {
|
||||
uv_sem_post(&uvSem_);
|
||||
}
|
||||
}
|
||||
|
||||
NativeAsyncWork* NativeEngine::CreateAsyncWork(NativeValue* asyncResource,
|
||||
NativeValue* asyncResourceName,
|
||||
NativeAsyncExecuteCallback execute,
|
||||
NativeAsyncCompleteCallback complete,
|
||||
void* data)
|
||||
NativeAsyncWork* NativeEngine::CreateAsyncWork(NativeValue* asyncResource, NativeValue* asyncResourceName,
|
||||
NativeAsyncExecuteCallback execute, NativeAsyncCompleteCallback complete, void* data)
|
||||
{
|
||||
(void)asyncResource;
|
||||
(void)asyncResourceName;
|
||||
@@ -162,12 +174,54 @@ void NativeEngine::EncodeToUtf8(NativeValue* nativeValue,
|
||||
|
||||
auto nativeString = reinterpret_cast<NativeString*>(nativeValue->GetInterface(NativeString::INTERFACE_ID));
|
||||
|
||||
if (nativeString) {
|
||||
*written = nativeString->EncodeWriteUtf8(buffer, bufferSize, nchars);
|
||||
} else {
|
||||
HILOG_ERROR("NativeEngine EncodeToUtf8 nativeString is nullptr");
|
||||
if (nativeString == nullptr) {
|
||||
HILOG_ERROR("nativeValue GetInterface is nullptr");
|
||||
return;
|
||||
}
|
||||
*written = nativeString->EncodeWriteUtf8(buffer, bufferSize, nchars);
|
||||
}
|
||||
|
||||
void NativeEngine::CheckUVLoop()
|
||||
{
|
||||
checkUVLoop_ = true;
|
||||
uv_thread_create(&uvThread_, NativeEngine::UVThreadRunner, this);
|
||||
}
|
||||
|
||||
void NativeEngine::CancelCheckUVLoop()
|
||||
{
|
||||
checkUVLoop_ = false;
|
||||
|
||||
uv_async_send(&uvAsync_);
|
||||
uv_thread_join(&uvThread_);
|
||||
}
|
||||
|
||||
void NativeEngine::PostLoopTask()
|
||||
{
|
||||
postTask_(true);
|
||||
uv_sem_wait(&uvSem_);
|
||||
}
|
||||
|
||||
void NativeEngine::UVThreadRunner(void* nativeEngine)
|
||||
{
|
||||
auto engine = static_cast<NativeEngine *>(nativeEngine);
|
||||
engine->PostLoopTask();
|
||||
while (engine->checkUVLoop_) {
|
||||
int32_t fd = uv_backend_fd(engine->loop_);
|
||||
int32_t timeout = uv_backend_timeout(engine->loop_);
|
||||
struct epoll_event ev;
|
||||
int32_t result = epoll_wait(fd, &ev, 1, timeout);
|
||||
if (!engine->checkUVLoop_) {
|
||||
HILOG_INFO("break thread");
|
||||
break;
|
||||
}
|
||||
if (result != -1 && errno != EINTR) {
|
||||
engine->PostLoopTask();
|
||||
} else {
|
||||
HILOG_ERROR("epoll wait fail");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NativeEngine::SetPostTask(PostTask postTask)
|
||||
{
|
||||
HILOG_INFO("SetPostTask in");
|
||||
@@ -180,5 +234,10 @@ void NativeEngine::TriggerPostTask()
|
||||
HILOG_ERROR("postTask_ is nullptr");
|
||||
return;
|
||||
}
|
||||
postTask_();
|
||||
postTask_(false);
|
||||
}
|
||||
|
||||
void* NativeEngine::GetJsEngine()
|
||||
{
|
||||
return jsEngine_;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_NATIVE_ENGINE_H
|
||||
#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_NATIVE_ENGINE_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "native_engine/native_async_work.h"
|
||||
#include "native_engine/native_deferred.h"
|
||||
#include "native_engine/native_reference.h"
|
||||
@@ -24,7 +26,6 @@
|
||||
|
||||
#include "module_manager/native_module_manager.h"
|
||||
#include "scope_manager/native_scope_manager.h"
|
||||
#include <string>
|
||||
|
||||
typedef struct uv_loop_s uv_loop_t;
|
||||
|
||||
@@ -52,20 +53,23 @@ enum LoopMode {
|
||||
LOOP_DEFAULT, LOOP_ONCE, LOOP_NOWAIT
|
||||
};
|
||||
|
||||
using PostTask = std::function<void()>;
|
||||
using PostTask = std::function<void(bool needSync)>;
|
||||
|
||||
class NativeEngine {
|
||||
public:
|
||||
NativeEngine();
|
||||
NativeEngine(void *jsEngine);
|
||||
virtual ~NativeEngine();
|
||||
|
||||
virtual NativeScopeManager* GetScopeManager();
|
||||
virtual NativeModuleManager* GetModuleManager();
|
||||
virtual uv_loop_t* GetUVLoop() const;
|
||||
|
||||
virtual void Loop(LoopMode mode);
|
||||
virtual void Loop(LoopMode mode, bool needSync = false);
|
||||
virtual void SetPostTask(PostTask postTask);
|
||||
virtual void TriggerPostTask();
|
||||
virtual void CheckUVLoop();
|
||||
virtual void CancelCheckUVLoop();
|
||||
virtual void* GetJsEngine();
|
||||
|
||||
virtual NativeValue* GetGlobal() = 0;
|
||||
|
||||
@@ -101,6 +105,7 @@ public:
|
||||
NativeValue* const* argv,
|
||||
size_t argc) = 0;
|
||||
virtual NativeValue* RunScript(NativeValue* script) = 0;
|
||||
virtual NativeValue* RunBufferScript(std::vector<uint8_t>& buffer) = 0;
|
||||
virtual NativeValue* DefineClass(const char* name,
|
||||
NativeCallback callback,
|
||||
void* data,
|
||||
@@ -129,15 +134,18 @@ public:
|
||||
virtual NativeValue* Deserialize(NativeEngine* context, NativeValue* recorder) = 0;
|
||||
virtual ExceptionInfo* GetExceptionForWorker() const = 0;
|
||||
virtual void DeleteSerializationData(NativeValue* value) const = 0;
|
||||
|
||||
virtual NativeValue* LoadModule(NativeValue* str, const std::string& fileName) = 0;
|
||||
void EncodeToUtf8(NativeValue* nativeValue, char* buffer, int32_t* written, size_t bufferSize, int32_t* nchars);
|
||||
|
||||
NativeErrorExtendedInfo* GetLastError();
|
||||
void SetLastError(int errorCode, uint32_t engineErrorCode = 0, void* engineReserved = nullptr);
|
||||
void ClearLastError();
|
||||
bool IsExceptionPending() const;
|
||||
NativeValue* GetAndClearLastException();
|
||||
void EncodeToUtf8(NativeValue* nativeValue, char* buffer, int32_t* written, size_t bufferSize, int32_t* nchars);
|
||||
NativeEngine(NativeEngine&) = delete;
|
||||
virtual NativeEngine& operator=(NativeEngine&) = delete;
|
||||
|
||||
virtual NativeValue* ValueToNativeValue(JSValueWrapper& value) = 0;
|
||||
|
||||
void MarkSubThread()
|
||||
{
|
||||
@@ -149,19 +157,29 @@ public:
|
||||
return isMainThread_;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
NativeModuleManager* moduleManager_ { nullptr };
|
||||
NativeScopeManager* scopeManager_ { nullptr };
|
||||
NativeModuleManager* moduleManager_ = nullptr;
|
||||
NativeScopeManager* scopeManager_ = nullptr;
|
||||
|
||||
NativeErrorExtendedInfo lastError_;
|
||||
NativeValue* lastException_ { nullptr };
|
||||
NativeValue* lastException_ = nullptr;
|
||||
|
||||
uv_loop_t* loop_;
|
||||
|
||||
void *jsEngine_;
|
||||
|
||||
private:
|
||||
bool isMainThread_ { true };
|
||||
PostTask postTask_ { nullptr };
|
||||
static void UVThreadRunner(void* nativeEngine);
|
||||
|
||||
void Init();
|
||||
void PostLoopTask();
|
||||
|
||||
bool checkUVLoop_ = false;
|
||||
PostTask postTask_ = nullptr;
|
||||
uv_thread_t uvThread_;
|
||||
uv_sem_t uvSem_;
|
||||
uv_async_t uvAsync_;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_NATIVE_ENGINE_H */
|
||||
|
||||
@@ -32,6 +32,7 @@ typedef void (*NativeAsyncExecuteCallback)(NativeEngine* engine, void* data);
|
||||
typedef void (*NativeAsyncCompleteCallback)(NativeEngine* engine, int status, void* data);
|
||||
|
||||
struct NativeObjectInfo {
|
||||
static NativeObjectInfo* CreateNewInstance() { return new NativeObjectInfo(); }
|
||||
NativeEngine* engine = nullptr;
|
||||
void* nativeObject = nullptr;
|
||||
NativeFinalize callback = nullptr;
|
||||
@@ -39,6 +40,7 @@ struct NativeObjectInfo {
|
||||
};
|
||||
|
||||
struct NativeFunctionInfo {
|
||||
static NativeFunctionInfo* CreateNewInstance() { return new NativeFunctionInfo(); }
|
||||
NativeEngine* engine = nullptr;
|
||||
NativeCallback callback = nullptr;
|
||||
void* data = nullptr;
|
||||
@@ -67,6 +69,34 @@ enum NativeValueType {
|
||||
NATIVE_BIGINT,
|
||||
};
|
||||
|
||||
struct JSValueWrapper {
|
||||
JSValueWrapper()
|
||||
{
|
||||
u.ptr = 0;
|
||||
tag = 0;
|
||||
}
|
||||
template<typename T>
|
||||
JSValueWrapper(T value)
|
||||
{
|
||||
*(T*)this = value;
|
||||
}
|
||||
template<typename T> operator T()
|
||||
{
|
||||
return *(T*)this;
|
||||
}
|
||||
template<typename T> JSValueWrapper& operator=(T value)
|
||||
{
|
||||
*(T*)this = value;
|
||||
return *this;
|
||||
}
|
||||
union {
|
||||
int32_t int32;
|
||||
double float64;
|
||||
void* ptr;
|
||||
} u;
|
||||
int64_t tag;
|
||||
};
|
||||
|
||||
class NativeValue {
|
||||
public:
|
||||
virtual ~NativeValue() {}
|
||||
@@ -101,26 +131,10 @@ public:
|
||||
virtual NativeValue* ToString() = 0;
|
||||
virtual NativeValue* ToObject() = 0;
|
||||
|
||||
virtual bool operator==(NativeValue* value) = 0;
|
||||
virtual bool StrictEquals(NativeValue* value) = 0;
|
||||
|
||||
protected:
|
||||
struct {
|
||||
template<typename T> operator T()
|
||||
{
|
||||
return *(T*)this;
|
||||
}
|
||||
template<typename T> T operator=(T value)
|
||||
{
|
||||
*(T*)this = value;
|
||||
return *this;
|
||||
}
|
||||
union {
|
||||
int32_t int32;
|
||||
double float64;
|
||||
void* ptr;
|
||||
} u;
|
||||
int64_t tag;
|
||||
} value_;
|
||||
JSValueWrapper value_;
|
||||
};
|
||||
|
||||
class NativeBoolean {
|
||||
|
||||
+11
@@ -10,6 +10,17 @@
|
||||
"//foundation/ace/napi:napi_packages"
|
||||
],
|
||||
"inner_kits": [
|
||||
{
|
||||
"header": {
|
||||
"header_base": "//foundation/ace/napi/interfaces/kits",
|
||||
"header_files": [
|
||||
"napi/native_api.h",
|
||||
"napi/native_common.h",
|
||||
"napi/native_node_api.h"
|
||||
]
|
||||
},
|
||||
"name": "//foundation/ace/napi:ace_napi"
|
||||
}
|
||||
],
|
||||
"test_list": [
|
||||
"//foundation/ace/napi:napi_packages_test",
|
||||
|
||||
@@ -30,10 +30,8 @@ struct EventListener {
|
||||
};
|
||||
|
||||
EventTarget::EventTarget(napi_env env, napi_value thisVar)
|
||||
: env_(env), thisVarRef_(nullptr), first_(nullptr), last_(nullptr)
|
||||
{
|
||||
env_ = env;
|
||||
first_ = last_ = nullptr;
|
||||
thisVarRef_ = nullptr;
|
||||
napi_create_reference(env, thisVar, 1, &thisVarRef_);
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ void NetServer::OnClose(uv_handle_t* peer)
|
||||
return;
|
||||
}
|
||||
|
||||
NetServer* that = (NetServer*)peer->data;
|
||||
NetServer* that = static_cast<NetServer*>(peer->data);
|
||||
that->Emit("disconnect", nullptr);
|
||||
free(peer);
|
||||
}
|
||||
@@ -89,7 +89,7 @@ void NetServer::OnConnection(uv_stream_t* server, int status)
|
||||
return;
|
||||
}
|
||||
|
||||
NetServer* that = (NetServer*)server->data;
|
||||
NetServer* that = static_cast<NetServer*>(server->data);
|
||||
|
||||
if (status != 0) {
|
||||
that->Emit("error", nullptr);
|
||||
@@ -118,7 +118,7 @@ void NetServer::OnServerClose(uv_handle_t* handle)
|
||||
return;
|
||||
}
|
||||
|
||||
NetServer* that = (NetServer*)handle->data;
|
||||
NetServer* that = static_cast<NetServer*>(handle->data);
|
||||
|
||||
for (NetClient* i = that->clients_; i != nullptr; i = i->next) {
|
||||
uv_close((uv_handle_t*)&i->tcp, nullptr);
|
||||
@@ -135,9 +135,9 @@ void NetServer::AfterWrite(uv_write_t* req, int status)
|
||||
return;
|
||||
}
|
||||
|
||||
NetServer* that = (NetServer*)req->data;
|
||||
NetServer* that = static_cast<NetServer*>(req->data);
|
||||
|
||||
WriteReq* wr = (WriteReq*)req;
|
||||
WriteReq* wr = reinterpret_cast<WriteReq*>(req);
|
||||
|
||||
free(wr->buf.base);
|
||||
free(wr);
|
||||
@@ -162,7 +162,7 @@ void NetServer::AfterRead(uv_stream_t* handle, ssize_t nread, const uv_buf_t* bu
|
||||
return;
|
||||
}
|
||||
|
||||
NetServer* that = (NetServer*)handle->data;
|
||||
NetServer* that = static_cast<NetServer*>(handle->data);
|
||||
WriteReq* wr = nullptr;
|
||||
uv_shutdown_t* sreq = nullptr;
|
||||
|
||||
@@ -201,7 +201,7 @@ void NetServer::AfterRead(uv_stream_t* handle, ssize_t nread, const uv_buf_t* bu
|
||||
|
||||
that->Emit("read", nullptr);
|
||||
|
||||
wr = (WriteReq*)malloc(sizeof(WriteReq));
|
||||
wr = static_cast<WriteReq*>(malloc(sizeof(WriteReq)));
|
||||
if (wr == nullptr) {
|
||||
HILOG_ERROR("wr is null");
|
||||
free(buf->base);
|
||||
|
||||
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "netserver.h"
|
||||
|
||||
#include "utils/log.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
NetServer::NetServer(napi_env env, napi_value thisVar) : EventTarget(env, thisVar)
|
||||
{
|
||||
napi_get_uv_event_loop(env, &loop_);
|
||||
tcpServer_ = { 0 };
|
||||
tcpServer_.data = this;
|
||||
serverClosed_ = false;
|
||||
clients_ = nullptr;
|
||||
}
|
||||
|
||||
NetServer::~NetServer() {}
|
||||
|
||||
int NetServer::Start(int port)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
int result = 0;
|
||||
|
||||
uv_ip4_addr("0.0.0.0", port, &addr);
|
||||
|
||||
result = uv_tcp_init(loop_, &tcpServer_);
|
||||
if (result) {
|
||||
this->Emit("error", nullptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = uv_tcp_bind(&tcpServer_, (const struct sockaddr*)&addr, 0);
|
||||
if (result) {
|
||||
this->Emit("error", nullptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = uv_listen((uv_stream_t*)&tcpServer_, SOMAXCONN, OnConnection);
|
||||
if (result) {
|
||||
this->Emit("error", nullptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Emit("started", nullptr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NetServer::Stop()
|
||||
{
|
||||
Emit("closed", nullptr);
|
||||
uint32_t thisRefCount = 0;
|
||||
napi_reference_unref(env_, thisVarRef_, &thisRefCount);
|
||||
}
|
||||
|
||||
void NetServer::OnClose(uv_handle_t* peer)
|
||||
{
|
||||
if (peer == nullptr) {
|
||||
HILOG_ERROR("peer is null");
|
||||
return;
|
||||
}
|
||||
|
||||
NetServer* that = (NetServer*)peer->data;
|
||||
that->Emit("disconnect", nullptr);
|
||||
free(peer);
|
||||
}
|
||||
|
||||
void NetServer::OnConnection(uv_stream_t* server, int status)
|
||||
{
|
||||
if (server == nullptr) {
|
||||
HILOG_ERROR("server is null");
|
||||
return;
|
||||
}
|
||||
|
||||
NetServer* that = (NetServer*)server->data;
|
||||
|
||||
if (status != 0) {
|
||||
that->Emit("error", nullptr);
|
||||
}
|
||||
|
||||
if (that->clients_ == nullptr) {
|
||||
that->clients_ = new NetClient();
|
||||
} else {
|
||||
auto tmp = new NetClient();
|
||||
tmp->next = that->clients_;
|
||||
that->clients_ = tmp;
|
||||
}
|
||||
|
||||
uv_tcp_init(that->loop_, (uv_tcp_t*)&that->clients_->tcp);
|
||||
that->clients_->tcp.data = server->data;
|
||||
uv_accept(server, (uv_stream_t*)&that->clients_->tcp);
|
||||
uv_read_start((uv_stream_t*)&that->clients_->tcp, EchoAlloc, AfterRead);
|
||||
|
||||
that->Emit("connect", nullptr);
|
||||
}
|
||||
|
||||
void NetServer::OnServerClose(uv_handle_t* handle)
|
||||
{
|
||||
if (handle == nullptr) {
|
||||
HILOG_ERROR("handle is null");
|
||||
return;
|
||||
}
|
||||
|
||||
NetServer* that = (NetServer*)handle->data;
|
||||
|
||||
for (NetClient* i = that->clients_; i != nullptr; i = i->next) {
|
||||
uv_close((uv_handle_t*)&i->tcp, nullptr);
|
||||
}
|
||||
|
||||
uint32_t thisRefCount = 0;
|
||||
napi_reference_unref(that->env_, that->thisVarRef_, &thisRefCount);
|
||||
}
|
||||
|
||||
void NetServer::AfterWrite(uv_write_t* req, int status)
|
||||
{
|
||||
if (req == nullptr) {
|
||||
HILOG_ERROR("req is null");
|
||||
return;
|
||||
}
|
||||
|
||||
NetServer* that = (NetServer*)req->data;
|
||||
|
||||
WriteReq* wr = (WriteReq*)req;
|
||||
|
||||
free(wr->buf.base);
|
||||
free(wr);
|
||||
|
||||
if (status == 0) {
|
||||
that->Emit("write", nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
that->Emit("error", nullptr);
|
||||
}
|
||||
|
||||
void NetServer::AfterRead(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf)
|
||||
{
|
||||
if (handle == nullptr) {
|
||||
HILOG_ERROR("handle is null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (buf == nullptr) {
|
||||
HILOG_ERROR("buf is null");
|
||||
return;
|
||||
}
|
||||
|
||||
NetServer* that = (NetServer*)handle->data;
|
||||
WriteReq* wr = nullptr;
|
||||
uv_shutdown_t* sreq = nullptr;
|
||||
|
||||
if (nread < 0) {
|
||||
free(buf->base);
|
||||
sreq = (uv_shutdown_t*)malloc(sizeof(*sreq));
|
||||
if (sreq == nullptr) {
|
||||
HILOG_ERROR("sreq is null");
|
||||
return;
|
||||
}
|
||||
sreq->data = that;
|
||||
uv_shutdown(sreq, handle, AfterShutdown);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nread == 0) {
|
||||
free(buf->base);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!that->serverClosed_) {
|
||||
for (int i = 0; i < nread; i++) {
|
||||
if (buf->base[i] == 'Q') {
|
||||
if (i + 1 < nread && buf->base[i + 1] == 'S') {
|
||||
free(buf->base);
|
||||
uv_close((uv_handle_t*)handle, OnClose);
|
||||
return;
|
||||
} else {
|
||||
uv_close((uv_handle_t*)&that->tcpServer_, OnServerClose);
|
||||
that->serverClosed_ = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
that->Emit("read", nullptr);
|
||||
|
||||
wr = (WriteReq*)malloc(sizeof(WriteReq));
|
||||
if (wr == nullptr) {
|
||||
HILOG_ERROR("wr is null");
|
||||
free(buf->base);
|
||||
return;
|
||||
}
|
||||
|
||||
wr->buf = uv_buf_init(buf->base, nread);
|
||||
|
||||
wr->req.data = that;
|
||||
|
||||
if (uv_write(&wr->req, handle, &wr->buf, 1, AfterWrite) != 0) {
|
||||
that->Emit("error", nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void NetServer::AfterShutdown(uv_shutdown_t* req, int status)
|
||||
{
|
||||
if (req == nullptr) {
|
||||
HILOG_ERROR("req is null");
|
||||
return;
|
||||
}
|
||||
|
||||
uv_close((uv_handle_t*)req->handle, OnClose);
|
||||
free(req);
|
||||
}
|
||||
|
||||
void NetServer::EchoAlloc(uv_handle_t* handle, size_t suggestedSize, uv_buf_t* buf)
|
||||
{
|
||||
if (handle == nullptr) {
|
||||
HILOG_ERROR("handle is null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (buf == nullptr) {
|
||||
HILOG_ERROR("buf is null");
|
||||
return;
|
||||
}
|
||||
|
||||
buf->base = (char*)malloc(suggestedSize);
|
||||
if (buf->base != nullptr) {
|
||||
HILOG_ERROR("buf->base is null");
|
||||
return;
|
||||
}
|
||||
|
||||
buf->len = suggestedSize;
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_NAPI_TEST_NATIVE_MODULE_NETSERVER_NETSERVER_H
|
||||
#define FOUNDATION_ACE_NAPI_TEST_NATIVE_MODULE_NETSERVER_NETSERVER_H
|
||||
|
||||
#include "event_target.h"
|
||||
|
||||
#include "napi/native_api.h"
|
||||
#include "napi/native_node_api.h"
|
||||
#include "securec.h"
|
||||
|
||||
#include "uv.h"
|
||||
|
||||
#define EVENT_TYPE_BUFFER_SIZE 64
|
||||
|
||||
struct WriteReq {
|
||||
uv_write_t req = { 0 };
|
||||
uv_buf_t buf = { 0 };
|
||||
};
|
||||
|
||||
class NetServerEvent {
|
||||
public:
|
||||
NetServerEvent(napi_env env, const char* type, char* buffer = nullptr, size_t length = 0)
|
||||
{
|
||||
env_ = env;
|
||||
|
||||
(void)strncpy_s(type_, EVENT_TYPE_BUFFER_SIZE, type, strlen(type));
|
||||
|
||||
buffer_ = buffer;
|
||||
length_ = length;
|
||||
}
|
||||
|
||||
virtual ~NetServerEvent() {}
|
||||
|
||||
virtual napi_value ToJsObject()
|
||||
{
|
||||
napi_value result;
|
||||
napi_create_object(env_, &result);
|
||||
|
||||
napi_value type;
|
||||
napi_create_string_utf8(env_, type_, strlen(type_), &type);
|
||||
napi_set_named_property(env_, result, "type", type);
|
||||
|
||||
if (length_ > 0) {
|
||||
napi_value data;
|
||||
napi_create_string_utf8(env_, buffer_, length_, &data);
|
||||
napi_set_named_property(env_, result, "data", data);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
napi_env env_;
|
||||
|
||||
char type_[EVENT_TYPE_BUFFER_SIZE];
|
||||
char* buffer_;
|
||||
size_t length_;
|
||||
};
|
||||
|
||||
struct NetClient {
|
||||
uv_tcp_t tcp = { 0 };
|
||||
uv_write_t req = { 0 };
|
||||
uv_buf_t buf = { 0 };
|
||||
NetClient* next = nullptr;
|
||||
};
|
||||
|
||||
class NetServer : public EventTarget {
|
||||
NetServer(napi_env env, napi_value thisVar);
|
||||
virtual ~NetServer();
|
||||
|
||||
public:
|
||||
int Start(int port);
|
||||
void Stop();
|
||||
|
||||
static napi_value Export(napi_env env, napi_value exports);
|
||||
|
||||
private:
|
||||
// Napi methods and properties
|
||||
static napi_value JS_Constructor(napi_env env, napi_callback_info cbinfo);
|
||||
static napi_value JS_Start(napi_env env, napi_callback_info cbinfo);
|
||||
static napi_value JS_Stop(napi_env env, napi_callback_info cbinfo);
|
||||
static napi_value JS_On(napi_env env, napi_callback_info cbinfo);
|
||||
static napi_value JS_Once(napi_env env, napi_callback_info cbinfo);
|
||||
static napi_value JS_Off(napi_env env, napi_callback_info cbinfo);
|
||||
|
||||
// C function and members
|
||||
static void EchoAlloc(uv_handle_t* handle, size_t suggestedSize, uv_buf_t* buf);
|
||||
static void AfterShutdown(uv_shutdown_t* req, int status);
|
||||
static void AfterWrite(uv_write_t* req, int status);
|
||||
static void AfterRead(uv_stream_t*, ssize_t nread, const uv_buf_t* buf);
|
||||
static void OnClose(uv_handle_t* peer);
|
||||
static void OnServerClose(uv_handle_t* handle);
|
||||
static void OnConnection(uv_stream_t*, int status);
|
||||
|
||||
uv_loop_t* loop_;
|
||||
int serverClosed_;
|
||||
uv_tcp_t tcpServer_;
|
||||
NetClient* clients_;
|
||||
};
|
||||
|
||||
#endif /* FOUNDATION_ACE_NAPI_TEST_NATIVE_MODULE_NETSERVER_NETSERVER_H */
|
||||
@@ -24,6 +24,7 @@ struct NativeHandle {
|
||||
};
|
||||
|
||||
struct NativeScope {
|
||||
static NativeScope* CreateNewInstance() { return new NativeScope(); }
|
||||
NativeHandle* handlePtr = nullptr;
|
||||
size_t handleCount = 0;
|
||||
bool escaped = false;
|
||||
@@ -34,12 +35,8 @@ struct NativeScope {
|
||||
|
||||
NativeScopeManager::NativeScopeManager()
|
||||
{
|
||||
root_ = new NativeScope();
|
||||
if (root_) {
|
||||
current_ = root_;
|
||||
} else {
|
||||
HILOG_ERROR("Construct NativeScopeManager error.");
|
||||
}
|
||||
root_ = NativeScope::CreateNewInstance();
|
||||
current_ = root_;
|
||||
}
|
||||
|
||||
NativeScopeManager::~NativeScopeManager()
|
||||
@@ -63,10 +60,17 @@ NativeScopeManager::~NativeScopeManager()
|
||||
|
||||
NativeScope* NativeScopeManager::Open()
|
||||
{
|
||||
if (current_ == nullptr) {
|
||||
HILOG_ERROR("current scope is null when open scope");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto scope = new NativeScope();
|
||||
current_->child = scope;
|
||||
scope->parent = current_;
|
||||
current_ = scope;
|
||||
if (scope != nullptr) {
|
||||
current_->child = scope;
|
||||
scope->parent = current_;
|
||||
current_ = scope;
|
||||
}
|
||||
|
||||
return scope;
|
||||
}
|
||||
@@ -146,15 +150,23 @@ NativeValue* NativeScopeManager::Escape(NativeScope* scope, NativeValue* value)
|
||||
|
||||
void NativeScopeManager::CreateHandle(NativeValue* value)
|
||||
{
|
||||
if (current_ == nullptr) {
|
||||
HILOG_ERROR("current scope is null when create handle");
|
||||
return;
|
||||
}
|
||||
auto handlePtr = new NativeHandle();
|
||||
if (handlePtr == nullptr) {
|
||||
HILOG_ERROR("create handle ptr failed");
|
||||
return;
|
||||
}
|
||||
if (current_->handlePtr == nullptr) {
|
||||
current_->handlePtr = new NativeHandle();
|
||||
current_->handlePtr = handlePtr;
|
||||
current_->handlePtr->value = value;
|
||||
current_->handlePtr->sibling = nullptr;
|
||||
} else {
|
||||
auto temp = new NativeHandle();
|
||||
temp->sibling = current_->handlePtr;
|
||||
temp->value = value;
|
||||
current_->handlePtr = temp;
|
||||
handlePtr->sibling = current_->handlePtr;
|
||||
handlePtr->value = value;
|
||||
current_->handlePtr = handlePtr;
|
||||
}
|
||||
current_->handleCount++;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,9 @@ public:
|
||||
virtual void CreateHandle(NativeValue* value);
|
||||
virtual NativeValue* Escape(NativeScope* scope, NativeValue* value);
|
||||
|
||||
NativeScopeManager(NativeScopeManager&) = delete;
|
||||
virtual NativeScopeManager& operator=(NativeScopeManager&) = delete;
|
||||
|
||||
private:
|
||||
NativeScope* root_;
|
||||
NativeScope* current_;
|
||||
|
||||
+44
-2
@@ -45,7 +45,6 @@ ohos_unittest("test_quickjs_unittest") {
|
||||
"//third_party/libuv:uv_static",
|
||||
"//third_party/quickjs:qjs",
|
||||
"//utils/native/base:utils",
|
||||
"//utils/native/base:utilsecurec",
|
||||
]
|
||||
|
||||
if (is_standard_system) {
|
||||
@@ -53,7 +52,50 @@ ohos_unittest("test_quickjs_unittest") {
|
||||
}
|
||||
}
|
||||
|
||||
ohos_unittest("test_ark_unittest") {
|
||||
module_out_path = module_output_path
|
||||
|
||||
configs = [ "//ark/js_runtime:ark_jsruntime_public_config" ]
|
||||
|
||||
include_dirs = [
|
||||
"//ark/js_runtime",
|
||||
"//foundation/ace/napi",
|
||||
"//foundation/ace/napi/interfaces/kits",
|
||||
"//foundation/ace/napi/native_engine",
|
||||
"//foundation/ace/napi/native_engine/impl/ark",
|
||||
"//third_party/googletest/include",
|
||||
"//third_party/node/src",
|
||||
"//utils/native/base/include",
|
||||
]
|
||||
|
||||
cflags = [ "-g3" ]
|
||||
|
||||
sources = [
|
||||
"test_ark.cpp",
|
||||
"test_napi.cpp",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//ark/js_runtime:libark_jsruntime",
|
||||
"//foundation/ace/napi/:ace_napi",
|
||||
"//foundation/ace/napi/:ace_napi_ark",
|
||||
"//third_party/googletest:gtest",
|
||||
"//third_party/googletest:gtest_main",
|
||||
"//third_party/libuv:uv_static",
|
||||
"//utils/native/base:utils",
|
||||
]
|
||||
|
||||
if (is_standard_system) {
|
||||
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
|
||||
} else {
|
||||
external_deps = [ "hilog:libhilog" ]
|
||||
}
|
||||
}
|
||||
|
||||
group("unittest") {
|
||||
testonly = true
|
||||
deps = [ ":test_quickjs_unittest" ]
|
||||
deps = [
|
||||
":test_ark_unittest",
|
||||
":test_quickjs_unittest",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include "utils/log.h"
|
||||
#include "ark_native_engine.h"
|
||||
|
||||
using panda::RuntimeOption;
|
||||
static NativeEngine* g_nativeEngine = nullptr;
|
||||
|
||||
NativeEngineTest::NativeEngineTest()
|
||||
{
|
||||
engine_ = g_nativeEngine;
|
||||
}
|
||||
|
||||
NativeEngineTest::~NativeEngineTest() {}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
testing::GTEST_FLAG(output) = "xml:./";
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
// Setup
|
||||
RuntimeOption option;
|
||||
option.SetGcType(RuntimeOption::GC_TYPE::GEN_GC);
|
||||
// const int64_t poolSize = 0x10000000; // 256M
|
||||
const int64_t poolSize = 0x1000000; // 16M
|
||||
option.SetGcPoolSize(poolSize);
|
||||
//option.SetPandaStdFile("pandastdlib/arkstdlib.abc");
|
||||
option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
|
||||
option.SetDebuggerLibraryPath("");
|
||||
EcmaVM* vm = panda::JSNApi::CreateJSVM(option);
|
||||
if (vm == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_nativeEngine = new ArkNativeEngine(vm, nullptr);
|
||||
|
||||
int ret = testing::UnitTest::GetInstance()->Run();
|
||||
|
||||
g_nativeEngine->Loop(LOOP_NOWAIT);
|
||||
|
||||
delete g_nativeEngine;
|
||||
g_nativeEngine = nullptr;
|
||||
panda::JSNApi::DestoryJSVM(vm);
|
||||
vm = nullptr;
|
||||
|
||||
return ret;
|
||||
}
|
||||
+104
-80
@@ -14,11 +14,8 @@
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include "napi/native_api.h"
|
||||
#include "napi/native_node_api.h"
|
||||
|
||||
#include "securec.h"
|
||||
#include "utils/log.h"
|
||||
|
||||
#define ASSERT_CHECK_CALL(call) \
|
||||
@@ -532,7 +529,7 @@ HWTEST_F(NativeEngineTest, ErrorTest, testing::ext::TestSize.Level0)
|
||||
bool isError = false;
|
||||
napi_is_error(env, error, &isError);
|
||||
ASSERT_TRUE(isError);
|
||||
napi_throw(env, error);
|
||||
//napi_throw(env, error);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -561,12 +558,12 @@ HWTEST_F(NativeEngineTest, ErrorTest, testing::ext::TestSize.Level0)
|
||||
ASSERT_TRUE(isError);
|
||||
}
|
||||
|
||||
napi_throw_error(env, "500", "Common error");
|
||||
napi_throw_range_error(env, "500", "Range error");
|
||||
napi_throw_type_error(env, "500", "Type error");
|
||||
//napi_throw_error(env, "500", "Common error");
|
||||
//napi_throw_range_error(env, "500", "Range error");
|
||||
//napi_throw_type_error(env, "500", "Type error");
|
||||
bool isExceptionPending = false;
|
||||
napi_is_exception_pending(env, &isExceptionPending);
|
||||
ASSERT_TRUE(isExceptionPending);
|
||||
//ASSERT_TRUE(isExceptionPending);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -582,6 +579,7 @@ HWTEST_F(NativeEngineTest, ReferenceTest, testing::ext::TestSize.Level0)
|
||||
napi_ref resultRef = nullptr;
|
||||
|
||||
napi_create_object(env, &result);
|
||||
ASSERT_CHECK_VALUE_TYPE(env, result, napi_object);
|
||||
napi_create_reference(env, result, 1, &resultRef);
|
||||
|
||||
uint32_t resultRefCount = 0;
|
||||
@@ -817,6 +815,101 @@ HWTEST_F(NativeEngineTest, StrictEqualsTest, testing::ext::TestSize.Level0)
|
||||
ASSERT_TRUE(isStrictEquals);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: CreateRuntimeTest
|
||||
* @tc.desc: Test create runtime.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(NativeEngineTest, CreateRuntimeTest, testing::ext::TestSize.Level0)
|
||||
{
|
||||
napi_env env = (napi_env)engine_;
|
||||
|
||||
napi_env newEnv = nullptr;
|
||||
napi_create_runtime(env, &newEnv);
|
||||
#ifdef USE_V8_ENGINE
|
||||
ASSERT_NE(newEnv, nullptr);
|
||||
#elif USE_QUICKJS_ENGINE
|
||||
ASSERT_EQ(newEnv, nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: SerializeDeSerializeTest
|
||||
* @tc.desc: Test serialize & deserialize.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(NativeEngineTest, SerializeDeSerializeTest, testing::ext::TestSize.Level0)
|
||||
{
|
||||
napi_env env = (napi_env)engine_;
|
||||
|
||||
napi_value undefined = nullptr;
|
||||
napi_get_undefined(env, &undefined);
|
||||
#ifdef USE_V8_ENGINE
|
||||
napi_value num = nullptr;
|
||||
uint32_t value = 1000;
|
||||
napi_create_uint32(env, value, &num);
|
||||
napi_value data = nullptr;
|
||||
napi_serialize(env, num, undefined, &data);
|
||||
ASSERT_NE(data, nullptr);
|
||||
|
||||
napi_value result = nullptr;
|
||||
napi_deserialize(env, data, &result);
|
||||
ASSERT_CHECK_VALUE_TYPE(env, result, napi_number);
|
||||
int32_t resultData = 0;
|
||||
napi_get_value_int32(env, result, &resultData);
|
||||
ASSERT_EQ(resultData, 1000);
|
||||
|
||||
napi_delete_serialization_data(env, data);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: IsCallableTest
|
||||
* @tc.desc: Test is callable.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(NativeEngineTest, IsCallableTest, testing::ext::TestSize.Level0)
|
||||
{
|
||||
napi_env env = (napi_env)engine_;
|
||||
|
||||
auto func = [](napi_env env, napi_callback_info info) -> napi_value {
|
||||
napi_value thisVar;
|
||||
napi_value* argv = nullptr;
|
||||
size_t argc = 0;
|
||||
void* data = nullptr;
|
||||
|
||||
napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);
|
||||
if (argc > 0) {
|
||||
argv = new napi_value[argc];
|
||||
}
|
||||
napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
|
||||
|
||||
napi_value result = nullptr;
|
||||
napi_create_object(env, &result);
|
||||
|
||||
napi_value messageKey = nullptr;
|
||||
const char* messageKeyStr = "message";
|
||||
napi_create_string_latin1(env, messageKeyStr, strlen(messageKeyStr), &messageKey);
|
||||
napi_value messageValue = nullptr;
|
||||
const char* messageValueStr = "OK";
|
||||
napi_create_string_latin1(env, messageValueStr, strlen(messageValueStr), &messageValue);
|
||||
napi_set_property(env, result, messageKey, messageValue);
|
||||
|
||||
if (argv != nullptr) {
|
||||
delete argv;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
napi_value funcValue = nullptr;
|
||||
napi_create_function(env, "testFunc", NAPI_AUTO_LENGTH, func, nullptr, &funcValue);
|
||||
ASSERT_NE(funcValue, nullptr);
|
||||
|
||||
bool result = false;
|
||||
napi_is_callable(env, funcValue, &result);
|
||||
ASSERT_TRUE(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: LoadModuleTest
|
||||
* @tc.desc: Test LoadModule Func.
|
||||
@@ -825,16 +918,16 @@ HWTEST_F(NativeEngineTest, StrictEqualsTest, testing::ext::TestSize.Level0)
|
||||
HWTEST_F(NativeEngineTest, LoadModuleTest, testing::ext::TestSize.Level0)
|
||||
{
|
||||
napi_env env = (napi_env)engine_;
|
||||
|
||||
std::string sourceText = "var a = 1; let b = 2;"
|
||||
"export function getA() {return a};"
|
||||
"export function getB() {return b};"
|
||||
"export default {'val': 4};";
|
||||
"export default {'val': 4};"
|
||||
"export var value = 4;";
|
||||
auto sourceString = engine_->CreateString(sourceText.c_str(), sourceText.length());
|
||||
|
||||
std::string file = "file.js";
|
||||
NativeValue *moduleValue = engine_->LoadModule(sourceString, file);
|
||||
auto moduleObject = reinterpret_cast<NativeObject *>(moduleValue->GetInterface(NativeObject::INTERFACE_ID));
|
||||
auto moduleObject = reinterpret_cast<NativeObject*>(moduleValue->GetInterface(NativeObject::INTERFACE_ID));
|
||||
|
||||
std::string key = "val";
|
||||
auto keyString = engine_->CreateString(key.c_str(), key.length());
|
||||
@@ -848,72 +941,3 @@ HWTEST_F(NativeEngineTest, LoadModuleTest, testing::ext::TestSize.Level0)
|
||||
napi_strict_equals(env, lvalue, rvalue, &result);
|
||||
ASSERT_TRUE(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: EncodeToUtf8Test
|
||||
* @tc.desc: Test EncodeToUtf8 Func.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(NativeEngineTest, EncodeToUtf8Test, testing::ext::TestSize.Level0)
|
||||
{
|
||||
std::string str = "encode";
|
||||
auto testStr = engine_->CreateString(str.c_str(), str.length());
|
||||
char* buffer = new char[str.length()];
|
||||
size_t bufferSize = str.length();
|
||||
int32_t written = 0;
|
||||
int32_t nchars = 0;
|
||||
memset_s(buffer, str.length(), 0, str.length());
|
||||
engine_->EncodeToUtf8(testStr, buffer, &written, bufferSize, &nchars);
|
||||
ASSERT_EQ(written, 6);
|
||||
ASSERT_EQ(nchars, 6);
|
||||
delete[] buffer;
|
||||
|
||||
str = "encode\xc2\xab\xe2\x98\x80";
|
||||
testStr = engine_->CreateString(str.c_str(), str.length());
|
||||
buffer = new char[str.length()];
|
||||
bufferSize = str.length();
|
||||
memset_s(buffer, str.length(), 0, str.length());
|
||||
engine_->EncodeToUtf8(testStr, buffer, &written, bufferSize, &nchars);
|
||||
ASSERT_EQ(written, 11);
|
||||
ASSERT_EQ(nchars, 8);
|
||||
delete[] buffer;
|
||||
|
||||
buffer = new char[str.length()];
|
||||
bufferSize = str.length();
|
||||
memset_s(buffer, str.length(), 0, str.length());
|
||||
bufferSize--;
|
||||
engine_->EncodeToUtf8(testStr, buffer, &written, bufferSize, &nchars);
|
||||
ASSERT_EQ(written, 8);
|
||||
ASSERT_EQ(nchars, 7);
|
||||
delete[] buffer;
|
||||
|
||||
buffer = new char[str.length()];
|
||||
bufferSize = str.length();
|
||||
memset_s(buffer, str.length(), 0, str.length());
|
||||
bufferSize -= 4;
|
||||
engine_->EncodeToUtf8(testStr, buffer, &written, bufferSize, &nchars);
|
||||
ASSERT_EQ(written, 6);
|
||||
ASSERT_EQ(nchars, 6);
|
||||
delete[] buffer;
|
||||
|
||||
str = "encode\xc2\xab\xe2\x98\x80t";
|
||||
testStr = engine_->CreateString(str.c_str(), str.length());
|
||||
buffer = new char[str.length()];
|
||||
bufferSize = str.length();
|
||||
memset_s(buffer, str.length(), 0, str.length());
|
||||
bufferSize--;
|
||||
engine_->EncodeToUtf8(testStr, buffer, &written, bufferSize, &nchars);
|
||||
ASSERT_EQ(written, 11);
|
||||
ASSERT_EQ(nchars, 8);
|
||||
delete[] buffer;
|
||||
|
||||
str = "";
|
||||
testStr = engine_->CreateString(str.c_str(), str.length());
|
||||
buffer = new char[str.length() + 1];
|
||||
bufferSize = str.length() + 1;
|
||||
memset_s(buffer, str.length(), 0, str.length());
|
||||
engine_->EncodeToUtf8(testStr, buffer, &written, bufferSize, &nchars);
|
||||
ASSERT_EQ(written, 0);
|
||||
ASSERT_EQ(nchars, 0);
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ int main(int argc, char** argv)
|
||||
|
||||
js_std_add_helpers(ctx, 0, nullptr);
|
||||
|
||||
g_nativeEngine = new QuickJSNativeEngine(rt, ctx);
|
||||
g_nativeEngine = new QuickJSNativeEngine(rt, ctx, 0); // default instance id 0
|
||||
|
||||
int ret = RUN_ALL_TESTS();
|
||||
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include "utils/log.h"
|
||||
#include "v8_native_engine.h"
|
||||
|
||||
static NativeEngine* g_nativeEngine = nullptr;
|
||||
|
||||
NativeEngineTest::NativeEngineTest()
|
||||
{
|
||||
engine_ = g_nativeEngine;
|
||||
}
|
||||
|
||||
NativeEngineTest::~NativeEngineTest() {}
|
||||
|
||||
extern const char _binary_strip_native_min_js_bin_start[];
|
||||
extern const char _binary_strip_native_min_js_bin_end[];
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int retCode = 0;
|
||||
|
||||
testing::GTEST_FLAG(output) = "xml:./";
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
static v8::StartupData snapshotBlob = {
|
||||
.data = _binary_strip_native_min_js_bin_start,
|
||||
.raw_size = _binary_strip_native_min_js_bin_end - _binary_strip_native_min_js_bin_start,
|
||||
};
|
||||
v8::V8::SetSnapshotDataBlob(&snapshotBlob);
|
||||
|
||||
std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
|
||||
v8::V8::InitializePlatform(platform.get());
|
||||
if (!v8::V8::Initialize()) {
|
||||
return retCode;
|
||||
}
|
||||
v8::Isolate::CreateParams createParams;
|
||||
createParams.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
|
||||
|
||||
if (createParams.array_buffer_allocator == nullptr) {
|
||||
return retCode;
|
||||
}
|
||||
|
||||
v8::Isolate* isolate = v8::Isolate::New(createParams);
|
||||
{
|
||||
v8::Isolate::Scope isolateScope(isolate);
|
||||
v8::HandleScope handleScope(isolate);
|
||||
v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
|
||||
v8::Local<v8::Context> context = v8::Context::New(isolate, nullptr, global);
|
||||
|
||||
v8::Persistent<v8::Context> persistContext;
|
||||
persistContext.Reset(isolate, context);
|
||||
|
||||
if (context.IsEmpty()) {
|
||||
return retCode;
|
||||
}
|
||||
|
||||
v8::Context::Scope contextScope(context);
|
||||
{
|
||||
g_nativeEngine = new V8NativeEngine(platform.get(), isolate, persistContext, 0); // default instance id 0
|
||||
|
||||
retCode = testing::UnitTest::GetInstance()->Run();
|
||||
|
||||
g_nativeEngine->Loop(LOOP_DEFAULT);
|
||||
delete g_nativeEngine;
|
||||
g_nativeEngine = nullptr;
|
||||
}
|
||||
}
|
||||
isolate->Dispose();
|
||||
v8::V8::Dispose();
|
||||
v8::V8::ShutdownPlatform();
|
||||
delete createParams.array_buffer_allocator;
|
||||
|
||||
return retCode;
|
||||
}
|
||||
Reference in New Issue
Block a user