From 72fe828ef6f8d68a283a36fd073bfad8860c4bbc Mon Sep 17 00:00:00 2001 From: liuweili Date: Thu, 28 Nov 2024 11:32:48 +0800 Subject: [PATCH] =?UTF-8?q?jsvm=E6=96=B0=E5=A2=9EAPI=20external=20string&&?= =?UTF-8?q?private?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: liuweili --- src/js_native_api_v8.cc | 247 ++++++++++++++++++++++++++++++++++++---- src/js_native_api_v8.h | 42 ++++--- src/jsvm.h | 161 ++++++++++++++++++++++++++ src/jsvm_types.h | 7 ++ 4 files changed, 422 insertions(+), 35 deletions(-) diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc index a61038398..749269dbc 100644 --- a/src/js_native_api_v8.cc +++ b/src/js_native_api_v8.cc @@ -728,7 +728,7 @@ class PropertyCallbackWrapperBase : public CallbackWrapper { JSVM_Value innerData = nullptr; if (_cb->namedPropertyData_ != nullptr) { v8impl::Reference* reference = reinterpret_cast(_cb->namedPropertyData_); - innerData = v8impl::JsValueFromV8LocalValue(reference->Get()); + innerData = v8impl::JsValueFromV8LocalValue(reference->GetValue()); } bool exceptionOccurred = false; @@ -761,7 +761,7 @@ class PropertyCallbackWrapperBase : public CallbackWrapper { JSVM_Value innerData = nullptr; if (_cb->namedPropertyData_ != nullptr) { v8impl::Reference* reference = reinterpret_cast(_cb->namedPropertyData_); - innerData = v8impl::JsValueFromV8LocalValue(reference->Get()); + innerData = v8impl::JsValueFromV8LocalValue(reference->GetValue()); } bool exceptionOccurred = false; JSVM_Value result = nullptr; @@ -792,7 +792,7 @@ class PropertyCallbackWrapperBase : public CallbackWrapper { JSVM_Value innerData = nullptr; if (_cb->namedPropertyData_ != nullptr) { v8impl::Reference* reference = reinterpret_cast(_cb->namedPropertyData_); - innerData = v8impl::JsValueFromV8LocalValue(reference->Get()); + innerData = v8impl::JsValueFromV8LocalValue(reference->GetValue()); } bool exceptionOccurred = false; @@ -826,7 +826,7 @@ class PropertyCallbackWrapperBase : public CallbackWrapper { JSVM_Value innerData = nullptr; if (_cb->namedPropertyData_ != nullptr) { v8impl::Reference* reference = reinterpret_cast(_cb->namedPropertyData_); - innerData = v8impl::JsValueFromV8LocalValue(reference->Get()); + innerData = v8impl::JsValueFromV8LocalValue(reference->GetValue()); } bool exceptionOccurred = false; @@ -859,7 +859,7 @@ class PropertyCallbackWrapperBase : public CallbackWrapper { JSVM_Value innerData = nullptr; if (_cb->indexedPropertyData_ != nullptr) { v8impl::Reference* reference = reinterpret_cast(_cb->indexedPropertyData_); - innerData = v8impl::JsValueFromV8LocalValue(reference->Get()); + innerData = v8impl::JsValueFromV8LocalValue(reference->GetValue()); } bool exceptionOccurred = false; @@ -892,7 +892,7 @@ class PropertyCallbackWrapperBase : public CallbackWrapper { JSVM_Value innerData = nullptr; if (_cb->indexedPropertyData_ != nullptr) { v8impl::Reference* reference = reinterpret_cast(_cb->indexedPropertyData_); - innerData = v8impl::JsValueFromV8LocalValue(reference->Get()); + innerData = v8impl::JsValueFromV8LocalValue(reference->GetValue()); } JSVM_Value result = nullptr; @@ -924,7 +924,7 @@ class PropertyCallbackWrapperBase : public CallbackWrapper { JSVM_Value innerData = nullptr; if (_cb->indexedPropertyData_ != nullptr) { v8impl::Reference* reference = reinterpret_cast(_cb->indexedPropertyData_); - innerData = v8impl::JsValueFromV8LocalValue(reference->Get()); + innerData = v8impl::JsValueFromV8LocalValue(reference->GetValue()); } bool exceptionOccurred = false; @@ -958,7 +958,7 @@ class PropertyCallbackWrapperBase : public CallbackWrapper { JSVM_Value innerData = nullptr; if (_cb->indexedPropertyData_ != nullptr) { v8impl::Reference* reference = reinterpret_cast(_cb->indexedPropertyData_); - innerData = v8impl::JsValueFromV8LocalValue(reference->Get()); + innerData = v8impl::JsValueFromV8LocalValue(reference->GetValue()); } bool exceptionOccurred = false; @@ -1117,7 +1117,11 @@ inline JSVM_Status Wrap(JSVM_Env env, // Currently, V8 has no API to detect if a symbol is local or global. // Until we have a V8 API for it, we consider that all symbols can be weak. // This matches the current Node-API behavior. -inline bool CanBeHeldWeakly(v8::Local value) { +inline bool CanBeHeldWeakly(v8::Local data) { + if (data->IsPrivate()) { + return false; + } + auto value = data.As(); return value->IsObject() || value->IsSymbol(); } @@ -1233,10 +1237,11 @@ void RefBase::Finalize() { } template -Reference::Reference(JSVM_Env env, v8::Local value, Args&&... args) +Reference::Reference(JSVM_Env env, v8::Local data, bool isValue, Args&&... args) : RefBase(env, std::forward(args)...), - persistent_(env->isolate, value), - can_be_weak_(CanBeHeldWeakly(value)), + persistent_(env->isolate, data), + is_value(isValue), + can_be_weak_(isValue && CanBeHeldWeakly(data.As())), deleted_by_user(false), wait_callback(false) { if (RefCount() == 0) { @@ -1250,14 +1255,16 @@ Reference::~Reference() { } Reference* Reference::New(JSVM_Env env, - v8::Local value, + v8::Local data, uint32_t initialRefcount, Ownership ownership, JSVM_Finalize finalizeCallback, void* finalizeData, - void* finalizeHint) { + void* finalizeHint, + bool isValue) { return new Reference(env, - value, + data, + isValue, initialRefcount, ownership, finalizeCallback, @@ -1293,11 +1300,20 @@ uint32_t Reference::Unref() { return refcount; } -v8::Local Reference::Get() { +v8::Local Reference::GetValue() { + DCHECK(); if (persistent_.IsEmpty()) { return v8::Local(); } else { - return v8::Local::New(env_->isolate, persistent_); + return v8::Local::New(env_->isolate, persistent_).As(); + } +} + +v8::Local Reference::GetData() { + if (persistent_.IsEmpty()) { + return v8::Local(); + } else { + return v8::Local::New(env_->isolate, persistent_); } } @@ -1416,11 +1432,13 @@ OH_JSVM_Init(const JSVM_InitOptions* options) { #endif v8::V8::InitializePlatform(v8impl::g_platform.get()); +#ifdef TARGET_OHOS if (node::ReadSystemXpmState()) { int secArgc = SECARGCNT; char *secArgv[SECARGCNT] = {const_cast("jsvm"), const_cast("--jitless")}; v8::V8::SetFlagsFromCommandLine(&secArgc, secArgv, false); } +#endif if (options && options->argc && options->argv) { v8::V8::SetFlagsFromCommandLine(options->argc, options->argv, options->removeFlags); @@ -1877,7 +1895,7 @@ OH_JSVM_CreateCodeCache(JSVM_Env env, CHECK_ARG(env, script); CHECK_ARG(env, data); CHECK_ARG(env, length); - auto jsvmData = reinterpret_cast(script); + auto jsvmData = reinterpret_cast(script); auto v8script = jsvmData->ToV8Local(env->isolate); v8::ScriptCompiler::CachedData* cache; cache = v8::ScriptCompiler::CreateCodeCache(v8script->GetUnboundScript()); @@ -1900,7 +1918,7 @@ OH_JSVM_RunScript(JSVM_Env env, JSVM_Script script, JSVM_Value* result) { CHECK_ARG(env, script); CHECK_ARG(env, result); - auto jsvmData = reinterpret_cast(script); + auto jsvmData = reinterpret_cast(script); auto v8script = jsvmData->ToV8Local(env->isolate); auto script_result = v8script->Run(env->context()); CHECK_MAYBE_EMPTY(env, script_result, JSVM_GENERIC_FAILURE); @@ -2912,6 +2930,60 @@ JSVM_Status JSVM_CDECL OH_JSVM_CreateArrayWithLength(JSVM_Env env, return jsvm_clear_last_error(env); } +JSVM_Status JSVM_CDECL OH_JSVM_CreateExternalStringLatin1(JSVM_Env env, + char* str, + size_t length, + JSVM_Finalize finalizeCallback, + void* finalizeHint, + JSVM_Value* result, + bool* copied) { + CHECK_ARG(env, copied); + return v8impl::NewExternalString( + env, + str, + length, + finalizeCallback, + finalizeHint, + result, + copied, + OH_JSVM_CreateStringLatin1, + [&](v8::Isolate* isolate) { + if (length == JSVM_AUTO_LENGTH) { + length = (std::string_view(str)).length(); + } + auto resource = new v8impl::ExternalOneByteStringResource( + env, str, length, finalizeCallback, finalizeHint); + return v8::String::NewExternalOneByte(isolate, resource); + }); +} + +JSVM_Status JSVM_CDECL OH_JSVM_CreateExternalStringUtf16(JSVM_Env env, + char16_t* str, + size_t length, + JSVM_Finalize finalizeCallback, + void* finalizeHint, + JSVM_Value* result, + bool* copied) { + CHECK_ARG(env, copied); + return v8impl::NewExternalString( + env, + str, + length, + finalizeCallback, + finalizeHint, + result, + copied, + OH_JSVM_CreateStringUtf16, + [&](v8::Isolate* isolate) { + if (length == JSVM_AUTO_LENGTH) { + length = (std::u16string_view(str)).length(); + } + auto resource = new v8impl::ExternalStringResource( + env, str, length, finalizeCallback, finalizeHint); + return v8::String::NewExternalTwoByte(isolate, resource); + }); +} + JSVM_Status JSVM_CDECL OH_JSVM_CreateStringLatin1(JSVM_Env env, const char* str, size_t length, @@ -3097,6 +3169,90 @@ JSVM_Status JSVM_CDECL OH_JSVM_SymbolFor(JSVM_Env env, return jsvm_clear_last_error(env); } +JSVM_Status JSVM_CDECL OH_JSVM_CreatePrivate(JSVM_Env env, + JSVM_Value description, + JSVM_Data* result) { + CHECK_ENV(env); + CHECK_ARG(env, result); + + v8::Isolate* isolate = env->isolate; + + if (description == nullptr) { + *result = v8impl::JsDataFromV8LocalData(v8::Private::New(isolate)); + } else { + v8::Local v8Name = v8impl::V8LocalValueFromJsValue(description); + RETURN_STATUS_IF_FALSE(env, v8Name->IsString(), JSVM_STRING_EXPECTED); + + *result = v8impl::JsDataFromV8LocalData(v8::Private::New(isolate, v8Name.As())); + } + + return jsvm_clear_last_error(env); +} + +JSVM_Status JSVM_CDECL OH_JSVM_SetPrivate(JSVM_Env env, + JSVM_Value object, + JSVM_Data key, + JSVM_Value value) { + JSVM_PREAMBLE(env); + CHECK_ARG(env, object); + CHECK_ARG(env, key); + CHECK_ARG(env, value); + + auto context = env->context(); + auto obj = v8impl::V8LocalValueFromJsValue(object); + RETURN_STATUS_IF_FALSE(env, obj->IsObject(), JSVM_OBJECT_EXPECTED); + auto privateKey = v8impl::V8LocalDataFromJsData(key); + RETURN_STATUS_IF_FALSE(env, privateKey->IsPrivate(), JSVM_INVALID_ARG); + auto val = v8impl::V8LocalValueFromJsValue(value); + + auto set_maybe = obj.As()->SetPrivate(context, privateKey.As(), val); + + RETURN_STATUS_IF_FALSE_WITH_PREAMBLE(env, set_maybe.FromMaybe(false), JSVM_GENERIC_FAILURE); + return GET_RETURN_STATUS(env); +} + +JSVM_Status JSVM_CDECL OH_JSVM_GetPrivate(JSVM_Env env, + JSVM_Value object, + JSVM_Data key, + JSVM_Value *result) { + JSVM_PREAMBLE(env); + CHECK_ARG(env, object); + CHECK_ARG(env, key); + CHECK_ARG(env, result); + + auto context = env->context(); + auto obj = v8impl::V8LocalValueFromJsValue(object); + RETURN_STATUS_IF_FALSE(env, obj->IsObject(), JSVM_OBJECT_EXPECTED); + auto privateKey = v8impl::V8LocalDataFromJsData(key); + RETURN_STATUS_IF_FALSE(env, privateKey->IsPrivate(), JSVM_INVALID_ARG); + + auto getMaybe = obj.As()->GetPrivate(context, privateKey.As()); + CHECK_MAYBE_EMPTY_WITH_PREAMBLE(env, getMaybe, JSVM_GENERIC_FAILURE); + + v8::Local val = getMaybe.ToLocalChecked(); + *result = v8impl::JsValueFromV8LocalValue(val); + return GET_RETURN_STATUS(env); +} + +JSVM_Status JSVM_CDECL OH_JSVM_DeletePrivate(JSVM_Env env, + JSVM_Value object, + JSVM_Data key) { + JSVM_PREAMBLE(env); + CHECK_ARG(env, object); + CHECK_ARG(env, key); + + auto context = env->context(); + auto obj = v8impl::V8LocalValueFromJsValue(object); + RETURN_STATUS_IF_FALSE(env, obj->IsObject(), JSVM_OBJECT_EXPECTED); + auto privateKey = v8impl::V8LocalDataFromJsData(key); + RETURN_STATUS_IF_FALSE(env, privateKey->IsPrivate(), JSVM_INVALID_ARG); + + auto deleteMaybe = obj.As()->DeletePrivate(context, privateKey.As()); + auto success = deleteMaybe.IsJust() && deleteMaybe.FromMaybe(false); + RETURN_STATUS_IF_FALSE_WITH_PREAMBLE(env, success, JSVM_GENERIC_FAILURE); + return GET_RETURN_STATUS(env); +} + static inline JSVM_Status set_error_code(JSVM_Env env, v8::Local error, JSVM_Value code, @@ -3944,6 +4100,33 @@ JSVM_Status JSVM_CDECL OH_JSVM_CreateReference(JSVM_Env env, return jsvm_clear_last_error(env); } +// ref for data can not be weak, so initialRefcount must be greater than 0 +JSVM_Status JSVM_CDECL OH_JSVM_CreateDataReference(JSVM_Env env, + JSVM_Data data, + uint32_t initialRefcount, + JSVM_Ref* result) { + // Omit JSVM_PREAMBLE and GET_RETURN_STATUS because V8 calls here cannot throw + // JS exceptions. + CHECK_ENV(env); + CHECK_ARG(env, data); + CHECK_ARG(env, result); + RETURN_STATUS_IF_FALSE(env, initialRefcount != 0, JSVM_INVALID_ARG); + + v8::Local v8_value = v8impl::V8LocalDataFromJsData(data); + v8impl::Reference* reference = v8impl::Reference::New( + env, + v8_value, + initialRefcount, + v8impl::Ownership::kUserland, + nullptr, + nullptr, + nullptr, + false); + + *result = reinterpret_cast(reference); + return jsvm_clear_last_error(env); +} + // Deletes a reference. The referenced value is released, and may be GC'd unless // there are other references to it. JSVM_Status JSVM_CDECL OH_JSVM_DeleteReference(JSVM_Env env, JSVM_Ref ref) { @@ -4023,7 +4206,27 @@ JSVM_Status JSVM_CDECL OH_JSVM_GetReferenceValue(JSVM_Env env, CHECK_ARG(env, result); v8impl::Reference* reference = reinterpret_cast(ref); - *result = v8impl::JsValueFromV8LocalValue(reference->Get()); + RETURN_STATUS_IF_FALSE(env, reference->IsValue(), JSVM_INVALID_ARG); + *result = v8impl::JsValueFromV8LocalValue(reference->GetValue()); + + return jsvm_clear_last_error(env); +} + +// Attempts to get a referenced value. If the reference is weak, the value might +// no longer be available, in that case the call is still successful but the +// result is NULL. +JSVM_Status JSVM_CDECL OH_JSVM_GetReferenceData(JSVM_Env env, + JSVM_Ref ref, + JSVM_Data* result) { + // Omit JSVM_PREAMBLE and GET_RETURN_STATUS because V8 calls here cannot throw + // JS exceptions. + CHECK_ENV(env); + CHECK_ARG(env, ref); + CHECK_ARG(env, result); + + v8impl::Reference* reference = reinterpret_cast(ref); + RETURN_STATUS_IF_FALSE(env, !reference->IsValue(), JSVM_INVALID_ARG); + *result = v8impl::JsDataFromV8LocalData(reference->GetData()); return jsvm_clear_last_error(env); } @@ -5206,7 +5409,7 @@ JSVM_Status JSVM_CDECL OH_JSVM_ObjectSetPrototypeOf(JSVM_Env env, JSVM_Status JSVM_CDECL OH_JSVM_RetainScript(JSVM_Env env, JSVM_Script script) { CHECK_ENV(env); - auto jsvmData = reinterpret_cast(script); + auto jsvmData = reinterpret_cast(script); RETURN_STATUS_IF_FALSE(env, jsvmData && !jsvmData->isGlobal, JSVM_INVALID_ARG); @@ -5219,7 +5422,7 @@ JSVM_Status JSVM_CDECL OH_JSVM_RetainScript(JSVM_Env env, JSVM_Script script) { JSVM_Status JSVM_CDECL OH_JSVM_ReleaseScript(JSVM_Env env, JSVM_Script script) { CHECK_ENV(env); - auto jsvmData = reinterpret_cast(script); + auto jsvmData = reinterpret_cast(script); RETURN_STATUS_IF_FALSE(env, jsvmData && jsvmData->isGlobal, JSVM_INVALID_ARG); diff --git a/src/js_native_api_v8.h b/src/js_native_api_v8.h index 7e799c7c2..540766b63 100644 --- a/src/js_native_api_v8.h +++ b/src/js_native_api_v8.h @@ -58,13 +58,13 @@ class Finalizer; class Agent; } // end of namespace v8impl -struct JSVM_Data__ { +struct JSVM_Script_Data__ { public: using SourcePtr = std::variant, v8::Global>; using DataType = enum { kJsvmScript }; template - JSVM_Data__(T ptr, bool retained, DataType type = kJsvmScript) + JSVM_Script_Data__(T ptr, bool retained, DataType type = kJsvmScript) : taggedPointer(ptr), isGlobal(retained), type(type) {} @@ -193,11 +193,11 @@ struct JSVM_Env__ { } template - JSVM_Data__ *NewJsvmData(T srcPtr, JSVM_Data__::DataType type = JSVM_Data__::kJsvmScript) { + JSVM_Script_Data__ *NewJsvmData(T srcPtr, JSVM_Script_Data__::DataType type = JSVM_Script_Data__::kJsvmScript) { if (dataStack.empty() || open_handle_scopes != dataStack.top().first) { - dataStack.emplace(open_handle_scopes, std::vector()); + dataStack.emplace(open_handle_scopes, std::vector()); } - auto newData = new JSVM_Data__(srcPtr, false, type); + auto newData = new JSVM_Script_Data__(srcPtr, false, type); dataStack.top().second.push_back(newData); return newData; } @@ -234,7 +234,7 @@ struct JSVM_Env__ { int32_t module_api_version = NODE_API_DEFAULT_MODULE_API_VERSION; bool in_gc_finalizer = false; v8::Locker* locker = nullptr; - std::stack>> dataStack; + std::stack>> dataStack; private: v8impl::Agent* inspector_agent_; @@ -395,9 +395,19 @@ inline JSVM_Value JsValueFromV8LocalValue(v8::Local local) { return reinterpret_cast(*local); } -inline v8::Local V8LocalValueFromJsValue(JSVM_Value v) { +inline JSVM_Data JsDataFromV8LocalData(v8::Local local) { + return reinterpret_cast(*local); +} + +inline v8::Local V8LocalValueFromJsValue(JSVM_Value value) { v8::Local local; - memcpy(static_cast(&local), &v, sizeof(v)); + memcpy(static_cast(&local), &value, sizeof(JSVM_Value)); + return local; +} + +inline v8::Local V8LocalDataFromJsData(JSVM_Data data) { + v8::Local local; + memcpy(static_cast(&local), &data, sizeof(JSVM_Data)); return local; } @@ -517,16 +527,17 @@ class RefBase : public TrackedFinalizer { class Reference : public RefBase { protected: template - Reference(JSVM_Env env, v8::Local value, Args&&... args); + Reference(JSVM_Env env, v8::Local value, bool isValue, Args&&... args); public: static Reference* New(JSVM_Env env, - v8::Local value, + v8::Local value, uint32_t initialRefcount, Ownership ownership, JSVM_Finalize finalizeCallback = nullptr, void* finalizeData = nullptr, - void* finalizeHint = nullptr); + void* finalizeHint = nullptr, + bool isValue = true); virtual ~Reference(); bool HasDeletedByUser() { @@ -534,8 +545,12 @@ class Reference : public RefBase { } uint32_t Ref(); uint32_t Unref(); - v8::Local Get(); + v8::Local GetValue(); + v8::Local GetData(); void Delete(); + bool IsValue() const { + return is_value; + } protected: void Finalize() override; @@ -545,7 +560,8 @@ class Reference : public RefBase { void SetWeak(); - v8impl::Persistent persistent_; + v8impl::Persistent persistent_; + bool is_value; bool can_be_weak_; bool deleted_by_user; bool wait_callback; diff --git a/src/jsvm.h b/src/jsvm.h index b5771f107..c67ae6ef8 100644 --- a/src/jsvm.h +++ b/src/jsvm.h @@ -611,6 +611,23 @@ JSVM_EXTERN JSVM_Status OH_JSVM_CreateReference(JSVM_Env env, uint32_t initialRefcount, JSVM_Ref* result); +/** + * @brief This API creates a new reference with the specified reference count to the data passed in. + * + * @param env The environment that the API is invoked under. + * @param value The JSVM_Data for which a reference is being created. + * @param initialRefcount Initial reference count for the new reference. + * @param result JSVM_Ref pointing to the new reference. + * @return Returns JSVM funtions result code. + * {@link JSVM_OK } if the function executed successfully.\n + * {@link JSVM_INVALID_ARG } if any parameter is null or the value of initialRefcount is 0.\n + * @since 16 + */ +JSVM_EXTERN JSVM_Status OH_JSVM_CreateDataReference(JSVM_Env env, + JSVM_Data data, + uint32_t initialRefcount, + JSVM_Ref* result); + /** * @brief his API deletes the reference passed in. * @@ -668,6 +685,23 @@ JSVM_EXTERN JSVM_Status OH_JSVM_GetReferenceValue(JSVM_Env env, JSVM_Ref ref, JSVM_Value* result); +/** + * @brief If still valid, this API returns the JSVM_Data representing the + * JavaScript data associated with the JSVM_Ref. Otherwise, result will be NULL. + * + * @param env The environment that the API is invoked under. + * @param ref The JSVM_Ref for which the corresponding value is being requested. + * @param result The JSVM_Data referenced by the JSVM_Ref. + * @return Returns JSVM funtions result code. + * {@link JSVM_OK } if the function executed successfully.\n + * {@link JSVM_INVALID_ARG } if any parameter is null or the ref is not a reference to JSVM_Data.\n + * + * @since 16 + */ +JSVM_EXTERN JSVM_Status OH_JSVM_GetReferenceData(JSVM_Env env, + JSVM_Ref ref, + JSVM_Data* result); + /** * @brief This API returns a JSVM-API value corresponding to a JavaScript Array type. * @@ -851,6 +885,81 @@ JSVM_EXTERN JSVM_Status OH_JSVM_SymbolFor(JSVM_Env env, size_t length, JSVM_Value* result); +/** + * @brief This API creates a JavaScript private key. + * + * @param env The environment that the API is invoked under. + * @param description Optional JSVM_Value which refers to a JavaScript string to be set as the description + * for the private key. + * @param result A JSVM_Data representing a JavaScript private key. + * @return Returns JSVM funtions result code. + * {@link JSVM_OK } if the function executed successfully.\n + * {@link JSVM_INVALID_ARG } if env or result is NULL.\n + * {@link JSVM_STRING_EXPECTED } if the description is not a string.\n + * @since 16 + */ +JSVM_EXTERN JSVM_Status OH_JSVM_CreatePrivate(JSVM_Env env, + JSVM_Value description, + JSVM_Data* result); + +/** + * @brief This API set a private property on the Object passed in. + * + * @param env The environment that the API is invoked under. + * @param object The object on which to set the private property. + * @param key The private key of the property. + * @param value The private property value. + * @return Returns JSVM funtions result code. + * {@link JSVM_OK } if the function executed successfully.\n + * {@link JSVM_INVALID_ARG } if any of the arguments is NULL or the key is not a private key.\n + * {@link JSVM_OBJECT_EXPECTED } object passed in is not a real object.\n + * {@link JSVM_GENERIC_FAILURE } if failed to set the private key but no exception is pending.\n + * {@link JSVM_PENDING_EXCPTION } if an exception occurs.\n + * @since 16 + */ +JSVM_EXTERN JSVM_Status OH_JSVM_SetPrivate(JSVM_Env env, + JSVM_Value object, + JSVM_Data key, + JSVM_Value value); + +/** + * @brief This API gets the requested private property from the Object passed in. + * + * @param env The environment that the API is invoked under. + * @param object The object from which to retrieve the private property. + * @param key The private key of the property. + * @param result The value of the private property. + * @return Returns JSVM funtions result code. + * {@link JSVM_OK } if the function executed successfully.\n + * {@link JSVM_INVALID_ARG } if any of the arguments is NULL or the key is not a private key.\n + * {@link JSVM_OBJECT_EXPECTED } object passed in is not a real object.\n + * {@link JSVM_GENERIC_FAILURE } if failed to get the private key but no exception is pending.\n + * {@link JSVM_PENDING_EXCPTION } if an exception occurs.\n + * @since 16 + */ +JSVM_EXTERN JSVM_Status OH_JSVM_GetPrivate(JSVM_Env env, + JSVM_Value object, + JSVM_Data key, + JSVM_Value *result); + +/** + * @brief This API attempts to delete the property of the private key from object. + * + * @param env The environment that the API is invoked under. + * @param object The object to query. + * @param key The private key of the property to delete. + * @return Returns JSVM funtions result code. + * {@link JSVM_OK } if the function executed successfully.\n + * {@link JSVM_INVALID_ARG } if any of the arguments is NULL or the key is not a private key.\n + * {@link JSVM_OBJECT_EXPECTED } object passed in is not a real object.\n + * {@link JSVM_GENERIC_FAILURE } if failed to delete the private key but no exception is pending.\n + * {@link JSVM_PENDING_EXCPTION } if an exception occurs.\n + * @since 16 + */ +JSVM_EXTERN JSVM_Status OH_JSVM_DeletePrivate(JSVM_Env env, + JSVM_Value object, + JSVM_Data key); + /** * @brief This API creates a JavaScript TypedArray object over an existing ArrayBuffer. TypedArray * objects provide an array-like view over an underlying data buffer where each element has the @@ -1050,6 +1159,58 @@ JSVM_EXTERN JSVM_Status OH_JSVM_CreateStringUtf8(JSVM_Env env, const char* str, size_t length, JSVM_Value* result); +/** + * @brief This API creates an external JavaScript string value from an ISO-8859-1-encoded C + * string. The native string is copied when failed to create external string. + * + * @param env The environment that the API is invoked under. + * @param str Character buffer representing an ISO-8859-1-encoded string. + * @param length The length of the string in bytes, or JSVM_AUTO_LENGTH if it is null-terminated. + * @param finalizeCb Optional callback to call when the external value is being collected. + * JSVM_Finalize provides more details. + * @param finalizeHint Optional hint to pass to the finalize callback during collection. + * @param result A JSVM_Value representing a JavaScript external string. + * @param copied flag indicate whether the external string is successfully created, + * true for faild to create external ones and fall back to non-external strings, false for success. + * @return Returns JSVM funtions result code. + * Returns {@link JSVM_OK } if the function executed successfully.\n + * Returns {@link JSVM_INVALID_ARG } if one of env, str and copied is NULL.\n + * @since 12 + */ +JSVM_Status JSVM_CDECL OH_JSVM_CreateExternalStringLatin1(JSVM_Env env, + char* str, + size_t length, + JSVM_Finalize finalizeCallback, + void* finalizeHint, + JSVM_Value* result, + bool* copied); + +/** + * @brief This API creates an external JavaScript string value from an UTF16-LE-encoded C + * string. The native string is copied when failed to create external string. + * + * @param env The environment that the API is invoked under. + * @param str Character buffer representing an UTF16-LE-encoded string. + * @param length The length of the string in bytes, or JSVM_AUTO_LENGTH if it is null-terminated. + * @param finalizeCb Optional callback to call when the external value is being collected. + * JSVM_Finalize provides more details. + * @param finalizeHint Optional hint to pass to the finalize callback during collection. + * @param result A JSVM_Value representing a JavaScript external string. + * @param copied flag indicate whether the external string is successfully created, + * true for faild to create external ones and fall back to non-external strings, false for success. + * @return Returns JSVM funtions result code. + * Returns {@link JSVM_OK } if the function executed successfully.\n + * Returns {@link JSVM_INVALID_ARG } if one of env, str and copied is NULL.\n + * @since 12 + */ + +JSVM_Status JSVM_CDECL OH_JSVM_CreateExternalStringUtf16(JSVM_Env env, + char16_t* str, + size_t length, + JSVM_Finalize finalizeCallback, + void* finalizeHint, + JSVM_Value* result, + bool* copied); /** * @brief This API returns the length of an array. diff --git a/src/jsvm_types.h b/src/jsvm_types.h index 4ee1793b3..6e0812ca8 100644 --- a/src/jsvm_types.h +++ b/src/jsvm_types.h @@ -108,6 +108,13 @@ typedef struct JSVM_CpuProfiler__* JSVM_CpuProfiler; */ typedef struct JSVM_Value__* JSVM_Value; +/** + * @brief To represent a JavaScript Data type. + * + * @since 16 + */ +typedef struct JSVM_Data__* JSVM_Data; + /** * @brief To represent a JavaScript value references. * -- Gitee