Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -212,10 +212,10 @@ jobs:
build/ScriptXTestLibs
build/googletest-src
- name: Setup Emscripten
uses: mymindstorm/setup-emsdk@v8
uses: mymindstorm/setup-emsdk@v11
with:
version: '2.0.5'
actions-cache-folder: 'emsdk-cache'
version: '3.0.0'
actions-cache-folder: 'emsdk-cache-3.0.0'
- name: Setup Node.js
uses: actions/setup-node@v1
with:
Expand All @@ -236,4 +236,4 @@ jobs:
run: |
cd build
# exclude failed tests
node UnitTests.js '--gtest_filter=-ThreadPool.*:EngineScopeTest.ExitEngine:EngineScopeTest.TwoThreads:EngineScopeTest.ThreadLocal:MessageQueue.Interrupt:MessageQueue.Shutdown:MessageQueue.ShutdownNow:MessageQueue.FullAndPostInsideLoopQueue:ReferenceTest.WeakGc:ReferenceTest.WeakGc:ReferenceTest.GlobalNotClear:ReferenceTest.GlobalOnEngineDestroy:ReferenceTest.WeakOnEngineDestroy:ReferenceTest.WeakNotClrear:ManagedObjectTest.EngineDispose:ManagedObjectTest.FunctionCallback:PressureTest.All:EngineTest.JsPromiseTest'
node UnitTests.js '--gtest_filter=-ThreadPool.*:EngineScopeTest.ExitEngine:EngineScopeTest.TwoThreads:EngineScopeTest.ThreadLocal:MessageQueue.Interrupt:MessageQueue.Shutdown:MessageQueue.ShutdownNow:MessageQueue.FullAndPostInsideLoopQueue:ReferenceTest.WeakGc:ReferenceTest.WeakGc:ReferenceTest.GlobalNotClear:ReferenceTest.GlobalOnEngineDestroy:ReferenceTest.WeakOnEngineDestroy:ReferenceTest.WeakNotClrear:ManagedObjectTest.EngineDispose:ManagedObjectTest.FunctionCallback:PressureTest.All:EngineTest.JsPromiseTest:ShowCaseTest.SetTimeout'
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@

---
Version 3.2.0 (2021-12):
1. fix QuickJs memory leak, engine instance not deleted on destroy
2. fix QuickJs missing EngineScope when run micro task (Promise)

Version 3.1.0 (2021-04):
1. add QuickJs backend
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.1.0
3.2.0
4 changes: 1 addition & 3 deletions backend/WebAssembly/WasmEngine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@

