OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/runtime/runtime-utils.h" | 5 #include "src/runtime/runtime-utils.h" |
6 | 6 |
7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
8 #include "src/char-predicates-inl.h" | |
9 #include "src/regexp/jsregexp-inl.h" | 8 #include "src/regexp/jsregexp-inl.h" |
10 #include "src/string-builder.h" | 9 #include "src/string-builder.h" |
11 #include "src/string-search.h" | 10 #include "src/string-search.h" |
12 | 11 |
13 namespace v8 { | 12 namespace v8 { |
14 namespace internal { | 13 namespace internal { |
15 | 14 |
16 | 15 |
17 // Perform string match of pattern on subject, starting at start index. | 16 // Perform string match of pattern on subject, starting at start index. |
18 // Caller must ensure that 0 <= start_index <= sub->length(), | 17 // Caller must ensure that 0 <= start_index <= sub->length(), |
(...skipping 1126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1145 if (is_one_byte) { | 1144 if (is_one_byte) { |
1146 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1145 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1147 isolate, result, isolate->factory()->NewRawOneByteString(length)); | 1146 isolate, result, isolate->factory()->NewRawOneByteString(length)); |
1148 } else { | 1147 } else { |
1149 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1148 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1150 isolate, result, isolate->factory()->NewRawTwoByteString(length)); | 1149 isolate, result, isolate->factory()->NewRawTwoByteString(length)); |
1151 } | 1150 } |
1152 return *result; | 1151 return *result; |
1153 } | 1152 } |
1154 | 1153 |
1155 // anonymous namespace for URIEncode helper functions | |
1156 namespace { | |
1157 | |
1158 bool IsUnescapePredicateInUriComponent(uc16 c) { | |
1159 if (IsAlphaNumeric(c)) { | |
1160 return true; | |
1161 } | |
1162 | |
1163 switch (c) { | |
1164 case '!': | |
1165 case '\'': | |
1166 case '(': | |
1167 case ')': | |
1168 case '*': | |
1169 case '-': | |
1170 case '.': | |
1171 case '_': | |
1172 case '~': | |
1173 return true; | |
1174 default: | |
1175 return false; | |
1176 } | |
1177 } | |
1178 | |
1179 bool IsUriSeparator(uc16 c) { | |
1180 switch (c) { | |
1181 case '#': | |
1182 case ':': | |
1183 case ';': | |
1184 case '/': | |
1185 case '?': | |
1186 case '$': | |
1187 case '&': | |
1188 case '+': | |
1189 case ',': | |
1190 case '@': | |
1191 case '=': | |
1192 return true; | |
1193 default: | |
1194 return false; | |
1195 } | |
1196 } | |
1197 | |
1198 void AddHexEncodedToBuffer(uint8_t octet, List<uint8_t>* buffer) { | |
1199 buffer->Add('%'); | |
1200 buffer->Add(HexCharOfValue(octet >> 4)); | |
1201 buffer->Add(HexCharOfValue(octet & 0x0F)); | |
1202 } | |
1203 | |
1204 void EncodeSingle(uc16 c, List<uint8_t>* buffer) { | |
1205 uint8_t x = (c >> 12) & 0xF; | |
1206 uint8_t y = (c >> 6) & 63; | |
1207 uint8_t z = c & 63; | |
1208 if (c <= 0x007F) { | |
1209 AddHexEncodedToBuffer(c, buffer); | |
1210 } else if (c <= 0x07FF) { | |
1211 AddHexEncodedToBuffer(y + 192, buffer); | |
1212 AddHexEncodedToBuffer(z + 128, buffer); | |
1213 } else { | |
1214 AddHexEncodedToBuffer(x + 224, buffer); | |
1215 AddHexEncodedToBuffer(y + 128, buffer); | |
1216 AddHexEncodedToBuffer(z + 128, buffer); | |
1217 } | |
1218 } | |
1219 | |
1220 void EncodePair(uc16 cc1, uc16 cc2, List<uint8_t>* buffer) { | |
1221 uint8_t u = ((cc1 >> 6) & 0xF) + 1; | |
1222 uint8_t w = (cc1 >> 2) & 0xF; | |
1223 uint8_t x = cc1 & 3; | |
1224 uint8_t y = (cc2 >> 6) & 0xF; | |
1225 uint8_t z = cc2 & 63; | |
1226 AddHexEncodedToBuffer((u >> 2) + 240, buffer); | |
1227 AddHexEncodedToBuffer((((u & 3) << 4) | w) + 128, buffer); | |
1228 AddHexEncodedToBuffer(((x << 4) | y) + 128, buffer); | |
1229 AddHexEncodedToBuffer(z + 128, buffer); | |
1230 } | |
1231 | |
1232 } // anonymous namespace | |
1233 | |
1234 RUNTIME_FUNCTION(Runtime_URIEncode) { | |
1235 HandleScope scope(isolate); | |
1236 DCHECK(args.length() == 2); | |
1237 CONVERT_ARG_HANDLE_CHECKED(String, uri, 0); | |
1238 CONVERT_BOOLEAN_ARG_CHECKED(is_uri, 1); | |
1239 | |
1240 uri = String::Flatten(uri); | |
1241 int uri_length = uri->length(); | |
1242 List<uint8_t> buffer(uri_length); | |
1243 | |
1244 { | |
1245 DisallowHeapAllocation no_gc; | |
1246 String::FlatContent uri_content = uri->GetFlatContent(); | |
1247 | |
1248 for (int k = 0; k < uri_length; k++) { | |
1249 uc16 cc1 = uri_content.Get(k); | |
1250 if (unibrow::Utf16::IsLeadSurrogate(cc1)) { | |
1251 k++; | |
1252 if (k < uri_length) { | |
1253 uc16 cc2 = uri->Get(k); | |
1254 if (unibrow::Utf16::IsTrailSurrogate(cc2)) { | |
1255 EncodePair(cc1, cc2, &buffer); | |
1256 continue; | |
1257 } | |
1258 } | |
1259 } else if (!unibrow::Utf16::IsTrailSurrogate(cc1)) { | |
1260 if (IsUnescapePredicateInUriComponent(cc1) || | |
1261 (is_uri && IsUriSeparator(cc1))) { | |
1262 buffer.Add(cc1); | |
1263 } else { | |
1264 EncodeSingle(cc1, &buffer); | |
1265 } | |
1266 continue; | |
1267 } | |
1268 | |
1269 AllowHeapAllocation allocate_error_and_return; | |
1270 THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewURIError()); | |
1271 } | |
1272 } | |
1273 | |
1274 Handle<String> result; | |
1275 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
1276 isolate, result, | |
1277 isolate->factory()->NewStringFromOneByte(buffer.ToConstVector())); | |
1278 return *result; | |
1279 } | |
1280 | 1154 |
1281 RUNTIME_FUNCTION(Runtime_StringLessThan) { | 1155 RUNTIME_FUNCTION(Runtime_StringLessThan) { |
1282 HandleScope handle_scope(isolate); | 1156 HandleScope handle_scope(isolate); |
1283 DCHECK_EQ(2, args.length()); | 1157 DCHECK_EQ(2, args.length()); |
1284 CONVERT_ARG_HANDLE_CHECKED(String, x, 0); | 1158 CONVERT_ARG_HANDLE_CHECKED(String, x, 0); |
1285 CONVERT_ARG_HANDLE_CHECKED(String, y, 1); | 1159 CONVERT_ARG_HANDLE_CHECKED(String, y, 1); |
1286 switch (String::Compare(x, y)) { | 1160 switch (String::Compare(x, y)) { |
1287 case ComparisonResult::kLessThan: | 1161 case ComparisonResult::kLessThan: |
1288 return isolate->heap()->true_value(); | 1162 return isolate->heap()->true_value(); |
1289 case ComparisonResult::kEqual: | 1163 case ComparisonResult::kEqual: |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1449 SealHandleScope shs(isolate); | 1323 SealHandleScope shs(isolate); |
1450 DCHECK(args.length() == 2); | 1324 DCHECK(args.length() == 2); |
1451 if (!args[0]->IsString()) return isolate->heap()->undefined_value(); | 1325 if (!args[0]->IsString()) return isolate->heap()->undefined_value(); |
1452 if (!args[1]->IsNumber()) return isolate->heap()->undefined_value(); | 1326 if (!args[1]->IsNumber()) return isolate->heap()->undefined_value(); |
1453 if (std::isinf(args.number_at(1))) return isolate->heap()->nan_value(); | 1327 if (std::isinf(args.number_at(1))) return isolate->heap()->nan_value(); |
1454 return __RT_impl_Runtime_StringCharCodeAtRT(args, isolate); | 1328 return __RT_impl_Runtime_StringCharCodeAtRT(args, isolate); |
1455 } | 1329 } |
1456 | 1330 |
1457 } // namespace internal | 1331 } // namespace internal |
1458 } // namespace v8 | 1332 } // namespace v8 |
OLD | NEW |