OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/objects.h" | 5 #include "src/objects.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 #include <iomanip> | 8 #include <iomanip> |
9 #include <sstream> | 9 #include <sstream> |
10 | 10 |
(...skipping 12352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12363 Handle<FixedArray> array = String::CalculateLineEnds(src, true); | 12363 Handle<FixedArray> array = String::CalculateLineEnds(src, true); |
12364 | 12364 |
12365 if (*array != isolate->heap()->empty_fixed_array()) { | 12365 if (*array != isolate->heap()->empty_fixed_array()) { |
12366 array->set_map(isolate->heap()->fixed_cow_array_map()); | 12366 array->set_map(isolate->heap()->fixed_cow_array_map()); |
12367 } | 12367 } |
12368 | 12368 |
12369 script->set_line_ends(*array); | 12369 script->set_line_ends(*array); |
12370 DCHECK(script->line_ends()->IsFixedArray()); | 12370 DCHECK(script->line_ends()->IsFixedArray()); |
12371 } | 12371 } |
12372 | 12372 |
| 12373 #define SMI_VALUE(x) (Smi::cast(x)->value()) |
| 12374 bool Script::GetPositionInfo(int position, PositionInfo* info, |
| 12375 OffsetFlag offset_flag) { |
| 12376 Handle<Script> script(this); |
| 12377 InitLineEnds(script); |
| 12378 |
| 12379 DisallowHeapAllocation no_allocation; |
| 12380 |
| 12381 DCHECK(script->line_ends()->IsFixedArray()); |
| 12382 FixedArray* ends = FixedArray::cast(script->line_ends()); |
| 12383 |
| 12384 const int ends_len = ends->length(); |
| 12385 if (ends_len == 0) return false; |
| 12386 |
| 12387 // Return early on invalid positions. Negative positions behave as if 0 was |
| 12388 // passed, and positions beyond the end of the script return as failure. |
| 12389 if (position < 0) { |
| 12390 position = 0; |
| 12391 } else if (position > SMI_VALUE(ends->get(ends_len - 1))) { |
| 12392 return false; |
| 12393 } |
| 12394 |
| 12395 // Determine line number by doing a binary search on the line ends array. |
| 12396 if (SMI_VALUE(ends->get(0)) >= position) { |
| 12397 info->line = 0; |
| 12398 info->line_start = 0; |
| 12399 info->column = position; |
| 12400 } else { |
| 12401 int left = 0; |
| 12402 int right = ends_len - 1; |
| 12403 |
| 12404 while (right > 0) { |
| 12405 DCHECK_LE(left, right); |
| 12406 const int mid = (left + right) / 2; |
| 12407 if (position > SMI_VALUE(ends->get(mid))) { |
| 12408 left = mid + 1; |
| 12409 } else if (position <= SMI_VALUE(ends->get(mid - 1))) { |
| 12410 right = mid - 1; |
| 12411 } else { |
| 12412 info->line = mid; |
| 12413 break; |
| 12414 } |
| 12415 } |
| 12416 DCHECK(SMI_VALUE(ends->get(info->line)) >= position && |
| 12417 SMI_VALUE(ends->get(info->line - 1)) < position); |
| 12418 info->line_start = SMI_VALUE(ends->get(info->line - 1)) + 1; |
| 12419 info->column = position - info->line_start; |
| 12420 } |
| 12421 |
| 12422 // Line end is position of the linebreak character. |
| 12423 info->line_end = SMI_VALUE(ends->get(info->line)); |
| 12424 if (info->line_end > 0) { |
| 12425 DCHECK(script->source()->IsString()); |
| 12426 Handle<String> src(String::cast(script->source())); |
| 12427 if (src->Get(info->line_end - 1) == '\r') { |
| 12428 info->line_end--; |
| 12429 } |
| 12430 } |
| 12431 |
| 12432 // Add offsets if requested. |
| 12433 if (offset_flag == WITH_OFFSET) { |
| 12434 if (info->line == 0) { |
| 12435 info->column += script->column_offset(); |
| 12436 } |
| 12437 info->line += script->line_offset(); |
| 12438 } |
| 12439 |
| 12440 return true; |
| 12441 } |
| 12442 #undef SMI_VALUE |
12373 | 12443 |
12374 int Script::GetColumnNumber(Handle<Script> script, int code_pos) { | 12444 int Script::GetColumnNumber(Handle<Script> script, int code_pos) { |
12375 int line_number = GetLineNumber(script, code_pos); | 12445 PositionInfo info; |
12376 if (line_number == -1) return -1; | 12446 if (!script->GetPositionInfo(code_pos, &info, WITH_OFFSET)) { |
| 12447 return -1; |
| 12448 } |
12377 | 12449 |
12378 DisallowHeapAllocation no_allocation; | 12450 return info.column; |
12379 FixedArray* line_ends_array = FixedArray::cast(script->line_ends()); | 12451 } |
12380 line_number = line_number - script->line_offset(); | 12452 |
12381 if (line_number == 0) return code_pos + script->column_offset(); | 12453 int Script::GetLineNumberWithArray(int code_pos) { |
12382 int prev_line_end_pos = | 12454 PositionInfo info; |
12383 Smi::cast(line_ends_array->get(line_number - 1))->value(); | 12455 if (!GetPositionInfo(code_pos, &info, WITH_OFFSET)) { |
12384 return code_pos - (prev_line_end_pos + 1); | 12456 return -1; |
| 12457 } |
| 12458 |
| 12459 return info.line; |
12385 } | 12460 } |
12386 | 12461 |
12387 | 12462 |
12388 int Script::GetLineNumberWithArray(int code_pos) { | |
12389 DisallowHeapAllocation no_allocation; | |
12390 DCHECK(line_ends()->IsFixedArray()); | |
12391 FixedArray* line_ends_array = FixedArray::cast(line_ends()); | |
12392 int line_ends_len = line_ends_array->length(); | |
12393 if (line_ends_len == 0) return -1; | |
12394 | |
12395 if ((Smi::cast(line_ends_array->get(0)))->value() >= code_pos) { | |
12396 return line_offset(); | |
12397 } | |
12398 | |
12399 int left = 0; | |
12400 int right = line_ends_len; | |
12401 while (int half = (right - left) / 2) { | |
12402 if ((Smi::cast(line_ends_array->get(left + half)))->value() > code_pos) { | |
12403 right -= half; | |
12404 } else { | |
12405 left += half; | |
12406 } | |
12407 } | |
12408 return right + line_offset(); | |
12409 } | |
12410 | |
12411 | |
12412 int Script::GetLineNumber(Handle<Script> script, int code_pos) { | 12463 int Script::GetLineNumber(Handle<Script> script, int code_pos) { |
12413 InitLineEnds(script); | 12464 InitLineEnds(script); |
12414 return script->GetLineNumberWithArray(code_pos); | 12465 return script->GetLineNumberWithArray(code_pos); |
12415 } | 12466 } |
12416 | 12467 |
12417 | 12468 |
12418 int Script::GetLineNumber(int code_pos) { | 12469 int Script::GetLineNumber(int code_pos) { |
12419 DisallowHeapAllocation no_allocation; | 12470 DisallowHeapAllocation no_allocation; |
12420 if (!line_ends()->IsUndefined()) return GetLineNumberWithArray(code_pos); | 12471 if (!line_ends()->IsUndefined()) return GetLineNumberWithArray(code_pos); |
12421 | 12472 |
(...skipping 5971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
18393 if (cell->value() != *new_value) { | 18444 if (cell->value() != *new_value) { |
18394 cell->set_value(*new_value); | 18445 cell->set_value(*new_value); |
18395 Isolate* isolate = cell->GetIsolate(); | 18446 Isolate* isolate = cell->GetIsolate(); |
18396 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 18447 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
18397 isolate, DependentCode::kPropertyCellChangedGroup); | 18448 isolate, DependentCode::kPropertyCellChangedGroup); |
18398 } | 18449 } |
18399 } | 18450 } |
18400 | 18451 |
18401 } // namespace internal | 18452 } // namespace internal |
18402 } // namespace v8 | 18453 } // namespace v8 |
OLD | NEW |