MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

optimize number fast paths

+38 -23
+38 -23
src/numbers.cc
··· 29 29 static constexpr size_t kExponentialBufferSize = 30 30 DoubleToStringConverter::kMaxExponentialDigits + 8 + 1; 31 31 32 + static const StringToDoubleConverter kDecimalStringConverter( 33 + 0, 0.0, 34 + std::numeric_limits<double>::quiet_NaN(), 35 + "Infinity", "NaN" 36 + ); 37 + 38 + static const StringToDoubleConverter kJsNumberStringConverter( 39 + StringToDoubleConverter::ALLOW_HEX, 0.0, 40 + std::numeric_limits<double>::quiet_NaN(), 41 + "Infinity", "NaN" 42 + ); 43 + 44 + static const StringToDoubleConverter kParseFloatStringConverter( 45 + StringToDoubleConverter::ALLOW_TRAILING_JUNK, 0.0, 46 + std::numeric_limits<double>::quiet_NaN(), 47 + "Infinity", "NaN" 48 + ); 49 + 50 + static bool is_ascii_js_string_trim_byte(unsigned char ch) { 51 + return 52 + ch == ' ' || ch == '\t' || ch == '\n' || 53 + ch == '\v' || ch == '\f' || ch == '\r'; 54 + } 55 + 32 56 #define JS_TRIM_TOKEN(bytes) { bytes, sizeof(bytes) - 1 } 33 57 static constexpr JsTrimToken kJsStringTrimTokens[] = { 34 - JS_TRIM_TOKEN("\t"), 35 - JS_TRIM_TOKEN("\n"), 36 - JS_TRIM_TOKEN("\v"), 37 - JS_TRIM_TOKEN("\f"), 38 - JS_TRIM_TOKEN("\r"), 39 - JS_TRIM_TOKEN(" "), 40 58 JS_TRIM_TOKEN("\xc2""\xa0"), 41 59 JS_TRIM_TOKEN("\xe1""\x9a""\x80"), 42 60 JS_TRIM_TOKEN("\xe2""\x80""\x80"), ··· 60 78 #undef JS_TRIM_TOKEN 61 79 62 80 static size_t js_string_trim_prefix_len(const char *str, size_t len) { 81 + if (len == 0) return 0; 82 + 83 + unsigned char first = (unsigned char)str[0]; 84 + if (first < 0x80) return is_ascii_js_string_trim_byte(first) ? 1 : 0; 85 + 63 86 for (const JsTrimToken &token : kJsStringTrimTokens) 64 87 if (len >= token.len && std::memcmp(str, token.bytes, token.len) == 0) return token.len; 65 88 return 0; 66 89 } 67 90 68 91 static size_t js_string_trim_suffix_len(const char *str, size_t len) { 92 + if (len == 0) return 0; 93 + 94 + unsigned char last = (unsigned char)str[len - 1]; 95 + if (last < 0x80) return is_ascii_js_string_trim_byte(last) ? 1 : 0; 96 + 69 97 for (const JsTrimToken &token : kJsStringTrimTokens) 70 98 if (len >= token.len && std::memcmp(str + len - token.len, token.bytes, token.len) == 0) return token.len; 71 99 return 0; ··· 158 186 return true; 159 187 } 160 188 161 - int flags = 0; 162 - if (mode == ANT_NUMBER_PARSE_JS_NUMBER) 163 - flags = 164 - StringToDoubleConverter::ALLOW_HEX | 165 - StringToDoubleConverter::ALLOW_LEADING_SPACES | 166 - StringToDoubleConverter::ALLOW_TRAILING_SPACES; 167 - else if (mode == ANT_NUMBER_PARSE_FLOAT_PREFIX) 168 - flags = 169 - StringToDoubleConverter::ALLOW_LEADING_SPACES | 170 - StringToDoubleConverter::ALLOW_TRAILING_JUNK; 171 - 172 - StringToDoubleConverter converter( 173 - flags, 0.0, 174 - std::numeric_limits<double>::quiet_NaN(), 175 - "Infinity", "NaN" 176 - ); 189 + const StringToDoubleConverter *converter = &kDecimalStringConverter; 190 + if (mode == ANT_NUMBER_PARSE_JS_NUMBER) converter = &kJsNumberStringConverter; 191 + else if (mode == ANT_NUMBER_PARSE_FLOAT_PREFIX) converter = &kParseFloatStringConverter; 177 192 178 193 int count = 0; 179 - double value = converter.StringToDouble(str, (int)len, &count); 194 + double value = converter->StringToDouble(str, (int)len, &count); 180 195 181 196 if (count <= 0) return false; 182 197 if (mode != ANT_NUMBER_PARSE_FLOAT_PREFIX && (size_t)count != len) return false;