From e1f42316a71f86b07341ee4614e11a2c65531dbb Mon Sep 17 00:00:00 2001 From: linbin Date: Tue, 28 Sep 2021 10:22:01 +0800 Subject: [PATCH] check and modify code with memory leaks. Signed-off-by: linbin Change-Id: Ica6d5443b98b2f5c7c112a09826f9a50ff856f55 --- .../impl/jerryscript/jerryscript_ext.cpp | 58 ++++++++++++------- .../jerryscript/jerryscript_native_engine.cpp | 35 +++++------ .../native_value/jerryscript_native_array.cpp | 14 ++++- .../jerryscript_native_array_buffer.cpp | 30 +++++++++- .../jerryscript_native_external.cpp | 4 +- .../jerryscript_native_function.cpp | 15 +++-- .../jerryscript_native_object.cpp | 52 ++++++++--------- .../jerryscript_native_string.cpp | 1 + .../jerryscript_native_typed_array.cpp | 18 +++++- 9 files changed, 147 insertions(+), 80 deletions(-) diff --git a/native_engine/impl/jerryscript/jerryscript_ext.cpp b/native_engine/impl/jerryscript/jerryscript_ext.cpp index 50efd8ac0..1228916c6 100644 --- a/native_engine/impl/jerryscript/jerryscript_ext.cpp +++ b/native_engine/impl/jerryscript/jerryscript_ext.cpp @@ -30,8 +30,11 @@ static jerry_object_native_info_t g_objectNativeInfo = { .free_cb = [](void *nativePointer) { auto externalCtx = (jerry_external_context*)nativePointer; if (externalCtx != nullptr) { - externalCtx->callback(externalCtx->value, externalCtx->hint); + if (externalCtx->callback != nullptr) { + externalCtx->callback(externalCtx->value, externalCtx->hint); + } delete externalCtx; + externalCtx = nullptr; } } }; @@ -39,46 +42,56 @@ static jerry_object_native_info_t g_objectNativeInfo = { bool jerry_add_external() { + bool result = false; auto callback = [](const jerry_value_t function, const jerry_value_t thisVal, const jerry_value_t args[], - const jerry_length_t argc) -> jerry_value_t - { - return jerry_create_boolean(true); - }; + const jerry_length_t argc) + -> jerry_value_t + { + return jerry_acquire_value(thisVal); + }; + auto global = jerry_get_global_object(); auto constructor = jerry_create_external_function(callback); auto prototype = jerry_create_object(); - - jerry_value_t propName = jerry_create_string_from_utf8 ((const jerry_char_t*)"prototype"); - jerry_value_t resultVal = jerry_set_property (constructor, propName, prototype); - jerry_release_value (propName); - - if (!jerry_value_to_boolean(resultVal)) { + auto resultVal = jerryx_set_property_str(constructor, "prototype", prototype); + + if (jerry_value_is_error(resultVal)) { HILOG_ERROR("jerry_add_external failed"); - return false; + } else { + auto setExternalRet = jerryx_set_property_str(global, "External", constructor); + if (jerry_value_is_error(setExternalRet)) { + HILOG_ERROR("jerry_add_external failed"); + } else { + result = true; + } + jerry_release_value(setExternalRet); } - - jerry_value_t global = jerry_get_global_object(); - jerryx_set_property_str(global, "External", constructor); + jerry_release_value(resultVal); + jerry_release_value(prototype); + jerry_release_value(constructor); jerry_release_value(global); - return true; + return result; } jerry_value_t jerry_create_external(void* value, jerry_finalizer_t finalizer, void* hint) { - auto externalCtx = new jerry_external_context { + auto externalCtx = new jerry_external_context{ .value = value, .callback = finalizer, .hint = hint, }; + + jerry_value_t object = 0; jerry_value_t global = jerry_get_global_object(); jerry_value_t external = jerryx_get_property_str(global, "External"); - jerry_value_t object = jerry_create_undefined(); if (!jerry_value_is_undefined(external)) { object = jerry_construct_object(external, nullptr, 0); jerry_set_object_native_pointer(object, (void*)externalCtx, &g_objectNativeInfo); + } else { + object = jerry_create_undefined(); } jerry_release_value(external); @@ -89,23 +102,24 @@ jerry_value_t jerry_create_external(void* value, jerry_finalizer_t finalizer, vo bool jerry_value_is_external(const jerry_value_t object) { + bool result = false; jerry_value_t global = jerry_get_global_object(); jerry_value_t external = jerryx_get_property_str(global, "External"); - jerry_value_t op = jerry_create_boolean(false); if (!jerry_value_is_undefined(external)) { - op = jerry_binary_operation(JERRY_BIN_OP_INSTANCEOF, object, external); + jerry_value_t op = jerry_binary_operation(JERRY_BIN_OP_INSTANCEOF, object, external); + result = jerry_get_boolean_value(op); + jerry_release_value(op); } jerry_release_value(external); jerry_release_value(global); - return jerry_get_boolean_value(op); + return result; } void* jerry_value_get_external(const jerry_value_t object) { jerry_external_context* externalCtx = nullptr; - jerry_get_object_native_pointer(object, (void**)&externalCtx, &g_objectNativeInfo); if (externalCtx != nullptr) { return externalCtx->value; diff --git a/native_engine/impl/jerryscript/jerryscript_native_engine.cpp b/native_engine/impl/jerryscript/jerryscript_native_engine.cpp index d2065f05b..c38d1b670 100644 --- a/native_engine/impl/jerryscript/jerryscript_native_engine.cpp +++ b/native_engine/impl/jerryscript/jerryscript_native_engine.cpp @@ -191,18 +191,17 @@ NativeValue* JerryScriptNativeEngine::CreatePromise(NativeDeferred** deferred) NativeValue* JerryScriptNativeEngine::CreateError(NativeValue* code, NativeValue* message) { jerry_value_t jerror = 0; - jerry_value_t jcode = 0; jerror = jerry_create_error_sz(JERRY_ERROR_COMMON, nullptr, 0); jerror = jerry_get_value_from_error(jerror, true); if (message) { - jerry_value_t jreturn = jerryx_set_property_str(jerror, "message", *message); - jerry_release_value(jreturn); + auto result = jerryx_set_property_str(jerror, "message", *message); + jerry_release_value(result); } if (code) { - jerry_value_t jreturn = jerryx_set_property_str(jerror, "code", *code); - jerry_release_value(jreturn); + auto result = jerryx_set_property_str(jerror, "code", *code); + jerry_release_value(result); } jerror = jerry_create_error_from_value(jerror, true); @@ -234,12 +233,6 @@ NativeValue* JerryScriptNativeEngine::CallFunction(NativeValue* thisVar, if (jerry_value_is_error(result)) { jerry_value_t errorObj = jerry_get_value_from_error(result, true); - jerry_value_t propName = jerry_create_string_from_utf8((const jerry_char_t*)"message"); - jerry_property_descriptor_t propDescriptor = { 0 }; - jerry_get_own_property_descriptor(errorObj, propName, &propDescriptor); - jerry_value_t setResult = jerry_set_property(errorObj, propName, propDescriptor.value); - jerry_release_value(propName); - jerry_release_value(setResult); Throw(JerryValueToNativeValue(this, errorObj)); return JerryValueToNativeValue(this, jerry_create_undefined()); } else { @@ -255,14 +248,19 @@ NativeValue* JerryScriptNativeEngine::RunScript(NativeValue* script) if (length == 0) { return nullptr; } - char* strScript = new char[length] { 0 }; - pscript->GetCString(strScript, length, &length); + char* strScript = new char[length + 1] { 0 }; + pscript->GetCString(strScript, length + 1, &length); jerry_value_t result = jerry_eval((const unsigned char*)strScript, pscript->GetLength(), JERRY_PARSE_NO_OPTS); + delete []strScript; + if (jerry_value_is_error(result)) { - result = jerry_get_value_from_error(result, true); + return JerryValueToNativeValue(this, jerry_get_value_from_error(result, true)); + } else if (this->IsExceptionPending()) { + jerry_release_value(result); + return GetAndClearLastException(); + } else { + return JerryValueToNativeValue(this, result); } - delete []strScript; - return JerryValueToNativeValue(this, result); } NativeValue* JerryScriptNativeEngine::RunBufferScript(std::vector& buffer) @@ -293,7 +291,8 @@ NativeValue* JerryScriptNativeEngine::DefineClass(const char* name, NativeValue* JerryScriptNativeEngine::CreateInstance(NativeValue* constructor, NativeValue* const* argv, size_t argc) { - return JerryValueToNativeValue(this, jerry_construct_object(*constructor, (const jerry_value_t*)argv, argc)); + jerry_value_t value = jerry_construct_object(*constructor, (const jerry_value_t*)argv, argc); + return JerryValueToNativeValue(this, value); } NativeReference* JerryScriptNativeEngine::CreateReference(NativeValue* value, uint32_t initialRefcount) @@ -329,9 +328,11 @@ bool JerryScriptNativeEngine::Throw(NativeErrorType type, const char* code, cons if (code) { jerry_value_t jcode = jerry_create_string_from_utf8((const unsigned char*)code); jerryx_set_property_str(jerror, "code", jcode); + jerry_release_value(jcode); } jerror = jerry_create_error_from_value(jerror, true); this->lastException_ = new JerryScriptNativeObject(this, jerror); + return true; } diff --git a/native_engine/impl/jerryscript/native_value/jerryscript_native_array.cpp b/native_engine/impl/jerryscript/native_value/jerryscript_native_array.cpp index e77642957..10fb2309e 100644 --- a/native_engine/impl/jerryscript/native_value/jerryscript_native_array.cpp +++ b/native_engine/impl/jerryscript/native_value/jerryscript_native_array.cpp @@ -35,14 +35,24 @@ void* JerryScriptNativeArray::GetInterface(int interfaceId) bool JerryScriptNativeArray::SetElement(uint32_t index, NativeValue* value) { - jerry_value_t returnValue = jerry_set_property_by_index(value_, index, value_); + bool result = true; + jerry_value_t returnValue = jerry_set_property_by_index(value_, index, *value); + if (jerry_value_is_error(returnValue)) { + result = false; + } jerry_release_value(returnValue); - return true; + return result; } NativeValue* JerryScriptNativeArray::GetElement(uint32_t index) { + bool result = true; jerry_value_t returnValue = jerry_get_property_by_index(value_, index); + if (jerry_value_is_error(returnValue)) { + result = false; + jerry_release_value(returnValue); + return nullptr; + } return JerryScriptNativeEngine::JerryValueToNativeValue(engine_, returnValue); } diff --git a/native_engine/impl/jerryscript/native_value/jerryscript_native_array_buffer.cpp b/native_engine/impl/jerryscript/native_value/jerryscript_native_array_buffer.cpp index 0e7eeeaa0..0043f2eab 100644 --- a/native_engine/impl/jerryscript/native_value/jerryscript_native_array_buffer.cpp +++ b/native_engine/impl/jerryscript/native_value/jerryscript_native_array_buffer.cpp @@ -15,6 +15,27 @@ #include "jerryscript_native_array_buffer.h" +struct JerryScriptNativeArrayBufferContext { + JerryScriptNativeEngine* engine = nullptr; + void* data = nullptr; + NativeFinalize callback = nullptr; + void* hint = nullptr; +}; + +static jerry_object_native_info_t g_nativeInfo = { + .free_cb = + [](void* pointer) { + auto arrayBufferCtx = reinterpret_cast(pointer); + if (arrayBufferCtx != nullptr) { + if (arrayBufferCtx->callback != nullptr) { + arrayBufferCtx->callback(arrayBufferCtx->engine, arrayBufferCtx->data, arrayBufferCtx->hint); + } + delete arrayBufferCtx; + arrayBufferCtx = nullptr; + } + }, +}; + JerryScriptNativeArrayBuffer::JerryScriptNativeArrayBuffer(JerryScriptNativeEngine* engine, jerry_value_t value) : JerryScriptNativeObject(engine, value) { @@ -33,7 +54,14 @@ JerryScriptNativeArrayBuffer::JerryScriptNativeArrayBuffer(JerryScriptNativeEngi void* hint) : JerryScriptNativeArrayBuffer(engine, 0) { - value_ = jerry_create_arraybuffer_external(length, (uint8_t*)value, [](void* nativePoint) { free(nativePoint); }); + value_ = jerry_create_arraybuffer_external(length, (uint8_t*)value, [](void* native_point) {}); + auto arrayBufferCtx = new JerryScriptNativeArrayBufferContext{ + .engine = engine, + .data = value, + .callback = callback, + .hint = hint, + }; + jerry_set_object_native_pointer(value_, arrayBufferCtx, &g_nativeInfo); } JerryScriptNativeArrayBuffer::~JerryScriptNativeArrayBuffer() {} diff --git a/native_engine/impl/jerryscript/native_value/jerryscript_native_external.cpp b/native_engine/impl/jerryscript/native_value/jerryscript_native_external.cpp index e33d23616..d33ac1c9a 100644 --- a/native_engine/impl/jerryscript/native_value/jerryscript_native_external.cpp +++ b/native_engine/impl/jerryscript/native_value/jerryscript_native_external.cpp @@ -32,7 +32,9 @@ JerryScriptNativeExternal::JerryScriptNativeExternal(JerryScriptNativeEngine* en [](void* data, void* hint) { auto info = reinterpret_cast(data); if (info != nullptr) { - info->callback(info->engine, info->nativeObject, info->hint); + if (info->callback != nullptr) { + info->callback(info->engine, info->nativeObject, info->hint); + } delete info; } }, diff --git a/native_engine/impl/jerryscript/native_value/jerryscript_native_function.cpp b/native_engine/impl/jerryscript/native_value/jerryscript_native_function.cpp index 864f18e98..d18f1e5fc 100644 --- a/native_engine/impl/jerryscript/native_value/jerryscript_native_function.cpp +++ b/native_engine/impl/jerryscript/native_value/jerryscript_native_function.cpp @@ -69,13 +69,16 @@ jerry_value_t JerryScriptNativeFunction::NativeFunctionCallback(const jerry_valu if (argc > 0) { callbackInfo.argv = new NativeValue*[argc]; - for (uint32_t i = 0; i < argc; i++) { - callbackInfo.argv[i] = - JerryScriptNativeEngine::JerryValueToNativeValue(engine, jerry_acquire_value(args[i])); - } } - - NativeValue* result = functionInfo->callback(functionInfo->engine, &callbackInfo); + for (uint32_t i = 0; i < argc; i++) { + callbackInfo.argv[i] = JerryScriptNativeEngine::JerryValueToNativeValue(engine, args[i]); + jerry_acquire_value(args[i]); + } + + NativeValue* result = nullptr; + if (functionInfo->callback) { + functionInfo->callback(functionInfo->engine, &callbackInfo); + } if (callbackInfo.argv != nullptr) { delete[] callbackInfo.argv; diff --git a/native_engine/impl/jerryscript/native_value/jerryscript_native_object.cpp b/native_engine/impl/jerryscript/native_value/jerryscript_native_object.cpp index 2d5320e8d..b79644a95 100644 --- a/native_engine/impl/jerryscript/native_value/jerryscript_native_object.cpp +++ b/native_engine/impl/jerryscript/native_value/jerryscript_native_object.cpp @@ -30,10 +30,16 @@ namespace { jerry_object_native_info_t g_freeCallback = { .free_cb = [](void* nativePointer) -> void { auto info = (JerryScriptNativeObjectInfo*)nativePointer; - if (info != nullptr) { + if (info == nullptr) { + return; + } + + if (info->cb != nullptr) { info->cb(info->engine, info->data, info->hint); - delete info; } + + delete info; + info = nullptr; }, }; } // namespace @@ -133,11 +139,15 @@ bool JerryScriptNativeObject::DefineProperty(NativePropertyDescriptor propertyDe prop.is_writable_defined = true; } + bool result = true; jerry_value_t returnValue = jerry_define_own_property(value_, propName, &prop); + jerry_type_t returnValueType = jerry_value_get_type(returnValue); + if (jerry_value_is_error(returnValueType)) { + result = false; + } jerry_release_value(returnValue); jerry_release_value(propName); - - return true; + return result; } bool JerryScriptNativeObject::SetProperty(NativeValue* key, NativeValue* value) @@ -168,9 +178,13 @@ bool JerryScriptNativeObject::DeleteProperty(NativeValue* key) bool JerryScriptNativeObject::SetProperty(const char* name, NativeValue* value) { + bool result = true; jerry_value_t returnValue = jerryx_set_property_str(value_, name, *value); + if (jerry_value_is_error(returnValue)) { + result = false; + } jerry_release_value(returnValue); - return true; + return result; } NativeValue* JerryScriptNativeObject::GetProperty(const char* name) @@ -181,8 +195,7 @@ NativeValue* JerryScriptNativeObject::GetProperty(const char* name) bool JerryScriptNativeObject::HasProperty(const char* name) { - bool result = jerryx_has_property_str(value_, name); - return result; + return jerryx_has_property_str(value_, name); } bool JerryScriptNativeObject::DeleteProperty(const char* name) @@ -195,37 +208,20 @@ bool JerryScriptNativeObject::DeleteProperty(const char* name) bool JerryScriptNativeObject::SetPrivateProperty(const char* name, NativeValue* value) { - bool result = false; - jerry_value_t key = jerry_create_string_from_utf8((const unsigned char*)name); - result = jerry_set_property(value_, key, *value); - jerry_release_value(key); - return result; + return SetProperty(name, value); } NativeValue* JerryScriptNativeObject::GetPrivateProperty(const char* name) { - jerry_value_t result = 0; - jerry_value_t key = jerry_create_string_from_utf8((const unsigned char*)name); - result = jerry_get_property(value_, key); - jerry_release_value(key); - return JerryScriptNativeEngine::JerryValueToNativeValue(engine_, result); + return GetProperty(name); } bool JerryScriptNativeObject::HasPrivateProperty(const char* name) { - jerry_value_t key = jerry_create_string_from_utf8((const unsigned char*)name); - jerry_value_t returnValue = jerry_has_property(value_, key); - bool result = jerry_value_to_boolean(returnValue); - jerry_release_value(returnValue); - jerry_release_value(key); - return result; + return HasProperty(name); } bool JerryScriptNativeObject::DeletePrivateProperty(const char* name) { - bool result = false; - jerry_value_t key = jerry_create_string_from_utf8((const unsigned char*)name); - result = jerry_delete_property(value_, key); - jerry_release_value(key); - return result; + return DeleteProperty(name); } \ No newline at end of file diff --git a/native_engine/impl/jerryscript/native_value/jerryscript_native_string.cpp b/native_engine/impl/jerryscript/native_value/jerryscript_native_string.cpp index 1ed4ca961..78968ba85 100644 --- a/native_engine/impl/jerryscript/native_value/jerryscript_native_string.cpp +++ b/native_engine/impl/jerryscript/native_value/jerryscript_native_string.cpp @@ -38,6 +38,7 @@ void JerryScriptNativeString::GetCString(char* buffer, size_t size, size_t* leng *length = GetLength(); } else { *length = jerry_string_to_utf8_char_buffer(value_, (jerry_char_t*)buffer, size); + buffer[*length] = '\0'; } } diff --git a/native_engine/impl/jerryscript/native_value/jerryscript_native_typed_array.cpp b/native_engine/impl/jerryscript/native_value/jerryscript_native_typed_array.cpp index 450212e88..468a33636 100644 --- a/native_engine/impl/jerryscript/native_value/jerryscript_native_typed_array.cpp +++ b/native_engine/impl/jerryscript/native_value/jerryscript_native_typed_array.cpp @@ -42,21 +42,27 @@ JerryScriptNativeTypedArray::JerryScriptNativeTypedArray(JerryScriptNativeEngine break; case NATIVE_INT16_ARRAY: jtype = JERRY_TYPEDARRAY_INT16; + length = length / 2; break; case NATIVE_UINT16_ARRAY: jtype = JERRY_TYPEDARRAY_UINT16; + length = length / 2; break; case NATIVE_INT32_ARRAY: jtype = JERRY_TYPEDARRAY_INT32; + length = length / 4; break; case NATIVE_UINT32_ARRAY: jtype = JERRY_TYPEDARRAY_UINT32; + length = length / 4; break; case NATIVE_FLOAT32_ARRAY: jtype = JERRY_TYPEDARRAY_FLOAT32; + length = length / 4; break; case NATIVE_FLOAT64_ARRAY: jtype = JERRY_TYPEDARRAY_FLOAT64; + length = length / 8; break; default:; } @@ -109,24 +115,30 @@ NativeTypedArrayType JerryScriptNativeTypedArray::GetTypedArrayType() size_t JerryScriptNativeTypedArray::GetLength() { - return jerry_get_typedarray_length(value_); + size_t byteLength = 0; + jerry_value_t arrayBuffer = jerry_get_typedarray_buffer(value_, nullptr, (jerry_length_t *)&byteLength); + jerry_release_value(arrayBuffer); + return byteLength; } NativeValue* JerryScriptNativeTypedArray::GetArrayBuffer() { - return new JerryScriptNativeArrayBuffer(engine_, jerry_get_typedarray_buffer(value_, nullptr, nullptr)); + jerry_value_t arrayBuffer = jerry_get_typedarray_buffer(value_, nullptr, nullptr); + return new JerryScriptNativeArrayBuffer(engine_, arrayBuffer); } void* JerryScriptNativeTypedArray::GetData() { jerry_value_t arrayBuffer = jerry_get_typedarray_buffer(value_, nullptr, nullptr); uint8_t* pointer = jerry_get_arraybuffer_pointer(arrayBuffer); + jerry_release_value(arrayBuffer); return pointer; } size_t JerryScriptNativeTypedArray::GetOffset() { size_t offset = 0; - jerry_get_typedarray_buffer(value_, (unsigned int*)&offset, nullptr); + jerry_value_t arrayBuffer = jerry_get_typedarray_buffer(value_, (unsigned int*)&offset, nullptr); + jerry_release_value(arrayBuffer); return offset; } -- Gitee