| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. | 
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without | 
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are | 
| 4 // met: | 4 // met: | 
| 5 // | 5 // | 
| 6 //     * Redistributions of source code must retain the above copyright | 6 //     * Redistributions of source code must retain the above copyright | 
| 7 //       notice, this list of conditions and the following disclaimer. | 7 //       notice, this list of conditions and the following disclaimer. | 
| 8 //     * Redistributions in binary form must reproduce the above | 8 //     * Redistributions in binary form must reproduce the above | 
| 9 //       copyright notice, this list of conditions and the following | 9 //       copyright notice, this list of conditions and the following | 
| 10 //       disclaimer in the documentation and/or other materials provided | 10 //       disclaimer in the documentation and/or other materials provided | 
| (...skipping 4347 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4358   ASSERT(args.length() == 3); | 4358   ASSERT(args.length() == 3); | 
| 4359 | 4359 | 
| 4360   CONVERT_ARG_HANDLE_CHECKED(String, sub, 0); | 4360   CONVERT_ARG_HANDLE_CHECKED(String, sub, 0); | 
| 4361   CONVERT_ARG_HANDLE_CHECKED(String, pat, 1); | 4361   CONVERT_ARG_HANDLE_CHECKED(String, pat, 1); | 
| 4362 | 4362 | 
| 4363   Object* index = args[2]; | 4363   Object* index = args[2]; | 
| 4364   uint32_t start_index; | 4364   uint32_t start_index; | 
| 4365   if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1); | 4365   if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1); | 
| 4366 | 4366 | 
| 4367   RUNTIME_ASSERT(start_index <= static_cast<uint32_t>(sub->length())); | 4367   RUNTIME_ASSERT(start_index <= static_cast<uint32_t>(sub->length())); | 
| 4368   int position = | 4368   int position = Runtime::StringMatch(isolate, sub, pat, start_index); | 
| 4369       Runtime::StringMatch(isolate, sub, pat, start_index); |  | 
| 4370   return Smi::FromInt(position); | 4369   return Smi::FromInt(position); | 
| 4371 } | 4370 } | 
| 4372 | 4371 | 
| 4373 | 4372 | 
| 4374 template <typename schar, typename pchar> | 4373 template <typename schar, typename pchar> | 
| 4375 static int StringMatchBackwards(Vector<const schar> subject, | 4374 static int StringMatchBackwards(Vector<const schar> subject, | 
| 4376                                 Vector<const pchar> pattern, | 4375                                 Vector<const pchar> pattern, | 
| 4377                                 int idx) { | 4376                                 int idx) { | 
| 4378   int pattern_length = pattern.length(); | 4377   int pattern_length = pattern.length(); | 
| 4379   ASSERT(pattern_length >= 1); | 4378   ASSERT(pattern_length >= 1); | 
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4459                                       pat_vector, | 4458                                       pat_vector, | 
| 4460                                       start_index); | 4459                                       start_index); | 
| 4461     } | 4460     } | 
| 4462   } | 4461   } | 
| 4463 | 4462 | 
| 4464   return Smi::FromInt(position); | 4463   return Smi::FromInt(position); | 
| 4465 } | 4464 } | 
| 4466 | 4465 | 
| 4467 | 4466 | 
| 4468 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringLocaleCompare) { | 4467 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringLocaleCompare) { | 
| 4469   SealHandleScope shs(isolate); | 4468   HandleScope handle_scope(isolate); | 
| 4470   ASSERT(args.length() == 2); | 4469   ASSERT(args.length() == 2); | 
| 4471 | 4470 | 
| 4472   CONVERT_ARG_CHECKED(String, str1, 0); | 4471   CONVERT_ARG_HANDLE_CHECKED(String, str1, 0); | 
| 4473   CONVERT_ARG_CHECKED(String, str2, 1); | 4472   CONVERT_ARG_HANDLE_CHECKED(String, str2, 1); | 
| 4474 | 4473 | 
| 4475   if (str1 == str2) return Smi::FromInt(0);  // Equal. | 4474   if (str1.is_identical_to(str2)) return Smi::FromInt(0);  // Equal. | 
| 4476   int str1_length = str1->length(); | 4475   int str1_length = str1->length(); | 
| 4477   int str2_length = str2->length(); | 4476   int str2_length = str2->length(); | 
| 4478 | 4477 | 
| 4479   // Decide trivial cases without flattening. | 4478   // Decide trivial cases without flattening. | 
| 4480   if (str1_length == 0) { | 4479   if (str1_length == 0) { | 
| 4481     if (str2_length == 0) return Smi::FromInt(0);  // Equal. | 4480     if (str2_length == 0) return Smi::FromInt(0);  // Equal. | 
| 4482     return Smi::FromInt(-str2_length); | 4481     return Smi::FromInt(-str2_length); | 
| 4483   } else { | 4482   } else { | 
| 4484     if (str2_length == 0) return Smi::FromInt(str1_length); | 4483     if (str2_length == 0) return Smi::FromInt(str1_length); | 
| 4485   } | 4484   } | 
| 4486 | 4485 | 
| 4487   int end = str1_length < str2_length ? str1_length : str2_length; | 4486   int end = str1_length < str2_length ? str1_length : str2_length; | 
| 4488 | 4487 | 
| 4489   // No need to flatten if we are going to find the answer on the first | 4488   // No need to flatten if we are going to find the answer on the first | 
| 4490   // character.  At this point we know there is at least one character | 4489   // character.  At this point we know there is at least one character | 
| 4491   // in each string, due to the trivial case handling above. | 4490   // in each string, due to the trivial case handling above. | 
| 4492   int d = str1->Get(0) - str2->Get(0); | 4491   int d = str1->Get(0) - str2->Get(0); | 
| 4493   if (d != 0) return Smi::FromInt(d); | 4492   if (d != 0) return Smi::FromInt(d); | 
| 4494 | 4493 | 
| 4495   str1->TryFlatten(); | 4494   str1 = String::Flatten(str1); | 
| 4496   str2->TryFlatten(); | 4495   str2 = String::Flatten(str2); | 
| 4497 | 4496 | 
| 4498   ConsStringIteratorOp* op1 = | 4497   DisallowHeapAllocation no_gc; | 
| 4499       isolate->runtime_state()->string_locale_compare_it1(); | 4498   String::FlatContent flat1 = str1->GetFlatContent(); | 
| 4500   ConsStringIteratorOp* op2 = | 4499   String::FlatContent flat2 = str2->GetFlatContent(); | 
| 4501       isolate->runtime_state()->string_locale_compare_it2(); |  | 
| 4502   // TODO(dcarney) Can do array compares here more efficiently. |  | 
| 4503   StringCharacterStream stream1(str1, op1); |  | 
| 4504   StringCharacterStream stream2(str2, op2); |  | 
| 4505 | 4500 | 
| 4506   for (int i = 0; i < end; i++) { | 4501   for (int i = 0; i < end; i++) { | 
| 4507     uint16_t char1 = stream1.GetNext(); | 4502     if (flat1.Get(i) != flat2.Get(i)) { | 
| 4508     uint16_t char2 = stream2.GetNext(); | 4503       return Smi::FromInt(flat1.Get(i) - flat2.Get(i)); | 
| 4509     if (char1 != char2) return Smi::FromInt(char1 - char2); | 4504     } | 
| 4510   } | 4505   } | 
| 4511 | 4506 | 
| 4512   return Smi::FromInt(str1_length - str2_length); | 4507   return Smi::FromInt(str1_length - str2_length); | 
| 4513 } | 4508 } | 
| 4514 | 4509 | 
| 4515 | 4510 | 
| 4516 RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_SubString) { | 4511 RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_SubString) { | 
| 4517   HandleScope scope(isolate); | 4512   HandleScope scope(isolate); | 
| 4518   ASSERT(args.length() == 3); | 4513   ASSERT(args.length() == 3); | 
| 4519 | 4514 | 
| (...skipping 1546 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 6066     } else { | 6061     } else { | 
| 6067       Handle<Object> initial_prototype(isolate->initial_object_prototype()); | 6062       Handle<Object> initial_prototype(isolate->initial_object_prototype()); | 
| 6068       Handle<Object> result = | 6063       Handle<Object> result = | 
| 6069           Object::GetElement(isolate, initial_prototype, index); | 6064           Object::GetElement(isolate, initial_prototype, index); | 
| 6070       RETURN_IF_EMPTY_HANDLE(isolate, result); | 6065       RETURN_IF_EMPTY_HANDLE(isolate, result); | 
| 6071       return *result; | 6066       return *result; | 
| 6072     } | 6067     } | 
| 6073   } | 6068   } | 
| 6074 | 6069 | 
| 6075   // Handle special arguments properties. | 6070   // Handle special arguments properties. | 
| 6076   if (key->Equals(isolate->heap()->length_string())) return Smi::FromInt(n); | 6071   if (String::Equals(isolate->factory()->length_string(), key)) { | 
| 6077   if (key->Equals(isolate->heap()->callee_string())) { | 6072     return Smi::FromInt(n); | 
|  | 6073   } | 
|  | 6074   if (String::Equals(isolate->factory()->callee_string(), key)) { | 
| 6078     JSFunction* function = frame->function(); | 6075     JSFunction* function = frame->function(); | 
| 6079     if (function->shared()->strict_mode() == STRICT) { | 6076     if (function->shared()->strict_mode() == STRICT) { | 
| 6080       return isolate->Throw(*isolate->factory()->NewTypeError( | 6077       return isolate->Throw(*isolate->factory()->NewTypeError( | 
| 6081           "strict_arguments_callee", HandleVector<Object>(NULL, 0))); | 6078           "strict_arguments_callee", HandleVector<Object>(NULL, 0))); | 
| 6082     } | 6079     } | 
| 6083     return function; | 6080     return function; | 
| 6084   } | 6081   } | 
| 6085 | 6082 | 
| 6086   // Lookup in the initial Object.prototype object. | 6083   // Lookup in the initial Object.prototype object. | 
| 6087   return isolate->initial_object_prototype()->GetProperty(*key); | 6084   return isolate->initial_object_prototype()->GetProperty(*key); | 
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 6167 | 6164 | 
| 6168   for (int i = from + 1; i < to; i++) { | 6165   for (int i = from + 1; i < to; i++) { | 
| 6169     d = 10 * d + (s[i] - '0'); | 6166     d = 10 * d + (s[i] - '0'); | 
| 6170   } | 6167   } | 
| 6171 | 6168 | 
| 6172   return d; | 6169   return d; | 
| 6173 } | 6170 } | 
| 6174 | 6171 | 
| 6175 | 6172 | 
| 6176 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToNumber) { | 6173 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToNumber) { | 
| 6177   SealHandleScope shs(isolate); | 6174   HandleScope handle_scope(isolate); | 
| 6178   ASSERT(args.length() == 1); | 6175   ASSERT(args.length() == 1); | 
| 6179   CONVERT_ARG_CHECKED(String, subject, 0); | 6176   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); | 
| 6180   subject->TryFlatten(); | 6177   subject = String::Flatten(subject); | 
| 6181 | 6178 | 
| 6182   // Fast case: short integer or some sorts of junk values. | 6179   // Fast case: short integer or some sorts of junk values. | 
| 6183   int len = subject->length(); |  | 
| 6184   if (subject->IsSeqOneByteString()) { | 6180   if (subject->IsSeqOneByteString()) { | 
|  | 6181     int len = subject->length(); | 
| 6185     if (len == 0) return Smi::FromInt(0); | 6182     if (len == 0) return Smi::FromInt(0); | 
| 6186 | 6183 | 
| 6187     uint8_t const* data = SeqOneByteString::cast(subject)->GetChars(); | 6184     DisallowHeapAllocation no_gc; | 
|  | 6185     uint8_t const* data = Handle<SeqOneByteString>::cast(subject)->GetChars(); | 
| 6188     bool minus = (data[0] == '-'); | 6186     bool minus = (data[0] == '-'); | 
| 6189     int start_pos = (minus ? 1 : 0); | 6187     int start_pos = (minus ? 1 : 0); | 
| 6190 | 6188 | 
| 6191     if (start_pos == len) { | 6189     if (start_pos == len) { | 
| 6192       return isolate->heap()->nan_value(); | 6190       return isolate->heap()->nan_value(); | 
| 6193     } else if (data[start_pos] > '9') { | 6191     } else if (data[start_pos] > '9') { | 
| 6194       // Fast check for a junk value. A valid string may start from a | 6192       // Fast check for a junk value. A valid string may start from a | 
| 6195       // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit or | 6193       // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit | 
| 6196       // the 'I' character ('Infinity'). All of that have codes not greater than | 6194       // or the 'I' character ('Infinity'). All of that have codes not greater | 
| 6197       // '9' except 'I' and  . | 6195       // than '9' except 'I' and  . | 
| 6198       if (data[start_pos] != 'I' && data[start_pos] != 0xa0) { | 6196       if (data[start_pos] != 'I' && data[start_pos] != 0xa0) { | 
| 6199         return isolate->heap()->nan_value(); | 6197         return isolate->heap()->nan_value(); | 
| 6200       } | 6198       } | 
| 6201     } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) { | 6199     } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) { | 
| 6202       // The maximal/minimal smi has 10 digits. If the string has less digits we | 6200       // The maximal/minimal smi has 10 digits. If the string has less digits | 
| 6203       // know it will fit into the smi-data type. | 6201       // we know it will fit into the smi-data type. | 
| 6204       int d = ParseDecimalInteger(data, start_pos, len); | 6202       int d = ParseDecimalInteger(data, start_pos, len); | 
| 6205       if (minus) { | 6203       if (minus) { | 
| 6206         if (d == 0) return isolate->heap()->minus_zero_value(); | 6204         if (d == 0) return isolate->heap()->minus_zero_value(); | 
| 6207         d = -d; | 6205         d = -d; | 
| 6208       } else if (!subject->HasHashCode() && | 6206       } else if (!subject->HasHashCode() && | 
| 6209                  len <= String::kMaxArrayIndexSize && | 6207                  len <= String::kMaxArrayIndexSize && | 
| 6210                  (len == 1 || data[0] != '0')) { | 6208                  (len == 1 || data[0] != '0')) { | 
| 6211         // String hash is not calculated yet but all the data are present. | 6209         // String hash is not calculated yet but all the data are present. | 
| 6212         // Update the hash field to speed up sequential convertions. | 6210         // Update the hash field to speed up sequential convertions. | 
| 6213         uint32_t hash = StringHasher::MakeArrayIndexHash(d, len); | 6211         uint32_t hash = StringHasher::MakeArrayIndexHash(d, len); | 
| 6214 #ifdef DEBUG | 6212 #ifdef DEBUG | 
| 6215         subject->Hash();  // Force hash calculation. | 6213         subject->Hash();  // Force hash calculation. | 
| 6216         ASSERT_EQ(static_cast<int>(subject->hash_field()), | 6214         ASSERT_EQ(static_cast<int>(subject->hash_field()), | 
| 6217                   static_cast<int>(hash)); | 6215                   static_cast<int>(hash)); | 
| 6218 #endif | 6216 #endif | 
| 6219         subject->set_hash_field(hash); | 6217         subject->set_hash_field(hash); | 
| 6220       } | 6218       } | 
| 6221       return Smi::FromInt(d); | 6219       return Smi::FromInt(d); | 
| 6222     } | 6220     } | 
| 6223   } | 6221   } | 
| 6224 | 6222 | 
| 6225   // Slower case. | 6223   // Slower case. | 
| 6226   int flags = ALLOW_HEX; | 6224   int flags = ALLOW_HEX; | 
| 6227   if (FLAG_harmony_numeric_literals) { | 6225   if (FLAG_harmony_numeric_literals) { | 
| 6228     // The current spec draft has not updated "ToNumber Applied to the String | 6226     // The current spec draft has not updated "ToNumber Applied to the String | 
| 6229     // Type", https://bugs.ecmascript.org/show_bug.cgi?id=1584 | 6227     // Type", https://bugs.ecmascript.org/show_bug.cgi?id=1584 | 
| 6230     flags |= ALLOW_OCTAL | ALLOW_BINARY; | 6228     flags |= ALLOW_OCTAL | ALLOW_BINARY; | 
| 6231   } | 6229   } | 
| 6232   return isolate->heap()->NumberFromDouble( | 6230 | 
| 6233       StringToDouble(isolate->unicode_cache(), subject, flags)); | 6231   double value; | 
|  | 6232 | 
|  | 6233   { DisallowHeapAllocation no_gc; | 
|  | 6234     String::FlatContent flat = subject->GetFlatContent(); | 
|  | 6235 | 
|  | 6236     // ECMA-262 section 15.1.2.3, empty string is NaN | 
|  | 6237     if (flat.IsAscii()) { | 
|  | 6238       value = StringToDouble( | 
|  | 6239           isolate->unicode_cache(), flat.ToOneByteVector(), flags); | 
|  | 6240     } else { | 
|  | 6241       value = StringToDouble( | 
|  | 6242           isolate->unicode_cache(), flat.ToUC16Vector(), flags); | 
|  | 6243     } | 
|  | 6244   } | 
|  | 6245 | 
|  | 6246   return *isolate->factory()->NewNumber(value); | 
| 6234 } | 6247 } | 
| 6235 | 6248 | 
| 6236 | 6249 | 
| 6237 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewString) { | 6250 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewString) { | 
| 6238   SealHandleScope shs(isolate); | 6251   SealHandleScope shs(isolate); | 
| 6239   CONVERT_SMI_ARG_CHECKED(length, 0); | 6252   CONVERT_SMI_ARG_CHECKED(length, 0); | 
| 6240   CONVERT_BOOLEAN_ARG_CHECKED(is_one_byte, 1); | 6253   CONVERT_BOOLEAN_ARG_CHECKED(is_one_byte, 1); | 
| 6241   if (length == 0) return isolate->heap()->empty_string(); | 6254   if (length == 0) return isolate->heap()->empty_string(); | 
| 6242   if (is_one_byte) { | 6255   if (is_one_byte) { | 
| 6243     return isolate->heap()->AllocateRawOneByteString(length); | 6256     return isolate->heap()->AllocateRawOneByteString(length); | 
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 6297 | 6310 | 
| 6298 RUNTIME_FUNCTION(MaybeObject*, Runtime_BasicJSONStringify) { | 6311 RUNTIME_FUNCTION(MaybeObject*, Runtime_BasicJSONStringify) { | 
| 6299   HandleScope scope(isolate); | 6312   HandleScope scope(isolate); | 
| 6300   ASSERT(args.length() == 1); | 6313   ASSERT(args.length() == 1); | 
| 6301   BasicJsonStringifier stringifier(isolate); | 6314   BasicJsonStringifier stringifier(isolate); | 
| 6302   return stringifier.Stringify(Handle<Object>(args[0], isolate)); | 6315   return stringifier.Stringify(Handle<Object>(args[0], isolate)); | 
| 6303 } | 6316 } | 
| 6304 | 6317 | 
| 6305 | 6318 | 
| 6306 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseInt) { | 6319 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseInt) { | 
| 6307   SealHandleScope shs(isolate); | 6320   HandleScope handle_scope(isolate); | 
|  | 6321   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); | 
|  | 6322   CONVERT_SMI_ARG_CHECKED(radix, 1); | 
|  | 6323   RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36)); | 
| 6308 | 6324 | 
| 6309   CONVERT_ARG_CHECKED(String, s, 0); | 6325   subject = String::Flatten(subject); | 
| 6310   CONVERT_SMI_ARG_CHECKED(radix, 1); | 6326   double value; | 
| 6311 | 6327 | 
| 6312   s->TryFlatten(); | 6328   { DisallowHeapAllocation no_gc; | 
|  | 6329     String::FlatContent flat = subject->GetFlatContent(); | 
| 6313 | 6330 | 
| 6314   RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36)); | 6331     // ECMA-262 section 15.1.2.3, empty string is NaN | 
| 6315   double value = StringToInt(isolate->unicode_cache(), s, radix); | 6332     if (flat.IsAscii()) { | 
| 6316   return isolate->heap()->NumberFromDouble(value); | 6333       value = StringToInt( | 
|  | 6334           isolate->unicode_cache(), flat.ToOneByteVector(), radix); | 
|  | 6335     } else { | 
|  | 6336       value = StringToInt( | 
|  | 6337           isolate->unicode_cache(), flat.ToUC16Vector(), radix); | 
|  | 6338     } | 
|  | 6339   } | 
|  | 6340 | 
|  | 6341   return *isolate->factory()->NewNumber(value); | 
| 6317 } | 6342 } | 
| 6318 | 6343 | 
| 6319 | 6344 | 
| 6320 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseFloat) { | 6345 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseFloat) { | 
| 6321   SealHandleScope shs(isolate); | 6346   HandleScope shs(isolate); | 
| 6322   CONVERT_ARG_CHECKED(String, str, 0); | 6347   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); | 
| 6323 | 6348 | 
| 6324   // ECMA-262 section 15.1.2.3, empty string is NaN | 6349   subject = String::Flatten(subject); | 
| 6325   double value = StringToDouble(isolate->unicode_cache(), | 6350   double value; | 
| 6326                                 str, ALLOW_TRAILING_JUNK, OS::nan_value()); |  | 
| 6327 | 6351 | 
| 6328   // Create a number object from the value. | 6352   { DisallowHeapAllocation no_gc; | 
| 6329   return isolate->heap()->NumberFromDouble(value); | 6353     String::FlatContent flat = subject->GetFlatContent(); | 
|  | 6354 | 
|  | 6355     // ECMA-262 section 15.1.2.3, empty string is NaN | 
|  | 6356     if (flat.IsAscii()) { | 
|  | 6357       value = StringToDouble(isolate->unicode_cache(), | 
|  | 6358                              flat.ToOneByteVector(), | 
|  | 6359                              ALLOW_TRAILING_JUNK, | 
|  | 6360                              OS::nan_value()); | 
|  | 6361     } else { | 
|  | 6362       ASSERT(flat.IsTwoByte()); | 
|  | 6363       value = StringToDouble(isolate->unicode_cache(), | 
|  | 6364                              flat.ToUC16Vector(), | 
|  | 6365                              ALLOW_TRAILING_JUNK, | 
|  | 6366                              OS::nan_value()); | 
|  | 6367     } | 
|  | 6368   } | 
|  | 6369 | 
|  | 6370   return *isolate->factory()->NewNumber(value); | 
| 6330 } | 6371 } | 
| 6331 | 6372 | 
| 6332 | 6373 | 
| 6333 static inline bool ToUpperOverflows(uc32 character) { | 6374 static inline bool ToUpperOverflows(uc32 character) { | 
| 6334   // y with umlauts and the micro sign are the only characters that stop | 6375   // y with umlauts and the micro sign are the only characters that stop | 
| 6335   // fitting into one-byte when converting to uppercase. | 6376   // fitting into one-byte when converting to uppercase. | 
| 6336   static const uc32 yuml_code = 0xff; | 6377   static const uc32 yuml_code = 0xff; | 
| 6337   static const uc32 micro_code = 0xb5; | 6378   static const uc32 micro_code = 0xb5; | 
| 6338   return (character == yuml_code || character == micro_code); | 6379   return (character == yuml_code || character == micro_code); | 
| 6339 } | 6380 } | 
| (...skipping 1154 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 7494   if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) { | 7535   if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) { | 
| 7495     result = Smi::FromInt(EQUAL); | 7536     result = Smi::FromInt(EQUAL); | 
| 7496   } else { | 7537   } else { | 
| 7497     result = Smi::FromInt(NOT_EQUAL); | 7538     result = Smi::FromInt(NOT_EQUAL); | 
| 7498   } | 7539   } | 
| 7499   return result; | 7540   return result; | 
| 7500 } | 7541 } | 
| 7501 | 7542 | 
| 7502 | 7543 | 
| 7503 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringEquals) { | 7544 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringEquals) { | 
| 7504   SealHandleScope shs(isolate); | 7545   HandleScope handle_scope(isolate); | 
| 7505   ASSERT(args.length() == 2); | 7546   ASSERT(args.length() == 2); | 
| 7506 | 7547 | 
| 7507   CONVERT_ARG_CHECKED(String, x, 0); | 7548   CONVERT_ARG_HANDLE_CHECKED(String, x, 0); | 
| 7508   CONVERT_ARG_CHECKED(String, y, 1); | 7549   CONVERT_ARG_HANDLE_CHECKED(String, y, 1); | 
| 7509 | 7550 | 
| 7510   bool not_equal = !x->Equals(y); | 7551   bool not_equal = !String::Equals(x, y); | 
| 7511   // This is slightly convoluted because the value that signifies | 7552   // This is slightly convoluted because the value that signifies | 
| 7512   // equality is 0 and inequality is 1 so we have to negate the result | 7553   // equality is 0 and inequality is 1 so we have to negate the result | 
| 7513   // from String::Equals. | 7554   // from String::Equals. | 
| 7514   ASSERT(not_equal == 0 || not_equal == 1); | 7555   ASSERT(not_equal == 0 || not_equal == 1); | 
| 7515   STATIC_CHECK(EQUAL == 0); | 7556   STATIC_CHECK(EQUAL == 0); | 
| 7516   STATIC_CHECK(NOT_EQUAL == 1); | 7557   STATIC_CHECK(NOT_EQUAL == 1); | 
| 7517   return Smi::FromInt(not_equal); | 7558   return Smi::FromInt(not_equal); | 
| 7518 } | 7559 } | 
| 7519 | 7560 | 
| 7520 | 7561 | 
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 7601     x_scaled /= 10; | 7642     x_scaled /= 10; | 
| 7602     tie = GREATER; | 7643     tie = GREATER; | 
| 7603   } | 7644   } | 
| 7604 | 7645 | 
| 7605   if (x_scaled < y_scaled) return Smi::FromInt(LESS); | 7646   if (x_scaled < y_scaled) return Smi::FromInt(LESS); | 
| 7606   if (x_scaled > y_scaled) return Smi::FromInt(GREATER); | 7647   if (x_scaled > y_scaled) return Smi::FromInt(GREATER); | 
| 7607   return Smi::FromInt(tie); | 7648   return Smi::FromInt(tie); | 
| 7608 } | 7649 } | 
| 7609 | 7650 | 
| 7610 | 7651 | 
| 7611 static Object* StringCharacterStreamCompare(RuntimeState* state, | 7652 RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_StringCompare) { | 
| 7612                                         String* x, | 7653   HandleScope handle_scope(isolate); | 
| 7613                                         String* y) { | 7654   ASSERT(args.length() == 2); | 
| 7614   StringCharacterStream stream_x(x, state->string_iterator_compare_x()); | 7655 | 
| 7615   StringCharacterStream stream_y(y, state->string_iterator_compare_y()); | 7656   CONVERT_ARG_HANDLE_CHECKED(String, x, 0); | 
| 7616   while (stream_x.HasMore() && stream_y.HasMore()) { | 7657   CONVERT_ARG_HANDLE_CHECKED(String, y, 1); | 
| 7617     int d = stream_x.GetNext() - stream_y.GetNext(); | 7658 | 
| 7618     if (d < 0) return Smi::FromInt(LESS); | 7659   isolate->counters()->string_compare_runtime()->Increment(); | 
| 7619     else if (d > 0) return Smi::FromInt(GREATER); | 7660 | 
|  | 7661   // A few fast case tests before we flatten. | 
|  | 7662   if (x.is_identical_to(y)) return Smi::FromInt(EQUAL); | 
|  | 7663   if (y->length() == 0) { | 
|  | 7664     if (x->length() == 0) return Smi::FromInt(EQUAL); | 
|  | 7665     return Smi::FromInt(GREATER); | 
|  | 7666   } else if (x->length() == 0) { | 
|  | 7667     return Smi::FromInt(LESS); | 
| 7620   } | 7668   } | 
| 7621 | 7669 | 
| 7622   // x is (non-trivial) prefix of y: | 7670   int d = x->Get(0) - y->Get(0); | 
| 7623   if (stream_y.HasMore()) return Smi::FromInt(LESS); | 7671   if (d < 0) return Smi::FromInt(LESS); | 
| 7624   // y is prefix of x: | 7672   else if (d > 0) return Smi::FromInt(GREATER); | 
| 7625   return Smi::FromInt(stream_x.HasMore() ? GREATER : EQUAL); |  | 
| 7626 } |  | 
| 7627 | 7673 | 
|  | 7674   // Slow case. | 
|  | 7675   x = String::Flatten(x); | 
|  | 7676   y = String::Flatten(y); | 
| 7628 | 7677 | 
| 7629 static Object* FlatStringCompare(String* x, String* y) { | 7678   DisallowHeapAllocation no_gc; | 
| 7630   ASSERT(x->IsFlat()); |  | 
| 7631   ASSERT(y->IsFlat()); |  | 
| 7632   Object* equal_prefix_result = Smi::FromInt(EQUAL); | 7679   Object* equal_prefix_result = Smi::FromInt(EQUAL); | 
| 7633   int prefix_length = x->length(); | 7680   int prefix_length = x->length(); | 
| 7634   if (y->length() < prefix_length) { | 7681   if (y->length() < prefix_length) { | 
| 7635     prefix_length = y->length(); | 7682     prefix_length = y->length(); | 
| 7636     equal_prefix_result = Smi::FromInt(GREATER); | 7683     equal_prefix_result = Smi::FromInt(GREATER); | 
| 7637   } else if (y->length() > prefix_length) { | 7684   } else if (y->length() > prefix_length) { | 
| 7638     equal_prefix_result = Smi::FromInt(LESS); | 7685     equal_prefix_result = Smi::FromInt(LESS); | 
| 7639   } | 7686   } | 
| 7640   int r; | 7687   int r; | 
| 7641   DisallowHeapAllocation no_gc; |  | 
| 7642   String::FlatContent x_content = x->GetFlatContent(); | 7688   String::FlatContent x_content = x->GetFlatContent(); | 
| 7643   String::FlatContent y_content = y->GetFlatContent(); | 7689   String::FlatContent y_content = y->GetFlatContent(); | 
| 7644   if (x_content.IsAscii()) { | 7690   if (x_content.IsAscii()) { | 
| 7645     Vector<const uint8_t> x_chars = x_content.ToOneByteVector(); | 7691     Vector<const uint8_t> x_chars = x_content.ToOneByteVector(); | 
| 7646     if (y_content.IsAscii()) { | 7692     if (y_content.IsAscii()) { | 
| 7647       Vector<const uint8_t> y_chars = y_content.ToOneByteVector(); | 7693       Vector<const uint8_t> y_chars = y_content.ToOneByteVector(); | 
| 7648       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); | 7694       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); | 
| 7649     } else { | 7695     } else { | 
| 7650       Vector<const uc16> y_chars = y_content.ToUC16Vector(); | 7696       Vector<const uc16> y_chars = y_content.ToUC16Vector(); | 
| 7651       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); | 7697       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); | 
| 7652     } | 7698     } | 
| 7653   } else { | 7699   } else { | 
| 7654     Vector<const uc16> x_chars = x_content.ToUC16Vector(); | 7700     Vector<const uc16> x_chars = x_content.ToUC16Vector(); | 
| 7655     if (y_content.IsAscii()) { | 7701     if (y_content.IsAscii()) { | 
| 7656       Vector<const uint8_t> y_chars = y_content.ToOneByteVector(); | 7702       Vector<const uint8_t> y_chars = y_content.ToOneByteVector(); | 
| 7657       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); | 7703       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); | 
| 7658     } else { | 7704     } else { | 
| 7659       Vector<const uc16> y_chars = y_content.ToUC16Vector(); | 7705       Vector<const uc16> y_chars = y_content.ToUC16Vector(); | 
| 7660       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); | 7706       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); | 
| 7661     } | 7707     } | 
| 7662   } | 7708   } | 
| 7663   Object* result; | 7709   Object* result; | 
| 7664   if (r == 0) { | 7710   if (r == 0) { | 
| 7665     result = equal_prefix_result; | 7711     result = equal_prefix_result; | 
| 7666   } else { | 7712   } else { | 
| 7667     result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER); | 7713     result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER); | 
| 7668   } | 7714   } | 
| 7669   ASSERT(result == |  | 
| 7670       StringCharacterStreamCompare(x->GetIsolate()->runtime_state(), x, y)); |  | 
| 7671   return result; | 7715   return result; | 
| 7672 } | 7716 } | 
| 7673 | 7717 | 
| 7674 | 7718 | 
| 7675 RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_StringCompare) { |  | 
| 7676   HandleScope shs(isolate); |  | 
| 7677   ASSERT(args.length() == 2); |  | 
| 7678 |  | 
| 7679   CONVERT_ARG_CHECKED(String, x, 0); |  | 
| 7680   CONVERT_ARG_CHECKED(String, y, 1); |  | 
| 7681 |  | 
| 7682   isolate->counters()->string_compare_runtime()->Increment(); |  | 
| 7683 |  | 
| 7684   // A few fast case tests before we flatten. |  | 
| 7685   if (x == y) return Smi::FromInt(EQUAL); |  | 
| 7686   if (y->length() == 0) { |  | 
| 7687     if (x->length() == 0) return Smi::FromInt(EQUAL); |  | 
| 7688     return Smi::FromInt(GREATER); |  | 
| 7689   } else if (x->length() == 0) { |  | 
| 7690     return Smi::FromInt(LESS); |  | 
| 7691   } |  | 
| 7692 |  | 
| 7693   int d = x->Get(0) - y->Get(0); |  | 
| 7694   if (d < 0) return Smi::FromInt(LESS); |  | 
| 7695   else if (d > 0) return Smi::FromInt(GREATER); |  | 
| 7696 |  | 
| 7697   Object* obj; |  | 
| 7698   { MaybeObject* maybe_obj = isolate->heap()->PrepareForCompare(x); |  | 
| 7699     if (!maybe_obj->ToObject(&obj)) return maybe_obj; |  | 
| 7700   } |  | 
| 7701   { MaybeObject* maybe_obj = isolate->heap()->PrepareForCompare(y); |  | 
| 7702     if (!maybe_obj->ToObject(&obj)) return maybe_obj; |  | 
| 7703   } |  | 
| 7704 |  | 
| 7705   return (x->IsFlat() && y->IsFlat()) ? FlatStringCompare(x, y) |  | 
| 7706       : StringCharacterStreamCompare(isolate->runtime_state(), x, y); |  | 
| 7707 } |  | 
| 7708 |  | 
| 7709 |  | 
| 7710 #define RUNTIME_UNARY_MATH(Name, name)                                         \ | 7719 #define RUNTIME_UNARY_MATH(Name, name)                                         \ | 
| 7711 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math##Name) {                           \ | 7720 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math##Name) {                           \ | 
| 7712   SealHandleScope shs(isolate);                                                \ | 7721   SealHandleScope shs(isolate);                                                \ | 
| 7713   ASSERT(args.length() == 1);                                                  \ | 7722   ASSERT(args.length() == 1);                                                  \ | 
| 7714   isolate->counters()->math_##name()->Increment();                             \ | 7723   isolate->counters()->math_##name()->Increment();                             \ | 
| 7715   CONVERT_DOUBLE_ARG_CHECKED(x, 0);                                            \ | 7724   CONVERT_DOUBLE_ARG_CHECKED(x, 0);                                            \ | 
| 7716   return isolate->heap()->AllocateHeapNumber(std::name(x));                    \ | 7725   return isolate->heap()->AllocateHeapNumber(std::name(x));                    \ | 
| 7717 } | 7726 } | 
| 7718 | 7727 | 
| 7719 RUNTIME_UNARY_MATH(Acos, acos) | 7728 RUNTIME_UNARY_MATH(Acos, acos) | 
| (...skipping 3856 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 11576 | 11585 | 
| 11577 | 11586 | 
| 11578 // Set the context local variable value. | 11587 // Set the context local variable value. | 
| 11579 static bool SetContextLocalValue(Isolate* isolate, | 11588 static bool SetContextLocalValue(Isolate* isolate, | 
| 11580                                  Handle<ScopeInfo> scope_info, | 11589                                  Handle<ScopeInfo> scope_info, | 
| 11581                                  Handle<Context> context, | 11590                                  Handle<Context> context, | 
| 11582                                  Handle<String> variable_name, | 11591                                  Handle<String> variable_name, | 
| 11583                                  Handle<Object> new_value) { | 11592                                  Handle<Object> new_value) { | 
| 11584   for (int i = 0; i < scope_info->ContextLocalCount(); i++) { | 11593   for (int i = 0; i < scope_info->ContextLocalCount(); i++) { | 
| 11585     Handle<String> next_name(scope_info->ContextLocalName(i)); | 11594     Handle<String> next_name(scope_info->ContextLocalName(i)); | 
| 11586     if (variable_name->Equals(*next_name)) { | 11595     if (String::Equals(variable_name, next_name)) { | 
| 11587       VariableMode mode; | 11596       VariableMode mode; | 
| 11588       InitializationFlag init_flag; | 11597       InitializationFlag init_flag; | 
| 11589       int context_index = | 11598       int context_index = | 
| 11590           scope_info->ContextSlotIndex(*next_name, &mode, &init_flag); | 11599           scope_info->ContextSlotIndex(*next_name, &mode, &init_flag); | 
| 11591       context->set(context_index, *new_value); | 11600       context->set(context_index, *new_value); | 
| 11592       return true; | 11601       return true; | 
| 11593     } | 11602     } | 
| 11594   } | 11603   } | 
| 11595 | 11604 | 
| 11596   return false; | 11605   return false; | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 11608   } | 11617   } | 
| 11609 | 11618 | 
| 11610   Handle<JSFunction> function(frame->function()); | 11619   Handle<JSFunction> function(frame->function()); | 
| 11611   Handle<SharedFunctionInfo> shared(function->shared()); | 11620   Handle<SharedFunctionInfo> shared(function->shared()); | 
| 11612   Handle<ScopeInfo> scope_info(shared->scope_info()); | 11621   Handle<ScopeInfo> scope_info(shared->scope_info()); | 
| 11613 | 11622 | 
| 11614   bool default_result = false; | 11623   bool default_result = false; | 
| 11615 | 11624 | 
| 11616   // Parameters. | 11625   // Parameters. | 
| 11617   for (int i = 0; i < scope_info->ParameterCount(); ++i) { | 11626   for (int i = 0; i < scope_info->ParameterCount(); ++i) { | 
| 11618     if (scope_info->ParameterName(i)->Equals(*variable_name)) { | 11627     HandleScope scope(isolate); | 
|  | 11628     if (String::Equals(handle(scope_info->ParameterName(i)), variable_name)) { | 
| 11619       frame->SetParameterValue(i, *new_value); | 11629       frame->SetParameterValue(i, *new_value); | 
| 11620       // Argument might be shadowed in heap context, don't stop here. | 11630       // Argument might be shadowed in heap context, don't stop here. | 
| 11621       default_result = true; | 11631       default_result = true; | 
| 11622     } | 11632     } | 
| 11623   } | 11633   } | 
| 11624 | 11634 | 
| 11625   // Stack locals. | 11635   // Stack locals. | 
| 11626   for (int i = 0; i < scope_info->StackLocalCount(); ++i) { | 11636   for (int i = 0; i < scope_info->StackLocalCount(); ++i) { | 
| 11627     if (scope_info->StackLocalName(i)->Equals(*variable_name)) { | 11637     HandleScope scope(isolate); | 
|  | 11638     if (String::Equals(handle(scope_info->StackLocalName(i)), variable_name)) { | 
| 11628       frame->SetExpression(i, *new_value); | 11639       frame->SetExpression(i, *new_value); | 
| 11629       return true; | 11640       return true; | 
| 11630     } | 11641     } | 
| 11631   } | 11642   } | 
| 11632 | 11643 | 
| 11633   if (scope_info->HasContext()) { | 11644   if (scope_info->HasContext()) { | 
| 11634     // Context locals. | 11645     // Context locals. | 
| 11635     Handle<Context> frame_context(Context::cast(frame->context())); | 11646     Handle<Context> frame_context(Context::cast(frame->context())); | 
| 11636     Handle<Context> function_context(frame_context->declaration_context()); | 11647     Handle<Context> function_context(frame_context->declaration_context()); | 
| 11637     if (SetContextLocalValue( | 11648     if (SetContextLocalValue( | 
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 11758   return catch_scope; | 11769   return catch_scope; | 
| 11759 } | 11770 } | 
| 11760 | 11771 | 
| 11761 | 11772 | 
| 11762 static bool SetCatchVariableValue(Isolate* isolate, | 11773 static bool SetCatchVariableValue(Isolate* isolate, | 
| 11763                                   Handle<Context> context, | 11774                                   Handle<Context> context, | 
| 11764                                   Handle<String> variable_name, | 11775                                   Handle<String> variable_name, | 
| 11765                                   Handle<Object> new_value) { | 11776                                   Handle<Object> new_value) { | 
| 11766   ASSERT(context->IsCatchContext()); | 11777   ASSERT(context->IsCatchContext()); | 
| 11767   Handle<String> name(String::cast(context->extension())); | 11778   Handle<String> name(String::cast(context->extension())); | 
| 11768   if (!name->Equals(*variable_name)) { | 11779   if (!String::Equals(name, variable_name)) { | 
| 11769     return false; | 11780     return false; | 
| 11770   } | 11781   } | 
| 11771   context->set(Context::THROWN_OBJECT_INDEX, *new_value); | 11782   context->set(Context::THROWN_OBJECT_INDEX, *new_value); | 
| 11772   return true; | 11783   return true; | 
| 11773 } | 11784 } | 
| 11774 | 11785 | 
| 11775 | 11786 | 
| 11776 // Create a plain JSObject which materializes the block scope for the specified | 11787 // Create a plain JSObject which materializes the block scope for the specified | 
| 11777 // block context. | 11788 // block context. | 
| 11778 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeBlockScope( | 11789 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeBlockScope( | 
| (...skipping 3443 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 15222   } | 15233   } | 
| 15223 } | 15234 } | 
| 15224 | 15235 | 
| 15225 | 15236 | 
| 15226 void Runtime::OutOfMemory() { | 15237 void Runtime::OutOfMemory() { | 
| 15227   Heap::FatalProcessOutOfMemory("CALL_AND_RETRY_LAST", true); | 15238   Heap::FatalProcessOutOfMemory("CALL_AND_RETRY_LAST", true); | 
| 15228   UNREACHABLE(); | 15239   UNREACHABLE(); | 
| 15229 } | 15240 } | 
| 15230 | 15241 | 
| 15231 } }  // namespace v8::internal | 15242 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|