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 using judgURIFunc = bool (*)(uint16_t); 100 101 enum class Placement { 102 START = 0, 103 END, 104 }; 105 106 class BuiltinsGlobal : public base::BuiltinsBase { 107 public: 108 static const inline JSTaggedValue INFINITY_VALUE = JSTaggedValue(base::POSITIVE_INFINITY); 109 static const inline JSTaggedValue NAN_VALUE = JSTaggedValue(base::NAN_VALUE); 110 static const inline JSTaggedValue UNDEFINED_VALUE = JSTaggedValue::Undefined(); 111 112 // 18.2.1 113 static JSTaggedValue NotSupportEval(EcmaRuntimeCallInfo *msg); 114 // 18.2.2 115 static JSTaggedValue IsFinite(EcmaRuntimeCallInfo *msg); 116 // 18.2.3 117 static JSTaggedValue IsNaN(EcmaRuntimeCallInfo *msg); 118 // 18.2.6 119 static JSTaggedValue DecodeURI(EcmaRuntimeCallInfo *msg); 120 static JSTaggedValue EncodeURI(EcmaRuntimeCallInfo *msg); 121 static JSTaggedValue DecodeURIComponent(EcmaRuntimeCallInfo *msg); 122 static JSTaggedValue EncodeURIComponent(EcmaRuntimeCallInfo *msg); 123 124 static JSTaggedValue PrintEntrypoint(EcmaRuntimeCallInfo *msg); 125 static JSTaggedValue MarkModuleCollectable(EcmaRuntimeCallInfo *msg); 126 static JSTaggedValue LoadNativeModule(EcmaRuntimeCallInfo *msg); 127 static JSTaggedValue CallJsBoundFunction(EcmaRuntimeCallInfo *msg); 128 static JSTaggedValue CallJsProxy(EcmaRuntimeCallInfo *msg); 129 static JSTaggedValue IsSendable(EcmaRuntimeCallInfo *msg); 130 131 static JSTaggedValue GetCurrentModuleName(EcmaRuntimeCallInfo *msg); 132 static JSTaggedValue GetCurrentBundleName(EcmaRuntimeCallInfo *msg); 133 #if ECMASCRIPT_ENABLE_RUNTIME_STAT 134 static JSTaggedValue StartRuntimeStat(EcmaRuntimeCallInfo *msg); 135 static JSTaggedValue StopRuntimeStat(EcmaRuntimeCallInfo *msg); 136 #endif 137 138 #if ECMASCRIPT_ENABLE_OPT_CODE_PROFILER 139 static JSTaggedValue PrintOptStat(EcmaRuntimeCallInfo *msg); 140 #endif 141 142 #if ECMASCRIPT_ENABLE_FUNCTION_CALL_TIMER 143 static JSTaggedValue PrintFunctionCallStat(EcmaRuntimeCallInfo *msg); 144 #endif 145 146 #if ECMASCRIPT_ENABLE_MEGA_PROFILER 147 static JSTaggedValue PrintMegaICStat(EcmaRuntimeCallInfo *msg); 148 #endif 149 150 // B.2.1.1 escape ( string ) 151 static JSTaggedValue Escape(EcmaRuntimeCallInfo *msg); 152 // B.2.1.2 unescape ( string ) 153 static JSTaggedValue Unescape(EcmaRuntimeCallInfo *msg); 154 GetGlobalConstants()155 static Span<const base::BuiltinConstantEntry> GetGlobalConstants() 156 { 157 return Span<const base::BuiltinConstantEntry>(GLOBAL_CONSTANTS); 158 } 159 GetGlobalFunctions()160 static Span<const base::BuiltinFunctionEntry> GetGlobalFunctions() 161 { 162 return Span<const base::BuiltinFunctionEntry>(GLOBAL_FUNCTIONS); 163 } 164 165 private: 166 #define BUILTIN_GLOBAL_CONSTANT_ENTRY(name, var) \ 167 base::BuiltinConstantEntry::Create(name, BuiltinsGlobal::var), 168 #define BUILTIN_GLOBAL_FUNCTION_ENTRY(name, func, length, id) \ 169 base::BuiltinFunctionEntry::Create(name, BuiltinsGlobal::func, length, kungfu::BuiltinsStubCSigns::id), 170 171 static inline std::array GLOBAL_CONSTANTS = { 172 BUILTIN_GLOBAL_CONSTANTS(BUILTIN_GLOBAL_CONSTANT_ENTRY) 173 }; 174 static constexpr std::array GLOBAL_FUNCTIONS = { 175 BUILTIN_GLOBAL_FUNCTIONS(BUILTIN_GLOBAL_FUNCTION_ENTRY) 176 }; 177 #undef BUILTIN_GLOBAL_CONSTANT_ENTRY 178 #undef BUILTIN_GLOBAL_FUNCTION_ENTRY 179 180 static void PrintString(JSThread *thread, EcmaString *string); 181 static void PrintValue(int64_t value, int64_t tag); 182 static JSTaggedValue Encode(JSThread *thread, const JSHandle<EcmaString> &str, judgURIFunc IsInURISet); 183 static JSTaggedValue Decode(JSThread *thread, const JSHandle<EcmaString> &str, judgURIFunc IsInURISet); 184 static JSTaggedValue UTF16EncodeCodePoint(JSThread *thread, judgURIFunc IsInURISet, 185 const std::vector<uint8_t> &oct, const JSHandle<EcmaString> &str, 186 uint32_t &start, int32_t &k, std::u16string &sStr); 187 static void HandleSingleByteCharacter(JSThread *thread, uint8_t &bb, 188 const JSHandle<EcmaString> &str, 189 uint32_t &start, int32_t &k, 190 std::u16string &sStr, judgURIFunc IsInURISet); 191 static JSTaggedValue DecodePercentEncoding(JSThread *thread, int32_t &n, 192 int32_t &k, const JSHandle<EcmaString> &str, 193 uint8_t &bb, std::vector<uint8_t> &oct); 194 static JSTaggedValue DecodePercentEncoding(JSThread *thread, const JSHandle<EcmaString> &str, int32_t &k, 195 judgURIFunc IsInURISet, int32_t strLen, std::u16string &sStr); 196 static bool IsUnescapedURI(uint16_t ch); 197 static bool IsInUnescapedURISet(uint16_t ch); 198 static bool IsInReservedURISet(uint16_t ch); 199 static bool IsReservedURI(uint16_t ch); 200 static bool IsInMarkURISet(uint16_t ch); 201 static bool IsHexDigits(uint16_t ch); 202 static uint8_t GetValueFromTwoHex(uint16_t front, uint16_t behind); 203 static uint16_t GetValueFromHexString(const JSHandle<EcmaString> &string); 204 // 22.1.3.17.2 StringPad ( S, maxLength, fillString, placement ) 205 static EcmaString *StringPad(JSThread *thread, 206 const JSHandle<EcmaString> &string, 207 uint32_t maxLength, 208 const JSHandle<EcmaString> &fillString, 209 Placement placement = Placement::START); IsUTF16HighSurrogate(uint16_t ch)210 static bool IsUTF16HighSurrogate(uint16_t ch) 211 { 212 return base::utf_helper::DECODE_LEAD_LOW <= ch && ch <= base::utf_helper::DECODE_LEAD_HIGH; 213 } 214 IsUTF16LowSurrogate(uint16_t ch)215 static bool IsUTF16LowSurrogate(uint16_t ch) 216 { 217 return base::utf_helper::DECODE_TRAIL_LOW <= ch && ch <= base::utf_helper::DECODE_TRAIL_HIGH; 218 } 219 220 // 11.1.3 Static Semantics: UTF16SurrogatePairToCodePoint ( lead, trail ) 221 static uint16_t UTF16SurrogatePairToCodePoint(uint16_t lead, uint16_t trail); 222 // 11.1.5 Static Semantics: StringToCodePoints ( string ) 223 static EcmaString *StringToCodePoints(JSThread *thread, const JSHandle<EcmaString> &string); 224 }; 225 } // namespace panda::ecmascript::builtins 226 227 #endif // ECMASCRIPT_BUILTINS_BUILTINS_ERROR_H 228