From 5746ddc1a120f412588c68b0f89947e459f827dd Mon Sep 17 00:00:00 2001 From: y00576111 Date: Sat, 18 Sep 2021 18:32:49 +0800 Subject: [PATCH] fixed b144e38 from https://gitee.com/yaojian16/ace_napi/pulls/34 add quickjs worker napi && support ark Signed-off-by: y00576111 Change-Id: Iaafedc94c71d0522fbd305d02048631987807cd6 --- native_engine/impl/ark/ark_native_engine.cpp | 10 ++ native_engine/impl/ark/ark_native_engine.h | 1 + .../impl/quickjs/quickjs_native_engine.cpp | 104 ++++++++++++++++-- .../impl/quickjs/quickjs_native_engine.h | 28 +++++ 4 files changed, 136 insertions(+), 7 deletions(-) diff --git a/native_engine/impl/ark/ark_native_engine.cpp b/native_engine/impl/ark/ark_native_engine.cpp index fd0eb35a3..ee81553f9 100644 --- a/native_engine/impl/ark/ark_native_engine.cpp +++ b/native_engine/impl/ark/ark_native_engine.cpp @@ -570,3 +570,13 @@ NativeValue* ArkNativeEngine::ValueToNativeValue(JSValueWrapper& value) Global arkValue = value; return ArkValueToNativeValue(this, arkValue.ToLocal(vm_)); } + +bool ArkNativeEngine::ExecuteJsBin(const std::string& fileName) +{ + panda::JSExecutionScope executionScope(vm_); + LocalScope scope(vm_); + Local file = StringRef::NewFromUtf8(vm_, fileName.c_str()); + Local entryPoint = StringRef::NewFromUtf8(vm_, PANDA_MAIN_FUNCTION); + bool ret = JSNApi::Execute(vm_, file, entryPoint); + return ret; +} diff --git a/native_engine/impl/ark/ark_native_engine.h b/native_engine/impl/ark/ark_native_engine.h index 0efbb561a..bd37bcb70 100644 --- a/native_engine/impl/ark/ark_native_engine.h +++ b/native_engine/impl/ark/ark_native_engine.h @@ -145,6 +145,7 @@ public: NativeValue* ValueToNativeValue(JSValueWrapper& value) override; + bool ExecuteJsBin(const std::string& fileName); private: EcmaVM* vm_ = nullptr; std::string exceptionStr_; diff --git a/native_engine/impl/quickjs/quickjs_native_engine.cpp b/native_engine/impl/quickjs/quickjs_native_engine.cpp index bc502ca5c..48fefcd36 100644 --- a/native_engine/impl/quickjs/quickjs_native_engine.cpp +++ b/native_engine/impl/quickjs/quickjs_native_engine.cpp @@ -30,8 +30,15 @@ #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, void* jsEngine) : NativeEngine(jsEngine) { @@ -586,27 +593,110 @@ NativeValue* QuickJSNativeEngine::JSValueToNativeValue(QuickJSNativeEngine* engi } void* QuickJSNativeEngine::CreateRuntime() + { + JSRuntime* runtime = JS_NewRuntime(); + JSContext* context = JS_NewContext(runtime); + return reinterpret_cast(new QuickJSNativeEngine(runtime, context, this)); +} + +bool QuickJSNativeEngine::CheckTransferList(JSValue transferList) { - return nullptr; + 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; } -NativeValue* QuickJSNativeEngine::Serialize(NativeEngine* context, NativeValue* value, NativeValue* transfer) +bool QuickJSNativeEngine::DetachTransferList(JSValue transferList) { - return nullptr; + 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(new SerializeData(dataLen, data)); +} + NativeValue* QuickJSNativeEngine::Deserialize(NativeEngine* context, NativeValue* recorder) { - return nullptr; + std::unique_ptr data(reinterpret_cast(recorder)); + JSValue result = JS_ReadObject(context_, data->GetData(), data->GetSize(), JS_WRITE_OBJ); + return JSValueToNativeValue(this, result); } - + void QuickJSNativeEngine::DeleteSerializationData(NativeValue* value) const { + SerializeData* data = reinterpret_cast(value); + delete data; } - + ExceptionInfo* QuickJSNativeEngine::GetExceptionForWorker() const { - return nullptr; + 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(JS_GetStringFromObject(msg)); + const char* error = "Error: "; + int len = strlen(exceptionStr) + strlen(error) + 1; + if (len <= 0) { + 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; } NativeValue* QuickJSNativeEngine::ValueToNativeValue(JSValueWrapper& value) diff --git a/native_engine/impl/quickjs/quickjs_native_engine.h b/native_engine/impl/quickjs/quickjs_native_engine.h index 0be47b113..91a395ce4 100644 --- a/native_engine/impl/quickjs/quickjs_native_engine.h +++ b/native_engine/impl/quickjs/quickjs_native_engine.h @@ -19,6 +19,32 @@ #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 value_; +}; + class QuickJSNativeEngine : public NativeEngine { public: QuickJSNativeEngine(JSRuntime* runtime, JSContext* contex, void* jsEngine); @@ -79,6 +105,8 @@ public: 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; -- Gitee