| Index: src/jsregexp.cc
|
| ===================================================================
|
| --- src/jsregexp.cc (revision 7267)
|
| +++ src/jsregexp.cc (working copy)
|
| @@ -35,7 +35,6 @@
|
| #include "platform.h"
|
| #include "string-search.h"
|
| #include "runtime.h"
|
| -#include "top.h"
|
| #include "compilation-cache.h"
|
| #include "string-stream.h"
|
| #include "parser.h"
|
| @@ -62,7 +61,6 @@
|
| namespace v8 {
|
| namespace internal {
|
|
|
| -
|
| Handle<Object> RegExpImpl::CreateRegExpLiteral(Handle<JSFunction> constructor,
|
| Handle<String> pattern,
|
| Handle<String> flags,
|
| @@ -97,12 +95,14 @@
|
| Handle<String> pattern,
|
| Handle<String> error_text,
|
| const char* message) {
|
| - Handle<FixedArray> elements = Factory::NewFixedArray(2);
|
| + Isolate* isolate = re->GetIsolate();
|
| + Factory* factory = isolate->factory();
|
| + Handle<FixedArray> elements = factory->NewFixedArray(2);
|
| elements->set(0, *pattern);
|
| elements->set(1, *error_text);
|
| - Handle<JSArray> array = Factory::NewJSArrayWithElements(elements);
|
| - Handle<Object> regexp_err = Factory::NewSyntaxError(message, array);
|
| - Top::Throw(*regexp_err);
|
| + Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
|
| + Handle<Object> regexp_err = factory->NewSyntaxError(message, array);
|
| + isolate->Throw(*regexp_err);
|
| }
|
|
|
|
|
| @@ -112,10 +112,12 @@
|
| Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
|
| Handle<String> pattern,
|
| Handle<String> flag_str) {
|
| + Isolate* isolate = re->GetIsolate();
|
| JSRegExp::Flags flags = RegExpFlagsFromString(flag_str);
|
| - Handle<FixedArray> cached = CompilationCache::LookupRegExp(pattern, flags);
|
| + CompilationCache* compilation_cache = isolate->compilation_cache();
|
| + Handle<FixedArray> cached = compilation_cache->LookupRegExp(pattern, flags);
|
| bool in_cache = !cached.is_null();
|
| - LOG(RegExpCompileEvent(re, in_cache));
|
| + LOG(isolate, RegExpCompileEvent(re, in_cache));
|
|
|
| Handle<Object> result;
|
| if (in_cache) {
|
| @@ -124,9 +126,9 @@
|
| }
|
| pattern = FlattenGetString(pattern);
|
| CompilationZoneScope zone_scope(DELETE_ON_EXIT);
|
| - PostponeInterruptsScope postpone;
|
| + PostponeInterruptsScope postpone(isolate);
|
| RegExpCompileData parse_result;
|
| - FlatStringReader reader(pattern);
|
| + FlatStringReader reader(isolate, pattern);
|
| if (!RegExpParser::ParseRegExp(&reader, flags.is_multiline(),
|
| &parse_result)) {
|
| // Throw an exception if we fail to parse the pattern.
|
| @@ -145,7 +147,8 @@
|
| parse_result.capture_count == 0) {
|
| RegExpAtom* atom = parse_result.tree->AsAtom();
|
| Vector<const uc16> atom_pattern = atom->data();
|
| - Handle<String> atom_string = Factory::NewStringFromTwoByte(atom_pattern);
|
| + Handle<String> atom_string =
|
| + isolate->factory()->NewStringFromTwoByte(atom_pattern);
|
| AtomCompile(re, pattern, flags, atom_string);
|
| } else {
|
| IrregexpInitialize(re, pattern, flags, parse_result.capture_count);
|
| @@ -154,7 +157,7 @@
|
| // Compilation succeeded so the data is set on the regexp
|
| // and we can store it in the cache.
|
| Handle<FixedArray> data(FixedArray::cast(re->data()));
|
| - CompilationCache::PutRegExp(pattern, flags, data);
|
| + compilation_cache->PutRegExp(pattern, flags, data);
|
|
|
| return re;
|
| }
|
| @@ -170,7 +173,7 @@
|
| case JSRegExp::IRREGEXP: {
|
| Handle<Object> result =
|
| IrregexpExec(regexp, subject, index, last_match_info);
|
| - ASSERT(!result.is_null() || Top::has_pending_exception());
|
| + ASSERT(!result.is_null() || Isolate::Current()->has_pending_exception());
|
| return result;
|
| }
|
| default:
|
| @@ -187,11 +190,11 @@
|
| Handle<String> pattern,
|
| JSRegExp::Flags flags,
|
| Handle<String> match_pattern) {
|
| - Factory::SetRegExpAtomData(re,
|
| - JSRegExp::ATOM,
|
| - pattern,
|
| - flags,
|
| - match_pattern);
|
| + re->GetIsolate()->factory()->SetRegExpAtomData(re,
|
| + JSRegExp::ATOM,
|
| + pattern,
|
| + flags,
|
| + match_pattern);
|
| }
|
|
|
|
|
| @@ -224,6 +227,8 @@
|
| Handle<String> subject,
|
| int index,
|
| Handle<JSArray> last_match_info) {
|
| + Isolate* isolate = re->GetIsolate();
|
| +
|
| ASSERT(0 <= index);
|
| ASSERT(index <= subject->length());
|
|
|
| @@ -237,24 +242,30 @@
|
| int needle_len = needle->length();
|
|
|
| if (needle_len != 0) {
|
| - if (index + needle_len > subject->length()) return Factory::null_value();
|
| + if (index + needle_len > subject->length())
|
| + return isolate->factory()->null_value();
|
| +
|
| // dispatch on type of strings
|
| index = (needle->IsAsciiRepresentation()
|
| ? (seq_sub->IsAsciiRepresentation()
|
| - ? SearchString(seq_sub->ToAsciiVector(),
|
| + ? SearchString(isolate,
|
| + seq_sub->ToAsciiVector(),
|
| needle->ToAsciiVector(),
|
| index)
|
| - : SearchString(seq_sub->ToUC16Vector(),
|
| + : SearchString(isolate,
|
| + seq_sub->ToUC16Vector(),
|
| needle->ToAsciiVector(),
|
| index))
|
| : (seq_sub->IsAsciiRepresentation()
|
| - ? SearchString(seq_sub->ToAsciiVector(),
|
| + ? SearchString(isolate,
|
| + seq_sub->ToAsciiVector(),
|
| needle->ToUC16Vector(),
|
| index)
|
| - : SearchString(seq_sub->ToUC16Vector(),
|
| + : SearchString(isolate,
|
| + seq_sub->ToUC16Vector(),
|
| needle->ToUC16Vector(),
|
| index)));
|
| - if (index == -1) return Factory::null_value();
|
| + if (index == -1) return FACTORY->null_value();
|
| }
|
| ASSERT(last_match_info->HasFastElements());
|
|
|
| @@ -288,13 +299,14 @@
|
|
|
| bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re, bool is_ascii) {
|
| // Compile the RegExp.
|
| + Isolate* isolate = re->GetIsolate();
|
| CompilationZoneScope zone_scope(DELETE_ON_EXIT);
|
| - PostponeInterruptsScope postpone;
|
| + PostponeInterruptsScope postpone(isolate);
|
| Object* entry = re->DataAt(JSRegExp::code_index(is_ascii));
|
| if (entry->IsJSObject()) {
|
| // If it's a JSObject, a previous compilation failed and threw this object.
|
| // Re-throw the object without trying again.
|
| - Top::Throw(entry);
|
| + isolate->Throw(entry);
|
| return false;
|
| }
|
| ASSERT(entry->IsTheHole());
|
| @@ -307,7 +319,7 @@
|
| }
|
|
|
| RegExpCompileData compile_data;
|
| - FlatStringReader reader(pattern);
|
| + FlatStringReader reader(isolate, pattern);
|
| if (!RegExpParser::ParseRegExp(&reader, flags.is_multiline(),
|
| &compile_data)) {
|
| // Throw an exception if we fail to parse the pattern.
|
| @@ -326,15 +338,16 @@
|
| is_ascii);
|
| if (result.error_message != NULL) {
|
| // Unable to compile regexp.
|
| - Handle<FixedArray> elements = Factory::NewFixedArray(2);
|
| + Factory* factory = isolate->factory();
|
| + Handle<FixedArray> elements = factory->NewFixedArray(2);
|
| elements->set(0, *pattern);
|
| Handle<String> error_message =
|
| - Factory::NewStringFromUtf8(CStrVector(result.error_message));
|
| + factory->NewStringFromUtf8(CStrVector(result.error_message));
|
| elements->set(1, *error_message);
|
| - Handle<JSArray> array = Factory::NewJSArrayWithElements(elements);
|
| + Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
|
| Handle<Object> regexp_err =
|
| - Factory::NewSyntaxError("malformed_regexp", array);
|
| - Top::Throw(*regexp_err);
|
| + factory->NewSyntaxError("malformed_regexp", array);
|
| + isolate->Throw(*regexp_err);
|
| re->SetDataAt(JSRegExp::code_index(is_ascii), *regexp_err);
|
| return false;
|
| }
|
| @@ -386,11 +399,11 @@
|
| JSRegExp::Flags flags,
|
| int capture_count) {
|
| // Initialize compiled code entries to null.
|
| - Factory::SetRegExpIrregexpData(re,
|
| - JSRegExp::IRREGEXP,
|
| - pattern,
|
| - flags,
|
| - capture_count);
|
| + re->GetIsolate()->factory()->SetRegExpIrregexpData(re,
|
| + JSRegExp::IRREGEXP,
|
| + pattern,
|
| + flags,
|
| + capture_count);
|
| }
|
|
|
|
|
| @@ -428,32 +441,34 @@
|
| Handle<String> subject,
|
| int index,
|
| Vector<int> output) {
|
| - Handle<FixedArray> irregexp(FixedArray::cast(regexp->data()));
|
| + Isolate* isolate = regexp->GetIsolate();
|
|
|
| + Handle<FixedArray> irregexp(FixedArray::cast(regexp->data()), isolate);
|
| +
|
| ASSERT(index >= 0);
|
| ASSERT(index <= subject->length());
|
| ASSERT(subject->IsFlat());
|
|
|
| // A flat ASCII string might have a two-byte first part.
|
| if (subject->IsConsString()) {
|
| - subject = Handle<String>(ConsString::cast(*subject)->first());
|
| + subject = Handle<String>(ConsString::cast(*subject)->first(), isolate);
|
| }
|
|
|
| #ifndef V8_INTERPRETED_REGEXP
|
| - ASSERT(output.length() >=
|
| - (IrregexpNumberOfCaptures(*irregexp) + 1) * 2);
|
| + ASSERT(output.length() >= (IrregexpNumberOfCaptures(*irregexp) + 1) * 2);
|
| do {
|
| bool is_ascii = subject->IsAsciiRepresentation();
|
| - Handle<Code> code(IrregexpNativeCode(*irregexp, is_ascii));
|
| + Handle<Code> code(IrregexpNativeCode(*irregexp, is_ascii), isolate);
|
| NativeRegExpMacroAssembler::Result res =
|
| NativeRegExpMacroAssembler::Match(code,
|
| subject,
|
| output.start(),
|
| output.length(),
|
| - index);
|
| + index,
|
| + isolate);
|
| if (res != NativeRegExpMacroAssembler::RETRY) {
|
| ASSERT(res != NativeRegExpMacroAssembler::EXCEPTION ||
|
| - Top::has_pending_exception());
|
| + isolate->has_pending_exception());
|
| STATIC_ASSERT(
|
| static_cast<int>(NativeRegExpMacroAssembler::SUCCESS) == RE_SUCCESS);
|
| STATIC_ASSERT(
|
| @@ -484,7 +499,7 @@
|
| for (int i = number_of_capture_registers - 1; i >= 0; i--) {
|
| register_vector[i] = -1;
|
| }
|
| - Handle<ByteArray> byte_codes(IrregexpByteCode(*irregexp, is_ascii));
|
| + Handle<ByteArray> byte_codes(IrregexpByteCode(*irregexp, is_ascii), isolate);
|
|
|
| if (IrregexpInterpreter::Match(byte_codes,
|
| subject,
|
| @@ -516,7 +531,7 @@
|
| int required_registers = RegExpImpl::IrregexpPrepare(jsregexp, subject);
|
| if (required_registers < 0) {
|
| // Compiling failed with an exception.
|
| - ASSERT(Top::has_pending_exception());
|
| + ASSERT(Isolate::Current()->has_pending_exception());
|
| return Handle<Object>::null();
|
| }
|
|
|
| @@ -542,11 +557,11 @@
|
| return last_match_info;
|
| }
|
| if (res == RE_EXCEPTION) {
|
| - ASSERT(Top::has_pending_exception());
|
| + ASSERT(Isolate::Current()->has_pending_exception());
|
| return Handle<Object>::null();
|
| }
|
| ASSERT(res == RE_FAILURE);
|
| - return Factory::null_value();
|
| + return Isolate::Current()->factory()->null_value();
|
| }
|
|
|
|
|
| @@ -1306,16 +1321,14 @@
|
| }
|
|
|
|
|
| -static unibrow::Mapping<unibrow::Ecma262UnCanonicalize> uncanonicalize;
|
| -static unibrow::Mapping<unibrow::CanonicalizationRange> canonrange;
|
| -
|
| -
|
| // Returns the number of characters in the equivalence class, omitting those
|
| // that cannot occur in the source string because it is ASCII.
|
| -static int GetCaseIndependentLetters(uc16 character,
|
| +static int GetCaseIndependentLetters(Isolate* isolate,
|
| + uc16 character,
|
| bool ascii_subject,
|
| unibrow::uchar* letters) {
|
| - int length = uncanonicalize.get(character, '\0', letters);
|
| + int length =
|
| + isolate->jsregexp_uncanonicalize()->get(character, '\0', letters);
|
| // Unibrow returns 0 or 1 for characters where case independence is
|
| // trivial.
|
| if (length == 0) {
|
| @@ -1331,7 +1344,8 @@
|
| }
|
|
|
|
|
| -static inline bool EmitSimpleCharacter(RegExpCompiler* compiler,
|
| +static inline bool EmitSimpleCharacter(Isolate* isolate,
|
| + RegExpCompiler* compiler,
|
| uc16 c,
|
| Label* on_failure,
|
| int cp_offset,
|
| @@ -1353,7 +1367,8 @@
|
|
|
| // Only emits non-letters (things that don't have case). Only used for case
|
| // independent matches.
|
| -static inline bool EmitAtomNonLetter(RegExpCompiler* compiler,
|
| +static inline bool EmitAtomNonLetter(Isolate* isolate,
|
| + RegExpCompiler* compiler,
|
| uc16 c,
|
| Label* on_failure,
|
| int cp_offset,
|
| @@ -1362,7 +1377,7 @@
|
| RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
|
| bool ascii = compiler->ascii();
|
| unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth];
|
| - int length = GetCaseIndependentLetters(c, ascii, chars);
|
| + int length = GetCaseIndependentLetters(isolate, c, ascii, chars);
|
| if (length < 1) {
|
| // This can't match. Must be an ASCII subject and a non-ASCII character.
|
| // We do not need to do anything since the ASCII pass already handled this.
|
| @@ -1424,7 +1439,8 @@
|
| }
|
|
|
|
|
| -typedef bool EmitCharacterFunction(RegExpCompiler* compiler,
|
| +typedef bool EmitCharacterFunction(Isolate* isolate,
|
| + RegExpCompiler* compiler,
|
| uc16 c,
|
| Label* on_failure,
|
| int cp_offset,
|
| @@ -1433,7 +1449,8 @@
|
|
|
| // Only emits letters (things that have case). Only used for case independent
|
| // matches.
|
| -static inline bool EmitAtomLetter(RegExpCompiler* compiler,
|
| +static inline bool EmitAtomLetter(Isolate* isolate,
|
| + RegExpCompiler* compiler,
|
| uc16 c,
|
| Label* on_failure,
|
| int cp_offset,
|
| @@ -1442,7 +1459,7 @@
|
| RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
|
| bool ascii = compiler->ascii();
|
| unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth];
|
| - int length = GetCaseIndependentLetters(c, ascii, chars);
|
| + int length = GetCaseIndependentLetters(isolate, c, ascii, chars);
|
| if (length <= 1) return false;
|
| // We may not need to check against the end of the input string
|
| // if this character lies before a character that matched.
|
| @@ -1880,6 +1897,7 @@
|
| RegExpCompiler* compiler,
|
| int characters_filled_in,
|
| bool not_at_start) {
|
| + Isolate* isolate = Isolate::Current();
|
| ASSERT(characters_filled_in < details->characters());
|
| int characters = details->characters();
|
| int char_mask;
|
| @@ -1910,7 +1928,8 @@
|
| }
|
| if (compiler->ignore_case()) {
|
| unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth];
|
| - int length = GetCaseIndependentLetters(c, compiler->ascii(), chars);
|
| + int length = GetCaseIndependentLetters(isolate, c, compiler->ascii(),
|
| + chars);
|
| ASSERT(length != 0); // Can only happen if c > char_mask (see above).
|
| if (length == 1) {
|
| // This letter has no case equivalents, so it's nice and simple
|
| @@ -2410,6 +2429,7 @@
|
| Trace* trace,
|
| bool first_element_checked,
|
| int* checked_up_to) {
|
| + Isolate* isolate = Isolate::Current();
|
| RegExpMacroAssembler* assembler = compiler->macro_assembler();
|
| bool ascii = compiler->ascii();
|
| Label* backtrack = trace->backtrack();
|
| @@ -2445,7 +2465,8 @@
|
| break;
|
| }
|
| if (emit_function != NULL) {
|
| - bool bound_checked = emit_function(compiler,
|
| + bool bound_checked = emit_function(isolate,
|
| + compiler,
|
| quarks[j],
|
| backtrack,
|
| cp_offset + j,
|
| @@ -4085,13 +4106,15 @@
|
| }
|
|
|
|
|
| -static void AddUncanonicals(ZoneList<CharacterRange>* ranges,
|
| +static void AddUncanonicals(Isolate* isolate,
|
| + ZoneList<CharacterRange>* ranges,
|
| int bottom,
|
| int top);
|
|
|
|
|
| void CharacterRange::AddCaseEquivalents(ZoneList<CharacterRange>* ranges,
|
| bool is_ascii) {
|
| + Isolate* isolate = Isolate::Current();
|
| uc16 bottom = from();
|
| uc16 top = to();
|
| if (is_ascii) {
|
| @@ -4101,7 +4124,7 @@
|
| unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth];
|
| if (top == bottom) {
|
| // If this is a singleton we just expand the one character.
|
| - int length = uncanonicalize.get(bottom, '\0', chars);
|
| + int length = isolate->jsregexp_uncanonicalize()->get(bottom, '\0', chars);
|
| for (int i = 0; i < length; i++) {
|
| uc32 chr = chars[i];
|
| if (chr != bottom) {
|
| @@ -4130,7 +4153,7 @@
|
| unibrow::uchar range[unibrow::Ecma262UnCanonicalize::kMaxWidth];
|
| int pos = bottom;
|
| while (pos < top) {
|
| - int length = canonrange.get(pos, '\0', range);
|
| + int length = isolate->jsregexp_canonrange()->get(pos, '\0', range);
|
| uc16 block_end;
|
| if (length == 0) {
|
| block_end = pos;
|
| @@ -4139,7 +4162,7 @@
|
| block_end = range[0];
|
| }
|
| int end = (block_end > top) ? top : block_end;
|
| - length = uncanonicalize.get(block_end, '\0', range);
|
| + length = isolate->jsregexp_uncanonicalize()->get(block_end, '\0', range);
|
| for (int i = 0; i < length; i++) {
|
| uc32 c = range[i];
|
| uc16 range_from = c - (block_end - pos);
|
| @@ -4249,7 +4272,8 @@
|
| }
|
|
|
|
|
| -static void AddUncanonicals(ZoneList<CharacterRange>* ranges,
|
| +static void AddUncanonicals(Isolate* isolate,
|
| + ZoneList<CharacterRange>* ranges,
|
| int bottom,
|
| int top) {
|
| unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth];
|
| @@ -4281,8 +4305,8 @@
|
| // case mappings.
|
| for (int i = 0; i < boundary_count; i++) {
|
| if (bottom < boundaries[i] && top >= boundaries[i]) {
|
| - AddUncanonicals(ranges, bottom, boundaries[i] - 1);
|
| - AddUncanonicals(ranges, boundaries[i], top);
|
| + AddUncanonicals(isolate, ranges, bottom, boundaries[i] - 1);
|
| + AddUncanonicals(isolate, ranges, boundaries[i], top);
|
| return;
|
| }
|
| }
|
| @@ -4293,7 +4317,8 @@
|
| #ifdef DEBUG
|
| for (int j = bottom; j <= top; j++) {
|
| unsigned current_char = j;
|
| - int length = uncanonicalize.get(current_char, '\0', chars);
|
| + int length = isolate->jsregexp_uncanonicalize()->get(current_char,
|
| + '\0', chars);
|
| for (int k = 0; k < length; k++) {
|
| ASSERT(chars[k] == current_char);
|
| }
|
| @@ -4306,7 +4331,7 @@
|
| // Step through the range finding equivalent characters.
|
| ZoneList<unibrow::uchar> *characters = new ZoneList<unibrow::uchar>(100);
|
| for (int i = bottom; i <= top; i++) {
|
| - int length = uncanonicalize.get(i, '\0', chars);
|
| + int length = isolate->jsregexp_uncanonicalize()->get(i, '\0', chars);
|
| for (int j = 0; j < length; j++) {
|
| uc32 chr = chars[j];
|
| if (chr != i && (chr < bottom || chr > top)) {
|
| @@ -4828,7 +4853,7 @@
|
|
|
|
|
| void Analysis::EnsureAnalyzed(RegExpNode* that) {
|
| - StackLimitCheck check;
|
| + StackLimitCheck check(Isolate::Current());
|
| if (check.HasOverflowed()) {
|
| fail("Stack overflow");
|
| return;
|
| @@ -5338,7 +5363,4 @@
|
| }
|
|
|
|
|
| -int OffsetsVector::static_offsets_vector_[
|
| - OffsetsVector::kStaticOffsetsVectorSize];
|
| -
|
| }} // namespace v8::internal
|
|
|