Correctly parse line ends for debugging.
Instead of using only \n as line terminator, we now use the definition in http://www.ecma-international.org/ecma-262/5.1/#sec-7.3 R=marja@chromium.org BUG=v8:2825 LOG=Y Review URL: https://codereview.chromium.org/821383009 Cr-Commit-Position: refs/heads/master@{#25989}
This commit is contained in:
parent
ad412d046b
commit
2050994d80
@ -8764,20 +8764,18 @@ static void CalculateLineEndsImpl(Isolate* isolate,
|
||||
Vector<const SourceChar> src,
|
||||
bool include_ending_line) {
|
||||
const int src_len = src.length();
|
||||
StringSearch<uint8_t, SourceChar> search(isolate, STATIC_CHAR_VECTOR("\n"));
|
||||
UnicodeCache* cache = isolate->unicode_cache();
|
||||
for (int i = 0; i < src_len - 1; i++) {
|
||||
SourceChar current = src[i];
|
||||
SourceChar next = src[i + 1];
|
||||
if (cache->IsLineTerminatorSequence(current, next)) line_ends->Add(i);
|
||||
}
|
||||
|
||||
// Find and record line ends.
|
||||
int position = 0;
|
||||
while (position != -1 && position < src_len) {
|
||||
position = search.Search(src, position);
|
||||
if (position != -1) {
|
||||
line_ends->Add(position);
|
||||
position++;
|
||||
} else if (include_ending_line) {
|
||||
// Even if the last line misses a line end, it is counted.
|
||||
line_ends->Add(src_len);
|
||||
return;
|
||||
}
|
||||
if (src_len > 0 && cache->IsLineTerminatorSequence(src[src_len - 1], 0)) {
|
||||
line_ends->Add(src_len - 1);
|
||||
} else if (include_ending_line) {
|
||||
// Even if the last line misses a line end, it is counted.
|
||||
line_ends->Add(src_len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,6 +121,12 @@ class UnicodeCache {
|
||||
bool IsIdentifierStart(unibrow::uchar c) { return kIsIdentifierStart.get(c); }
|
||||
bool IsIdentifierPart(unibrow::uchar c) { return kIsIdentifierPart.get(c); }
|
||||
bool IsLineTerminator(unibrow::uchar c) { return kIsLineTerminator.get(c); }
|
||||
bool IsLineTerminatorSequence(unibrow::uchar c, unibrow::uchar next) {
|
||||
if (!IsLineTerminator(c)) return false;
|
||||
if (c == 0x000d && next == 0x000a) return false; // CR with following LF.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsWhiteSpace(unibrow::uchar c) { return kIsWhiteSpace.get(c); }
|
||||
bool IsWhiteSpaceOrLineTerminator(unibrow::uchar c) {
|
||||
return kIsWhiteSpaceOrLineTerminator.get(c);
|
||||
|
40
test/mjsunit/regress/regress-2825.js
Normal file
40
test/mjsunit/regress/regress-2825.js
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright 2015 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --expose-debug-as debug
|
||||
|
||||
// Do not edit this file with an editor that replaces \r with \r\n.
|
||||
// Variable definitions for i0 through i3 are each terminated with \r.
|
||||
function f() {
|
||||
var i0 = 0;
var i1 = 1;
var i2 = 2;
var i3 = 3;
|
||||
var j0 = 0;
|
||||
var j1 = 1;
|
||||
var j2 = 2;
|
||||
var j3 = 3;
|
||||
}
|
||||
|
||||
Debug = debug.Debug;
|
||||
var exception = null;
|
||||
var break_point_hit = false;
|
||||
|
||||
function listener(event, exec_state, event_data, data) {
|
||||
if (event != Debug.DebugEvent.Break) return;
|
||||
try {
|
||||
break_point_hit = true;
|
||||
assertEquals(" var i2 = 2;", exec_state.frame(0).sourceLineText());
|
||||
} catch (e) {
|
||||
print(e + e.stack);
|
||||
exception = e;
|
||||
}
|
||||
}
|
||||
|
||||
Debug.setListener(listener);
|
||||
|
||||
Debug.setBreakPoint(f, 3, 0);
|
||||
|
||||
f();
|
||||
|
||||
Debug.setListener(null);
|
||||
assertTrue(break_point_hit);
|
||||
assertNull(exception);
|
Loading…
Reference in New Issue
Block a user