1 /**
2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <gtest/gtest.h>
17
18 #include "get_test_class.h"
19 #include "ets_coroutine.h"
20
21 #include "types/ets_array.h"
22 #include "types/ets_class.h"
23 #include "libpandabase/utils/utils.h"
24
25 // NOLINTBEGIN(readability-magic-numbers)
26
27 namespace ark::ets::test {
28
29 class EtsArrayTest : public testing::Test {
30 public:
EtsArrayTest()31 EtsArrayTest()
32 {
33 options_.SetShouldLoadBootPandaFiles(true);
34 options_.SetShouldInitializeIntrinsics(false);
35 options_.SetCompilerEnableJit(false);
36 options_.SetGcType("epsilon");
37 options_.SetLoadRuntimes({"ets"});
38
39 auto stdlib = std::getenv("PANDA_STD_LIB");
40 if (stdlib == nullptr) {
41 std::cerr << "PANDA_STD_LIB env variable should be set and point to mock_stdlib.abc" << std::endl;
42 std::abort();
43 }
44 options_.SetBootPandaFiles({stdlib});
45
46 Runtime::Create(options_);
47 }
48
~EtsArrayTest()49 ~EtsArrayTest() override
50 {
51 Runtime::Destroy();
52 }
53
54 NO_COPY_SEMANTIC(EtsArrayTest);
55 NO_MOVE_SEMANTIC(EtsArrayTest);
56
SetUp()57 void SetUp() override
58 {
59 coroutine_ = EtsCoroutine::GetCurrent();
60 coroutine_->ManagedCodeBegin();
61 }
62
TearDown()63 void TearDown() override
64 {
65 coroutine_->ManagedCodeEnd();
66 }
67
68 private:
69 RuntimeOptions options_;
70 EtsCoroutine *coroutine_ = nullptr;
71 };
72
73 template <class ClassType, EtsClassRoot ETS_CLASS_ROOT>
TestEtsPrimitiveArray(uint32_t arrayLength,ClassType element)74 static void TestEtsPrimitiveArray(uint32_t arrayLength, ClassType element)
75 {
76 auto *array = EtsPrimitiveArray<ClassType, ETS_CLASS_ROOT>::Create(arrayLength);
77 ASSERT_NE(array, nullptr);
78
79 ASSERT_EQ(array->GetLength(), arrayLength);
80 ASSERT_EQ(array->GetElementSize(), sizeof(ClassType));
81 ASSERT_EQ(array->IsPrimitive(), true);
82
83 for (uint32_t idx = 0; idx < arrayLength; ++idx) {
84 array->Set(idx, element);
85 ASSERT_EQ(array->Get(idx), element);
86 }
87 }
88
TEST_F(EtsArrayTest,PrimitiveEtsArray)89 TEST_F(EtsArrayTest, PrimitiveEtsArray)
90 {
91 uint32_t arrayLength = 100U;
92
93 TestEtsPrimitiveArray<EtsBoolean, EtsClassRoot::BOOLEAN_ARRAY>(arrayLength, 1U); // EtsBooleanArray
94 TestEtsPrimitiveArray<EtsByte, EtsClassRoot::BYTE_ARRAY>(arrayLength, 127_I); // EtsByteArray
95 TestEtsPrimitiveArray<EtsChar, EtsClassRoot::CHAR_ARRAY>(arrayLength, 65000U); // EtsCharArray
96 TestEtsPrimitiveArray<EtsShort, EtsClassRoot::SHORT_ARRAY>(arrayLength, 150_I); // EtsShortArray
97 TestEtsPrimitiveArray<EtsInt, EtsClassRoot::INT_ARRAY>(arrayLength, 65000_I); // EtsIntArray
98 TestEtsPrimitiveArray<EtsLong, EtsClassRoot::LONG_ARRAY>(arrayLength, 65000L); // EtsLongArray
99 TestEtsPrimitiveArray<EtsFloat, EtsClassRoot::FLOAT_ARRAY>(arrayLength, 65000.0F); // EtsFloatArray
100 TestEtsPrimitiveArray<EtsDouble, EtsClassRoot::DOUBLE_ARRAY>(arrayLength, 65000.0_D); // EtsDoubleArray
101 }
102
TestEtsObjectArray(const char * className,const char * source,uint32_t arrayLength)103 static void TestEtsObjectArray(const char *className, const char *source, uint32_t arrayLength)
104 {
105 EtsClass *klass = GetTestClass(source, className);
106 ASSERT_NE(klass, nullptr);
107
108 auto *array = EtsObjectArray::Create(klass, arrayLength);
109 ASSERT_NE(array, nullptr);
110
111 ASSERT_EQ(array->GetLength(), arrayLength);
112 ASSERT_EQ(array->GetElementSize(), array->GetClass()->GetComponentSize());
113 ASSERT_EQ(array->IsPrimitive(), false);
114
115 for (uint32_t idx = 0; idx < arrayLength; idx++) {
116 auto *obj = EtsObject::Create(klass);
117 array->Set(idx, obj);
118 ASSERT_EQ(array->Get(idx), obj);
119 }
120 }
121
TEST_F(EtsArrayTest,EtsObjectArray)122 TEST_F(EtsArrayTest, EtsObjectArray)
123 {
124 const char *source = R"(
125 .language eTS
126 .record Rectangle {
127 i32 Width
128 f32 Height
129 i64 COLOR <static>
130 }
131 )";
132 TestEtsObjectArray("LRectangle;", source, 100U);
133
134 source = R"(
135 .language eTS
136 .record Triangle {
137 i32 firSide
138 i32 secSide
139 i32 thirdSide
140 i64 COLOR <static>
141 }
142 )";
143 TestEtsObjectArray("LTriangle;", source, 1000U);
144
145 source = R"(
146 .language eTS
147 .record Ball {
148 f32 RADIUS <static>
149 i32 SPEED <static>
150 f32 vx
151 i32 vy
152 }
153 )";
154 TestEtsObjectArray("LBall;", source, 10000U);
155 }
156
157 } // namespace ark::ets::test
158
159 // NOLINTEND(readability-magic-numbers)
160