Optimized String.prototype.match.
Improved the stack information in profiles.
Fixed bug in ARM port making it possible to compile the runtime system for thumb mode again.
Implemented a number of optimizations in the code generator.
Fixed a number of memory leaks in tests.
Fixed crash bug in connection with script source code and external strings.
git-svn-id: http://v8.googlecode.com/svn/trunk@1642 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/runtime.cc b/src/runtime.cc
index 38db689..5962b2a 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -1038,7 +1038,9 @@
CONVERT_CHECKED(Smi, index, args[2]);
CONVERT_CHECKED(JSArray, raw_last_match_info, args[3]);
Handle<JSArray> last_match_info(raw_last_match_info);
- CHECK(last_match_info->HasFastElements());
+ RUNTIME_ASSERT(last_match_info->HasFastElements());
+ RUNTIME_ASSERT(index->value() >= 0);
+ RUNTIME_ASSERT(index->value() <= subject->length());
Handle<Object> result = RegExpImpl::Exec(regexp,
subject,
index->value(),
@@ -1048,23 +1050,6 @@
}
-static Object* Runtime_RegExpExecGlobal(Arguments args) {
- HandleScope scope;
- ASSERT(args.length() == 3);
- CONVERT_CHECKED(JSRegExp, raw_regexp, args[0]);
- Handle<JSRegExp> regexp(raw_regexp);
- CONVERT_CHECKED(String, raw_subject, args[1]);
- Handle<String> subject(raw_subject);
- CONVERT_CHECKED(JSArray, raw_last_match_info, args[2]);
- Handle<JSArray> last_match_info(raw_last_match_info);
- CHECK(last_match_info->HasFastElements());
- Handle<Object> result =
- RegExpImpl::ExecGlobal(regexp, subject, last_match_info);
- if (result.is_null()) return Failure::Exception();
- return *result;
-}
-
-
static Object* Runtime_MaterializeRegExpLiteral(Arguments args) {
HandleScope scope;
ASSERT(args.length() == 4);
@@ -2337,6 +2322,57 @@
}
+static Object* Runtime_StringMatch(Arguments args) {
+ ASSERT_EQ(3, args.length());
+
+ CONVERT_ARG_CHECKED(String, subject, 0);
+ CONVERT_ARG_CHECKED(JSRegExp, regexp, 1);
+ CONVERT_ARG_CHECKED(JSArray, regexp_info, 2);
+ HandleScope handles;
+
+ Handle<Object> match = RegExpImpl::Exec(regexp, subject, 0, regexp_info);
+
+ if (match.is_null()) {
+ return Failure::Exception();
+ }
+ if (match->IsNull()) {
+ return Heap::null_value();
+ }
+ int length = subject->length();
+
+ ZoneScope zone_space(DELETE_ON_EXIT);
+ ZoneList<int> offsets(8);
+ do {
+ int start;
+ int end;
+ {
+ AssertNoAllocation no_alloc;
+ FixedArray* elements = regexp_info->elements();
+ start = Smi::cast(elements->get(RegExpImpl::kFirstCapture))->value();
+ end = Smi::cast(elements->get(RegExpImpl::kFirstCapture + 1))->value();
+ }
+ 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 (match.is_null()) {
+ return Failure::Exception();
+ }
+ } while (!match->IsNull());
+ int matches = offsets.length() / 2;
+ Handle<FixedArray> elements = Factory::NewFixedArray(matches);
+ for (int i = 0; i < matches ; i++) {
+ int from = offsets.at(i * 2);
+ int to = offsets.at(i * 2 + 1);
+ elements->set(i, *Factory::NewStringSlice(subject, from, to));
+ }
+ Handle<JSArray> result = Factory::NewJSArrayWithElements(elements);
+ result->set_length(Smi::FromInt(matches));
+ return *result;
+}
+
+
static Object* Runtime_NumberToRadixString(Arguments args) {
NoHandleAllocation ha;
ASSERT(args.length() == 2);
@@ -6473,6 +6509,22 @@
}
+// If an object given is an external string, check that the underlying
+// resource is accessible. For other kinds of objects, always return true.
+static bool IsExternalStringValid(Object* str) {
+ if (!str->IsString() || !StringShape(String::cast(str)).IsExternal()) {
+ return true;
+ }
+ if (StringShape(String::cast(str)).IsAsciiRepresentation()) {
+ return ExternalAsciiString::cast(str)->resource() != 0;
+ } else if (StringShape(String::cast(str)).IsTwoByteRepresentation()) {
+ return ExternalTwoByteString::cast(str)->resource() != 0;
+ } else {
+ return true;
+ }
+}
+
+
// Helper function used by Runtime_DebugGetLoadedScripts below.
static int DebugGetLoadedScripts(FixedArray* instances, int instances_size) {
NoHandleAllocation ha;
@@ -6484,7 +6536,7 @@
while (iterator.has_next()) {
HeapObject* obj = iterator.next();
ASSERT(obj != NULL);
- if (obj->IsScript()) {
+ if (obj->IsScript() && IsExternalStringValid(Script::cast(obj)->source())) {
if (instances != NULL && count < instances_size) {
instances->set(count, obj);
}