• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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