/* * Copyright (C) 2008 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef WRECGenerator_h #define WRECGenerator_h #include <wtf/Platform.h> #if ENABLE(WREC) #include "Quantifier.h" #include "MacroAssembler.h" #include <wtf/ASCIICType.h> #include <wtf/unicode/Unicode.h> #include "WREC.h" namespace JSC { class JSGlobalData; namespace WREC { class CharacterRange; class GenerateAtomFunctor; class Parser; struct CharacterClass; class Generator : private MacroAssembler { public: using MacroAssembler::Jump; using MacroAssembler::JumpList; using MacroAssembler::Label; enum ParenthesesType { Capturing, NonCapturing, Assertion, InvertedAssertion, Error }; static CompiledRegExp compileRegExp(JSGlobalData*, const UString& pattern, unsigned* numSubpatterns_ptr, const char** error_ptr, RefPtr<ExecutablePool>& pool, bool ignoreCase = false, bool multiline = false); Generator(Parser& parser) : m_parser(parser) { } #if CPU(X86) static const RegisterID input = X86Registers::eax; static const RegisterID index = X86Registers::edx; static const RegisterID length = X86Registers::ecx; static const RegisterID output = X86Registers::edi; static const RegisterID character = X86Registers::esi; static const RegisterID repeatCount = X86Registers::ebx; // How many times the current atom repeats in the current match. static const RegisterID returnRegister = X86Registers::eax; #endif #if CPU(X86_64) static const RegisterID input = X86Registers::edi; static const RegisterID index = X86Registers::esi; static const RegisterID length = X86Registers::edx; static const RegisterID output = X86Registers::ecx; static const RegisterID character = X86Registers::eax; static const RegisterID repeatCount = X86Registers::ebx; // How many times the current atom repeats in the current match. static const RegisterID returnRegister = X86Registers::eax; #endif void generateEnter(); void generateSaveIndex(); void generateIncrementIndex(Jump* failure = 0); void generateLoadCharacter(JumpList& failures); void generateJumpIfNotEndOfInput(Label); void generateReturnSuccess(); void generateReturnFailure(); void generateGreedyQuantifier(JumpList& failures, GenerateAtomFunctor& functor, unsigned min, unsigned max); void generateNonGreedyQuantifier(JumpList& failures, GenerateAtomFunctor& functor, unsigned min, unsigned max); void generateBacktrack1(); void generateBacktrackBackreference(unsigned subpatternId); void generateCharacterClass(JumpList& failures, const CharacterClass& charClass, bool invert); void generateCharacterClassInverted(JumpList& failures, const CharacterClass& charClass); void generateCharacterClassInvertedRange(JumpList& failures, JumpList& matchDest, const CharacterRange* ranges, unsigned count, unsigned* matchIndex, const UChar* matches, unsigned matchCount); void generatePatternCharacter(JumpList& failures, int ch); void generatePatternCharacterSequence(JumpList& failures, int* sequence, size_t count); void generateAssertionWordBoundary(JumpList& failures, bool invert); void generateAssertionBOL(JumpList& failures); void generateAssertionEOL(JumpList& failures); void generateBackreference(JumpList& failures, unsigned subpatternID); void generateBackreferenceQuantifier(JumpList& failures, Quantifier::Type quantifierType, unsigned subpatternId, unsigned min, unsigned max); void generateParenthesesAssertion(JumpList& failures); void generateParenthesesInvertedAssertion(JumpList& failures); Jump generateParenthesesResetTrampoline(JumpList& newFailures, unsigned subpatternIdBefore, unsigned subpatternIdAfter); void generateParenthesesNonGreedy(JumpList& failures, Label start, Jump success, Jump fail); void terminateAlternative(JumpList& successes, JumpList& failures); void terminateDisjunction(JumpList& successes); private: bool generatePatternCharacterPair(JumpList& failures, int ch1, int ch2); Parser& m_parser; }; } } // namespace JSC::WREC #endif // ENABLE(WREC) #endif // WRECGenerator_h