| Index: runtime/lib/regexp_jsc.cc
|
| ===================================================================
|
| --- runtime/lib/regexp_jsc.cc (revision 44981)
|
| +++ runtime/lib/regexp_jsc.cc (working copy)
|
| @@ -1,172 +0,0 @@
|
| -// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
| -// for details. All rights reserved. Use of this source code is governed by a
|
| -// BSD-style license that can be found in the LICENSE file.
|
| -// This file encapsulates all the interaction with the
|
| -// JSC regular expression library also referred to as pcre
|
| -
|
| -#include "lib/regexp_jsc.h"
|
| -
|
| -#include "platform/assert.h"
|
| -#include "vm/allocation.h"
|
| -#include "vm/exceptions.h"
|
| -#include "vm/globals.h"
|
| -#include "vm/isolate.h"
|
| -#include "third_party/jscre/pcre.h"
|
| -
|
| -namespace dart {
|
| -
|
| -static uint16_t* GetTwoByteData(const String& str) {
|
| - Zone* zone = Isolate::Current()->current_zone();
|
| - uint16_t* two_byte_str = zone->Alloc<uint16_t>(str.Length());
|
| - for (intptr_t i = 0; i < str.Length(); i++) {
|
| - two_byte_str[i] = str.CharAt(i);
|
| - }
|
| - return two_byte_str;
|
| -}
|
| -
|
| -
|
| -static void* JSREMalloc(size_t size) {
|
| - intptr_t regexp_size = static_cast<intptr_t>(size);
|
| - ASSERT(regexp_size > 0);
|
| - const JSRegExp& new_regex = JSRegExp::Handle(JSRegExp::New(size));
|
| - return new_regex.GetDataStartAddress();
|
| -}
|
| -
|
| -
|
| -static void JSREFree(void* ptr) {
|
| - USE(ptr); // Do nothing, memory is garbage collected.
|
| -}
|
| -
|
| -
|
| -static void ThrowExceptionOnError(const String& pattern,
|
| - const char* error_msg) {
|
| - if (error_msg == NULL) {
|
| - error_msg = "Unknown regexp compile error. ";
|
| - }
|
| - const String& errmsg = String::Handle(String::New(error_msg));
|
| - const String& message = String::Handle(String::Concat(errmsg, pattern));
|
| - const Array& args = Array::Handle(Array::New(1));
|
| - args.SetAt(0, message);
|
| - Exceptions::ThrowByType(Exceptions::kFormat, args);
|
| -}
|
| -
|
| -
|
| -RawJSRegExp* Jscre::Compile(const String& pattern,
|
| - bool multi_line,
|
| - bool ignore_case) {
|
| - // First convert the pattern to UTF16 format as the jscre library expects
|
| - // strings to be in UTF16 encoding.
|
| - uint16_t* two_byte_pattern = GetTwoByteData(pattern);
|
| -
|
| - // A Dart regexp is always global.
|
| - bool is_global = true;
|
| - // Parse the flags.
|
| - jscre::JSRegExpIgnoreCaseOption jscre_ignore_case = ignore_case ?
|
| - jscre::JSRegExpIgnoreCase : jscre::JSRegExpDoNotIgnoreCase;
|
| - jscre::JSRegExpMultilineOption jscre_multi_line = multi_line ?
|
| - jscre::JSRegExpMultiline : jscre::JSRegExpSingleLine;
|
| -
|
| - // Compile the regex by calling into the jscre library.
|
| - uint32_t num_bracket_expressions = 0;
|
| - const char* error_msg = NULL;
|
| - jscre::JSRegExp* jscregexp = jscre::jsRegExpCompile(two_byte_pattern,
|
| - pattern.Length(),
|
| - jscre_ignore_case,
|
| - jscre_multi_line,
|
| - &num_bracket_expressions,
|
| - &error_msg,
|
| - &JSREMalloc,
|
| - &JSREFree);
|
| -
|
| - if (jscregexp == NULL) {
|
| - // There was an error compiling the regex, Throw an exception.
|
| - ThrowExceptionOnError(pattern, error_msg);
|
| - UNREACHABLE();
|
| - return JSRegExp::null();
|
| - } else {
|
| - // Setup the compiled regex object and return it.
|
| - JSRegExp& regexp =
|
| - JSRegExp::Handle(JSRegExp::FromDataStartAddress(jscregexp));
|
| - regexp.set_pattern(pattern);
|
| - if (jscre_multi_line == jscre::JSRegExpMultiline) {
|
| - regexp.set_is_multi_line();
|
| - }
|
| - if (jscre_ignore_case == jscre::JSRegExpIgnoreCase) {
|
| - regexp.set_is_ignore_case();
|
| - }
|
| - if (is_global) {
|
| - regexp.set_is_global();
|
| - }
|
| - regexp.set_is_complex(); // Always use jscre library.
|
| - regexp.set_num_bracket_expressions(num_bracket_expressions);
|
| - return regexp.raw();
|
| - }
|
| -}
|
| -
|
| -
|
| -RawArray* Jscre::Execute(const JSRegExp& regex,
|
| - const String& str,
|
| - intptr_t start_index) {
|
| - // First convert the input str to UTF16 format as the jscre library expects
|
| - // strings to be in UTF16 encoding.
|
| - uint16_t* two_byte_str = GetTwoByteData(str);
|
| -
|
| - // Execute a regex match by calling into the jscre library.
|
| - jscre::JSRegExp* jscregexp =
|
| - reinterpret_cast<jscre::JSRegExp*>(regex.GetDataStartAddress());
|
| - ASSERT(jscregexp != NULL);
|
| - const Smi& num_bracket_exprs = Smi::Handle(regex.num_bracket_expressions());
|
| - intptr_t num_bracket_expressions = num_bracket_exprs.Value();
|
| - Zone* zone = Isolate::Current()->current_zone();
|
| - // The jscre library rounds the passed in size to a multiple of 3 in order
|
| - // to reuse the passed in offsets array as a temporary chunk of working
|
| - // storage during matching, so we just pass in a size which is a multiple
|
| - // of 3.
|
| - const int kJscreMultiple = 3;
|
| - int offsets_length = (num_bracket_expressions + 1) * kJscreMultiple;
|
| - int* offsets = NULL;
|
| - offsets = zone->Alloc<int>(offsets_length);
|
| - int retval = jscre::jsRegExpExecute(jscregexp,
|
| - two_byte_str,
|
| - str.Length(),
|
| - start_index,
|
| - offsets,
|
| - offsets_length);
|
| -
|
| - // The KJS JavaScript engine returns null (ie, a failed match) when
|
| - // JSRE's internal match limit is exceeded. We duplicate that behavior here.
|
| - if (retval == jscre::JSRegExpErrorNoMatch
|
| - || retval == jscre::JSRegExpErrorHitLimit) {
|
| - return Array::null();
|
| - }
|
| -
|
| - // Other JSRE errors:
|
| - if (retval < 0) {
|
| - const String& pattern = String::Handle(regex.pattern());
|
| - const int kErrorLength = 256;
|
| - char error_msg[kErrorLength];
|
| - OS::SNPrint(error_msg, kErrorLength,
|
| - "jscre::jsRegExpExecute error : %d", retval);
|
| - ThrowExceptionOnError(pattern, error_msg);
|
| - UNREACHABLE();
|
| - return Array::null();
|
| - }
|
| -
|
| - const int kMatchPair = 2;
|
| - Array& array =
|
| - Array::Handle(Array::New(kMatchPair * (num_bracket_expressions + 1)));
|
| - // The matches come in (start, end + 1) pairs for each bracketted expression.
|
| - Smi& start = Smi::Handle();
|
| - Smi& end = Smi::Handle();
|
| - for (intptr_t i = 0;
|
| - i < (kMatchPair * (num_bracket_expressions + 1));
|
| - i += kMatchPair) {
|
| - start = Smi::New(offsets[i]);
|
| - end = Smi::New(offsets[i + 1]);
|
| - array.SetAt(i, start);
|
| - array.SetAt(i+1, end);
|
| - }
|
| - return array.raw();
|
| -}
|
| -
|
| -} // namespace dart
|
|
|