| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | |
| 2 // Redistribution and use in source and binary forms, with or without | |
| 3 // modification, are permitted provided that the following conditions are | |
| 4 // met: | |
| 5 // | |
| 6 // * Redistributions of source code must retain the above copyright | |
| 7 // notice, this list of conditions and the following disclaimer. | |
| 8 // * Redistributions in binary form must reproduce the above | |
| 9 // copyright notice, this list of conditions and the following | |
| 10 // disclaimer in the documentation and/or other materials provided | |
| 11 // with the distribution. | |
| 12 // * Neither the name of Google Inc. nor the names of its | |
| 13 // contributors may be used to endorse or promote products derived | |
| 14 // from this software without specific prior written permission. | |
| 15 // | |
| 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 27 | |
| 28 #include "experimental-scanner.h" | |
| 29 | |
| 30 namespace v8 { | |
| 31 namespace internal { | |
| 32 | |
| 33 template<> | |
| 34 const uint8_t* ExperimentalScanner<uint8_t>::GetNewBufferBasedOnHandle() const { | |
| 35 String::FlatContent content = source_handle_->GetFlatContent(); | |
| 36 return content.ToOneByteVector().start(); | |
| 37 } | |
| 38 | |
| 39 | |
| 40 template <> | |
| 41 const uint16_t* ExperimentalScanner<uint16_t>::GetNewBufferBasedOnHandle() | |
| 42 const { | |
| 43 String::FlatContent content = source_handle_->GetFlatContent(); | |
| 44 return content.ToUC16Vector().start(); | |
| 45 } | |
| 46 | |
| 47 | |
| 48 template<> | |
| 49 const int8_t* ExperimentalScanner<int8_t>::GetNewBufferBasedOnHandle() const { | |
| 50 String::FlatContent content = source_handle_->GetFlatContent(); | |
| 51 return reinterpret_cast<const int8_t*>(content.ToOneByteVector().start()); | |
| 52 } | |
| 53 | |
| 54 | |
| 55 template<> | |
| 56 bool ExperimentalScanner<uint8_t>::IsSubstringOfSource(const TokenDesc& token) { | |
| 57 return !token.has_escapes; | |
| 58 } | |
| 59 | |
| 60 | |
| 61 template<> | |
| 62 bool ExperimentalScanner<uint16_t>::IsSubstringOfSource( | |
| 63 const TokenDesc& token) { | |
| 64 if (token.has_escapes) return false; | |
| 65 const uint16_t* start = buffer_ + token.beg_pos; | |
| 66 const uint16_t* end = buffer_ + token.end_pos; | |
| 67 for (const uint16_t* cursor = start; cursor != end; ++cursor) { | |
| 68 if (*cursor >= unibrow::Latin1::kMaxChar) return true; | |
| 69 } | |
| 70 return false; | |
| 71 } | |
| 72 | |
| 73 | |
| 74 template<> | |
| 75 bool ExperimentalScanner<int8_t>::IsSubstringOfSource(const TokenDesc& token) { | |
| 76 // FIXME: implement. | |
| 77 UNREACHABLE(); | |
| 78 return false; | |
| 79 } | |
| 80 | |
| 81 | |
| 82 template<> | |
| 83 bool ExperimentalScanner<uint8_t>::FillLiteral( | |
| 84 const TokenDesc& token, LiteralDesc* literal) { | |
| 85 literal->beg_pos = token.beg_pos; | |
| 86 const uint8_t* start = buffer_ + token.beg_pos; | |
| 87 const uint8_t* end = buffer_ + token.end_pos; | |
| 88 if (token.token == Token::STRING) { | |
| 89 ++start; | |
| 90 --end; | |
| 91 } | |
| 92 if (IsSubstringOfSource(token)) { | |
| 93 literal->is_ascii = true; | |
| 94 literal->is_in_buffer = false; | |
| 95 literal->offset = start - buffer_; | |
| 96 literal->length = end - start; | |
| 97 literal->ascii_string = Vector<const char>( | |
| 98 reinterpret_cast<const char*>(start), literal->length); | |
| 99 return true; | |
| 100 } | |
| 101 return CopyToLiteralBuffer(start, end, token, literal); | |
| 102 } | |
| 103 | |
| 104 | |
| 105 template<> | |
| 106 bool ExperimentalScanner<uint16_t>::FillLiteral( | |
| 107 const TokenDesc& token, LiteralDesc* literal) { | |
| 108 literal->beg_pos = token.beg_pos; | |
| 109 const uint16_t* start = buffer_ + token.beg_pos; | |
| 110 const uint16_t* end = buffer_ + token.end_pos; | |
| 111 if (token.token == Token::STRING) { | |
| 112 ++start; | |
| 113 --end; | |
| 114 } | |
| 115 if (IsSubstringOfSource(token)) { | |
| 116 literal->is_ascii = false; | |
| 117 literal->is_in_buffer = false; | |
| 118 literal->offset = start - buffer_; | |
| 119 literal->length = end - start; | |
| 120 literal->utf16_string = Vector<const uint16_t>(start, literal->length); | |
| 121 return true; | |
| 122 } | |
| 123 return CopyToLiteralBuffer(start, end, token, literal); | |
| 124 } | |
| 125 | |
| 126 | |
| 127 template<> | |
| 128 bool ExperimentalScanner<int8_t>::FillLiteral( | |
| 129 const TokenDesc& token, LiteralDesc* literal) { | |
| 130 // FIXME: implement. | |
| 131 UNREACHABLE(); | |
| 132 return false; | |
| 133 } | |
| 134 | |
| 135 | |
| 136 template<class Char> | |
| 137 bool ExperimentalScanner<Char>::CopyToLiteralBuffer(const Char* start, | |
| 138 const Char* end, | |
| 139 const TokenDesc& token, | |
| 140 LiteralDesc* literal) { | |
| 141 literal->buffer.Reset(); | |
| 142 if (token.has_escapes) { | |
| 143 for (const Char* cursor = start; cursor != end;) { | |
| 144 if (*cursor != '\\') { | |
| 145 literal->buffer.AddChar(*cursor++); | |
| 146 } else if (token.token == Token::IDENTIFIER) { | |
| 147 uc32 c; | |
| 148 cursor = ScanIdentifierUnicodeEscape(cursor, end, &c); | |
| 149 ASSERT(cursor != NULL); | |
| 150 if (cursor == NULL) return false; | |
| 151 literal->buffer.AddChar(c); | |
| 152 } else { | |
| 153 cursor = ScanEscape(cursor, end, &literal->buffer); | |
| 154 ASSERT(cursor != NULL); | |
| 155 if (cursor == NULL) return false; | |
| 156 } | |
| 157 } | |
| 158 } else { | |
| 159 for (const Char* cursor = start; cursor != end;) { | |
| 160 literal->buffer.AddChar(*cursor++); | |
| 161 } | |
| 162 } | |
| 163 literal->is_ascii = literal->buffer.is_ascii(); | |
| 164 literal->is_in_buffer = true; | |
| 165 literal->length = literal->buffer.length(); | |
| 166 if (literal->is_ascii) { | |
| 167 literal->ascii_string = literal->buffer.ascii_literal(); | |
| 168 } else { | |
| 169 literal->utf16_string = literal->buffer.utf16_literal(); | |
| 170 } | |
| 171 return true; | |
| 172 } | |
| 173 | |
| 174 | |
| 175 template<class Char> | |
| 176 Handle<String> ExperimentalScanner<Char>::InternalizeLiteral( | |
| 177 LiteralDesc* literal) { | |
| 178 Factory* factory = isolate_->factory(); | |
| 179 if (literal->is_in_buffer) { | |
| 180 return literal->is_ascii | |
| 181 ? factory->InternalizeOneByteString( | |
| 182 Vector<const uint8_t>::cast(literal->ascii_string)) | |
| 183 : factory->InternalizeTwoByteString(literal->utf16_string); | |
| 184 } | |
| 185 if (sizeof(Char) == 1) { | |
| 186 SubStringKey<uint8_t> key( | |
| 187 source_handle_, literal->offset, literal->length); | |
| 188 return factory->InternalizeStringWithKey(&key); | |
| 189 } else { | |
| 190 SubStringKey<uint16_t> key( | |
| 191 source_handle_, literal->offset, literal->length); | |
| 192 return factory->InternalizeStringWithKey(&key); | |
| 193 } | |
| 194 } | |
| 195 | |
| 196 | |
| 197 template<> | |
| 198 Handle<String> ExperimentalScanner<uint8_t>::AllocateLiteral( | |
| 199 LiteralDesc* literal, PretenureFlag pretenured) { | |
| 200 Factory* factory = isolate_->factory(); | |
| 201 if (literal->is_in_buffer) { | |
| 202 return literal->is_ascii | |
| 203 ? factory->NewStringFromAscii(literal->ascii_string, pretenured) | |
| 204 : factory->NewStringFromTwoByte(literal->utf16_string, pretenured); | |
| 205 } | |
| 206 int from = literal->offset; | |
| 207 int length = literal->length; | |
| 208 // Save the offset and the length before allocating the string as it may | |
| 209 // cause a GC, invalidate the literal, and move the source. | |
| 210 Handle<String> result = factory->NewRawOneByteString(length, pretenured); | |
| 211 uint8_t* chars = SeqOneByteString::cast(*result)->GetChars(); | |
| 212 String::WriteToFlat(*source_handle_, chars, from, from + length); | |
| 213 return result; | |
| 214 } | |
| 215 | |
| 216 | |
| 217 template<> | |
| 218 Handle<String> ExperimentalScanner<uint16_t>::AllocateLiteral( | |
| 219 LiteralDesc* literal, PretenureFlag pretenured) { | |
| 220 Factory* factory = isolate_->factory(); | |
| 221 if (literal->is_in_buffer) { | |
| 222 return literal->is_ascii | |
| 223 ? factory->NewStringFromAscii(literal->ascii_string, pretenured) | |
| 224 : factory->NewStringFromTwoByte(literal->utf16_string, pretenured); | |
| 225 } | |
| 226 // Save the offset and the length before allocating the string as it may | |
| 227 // cause a GC, invalidate the literal, and move the source. | |
| 228 int from = literal->offset; | |
| 229 int length = literal->length; | |
| 230 Handle<String> result = factory->NewRawTwoByteString(length, pretenured); | |
| 231 uint16_t* chars = SeqTwoByteString::cast(*result)->GetChars(); | |
| 232 String::WriteToFlat(*source_handle_, chars, from, from + length); | |
| 233 return result; | |
| 234 } | |
| 235 | |
| 236 | |
| 237 template<> | |
| 238 Handle<String> ExperimentalScanner<int8_t>::AllocateLiteral( | |
| 239 LiteralDesc* literal, PretenureFlag pretenured) { | |
| 240 // FIXME: implement | |
| 241 UNREACHABLE(); | |
| 242 return Handle<String>(); | |
| 243 } | |
| 244 | |
| 245 template class ExperimentalScanner<uint8_t>; | |
| 246 template class ExperimentalScanner<uint16_t>; | |
| 247 template class ExperimentalScanner<int8_t>; | |
| 248 | |
| 249 } } // v8::internal | |
| OLD | NEW |