diff --git a/native_engine/impl/ark/ark_native_engine.cpp b/native_engine/impl/ark/ark_native_engine.cpp index fd0eb35a37d7a37b581b30ee846882df8073079e..ee81553f90e7b026e316fde504552c48f621b17e 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 0efbb561a1adfa0a654064377af77290da68ac83..bd37bcb70232c4f711bd40b270008b1423a84373 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 bc502ca5ce6d083c870bab0f990e577a6464e406..48fefcd369028f159e4d12582020396a7ca11853 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 0be47b11358e7dd4eb51b5dbb35ce65e3c4d5941..91a395ce475f3174aa12d32759f2d7c7df225735 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;