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