source: webkit/trunk/JavaScriptCore/runtime/RegExp.cpp@ 42478

Last change on this file since 42478 was 40562, checked in by [email protected], 16 years ago

2009-02-03 Gavin Barraclough <[email protected]>

Reviewed by Geoff Garen.

https://bugs.webkit.org/show_bug.cgi?id=23715

Simplify MacroAssembler interface, by combining comparison methods.
Seprate operations are combined as follows:

jz32/jnz32/jzPtr/jnzPtr -> branchTest32/branchTestPtr,
j*(Add|Mul|Sub)32/j*(Add|Mul|Sub)Ptr -> branch(Add|Mul|Sub)32/branch(Add|Mul|Sub)Ptr
j*32/j*Ptr (all other two op combparisons) -> branch32/brnachPtr
set*32 -> set32

Also, represent the Scale of BaseIndex addresses as a plain enum (0,1,2,3),
instead of as multiplicands (1,2,4,8).

This patch singificantly reduces replication of code, and increases functionality supported
by the MacroAssembler. No performance impact.

  • assembler/MacroAssembler.h: (JSC::MacroAssembler::): (JSC::MacroAssembler::branchPtr): (JSC::MacroAssembler::branchPtrWithPatch): (JSC::MacroAssembler::branch32): (JSC::MacroAssembler::branch16): (JSC::MacroAssembler::branchTestPtr): (JSC::MacroAssembler::branchTest32): (JSC::MacroAssembler::branchAddPtr): (JSC::MacroAssembler::branchAdd32): (JSC::MacroAssembler::branchMul32): (JSC::MacroAssembler::branchSubPtr): (JSC::MacroAssembler::branchSub32): (JSC::MacroAssembler::set32): (JSC::MacroAssembler::setTest32):
  • assembler/X86Assembler.h: (JSC::X86Assembler::): (JSC::X86Assembler::jccRel32): (JSC::X86Assembler::setccOpcode): (JSC::X86Assembler::cmpq_mr): (JSC::X86Assembler::setcc_r): (JSC::X86Assembler::sete_r): (JSC::X86Assembler::setne_r): (JSC::X86Assembler::jne): (JSC::X86Assembler::je): (JSC::X86Assembler::jl): (JSC::X86Assembler::jb): (JSC::X86Assembler::jle): (JSC::X86Assembler::jbe): (JSC::X86Assembler::jge): (JSC::X86Assembler::jg): (JSC::X86Assembler::ja): (JSC::X86Assembler::jae): (JSC::X86Assembler::jo): (JSC::X86Assembler::jp): (JSC::X86Assembler::js): (JSC::X86Assembler::jcc): (JSC::X86Assembler::X86InstructionFormatter::putModRmSib):
  • jit/JIT.cpp: (JSC::JIT::compileOpStrictEq): (JSC::JIT::emitSlowScriptCheck): (JSC::JIT::privateCompileMainPass): (JSC::JIT::privateCompileSlowCases): (JSC::JIT::privateCompile): (JSC::JIT::privateCompileCTIMachineTrampolines):
  • jit/JITArithmetic.cpp: (JSC::JIT::compileFastArith_op_lshift): (JSC::JIT::compileFastArith_op_mod): (JSC::JIT::compileFastArith_op_post_inc): (JSC::JIT::compileFastArith_op_post_dec): (JSC::JIT::compileFastArith_op_pre_inc): (JSC::JIT::compileFastArith_op_pre_dec): (JSC::JIT::compileBinaryArithOp): (JSC::JIT::compileFastArith_op_add): (JSC::JIT::compileFastArith_op_mul):
  • jit/JITCall.cpp: (JSC::JIT::compileOpCall): (JSC::JIT::compileOpCallSlowCase):
  • jit/JITInlineMethods.h: (JSC::JIT::checkStructure): (JSC::JIT::emitJumpIfJSCell): (JSC::JIT::emitJumpIfNotJSCell): (JSC::JIT::emitJumpIfImmediateNumber): (JSC::JIT::emitJumpIfNotImmediateNumber): (JSC::JIT::emitJumpIfImmediateInteger): (JSC::JIT::emitJumpIfNotImmediateInteger): (JSC::JIT::emitFastArithDeTagImmediateJumpIfZero):
  • jit/JITPropertyAccess.cpp: (JSC::JIT::compileGetByIdHotPath): (JSC::JIT::compilePutByIdHotPath): (JSC::JIT::privateCompilePutByIdTransition): (JSC::JIT::privateCompilePatchGetArrayLength): (JSC::JIT::privateCompileGetByIdProto): (JSC::JIT::privateCompileGetByIdProtoList): (JSC::JIT::privateCompileGetByIdChainList): (JSC::JIT::privateCompileGetByIdChain):
  • runtime/RegExp.cpp: (JSC::RegExp::match):
  • wrec/WRECGenerator.cpp: (JSC::WREC::Generator::generateEnter): (JSC::WREC::Generator::generateIncrementIndex): (JSC::WREC::Generator::generateLoadCharacter): (JSC::WREC::Generator::generateJumpIfNotEndOfInput): (JSC::WREC::Generator::generateBackreferenceQuantifier): (JSC::WREC::Generator::generateNonGreedyQuantifier): (JSC::WREC::Generator::generateGreedyQuantifier): (JSC::WREC::Generator::generatePatternCharacterPair): (JSC::WREC::Generator::generatePatternCharacter): (JSC::WREC::Generator::generateCharacterClassInvertedRange): (JSC::WREC::Generator::generateCharacterClassInverted): (JSC::WREC::Generator::generateAssertionBOL): (JSC::WREC::Generator::generateAssertionEOL): (JSC::WREC::Generator::generateAssertionWordBoundary): (JSC::WREC::Generator::generateBackreference):
  • Property svn:eol-style set to native
