Author: [EMAIL PROTECTED]
Date: Thu Oct 2 08:35:28 2008
New Revision: 413
Added:
branches/bleeding_edge/test/mjsunit/regexp-indexof.js
Modified:
branches/bleeding_edge/src/jsregexp.cc
branches/bleeding_edge/src/jsregexp.h
branches/bleeding_edge/src/log.cc
branches/bleeding_edge/src/objects-debug.cc
branches/bleeding_edge/src/objects.h
branches/bleeding_edge/src/runtime.cc
branches/bleeding_edge/src/runtime.h
branches/bleeding_edge/src/unicode.cc
branches/bleeding_edge/src/unicode.h
Log:
- Case-sensitive atomic regular expressions now use the same code as
String.indexOf to do matching.
- The --log option is no longer automatically enabled by the other log
options.
Modified: branches/bleeding_edge/src/jsregexp.cc
==============================================================================
--- branches/bleeding_edge/src/jsregexp.cc (original)
+++ branches/bleeding_edge/src/jsregexp.cc Thu Oct 2 08:35:28 2008
@@ -32,6 +32,7 @@
#include "jsregexp.h"
#include "third_party/jscre/pcre.h"
#include "platform.h"
+#include "runtime.h"
#include "top.h"
namespace v8 { namespace internal {
@@ -142,6 +143,117 @@
}
+unibrow::Predicate<unibrow::RegExpSpecialChar, 128>
is_reg_exp_special_char;
+
+
+Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
+ Handle<String> pattern,
+ Handle<String> flags) {
+ bool is_atom = true;
+ for (int i = 0; is_atom && i < flags->length(); i++) {
+ if (flags->Get(i) == 'i')
+ is_atom = false;
+ }
+ for (int i = 0; is_atom && i < pattern->length(); i++) {
+ if (is_reg_exp_special_char.get(pattern->Get(i)))
+ is_atom = false;
+ }
+ Handle<Object> result;
+ if (is_atom) {
+ result = AtomCompile(re, pattern);
+ } else {
+ result = JsreCompile(re, pattern, flags);
+ }
+
+ LOG(RegExpCompileEvent(re));
+ return result;
+}
+
+
+Handle<Object> RegExpImpl::Exec(Handle<JSRegExp> regexp,
+ Handle<String> subject,
+ Handle<Object> index) {
+ switch (regexp->type_tag()) {
+ case JSRegExp::JSCRE:
+ return JsreExec(regexp, subject, index);
+ case JSRegExp::ATOM:
+ return AtomExec(regexp, subject, index);
+ default:
+ UNREACHABLE();
+ return Handle<Object>();
+ }
+}
+
+
+Handle<Object> RegExpImpl::ExecGlobal(Handle<JSRegExp> regexp,
+ Handle<String> subject) {
+ switch (regexp->type_tag()) {
+ case JSRegExp::JSCRE:
+ return JsreExecGlobal(regexp, subject);
+ case JSRegExp::ATOM:
+ return AtomExecGlobal(regexp, subject);
+ default:
+ UNREACHABLE();
+ return Handle<Object>();
+ }
+}
+
+
+Handle<Object> RegExpImpl::AtomCompile(Handle<JSRegExp> re,
+ Handle<String> pattern) {
+ re->set_type_tag(JSRegExp::ATOM);
+ re->set_data(*pattern);
+ return re;
+}
+
+
+Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re,
+ Handle<String> subject,
+ Handle<Object> index) {
+ Handle<String> needle(String::cast(re->data()));
+
+ uint32_t start_index;
+ if (!Array::IndexFromObject(*index, &start_index)) {
+ return Handle<Smi>(Smi::FromInt(-1));
+ }
+
+ LOG(RegExpExecEvent(re, start_index, subject));
+ int value = Runtime::StringMatchKmp(*subject, *needle, start_index);
+ if (value == -1) return Factory::null_value();
+ Handle<JSArray> result = Factory::NewJSArray(2);
+ SetElement(result, 0, Handle<Smi>(Smi::FromInt(value)));
+ SetElement(result, 1, Handle<Smi>(Smi::FromInt(value +
needle->length())));
+ return result;
+}
+
+
+Handle<Object> RegExpImpl::AtomExecGlobal(Handle<JSRegExp> re,
+ Handle<String> subject) {
+ Handle<String> needle(String::cast(re->data()));
+ Handle<JSArray> result = Factory::NewJSArray(1);
+ bool keep_going = true;
+ int index = 0;
+ int match_count = 0;
+ int needle_length = needle->length();
+ while (keep_going) {
+ LOG(RegExpExecEvent(re, index, subject));
+ int value = Runtime::StringMatchKmp(*subject, *needle, index);
+ if (value == -1) break;
+ HandleScope scope;
+ int end = value + needle_length;
+ Handle<JSArray> pair = Factory::NewJSArray(2);
+ SetElement(pair, 0, Handle<Smi>(Smi::FromInt(value)));
+ SetElement(pair, 1, Handle<Smi>(Smi::FromInt(end)));
+ SetElement(result, match_count, pair);
+ match_count++;
+ index = end;
+ if (needle_length == 0)
+ index++;
+ }
+ return result;
+}
+
+
Handle<Object> RegExpImpl::JsreCompile(Handle<JSRegExp> re,
Handle<String> pattern,
Handle<String> flags) {
@@ -206,8 +318,6 @@
re->set_type_tag(JSRegExp::JSCRE);
re->set_data(*value);
- LOG(RegExpCompileEvent(re));
-
return re;
}
@@ -260,7 +370,6 @@
SetElement(result, i, Handle<Object>(Smi::FromInt(offsets_vector[i])));
SetElement(result, i+1,
Handle<Object>(Smi::FromInt(offsets_vector[i+1])));
}
-
return result;
}
Modified: branches/bleeding_edge/src/jsregexp.h
==============================================================================
--- branches/bleeding_edge/src/jsregexp.h (original)
+++ branches/bleeding_edge/src/jsregexp.h Thu Oct 2 08:35:28 2008
@@ -44,20 +44,41 @@
// This function calls the garbage collector if necessary.
static Handle<String> ToString(Handle<Object> value);
- static Handle<Object> JsreCompile(Handle<JSRegExp> re,
- Handle<String> pattern,
- Handle<String> flags);
+ static Handle<Object> Compile(Handle<JSRegExp> re,
+ Handle<String> pattern,
+ Handle<String> flags);
// Implements RegExp.prototype.exec(string) function.
// See ECMA-262 section 15.10.6.2.
// This function calls the garbage collector if necessary.
- static Handle<Object> JsreExec(Handle<JSRegExp> regexp,
- Handle<String> subject,
- Handle<Object> index);
+ static Handle<Object> Exec(Handle<JSRegExp> regexp,
+ Handle<String> subject,
+ Handle<Object> index);
// Call RegExp.prototyp.exec(string) in a loop.
// Used by String.prototype.match and String.prototype.replace.
// This function calls the garbage collector if necessary.
+ static Handle<Object> ExecGlobal(Handle<JSRegExp> regexp,
+ Handle<String> subject);
+
+ static Handle<Object> AtomCompile(Handle<JSRegExp> re,
+ Handle<String> pattern);
+
+ static Handle<Object> AtomExec(Handle<JSRegExp> regexp,
+ Handle<String> subject,
+ Handle<Object> index);
+
+ static Handle<Object> AtomExecGlobal(Handle<JSRegExp> regexp,
+ Handle<String> subject);
+
+ static Handle<Object> JsreCompile(Handle<JSRegExp> re,
+ Handle<String> pattern,
+ Handle<String> flags);
+
+ static Handle<Object> JsreExec(Handle<JSRegExp> regexp,
+ Handle<String> subject,
+ Handle<Object> index);
+
static Handle<Object> JsreExecGlobal(Handle<JSRegExp> regexp,
Handle<String> subject);
Modified: branches/bleeding_edge/src/log.cc
==============================================================================
--- branches/bleeding_edge/src/log.cc (original)
+++ branches/bleeding_edge/src/log.cc Thu Oct 2 08:35:28 2008
@@ -258,7 +258,7 @@
void Logger::Preamble(const char* content) {
#ifdef ENABLE_LOGGING_AND_PROFILING
- if (logfile_ == NULL) return;
+ if (logfile_ == NULL || !FLAG_log) return;
ScopedLock sl(mutex_);
fprintf(logfile_, "%s", content);
#endif
@@ -267,7 +267,7 @@
void Logger::StringEvent(const char* name, const char* value) {
#ifdef ENABLE_LOGGING_AND_PROFILING
- if (logfile_ == NULL) return;
+ if (logfile_ == NULL || !FLAG_log) return;
ScopedLock sl(mutex_);
fprintf(logfile_, "%s,\"%s\"\n", name, value);
#endif
@@ -276,7 +276,7 @@
void Logger::IntEvent(const char* name, int value) {
#ifdef ENABLE_LOGGING_AND_PROFILING
- if (logfile_ == NULL) return;
+ if (logfile_ == NULL || !FLAG_log) return;
ScopedLock sl(mutex_);
fprintf(logfile_, "%s,%d\n", name, value);
#endif
@@ -360,6 +360,15 @@
Handle<String> source_string = Handle<String>::cast(source);
SmartPointer<uc16> cstring = source_string->ToWideCString();
+ if (regexp->type()->IsSmi()) {
+ switch (regexp->type_tag()) {
+ case JSRegExp::ATOM:
+ fprintf(logfile_, "a");
+ break;
+ default:
+ break;
+ }
+ }
fprintf(logfile_, "/");
for (int i = 0, n = source_string->length(); i < n; i++) {
uc16 c = cstring[i];
@@ -475,7 +484,7 @@
void Logger::NewEvent(const char* name, void* object, size_t size) {
#ifdef ENABLE_LOGGING_AND_PROFILING
- if (logfile_ == NULL) return;
+ if (logfile_ == NULL || !FLAG_log) return;
ScopedLock sl(mutex_);
fprintf(logfile_, "new,%s,0x%x,%u\n", name,
reinterpret_cast<unsigned int>(object),
@@ -486,7 +495,7 @@
void Logger::DeleteEvent(const char* name, void* object) {
#ifdef ENABLE_LOGGING_AND_PROFILING
- if (logfile_ == NULL) return;
+ if (logfile_ == NULL || !FLAG_log) return;
ScopedLock sl(mutex_);
fprintf(logfile_, "delete,%s,0x%x\n", name,
reinterpret_cast<unsigned int>(object));
@@ -559,7 +568,7 @@
void Logger::ResourceEvent(const char* name, const char* tag) {
#ifdef ENABLE_LOGGING_AND_PROFILING
- if (logfile_ == NULL) return;
+ if (logfile_ == NULL || !FLAG_log) return;
ScopedLock sl(mutex_);
fprintf(logfile_, "%s,%s,", name, tag);
@@ -616,7 +625,7 @@
void Logger::DebugTag(const char* call_site_tag) {
#ifdef ENABLE_LOGGING_AND_PROFILING
- if (logfile_ == NULL) return;
+ if (logfile_ == NULL || !FLAG_log) return;
ScopedLock sl(mutex_);
fprintf(logfile_, "debug-tag,%s\n", call_site_tag);
#endif
@@ -625,7 +634,7 @@
void Logger::DebugEvent(const char* event_type, Vector<uint16_t>
parameter) {
#ifdef ENABLE_LOGGING_AND_PROFILING
- if (logfile_ == NULL) return;
+ if (logfile_ == NULL || !FLAG_log) return;
StringBuilder s(parameter.length() + 1);
for (int i = 0; i < parameter.length(); ++i) {
s.AddCharacter(static_cast<char>(parameter[i]));
@@ -644,7 +653,7 @@
#ifdef ENABLE_LOGGING_AND_PROFILING
void Logger::TickEvent(TickSample* sample, bool overflow) {
- if (logfile_ == NULL) return;
+ if (logfile_ == NULL || !FLAG_log) return;
ScopedLock sl(mutex_);
fprintf(logfile_, "tick,0x%x,0x%x,%d", sample->pc, sample->sp,
static_cast<int>(sample->state));
@@ -669,15 +678,12 @@
// --prof implies --log-code.
if (FLAG_prof) FLAG_log_code = true;
- // Each of the individual log flags implies --log. Check after
- // checking --log-all and --prof in case they set --log-code.
- if (FLAG_log_api || FLAG_log_code || FLAG_log_gc ||
- FLAG_log_handles || FLAG_log_suspect || FLAG_log_regexp) {
- FLAG_log = true;
- }
+ bool open_log_file = FLAG_log || FLAG_log_api || FLAG_log_code
+ || FLAG_log_gc || FLAG_log_handles || FLAG_log_suspect
+ || FLAG_log_regexp;
// If we're logging anything, we need to open the log file.
- if (FLAG_log) {
+ if (open_log_file) {
if (strcmp(FLAG_logfile, "-") == 0) {
logfile_ = stdout;
} else {
Modified: branches/bleeding_edge/src/objects-debug.cc
==============================================================================
--- branches/bleeding_edge/src/objects-debug.cc (original)
+++ branches/bleeding_edge/src/objects-debug.cc Thu Oct 2 08:35:28 2008
@@ -630,7 +630,19 @@
void JSRegExp::JSRegExpVerify() {
JSObjectVerify();
ASSERT(type()->IsSmi() || type()->IsUndefined());
- ASSERT(data()->IsUndefined() || data()->IsFixedArray());
+ if (type()->IsSmi()) {
+ switch (type_tag()) {
+ case JSRegExp::JSCRE:
+ ASSERT(data()->IsFixedArray());
+ break;
+ default:
+ ASSERT_EQ(JSRegExp::ATOM, type_tag());
+ ASSERT(data()->IsString());
+ break;
+ }
+ } else {
+ ASSERT(data()->IsUndefined());
+ }
}
Modified: branches/bleeding_edge/src/objects.h
==============================================================================
--- branches/bleeding_edge/src/objects.h (original)
+++ branches/bleeding_edge/src/objects.h Thu Oct 2 08:35:28 2008
@@ -2813,7 +2813,7 @@
// Regular expressions
class JSRegExp: public JSObject {
public:
- enum Type { JSCRE, INDEX_OF };
+ enum Type { JSCRE, ATOM };
inline Type type_tag();
inline void set_type_tag(Type value);
Modified: branches/bleeding_edge/src/runtime.cc
==============================================================================
--- branches/bleeding_edge/src/runtime.cc (original)
+++ branches/bleeding_edge/src/runtime.cc Thu Oct 2 08:35:28 2008
@@ -251,7 +251,7 @@
Handle<String> pattern(raw_pattern);
CONVERT_CHECKED(String, raw_flags, args[2]);
Handle<String> flags(raw_flags);
- return *RegExpImpl::JsreCompile(re, pattern, flags);
+ return *RegExpImpl::Compile(re, pattern, flags);
}
@@ -704,7 +704,7 @@
Handle<String> subject(raw_subject);
Handle<Object> index(args[2]);
ASSERT(index->IsNumber());
- return *RegExpImpl::JsreExec(regexp, subject, index);
+ return *RegExpImpl::Exec(regexp, subject, index);
}
@@ -715,7 +715,7 @@
Handle<JSRegExp> regexp(raw_regexp);
CONVERT_CHECKED(String, raw_subject, args[1]);
Handle<String> subject(raw_subject);
- return *RegExpImpl::JsreExecGlobal(regexp, subject);
+ return *RegExpImpl::ExecGlobal(regexp, subject);
}
@@ -942,23 +942,15 @@
}
-static Object* Runtime_StringIndexOf(Arguments args) {
- NoHandleAllocation ha;
- ASSERT(args.length() == 3);
-
- CONVERT_CHECKED(String, sub, args[0]);
- CONVERT_CHECKED(String, pat, args[1]);
- Object* index = args[2];
-
+int Runtime::StringMatchKmp(String* sub, String* pat, int start_index) {
sub->TryFlatten();
pat->TryFlatten();
int subject_length = sub->length();
int pattern_length = pat->length();
- uint32_t start_index;
- if (!Array::IndexFromObject(index, &start_index)) return
Smi::FromInt(-1);
- if (pattern_length == 0) return Smi::FromInt(start_index);
+ if (start_index > subject_length) return -1;
+ if (pattern_length == 0) return start_index;
// Searching for one specific character is common. For one
// character patterns the KMP algorithm is guaranteed to slow down
@@ -967,10 +959,10 @@
uint16_t pattern_char = pat->Get(0);
for (int i = start_index; i < subject_length; i++) {
if (sub->Get(i) == pattern_char) {
- return Smi::FromInt(i);
+ return i;
}
}
- return Smi::FromInt(-1);
+ return -1;
}
// For small searches, KMP is not worth the setup overhead.
@@ -983,10 +975,10 @@
for (int j = 1; j < pattern_length; j++) {
if (pat->Get(j) != sub->Get(j + i)) break;
- if (j == pattern_length - 1) return Smi::FromInt(i);
+ if (j == pattern_length - 1) return i;
}
}
- return Smi::FromInt(-1);
+ return -1;
}
// For patterns with a larger length we use the KMP algorithm.
@@ -1010,11 +1002,25 @@
subject_index++;
if (pattern_index >= pattern_length) {
DeleteArray(next_table);
- return Smi::FromInt(subject_index - pattern_index);
+ return subject_index - pattern_index;
}
}
DeleteArray(next_table);
- return Smi::FromInt(-1);
+ return -1;
+}
+
+
+static Object* Runtime_StringIndexOf(Arguments args) {
+ NoHandleAllocation ha;
+ ASSERT(args.length() == 3);
+
+ CONVERT_CHECKED(String, sub, args[0]);
+ CONVERT_CHECKED(String, pat, args[1]);
+ Object* index = args[2];
+ uint32_t start_index;
+ if (!Array::IndexFromObject(index, &start_index)) return
Smi::FromInt(-1);
+
+ return Smi::FromInt(Runtime::StringMatchKmp(sub, pat, start_index));
}
Modified: branches/bleeding_edge/src/runtime.h
==============================================================================
--- branches/bleeding_edge/src/runtime.h (original)
+++ branches/bleeding_edge/src/runtime.h Thu Oct 2 08:35:28 2008
@@ -332,6 +332,8 @@
// Get the runtime function with the given name.
static Function* FunctionForName(const char* name);
+ static int StringMatchKmp(String* sub, String* pat, int index);
+
// TODO(1240886): The following three methods are *not* handle safe,
// but accept handle arguments. This seems fragile.
Modified: branches/bleeding_edge/src/unicode.cc
==============================================================================
--- branches/bleeding_edge/src/unicode.cc (original)
+++ branches/bleeding_edge/src/unicode.cc Thu Oct 2 08:35:28 2008
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
-// This file was generated at 2008-09-08 11:13:45.862026
+// This file was generated at 2008-10-01 18:05:45.480436
#include "unicode-inl.h"
#include <cstdlib>
@@ -659,6 +659,20 @@
}
}
+// RegExpSpecialChar: 'Rx' in point.properties
+
+static const uint16_t kRegExpSpecialCharTable0Size = 9;
+static const uint16_t kRegExpSpecialCharTable0[9] = { 36, 32808, 43, 46,
63, 32859, 94, 32891, 125 }; // NOLINT
+bool RegExpSpecialChar::Is(uchar c) {
+ int chunk_index = c >> 15;
+ switch (chunk_index) {
+ case 0: return LookupPredicate(kRegExpSpecialCharTable0,
+ kRegExpSpecialCharTable0Size,
+ c);
+ default: return false;
+ }
+}
+
// CombiningMark: point.category in ['Mn', 'Mc']
static const uint16_t kCombiningMarkTable0Size = 214;
@@ -796,7 +810,7 @@
uchar UnicodeData::kMaxCodePoint = 1114109;
int UnicodeData::GetByteCount() {
- return 0 + (sizeof(uint16_t) * kUppercaseTable0Size) + (sizeof(uint16_t)
* kUppercaseTable1Size) + (sizeof(uint16_t) * kUppercaseTable2Size) +
(sizeof(uint16_t) * kUppercaseTable3Size) + (sizeof(uint16_t) *
kLowercaseTable0Size) + (sizeof(uint16_t) * kLowercaseTable1Size) +
(sizeof(uint16_t) * kLowercaseTable2Size) + (sizeof(uint16_t) *
kLowercaseTable3Size) + (sizeof(uint16_t) * kLetterTable0Size) +
(sizeof(uint16_t) * kLetterTable1Size) + (sizeof(uint16_t) *
kLetterTable2Size) + (sizeof(uint16_t) * kLetterTable3Size) +
(sizeof(uint16_t) * kLetterTable4Size) + (sizeof(uint16_t) *
kLetterTable5Size) + (sizeof(uint16_t) * kSpaceTable0Size) +
(sizeof(uint16_t) * kTitlecaseTable0Size) + (sizeof(uint16_t) *
kNumberTable0Size) + (sizeof(uint16_t) * kNumberTable1Size) +
(sizeof(uint16_t) * kNumberTable2Size) + (sizeof(uint16_t) *
kNumberTable3Size) + (sizeof(uint16_t) * kDecimalDigitTable0Size) +
(sizeof(uint16_t) * kDecimalDigitTable1Size) + (sizeof(uint16_t) *
kDecimalDigitTable2Size) + (sizeof(uint16_t) * kDecimalDigitTable3Size) +
(sizeof(uint16_t) * kIdeographicTable0Size) + (sizeof(uint16_t) *
kIdeographicTable1Size) + (sizeof(uint16_t) * kIdeographicTable4Size) +
(sizeof(uint16_t) * kIdeographicTable5Size) + (sizeof(uint16_t) *
kWhiteSpaceTable0Size) + (sizeof(uint16_t) * kHexDigitTable0Size) +
(sizeof(uint16_t) * kHexDigitTable1Size) + (sizeof(uint16_t) *
kAsciiHexDigitTable0Size) + (sizeof(uint16_t) * kBidiControlTable0Size) +
(sizeof(uint16_t) * kJoinControlTable0Size) + (sizeof(uint16_t) *
kDashTable0Size) + (sizeof(uint16_t) * kDashTable1Size) + (sizeof(uint16_t)
* kHyphenTable0Size) + (sizeof(uint16_t) * kHyphenTable1Size) +
(sizeof(uint16_t) * kLineTerminatorTable0Size) + (sizeof(uint16_t) *
kCombiningMarkTable0Size) + (sizeof(uint16_t) * kCombiningMarkTable1Size) +
(sizeof(uint16_t) * kCombiningMarkTable2Size) + (sizeof(uint16_t) *
kCombiningMarkTable3Size) + (sizeof(uint16_t) * kCombiningMarkTable28Size)
+ (sizeof(uint16_t) * kConnectorPunctuationTable0Size) + (sizeof(uint16_t)
* kConnectorPunctuationTable1Size) + (sizeof(uint16_t) *
kToLowercaseTable0Size) + (sizeof(uint16_t) * kToLowercaseTable1Size) +
(sizeof(uint16_t) * kToLowercaseTable2Size) + (sizeof(uint16_t) *
kToUppercaseTable0Size) + (sizeof(uint16_t) * kToUppercaseTable1Size) +
(sizeof(uint16_t) * kToUppercaseTable2Size); // NOLINT
+ return 0 + (sizeof(uint16_t) * kUppercaseTable0Size) + (sizeof(uint16_t)
* kUppercaseTable1Size) + (sizeof(uint16_t) * kUppercaseTable2Size) +
(sizeof(uint16_t) * kUppercaseTable3Size) + (sizeof(uint16_t) *
kLowercaseTable0Size) + (sizeof(uint16_t) * kLowercaseTable1Size) +
(sizeof(uint16_t) * kLowercaseTable2Size) + (sizeof(uint16_t) *
kLowercaseTable3Size) + (sizeof(uint16_t) * kLetterTable0Size) +
(sizeof(uint16_t) * kLetterTable1Size) + (sizeof(uint16_t) *
kLetterTable2Size) + (sizeof(uint16_t) * kLetterTable3Size) +
(sizeof(uint16_t) * kLetterTable4Size) + (sizeof(uint16_t) *
kLetterTable5Size) + (sizeof(uint16_t) * kSpaceTable0Size) +
(sizeof(uint16_t) * kTitlecaseTable0Size) + (sizeof(uint16_t) *
kNumberTable0Size) + (sizeof(uint16_t) * kNumberTable1Size) +
(sizeof(uint16_t) * kNumberTable2Size) + (sizeof(uint16_t) *
kNumberTable3Size) + (sizeof(uint16_t) * kDecimalDigitTable0Size) +
(sizeof(uint16_t) * kDecimalDigitTable1Size) + (sizeof(uint16_t) *
kDecimalDigitTable2Size) + (sizeof(uint16_t) * kDecimalDigitTable3Size) +
(sizeof(uint16_t) * kIdeographicTable0Size) + (sizeof(uint16_t) *
kIdeographicTable1Size) + (sizeof(uint16_t) * kIdeographicTable4Size) +
(sizeof(uint16_t) * kIdeographicTable5Size) + (sizeof(uint16_t) *
kWhiteSpaceTable0Size) + (sizeof(uint16_t) * kHexDigitTable0Size) +
(sizeof(uint16_t) * kHexDigitTable1Size) + (sizeof(uint16_t) *
kAsciiHexDigitTable0Size) + (sizeof(uint16_t) * kBidiControlTable0Size) +
(sizeof(uint16_t) * kJoinControlTable0Size) + (sizeof(uint16_t) *
kDashTable0Size) + (sizeof(uint16_t) * kDashTable1Size) + (sizeof(uint16_t)
* kHyphenTable0Size) + (sizeof(uint16_t) * kHyphenTable1Size) +
(sizeof(uint16_t) * kLineTerminatorTable0Size) + (sizeof(uint16_t) *
kRegExpSpecialCharTable0Size) + (sizeof(uint16_t) *
kCombiningMarkTable0Size) + (sizeof(uint16_t) * kCombiningMarkTable1Size) +
(sizeof(uint16_t) * kCombiningMarkTable2Size) + (sizeof(uint16_t) *
kCombiningMarkTable3Size) + (sizeof(uint16_t) * kCombiningMarkTable28Size)
+ (sizeof(uint16_t) * kConnectorPunctuationTable0Size) + (sizeof(uint16_t)
* kConnectorPunctuationTable1Size) + (sizeof(uint16_t) *
kToLowercaseTable0Size) + (sizeof(uint16_t) * kToLowercaseTable1Size) +
(sizeof(uint16_t) * kToLowercaseTable2Size) + (sizeof(uint16_t) *
kToUppercaseTable0Size) + (sizeof(uint16_t) * kToUppercaseTable1Size) +
(sizeof(uint16_t) * kToUppercaseTable2Size); // NOLINT
}
} // namespace unicode
Modified: branches/bleeding_edge/src/unicode.h
==============================================================================
--- branches/bleeding_edge/src/unicode.h (original)
+++ branches/bleeding_edge/src/unicode.h Thu Oct 2 08:35:28 2008
@@ -258,6 +258,9 @@
struct LineTerminator {
static bool Is(uchar c);
};
+struct RegExpSpecialChar {
+ static bool Is(uchar c);
+};
struct CombiningMark {
static bool Is(uchar c);
};
Added: branches/bleeding_edge/test/mjsunit/regexp-indexof.js
==============================================================================
--- (empty file)
+++ branches/bleeding_edge/test/mjsunit/regexp-indexof.js Thu Oct 2
08:35:28 2008
@@ -0,0 +1,60 @@
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+function CheckMatch(re, str, matches) {
+ assertEquals(matches.length > 0, re.test(str));
+ var result = str.match(re);
+ if (matches.length > 0) {
+ assertEquals(matches.length, result.length);
+ for (idx in matches) {
+ var from = matches[idx][0];
+ var length = matches[idx][1];
+ var expected = str.substr(from, length);
+ assertEquals(expected, result[idx]);
+ }
+ assertEquals(expected, RegExp.lastMatch);
+ assertEquals(str.substr(0, from), RegExp.leftContext);
+ assertEquals(str.substr(from + length), RegExp.rightContext);
+ } else {
+ assertTrue(result === null);
+ }
+}
+
+CheckMatch(/abc/, "xxxabcxxxabcxxx", [[3, 3]]);
+CheckMatch(/abc/g, "xxxabcxxxabcxxx", [[3, 3], [9, 3]]);
+CheckMatch(/abc/, "xxxabababcxxxabcxxx", [[7, 3]]);
+CheckMatch(/abc/g, "abcabcabc", [[0, 3], [3, 3], [6, 3]]);
+CheckMatch(/aba/g, "ababababa", [[0, 3], [4, 3]]);
+CheckMatch(/foo/g, "ofooofoooofofooofo", [[1, 3], [5, 3], [12, 3]]);
+CheckMatch(/foobarbaz/, "xx", []);
+CheckMatch(new RegExp(""), "xxx", [[0, 0]]);
+CheckMatch(/abc/, "abababa", []);
+
+assertEquals("xxxdefxxxdefxxx", "xxxabcxxxabcxxx".replace(/abc/g, "def"));
+assertEquals("o-o-oofo-ofo", "ofooofoooofofooofo".replace(/foo/g, "-"));
+assertEquals("deded", "deded".replace(/x/g, "-"));
+assertEquals("-a-b-c-d-e-f-", "abcdef".replace(new RegExp("", "g"), "-"));
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---