Signed-off-by: zhongjianfei <zhongjianfei@huawei.com>
Change-Id: Ic43ae2175fca333394f68d670ee60343cf63c278
This commit is contained in:
zhongjianfei
2021-09-14 15:36:27 +08:00
parent 309b4f7df6
commit a99921b5ca
93 changed files with 6890 additions and 509 deletions
+62
View File
@@ -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",
]
}
-65
View File
@@ -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:
" == &gt;
& == &gt;
' == &gt;
< == &gt;
> == &gt;
-->
<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>
+9 -6
View File
@@ -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 */
+1 -1
View File
@@ -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,
+104 -25
View File
@@ -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);
}
}
+9 -3
View File
@@ -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_;
+23
View File
@@ -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_));
}
+154
View File
@@ -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_;
+14 -10
View File
@@ -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 */
+23
View File
@@ -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 */
+861
View File
@@ -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);
}
+202
View File
@@ -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 */
+26 -10
View File
@@ -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);
}
+19 -7
View File
@@ -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);
}
-2
View File
@@ -68,8 +68,6 @@ private:
uv_work_t work_;
uv_async_t workAsyncHandler_;
NativeEngine* engine_;
int status_;
NativeAsyncExecuteCallback execute_;
NativeAsyncCompleteCallback complete_;
void* data_;
+78 -19
View File
@@ -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_;
}
+29 -11
View File
@@ -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 -18
View File
@@ -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
View File
@@ -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;
}
+115
View File
@@ -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 */
+26 -14
View File
@@ -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++;
}
+3
View File
@@ -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
View File
@@ -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",
]
}
+62
View File
@@ -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
View File
@@ -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;
}
+1 -1
View File
@@ -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();
+89
View File
@@ -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;
}