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_DATE_H 17 #define ECMASCRIPT_BUILTINS_BUILTINS_DATE_H 18 19 #include "ecmascript/base/builtins_base.h" 20 #include "ecmascript/js_date.h" 21 22 // List of functions in Date, excluding the '@@' properties. 23 // V(name, func, length, stubIndex) 24 // where BuiltinsDate::func refers to the native implementation of Date[name]. 25 // kungfu::BuiltinsStubCSigns::stubIndex refers to the builtin stub index, or INVALID if no stub available. 26 #define BUILTIN_DATE_FUNCTIONS(V) \ 27 /* Date.now ( ) */ \ 28 V("now", Now, 0, DateNow) \ 29 /* Date.parse ( string ) */ \ 30 V("parse", Parse, 1, INVALID) \ 31 /* Date.UTC ( year [ , month [ , date [ , hours [ , minutes [ , seconds [ , ms ] ] ] ] ] ] ) */ \ 32 V("UTC", UTC, ::panda::ecmascript::builtins::BuiltinsDate::UTC_LENGTH, INVALID) 33 34 // List of functions in Date.prototype, excluding the constructor and '@@' properties. 35 // V(name, func, length, stubIndex) 36 // where BuiltinsDate::func refers to the native implementation of Date.prototype[name]. 37 #define BUILTIN_DATE_PROTOTYPE_FUNCTIONS(V) \ 38 /* Date.prototype.getDate ( ) */ \ 39 V("getDate", GetDate, 0, INVALID) \ 40 /* Date.prototype.getDay ( ) */ \ 41 V("getDay", GetDay, 0, INVALID) \ 42 /* Date.prototype.getFullYear ( ) */ \ 43 V("getFullYear", GetFullYear, 0, INVALID) \ 44 /* Date.prototype.getHours ( ) */ \ 45 V("getHours", GetHours, 0, INVALID) \ 46 /* Date.prototype.getMilliseconds ( ) */ \ 47 V("getMilliseconds", GetMilliseconds, 0, INVALID) \ 48 /* Date.prototype.getMinutes ( ) */ \ 49 V("getMinutes", GetMinutes, 0, INVALID) \ 50 /* Date.prototype.getMonth ( ) */ \ 51 V("getMonth", GetMonth, 0, INVALID) \ 52 /* Date.prototype.getSeconds ( ) */ \ 53 V("getSeconds", GetSeconds, 0, INVALID) \ 54 /* Date.prototype.getTime ( ) */ \ 55 V("getTime", GetTime, 0, DateGetTime) \ 56 /* Date.prototype.getTimezoneOffset ( ) */ \ 57 V("getTimezoneOffset", GetTimezoneOffset, 0, INVALID) \ 58 /* Date.prototype.getUTCDate ( ) */ \ 59 V("getUTCDate", GetUTCDate, 0, INVALID) \ 60 /* Date.prototype.getUTCDay ( ) */ \ 61 V("getUTCDay", GetUTCDay, 0, INVALID) \ 62 /* Date.prototype.getUTCFullYear ( ) */ \ 63 V("getUTCFullYear", GetUTCFullYear, 0, INVALID) \ 64 /* Date.prototype.getUTCHours ( ) */ \ 65 V("getUTCHours", GetUTCHours, 0, INVALID) \ 66 /* Date.prototype.getUTCMilliseconds ( ) */ \ 67 V("getUTCMilliseconds", GetUTCMilliseconds, 0, INVALID) \ 68 /* Date.prototype.getUTCMinutes ( ) */ \ 69 V("getUTCMinutes", GetUTCMinutes, 0, INVALID) \ 70 /* Date.prototype.getUTCMonth ( ) */ \ 71 V("getUTCMonth", GetUTCMonth, 0, INVALID) \ 72 /* Date.prototype.getUTCSeconds ( ) */ \ 73 V("getUTCSeconds", GetUTCSeconds, 0, INVALID) \ 74 /* Date.prototype.setDate ( date ) */ \ 75 V("setDate", SetDate, 1, INVALID) \ 76 /* Date.prototype.setFullYear ( year [ , month [ , date ] ] ) */ \ 77 V("setFullYear", SetFullYear, 3, INVALID) \ 78 /* Date.prototype.setHours ( hour [ , min [ , sec [ , ms ] ] ] ) */ \ 79 V("setHours", SetHours, 4, INVALID) \ 80 /* Date.prototype.setMilliseconds ( ms ) */ \ 81 V("setMilliseconds", SetMilliseconds, 1, INVALID) \ 82 /* Date.prototype.setMinutes ( min [ , sec [ , ms ] ] ) */ \ 83 V("setMinutes", SetMinutes, 3, INVALID) \ 84 /* Date.prototype.setMonth ( month [ , date ] ) */ \ 85 V("setMonth", SetMonth, 2, INVALID) \ 86 /* Date.prototype.setSeconds ( sec [ , ms ] ) */ \ 87 V("setSeconds", SetSeconds, 2, INVALID) \ 88 /* Date.prototype.setTime ( time ) */ \ 89 V("setTime", SetTime, 1, INVALID) \ 90 /* Date.prototype.setUTCDate ( date ) */ \ 91 V("setUTCDate", SetUTCDate, 1, INVALID) \ 92 /* Date.prototype.setUTCFullYear ( year [ , month [ , date ] ] ) */ \ 93 V("setUTCFullYear", SetUTCFullYear, 3, INVALID) \ 94 /* Date.prototype.setUTCHours ( hour [ , min [ , sec [ , ms ] ] ] ) */ \ 95 V("setUTCHours", SetUTCHours, 4, INVALID) \ 96 /* Date.prototype.setUTCMilliseconds ( ms ) */ \ 97 V("setUTCMilliseconds", SetUTCMilliseconds, 1, INVALID) \ 98 /* Date.prototype.setUTCMinutes ( min [ , sec [ , ms ] ] ) */ \ 99 V("setUTCMinutes", SetUTCMinutes, 3, INVALID) \ 100 /* Date.prototype.setUTCMonth ( month [ , date ] ) */ \ 101 V("setUTCMonth", SetUTCMonth, 2, INVALID) \ 102 /* Date.prototype.setUTCSeconds ( sec [ , ms ] ) */ \ 103 V("setUTCSeconds", SetUTCSeconds, 2, INVALID) \ 104 /* Date.prototype.toDateString ( ) */ \ 105 V("toDateString", ToDateString, 0, INVALID) \ 106 /* Date.prototype.toISOString ( ) */ \ 107 V("toISOString", ToISOString, 0, INVALID) \ 108 /* Date.prototype.toJSON ( key ) */ \ 109 V("toJSON", ToJSON, 1, INVALID) \ 110 /* Date.prototype.toLocaleDateString ( [ reserved1 [ , reserved2 ] ] ) */ \ 111 V("toLocaleDateString", ToLocaleDateString, 0, INVALID) \ 112 /* Date.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] ) */ \ 113 V("toLocaleString", ToLocaleString, 0, INVALID) \ 114 /* Date.prototype.toLocaleTimeString ( [ reserved1 [ , reserved2 ] ] ) */ \ 115 V("toLocaleTimeString", ToLocaleTimeString, 0, INVALID) \ 116 /* Date.prototype.toString ( ) */ \ 117 V("toString", ToString, 0, INVALID) \ 118 /* Date.prototype.toTimeString ( ) */ \ 119 V("toTimeString", ToTimeString, 0, INVALID) \ 120 /* Date.prototype.toUTCString ( ) */ \ 121 V("toUTCString", ToUTCString, 0, INVALID) \ 122 /* Date.prototype.valueOf ( ) */ \ 123 V("valueOf", ValueOf, 0, INVALID) 124 125 namespace panda::ecmascript::builtins { 126 class BuiltinsDate : public base::BuiltinsBase { 127 public: 128 static constexpr int UTC_LENGTH = 7; 129 130 // 20.4.2 The Date Constructor 131 static JSTaggedValue DateConstructor(EcmaRuntimeCallInfo *argv); 132 133 // 20.4.3.1 Date.now ( ) 134 static JSTaggedValue Now(EcmaRuntimeCallInfo *argv); 135 136 // 20.4.3.4 Date.UTC ( year [ , month [ , date [ , hours [ , minutes [ , seconds [ , ms ] ] ] ] ] ] ) 137 static JSTaggedValue UTC(EcmaRuntimeCallInfo *argv); 138 139 static JSTaggedValue Parse(EcmaRuntimeCallInfo *argv); 140 141 // 20.4.4.2 Date.prototype.getDate ( ) 142 GET_DATE_VALUE(GetDate, DAYS, true); 143 144 // 20.4.4.3 Date.prototype.getDay ( ) 145 GET_DATE_VALUE(GetDay, WEEKDAY, true); 146 147 // 20.4.4.4 Date.prototype.getFullYear ( ) 148 GET_DATE_VALUE(GetFullYear, YEAR, true); 149 150 // 20.4.4.5 Date.prototype.getHours ( ) 151 GET_DATE_VALUE(GetHours, HOUR, true); 152 153 // 20.4.4.6 Date.prototype.getMilliseconds ( ) 154 GET_DATE_VALUE(GetMilliseconds, MS, true); 155 156 // 20.4.4.7 Date.prototype.getMinutes ( ) 157 GET_DATE_VALUE(GetMinutes, MIN, true); 158 159 // 20.4.4.8 Date.prototype.getMonth ( ) 160 GET_DATE_VALUE(GetMonth, MONTH, true); 161 162 // 20.4.4.9 Date.prototype.getSeconds ( ) 163 GET_DATE_VALUE(GetSeconds, SEC, true); 164 165 // 20.4.4.10 Date.prototype.getTime ( ) 166 static JSTaggedValue GetTime(EcmaRuntimeCallInfo *argv); 167 168 // 20.4.4.11 Date.prototype.getTimezoneOffset ( ) 169 GET_DATE_VALUE(GetTimezoneOffset, TIMEZONE, true); 170 171 // 20.4.4.12 Date.prototype.getUTCDate ( ) 172 GET_DATE_VALUE(GetUTCDate, DAYS, false); 173 174 // 20.4.4.13 Date.prototype.getUTCDay ( ) 175 GET_DATE_VALUE(GetUTCDay, WEEKDAY, false); 176 177 // 20.4.4.14 Date.prototype.getUTCFullYear ( ) 178 GET_DATE_VALUE(GetUTCFullYear, YEAR, false); 179 180 // 20.4.4.15 Date.prototype.getUTCHours ( ) 181 GET_DATE_VALUE(GetUTCHours, HOUR, false); 182 183 // 20.4.4.16 Date.prototype.getUTCMilliseconds ( ) 184 GET_DATE_VALUE(GetUTCMilliseconds, MS, false); 185 186 // 20.4.4.17 Date.prototype.getUTCMinutes ( ) 187 GET_DATE_VALUE(GetUTCMinutes, MIN, false); 188 189 // 20.4.4.18 Date.prototype.getUTCMonth ( ) 190 GET_DATE_VALUE(GetUTCMonth, MONTH, false); 191 192 // 20.4.4.19 Date.prototype.getUTCSeconds ( ) 193 GET_DATE_VALUE(GetUTCSeconds, SEC, false); 194 195 // 20.3.4.20 Date.prototype.setDate ( date ) 196 SET_DATE_VALUE(SetDate, CODE_SET_DATE, true); 197 198 // 20.3.4.21 Date.prototype.setFullYear ( year [ , month [ , date ] ] ) 199 SET_DATE_VALUE(SetFullYear, CODE_SET_FULL_YEAR, true); 200 201 // 20.3.4.22 Date.prototype.setHours ( hour [ , min [ , sec [ , ms ] ] ] ) 202 SET_DATE_VALUE(SetHours, CODE_SET_HOURS, true); 203 204 // 20.3.4.23 Date.prototype.setMilliseconds ( ms ) 205 SET_DATE_VALUE(SetMilliseconds, CODE_SET_MILLISECONDS, true); 206 207 // 20.3.4.24 Date.prototype.setMinutes ( min [ , sec [ , ms ] ] ) 208 SET_DATE_VALUE(SetMinutes, CODE_SET_MINUTES, true); 209 210 // 20.3.4.25 Date.prototype.setMonth ( month [ , date ] ) 211 SET_DATE_VALUE(SetMonth, CODE_SET_MONTH, true); 212 213 // 20.3.4.26 Date.prototype.setSeconds ( sec [ , ms ] ) 214 SET_DATE_VALUE(SetSeconds, CODE_SET_SECONDS, true); 215 216 // 20.3.4.27 Date.prototype.setTime ( time ) 217 static JSTaggedValue SetTime(EcmaRuntimeCallInfo *argv); 218 219 // 20.3.4.28 Date.prototype.setUTCDate ( date ) 220 SET_DATE_VALUE(SetUTCDate, CODE_SET_DATE, false); 221 222 // 20.3.4.29 Date.prototype.setUTCFullYear ( year [ , month [ , date ] ] ) 223 SET_DATE_VALUE(SetUTCFullYear, CODE_SET_FULL_YEAR, false); 224 225 // 20.3.4.30 Date.prototype.setUTCHours ( hour [ , min [ , sec [ , ms ] ] ] ) 226 SET_DATE_VALUE(SetUTCHours, CODE_SET_HOURS, false); 227 228 // 20.3.4.31 Date.prototype.setUTCMilliseconds ( ms ) 229 SET_DATE_VALUE(SetUTCMilliseconds, CODE_SET_MILLISECONDS, false); 230 231 // 20.3.4.32 Date.prototype.setUTCMinutes ( min [ , sec [, ms ] ] ) 232 SET_DATE_VALUE(SetUTCMinutes, CODE_SET_MINUTES, false); 233 234 // 20.3.4.33 Date.prototype.setUTCMonth ( month [ , date ] ) 235 SET_DATE_VALUE(SetUTCMonth, CODE_SET_MONTH, false); 236 237 // 20.3.4.34 Date.prototype.setUTCSeconds ( sec [ , ms ] ) 238 SET_DATE_VALUE(SetUTCSeconds, CODE_SET_SECONDS, false); 239 240 // 20.4.4.35 Date.prototype.toDateString ( ) 241 DATE_STRING(ToDateString); 242 243 // 20.4.4.36 Date.prototype.toISOString ( ) 244 DATE_TO_STRING(ToISOString); 245 246 // 20.4.4.37 Date.prototype.toJSON ( key ) 247 static JSTaggedValue ToJSON(EcmaRuntimeCallInfo *argv); 248 249 // 20.4.4.38 Date.prototype.toLocaleDateString ( [ reserved1 [ , reserved2 ] ] ) 250 static JSTaggedValue ToLocaleDateString(EcmaRuntimeCallInfo *argv); 251 252 // 20.4.4.39 Date.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] ) 253 static JSTaggedValue ToLocaleString(EcmaRuntimeCallInfo *argv); 254 255 // 20.4.4.40 Date.prototype.toLocaleTimeString ( [ reserved1 [ , reserved2 ] ] ) 256 static JSTaggedValue ToLocaleTimeString(EcmaRuntimeCallInfo *argv); 257 258 // 20.4.4.41 Date.prototype.toString ( ) 259 DATE_STRING(ToString); 260 261 // 20.4.4.42 Date.prototype.toTimeString ( ) 262 DATE_STRING(ToTimeString); 263 264 // 20.4.4.43 Date.prototype.toUTCString ( ) 265 DATE_STRING(ToUTCString); 266 267 // 20.4.4.44 Date.prototype.valueOf ( ) 268 static JSTaggedValue ValueOf(EcmaRuntimeCallInfo *argv); 269 270 // 20.4.4.45 Date.prototype [ @@toPrimitive ] 271 static JSTaggedValue ToPrimitive(EcmaRuntimeCallInfo *argv); 272 273 // Excluding the '@@' internal properties GetDateFunctions()274 static Span<const base::BuiltinFunctionEntry> GetDateFunctions() 275 { 276 return Span<const base::BuiltinFunctionEntry>(DATE_FUNCTIONS); 277 } 278 279 // Excluding the constructor and '@@' internal properties. GetDatePrototypeFunctions()280 static Span<const base::BuiltinFunctionEntry> GetDatePrototypeFunctions() 281 { 282 return Span<const base::BuiltinFunctionEntry>(DATE_PROTOTYPE_FUNCTIONS); 283 } 284 GetNumPrototypeInlinedProperties()285 static size_t GetNumPrototypeInlinedProperties() 286 { 287 // 2 : 2 more inline properties in Date.prototype: 288 // (1) Date.prototype.constructor 289 // (2) Date.prototype [ @@toPrimitive ] 290 return GetDatePrototypeFunctions().Size() + 2; 291 } 292 293 private: 294 #define BUILTIN_DATE_FUNCTION_ENTRY(name, func, length, builtinId) \ 295 base::BuiltinFunctionEntry::Create(name, BuiltinsDate::func, length, kungfu::BuiltinsStubCSigns::builtinId), 296 297 static constexpr std::array DATE_FUNCTIONS = { 298 BUILTIN_DATE_FUNCTIONS(BUILTIN_DATE_FUNCTION_ENTRY) 299 }; 300 static constexpr std::array DATE_PROTOTYPE_FUNCTIONS = { 301 BUILTIN_DATE_PROTOTYPE_FUNCTIONS(BUILTIN_DATE_FUNCTION_ENTRY) 302 }; 303 #undef BUILTIN_DATE_FUNCTION_ENTRY 304 static JSTaggedValue ExtractDateFields(JSThread *thread, uint32_t &length, EcmaRuntimeCallInfo *argv, 305 JSTaggedValue &timeValue); 306 307 // definition for set data code. 308 static constexpr uint32_t CODE_SET_DATE = 0x32; 309 static constexpr uint32_t CODE_SET_MILLISECONDS = 0x76; 310 static constexpr uint32_t CODE_SET_SECONDS = 0x75; 311 static constexpr uint32_t CODE_SET_MINUTES = 0x74; 312 static constexpr uint32_t CODE_SET_HOURS = 0x73; 313 static constexpr uint32_t CODE_SET_MONTH = 0x31; 314 static constexpr uint32_t CODE_SET_FULL_YEAR = 0x30; 315 static constexpr uint8_t CONSTRUCTOR_MAX_LENGTH = 7; 316 }; 317 } // namespace panda::ecmascript::builtins 318 #endif // ECMASCRIPT_BUILTINS_BUILTINS_DATE_H 319