File size: 5.7 KB
Line 
1/*
2 * Copyright (C) 1999-2001, 2004 Harri Porten ([email protected])
3 * Copyright (c) 2007, 2008 Apple Inc. All rights reserved.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 *
19 */
20
21#include "config.h"
22#include "RegExp.h"
23
24#include "JIT.h"
25#include "Lexer.h"
26#include "WRECGenerator.h"
27#include <pcre/pcre.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include <wtf/Assertions.h>
32#include <wtf/OwnArrayPtr.h>
33
34namespace JSC {
35
36#if ENABLE(WREC)
37using namespace WREC;
38#endif
39
40inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern)
41 : m_pattern(pattern)
42 , m_flagBits(0)
43 , m_regExp(0)
44 , m_constructionError(0)
45 , m_numSubpatterns(0)
46{
47#if ENABLE(WREC)
48 m_wrecFunction = Generator::compileRegExp(globalData, pattern, &m_numSubpatterns, &m_constructionError, m_executablePool);
49 if (m_wrecFunction || m_constructionError)
50 return;
51 // Fall through to non-WREC case.
52#else
53 UNUSED_PARAM(globalData);
54#endif
55 m_regExp = jsRegExpCompile(reinterpret_cast<const UChar*>(pattern.data()), pattern.size(),
56 JSRegExpDoNotIgnoreCase, JSRegExpSingleLine, &m_numSubpatterns, &m_constructionError);
57}
58
59PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& pattern)
60{
61 return adoptRef(new RegExp(globalData, pattern));
62}
63
64inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern, const UString& flags)
65 : m_pattern(pattern)
66 , m_flags(flags)
67 , m_flagBits(0)
68 , m_regExp(0)
69 , m_constructionError(0)
70 , m_numSubpatterns(0)
71{
72 // NOTE: The global flag is handled on a case-by-case basis by functions like
73 // String::match and RegExpObject::match.
74 if (flags.find('g') != -1)
75 m_flagBits |= Global;
76
77 // FIXME: Eliminate duplication by adding a way ask a JSRegExp what its flags are?
78 JSRegExpIgnoreCaseOption ignoreCaseOption = JSRegExpDoNotIgnoreCase;
79 if (flags.find('i') != -1) {
80 m_flagBits |= IgnoreCase;
81 ignoreCaseOption = JSRegExpIgnoreCase;
82 }
83
84 JSRegExpMultilineOption multilineOption = JSRegExpSingleLine;
85 if (flags.find('m') != -1) {
86 m_flagBits |= Multiline;
87 multilineOption = JSRegExpMultiline;
88 }
89
90#if ENABLE(WREC)
91 m_wrecFunction = Generator::compileRegExp(globalData, pattern, &m_numSubpatterns, &m_constructionError, m_executablePool, (m_flagBits & IgnoreCase), (m_flagBits & Multiline));
92 if (m_wrecFunction || m_constructionError)
93 return;
94 // Fall through to non-WREC case.
95#else
96 UNUSED_PARAM(globalData);
97#endif
98 m_regExp = jsRegExpCompile(reinterpret_cast<const UChar*>(pattern.data()), pattern.size(),
99 ignoreCaseOption, multilineOption, &m_numSubpatterns, &m_constructionError);
100}
101
102PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& pattern, const UString& flags)
103{
104 return adoptRef(new RegExp(globalData, pattern, flags));
105}
106
107RegExp::~RegExp()
108{
109 jsRegExpFree(m_regExp);
110}
111
112int RegExp::match(const UString& s, int startOffset, OwnArrayPtr<int>* ovector)
113{
114 if (startOffset < 0)
115 startOffset = 0;
116 if (ovector)
117 ovector->clear();
118
119 if (startOffset > s.size() || s.isNull())
120 return -1;
121
122#if ENABLE(WREC)
123 if (m_wrecFunction) {
124 int offsetVectorSize = (m_numSubpatterns + 1) * 2;
125 int* offsetVector = new int [offsetVectorSize];
126 ASSERT(offsetVector);
127 for (int j = 0; j < offsetVectorSize; ++j)
128 offsetVector[j] = -1;
129
130 OwnArrayPtr<int> nonReturnedOvector;
131 if (!ovector)
132 nonReturnedOvector.set(offsetVector);
133 else
134 ovector->set(offsetVector);
135
136 int result = m_wrecFunction(s.data(), startOffset, s.size(), offsetVector);
137
138 if (result < 0) {
139#ifndef NDEBUG
140 // TODO: define up a symbol, rather than magic -1
141 if (result != -1)
142 fprintf(stderr, "jsRegExpExecute failed with result %d\n", result);
143#endif
144 if (ovector)
145 ovector->clear();
146 }
147 return result;
148 } else
149#endif
150 if (m_regExp) {
151 // Set up the offset vector for the result.
152 // First 2/3 used for result, the last third used by PCRE.
153 int* offsetVector;
154 int offsetVectorSize;
155 int fixedSizeOffsetVector[3];
156 if (!ovector) {
157 offsetVectorSize = 3;
158 offsetVector = fixedSizeOffsetVector;
159 } else {
160 offsetVectorSize = (m_numSubpatterns + 1) * 3;
161 offsetVector = new int [offsetVectorSize];
162 ovector->set(offsetVector);
163 }
164
165 int numMatches = jsRegExpExecute(m_regExp, reinterpret_cast<const UChar*>(s.data()), s.size(), startOffset, offsetVector, offsetVectorSize);
166
167 if (numMatches < 0) {
168#ifndef NDEBUG
169 if (numMatches != JSRegExpErrorNoMatch)
170 fprintf(stderr, "jsRegExpExecute failed with result %d\n", numMatches);
171#endif
172 if (ovector)
173 ovector->clear();
174 return -1;
175 }
176
177 return offsetVector[0];
178 }
179
180 return -1;
181}
182
183} // namespace JSC
Note: See TracBrowser for help on using the repository browser.