Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/object.h" | 5 #include "vm/object.h" |
| 6 | 6 |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
| 9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
| 10 #include "vm/bigint_operations.h" | 10 #include "vm/bigint_operations.h" |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 183 if (is_setter) { | 183 if (is_setter) { |
| 184 // Setters need to end with '='. | 184 // Setters need to end with '='. |
| 185 const String& suffix = String::Handle(Symbols::Equals()); | 185 const String& suffix = String::Handle(Symbols::Equals()); |
| 186 return String::Concat(result, suffix); | 186 return String::Concat(result, suffix); |
| 187 } | 187 } |
| 188 | 188 |
| 189 return result.raw(); | 189 return result.raw(); |
| 190 } | 190 } |
| 191 | 191 |
| 192 | 192 |
| 193 template<typename type> | |
| 194 static bool IsSpecialCharacter(type value) { | |
| 195 return ((value == '"') || | |
| 196 (value == '\n') || | |
| 197 (value == '\f') || | |
| 198 (value == '\b') || | |
| 199 (value == '\t') || | |
| 200 (value == '\v') || | |
| 201 (value == '\r')); | |
| 202 } | |
| 203 | |
| 204 | |
| 205 template<typename type> | |
| 206 static type SpecialCharacter(type value) { | |
| 207 if (value == '"') { | |
| 208 return '"'; | |
| 209 } else if (value == '\n') { | |
| 210 return 'n'; | |
| 211 } else if (value == '\f') { | |
| 212 return 'f'; | |
| 213 } else if (value == '\b') { | |
| 214 return 'b'; | |
| 215 } else if (value == '\t') { | |
| 216 return 't'; | |
| 217 } else if (value == '\v') { | |
| 218 return 'v'; | |
| 219 } else if (value == '\r') { | |
| 220 return 'r'; | |
| 221 } | |
| 222 UNREACHABLE(); | |
| 223 return '\0'; | |
| 224 } | |
| 225 | |
| 226 | |
| 193 void Object::InitOnce() { | 227 void Object::InitOnce() { |
| 194 // TODO(iposva): NoGCScope needs to be added here. | 228 // TODO(iposva): NoGCScope needs to be added here. |
| 195 ASSERT(class_class() == null_); | 229 ASSERT(class_class() == null_); |
| 196 // Initialize the static vtable values. | 230 // Initialize the static vtable values. |
| 197 { | 231 { |
| 198 Object fake_object; | 232 Object fake_object; |
| 199 Smi fake_smi; | 233 Smi fake_smi; |
| 200 Object::handle_vtable_ = fake_object.vtable(); | 234 Object::handle_vtable_ = fake_object.vtable(); |
| 201 Smi::handle_vtable_ = fake_smi.vtable(); | 235 Smi::handle_vtable_ = fake_smi.vtable(); |
| 202 } | 236 } |
| (...skipping 4830 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5033 GrowableObjectArray::Handle(GrowableObjectArray::New(data.Length())); | 5067 GrowableObjectArray::Handle(GrowableObjectArray::New(data.Length())); |
| 5034 const String& private_key = String::Handle(PrivateKey()); | 5068 const String& private_key = String::Handle(PrivateKey()); |
| 5035 intptr_t private_len = private_key.Length(); | 5069 intptr_t private_len = private_key.Length(); |
| 5036 | 5070 |
| 5037 String& blank = String::Handle(String::New(" ")); | 5071 String& blank = String::Handle(String::New(" ")); |
| 5038 String& newline = String::Handle(String::New("\n")); | 5072 String& newline = String::Handle(String::New("\n")); |
| 5039 String& two_newlines = String::Handle(String::New("\n\n")); | 5073 String& two_newlines = String::Handle(String::New("\n\n")); |
| 5040 String& double_quotes = String::Handle(String::New("\"")); | 5074 String& double_quotes = String::Handle(String::New("\"")); |
| 5041 String& dollar = String::Handle(String::New("$")); | 5075 String& dollar = String::Handle(String::New("$")); |
| 5042 String& two_spaces = String::Handle(String::New(" ")); | 5076 String& two_spaces = String::Handle(String::New(" ")); |
| 5077 String& raw_string = String::Handle(String::New("@")); | |
| 5043 | 5078 |
| 5044 Token::Kind curr = iterator.CurrentTokenKind(); | 5079 Token::Kind curr = iterator.CurrentTokenKind(); |
| 5045 Token::Kind prev = Token::kILLEGAL; | 5080 Token::Kind prev = Token::kILLEGAL; |
| 5046 // Handles used in the loop. | 5081 // Handles used in the loop. |
| 5047 Object& obj = Object::Handle(); | 5082 Object& obj = Object::Handle(); |
| 5048 String& literal = String::Handle(); | 5083 String& literal = String::Handle(); |
| 5049 // Current indentation level. | 5084 // Current indentation level. |
| 5050 int indent = 0; | 5085 int indent = 0; |
| 5051 | 5086 |
| 5052 while (curr != Token::kEOS) { | 5087 while (curr != Token::kEOS) { |
| 5053 // Remember current values for this token. | 5088 // Remember current values for this token. |
| 5054 obj = iterator.CurrentToken(); | 5089 obj = iterator.CurrentToken(); |
| 5055 literal = iterator.MakeLiteralToken(obj); | 5090 literal = iterator.MakeLiteralToken(obj); |
| 5056 // Advance to be able to use next token kind. | 5091 // Advance to be able to use next token kind. |
| 5057 iterator.Advance(); | 5092 iterator.Advance(); |
| 5058 Token::Kind next = iterator.CurrentTokenKind(); | 5093 Token::Kind next = iterator.CurrentTokenKind(); |
| 5059 | 5094 |
| 5060 // Handle the current token. | 5095 // Handle the current token. |
| 5061 if (curr == Token::kSTRING) { | 5096 if (curr == Token::kSTRING) { |
| 5062 bool escape_quotes = false; | 5097 bool is_raw_string = false; |
| 5098 bool escape_characters = false; | |
| 5063 for (intptr_t i = 0; i < literal.Length(); i++) { | 5099 for (intptr_t i = 0; i < literal.Length(); i++) { |
| 5064 if (literal.CharAt(i) == '"') { | 5100 if (IsSpecialCharacter(literal.CharAt(i))) { |
| 5065 escape_quotes = true; | 5101 escape_characters = true; |
| 5066 break; | 5102 } |
| 5103 // TODO(4995): Temp solution for raw strings, this will break | |
|
Ivan Posva
2012/09/09 10:24:17
I see two different options here to fix this curre
Ivan Posva
2012/09/09 10:31:58
Of course I had another idea just after hitting se
| |
| 5104 // if we saw a string that is not a raw string but has back slashes | |
| 5105 // in it. | |
| 5106 if ((literal.CharAt(i) == '\\')) { | |
| 5107 if ((next != Token::kINTERPOL_VAR) && | |
| 5108 (next != Token::kINTERPOL_START) && | |
| 5109 (prev != Token::kINTERPOL_VAR) && | |
| 5110 (prev != Token::kINTERPOL_END)) { | |
| 5111 is_raw_string = true; | |
| 5112 } else { | |
| 5113 escape_characters = true; | |
| 5114 } | |
| 5067 } | 5115 } |
| 5068 } | 5116 } |
| 5069 if ((prev != Token::kINTERPOL_VAR) && (prev != Token::kINTERPOL_END)) { | 5117 if ((prev != Token::kINTERPOL_VAR) && (prev != Token::kINTERPOL_END)) { |
| 5118 if (is_raw_string) { | |
| 5119 literals.Add(raw_string); | |
| 5120 } | |
| 5070 literals.Add(double_quotes); | 5121 literals.Add(double_quotes); |
| 5071 } | 5122 } |
| 5072 if (escape_quotes) { | 5123 if (escape_characters) { |
| 5073 literal = String::EscapeDoubleQuotes(literal); | 5124 literal = String::EscapeSpecialCharacters(literal, is_raw_string); |
| 5074 literals.Add(literal); | 5125 literals.Add(literal); |
| 5075 } else { | 5126 } else { |
| 5076 literals.Add(literal); | 5127 literals.Add(literal); |
| 5077 } | 5128 } |
| 5078 if ((next != Token::kINTERPOL_VAR) && (next != Token::kINTERPOL_START)) { | 5129 if ((next != Token::kINTERPOL_VAR) && (next != Token::kINTERPOL_START)) { |
| 5079 literals.Add(double_quotes); | 5130 literals.Add(double_quotes); |
| 5080 } | 5131 } |
| 5081 } else if (curr == Token::kINTERPOL_VAR) { | 5132 } else if (curr == Token::kINTERPOL_VAR) { |
| 5082 literals.Add(dollar); | 5133 literals.Add(dollar); |
| 5134 if (literal.CharAt(0) == Scanner::kPrivateIdentifierStart) { | |
| 5135 literal = String::SubString(literal, 0, literal.Length() - private_len); | |
| 5136 } | |
| 5083 literals.Add(literal); | 5137 literals.Add(literal); |
| 5084 } else if (curr == Token::kIDENT) { | 5138 } else if (curr == Token::kIDENT) { |
| 5085 if (literal.CharAt(0) == Scanner::kPrivateIdentifierStart) { | 5139 if (literal.CharAt(0) == Scanner::kPrivateIdentifierStart) { |
| 5086 literal = String::SubString(literal, 0, literal.Length() - private_len); | 5140 literal = String::SubString(literal, 0, literal.Length() - private_len); |
| 5087 } | 5141 } |
| 5088 literals.Add(literal); | 5142 literals.Add(literal); |
| 5089 } else { | 5143 } else { |
| 5090 literals.Add(literal); | 5144 literals.Add(literal); |
| 5091 } | 5145 } |
| 5092 // Determine the separation text based on this current token. | 5146 // Determine the separation text based on this current token. |
| (...skipping 4315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9408 const ExternalFourByteString& fourstr = | 9462 const ExternalFourByteString& fourstr = |
| 9409 ExternalFourByteString::Cast(src); | 9463 ExternalFourByteString::Cast(src); |
| 9410 NoGCScope no_gc; | 9464 NoGCScope no_gc; |
| 9411 String::Copy(dst, dst_offset, fourstr.CharAddr(0) + src_offset, len); | 9465 String::Copy(dst, dst_offset, fourstr.CharAddr(0) + src_offset, len); |
| 9412 } | 9466 } |
| 9413 } | 9467 } |
| 9414 } | 9468 } |
| 9415 } | 9469 } |
| 9416 | 9470 |
| 9417 | 9471 |
| 9418 RawString* String::EscapeDoubleQuotes(const String& str) { | 9472 RawString* String::EscapeSpecialCharacters(const String& str, bool raw_str) { |
| 9419 if (str.IsOneByteString()) { | 9473 if (str.IsOneByteString()) { |
| 9420 const OneByteString& onestr = OneByteString::Cast(str); | 9474 const OneByteString& onestr = OneByteString::Cast(str); |
| 9421 return onestr.EscapeDoubleQuotes(); | 9475 return onestr.EscapeSpecialCharacters(raw_str); |
| 9422 } | 9476 } |
| 9423 if (str.IsTwoByteString()) { | 9477 if (str.IsTwoByteString()) { |
| 9424 const TwoByteString& twostr = TwoByteString::Cast(str); | 9478 const TwoByteString& twostr = TwoByteString::Cast(str); |
| 9425 return twostr.EscapeDoubleQuotes(); | 9479 return twostr.EscapeSpecialCharacters(raw_str); |
| 9426 } | 9480 } |
| 9427 ASSERT(str.IsFourByteString()); | 9481 ASSERT(str.IsFourByteString()); |
| 9428 const FourByteString& fourstr = FourByteString::Cast(str); | 9482 const FourByteString& fourstr = FourByteString::Cast(str); |
| 9429 return fourstr.EscapeDoubleQuotes(); | 9483 return fourstr.EscapeSpecialCharacters(raw_str); |
| 9430 } | 9484 } |
| 9431 | 9485 |
| 9432 | 9486 |
| 9433 RawString* String::NewFormatted(const char* format, ...) { | 9487 RawString* String::NewFormatted(const char* format, ...) { |
| 9434 va_list args; | 9488 va_list args; |
| 9435 va_start(args, format); | 9489 va_start(args, format); |
| 9436 intptr_t len = OS::VSNPrint(NULL, 0, format, args); | 9490 intptr_t len = OS::VSNPrint(NULL, 0, format, args); |
| 9437 va_end(args); | 9491 va_end(args); |
| 9438 | 9492 |
| 9439 Zone* zone = Isolate::Current()->current_zone(); | 9493 Zone* zone = Isolate::Current()->current_zone(); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9587 return Transform(CaseMapping::ToUpper, str, space); | 9641 return Transform(CaseMapping::ToUpper, str, space); |
| 9588 } | 9642 } |
| 9589 | 9643 |
| 9590 | 9644 |
| 9591 RawString* String::ToLowerCase(const String& str, Heap::Space space) { | 9645 RawString* String::ToLowerCase(const String& str, Heap::Space space) { |
| 9592 // TODO(cshapiro): create a fast-path for OneByteString instances. | 9646 // TODO(cshapiro): create a fast-path for OneByteString instances. |
| 9593 return Transform(CaseMapping::ToLower, str, space); | 9647 return Transform(CaseMapping::ToLower, str, space); |
| 9594 } | 9648 } |
| 9595 | 9649 |
| 9596 | 9650 |
| 9597 RawOneByteString* OneByteString::EscapeDoubleQuotes() const { | 9651 RawOneByteString* OneByteString::EscapeSpecialCharacters(bool raw_str) const { |
| 9598 intptr_t len = Length(); | 9652 intptr_t len = Length(); |
| 9599 if (len > 0) { | 9653 if (len > 0) { |
| 9600 intptr_t num_quotes = 0; | 9654 intptr_t num_escapes = 0; |
| 9601 intptr_t index = 0; | 9655 intptr_t index = 0; |
| 9602 for (intptr_t i = 0; i < len; i++) { | 9656 for (intptr_t i = 0; i < len; i++) { |
| 9603 if (*CharAddr(i) == '"') { | 9657 if (IsSpecialCharacter(*CharAddr(i)) || |
| 9604 num_quotes += 1; | 9658 (!raw_str && (*CharAddr(i) == '\\'))) { |
| 9659 num_escapes += 1; | |
| 9605 } | 9660 } |
| 9606 } | 9661 } |
| 9607 const OneByteString& dststr = OneByteString::Handle( | 9662 const OneByteString& dststr = OneByteString::Handle( |
| 9608 OneByteString::New(len + num_quotes, Heap::kNew)); | 9663 OneByteString::New(len + num_escapes, Heap::kNew)); |
| 9609 for (intptr_t i = 0; i < len; i++) { | 9664 for (intptr_t i = 0; i < len; i++) { |
| 9610 if (*CharAddr(i) == '"') { | 9665 if (IsSpecialCharacter(*CharAddr(i))) { |
| 9611 *(dststr.CharAddr(index)) = '\\'; | 9666 *(dststr.CharAddr(index)) = '\\'; |
| 9612 *(dststr.CharAddr(index + 1)) = '"'; | 9667 *(dststr.CharAddr(index + 1)) = SpecialCharacter(*CharAddr(i)); |
| 9668 index += 2; | |
| 9669 } else if (!raw_str && (*CharAddr(i) == '\\')) { | |
| 9670 *(dststr.CharAddr(index)) = '\\'; | |
| 9671 *(dststr.CharAddr(index + 1)) = '\\'; | |
| 9613 index += 2; | 9672 index += 2; |
| 9614 } else { | 9673 } else { |
| 9615 *(dststr.CharAddr(index)) = *CharAddr(i); | 9674 *(dststr.CharAddr(index)) = *CharAddr(i); |
| 9616 index += 1; | 9675 index += 1; |
| 9617 } | 9676 } |
| 9618 } | 9677 } |
| 9619 return dststr.raw(); | 9678 return dststr.raw(); |
| 9620 } | 9679 } |
| 9621 return OneByteString::null(); | 9680 return OneByteString::null(); |
| 9622 } | 9681 } |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9785 } | 9844 } |
| 9786 return result.raw(); | 9845 return result.raw(); |
| 9787 } | 9846 } |
| 9788 | 9847 |
| 9789 | 9848 |
| 9790 const char* OneByteString::ToCString() const { | 9849 const char* OneByteString::ToCString() const { |
| 9791 return String::ToCString(); | 9850 return String::ToCString(); |
| 9792 } | 9851 } |
| 9793 | 9852 |
| 9794 | 9853 |
| 9795 RawTwoByteString* TwoByteString::EscapeDoubleQuotes() const { | 9854 RawTwoByteString* TwoByteString::EscapeSpecialCharacters(bool raw_str) const { |
| 9796 intptr_t len = Length(); | 9855 intptr_t len = Length(); |
| 9797 if (len > 0) { | 9856 if (len > 0) { |
| 9798 intptr_t num_quotes = 0; | 9857 intptr_t num_escapes = 0; |
| 9799 intptr_t index = 0; | 9858 intptr_t index = 0; |
| 9800 for (intptr_t i = 0; i < len; i++) { | 9859 for (intptr_t i = 0; i < len; i++) { |
| 9801 if (*CharAddr(i) == '"') { | 9860 if (IsSpecialCharacter(*CharAddr(i)) || |
| 9802 num_quotes += 1; | 9861 (!raw_str && (*CharAddr(i) == '\\'))) { |
| 9862 num_escapes += 1; | |
| 9803 } | 9863 } |
| 9804 } | 9864 } |
| 9805 const TwoByteString& dststr = TwoByteString::Handle( | 9865 const TwoByteString& dststr = TwoByteString::Handle( |
| 9806 TwoByteString::New(len + num_quotes, Heap::kNew)); | 9866 TwoByteString::New(len + num_escapes, Heap::kNew)); |
| 9807 for (intptr_t i = 0; i < len; i++) { | 9867 for (intptr_t i = 0; i < len; i++) { |
| 9808 if (*CharAddr(i) == '"') { | 9868 if (IsSpecialCharacter(*CharAddr(i))) { |
| 9809 *(dststr.CharAddr(index)) = '\\'; | 9869 *(dststr.CharAddr(index)) = '\\'; |
| 9810 *(dststr.CharAddr(index + 1)) = '"'; | 9870 *(dststr.CharAddr(index + 1)) = SpecialCharacter(*CharAddr(i)); |
| 9871 index += 2; | |
| 9872 } else if (!raw_str && (*CharAddr(i) == '\\')) { | |
| 9873 *(dststr.CharAddr(index)) = '\\'; | |
| 9874 *(dststr.CharAddr(index + 1)) = '\\'; | |
| 9811 index += 2; | 9875 index += 2; |
| 9812 } else { | 9876 } else { |
| 9813 *(dststr.CharAddr(index)) = *CharAddr(i); | 9877 *(dststr.CharAddr(index)) = *CharAddr(i); |
| 9814 index += 1; | 9878 index += 1; |
| 9815 } | 9879 } |
| 9816 } | 9880 } |
| 9817 return dststr.raw(); | 9881 return dststr.raw(); |
| 9818 } | 9882 } |
| 9819 return TwoByteString::null(); | 9883 return TwoByteString::null(); |
| 9820 } | 9884 } |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9917 } | 9981 } |
| 9918 return result.raw(); | 9982 return result.raw(); |
| 9919 } | 9983 } |
| 9920 | 9984 |
| 9921 | 9985 |
| 9922 const char* TwoByteString::ToCString() const { | 9986 const char* TwoByteString::ToCString() const { |
| 9923 return String::ToCString(); | 9987 return String::ToCString(); |
| 9924 } | 9988 } |
| 9925 | 9989 |
| 9926 | 9990 |
| 9927 RawFourByteString* FourByteString::EscapeDoubleQuotes() const { | 9991 RawFourByteString* FourByteString::EscapeSpecialCharacters(bool raw_str) const { |
| 9928 intptr_t len = Length(); | 9992 intptr_t len = Length(); |
| 9929 if (len > 0) { | 9993 if (len > 0) { |
| 9930 intptr_t num_quotes = 0; | 9994 intptr_t num_escapes = 0; |
| 9931 intptr_t index = 0; | 9995 intptr_t index = 0; |
| 9932 for (intptr_t i = 0; i < len; i++) { | 9996 for (intptr_t i = 0; i < len; i++) { |
| 9933 if (*CharAddr(i) == '"') { | 9997 if (IsSpecialCharacter(*CharAddr(i)) || |
| 9934 num_quotes += 1; | 9998 (!raw_str && (*CharAddr(i) == '\\'))) { |
| 9999 num_escapes += 1; | |
| 9935 } | 10000 } |
| 9936 } | 10001 } |
| 9937 const FourByteString& dststr = FourByteString::Handle( | 10002 const FourByteString& dststr = FourByteString::Handle( |
| 9938 FourByteString::New(len + num_quotes, Heap::kNew)); | 10003 FourByteString::New(len + num_escapes, Heap::kNew)); |
| 9939 for (intptr_t i = 0; i < len; i++) { | 10004 for (intptr_t i = 0; i < len; i++) { |
| 9940 if (*CharAddr(i) == '"') { | 10005 if (IsSpecialCharacter(*CharAddr(i))) { |
| 9941 *(dststr.CharAddr(index)) = '\\'; | 10006 *(dststr.CharAddr(index)) = '\\'; |
| 9942 *(dststr.CharAddr(index + 1)) = '"'; | 10007 *(dststr.CharAddr(index + 1)) = SpecialCharacter(*CharAddr(i)); |
| 10008 index += 2; | |
| 10009 } else if (!raw_str && (*CharAddr(i) == '\\')) { | |
| 10010 *(dststr.CharAddr(index)) = '\\'; | |
| 10011 *(dststr.CharAddr(index + 1)) = '\\'; | |
| 9943 index += 2; | 10012 index += 2; |
| 9944 } else { | 10013 } else { |
| 9945 *(dststr.CharAddr(index)) = *CharAddr(i); | 10014 *(dststr.CharAddr(index)) = *CharAddr(i); |
| 9946 index += 1; | 10015 index += 1; |
| 9947 } | 10016 } |
| 9948 } | 10017 } |
| 9949 return dststr.raw(); | 10018 return dststr.raw(); |
| 9950 } | 10019 } |
| 9951 return FourByteString::null(); | 10020 return FourByteString::null(); |
| 9952 } | 10021 } |
| (...skipping 1461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11414 } | 11483 } |
| 11415 return result.raw(); | 11484 return result.raw(); |
| 11416 } | 11485 } |
| 11417 | 11486 |
| 11418 | 11487 |
| 11419 const char* WeakProperty::ToCString() const { | 11488 const char* WeakProperty::ToCString() const { |
| 11420 return "_WeakProperty"; | 11489 return "_WeakProperty"; |
| 11421 } | 11490 } |
| 11422 | 11491 |
| 11423 } // namespace dart | 11492 } // namespace dart |
| OLD | NEW |