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" |
8 #include "src/regexp/jsregexp-inl.h" | 9 #include "src/regexp/jsregexp-inl.h" |
9 #include "src/string-builder.h" | 10 #include "src/string-builder.h" |
10 #include "src/string-search.h" | 11 #include "src/string-search.h" |
11 | 12 |
12 namespace v8 { | 13 namespace v8 { |
13 namespace internal { | 14 namespace internal { |
14 | 15 |
15 | 16 |
16 // Perform string match of pattern on subject, starting at start index. | 17 // Perform string match of pattern on subject, starting at start index. |
17 // Caller must ensure that 0 <= start_index <= sub->length(), | 18 // Caller must ensure that 0 <= start_index <= sub->length(), |
(...skipping 1126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1144 if (is_one_byte) { | 1145 if (is_one_byte) { |
1145 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1146 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1146 isolate, result, isolate->factory()->NewRawOneByteString(length)); | 1147 isolate, result, isolate->factory()->NewRawOneByteString(length)); |
1147 } else { | 1148 } else { |
1148 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1149 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1149 isolate, result, isolate->factory()->NewRawTwoByteString(length)); | 1150 isolate, result, isolate->factory()->NewRawTwoByteString(length)); |
1150 } | 1151 } |
1151 return *result; | 1152 return *result; |
1152 } | 1153 } |
1153 | 1154 |
| 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 RUNTIME_FUNCTION(Runtime_StringLessThan) { | 1281 RUNTIME_FUNCTION(Runtime_StringLessThan) { |
1155 HandleScope handle_scope(isolate); | 1282 HandleScope handle_scope(isolate); |
1156 DCHECK_EQ(2, args.length()); | 1283 DCHECK_EQ(2, args.length()); |
1157 CONVERT_ARG_HANDLE_CHECKED(String, x, 0); | 1284 CONVERT_ARG_HANDLE_CHECKED(String, x, 0); |
1158 CONVERT_ARG_HANDLE_CHECKED(String, y, 1); | 1285 CONVERT_ARG_HANDLE_CHECKED(String, y, 1); |
1159 switch (String::Compare(x, y)) { | 1286 switch (String::Compare(x, y)) { |
1160 case ComparisonResult::kLessThan: | 1287 case ComparisonResult::kLessThan: |
1161 return isolate->heap()->true_value(); | 1288 return isolate->heap()->true_value(); |
1162 case ComparisonResult::kEqual: | 1289 case ComparisonResult::kEqual: |
1163 case ComparisonResult::kGreaterThan: | 1290 case ComparisonResult::kGreaterThan: |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1322 SealHandleScope shs(isolate); | 1449 SealHandleScope shs(isolate); |
1323 DCHECK(args.length() == 2); | 1450 DCHECK(args.length() == 2); |
1324 if (!args[0]->IsString()) return isolate->heap()->undefined_value(); | 1451 if (!args[0]->IsString()) return isolate->heap()->undefined_value(); |
1325 if (!args[1]->IsNumber()) return isolate->heap()->undefined_value(); | 1452 if (!args[1]->IsNumber()) return isolate->heap()->undefined_value(); |
1326 if (std::isinf(args.number_at(1))) return isolate->heap()->nan_value(); | 1453 if (std::isinf(args.number_at(1))) return isolate->heap()->nan_value(); |
1327 return __RT_impl_Runtime_StringCharCodeAtRT(args, isolate); | 1454 return __RT_impl_Runtime_StringCharCodeAtRT(args, isolate); |
1328 } | 1455 } |
1329 | 1456 |
1330 } // namespace internal | 1457 } // namespace internal |
1331 } // namespace v8 | 1458 } // namespace v8 |
OLD | NEW |