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 "intrinsics.h"
17 #include "libpandabase/utils/logger.h"
18 #include "runtime/include/class.h"
19 #include "runtime/include/exceptions.h"
20 #include "plugins/ets/runtime/types/ets_primitives.h"
21 #include "plugins/ets/runtime/types/ets_string.h"
22 #include "plugins/ets/runtime/types/ets_string_builder.h"
23 #include "plugins/ets/runtime/types/ets_array.h"
24 #include "libpandabase/utils/utf.h"
25 #include "plugins/ets/runtime/ets_handle.h"
26 #include "plugins/ets/runtime/ets_handle_scope.h"
27 #include "runtime/arch/memory_helpers.h"
28 #include <unistd.h>
29
30 #include "plugins/ets/runtime/intrinsics/helpers/ets_to_string_cache.h"
31
32 namespace ark::ets::intrinsics {
33
34 static inline constexpr size_t NULL_BYTES_NUM = 5;
35
GetNullString()36 EtsString *GetNullString()
37 {
38 auto ctx = Runtime::GetCurrent()->GetLanguageContext(panda_file::SourceLang::ETS);
39 auto vm = Runtime::GetCurrent()->GetPandaVM();
40
41 std::array<uint8_t, NULL_BYTES_NUM> nullBytes = {'n', 'u', 'l', 'l', '\0'};
42
43 return EtsString::FromCoreType(
44 vm->GetStringTable()->GetOrInternString(nullBytes.data(), nullBytes.size() - 1, ctx));
45 }
46
StdCoreStringBuilderConcatStrings(EtsString * lhs,EtsString * rhs)47 EtsString *StdCoreStringBuilderConcatStrings(EtsString *lhs, EtsString *rhs)
48 {
49 if (lhs == nullptr || rhs == nullptr) {
50 // GetNullString()-call below may trigger GC and move lhs/rhs args, need to hold them
51 auto thread = ManagedThread::GetCurrent();
52 [[maybe_unused]] HandleScope<ObjectHeader *> scope(thread);
53 VMHandle<EtsString> lhsHandle(thread, lhs == nullptr ? nullptr : lhs->GetCoreType());
54 VMHandle<EtsString> rhsHandle(thread, rhs == nullptr ? nullptr : rhs->GetCoreType());
55
56 EtsString *nullString = GetNullString();
57
58 // Restore args from handles
59 lhs = lhsHandle.GetPtr();
60 rhs = rhsHandle.GetPtr();
61
62 lhs = lhs == nullptr ? nullString : lhs;
63 rhs = rhs == nullptr ? nullString : rhs;
64 }
65 return EtsString::Concat(lhs, rhs);
66 }
67
StdCoreToStringBoolean(EtsBoolean i)68 EtsString *StdCoreToStringBoolean(EtsBoolean i)
69 {
70 std::string s = i == 1 ? "true" : "false";
71 return EtsString::CreateFromMUtf8(s.c_str());
72 }
73
StdCoreToStringByte(EtsByte i)74 EtsString *StdCoreToStringByte(EtsByte i)
75 {
76 std::string s = std::to_string(i);
77 return EtsString::CreateFromMUtf8(s.c_str());
78 }
79
StdCoreToStringChar(EtsChar i)80 EtsString *StdCoreToStringChar(EtsChar i)
81 {
82 return EtsString::CreateFromUtf16(&i, 1);
83 }
84
StdCoreToStringShort(EtsShort i)85 EtsString *StdCoreToStringShort(EtsShort i)
86 {
87 return StdCoreToStringLong(i);
88 }
89
StdCoreToStringInt(EtsInt i)90 EtsString *StdCoreToStringInt(EtsInt i)
91 {
92 return StdCoreToStringLong(i);
93 }
94
StdCoreToStringLong(EtsLong i)95 EtsString *StdCoreToStringLong(EtsLong i)
96 {
97 auto *cache = PandaEtsVM::GetCurrent()->GetLongToStringCache();
98 ASSERT(cache != nullptr);
99 return cache->GetOrCache(EtsCoroutine::GetCurrent(), i);
100 }
101
StdCoreStringBuilderAppendString(ObjectHeader * sb,EtsString * str)102 ObjectHeader *StdCoreStringBuilderAppendString(ObjectHeader *sb, EtsString *str)
103 {
104 return StringBuilderAppendString(sb, str);
105 }
106
StdCoreStringBuilderAppendString2(ObjectHeader * sb,EtsString * str0,EtsString * str1)107 ObjectHeader *StdCoreStringBuilderAppendString2(ObjectHeader *sb, EtsString *str0, EtsString *str1)
108 {
109 return StringBuilderAppendStrings(sb, str0, str1);
110 }
111
StdCoreStringBuilderAppendString3(ObjectHeader * sb,EtsString * str0,EtsString * str1,EtsString * str2)112 ObjectHeader *StdCoreStringBuilderAppendString3(ObjectHeader *sb, EtsString *str0, EtsString *str1, EtsString *str2)
113 {
114 return StringBuilderAppendStrings(sb, str0, str1, str2);
115 }
116
StdCoreStringBuilderAppendString4(ObjectHeader * sb,EtsString * str0,EtsString * str1,EtsString * str2,EtsString * str3)117 ObjectHeader *StdCoreStringBuilderAppendString4(ObjectHeader *sb, EtsString *str0, EtsString *str1, EtsString *str2,
118 EtsString *str3)
119 {
120 return StringBuilderAppendStrings(sb, str0, str1, str2, str3);
121 }
122
StdCoreStringBuilderAppendBool(ObjectHeader * sb,EtsBoolean v)123 ObjectHeader *StdCoreStringBuilderAppendBool(ObjectHeader *sb, EtsBoolean v)
124 {
125 return StringBuilderAppendBool(sb, v);
126 }
127
StdCoreStringBuilderAppendChar(ObjectHeader * sb,EtsChar v)128 ObjectHeader *StdCoreStringBuilderAppendChar(ObjectHeader *sb, EtsChar v)
129 {
130 return StringBuilderAppendChar(sb, v);
131 }
132
StdCoreStringBuilderAppendByte(ObjectHeader * sb,EtsByte v)133 ObjectHeader *StdCoreStringBuilderAppendByte(ObjectHeader *sb, EtsByte v)
134 {
135 return StringBuilderAppendLong(sb, static_cast<EtsLong>(v));
136 }
137
StdCoreStringBuilderAppendShort(ObjectHeader * sb,EtsShort v)138 ObjectHeader *StdCoreStringBuilderAppendShort(ObjectHeader *sb, EtsShort v)
139 {
140 return StringBuilderAppendLong(sb, static_cast<EtsLong>(v));
141 }
142
StdCoreStringBuilderAppendInt(ObjectHeader * sb,EtsInt v)143 ObjectHeader *StdCoreStringBuilderAppendInt(ObjectHeader *sb, EtsInt v)
144 {
145 return StringBuilderAppendLong(sb, static_cast<EtsLong>(v));
146 }
147
StdCoreStringBuilderAppendLong(ObjectHeader * sb,EtsLong v)148 ObjectHeader *StdCoreStringBuilderAppendLong(ObjectHeader *sb, EtsLong v)
149 {
150 return StringBuilderAppendLong(sb, v);
151 }
152
StdCoreStringBuilderAppendFloat(ObjectHeader * sb,EtsFloat v)153 ObjectHeader *StdCoreStringBuilderAppendFloat(ObjectHeader *sb, EtsFloat v)
154 {
155 return StringBuilderAppendFloat(sb, v);
156 }
157
StdCoreStringBuilderAppendDouble(ObjectHeader * sb,EtsDouble v)158 ObjectHeader *StdCoreStringBuilderAppendDouble(ObjectHeader *sb, EtsDouble v)
159 {
160 return StringBuilderAppendDouble(sb, v);
161 }
162
StdCoreStringBuilderToString(ObjectHeader * sb)163 EtsString *StdCoreStringBuilderToString(ObjectHeader *sb)
164 {
165 return StringBuilderToString(sb);
166 }
167
168 } // namespace ark::ets::intrinsics
169