Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1541)

Unified Diff: Source/core/platform/text/RegularExpression.cpp

Issue 13896017: Switch RegularExpression from YARR to V8 (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/platform/text/RegularExpression.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/platform/text/RegularExpression.cpp
diff --git a/Source/core/platform/text/RegularExpression.cpp b/Source/core/platform/text/RegularExpression.cpp
index 2b225ade22404e6a9f0898590695203021b4a10e..59b15f6a187d03086eb252253a7e8a7be0511c92 100644
--- a/Source/core/platform/text/RegularExpression.cpp
+++ b/Source/core/platform/text/RegularExpression.cpp
@@ -28,67 +28,70 @@
#include "config.h"
#include "RegularExpression.h"
-#include <wtf/BumpPointerAllocator.h>
-#include <yarr/Yarr.h>
-#include "Logging.h"
+// FIXME: These seem like a layering violation, but converting the strings manually
+// without v8String is difficult, and calling into v8 without V8RecursionScope will
+// assert. Perhaps v8 basic utilities shouldn't be in bindings, or we should put
+// RegularExpression as some kind of abstract interface that's implemented in bindings.
+#include "V8Binding.h"
+#include "V8RecursionScope.h"
namespace WebCore {
-RegularExpression::RegularExpression(const String& pattern, TextCaseSensitivity caseSensitivity, MultilineMode multilineMode)
- : m_numSubpatterns(0)
- , m_regExpByteCode(compile(pattern, caseSensitivity, multilineMode))
+static v8::Handle<v8::Context> regexContext()
abarth-chromium 2013/04/21 22:31:52 This copies a persistent handle, which is a patter
esprehn 2013/04/21 23:11:10 So I can do return v8::Local<v8::Context>::New(sta
abarth-chromium 2013/04/21 23:57:00 Yep.
{
+ static ScopedPersistent<v8::Context>* staticRegexContext = new ScopedPersistent<v8::Context>(v8::Context::New());
adamk 2013/04/22 16:40:38 I think an ASSERT(isMainThread()) would be good at
+ return staticRegexContext->get();
}
-PassOwnPtr<JSC::Yarr::BytecodePattern> RegularExpression::compile(const String& patternString, TextCaseSensitivity caseSensitivity, MultilineMode multilineMode)
+RegularExpression::RegularExpression(const String& pattern, TextCaseSensitivity caseSensitivity, MultilineMode multilineMode)
{
- const char* constructionError = 0;
- JSC::Yarr::YarrPattern pattern(patternString, (caseSensitivity == TextCaseInsensitive), (multilineMode == MultilineEnabled), &constructionError);
- if (constructionError) {
- LOG_ERROR("RegularExpression: YARR compile failed with '%s'", constructionError);
- return nullptr;
- }
-
- m_numSubpatterns = pattern.m_numSubpatterns;
-
- return JSC::Yarr::byteCompile(pattern, &m_regexAllocator);
+ v8::HandleScope handleScope;
+ v8::Handle<v8::Context> context(regexContext());
+ v8::Context::Scope scope(context);
abarth-chromium 2013/04/21 22:31:52 It looks like regexContext() should return a new L
+
+ unsigned flags = v8::RegExp::kNone;
abarth-chromium 2013/04/21 22:31:52 Can we declare flags to be of type v8::RegExp::Fla
esprehn 2013/04/21 23:11:10 Nope, the compiler won't let you do |= if you do t
abarth-chromium 2013/04/21 23:57:00 Ok.
+ if (caseSensitivity == TextCaseInsensitive)
+ flags |= v8::RegExp::kIgnoreCase;
+ if (multilineMode == MultilineEnabled)
+ flags |= v8::RegExp::kMultiline;
+
+ v8::TryCatch tryCatch;
abarth-chromium 2013/04/21 22:31:52 Do we need to check anything about this object at
esprehn 2013/04/21 23:11:10 I don't think so, but adamk would know more. I sup
+ m_regex.set(v8::RegExp::New(v8String(pattern, context->GetIsolate()), static_cast<v8::RegExp::Flags>(flags)));
}
-int RegularExpression::match(const String& str, int startFrom, int* matchLength) const
+int RegularExpression::match(const String& string, int startFrom, int* matchLength) const
{
- if (!m_regExpByteCode)
+ if (m_regex.isEmpty() || string.isNull())
return -1;
- if (str.isNull())
+ // v8 strings are limited to int.
+ if (string.length() > INT_MAX)
return -1;
- int offsetVectorSize = (m_numSubpatterns + 1) * 2;
- unsigned* offsetVector;
- Vector<unsigned, 32> nonReturnedOvector;
+ v8::HandleScope handleScope;
+ v8::Handle<v8::Context> context(regexContext());
+ v8::Context::Scope scope(context);
+ v8::TryCatch tryCatch;
- nonReturnedOvector.resize(offsetVectorSize);
- offsetVector = nonReturnedOvector.data();
+ V8RecursionScope::MicrotaskSuppression microtaskScope;
- ASSERT(offsetVector);
- for (unsigned j = 0, i = 0; i < m_numSubpatterns + 1; j += 2, i++)
- offsetVector[j] = JSC::Yarr::offsetNoMatch;
+ v8::Local<v8::Function> exec = m_regex->Get(v8::String::NewSymbol("exec")).As<v8::Function>();
abarth-chromium 2013/04/21 22:31:52 Does this ASSERT if we don't get a v8::Function ou
esprehn 2013/04/21 23:11:10 It does with V8_ENABLE_CHECKS enabled which could
abarth-chromium 2013/04/21 23:57:00 As long as it ASSERTs with V8_ENABLE_CHECKS, I thi
- unsigned result;
- if (str.length() <= INT_MAX)
- result = JSC::Yarr::interpret(m_regExpByteCode.get(), str, startFrom, offsetVector);
- else {
- // This code can't handle unsigned offsets. Limit our processing to strings with offsets that
- // can be represented as ints.
- result = JSC::Yarr::offsetNoMatch;
- }
+ v8::Handle<v8::Value> argv[] = { v8String(string, context->GetIsolate()) };
+ v8::Local<v8::Value> returnValue = exec->Call(m_regex.get(), 1, argv);
- if (result == JSC::Yarr::offsetNoMatch)
+ if (!returnValue->IsObject())
return -1;
- // 1 means 1 match; 0 means more than one match. First match is recorded in offsetVector.
- if (matchLength)
- *matchLength = offsetVector[1] - offsetVector[0];
- return offsetVector[0];
+ v8::Local<v8::Object> result = returnValue.As<v8::Object>();
+ double index = result->Get(v8::String::NewSymbol("index")).As<v8::Number>()->Value();
adamk 2013/04/22 16:40:38 Note that the V8 API exposes some more int-like ty
+
+ if (matchLength) {
+ v8::Local<v8::String> match = result->Get(0).As<v8::String>();
adamk 2013/04/22 16:40:38 To someone not familiar with the JS RegExp API, th
+ *matchLength = match->Length();
+ }
+
+ return static_cast<int>(index);
}
void replace(String& string, const RegularExpression& target, const String& replacement)
« no previous file with comments | « Source/core/platform/text/RegularExpression.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698