• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 #ifndef ECMASCRIPT_BUILTINS_BUILTINS_GLOBAL_H
17 #define ECMASCRIPT_BUILTINS_BUILTINS_GLOBAL_H
18 
19 #include "ecmascript/base/builtins_base.h"
20 #include "ecmascript/js_thread.h"
21 
22 #define BUILTIN_GLOBAL_CONSTANTS(V)     \
23     V("Infinity",  INFINITY_VALUE)      \
24     V("NaN",       NAN_VALUE)           \
25     V("undefined", UNDEFINED_VALUE)
26 
27 // List of functions in the global object.
28 // V(name, func, length, stubIndex)
29 // where BuiltinsGlobal::func refers to the native implementation of globalThis[name].
30 //       kungfu::BuiltinsStubCSigns::stubIndex refers to the builtin stub index, or INVALID if no stub available.
31 // The following global object properties are not implemented yet:
32 //   - Encode ( string, extraUnescaped )
33 //   - Decode ( string, preserveEscapeSet )
34 //   - ParseHexOctet ( string, position )
35 // The following global object properties are not listed here:
36 //   - parseFloat ( string ), listed in builtins_number.h instead.
37 //   - parseInt ( string ), listed in builtins_number.h instead.
38 #define BUILTIN_GLOBAL_FUNCTIONS_COMMON(V)                                            \
39     /* decodeURI ( encodedURI ) */                                                    \
40     V("decodeURI",                DecodeURI,             1, INVALID)                  \
41     /* decodeURIComponent ( encodedURIComponent ) */                                  \
42     V("decodeURIComponent",       DecodeURIComponent,    1, GlobalDecodeURIComponent) \
43     /* encodeURI ( uri ) */                                                           \
44     V("encodeURI",                EncodeURI,             1, INVALID)                  \
45     /* encodeURIComponent ( uriComponent ) */                                         \
46     V("encodeURIComponent",       EncodeURIComponent,    1, INVALID)                  \
47     /* escape ( string ), defined in B.2.1 */                                         \
48     V("escape",                   Escape,                1, INVALID)                  \
49     /* eval ( x ), which is NOT supported in ArkTS engine */                          \
50     V("eval",                     NotSupportEval,        1, INVALID)                  \
51     /* isFinite ( number ) */                                                         \
52     V("isFinite",                 IsFinite,              1, GlobalIsFinite)           \
53     /* isNaN ( number ) */                                                            \
54     V("isNaN",                    IsNaN,                 1, GlobalIsNan)              \
55     /* unescape ( string )*/                                                          \
56     V("unescape",                 Unescape,              1, INVALID)                  \
57     /* The following are ArkTS extensions */                                          \
58     V("markModuleCollectable",    MarkModuleCollectable, 0, INVALID)                  \
59     V("loadNativeModule",         LoadNativeModule,      0, INVALID)                  \
60     V("print",                    PrintEntrypoint,       0, INVALID)                  \
61     V("isSendable",               IsSendable,            0, INVALID)                  \
62     V("__getCurrentModuleName__", GetCurrentModuleName,  0, INVALID)                  \
63     V("__getCurrentBundleName__", GetCurrentBundleName,  0, INVALID)
64 #if ECMASCRIPT_ENABLE_RUNTIME_STAT
65 #define BUILTIN_GLOBAL_FUNCTIONS_RUNTIME_STAT(V)        \
66     V("startRuntimeStat", StartRuntimeStat, 0, INVALID) \
67     V("stopRuntimeStat",  StopRuntimeStat,  0, INVALID)
68 #else
69 #define BUILTIN_GLOBAL_FUNCTIONS_RUNTIME_STAT(V) // Nothing
70 #endif
71 
72 #if ECMASCRIPT_ENABLE_OPT_CODE_PROFILER
73 #define BUILTIN_GLOBAL_FUNCTIONS_OPT_CODE_PROFILER(V)   \
74     V("printOptStat", PrintOptStat, 0, INVALID)
75 #else
76 #define BUILTIN_GLOBAL_FUNCTIONS_OPT_CODE_PROFILER(V) // Nothing
77 #endif
78 
79 #if ECMASCRIPT_ENABLE_FUNCTION_CALL_TIMER
80 #define BUILTIN_GLOBAL_FUNCTIONS_FUNCTION_CALL_TIMER(V) \
81     V("printFunctionCallStat", PrintFunctionCallStat, 0, INVALID)
82 #else
83 #define BUILTIN_GLOBAL_FUNCTIONS_FUNCTION_CALL_TIMER(V) // Nothing
84 #endif
85 
86 #define BUILTIN_GLOBAL_FUNCTIONS(V)                     \
87     BUILTIN_GLOBAL_FUNCTIONS_COMMON(V)                  \
88     BUILTIN_GLOBAL_FUNCTIONS_RUNTIME_STAT(V)            \
89     BUILTIN_GLOBAL_FUNCTIONS_OPT_CODE_PROFILER(V)       \
90     BUILTIN_GLOBAL_FUNCTIONS_FUNCTION_CALL_TIMER(V)
91 
92 namespace panda::ecmascript::builtins {
93 static constexpr uint8_t BIT_MASK = 0x0F;
94 static constexpr uint8_t BIT_MASK_FF = 0xFF;
95 static constexpr uint16_t BIT_MASK_4F = 0xFFFF;
96 static constexpr uint16_t BIT16_MASK = 0x3FF;
97 static constexpr uint8_t BIT_MASK_ONE = 0x80;
98 static constexpr uint8_t BIT_MASK_TWO = 0xC0;
99 static constexpr uint8_t BIT_MASK_THR = 0xE0;
100 static constexpr uint8_t BIT_MASK_FOR = 0xF0;
101 using judgURIFunc = bool (*)(uint16_t);
102 
103 enum class Placement {
104     START = 0,
105     END,
106 };
107 
108 class BuiltinsGlobal : public base::BuiltinsBase {
109 public:
110     static const inline JSTaggedValue INFINITY_VALUE = JSTaggedValue(base::POSITIVE_INFINITY);
111     static const inline JSTaggedValue NAN_VALUE = JSTaggedValue(base::NAN_VALUE);
112     static const inline JSTaggedValue UNDEFINED_VALUE = JSTaggedValue::Undefined();
113 
114     // 18.2.1
115     static JSTaggedValue NotSupportEval(EcmaRuntimeCallInfo *msg);
116     // 18.2.2
117     static JSTaggedValue IsFinite(EcmaRuntimeCallInfo *msg);
118     // 18.2.3
119     static JSTaggedValue IsNaN(EcmaRuntimeCallInfo *msg);
120     // 18.2.6
121     static JSTaggedValue DecodeURI(EcmaRuntimeCallInfo *msg);
122     static JSTaggedValue EncodeURI(EcmaRuntimeCallInfo *msg);
123     static JSTaggedValue DecodeURIComponent(EcmaRuntimeCallInfo *msg);
124     static JSTaggedValue EncodeURIComponent(EcmaRuntimeCallInfo *msg);
125 
126     static JSTaggedValue PrintEntrypoint(EcmaRuntimeCallInfo *msg);
127     static JSTaggedValue MarkModuleCollectable(EcmaRuntimeCallInfo *msg);
128     static JSTaggedValue LoadNativeModule(EcmaRuntimeCallInfo *msg);
129     static JSTaggedValue CallJsBoundFunction(EcmaRuntimeCallInfo *msg);
130     static JSTaggedValue CallJsProxy(EcmaRuntimeCallInfo *msg);
131     static JSTaggedValue IsSendable(EcmaRuntimeCallInfo *msg);
132 
133     static JSTaggedValue GetCurrentModuleName(EcmaRuntimeCallInfo *msg);
134     static JSTaggedValue GetCurrentBundleName(EcmaRuntimeCallInfo *msg);
135 #if ECMASCRIPT_ENABLE_RUNTIME_STAT
136     static JSTaggedValue StartRuntimeStat(EcmaRuntimeCallInfo *msg);
137     static JSTaggedValue StopRuntimeStat(EcmaRuntimeCallInfo *msg);
138 #endif
139 
140 #if ECMASCRIPT_ENABLE_OPT_CODE_PROFILER
141     static JSTaggedValue PrintOptStat(EcmaRuntimeCallInfo *msg);
142 #endif
143 
144 #if ECMASCRIPT_ENABLE_FUNCTION_CALL_TIMER
145     static JSTaggedValue PrintFunctionCallStat(EcmaRuntimeCallInfo *msg);
146 #endif
147 
148 #if ECMASCRIPT_ENABLE_MEGA_PROFILER
149     static JSTaggedValue PrintMegaICStat(EcmaRuntimeCallInfo *msg);
150 #endif
151 
152     // B.2.1.1 escape ( string )
153     static JSTaggedValue Escape(EcmaRuntimeCallInfo *msg);
154     // B.2.1.2 unescape ( string )
155     static JSTaggedValue Unescape(EcmaRuntimeCallInfo *msg);
156 
GetGlobalConstants()157     static Span<const base::BuiltinConstantEntry> GetGlobalConstants()
158     {
159         return Span<const base::BuiltinConstantEntry>(GLOBAL_CONSTANTS);
160     }
161 
GetGlobalFunctions()162     static Span<const base::BuiltinFunctionEntry> GetGlobalFunctions()
163     {
164         return Span<const base::BuiltinFunctionEntry>(GLOBAL_FUNCTIONS);
165     }
166 
167 private:
168 #define BUILTIN_GLOBAL_CONSTANT_ENTRY(name, var) \
169     base::BuiltinConstantEntry::Create(name, BuiltinsGlobal::var),
170 #define BUILTIN_GLOBAL_FUNCTION_ENTRY(name, func, length, id) \
171     base::BuiltinFunctionEntry::Create(name, BuiltinsGlobal::func, length, BUILTINS_STUB_ID(id)),
172 
173     static inline std::array GLOBAL_CONSTANTS = {
174         BUILTIN_GLOBAL_CONSTANTS(BUILTIN_GLOBAL_CONSTANT_ENTRY)
175     };
176     static constexpr std::array GLOBAL_FUNCTIONS = {
177         BUILTIN_GLOBAL_FUNCTIONS(BUILTIN_GLOBAL_FUNCTION_ENTRY)
178     };
179 #undef BUILTIN_GLOBAL_CONSTANT_ENTRY
180 #undef BUILTIN_GLOBAL_FUNCTION_ENTRY
181 
182     static void PrintString(JSThread *thread, EcmaString *string);
183     static void PrintValue(int64_t value, int64_t tag);
184     static JSTaggedValue Encode(JSThread *thread, const JSHandle<EcmaString> &str, judgURIFunc IsInURISet);
185     static JSTaggedValue Decode(JSThread *thread, const JSHandle<EcmaString> &str, judgURIFunc IsInURISet);
186 #if ENABLE_NEXT_OPTIMIZATION
187     template <typename T>
188     static JSTaggedValue DoDecode(JSThread *thread, const JSHandle<EcmaString> &str, judgURIFunc IsInURISet,
189                                            const T *data);
190     static JSTaggedValue UTF16EncodeCodePoint(JSThread *thread, judgURIFunc IsInURISet,
191                                                 const std::vector<uint8_t> &oct, const JSHandle<EcmaString> &str,
192                                                 uint32_t &start, int32_t &k, std::u16string &resStr);
193     static void HandleSingleByteCharacter(JSThread *thread, uint8_t &bb,
194                                             const JSHandle<EcmaString> &str,
195                                             uint32_t &start, int32_t &k,
196                                             std::u16string &resStr, judgURIFunc IsInURISet);
197     template <typename T>
198     static inline uint16_t GetCodeUnit(Span<T> &sp, int32_t index, int32_t length);
199     template <typename T>
200     static JSTaggedValue DecodePercentEncoding(JSThread *thread, int32_t &n,
201                                                 int32_t &k, const JSHandle<EcmaString> &str,
202                                                 uint8_t &bb, std::vector<uint8_t> &oct, Span<T> &sp, int32_t strLen);
203     template <typename T>
204     static JSTaggedValue DecodePercentEncoding(JSThread *thread, const JSHandle<EcmaString> &str, int32_t &k,
205                                                judgURIFunc IsInURISet, int32_t strLen, std::u16string &resStr,
206                                                Span<T> &sp);
207     static inline bool IsUnescapedURI(uint16_t ch);
208     static inline bool IsInUnescapedURISet(uint16_t ch);
209     static inline bool IsInReservedURISet(uint16_t ch);
210     static inline bool IsReservedURI(uint16_t ch);
211     static inline bool IsInMarkURISet(uint16_t ch);
212     static inline void AppendPercentEncodedByte(std::u16string& sStr, uint8_t byte, uint8_t &len);
213     static inline void AppendU32Data(std::u16string &resStr, uint32_t data);
214 #else // ENABLE_NEXT_OPTIMIZATION
215     static JSTaggedValue UTF16EncodeCodePoint(JSThread *thread, judgURIFunc IsInURISet,
216                                               const std::vector<uint8_t> &oct, const JSHandle<EcmaString> &str,
217                                               uint32_t &start, int32_t &k, std::u16string &sStr);
218     static void HandleSingleByteCharacter(JSThread *thread, uint8_t &bb,
219                                           const JSHandle<EcmaString> &str,
220                                           uint32_t &start, int32_t &k,
221                                           std::u16string &sStr, judgURIFunc IsInURISet);
222     static JSTaggedValue DecodePercentEncoding(JSThread *thread, int32_t &n,
223                                                int32_t &k, const JSHandle<EcmaString> &str,
224                                                uint8_t &bb, std::vector<uint8_t> &oct);
225     static JSTaggedValue DecodePercentEncoding(JSThread *thread, const JSHandle<EcmaString> &str, int32_t &k,
226                                                judgURIFunc IsInURISet, int32_t strLen, std::u16string &sStr);
227     static bool IsUnescapedURI(uint16_t ch);
228     static bool IsInUnescapedURISet(uint16_t ch);
229     static bool IsInReservedURISet(uint16_t ch);
230     static bool IsReservedURI(uint16_t ch);
231     static bool IsInMarkURISet(uint16_t ch);
232     static bool IsHexDigits(uint16_t ch);
233     static uint8_t GetValueFromTwoHex(uint16_t front, uint16_t behind);
234 #endif // ENABLE_NEXT_OPTIMIZATION
235     static uint16_t GetValueFromHexString(JSThread *thread, const JSHandle<EcmaString> &string);
236     // 22.1.3.17.2 StringPad ( S, maxLength, fillString, placement )
237     static EcmaString *StringPad(JSThread *thread,
238                                  const JSHandle<EcmaString> &string,
239                                  uint32_t maxLength,
240                                  const JSHandle<EcmaString> &fillString,
241                                  Placement placement = Placement::START);
IsUTF16HighSurrogate(uint16_t ch)242     static bool IsUTF16HighSurrogate(uint16_t ch)
243     {
244         return common::utf_helper::DECODE_LEAD_LOW <= ch && ch <= common::utf_helper::DECODE_LEAD_HIGH;
245     }
246 
IsUTF16LowSurrogate(uint16_t ch)247     static bool IsUTF16LowSurrogate(uint16_t ch)
248     {
249         return common::utf_helper::DECODE_TRAIL_LOW <= ch && ch <= common::utf_helper::DECODE_TRAIL_HIGH;
250     }
251 
252     // 11.1.3 Static Semantics: UTF16SurrogatePairToCodePoint ( lead, trail )
253     static uint16_t UTF16SurrogatePairToCodePoint(uint16_t lead, uint16_t trail);
254     // 11.1.5 Static Semantics: StringToCodePoints ( string )
255     static EcmaString *StringToCodePoints(JSThread *thread, const JSHandle<EcmaString> &string);
256 };
257 }  // namespace panda::ecmascript::builtins
258 
259 #endif  // ECMASCRIPT_BUILTINS_BUILTINS_ERROR_H
260