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 12360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12371 Handle<FixedArray> array = String::CalculateLineEnds(src, true); | 12371 Handle<FixedArray> array = String::CalculateLineEnds(src, true); |
12372 | 12372 |
12373 if (*array != isolate->heap()->empty_fixed_array()) { | 12373 if (*array != isolate->heap()->empty_fixed_array()) { |
12374 array->set_map(isolate->heap()->fixed_cow_array_map()); | 12374 array->set_map(isolate->heap()->fixed_cow_array_map()); |
12375 } | 12375 } |
12376 | 12376 |
12377 script->set_line_ends(*array); | 12377 script->set_line_ends(*array); |
12378 DCHECK(script->line_ends()->IsFixedArray()); | 12378 DCHECK(script->line_ends()->IsFixedArray()); |
12379 } | 12379 } |
12380 | 12380 |
12381 #define SMI_VALUE(x) (Smi::cast(x)->value()) | 12381 |
12382 bool Script::GetPositionInfo(int position, PositionInfo* info, | 12382 int Script::GetColumnNumber(Handle<Script> script, int code_pos) { |
12383 OffsetFlag offset_flag) { | 12383 int line_number = GetLineNumber(script, code_pos); |
12384 Handle<Script> script(this); | 12384 if (line_number == -1) return -1; |
12385 InitLineEnds(script); | |
12386 | 12385 |
12387 DisallowHeapAllocation no_allocation; | 12386 DisallowHeapAllocation no_allocation; |
12388 | 12387 FixedArray* line_ends_array = FixedArray::cast(script->line_ends()); |
12389 DCHECK(line_ends()->IsFixedArray()); | 12388 line_number = line_number - script->line_offset(); |
12390 FixedArray* ends = FixedArray::cast(line_ends()); | 12389 if (line_number == 0) return code_pos + script->column_offset(); |
12391 | 12390 int prev_line_end_pos = |
12392 const int ends_len = ends->length(); | 12391 Smi::cast(line_ends_array->get(line_number - 1))->value(); |
12393 if (ends_len == 0) return false; | 12392 return code_pos - (prev_line_end_pos + 1); |
12394 | |
12395 // Return early on invalid positions. Negative positions behave as if 0 was | |
12396 // passed, and positions beyond the end of the script return as failure. | |
12397 if (position < 0) { | |
12398 position = 0; | |
12399 } else if (position > SMI_VALUE(ends->get(ends_len - 1))) { | |
12400 return false; | |
12401 } | |
12402 | |
12403 // Determine line number by doing a binary search on the line ends array. | |
12404 if (SMI_VALUE(ends->get(0)) >= position) { | |
12405 info->line = 0; | |
12406 info->line_start = 0; | |
12407 info->column = position; | |
12408 } else { | |
12409 int left = 0; | |
12410 int right = ends_len - 1; | |
12411 | |
12412 while (right > 0) { | |
12413 DCHECK_LE(left, right); | |
12414 const int mid = (left + right) / 2; | |
12415 if (position > SMI_VALUE(ends->get(mid))) { | |
12416 left = mid + 1; | |
12417 } else if (position <= SMI_VALUE(ends->get(mid - 1))) { | |
12418 right = mid - 1; | |
12419 } else { | |
12420 info->line = mid; | |
12421 break; | |
12422 } | |
12423 } | |
12424 DCHECK(SMI_VALUE(ends->get(info->line)) >= position && | |
12425 SMI_VALUE(ends->get(info->line - 1)) < position); | |
12426 info->line_start = SMI_VALUE(ends->get(info->line - 1)) + 1; | |
12427 info->column = position - info->line_start; | |
12428 } | |
12429 | |
12430 // Line end is position of the linebreak character. | |
12431 info->line_end = SMI_VALUE(ends->get(info->line)); | |
12432 if (info->line_end > 0) { | |
12433 DCHECK(source()->IsString()); | |
12434 Handle<String> src(String::cast(source())); | |
12435 if (src->Get(info->line_end - 1) == '\r') { | |
12436 info->line_end--; | |
12437 } | |
12438 } | |
12439 | |
12440 // Add offsets if requested. | |
12441 if (offset_flag == kWithOffset) { | |
12442 if (info->line == 0) { | |
12443 info->column += column_offset(); | |
12444 } | |
12445 info->line += line_offset(); | |
12446 } | |
12447 | |
12448 return true; | |
12449 } | |
12450 #undef SMI_VALUE | |
12451 | |
12452 int Script::GetColumnNumber(Handle<Script> script, int code_pos) { | |
12453 PositionInfo info; | |
12454 if (!script->GetPositionInfo(code_pos, &info, kWithOffset)) { | |
12455 return -1; | |
12456 } | |
12457 | |
12458 return info.column; | |
12459 } | |
12460 | |
12461 int Script::GetLineNumberWithArray(int code_pos) { | |
12462 PositionInfo info; | |
12463 if (!GetPositionInfo(code_pos, &info, kWithOffset)) { | |
12464 return -1; | |
12465 } | |
12466 | |
12467 return info.line; | |
12468 } | 12393 } |
12469 | 12394 |
12470 | 12395 |
| 12396 int Script::GetLineNumberWithArray(int code_pos) { |
| 12397 DisallowHeapAllocation no_allocation; |
| 12398 DCHECK(line_ends()->IsFixedArray()); |
| 12399 FixedArray* line_ends_array = FixedArray::cast(line_ends()); |
| 12400 int line_ends_len = line_ends_array->length(); |
| 12401 if (line_ends_len == 0) return -1; |
| 12402 |
| 12403 if ((Smi::cast(line_ends_array->get(0)))->value() >= code_pos) { |
| 12404 return line_offset(); |
| 12405 } |
| 12406 |
| 12407 int left = 0; |
| 12408 int right = line_ends_len; |
| 12409 while (int half = (right - left) / 2) { |
| 12410 if ((Smi::cast(line_ends_array->get(left + half)))->value() > code_pos) { |
| 12411 right -= half; |
| 12412 } else { |
| 12413 left += half; |
| 12414 } |
| 12415 } |
| 12416 return right + line_offset(); |
| 12417 } |
| 12418 |
| 12419 |
12471 int Script::GetLineNumber(Handle<Script> script, int code_pos) { | 12420 int Script::GetLineNumber(Handle<Script> script, int code_pos) { |
12472 InitLineEnds(script); | 12421 InitLineEnds(script); |
12473 return script->GetLineNumberWithArray(code_pos); | 12422 return script->GetLineNumberWithArray(code_pos); |
12474 } | 12423 } |
12475 | 12424 |
12476 | 12425 |
12477 int Script::GetLineNumber(int code_pos) { | 12426 int Script::GetLineNumber(int code_pos) { |
12478 DisallowHeapAllocation no_allocation; | 12427 DisallowHeapAllocation no_allocation; |
12479 if (!line_ends()->IsUndefined()) return GetLineNumberWithArray(code_pos); | 12428 if (!line_ends()->IsUndefined()) return GetLineNumberWithArray(code_pos); |
12480 | 12429 |
(...skipping 5951 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
18432 if (cell->value() != *new_value) { | 18381 if (cell->value() != *new_value) { |
18433 cell->set_value(*new_value); | 18382 cell->set_value(*new_value); |
18434 Isolate* isolate = cell->GetIsolate(); | 18383 Isolate* isolate = cell->GetIsolate(); |
18435 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 18384 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
18436 isolate, DependentCode::kPropertyCellChangedGroup); | 18385 isolate, DependentCode::kPropertyCellChangedGroup); |
18437 } | 18386 } |
18438 } | 18387 } |
18439 | 18388 |
18440 } // namespace internal | 18389 } // namespace internal |
18441 } // namespace v8 | 18390 } // namespace v8 |
OLD | NEW |