namespace script::wasm_backend {

std::thread::id WasmEngine::engineThreadId_{};

WasmEngine::WasmEngine() { engineThreadId_ = std::this_thread::get_id(); }

WasmEngine* WasmEngine::instance() {
Expand All @@ -49,7 +47,7 @@ void WasmEngine::destroy() {

bool WasmEngine::isDestroying() const { return false; }

void WasmEngine::unitTestResetRetistry() {
void WasmEngine::unitTestResetRegistry() {
classDefineRegistry_.clear();
ScriptEngine::classDefineRegistry_.clear();
}
Expand Down
4 changes: 2 additions & 2 deletions backend/WebAssembly/WasmEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ class WasmEngine : public ScriptEngine {
std::shared_ptr<utils::MessageQueue> messageQueue_ = std::make_shared<utils::MessageQueue>();
bool ignoreDestroyCall_ = false;

static std::thread::id engineThreadId_;
std::thread::id engineThreadId_ = {};

WasmEngine();

// for unit-test only
void unitTestResetRetistry();
void unitTestResetRegistry();

public:
static WasmEngine* instance();
Expand Down
2 changes: 1 addition & 1 deletion docs/en/WebAssembly.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ The memory can only be managed manually. There are two main aspects related to S
In V8 and JSCore, depending on the finalize callback provided by the engine, the automatic release of the bound class
is realized, but in WASM it is not possible, and the user can only release it by himself. ScriptX provides auxiliary methods in the JS global scope.

Give a chestnut:
For example:

```C++
static ClassDefine<Test> test =
Expand Down
2 changes: 1 addition & 1 deletion docs/zh/WebAssembly.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Wasm没有GC,JS也没有finalize回调。。。所以就很坑爹
2. 绑定类的内存释放

### 绑定类的内存释放
在V8和JSCore中,依赖引擎提供的finalize回调,实现了绑定类的自动释放,但是在WASM中就搞不定了,使用者只能自己释放只。ScriptX在JS全局提供了辅助方法。
在V8和JSCore中,依赖引擎提供的finalize回调,实现了绑定类的自动释放,但是在WASM中就搞不定了,使用者只能自己释放之。ScriptX在JS全局提供了辅助方法。

举个栗子:

Expand Down
2 changes: 1 addition & 1 deletion src/Utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Tracer::Delegate* Tracer::delegate_;
void Tracer::setDelegate(Tracer::Delegate* d) {
delegate_ = d;
// use atomic to insert a memory barrier here.
std::atomic_int().store(0, std::memory_order_release);
std::atomic_thread_fence(std::memory_order_release);
}

Tracer::Tracer(ScriptEngine* engine, const char* traceName) noexcept : engine_(engine) {
Expand Down
2 changes: 2 additions & 0 deletions src/utils/MessageQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ struct alignas(std::max_align_t) ArbitraryData {

ArbitraryData& operator=(const ArbitraryData&);

SCRIPTX_DISALLOW_MOVE(ArbitraryData);

~ArbitraryData() = default;
};

Expand Down
4 changes: 2 additions & 2 deletions src/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@

// ScriptX version config files
// auto generated from the file VERSION
#define SCRIPTX_VERSION_STRING "3.1.0"
#define SCRIPTX_VERSION_STRING "3.2.0"
#define SCRIPTX_VERSION_MAJOR 3
#define SCRIPTX_VERSION_MINOR 1
#define SCRIPTX_VERSION_MINOR 2
#define SCRIPTX_VERSION_PATCH 0

namespace script {
Expand Down
10 changes: 5 additions & 5 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ add_executable(UnitTests)
include(cmake/TestEnv.cmake)

if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
string(APPEND CMAKE_CXX_FLAGS_RELEASE " -O3 -flto")

if (TEST_FLAG_ENABLE_ASAN)
# macOS doesn't support -fsanitize=memory
string(APPEND UNIT_TEST_ASAN_FLAGS
Expand All @@ -39,10 +37,10 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU
# devops support gcov only
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# for clang
string(APPEND CMAKE_CXX_FLAGS " --coverage -g3")
string(APPEND CMAKE_CXX_FLAGS " --coverage")
else ()
# for gcc
string(APPEND CMAKE_CXX_FLAGS " -fprofile-arcs -ftest-coverage -g3")
string(APPEND CMAKE_CXX_FLAGS " -fprofile-arcs -ftest-coverage")
endif()
endif ()
endif ()
Expand Down Expand Up @@ -73,7 +71,9 @@ target_sources(UnitTests PRIVATE
src/InteroperateTest.cc
src/ExceptionTest.cc
src/PressureTest.cc
src/EngineTest.cc)
src/EngineTest.cc
src/ShowCaseTest.cc
)

######## ScriptX config ##########

Expand Down
7 changes: 3 additions & 4 deletions test/src/EngineTest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,11 @@ TEST_F(EngineTest, JsPromiseTest) {
engine->eval(
u8R"(
const promise = new Promise((resolve, reject) => {
resolve('Ok');
resolve(1);
});

promise.then(x => {
console.log(x);
setValue(1);
promise.then(num => {
setValue(num);
});
)");

Expand Down
95 changes: 95 additions & 0 deletions test/src/ShowCaseTest.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* Tencent is pleased to support the open source community by making ScriptX available.
* Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "test.h"

namespace script::test {

DEFINE_ENGINE_TEST(ShowCaseTest);

/**
* show how to implement a `setTimeout(function, delayMs)`
*/
namespace {

void defineSetTimeout(ScriptEngine* engine) {
EngineScope scope(engine);
auto setTimeOut = Function::newFunction([](const Arguments& args) -> Local<Value> {
// make a global ref, we are going to pass it beyond stack-frame lifecycle
auto callback = Global<Function>(args[0].asFunction());
auto delayMs = args[1].asNumber().toInt64();
auto engine = args.engine();

auto runner = [fun = std::move(callback), engine]() {
// make a scope
EngineScope scope(engine);
try {
// run the callback function
fun.get().call();
} catch (const Exception& e) {
Logger() << "error in setTimeout:" << e;
}
};
using RunnerType = decltype(runner);

auto&& queue = args.engine()->messageQueue();
auto msg = queue->obtainInplaceMessage(
[](utils::InplaceMessage& msg) { msg.getObject<RunnerType>()(); });
msg->inplaceObject<RunnerType>(std::move(runner));
queue->postMessage(msg, std::chrono::milliseconds(delayMs));

return {};
});

engine->set("test_setTimeout", setTimeOut);
}

} // namespace

TEST_F(ShowCaseTest, SetTimeout) {
defineSetTimeout(engine);
{
EngineScope scope(engine);
int mark = 0;

engine->set("setMark", Function::newFunction([&mark](int v) { mark = v; }));

engine->eval(TS().js(u8R"(
test_setTimeout(() => {
setMark(1);
test_setTimeout(() => setMark(2), 0);
}, 0);
)")
.lua(u8R"(
test_setTimeout(
function()
setMark(1);
test_setTimeout(function() setMark(2) end, 0);
end,
0);
)")
.select());
auto&& queue = engine->messageQueue();
ASSERT_EQ(mark, 0);
queue->loopQueue(utils::MessageQueue::LoopType::kLoopOnce);
ASSERT_EQ(mark, 1);
queue->loopQueue(utils::MessageQueue::LoopType::kLoopOnce);
ASSERT_EQ(mark, 2);
}
}

} // namespace script::test
2 changes: 1 addition & 1 deletion test/src/gtest_main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ void ScriptXTestFixture::SetUp() {
#ifdef SCRIPTX_BACKEND_WEBASSEMBLY
auto eng = script::ScriptEngineImpl::instance();
script::ScriptEngineImpl::ignoreDestroyCall();
eng->unitTestResetRetistry();
eng->unitTestResetRegistry();
engine = eng;
#else
engine = new script::ScriptEngineImpl();
Expand Down