* Copyright (c) 2025 Huawei Device Co., Ltd.
* 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 <thread>
#include "ecmascript/ecma_vm.h"
#include "ecmascript/js_thread.h"
#include "ecmascript/object_factory.h"
#include "ecmascript/tests/test_helper.h"
#include "ecmascript/serializer/value_serializer.h"
#include "ecmascript/serializer/base_deserializer.h"
using namespace panda::ecmascript;
using namespace testing::ext;
namespace panda::test {
class CMCJSDeserializerTest {
public:
CMCJSDeserializerTest() : ecmaVm(nullptr), scope(nullptr), thread(nullptr) {}
void Init()
{
JSRuntimeOptions options;
options.SetEnableCMCGC(true);
ecmaVm = JSNApi::CreateEcmaVM(options);
EXPECT_TRUE(ecmaVm != nullptr) << "Cannot create Runtime";
thread = ecmaVm->GetJSThread();
scope = new EcmaHandleScope(thread);
thread->ManagedCodeBegin();
}
void Destroy()
{
thread->ManagedCodeEnd();
delete scope;
scope = nullptr;
thread->ClearException();
JSNApi::DestroyJSVM(ecmaVm);
}
void SerializeTaggedArrayTest(SerializeData *data)
{
Init();
BaseDeserializer deserializer(thread, data);
JSHandle<JSTaggedValue> res = deserializer.ReadValue();
EXPECT_TRUE(!res.IsEmpty());
EXPECT_TRUE(res->IsTaggedArray());
Destroy();
}
private:
EcmaVM *ecmaVm = nullptr;
EcmaHandleScope *scope = nullptr;
JSThread *thread = nullptr;
};
class CMCJSSerializerTest : public testing::Test {
public:
static void SetUpTestCase()
{
GTEST_LOG_(INFO) << "SetUpTestCase";
}
static void TearDownTestCase()
{
GTEST_LOG_(INFO) << "TearDownCase";
}
void SetUp() override
{
JSRuntimeOptions options;
options.SetEnableCMCGC(true);
ecmaVm = JSNApi::CreateEcmaVM(options);
EXPECT_TRUE(ecmaVm != nullptr) << "Cannot create Runtime";
thread = ecmaVm->GetJSThread();
scope = new EcmaHandleScope(thread);
thread->ManagedCodeBegin();
}
void TearDown() override
{
thread->ManagedCodeEnd();
delete scope;
scope = nullptr;
thread->ClearException();
JSNApi::DestroyJSVM(ecmaVm);
}
JSThread *thread {nullptr};
EcmaVM *ecmaVm {nullptr};
EcmaHandleScope *scope {nullptr};
};
HWTEST_F_L0(CMCJSSerializerTest, SerializeTaggedArrayTest)
{
ObjectFactory *factory = ecmaVm->GetFactory();
JSHandle<TaggedArray> array = factory->NewTaggedArray(10, JSTaggedValue::Hole());
for (int i = 0; i < 5; i++) {
JSHandle<TaggedArray> array1 =
factory->NewTaggedArray(10, JSTaggedValue::Hole());
JSHandle<TaggedArray> array2 =
factory->NewTaggedArray(10, JSTaggedValue::Hole(), MemSpaceType::NON_MOVABLE);
array->Set(thread, i, array1);
array->Set(thread, i + 1, array2);
}
ValueSerializer *serializer = new ValueSerializer(thread, false, true);
bool success = serializer->WriteValue(thread, JSHandle<JSTaggedValue>(array),
JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
EXPECT_TRUE(success);
std::unique_ptr<SerializeData> data = serializer->Release();
CMCJSDeserializerTest jsDeserializerTest;
std::thread t1(&CMCJSDeserializerTest::SerializeTaggedArrayTest, jsDeserializerTest, data.release());
ecmascript::ThreadSuspensionScope scope(thread);
t1.join();
delete serializer;
};
}