diff --git a/DesktopEditor/doctrenderer/js_internal/v8/v8_base.cpp b/DesktopEditor/doctrenderer/js_internal/v8/v8_base.cpp index 5e8efbc50a..bacd5dedac 100644 --- a/DesktopEditor/doctrenderer/js_internal/v8/v8_base.cpp +++ b/DesktopEditor/doctrenderer/js_internal/v8/v8_base.cpp @@ -214,8 +214,9 @@ namespace NSJSBase m_internal->m_contextPersistent.Reset(isolate, v8::Context::New(isolate)); // create temporary local handle to context m_internal->m_context = v8::Local::New(isolate, m_internal->m_contextPersistent); - // insert CreateEmbedObject() function to global object of this context + // insert embed functions to global object of this context m_internal->InsertToGlobal("CreateEmbedObject", CreateEmbedNativeObject); + m_internal->InsertToGlobal("FreeEmbedObject", FreeNativeObject); // clear temporary local handle m_internal->m_context.Clear(); } @@ -689,4 +690,22 @@ namespace NSJSBase NSJSBase::CJSEmbedObjectPrivate::CreateWeaker(obj); args.GetReturnValue().Set(obj); } + + void FreeNativeObject(const v8::FunctionCallbackInfo& args) + { + v8::Isolate* isolate = args.GetIsolate(); + v8::HandleScope scope(isolate); + + if (args.Length() != 1) + { + args.GetReturnValue().Set(v8::Undefined(isolate)); + return; + } + + v8::Local obj = args[0].As(); + v8::Local field = v8::Local::Cast(obj->GetInternalField(0)); + CJSEmbedObject* native = static_cast(field->Value()); + delete native; + // weak persistent handle will be cleared and removed in CJSEmbedObjectPrivate destructor + } } diff --git a/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h b/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h index 2300c3228a..f6a424bca6 100644 --- a/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h +++ b/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h @@ -883,6 +883,7 @@ namespace NSJSBase // embed void CreateEmbedNativeObject(const v8::FunctionCallbackInfo& args); + void FreeNativeObject(const v8::FunctionCallbackInfo& args); class CJSEmbedObjectAdapterV8Template : public CJSEmbedObjectAdapterBase { diff --git a/DesktopEditor/doctrenderer/test/embed/external/main.cpp b/DesktopEditor/doctrenderer/test/embed/external/main.cpp index 538e819a35..572d24afdf 100644 --- a/DesktopEditor/doctrenderer/test/embed/external/main.cpp +++ b/DesktopEditor/doctrenderer/test/embed/external/main.cpp @@ -5,10 +5,10 @@ int main() // TODO: test // testMultipleContexts(); - // testEmbedExternal(); + testEmbedExternal(); // testEmbedInternal(); // testHashEmbed(); - testEmbedMixed(); + // testEmbedMixed(); return 0; } diff --git a/DesktopEditor/doctrenderer/test/embed/external/test_functions.cpp b/DesktopEditor/doctrenderer/test/embed/external/test_functions.cpp index d3b4096495..b4cc5424e5 100644 --- a/DesktopEditor/doctrenderer/test/embed/external/test_functions.cpp +++ b/DesktopEditor/doctrenderer/test/embed/external/test_functions.cpp @@ -98,16 +98,16 @@ void testEmbedExternal() CJSContextScope scope(context); CJSContext::Embed(); - JSSmart res1 = context->runScript("(function() { let value = CreateEmbedObject('CTestEmbed'); let ret = value.FunctionSum(10, 5); return ret; })();"); + JSSmart res1 = context->runScript("(function() { let value = CreateEmbedObject('CTestEmbed'); let ret = value.FunctionSum(10, 5); FreeEmbedObject(value); return ret; })();"); std::cout << "FunctionSum(10, 5) = " << res1->toInt32() << std::endl; - JSSmart res2 = context->runScript("(function() { let value = CreateEmbedObject('CTestEmbed'); let ret = value.FunctionSquare(4); return ret; })();"); + JSSmart res2 = context->runScript("(function() { let value = CreateEmbedObject('CTestEmbed'); let ret = value.FunctionSquare(4); FreeEmbedObject(value); return ret; })();"); std::cout << "FunctionSquare(4) = " << res2->toInt32() << std::endl; - JSSmart res3 = context->runScript("(function() { let value = CreateEmbedObject('CTestEmbed'); let ret = value.FunctionDel(30, 3); return ret; })();"); + JSSmart res3 = context->runScript("(function() { let value = CreateEmbedObject('CTestEmbed'); let ret = value.FunctionDel(30, 3); FreeEmbedObject(value); return ret; })();"); std::cout << "FunctionDel(30, 3) = " << res3->toInt32() << std::endl; - JSSmart res4 = context->runScript("(function() { let value = CreateEmbedObject('CTestEmbed'); let ret = value.FunctionGet(); return ret; })();"); + JSSmart res4 = context->runScript("(function() { let value = CreateEmbedObject('CTestEmbed'); let ret = value.FunctionGet(); FreeEmbedObject(value); return ret; })();"); std::cout << "FunctionGet() = " << res4->toInt32() << std::endl; }