• 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, INVALID)       \
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, INVALID)       \
53     /* isNaN ( number ) */                                              \
54     V("isNaN",                 IsNaN,                 1, INVALID)       \
55     /* unescape ( string )*/                                            \
56     V("unescape",              Unescape,              1, INVALID)       \
57     /* The following are ArkTS extensions */                            \
58     V("markModuleCollectable", MarkModuleCollectable, 0, INVALID)       \
59     V("print",                 PrintEntrypoint,       0, INVALID)
60 
61 #if ECMASCRIPT_ENABLE_RUNTIME_STAT
62 #define BUILTIN_GLOBAL_FUNCTIONS_RUNTIME_STAT(V)        \
63     V("startRuntimeStat", StartRuntimeStat, 0, INVALID) \
64     V("stopRuntimeStat",  StopRuntimeStat,  0, INVALID)
65 #else
66 #define BUILTIN_GLOBAL_FUNCTIONS_RUNTIME_STAT(V) // Nothing
67 #endif
68 
69 #if ECMASCRIPT_ENABLE_OPT_CODE_PROFILER
70 #define BUILTIN_GLOBAL_FUNCTIONS_OPT_CODE_PROFILER(V)   \
71     V("printOptStat", PrintOptStat, 0, INVALID)
72 #else
73 #define BUILTIN_GLOBAL_FUNCTIONS_OPT_CODE_PROFILER(V) // Nothing
74 #endif
75 
76 #if ECMASCRIPT_ENABLE_FUNCTION_CALL_TIMER
77 #define BUILTIN_GLOBAL_FUNCTIONS_FUNCTION_CALL_TIMER(V) \
78     V("printFunctionCallStat", PrintFunctionCallStat, 0, INVALID)
79 #else
80 #define BUILTIN_GLOBAL_FUNCTIONS_FUNCTION_CALL_TIMER(V) // Nothing
81 #endif
82 
83 #define BUILTIN_GLOBAL_FUNCTIONS(V)                     \
84     BUILTIN_GLOBAL_FUNCTIONS_COMMON(V)                  \
85     BUILTIN_GLOBAL_FUNCTIONS_RUNTIME_STAT(V)            \
86     BUILTIN_GLOBAL_FUNCTIONS_OPT_CODE_PROFILER(V)       \
87     BUILTIN_GLOBAL_FUNCTIONS_FUNCTION_CALL_TIMER(V)
88 
89 namespace panda::ecmascript::builtins {
90 static constexpr uint8_t BIT_MASK = 0x0F;
91 static constexpr uint8_t BIT_MASK_FF = 0xFF;
92 static constexpr uint16_t BIT_MASK_4F = 0xFFFF;
93 static constexpr uint16_t BIT16_MASK = 0x3FF;
94 static constexpr uint8_t BIT_MASK_ONE = 0x80;
95 static constexpr uint8_t BIT_MASK_TWO = 0xC0;
96 using judgURIFunc = bool (*)(uint16_t);
97 
98 enum class Placement {
99     START = 0,
100     END,
101 };
102 
103 class BuiltinsGlobal : public base::BuiltinsBase {
104 public:
105     static const inline JSTaggedValue INFINITY_VALUE = JSTaggedValue(base::POSITIVE_INFINITY);
106     static const inline JSTaggedValue NAN_VALUE = JSTaggedValue(base::NAN_VALUE);
107     static const inline JSTaggedValue UNDEFINED_VALUE = JSTaggedValue::Undefined();
108 
109     // 18.2.1
110     static JSTaggedValue NotSupportEval(EcmaRuntimeCallInfo *msg);
111     // 18.2.2
112     static JSTaggedValue IsFinite(EcmaRuntimeCallInfo *msg);
113     // 18.2.3
114     static JSTaggedValue IsNaN(EcmaRuntimeCallInfo *msg);
115     // 18.2.6
116     static JSTaggedValue DecodeURI(EcmaRuntimeCallInfo *msg);
117     static JSTaggedValue EncodeURI(EcmaRuntimeCallInfo *msg);
118     static JSTaggedValue DecodeURIComponent(EcmaRuntimeCallInfo *msg);
119     static JSTaggedValue EncodeURIComponent(EcmaRuntimeCallInfo *msg);
120 
121     static JSTaggedValue PrintEntrypoint(EcmaRuntimeCallInfo *msg);
122     static JSTaggedValue MarkModuleCollectable(EcmaRuntimeCallInfo *msg);
123     static JSTaggedValue CallJsBoundFunction(EcmaRuntimeCallInfo *msg);
124     static JSTaggedValue CallJsProxy(EcmaRuntimeCallInfo *msg);
125 #if ECMASCRIPT_ENABLE_RUNTIME_STAT
126     static JSTaggedValue StartRuntimeStat(EcmaRuntimeCallInfo *msg);
127     static JSTaggedValue StopRuntimeStat(EcmaRuntimeCallInfo *msg);
128 #endif
129 
130 #if ECMASCRIPT_ENABLE_OPT_CODE_PROFILER
131     static JSTaggedValue PrintOptStat(EcmaRuntimeCallInfo *msg);
132 #endif
133 
134 #if ECMASCRIPT_ENABLE_FUNCTION_CALL_TIMER
135     static JSTaggedValue PrintFunctionCallStat(EcmaRuntimeCallInfo *msg);
136 #endif
137     // B.2.1.1 escape ( string )
138     static JSTaggedValue Escape(EcmaRuntimeCallInfo *msg);
139     // B.2.1.2 unescape ( string )
140     static JSTaggedValue Unescape(EcmaRuntimeCallInfo *msg);
141 
GetGlobalConstants()142     static Span<const base::BuiltinConstantEntry> GetGlobalConstants()
143     {
144         return Span<const base::BuiltinConstantEntry>(GLOBAL_CONSTANTS);
145     }
146 
GetGlobalFunctions()147     static Span<const base::BuiltinFunctionEntry> GetGlobalFunctions()
148     {
149         return Span<const base::BuiltinFunctionEntry>(GLOBAL_FUNCTIONS);
150     }
151 
152 private:
153 #define BUILTIN_GLOBAL_CONSTANT_ENTRY(name, var) \
154     base::BuiltinConstantEntry::Create(name, BuiltinsGlobal::var),
155 #define BUILTIN_GLOBAL_FUNCTION_ENTRY(name, func, length, id) \
156     base::BuiltinFunctionEntry::Create(name, BuiltinsGlobal::func, length, kungfu::BuiltinsStubCSigns::id),
157 
158     static inline std::array GLOBAL_CONSTANTS = {
159         BUILTIN_GLOBAL_CONSTANTS(BUILTIN_GLOBAL_CONSTANT_ENTRY)
160     };
161     static constexpr std::array GLOBAL_FUNCTIONS = {
162         BUILTIN_GLOBAL_FUNCTIONS(BUILTIN_GLOBAL_FUNCTION_ENTRY)
163     };
164 #undef BUILTIN_GLOBAL_CONSTANT_ENTRY
165 #undef BUILTIN_GLOBAL_FUNCTION_ENTRY
166 
167     static void PrintString(JSThread *thread, EcmaString *string);
168     static void PrintValue(int64_t value, int64_t tag);
169     static JSTaggedValue Encode(JSThread *thread, const JSHandle<EcmaString> &str, judgURIFunc IsInURISet);
170     static JSTaggedValue Decode(JSThread *thread, const JSHandle<EcmaString> &str, judgURIFunc IsInURISet);
171     static bool IsUnescapedURI(uint16_t ch);
172     static bool IsInUnescapedURISet(uint16_t ch);
173     static bool IsInReservedURISet(uint16_t ch);
174     static bool IsReservedURI(uint16_t ch);
175     static bool IsInMarkURISet(uint16_t ch);
176     static bool IsHexDigits(uint16_t ch);
177     static uint8_t GetValueFromTwoHex(uint16_t front, uint16_t behind);
178     static uint16_t GetValueFromHexString(const JSHandle<EcmaString> &string);
179     // 22.1.3.17.2 StringPad ( S, maxLength, fillString, placement )
180     static EcmaString *StringPad(JSThread *thread,
181                                  const JSHandle<EcmaString> &string,
182                                  uint32_t maxLength,
183                                  const JSHandle<EcmaString> &fillString,
184                                  Placement placement = Placement::START);
IsUTF16HighSurrogate(uint16_t ch)185     static bool IsUTF16HighSurrogate(uint16_t ch)
186     {
187         return base::utf_helper::DECODE_LEAD_LOW <= ch && ch <= base::utf_helper::DECODE_LEAD_HIGH;
188     }
189 
IsUTF16LowSurrogate(uint16_t ch)190     static bool IsUTF16LowSurrogate(uint16_t ch)
191     {
192         return base::utf_helper::DECODE_TRAIL_LOW <= ch && ch <= base::utf_helper::DECODE_TRAIL_HIGH;
193     }
194 
195     // 11.1.3 Static Semantics: UTF16SurrogatePairToCodePoint ( lead, trail )
196     static uint16_t UTF16SurrogatePairToCodePoint(uint16_t lead, uint16_t trail);
197     // 11.1.5 Static Semantics: StringToCodePoints ( string )
198     static EcmaString *StringToCodePoints(JSThread *thread, const JSHandle<EcmaString> &string);
199 };
200 }  // namespace panda::ecmascript::builtins
201 
202 #endif  // ECMASCRIPT_BUILTINS_BUILTINS_ERROR_H
203