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/become.h" | 10 #include "vm/become.h" |
(...skipping 9005 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9016 RawGrowableObjectArray* Script::GenerateLineNumberArray() const { | 9016 RawGrowableObjectArray* Script::GenerateLineNumberArray() const { |
9017 Zone* zone = Thread::Current()->zone(); | 9017 Zone* zone = Thread::Current()->zone(); |
9018 const GrowableObjectArray& info = | 9018 const GrowableObjectArray& info = |
9019 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); | 9019 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); |
9020 const String& source = String::Handle(zone, Source()); | 9020 const String& source = String::Handle(zone, Source()); |
9021 const String& key = Symbols::Empty(); | 9021 const String& key = Symbols::Empty(); |
9022 const Object& line_separator = Object::Handle(zone); | 9022 const Object& line_separator = Object::Handle(zone); |
9023 Smi& value = Smi::Handle(zone); | 9023 Smi& value = Smi::Handle(zone); |
9024 | 9024 |
9025 if (kind() == RawScript::kKernelTag) { | 9025 if (kind() == RawScript::kKernelTag) { |
9026 const Array& line_starts_array = Array::Handle(line_starts()); | 9026 const TypedData& line_starts_data = TypedData::Handle(line_starts()); |
9027 if (line_starts_array.IsNull()) { | 9027 if (line_starts_data.IsNull()) { |
9028 // Scripts in the AOT snapshot do not have a line starts array. | 9028 // Scripts in the AOT snapshot do not have a line starts array. |
9029 // A well-formed line number array has a leading null. | 9029 // A well-formed line number array has a leading null. |
9030 info.Add(line_separator); // New line. | 9030 info.Add(line_separator); // New line. |
9031 return info.raw(); | 9031 return info.raw(); |
9032 } | 9032 } |
9033 intptr_t line_count = line_starts_array.Length(); | 9033 intptr_t line_count = line_starts_data.Length(); |
9034 ASSERT(line_count > 0); | 9034 ASSERT(line_count > 0); |
9035 const Array& debug_positions_array = Array::Handle(debug_positions()); | 9035 const Array& debug_positions_array = Array::Handle(debug_positions()); |
9036 intptr_t token_count = debug_positions_array.Length(); | 9036 intptr_t token_count = debug_positions_array.Length(); |
9037 int token_index = 0; | 9037 int token_index = 0; |
9038 | 9038 |
9039 for (int line_index = 0; line_index < line_count; ++line_index) { | 9039 for (int line_index = 0; line_index < line_count; ++line_index) { |
9040 value ^= line_starts_array.At(line_index); | 9040 intptr_t start = line_starts_data.GetUint32(line_index << 2); |
9041 intptr_t start = value.Value(); | |
9042 // Output the rest of the tokens if we have no next line. | 9041 // Output the rest of the tokens if we have no next line. |
9043 intptr_t end = TokenPosition::kMaxSourcePos; | 9042 intptr_t end = TokenPosition::kMaxSourcePos; |
9044 if (line_index + 1 < line_count) { | 9043 if (line_index + 1 < line_count) { |
9045 value ^= line_starts_array.At(line_index + 1); | 9044 end = line_starts_data.GetUint32((line_index + 1) << 2); |
9046 end = value.Value(); | |
9047 } | 9045 } |
9048 bool first = true; | 9046 bool first = true; |
9049 while (token_index < token_count) { | 9047 while (token_index < token_count) { |
9050 value ^= debug_positions_array.At(token_index); | 9048 value ^= debug_positions_array.At(token_index); |
9051 intptr_t debug_position = value.Value(); | 9049 intptr_t debug_position = value.Value(); |
9052 if (debug_position >= end) break; | 9050 if (debug_position >= end) break; |
9053 | 9051 |
9054 if (first) { | 9052 if (first) { |
9055 info.Add(line_separator); // New line. | 9053 info.Add(line_separator); // New line. |
9056 value = Smi::New(line_index + 1); // Line number. | 9054 value = Smi::New(line_index + 1); // Line number. |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9168 } | 9166 } |
9169 | 9167 |
9170 void Script::set_resolved_url(const String& value) const { | 9168 void Script::set_resolved_url(const String& value) const { |
9171 StorePointer(&raw_ptr()->resolved_url_, value.raw()); | 9169 StorePointer(&raw_ptr()->resolved_url_, value.raw()); |
9172 } | 9170 } |
9173 | 9171 |
9174 void Script::set_source(const String& value) const { | 9172 void Script::set_source(const String& value) const { |
9175 StorePointer(&raw_ptr()->source_, value.raw()); | 9173 StorePointer(&raw_ptr()->source_, value.raw()); |
9176 } | 9174 } |
9177 | 9175 |
9178 void Script::set_line_starts(const Array& value) const { | 9176 void Script::set_line_starts(const TypedData& value) const { |
9179 StorePointer(&raw_ptr()->line_starts_, value.raw()); | 9177 StorePointer(&raw_ptr()->line_starts_, value.raw()); |
9180 } | 9178 } |
9181 | 9179 |
9182 void Script::set_debug_positions(const Array& value) const { | 9180 void Script::set_debug_positions(const Array& value) const { |
9183 StorePointer(&raw_ptr()->debug_positions_, value.raw()); | 9181 StorePointer(&raw_ptr()->debug_positions_, value.raw()); |
9184 } | 9182 } |
9185 | 9183 |
9186 void Script::set_yield_positions(const Array& value) const { | 9184 void Script::set_yield_positions(const Array& value) const { |
9187 StorePointer(&raw_ptr()->yield_positions_, value.raw()); | 9185 StorePointer(&raw_ptr()->yield_positions_, value.raw()); |
9188 } | 9186 } |
9189 | 9187 |
9190 RawArray* Script::yield_positions() const { | 9188 RawArray* Script::yield_positions() const { |
9191 #if !defined(DART_PRECOMPILED_RUNTIME) | 9189 #if !defined(DART_PRECOMPILED_RUNTIME) |
9192 Array& yields = Array::Handle(raw_ptr()->yield_positions_); | 9190 Array& yields = Array::Handle(raw_ptr()->yield_positions_); |
9193 if (yields.IsNull() && kind() == RawScript::kKernelTag) { | 9191 if (yields.IsNull() && kind() == RawScript::kKernelTag) { |
9194 // This is created lazily. Now we need it. | 9192 // This is created lazily. Now we need it. |
9195 kernel::CollectTokenPositionsFor(*this); | 9193 kernel::CollectTokenPositionsFor(*this); |
9196 } | 9194 } |
9197 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 9195 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
9198 return raw_ptr()->yield_positions_; | 9196 return raw_ptr()->yield_positions_; |
9199 } | 9197 } |
9200 | 9198 |
9201 RawArray* Script::line_starts() const { | 9199 RawTypedData* Script::line_starts() const { |
9202 return raw_ptr()->line_starts_; | 9200 return raw_ptr()->line_starts_; |
9203 } | 9201 } |
9204 | 9202 |
9205 RawArray* Script::debug_positions() const { | 9203 RawArray* Script::debug_positions() const { |
9206 #if !defined(DART_PRECOMPILED_RUNTIME) | 9204 #if !defined(DART_PRECOMPILED_RUNTIME) |
9207 Array& debug_positions_array = Array::Handle(raw_ptr()->debug_positions_); | 9205 Array& debug_positions_array = Array::Handle(raw_ptr()->debug_positions_); |
9208 if (debug_positions_array.IsNull() && kind() == RawScript::kKernelTag) { | 9206 if (debug_positions_array.IsNull() && kind() == RawScript::kKernelTag) { |
9209 // This is created lazily. Now we need it. | 9207 // This is created lazily. Now we need it. |
9210 kernel::CollectTokenPositionsFor(*this); | 9208 kernel::CollectTokenPositionsFor(*this); |
9211 } | 9209 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9256 } | 9254 } |
9257 | 9255 |
9258 // Specialized for AOT compilation, which does this lookup for every token | 9256 // Specialized for AOT compilation, which does this lookup for every token |
9259 // position that could be part of a stack trace. | 9257 // position that could be part of a stack trace. |
9260 intptr_t Script::GetTokenLineUsingLineStarts( | 9258 intptr_t Script::GetTokenLineUsingLineStarts( |
9261 TokenPosition target_token_pos) const { | 9259 TokenPosition target_token_pos) const { |
9262 if (target_token_pos.IsNoSource()) { | 9260 if (target_token_pos.IsNoSource()) { |
9263 return 0; | 9261 return 0; |
9264 } | 9262 } |
9265 Zone* zone = Thread::Current()->zone(); | 9263 Zone* zone = Thread::Current()->zone(); |
9266 Array& line_starts_array = Array::Handle(zone, line_starts()); | 9264 TypedData& line_starts_data = TypedData::Handle(zone, line_starts()); |
9267 Smi& token_pos = Smi::Handle(zone); | 9265 if (line_starts_data.IsNull()) { |
9268 if (line_starts_array.IsNull()) { | |
9269 ASSERT(kind() != RawScript::kKernelTag); | 9266 ASSERT(kind() != RawScript::kKernelTag); |
9270 GrowableObjectArray& line_starts_list = | 9267 GrowableArray<intptr_t> line_starts_list(10); |
9271 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); | |
9272 const TokenStream& tkns = TokenStream::Handle(zone, tokens()); | 9268 const TokenStream& tkns = TokenStream::Handle(zone, tokens()); |
9273 TokenStream::Iterator tkit(zone, tkns, TokenPosition::kMinSource, | 9269 TokenStream::Iterator tkit(zone, tkns, TokenPosition::kMinSource, |
9274 TokenStream::Iterator::kAllTokens); | 9270 TokenStream::Iterator::kAllTokens); |
9275 intptr_t cur_line = line_offset() + 1; | 9271 intptr_t cur_line = line_offset() + 1; |
9276 token_pos = Smi::New(0); | 9272 intptr_t token_pos = 0; |
9277 line_starts_list.Add(token_pos); | 9273 line_starts_list.Add(token_pos); |
9278 while (tkit.CurrentTokenKind() != Token::kEOS) { | 9274 while (tkit.CurrentTokenKind() != Token::kEOS) { |
9279 if (tkit.CurrentTokenKind() == Token::kNEWLINE) { | 9275 if (tkit.CurrentTokenKind() == Token::kNEWLINE) { |
9280 cur_line++; | 9276 cur_line++; |
9281 token_pos = Smi::New(tkit.CurrentPosition().value() + 1); | 9277 token_pos = tkit.CurrentPosition().value() + 1; |
9282 line_starts_list.Add(token_pos); | 9278 line_starts_list.Add(token_pos); |
9283 } | 9279 } |
9284 tkit.Advance(); | 9280 tkit.Advance(); |
9285 } | 9281 } |
9286 line_starts_array = Array::MakeFixedLength(line_starts_list); | 9282 |
9287 set_line_starts(line_starts_array); | 9283 intptr_t length = line_starts_list.length(); |
| 9284 line_starts_data = |
| 9285 TypedData::New(kTypedDataUint32ArrayCid, length, Heap::kOld); |
| 9286 for (intptr_t i = 0; i < length; ++i) { |
| 9287 line_starts_data.SetUint32(i << 2, line_starts_list.At(i)); |
| 9288 } |
| 9289 |
| 9290 set_line_starts(line_starts_data); |
9288 } | 9291 } |
9289 | 9292 |
9290 ASSERT(line_starts_array.Length() > 0); | 9293 ASSERT(line_starts_data.Length() > 0); |
9291 intptr_t offset = target_token_pos.Pos(); | 9294 intptr_t offset = target_token_pos.Pos(); |
9292 intptr_t min = 0; | 9295 intptr_t min = 0; |
9293 intptr_t max = line_starts_array.Length() - 1; | 9296 intptr_t max = line_starts_data.Length() - 1; |
9294 | 9297 |
9295 // Binary search to find the line containing this offset. | 9298 // Binary search to find the line containing this offset. |
9296 while (min < max) { | 9299 while (min < max) { |
9297 int midpoint = (max - min + 1) / 2 + min; | 9300 int midpoint = (max - min + 1) / 2 + min; |
9298 token_pos ^= line_starts_array.At(midpoint); | 9301 intptr_t value = line_starts_data.GetUint32(midpoint << 2); |
9299 if (token_pos.Value() > offset) { | 9302 if (value > offset) { |
9300 max = midpoint - 1; | 9303 max = midpoint - 1; |
9301 } else { | 9304 } else { |
9302 min = midpoint; | 9305 min = midpoint; |
9303 } | 9306 } |
9304 } | 9307 } |
9305 return min + 1; // Line numbers start at 1. | 9308 return min + 1; // Line numbers start at 1. |
9306 } | 9309 } |
9307 | 9310 |
9308 void Script::GetTokenLocation(TokenPosition token_pos, | 9311 void Script::GetTokenLocation(TokenPosition token_pos, |
9309 intptr_t* line, | 9312 intptr_t* line, |
9310 intptr_t* column, | 9313 intptr_t* column, |
9311 intptr_t* token_len) const { | 9314 intptr_t* token_len) const { |
9312 ASSERT(line != NULL); | 9315 ASSERT(line != NULL); |
9313 Zone* zone = Thread::Current()->zone(); | 9316 Zone* zone = Thread::Current()->zone(); |
9314 | 9317 |
9315 if (kind() == RawScript::kKernelTag) { | 9318 if (kind() == RawScript::kKernelTag) { |
9316 const Array& line_starts_array = Array::Handle(zone, line_starts()); | 9319 const TypedData& line_starts_data = TypedData::Handle(zone, line_starts()); |
9317 if (line_starts_array.IsNull()) { | 9320 if (line_starts_data.IsNull()) { |
9318 // Scripts in the AOT snapshot do not have a line starts array. | 9321 // Scripts in the AOT snapshot do not have a line starts array. |
9319 *line = -1; | 9322 *line = -1; |
9320 if (column != NULL) { | 9323 if (column != NULL) { |
9321 *column = -1; | 9324 *column = -1; |
9322 } | 9325 } |
9323 if (token_len != NULL) { | 9326 if (token_len != NULL) { |
9324 *token_len = 1; | 9327 *token_len = 1; |
9325 } | 9328 } |
9326 return; | 9329 return; |
9327 } | 9330 } |
9328 ASSERT(line_starts_array.Length() > 0); | 9331 ASSERT(line_starts_data.Length() > 0); |
9329 intptr_t offset = token_pos.value(); | 9332 intptr_t offset = token_pos.value(); |
9330 intptr_t min = 0; | 9333 intptr_t min = 0; |
9331 intptr_t max = line_starts_array.Length() - 1; | 9334 intptr_t max = line_starts_data.Length() - 1; |
9332 | 9335 |
9333 // Binary search to find the line containing this offset. | 9336 // Binary search to find the line containing this offset. |
9334 Smi& smi = Smi::Handle(zone); | |
9335 while (min < max) { | 9337 while (min < max) { |
9336 intptr_t midpoint = (max - min + 1) / 2 + min; | 9338 intptr_t midpoint = (max - min + 1) / 2 + min; |
9337 | 9339 intptr_t value = line_starts_data.GetUint32(midpoint << 2); |
9338 smi ^= line_starts_array.At(midpoint); | 9340 if (value > offset) { |
9339 if (smi.Value() > offset) { | |
9340 max = midpoint - 1; | 9341 max = midpoint - 1; |
9341 } else { | 9342 } else { |
9342 min = midpoint; | 9343 min = midpoint; |
9343 } | 9344 } |
9344 } | 9345 } |
9345 *line = min + 1; // Line numbers start at 1. | 9346 *line = min + 1; // Line numbers start at 1. |
9346 smi ^= line_starts_array.At(min); | 9347 intptr_t value = line_starts_data.GetUint32(min << 2); |
9347 if (column != NULL) { | 9348 if (column != NULL) { |
9348 *column = offset - smi.Value() + 1; | 9349 *column = offset - value + 1; |
9349 } | 9350 } |
9350 if (token_len != NULL) { | 9351 if (token_len != NULL) { |
9351 // We don't explicitly save this data: Load the source | 9352 // We don't explicitly save this data: Load the source |
9352 // and find it from there. | 9353 // and find it from there. |
9353 const String& source = String::Handle(zone, Source()); | 9354 const String& source = String::Handle(zone, Source()); |
9354 *token_len = 1; | 9355 *token_len = 1; |
9355 if (offset < source.Length() && | 9356 if (offset < source.Length() && |
9356 Scanner::IsIdentStartChar(source.CharAt(offset))) { | 9357 Scanner::IsIdentStartChar(source.CharAt(offset))) { |
9357 for (intptr_t i = offset + 1; | 9358 for (intptr_t i = offset + 1; |
9358 i < source.Length() && Scanner::IsIdentChar(source.CharAt(i)); | 9359 i < source.Length() && Scanner::IsIdentChar(source.CharAt(i)); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9410 } | 9411 } |
9411 } | 9412 } |
9412 | 9413 |
9413 void Script::TokenRangeAtLine(intptr_t line_number, | 9414 void Script::TokenRangeAtLine(intptr_t line_number, |
9414 TokenPosition* first_token_index, | 9415 TokenPosition* first_token_index, |
9415 TokenPosition* last_token_index) const { | 9416 TokenPosition* last_token_index) const { |
9416 ASSERT(first_token_index != NULL && last_token_index != NULL); | 9417 ASSERT(first_token_index != NULL && last_token_index != NULL); |
9417 ASSERT(line_number > 0); | 9418 ASSERT(line_number > 0); |
9418 | 9419 |
9419 if (kind() == RawScript::kKernelTag) { | 9420 if (kind() == RawScript::kKernelTag) { |
9420 const Array& line_starts_array = Array::Handle(line_starts()); | 9421 const TypedData& line_starts_data = TypedData::Handle(line_starts()); |
9421 if (line_starts_array.IsNull()) { | 9422 if (line_starts_data.IsNull()) { |
9422 // Scripts in the AOT snapshot do not have a line starts array. | 9423 // Scripts in the AOT snapshot do not have a line starts array. |
9423 *first_token_index = TokenPosition::kNoSource; | 9424 *first_token_index = TokenPosition::kNoSource; |
9424 *last_token_index = TokenPosition::kNoSource; | 9425 *last_token_index = TokenPosition::kNoSource; |
9425 return; | 9426 return; |
9426 } | 9427 } |
9427 ASSERT(line_starts_array.Length() >= line_number); | 9428 ASSERT(line_starts_data.Length() >= line_number); |
9428 Smi& value = Smi::Handle(); | 9429 intptr_t value = line_starts_data.GetUint32((line_number - 1) << 2); |
9429 value ^= line_starts_array.At(line_number - 1); | 9430 *first_token_index = TokenPosition(value); |
9430 *first_token_index = TokenPosition(value.Value()); | 9431 if (line_starts_data.Length() > line_number) { |
9431 if (line_starts_array.Length() > line_number) { | 9432 value = line_starts_data.GetUint32(line_number << 2); |
9432 value ^= line_starts_array.At(line_number); | 9433 *last_token_index = TokenPosition(value - 1); |
9433 *last_token_index = TokenPosition(value.Value() - 1); | |
9434 } else { | 9434 } else { |
9435 // Length of source is last possible token in this script. | 9435 // Length of source is last possible token in this script. |
9436 *last_token_index = TokenPosition(String::Handle(Source()).Length()); | 9436 *last_token_index = TokenPosition(String::Handle(Source()).Length()); |
9437 } | 9437 } |
9438 return; | 9438 return; |
9439 } | 9439 } |
9440 | 9440 |
9441 Zone* zone = Thread::Current()->zone(); | 9441 Zone* zone = Thread::Current()->zone(); |
9442 *first_token_index = TokenPosition::kNoSource; | 9442 *first_token_index = TokenPosition::kNoSource; |
9443 *last_token_index = TokenPosition::kNoSource; | 9443 *last_token_index = TokenPosition::kNoSource; |
(...skipping 13090 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
22534 } | 22534 } |
22535 return UserTag::null(); | 22535 return UserTag::null(); |
22536 } | 22536 } |
22537 | 22537 |
22538 const char* UserTag::ToCString() const { | 22538 const char* UserTag::ToCString() const { |
22539 const String& tag_label = String::Handle(label()); | 22539 const String& tag_label = String::Handle(label()); |
22540 return tag_label.ToCString(); | 22540 return tag_label.ToCString(); |
22541 } | 22541 } |
22542 | 22542 |
22543 } // namespace dart | 22543 } // namespace dart |
OLD | NEW |