Commit a8921c46 authored by sandholm@chromium.org's avatar sandholm@chromium.org

Inctroduce NewStrictSubstring to avoid check for SubString(str, 0, str.length). Cleanup JsonParser.

Review URL: http://codereview.chromium.org/7230006

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8369 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 650df48c
......@@ -214,6 +214,16 @@ Handle<String> Factory::NewSubString(Handle<String> str,
}
Handle<String> Factory::NewStrictSubString(Handle<String> str,
int begin,
int end) {
ASSERT(begin > 0 || end < str->length());
CALL_HEAP_FUNCTION(isolate(),
isolate()->heap()->AllocateSubString(*str, begin, end),
String);
}
Handle<String> Factory::NewExternalStringFromAscii(
ExternalAsciiString::Resource* resource) {
CALL_HEAP_FUNCTION(
......
......@@ -133,6 +133,11 @@ class Factory {
int begin,
int end);
// Create a new string object which holds a strict substring of a string.
Handle<String> NewStrictSubString(Handle<String> str,
int begin,
int end);
// Creates a new external String object. There are two String encodings
// in the system: ASCII and two byte. Unlike other String types, it does
// not make sense to have a UTF-8 factory function for external strings,
......
......@@ -109,7 +109,7 @@ class JsonParser BASE_EMBEDDED {
Handle<String> ScanJsonString();
// Slow version for unicode support, uses the first ascii_count characters,
// as first part of a ConsString
Handle<String> SlowScanJsonString();
Handle<String> SlowScanJsonString(int beg_pos);
// A JSON number (production JSONNumber) is a subset of the valid JavaScript
// decimal number literals.
......@@ -156,15 +156,9 @@ class JsonParser BASE_EMBEDDED {
int source_length_;
Handle<SeqAsciiString> seq_source_;
// begin and end position of scanned string or number
int beg_pos_;
int end_pos_;
Isolate* isolate_;
uc32 c0_;
int position_;
double number_;
};
template <bool seq_ascii>
......@@ -353,7 +347,7 @@ Handle<Object> JsonParser<seq_ascii>::ParseJsonArray() {
template <bool seq_ascii>
Handle<Object> JsonParser<seq_ascii>::ParseJsonNumber() {
bool negative = false;
beg_pos_ = position_;
int beg_pos = position_;
if (c0_ == '-') {
Advance();
negative = true;
......@@ -373,9 +367,8 @@ Handle<Object> JsonParser<seq_ascii>::ParseJsonNumber() {
Advance();
} while (c0_ >= '0' && c0_ <= '9');
if (c0_ != '.' && c0_ != 'e' && c0_ != 'E' && digits < 10) {
number_ = (negative ? -i : i);
SkipWhitespace();
return isolate()->factory()->NewNumber(number_);
return Handle<Smi>(Smi::FromInt((negative ? -i : i)), isolate());
}
}
if (c0_ == '.') {
......@@ -393,35 +386,36 @@ Handle<Object> JsonParser<seq_ascii>::ParseJsonNumber() {
Advance();
} while (c0_ >= '0' && c0_ <= '9');
}
int length = position_ - beg_pos_;
int length = position_ - beg_pos;
double number;
if (seq_ascii) {
Vector<const char> chars(seq_source_->GetChars() + beg_pos_, length);
number_ = StringToDouble(isolate()->unicode_cache(),
Vector<const char> chars(seq_source_->GetChars() + beg_pos, length);
number = StringToDouble(isolate()->unicode_cache(),
chars,
NO_FLAGS, // Hex, octal or trailing junk.
OS::nan_value());
} else {
Vector<char> buffer = Vector<char>::New(length);
String::WriteToFlat(*source_, buffer.start(), beg_pos_, position_);
String::WriteToFlat(*source_, buffer.start(), beg_pos, position_);
Vector<const char> result =
Vector<const char>(reinterpret_cast<const char*>(buffer.start()),
length);
number_ = StringToDouble(isolate()->unicode_cache(),
number = StringToDouble(isolate()->unicode_cache(),
result,
NO_FLAGS, // Hex, octal or trailing junk.
0.0);
buffer.Dispose();
}
SkipWhitespace();
return isolate()->factory()->NewNumber(number_);
return isolate()->factory()->NewNumber(number);
}
template <bool seq_ascii>
Handle<String> JsonParser<seq_ascii>::SlowScanJsonString() {
Handle<String> JsonParser<seq_ascii>::SlowScanJsonString(int beg_pos) {
// The currently scanned ascii characters.
Handle<String> ascii(isolate()->factory()->NewSubString(source_,
beg_pos_,
position_));
Handle<String> ascii(isolate()->factory()->NewStrictSubString(source_,
beg_pos,
position_));
Handle<String> two_byte =
isolate()->factory()->NewRawTwoByteString(kInitialSpecialStringSize,
NOT_TENURED);
......@@ -518,7 +512,7 @@ template <bool is_symbol>
Handle<String> JsonParser<seq_ascii>::ScanJsonString() {
ASSERT_EQ('"', c0_);
Advance();
beg_pos_ = position_;
int beg_pos = position_;
// Fast case for ascii only without escape characters.
while (c0_ != '"') {
// Check for control character (0x00-0x1f) or unterminated string (<0).
......@@ -526,19 +520,21 @@ Handle<String> JsonParser<seq_ascii>::ScanJsonString() {
if (c0_ != '\\' && (seq_ascii || c0_ < kMaxAsciiCharCode)) {
Advance();
} else {
return this->SlowScanJsonString();
return this->SlowScanJsonString(beg_pos);
}
}
ASSERT_EQ('"', c0_);
end_pos_ = position_;
int end_pos = position_;
// Advance past the last '"'.
AdvanceSkipWhitespace();
if (seq_ascii && is_symbol) {
return isolate()->factory()->LookupAsciiSymbol(seq_source_,
beg_pos_,
end_pos_ - beg_pos_);
beg_pos,
end_pos - beg_pos);
} else {
return isolate()->factory()->NewSubString(source_, beg_pos_, end_pos_);
return isolate()->factory()->NewStrictSubString(source_,
beg_pos,
end_pos);
}
}
......
......@@ -278,7 +278,7 @@ function BasicJSONSerialize(key, value, stack, builder) {
}
}
if (IS_STRING(value)) {
builder.push(%QuoteJSONString(value));
builder.push(value !== "" ? %QuoteJSONString(value) : '""');
} else if (IS_NUMBER(value)) {
builder.push(JSON_NUMBER_TO_STRING(value));
} else if (IS_BOOLEAN(value)) {
......
......@@ -3146,9 +3146,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringMatch) {
ZoneScope zone_space(isolate, DELETE_ON_EXIT);
ZoneList<int> offsets(8);
int start;
int end;
do {
int start;
int end;
{
AssertNoAllocation no_alloc;
FixedArray* elements = FixedArray::cast(regexp_info->elements());
......@@ -3157,20 +3157,23 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringMatch) {
}
offsets.Add(start);
offsets.Add(end);
int index = start < end ? end : end + 1;
if (index > length) break;
match = RegExpImpl::Exec(regexp, subject, index, regexp_info);
if (start == end) if (++end > length) break;
match = RegExpImpl::Exec(regexp, subject, end, regexp_info);
if (match.is_null()) {
return Failure::Exception();
}
} while (!match->IsNull());
int matches = offsets.length() / 2;
Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches);
for (int i = 0; i < matches ; i++) {
Handle<String> substring = isolate->factory()->
NewSubString(subject, offsets.at(0), offsets.at(1));
elements->set(0, *substring);
for (int i = 1; i < matches ; i++) {
int from = offsets.at(i * 2);
int to = offsets.at(i * 2 + 1);
Handle<String> match = isolate->factory()->NewSubString(subject, from, to);
elements->set(i, *match);
Handle<String> substring = isolate->factory()->
NewStrictSubString(subject, from, to);
elements->set(i, *substring);
}
Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(elements);
result->set_length(Smi::FromInt(matches));
......@@ -3320,6 +3323,7 @@ static RegExpImpl::IrregexpResult SearchRegExpNoCaptureMultiple(
OffsetsVector registers(required_registers);
Vector<int32_t> register_vector(registers.vector(), registers.length());
int subject_length = subject->length();
bool first = true;
for (;;) { // Break on failure, return on exception.
RegExpImpl::IrregexpResult result =
......@@ -3337,9 +3341,15 @@ static RegExpImpl::IrregexpResult SearchRegExpNoCaptureMultiple(
}
match_end = register_vector[1];
HandleScope loop_scope(isolate);
builder->Add(*isolate->factory()->NewSubString(subject,
match_start,
match_end));
if (!first) {
builder->Add(*isolate->factory()->NewStrictSubString(subject,
match_start,
match_end));
} else {
builder->Add(*isolate->factory()->NewSubString(subject,
match_start,
match_end));
}
if (match_start != match_end) {
pos = match_end;
} else {
......@@ -3352,6 +3362,7 @@ static RegExpImpl::IrregexpResult SearchRegExpNoCaptureMultiple(
ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION);
return result;
}
first = false;
}
if (match_start >= 0) {
......@@ -3403,7 +3414,7 @@ static RegExpImpl::IrregexpResult SearchRegExpMultiple(
// at the end, so we have two vectors that we swap between.
OffsetsVector registers2(required_registers);
Vector<int> prev_register_vector(registers2.vector(), registers2.length());
bool first = true;
do {
int match_start = register_vector[0];
builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
......@@ -3421,18 +3432,30 @@ static RegExpImpl::IrregexpResult SearchRegExpMultiple(
// subject, i.e., 3 + capture count in total.
Handle<FixedArray> elements =
isolate->factory()->NewFixedArray(3 + capture_count);
Handle<String> match = isolate->factory()->NewSubString(subject,
match_start,
match_end);
Handle<String> match;
if (!first) {
match = isolate->factory()->NewStrictSubString(subject,
match_start,
match_end);
} else {
match = isolate->factory()->NewSubString(subject,
match_start,
match_end);
}
elements->set(0, *match);
for (int i = 1; i <= capture_count; i++) {
int start = register_vector[i * 2];
if (start >= 0) {
int end = register_vector[i * 2 + 1];
ASSERT(start <= end);
Handle<String> substring = isolate->factory()->NewSubString(subject,
start,
end);
Handle<String> substring;
if (!first) {
substring = isolate->factory()->NewStrictSubString(subject,
start,
end);
} else {
substring = isolate->factory()->NewSubString(subject, start, end);
}
elements->set(i, *substring);
} else {
ASSERT(register_vector[i * 2 + 1] < 0);
......@@ -3462,6 +3485,7 @@ static RegExpImpl::IrregexpResult SearchRegExpMultiple(
subject,
pos,
register_vector);
first = false;
} while (result == RegExpImpl::RE_SUCCESS);
if (result != RegExpImpl::RE_EXCEPTION) {
......@@ -5830,7 +5854,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) {
HandleScope local_loop_handle;
int part_end = indices.at(i);
Handle<String> substring =
isolate->factory()->NewSubString(subject, part_start, part_end);
isolate->factory()->NewStrictSubString(subject, part_start, part_end);
elements->set(i, *substring);
part_start = part_end + pattern_length;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment