| 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 |