| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/ast.h" | 8 #include "src/ast.h" |
| 9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
| 10 #include "src/base/platform/platform.h" | 10 #include "src/base/platform/platform.h" |
| (...skipping 4461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4472 if (ParseHexEscape(2, &value)) { | 4472 if (ParseHexEscape(2, &value)) { |
| 4473 builder->AddCharacter(value); | 4473 builder->AddCharacter(value); |
| 4474 } else { | 4474 } else { |
| 4475 builder->AddCharacter('x'); | 4475 builder->AddCharacter('x'); |
| 4476 } | 4476 } |
| 4477 break; | 4477 break; |
| 4478 } | 4478 } |
| 4479 case 'u': { | 4479 case 'u': { |
| 4480 Advance(2); | 4480 Advance(2); |
| 4481 uc32 value; | 4481 uc32 value; |
| 4482 if (ParseHexEscape(4, &value)) { | 4482 if (ParseUnicodeEscape(&value)) { |
| 4483 builder->AddCharacter(value); | 4483 builder->AddCharacter(value); |
| 4484 } else { | 4484 } else { |
| 4485 builder->AddCharacter('u'); | 4485 builder->AddCharacter('u'); |
| 4486 } | 4486 } |
| 4487 break; | 4487 break; |
| 4488 } | 4488 } |
| 4489 default: | 4489 default: |
| 4490 // Identity escape. | 4490 // Identity escape. |
| 4491 builder->AddCharacter(Next()); | 4491 builder->AddCharacter(Next()); |
| 4492 Advance(2); | 4492 Advance(2); |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4725 Advance(); | 4725 Advance(); |
| 4726 if (value < 32 && '0' <= current() && current() <= '7') { | 4726 if (value < 32 && '0' <= current() && current() <= '7') { |
| 4727 value = value * 8 + current() - '0'; | 4727 value = value * 8 + current() - '0'; |
| 4728 Advance(); | 4728 Advance(); |
| 4729 } | 4729 } |
| 4730 } | 4730 } |
| 4731 return value; | 4731 return value; |
| 4732 } | 4732 } |
| 4733 | 4733 |
| 4734 | 4734 |
| 4735 bool RegExpParser::ParseHexEscape(int length, uc32 *value) { | 4735 bool RegExpParser::ParseHexEscape(int length, uc32* value) { |
| 4736 int start = position(); | 4736 int start = position(); |
| 4737 uc32 val = 0; | 4737 uc32 val = 0; |
| 4738 bool done = false; | 4738 for (int i = 0; i < length; ++i) { |
| 4739 for (int i = 0; !done; i++) { | |
| 4740 uc32 c = current(); | 4739 uc32 c = current(); |
| 4741 int d = HexValue(c); | 4740 int d = HexValue(c); |
| 4742 if (d < 0) { | 4741 if (d < 0) { |
| 4743 Reset(start); | 4742 Reset(start); |
| 4744 return false; | 4743 return false; |
| 4745 } | 4744 } |
| 4746 val = val * 16 + d; | 4745 val = val * 16 + d; |
| 4747 Advance(); | 4746 Advance(); |
| 4748 if (i == length - 1) { | 4747 } |
| 4749 done = true; | 4748 *value = val; |
| 4749 return true; |
| 4750 } |
| 4751 |
| 4752 |
| 4753 bool RegExpParser::ParseUnicodeEscape(uc32* value) { |
| 4754 if (current() == '{') { |
| 4755 int start = position(); |
| 4756 Advance(); |
| 4757 if (ParseUnlimitedLengthHexEscape(0x10ffff, value)) { |
| 4758 if (current() == '}') { |
| 4759 Advance(); |
| 4760 return true; |
| 4761 } |
| 4762 Reset(start); |
| 4763 return false; |
| 4764 } |
| 4765 // Parsing the hex number failed. |
| 4766 Reset(start); |
| 4767 return false; |
| 4768 } |
| 4769 // \u but no { |
| 4770 return ParseHexEscape(4, value); |
| 4771 } |
| 4772 |
| 4773 |
| 4774 bool RegExpParser::ParseUnlimitedLengthHexEscape(int max_value, uc32* value) { |
| 4775 int start = position(); |
| 4776 uc32 val = 0; |
| 4777 int d = HexValue(current()); |
| 4778 if (d < 0) { |
| 4779 Reset(start); |
| 4780 return false; |
| 4781 } |
| 4782 while (d >= 0) { |
| 4783 val = val * 16 + d; |
| 4784 Advance(); |
| 4785 d = HexValue(current()); |
| 4786 if (val > max_value) { |
| 4787 Reset(start); |
| 4788 return false; |
| 4750 } | 4789 } |
| 4751 } | 4790 } |
| 4752 *value = val; | 4791 *value = val; |
| 4753 return true; | 4792 return true; |
| 4754 } | 4793 } |
| 4755 | 4794 |
| 4756 | 4795 |
| 4757 uc32 RegExpParser::ParseClassCharacterEscape() { | 4796 uc32 RegExpParser::ParseClassCharacterEscape() { |
| 4758 DCHECK(current() == '\\'); | 4797 DCHECK(current() == '\\'); |
| 4759 DCHECK(has_next() && !IsSpecialClassEscape(Next())); | 4798 DCHECK(has_next() && !IsSpecialClassEscape(Next())); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4808 if (ParseHexEscape(2, &value)) { | 4847 if (ParseHexEscape(2, &value)) { |
| 4809 return value; | 4848 return value; |
| 4810 } | 4849 } |
| 4811 // If \x is not followed by a two-digit hexadecimal, treat it | 4850 // If \x is not followed by a two-digit hexadecimal, treat it |
| 4812 // as an identity escape. | 4851 // as an identity escape. |
| 4813 return 'x'; | 4852 return 'x'; |
| 4814 } | 4853 } |
| 4815 case 'u': { | 4854 case 'u': { |
| 4816 Advance(); | 4855 Advance(); |
| 4817 uc32 value; | 4856 uc32 value; |
| 4818 if (ParseHexEscape(4, &value)) { | 4857 if (ParseUnicodeEscape(&value)) { |
| 4858 fprintf(stderr, "worked; returning code point %d\n", value); |
| 4819 return value; | 4859 return value; |
| 4820 } | 4860 } |
| 4821 // If \u is not followed by a four-digit hexadecimal, treat it | 4861 // If \u is not followed by a legal hex decimal sequence, treat it as an |
| 4822 // as an identity escape. | 4862 // identity escape. |
| 4823 return 'u'; | 4863 return 'u'; |
| 4824 } | 4864 } |
| 4825 default: { | 4865 default: { |
| 4826 // Extended identity escape. We accept any character that hasn't | 4866 // Extended identity escape. We accept any character that hasn't |
| 4827 // been matched by a more specific case, not just the subset required | 4867 // been matched by a more specific case, not just the subset required |
| 4828 // by the ECMAScript specification. | 4868 // by the ECMAScript specification. |
| 4829 uc32 result = current(); | 4869 uc32 result = current(); |
| 4830 Advance(); | 4870 Advance(); |
| 4831 return result; | 4871 return result; |
| 4832 } | 4872 } |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5023 | 5063 |
| 5024 // We cannot internalize on a background thread; a foreground task will take | 5064 // We cannot internalize on a background thread; a foreground task will take |
| 5025 // care of calling Parser::Internalize just before compilation. | 5065 // care of calling Parser::Internalize just before compilation. |
| 5026 | 5066 |
| 5027 if (compile_options() == ScriptCompiler::kProduceParserCache) { | 5067 if (compile_options() == ScriptCompiler::kProduceParserCache) { |
| 5028 if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); | 5068 if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); |
| 5029 log_ = NULL; | 5069 log_ = NULL; |
| 5030 } | 5070 } |
| 5031 } | 5071 } |
| 5032 } } // namespace v8::internal | 5072 } } // namespace v8::internal |
| OLD | NEW |