From 1ea0e706981006c48ad16a1ff8051df03610f20b Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 16 May 2011 11:28:00 +0200 Subject: qdoc: Fixed QTBUG-19338 --- tools/qdoc3/ditaxmlgenerator.cpp | 5 ++++- tools/qdoc3/generator.cpp | 11 +++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/tools/qdoc3/ditaxmlgenerator.cpp b/tools/qdoc3/ditaxmlgenerator.cpp index 342bb90..c45648b 100644 --- a/tools/qdoc3/ditaxmlgenerator.cpp +++ b/tools/qdoc3/ditaxmlgenerator.cpp @@ -1199,7 +1199,10 @@ int DitaXmlGenerator::generateAtom(const Atom *atom, Just output the href as if the image is in the images directory... */ - fileName = QLatin1String("images/") + protectEnc(atom->string()); + if (atom->string()[0] == '/') + fileName = QLatin1String("images") + atom->string(); + else + fileName = QLatin1String("images/") + atom->string(); } if (currentTag() != DT_xref) diff --git a/tools/qdoc3/generator.cpp b/tools/qdoc3/generator.cpp index f05c030..81aba6b 100644 --- a/tools/qdoc3/generator.cpp +++ b/tools/qdoc3/generator.cpp @@ -783,10 +783,13 @@ QString Generator::imageFileName(const Node *relative, const QString& fileBase) if (filePath.isEmpty()) return QString(); - return QLatin1String("images/") - + Config::copyFile(relative->doc().location(), - filePath, userFriendlyFilePath, - outputDir() + QLatin1String("/images")); + QString path = Config::copyFile(relative->doc().location(), + filePath, + userFriendlyFilePath, + outputDir() + QLatin1String("/images")); + if (path[0] != '/') + return QLatin1String("images/") + path; + return QLatin1String("images") + path; } void Generator::setImageFileExtensions(const QStringList& extensions) -- cgit v0.12 From 1bd6f1bd280ee6e1ecd4de2291c8ccfb4d06b7a4 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Thu, 16 Jun 2011 16:10:38 +0200 Subject: Doc: Removed non-ASCII characters from the documentation. --- doc/src/platforms/supported-platforms.qdoc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/src/platforms/supported-platforms.qdoc b/doc/src/platforms/supported-platforms.qdoc index 9d47695..ba59c37 100644 --- a/doc/src/platforms/supported-platforms.qdoc +++ b/doc/src/platforms/supported-platforms.qdoc @@ -334,8 +334,8 @@ \section2 Advanced Text Layout Engine - Qt for Windows CE supports TrueType® and raster fonts. Qt also has - extended Unicode support and right-to-left languages. Qt’s rich text + Qt for Windows CE supports TrueType and raster fonts. Qt also has + extended Unicode support and right-to-left languages. Qt's rich text engine adds capabilities for complex text layouts including tables, path tracing and text which flows around shapes. @@ -373,7 +373,7 @@ by embedded Linux. You can use Qt to create highly memory efficient devices and applications that have completely unique user experiences. - Qt runs anywhere Linux runs. Qt’s intuitive API means fewer lines of + Qt runs anywhere Linux runs. Qt's intuitive API means fewer lines of code and higher level functionality in less time. Use the code from one single code-base and rebuild for all \l{Supported Platforms} {supported platforms}. @@ -410,7 +410,7 @@ frame buffer} that will match the physical device display, pixel for pixel. This gives the developer a realistic testing infrastructure testing on the desktop where the frame buffer simulates the physical - device display’s width, height and color depth. + device display's width, height and color depth. \section2 Inter-Process Communication (IPC) @@ -421,7 +421,7 @@ \section2 Extended Font Format Qt supports a wide range of font formats on embedded Linux including: - TrueType®, Postscript® Type1 and Qt pre-rendered fonts. Qt has + TrueType, Postscript Type1 and Qt pre-rendered fonts. Qt has extended Unicode support including automatic data extraction at build time and automatic update at runtime. @@ -681,7 +681,7 @@ \group platform-details Qt is a cross-platform application and UI framework. Using Qt, - you can write web-enabled applications once and deploy them + you can write GUI applications once and deploy them across desktop, mobile and embedded operating systems without rewriting the source code. -- cgit v0.12 From 26c29a2dd7efa4c66063d1255e1f694462cbae85 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Thu, 16 Jun 2011 20:20:50 +0200 Subject: Doc: Added more appropriate links to help reduce confusion. Task-number: QTBUG-19919 --- src/gui/widgets/qtextedit.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp index 6757d77..b6661c9 100644 --- a/src/gui/widgets/qtextedit.cpp +++ b/src/gui/widgets/qtextedit.cpp @@ -2472,6 +2472,8 @@ bool QTextEdit::find(const QString &exp, QTextDocument::FindFlags options) and the text edit will try to guess the right format. Use setHtml() or setPlainText() directly to avoid text edit's guessing. + + \sa toPlainText(), toHtml() */ void QTextEdit::setText(const QString &text) { -- cgit v0.12 From 9ed61311bce15b8f1bb4b30ee9133f1a2355f41d Mon Sep 17 00:00:00 2001 From: David Boddie Date: Thu, 16 Jun 2011 20:24:11 +0200 Subject: Doc: Added a simple introduction to Qt and fixed links. --- doc/src/declarative/declarativeui.qdoc | 2 +- doc/src/declarative/qtquick-intro.qdoc | 2 +- doc/src/index.qdoc | 4 +- doc/src/qt-features.qdoc | 204 +++++++++++++++++++++++++++++++++ doc/src/qt4-intro.qdoc | 2 +- 5 files changed, 209 insertions(+), 5 deletions(-) create mode 100644 doc/src/qt-features.qdoc diff --git a/doc/src/declarative/declarativeui.qdoc b/doc/src/declarative/declarativeui.qdoc index 56ab29f..d1d82d8 100644 --- a/doc/src/declarative/declarativeui.qdoc +++ b/doc/src/declarative/declarativeui.qdoc @@ -46,7 +46,7 @@ Qt applications. \section1 Getting Started \list -\o \l{Intro to Qt Quick}{Introduction to Qt Quick} +\o \l{Introduction to Qt Quick} \o \l{QML for Qt Programmers}{QML Programming for Qt Programmers} \o \l{Getting Started Programming with QML} diff --git a/doc/src/declarative/qtquick-intro.qdoc b/doc/src/declarative/qtquick-intro.qdoc index bdad2c3..4cd5db3 100644 --- a/doc/src/declarative/qtquick-intro.qdoc +++ b/doc/src/declarative/qtquick-intro.qdoc @@ -27,7 +27,7 @@ /*! \page qml-intro.html -\title Intro to Qt Quick +\title Introduction to Qt Quick Qt Quick is a collection of technologies that are designed to help developers create the kind of intuitive, modern, and fluid user interfaces that are diff --git a/doc/src/index.qdoc b/doc/src/index.qdoc index 979c654..2ce6781 100644 --- a/doc/src/index.qdoc +++ b/doc/src/index.qdoc @@ -36,8 +36,8 @@ What is Qt \enddiv \list - \o \l{Qt Whitepaper}{Qt C++ Framework} - \o \l{Intro to Qt Quick}{Qt Quick} + \o \l{Qt Features Overview} + \o \l{Introduction to Qt Quick}{Qt Quick} \o \l{external: Qt Mobility Manual}{Qt Mobility} \o \l{Qt WebKit} \endlist diff --git a/doc/src/qt-features.qdoc b/doc/src/qt-features.qdoc new file mode 100644 index 0000000..0ae00b0 --- /dev/null +++ b/doc/src/qt-features.qdoc @@ -0,0 +1,204 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qt-overview.html + \title Qt Features Overview + + This document provides a summary of the most important features of Qt, + providing links to other pages in the documentation that cover these + features in more detail. It is not intended to be a comprehensive + guide to Qt's features. + + \section1 Fundamental Technologies in Qt + + Qt is built upon a set of core technologies, provided by the \l QtCore + and \l QtGui modules. These include the following: + + \list + \o \l{The Tulip Container Classes}, a set of template container classes. + \o \l{The Arthur Paint System}, the Qt 4 painting framework. + \o \l{The Interview Framework}, a model/view architecture for item views + and the \l{QtSQL Module}, which also uses this architecture. + \o \l{The Scribe Classes}, a framework for creating text documents, + performing low-level text layout and writing OpenDocument files. + \o A collection of \l{Qt Widget Gallery}{common desktop widgets}, styled + to fit in on each supported platform. + \o \l{The Qt 4 Main Window Classes}, a main window, toolbar, menu, and + docking architecture. + \o The \l{Graphics View} framework provides a canvas for producing + interactive graphics. + \o The \l{QtNetwork Module} provides support for TCP, UDP and local + sockets that are integrated with Qt's event model, including support + for Secure Socket Layer (SSL) communications, + \l{QNetworkProxy}{network proxy} servers and + \l{Bearer Management}{network bearer management}. + \o Enhanced \l{qt4-threads.html}{thread support} allows + \l{Signals & Slots}{signal-slot} connections across threads and + per-thread event loops. + Additionally, \l{Thread Support in Qt}{a framework for concurrent programming} + using Qt paradigms makes common threading tasks easier. + \o A \l{resource system} for embedding images and other resource files + into executable files makes it easier to deploy applications. + \o A \l{QTestLib Manual}{unit testing framework} for Qt applications and + libraries. + \endlist + + The mature classes provided by these technologies have been used to build + robust, cross-platform desktop applications. They are augmented by a number + of additional technologies and improvements that have appeared over the + lifetime of Qt 4. + + \section1 Graphical User Interfaces + + \div{class="float-right"} + \inlineimage gtk-tabwidget.png + \enddiv + \div{class="float-right"} + \inlineimage gtk-progressbar.png + \br + \inlineimage gtk-checkbox.png + \br + \inlineimage plastique-combobox.png + \br + \inlineimage plastique-radiobutton.png + \enddiv + + Alongside the support for traditional desktop user interfaces, Qt includes + support for declarative UI development with \l{Qt Quick}, a set of + technologies for creating fluid, dynamic user interfaces. A starting point + for exploring this approach can be found in the \l{Introduction to Qt Quick} + guide. + + Qt provides a range of standard user interface elements, called widgets, + for each supported platform. Widgets can be used as containers for other + widgets, as windows, and as regular controls that the user interacts with. + Where the platform supports it, widgets can be made to appear partially + transparent, and may be styled with \l{Qt Style Sheets}. + + Support for \l{QTouchEvent}{touch input} and \l{Gestures Programming}{gestures} + enable widgets to be used to create intuitive user interfaces for + touch-enabled devices. + + User interfaces can also be created dynamically at run-time with the + features provided by the \l{QtUiTools} module. + + A selection of available widgets are shown in the \l{Qt Widget Gallery}. + An introduction to the concepts behind widgets can be found in the + \l{Widgets Tutorial}. + + \clearfloat + \section1 Painting, Printing and Rendering + + \div{class="float-left"} + \inlineimage qpainter-affinetransformations.png + \enddiv + + Widgets are just one of many kinds of paint device that Qt can render onto. + This support for unified painting makes it possible for applications to use + the same painting code for different tasks, as well as allowing Qt to be + extended to support additional file formats. + + Qt provides support for common bitmap image formats, + \l{QtSvg Module}{Scalable Vector Graphics} (SVG) drawings and animations, + Postscript and Portable Document Format (PDF) files. Postscript and PDF are + integrated with \l{Printing with Qt}{Qt's printing system}, which also + allows printed output to be previewed. + + Interactive graphics can be created with the + \l{The Animation Framework}{animation framework}, allowing animations to be + used with both widgets and graphics items. Animations can be used with the + \l{The State Machine Framework}{state machine framework}, which provides a + way to express application logic and integrate it with the user interface. + Animations can be enhanced with a collection of + \l{QGraphicsEffect}{graphics effects} that operate on graphics items and + can be applied individually or combined to create more complex effects. + + Qt supports integration with \l{QtOpenGL}{OpenGL} on a number of levels, + providing convenience functions for handling textures and colors, as well + as providing support for pixel and sample buffers. Future support for + higher level 3D integration is provided by Qt3D enablers which include + \l{QMatrix4x4}{matrix multiplication}, \l{QQuaternion}{quaternions}, and an + API for \l{QGLShader}{vertex and fragment shaders}. + + Two APIs are provided for multimedia. The + \l{Phonon Overview}{Phonon Multimedia Framework} has traditionally been + used on desktop platforms. A set of + \l{QtMultimedia Module}{multimedia services} provides low-level access to + the system's audio system and is often used on mobile devices. + + \clearfloat + \section1 Infrastructure + + \div{class="float-right"} + \inlineimage qtscript-context2d.png + \enddiv + + Facilities for Inter-Process Communication (IPC) and Remote Procedure + Calling (RPC) mechanisms are available on platforms that support the + \l{intro-to-dbus.html}{D-Bus} message bus system. + + An \l{Undo Framework}{Undo framework} based on the + \l{Books about GUI Design#Design Patterns}{Command pattern} is designed to + enable a consistent approach to handling data in editing applications. + + The \l{QtScript} and \l{QtScriptTools} modules provide support for + application scripting and debugging using the ECMAScript language. + + The \l{QtHelp Module} provides the foundations of an interactive help + system that can be used in conjunction with Qt Creator or integrated into + applications directly. + + XML handling is supported in a number of places in Qt. The \l QtCore module + provides classes for reading and writing XML streams. The \l QtXmlPatterns + module includes XQuery, XPath and XSLT support, providing facilities for + XML processing beyond that supported by the QtXml module, which contains + SAX and DOM parsers. XML schema validation in the QtXmlPatterns module + covers large parts of version 1.0 of the specification. + + \clearfloat + \section1 Web Client Integration + + Integration between \l{Webkit in Qt}{Qt and WebKit} makes it possible for + developers to use a fully-featured Web browser engine to display documents + and access online services. Developers can access the browser's environment + to create documents and run scripts within one or more browser widgets. + + A \l{QWebElement}{DOM access API} for QtWebKit provides a cleaner and safer + way to access elements and structures of Web pages without the use of + JavaScript. + + \section1 Further Reading + + Many of the technologies mentioned here, as well as other, more specific + features, are listed in the \l{What's New in Qt 4} document. A complete + list of Qt's modules can be found on the \l{All Modules} page, which + also includes more domain-specific technologies. + + The tools that are supplied with Qt are covered by the listing in the + \l{Qt's Tools} document. +*/ diff --git a/doc/src/qt4-intro.qdoc b/doc/src/qt4-intro.qdoc index 41d8b2e..d75bdca 100644 --- a/doc/src/qt4-intro.qdoc +++ b/doc/src/qt4-intro.qdoc @@ -132,7 +132,7 @@ In Qt 4.4: \list - \o \l{Webkit in QT}{Qt WebKit integration}, making it possible for developers + \o \l{WebKit in Qt}{Qt WebKit integration}, making it possible for developers to use a fully-featured Web browser to display documents and access online services. \o A multimedia API provided by the \l{Phonon Overview}{Phonon Multimedia Framework}. -- cgit v0.12 From 6a2f18140bbc41207eb2f5e2323b699600d89606 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Thu, 30 Jun 2011 19:08:43 +0200 Subject: Modified \since command behavior slightly to handle project and version. (The since argument can contain a project name and version, defaulting to the qdoc project if only a version number is specified.) Refactored common code into the Generator class. Fixed \sincelist HTML generation for tables containing only one item. --- tools/qdoc3/ditaxmlgenerator.cpp | 83 ----------------------- tools/qdoc3/ditaxmlgenerator.h | 11 --- tools/qdoc3/doc.cpp | 2 +- tools/qdoc3/generator.cpp | 142 +++++++++++++++++++++++++++++++++++++-- tools/qdoc3/generator.h | 12 ++++ tools/qdoc3/htmlgenerator.cpp | 103 +++++----------------------- tools/qdoc3/htmlgenerator.h | 11 --- tools/qdoc3/node.cpp | 10 +++ tools/qdoc3/node.h | 2 +- 9 files changed, 174 insertions(+), 202 deletions(-) diff --git a/tools/qdoc3/ditaxmlgenerator.cpp b/tools/qdoc3/ditaxmlgenerator.cpp index c49ff65..64f12d6 100644 --- a/tools/qdoc3/ditaxmlgenerator.cpp +++ b/tools/qdoc3/ditaxmlgenerator.cpp @@ -62,25 +62,6 @@ QT_BEGIN_NAMESPACE #define COMMAND_VERSION Doc::alias("version") int DitaXmlGenerator::id = 0; -QString DitaXmlGenerator::sinceTitles[] = - { - " New Namespaces", - " New Classes", - " New Member Functions", - " New Functions in Namespaces", - " New Global Functions", - " New Macros", - " New Enum Types", - " New Typedefs", - " New Properties", - " New Variables", - " New QML Elements", - " New Qml Properties", - " New Qml Signals", - " New Qml Methods", - "" - }; - /* The strings in this array must appear in the same order as the values in enum DitaXmlGenerator::DitaTag. @@ -3955,70 +3936,6 @@ void DitaXmlGenerator::findAllClasses(const InnerNode* node) } } -/*! - For generating the "New Classes... in 4.x" section on the - What's New in 4.x" page. - */ -void DitaXmlGenerator::findAllSince(const InnerNode* node) -{ - NodeList::const_iterator child = node->childNodes().constBegin(); - while (child != node->childNodes().constEnd()) { - QString sinceVersion = (*child)->since(); - if (((*child)->access() != Node::Private) && !sinceVersion.isEmpty()) { - NewSinceMaps::iterator nsmap = newSinceMaps.find(sinceVersion); - if (nsmap == newSinceMaps.end()) - nsmap = newSinceMaps.insert(sinceVersion,NodeMultiMap()); - NewClassMaps::iterator ncmap = newClassMaps.find(sinceVersion); - if (ncmap == newClassMaps.end()) - ncmap = newClassMaps.insert(sinceVersion,NodeMap()); - NewClassMaps::iterator nqcmap = newQmlClassMaps.find(sinceVersion); - if (nqcmap == newQmlClassMaps.end()) - nqcmap = newQmlClassMaps.insert(sinceVersion,NodeMap()); - - if ((*child)->type() == Node::Function) { - FunctionNode *func = static_cast(*child); - if ((func->status() > Node::Obsolete) && - (func->metaness() != FunctionNode::Ctor) && - (func->metaness() != FunctionNode::Dtor)) { - nsmap.value().insert(func->name(),(*child)); - } - } - else if ((*child)->url().isEmpty()) { - if ((*child)->type() == Node::Class && !(*child)->doc().isEmpty()) { - QString className = (*child)->name(); - if ((*child)->parent() && - (*child)->parent()->type() == Node::Namespace && - !(*child)->parent()->name().isEmpty()) - className = (*child)->parent()->name()+"::"+className; - nsmap.value().insert(className,(*child)); - ncmap.value().insert(className,(*child)); - } - else if ((*child)->subType() == Node::QmlClass) { - QString className = (*child)->name(); - if ((*child)->parent() && - (*child)->parent()->type() == Node::Namespace && - !(*child)->parent()->name().isEmpty()) - className = (*child)->parent()->name()+"::"+className; - nsmap.value().insert(className,(*child)); - nqcmap.value().insert(className,(*child)); - } - } - else { - QString name = (*child)->name(); - if ((*child)->parent() && - (*child)->parent()->type() == Node::Namespace && - !(*child)->parent()->name().isEmpty()) - name = (*child)->parent()->name()+"::"+name; - nsmap.value().insert(name,(*child)); - } - if ((*child)->isInnerNode()) { - findAllSince(static_cast(*child)); - } - } - ++child; - } -} - void DitaXmlGenerator::findAllFunctions(const InnerNode* node) { NodeList::ConstIterator c = node->childNodes().begin(); diff --git a/tools/qdoc3/ditaxmlgenerator.h b/tools/qdoc3/ditaxmlgenerator.h index 408f46c..d8d3563 100644 --- a/tools/qdoc3/ditaxmlgenerator.h +++ b/tools/qdoc3/ditaxmlgenerator.h @@ -51,12 +51,6 @@ QT_BEGIN_NAMESPACE -typedef QMultiMap NodeMultiMap; -typedef QMap NewSinceMaps; -typedef QMap ParentMaps; -typedef QMap NodeMap; -typedef QMap NewClassMaps; - typedef QMap GuidMap; typedef QMap GuidMaps; @@ -418,7 +412,6 @@ class DitaXmlGenerator : public PageGenerator void findAllFunctions(const InnerNode *node); void findAllLegaleseTexts(const InnerNode *node); void findAllNamespaces(const InnerNode *node); - void findAllSince(const InnerNode *node); static int hOffset(const Node *node); static bool isThreeColumnEnumValueTable(const Atom *atom); virtual QString getLink(const Atom *atom, @@ -515,10 +508,6 @@ class DitaXmlGenerator : public PageGenerator #endif QMap funcIndex; QMap legaleseTexts; - NewSinceMaps newSinceMaps; - static QString sinceTitles[]; - NewClassMaps newClassMaps; - NewClassMaps newQmlClassMaps; static int id; static QString ditaTags[]; QStack xmlWriterStack; diff --git a/tools/qdoc3/doc.cpp b/tools/qdoc3/doc.cpp index 479931d..37f68f8 100644 --- a/tools/qdoc3/doc.cpp +++ b/tools/qdoc3/doc.cpp @@ -828,7 +828,7 @@ void DocParser::parse(const QString& source, append(Atom::AnnotatedList, getArgument()); break; case CMD_SINCELIST: - append(Atom::SinceList, getArgument()); + append(Atom::SinceList, getRestOfLine().simplified()); break; case CMD_GENERATELIST: append(Atom::GeneratedList, getArgument()); diff --git a/tools/qdoc3/generator.cpp b/tools/qdoc3/generator.cpp index 6c92e54..355c9b2 100644 --- a/tools/qdoc3/generator.cpp +++ b/tools/qdoc3/generator.cpp @@ -77,6 +77,25 @@ QString Generator::outDir; QString Generator::project; QHash Generator::outputPrefixes; +QString Generator::sinceTitles[] = + { + " New Namespaces", + " New Classes", + " New Member Functions", + " New Functions in Namespaces", + " New Global Functions", + " New Macros", + " New Enum Types", + " New Typedefs", + " New Properties", + " New Variables", + " New QML Elements", + " New QML Properties", + " New QML Signals", + " New QML Methods", + "" + }; + static void singularPlural(Text& text, const NodeList& nodes) { if (nodes.count() == 1) @@ -760,8 +779,18 @@ QString Generator::typeString(const Node *node) case Node::Class: return "class"; case Node::Fake: - default: - return "documentation"; + { + switch (node->subType()) { + case Node::QmlClass: + return "element"; + case Node::QmlPropertyGroup: + return "property group"; + case Node::QmlBasicType: + return "type"; + default: + return "documentation"; + } + } case Node::Enum: return "enum"; case Node::Typedef: @@ -770,6 +799,8 @@ QString Generator::typeString(const Node *node) return "function"; case Node::Property: return "property"; + default: + return "documentation"; } } @@ -1094,11 +1125,21 @@ void Generator::generateSince(const Node *node, CodeMarker *marker) text << " was introduced or modified in "; else text << " was introduced in "; - if (project.isEmpty()) - text << "version"; - else - text << project; - text << " " << node->since() << "." << Atom::ParaRight; + + QStringList since = node->since().split(" "); + if (since.count() == 1) { + // Handle legacy use of \since . + if (project.isEmpty()) + text << "version"; + else + text << project; + text << " " << since[0]; + } else { + // Reconstruct the string. + text << " " << since.join(" "); + } + + text << "." << Atom::ParaRight; generateText(text, node, marker); } } @@ -1349,4 +1390,91 @@ QStringList Generator::getMetadataElements(const InnerNode* inner, const QString return s; } +/*! + For generating the "New Classes... in 4.6" section on the + What's New in 4.6" page. + */ +void Generator::findAllSince(const InnerNode *node) +{ + NodeList::const_iterator child = node->childNodes().constBegin(); + + // Traverse the tree, starting at the node supplied. + + while (child != node->childNodes().constEnd()) { + + QString sinceString = (*child)->since(); + + if (((*child)->access() != Node::Private) && !sinceString.isEmpty()) { + + // Insert a new entry into each map for each new since string found. + NewSinceMaps::iterator nsmap = newSinceMaps.find(sinceString); + if (nsmap == newSinceMaps.end()) + nsmap = newSinceMaps.insert(sinceString,NodeMultiMap()); + + NewClassMaps::iterator ncmap = newClassMaps.find(sinceString); + if (ncmap == newClassMaps.end()) + ncmap = newClassMaps.insert(sinceString,NodeMap()); + + NewClassMaps::iterator nqcmap = newQmlClassMaps.find(sinceString); + if (nqcmap == newQmlClassMaps.end()) + nqcmap = newQmlClassMaps.insert(sinceString,NodeMap()); + + if ((*child)->type() == Node::Function) { + // Insert functions into the general since map. + FunctionNode *func = static_cast(*child); + if ((func->status() > Node::Obsolete) && + (func->metaness() != FunctionNode::Ctor) && + (func->metaness() != FunctionNode::Dtor)) { + nsmap.value().insert(func->name(),(*child)); + } + } + else if ((*child)->url().isEmpty()) { + if ((*child)->type() == Node::Class && !(*child)->doc().isEmpty()) { + // Insert classes into the since and class maps. + QString className = (*child)->name(); + if ((*child)->parent() && + (*child)->parent()->type() == Node::Namespace && + !(*child)->parent()->name().isEmpty()) + className = (*child)->parent()->name()+"::"+className; + + nsmap.value().insert(className,(*child)); + ncmap.value().insert(className,(*child)); + } + else if ((*child)->subType() == Node::QmlClass) { + // Insert QML elements into the since and element maps. + QString className = (*child)->name(); + if ((*child)->parent() && + (*child)->parent()->type() == Node::Namespace && + !(*child)->parent()->name().isEmpty()) + className = (*child)->parent()->name()+"::"+className; + + nsmap.value().insert(className,(*child)); + nqcmap.value().insert(className,(*child)); + } + else if ((*child)->type() == Node::QmlProperty) { + // Insert QML properties into the since map. + QString propertyName = (*child)->name(); + nsmap.value().insert(propertyName,(*child)); + } + } + else { + // Insert external documents into the general since map. + QString name = (*child)->name(); + if ((*child)->parent() && + (*child)->parent()->type() == Node::Namespace && + !(*child)->parent()->name().isEmpty()) + name = (*child)->parent()->name()+"::"+name; + + nsmap.value().insert(name,(*child)); + } + + // Find child nodes with since commands. + if ((*child)->isInnerNode()) { + findAllSince(static_cast(*child)); + } + } + ++child; + } +} + QT_END_NAMESPACE diff --git a/tools/qdoc3/generator.h b/tools/qdoc3/generator.h index e5e9747..e66915b 100644 --- a/tools/qdoc3/generator.h +++ b/tools/qdoc3/generator.h @@ -57,6 +57,12 @@ QT_BEGIN_NAMESPACE +typedef QMap NodeMap; +typedef QMultiMap NodeMultiMap; +typedef QMap NewSinceMaps; +typedef QMap ParentMaps; +typedef QMap NewClassMaps; + class ClassNode; class Config; class CodeMarker; @@ -152,6 +158,7 @@ class Generator QString getMetadataElement(const InnerNode* inner, const QString& t); QStringList getMetadataElements(const InnerNode* inner, const QString& t); + void findAllSince(const InnerNode *node); private: void generateReimplementedFrom(const FunctionNode *func, @@ -180,6 +187,11 @@ class Generator const NodeList& subs, CodeMarker *marker); + static QString sinceTitles[]; + NewSinceMaps newSinceMaps; + NewClassMaps newClassMaps; + NewClassMaps newQmlClassMaps; + private: QString amp; QString lt; diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index 52da178..655c3b4 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -66,25 +66,6 @@ bool HtmlGenerator::debugging_on = false; QString HtmlGenerator::divNavTop = ""; -QString HtmlGenerator::sinceTitles[] = - { - " New Namespaces", - " New Classes", - " New Member Functions", - " New Functions in Namespaces", - " New Global Functions", - " New Macros", - " New Enum Types", - " New Typedefs", - " New Properties", - " New Variables", - " New QML Elements", - " New QML Properties", - " New QML Signals", - " New QML Methods", - "" - }; - static bool showBrokenLinks = false; static QRegExp linkTag("(<@link node=\"([^\"]+)\">).*()"); @@ -606,14 +587,18 @@ int HtmlGenerator::generateAtom(const Atom *atom, ncmap = newClassMaps.find(atom->string()); NewClassMaps::const_iterator nqcmap; nqcmap = newQmlClassMaps.find(atom->string()); + if ((nsmap != newSinceMaps.constEnd()) && !nsmap.value().isEmpty()) { QList
sections; QList
::ConstIterator s; + for (int i=0; itype()) { case Node::Fake: @@ -1346,6 +1331,7 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker) // Generate brief text and status for modules. generateBrief(fake, marker); generateStatus(fake, marker); + generateSince(fake, marker); if (moduleNamespaceMap.contains(fake->name())) { out() << "" << divNavTop << "\n"; @@ -1362,6 +1348,7 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker) // Generate brief text and status for modules. generateBrief(fake, marker); generateStatus(fake, marker); + generateSince(fake, marker); out() << "
    \n"; @@ -1393,6 +1380,7 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker) generateQmlInherits(qml_cn, marker); generateQmlInheritedBy(qml_cn, marker); generateQmlInstantiates(qml_cn, marker); + generateSince(qml_cn, marker); QString allQmlMembersLink = generateAllQmlMembersFile(qml_cn, marker); if (!allQmlMembersLink.isEmpty()) { @@ -2242,9 +2230,6 @@ void HtmlGenerator::generateCompactList(const Node *relative, for (int i=0; i element to contain all the
    elements. */ out() << "
    \n"; + numTableRows = 0; + + int curParNr = 0; + int curParOffset = 0; - for (int i=0; i\n"; curParOffset++; } - out() << "
    \n"; + if (classMap.count() > 0) + out() << "\n"; + out() << "\n"; } @@ -3357,70 +3348,6 @@ void HtmlGenerator::findAllClasses(const InnerNode *node) } } -/*! - For generating the "New Classes... in 4.6" section on the - What's New in 4.6" page. - */ -void HtmlGenerator::findAllSince(const InnerNode *node) -{ - NodeList::const_iterator child = node->childNodes().constBegin(); - while (child != node->childNodes().constEnd()) { - QString sinceVersion = (*child)->since(); - if (((*child)->access() != Node::Private) && !sinceVersion.isEmpty()) { - NewSinceMaps::iterator nsmap = newSinceMaps.find(sinceVersion); - if (nsmap == newSinceMaps.end()) - nsmap = newSinceMaps.insert(sinceVersion,NodeMultiMap()); - NewClassMaps::iterator ncmap = newClassMaps.find(sinceVersion); - if (ncmap == newClassMaps.end()) - ncmap = newClassMaps.insert(sinceVersion,NodeMap()); - NewClassMaps::iterator nqcmap = newQmlClassMaps.find(sinceVersion); - if (nqcmap == newQmlClassMaps.end()) - nqcmap = newQmlClassMaps.insert(sinceVersion,NodeMap()); - - if ((*child)->type() == Node::Function) { - FunctionNode *func = static_cast(*child); - if ((func->status() > Node::Obsolete) && - (func->metaness() != FunctionNode::Ctor) && - (func->metaness() != FunctionNode::Dtor)) { - nsmap.value().insert(func->name(),(*child)); - } - } - else if ((*child)->url().isEmpty()) { - if ((*child)->type() == Node::Class && !(*child)->doc().isEmpty()) { - QString className = (*child)->name(); - if ((*child)->parent() && - (*child)->parent()->type() == Node::Namespace && - !(*child)->parent()->name().isEmpty()) - className = (*child)->parent()->name()+"::"+className; - nsmap.value().insert(className,(*child)); - ncmap.value().insert(className,(*child)); - } - else if ((*child)->subType() == Node::QmlClass) { - QString className = (*child)->name(); - if ((*child)->parent() && - (*child)->parent()->type() == Node::Namespace && - !(*child)->parent()->name().isEmpty()) - className = (*child)->parent()->name()+"::"+className; - nsmap.value().insert(className,(*child)); - nqcmap.value().insert(className,(*child)); - } - } - else { - QString name = (*child)->name(); - if ((*child)->parent() && - (*child)->parent()->type() == Node::Namespace && - !(*child)->parent()->name().isEmpty()) - name = (*child)->parent()->name()+"::"+name; - nsmap.value().insert(name,(*child)); - } - if ((*child)->isInnerNode()) { - findAllSince(static_cast(*child)); - } - } - ++child; - } -} - void HtmlGenerator::findAllFunctions(const InnerNode *node) { NodeList::ConstIterator c = node->childNodes().begin(); diff --git a/tools/qdoc3/htmlgenerator.h b/tools/qdoc3/htmlgenerator.h index 70ec0b7..e36c562 100644 --- a/tools/qdoc3/htmlgenerator.h +++ b/tools/qdoc3/htmlgenerator.h @@ -56,12 +56,6 @@ QT_BEGIN_NAMESPACE -typedef QMultiMap NodeMultiMap; -typedef QMap NewSinceMaps; -typedef QMap ParentMaps; -typedef QMap NodeMap; -typedef QMap NewClassMaps; - class HelpProjectWriter; class HtmlGenerator : public PageGenerator @@ -224,7 +218,6 @@ class HtmlGenerator : public PageGenerator void findAllFunctions(const InnerNode *node); void findAllLegaleseTexts(const InnerNode *node); void findAllNamespaces(const InnerNode *node); - void findAllSince(const InnerNode *node); static int hOffset(const Node *node); static bool isThreeColumnEnumValueTable(const Atom *atom); virtual QString getLink(const Atom *atom, @@ -292,10 +285,6 @@ class HtmlGenerator : public PageGenerator NodeMap qmlClasses; QMap funcIndex; QMap legaleseTexts; - NewSinceMaps newSinceMaps; - static QString sinceTitles[]; - NewClassMaps newClassMaps; - NewClassMaps newQmlClassMaps; static int id; public: static bool debugging_on; diff --git a/tools/qdoc3/node.cpp b/tools/qdoc3/node.cpp index 683c210..87bbd93 100644 --- a/tools/qdoc3/node.cpp +++ b/tools/qdoc3/node.cpp @@ -157,6 +157,16 @@ void Node::setLink(LinkType linkType, const QString &link, const QString &desc) } /*! + Sets the information about the project and version a node was introduced + in. The string is simplified, removing excess whitespace before being + stored. +*/ +void Node::setSince(const QString &since) +{ + sinc = since.simplified(); +} + +/*! Returns a string representing the access specifier. */ QString Node::accessString() const diff --git a/tools/qdoc3/node.h b/tools/qdoc3/node.h index e1e9440..cb16bea 100644 --- a/tools/qdoc3/node.h +++ b/tools/qdoc3/node.h @@ -151,7 +151,7 @@ class Node void setDoc(const Doc& doc, bool replace = false); void setStatus(Status status) { sta = status; } void setThreadSafeness(ThreadSafeness safeness) { saf = safeness; } - void setSince(const QString &since) { sinc = since; } + void setSince(const QString &since); void setRelates(InnerNode* pseudoParent); void setModuleName(const QString &module) { mod = module; } void setLink(LinkType linkType, const QString &link, const QString &desc); -- cgit v0.12 From 01b3f508d1f7e9951baf60f487feadfa98ba4751 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Thu, 30 Jun 2011 19:13:55 +0200 Subject: Doc: Removed whitespace. --- doc/src/qt4-intro.qdoc | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/src/qt4-intro.qdoc b/doc/src/qt4-intro.qdoc index d75bdca..1547a7c 100644 --- a/doc/src/qt4-intro.qdoc +++ b/doc/src/qt4-intro.qdoc @@ -610,7 +610,6 @@ introduced in Qt 4.7. \sincelist 4.7 - */ /*! -- cgit v0.12 From 609dc22f719ecb8d48349fd56f84960bbf46d731 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Thu, 30 Jun 2011 19:14:30 +0200 Subject: Doc: Standardized on QtQuick for \since declarations. --- src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp | 4 ++-- src/declarative/graphicsitems/qdeclarativeborderimage.cpp | 4 ++-- src/declarative/graphicsitems/qdeclarativeflickable.cpp | 4 ++-- src/declarative/graphicsitems/qdeclarativegridview.cpp | 2 +- src/declarative/graphicsitems/qdeclarativeimage.cpp | 4 ++-- src/declarative/graphicsitems/qdeclarativeitem.cpp | 2 +- src/declarative/graphicsitems/qdeclarativelistview.cpp | 2 +- src/declarative/graphicsitems/qdeclarativemousearea.cpp | 2 +- src/declarative/graphicsitems/qdeclarativepositioners.cpp | 6 +++--- src/declarative/graphicsitems/qdeclarativerepeater.cpp | 6 +++--- src/declarative/graphicsitems/qdeclarativetext.cpp | 8 ++++---- src/declarative/graphicsitems/qdeclarativetextedit.cpp | 10 +++++----- src/declarative/graphicsitems/qdeclarativetextinput.cpp | 8 ++++---- 13 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp b/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp index b7fcbb5..fb1bdf6 100644 --- a/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp @@ -88,7 +88,7 @@ QT_BEGIN_NAMESPACE /*! \qmlproperty bool AnimatedImage::cache - \since Quick 1.1 + \since QtQuick 1.1 Specifies whether the image should be cached. The default value is true. Setting \a cache to false is useful when dealing with large images, @@ -97,7 +97,7 @@ QT_BEGIN_NAMESPACE /*! \qmlproperty bool AnimatedImage::mirror - \since Quick 1.1 + \since QtQuick 1.1 This property holds whether the image should be horizontally inverted (effectively displaying a mirrored image). diff --git a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp index 836ad49..bd6405c 100644 --- a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp @@ -215,7 +215,7 @@ QDeclarativeBorderImage::~QDeclarativeBorderImage() /*! \qmlproperty bool BorderImage::cache - \since Quick 1.1 + \since QtQuick 1.1 Specifies whether the image should be cached. The default value is true. Setting \a cache to false is useful when dealing with large images, @@ -224,7 +224,7 @@ QDeclarativeBorderImage::~QDeclarativeBorderImage() /*! \qmlproperty bool BorderImage::mirror - \since Quick 1.1 + \since QtQuick 1.1 This property holds whether the image should be horizontally inverted (effectively displaying a mirrored image). diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp index 4a465cc..93af16f 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp @@ -1414,7 +1414,7 @@ void QDeclarativeFlickable::setContentHeight(qreal h) /*! \qmlmethod Flickable::resizeContent(real width, real height, QPointF center) \preliminary - \since Quick 1.1 + \since QtQuick 1.1 Resizes the content to \a width x \a height about \a center. @@ -1454,7 +1454,7 @@ void QDeclarativeFlickable::resizeContent(qreal w, qreal h, QPointF center) /*! \qmlmethod Flickable::returnToBounds() \preliminary - \since Quick 1.1 + \since QtQuick 1.1 Ensures the content is within legal bounds. diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index afc3eac..5da3f77 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -2584,7 +2584,7 @@ void QDeclarativeGridView::positionViewAtIndex(int index, int mode) /*! \qmlmethod GridView::positionViewAtBeginning() \qmlmethod GridView::positionViewAtEnd() - \since Quick 1.1 + \since QtQuick 1.1 Positions the view at the beginning or end, taking into account any header or footer. diff --git a/src/declarative/graphicsitems/qdeclarativeimage.cpp b/src/declarative/graphicsitems/qdeclarativeimage.cpp index e6bb798..9b9d680 100644 --- a/src/declarative/graphicsitems/qdeclarativeimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeimage.cpp @@ -473,7 +473,7 @@ QRectF QDeclarativeImage::boundingRect() const /*! \qmlproperty bool Image::cache - \since Quick 1.1 + \since QtQuick 1.1 Specifies whether the image should be cached. The default value is true. Setting \a cache to false is useful when dealing with large images, @@ -482,7 +482,7 @@ QRectF QDeclarativeImage::boundingRect() const /*! \qmlproperty bool Image::mirror - \since Quick 1.1 + \since QtQuick 1.1 This property holds whether the image should be horizontally inverted (effectively displaying a mirrored image). diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp index ccf0de0..ee2d19d 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp @@ -3444,7 +3444,7 @@ qreal QDeclarativeItem::implicitHeight() const /*! \qmlproperty real Item::implicitWidth \qmlproperty real Item::implicitHeight - \since Quick 1.1 + \since QtQuick 1.1 Defines the natural width or height of the Item if no \l width or \l height is specified. diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 8695bc6..16a76e2 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -3007,7 +3007,7 @@ void QDeclarativeListView::positionViewAtIndex(int index, int mode) /*! \qmlmethod ListView::positionViewAtBeginning() \qmlmethod ListView::positionViewAtEnd() - \since Quick 1.1 + \since QtQuick 1.1 Positions the view at the beginning or end, taking into account any header or footer. diff --git a/src/declarative/graphicsitems/qdeclarativemousearea.cpp b/src/declarative/graphicsitems/qdeclarativemousearea.cpp index 18f008a..0e06a4c 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea.cpp +++ b/src/declarative/graphicsitems/qdeclarativemousearea.cpp @@ -419,7 +419,7 @@ void QDeclarativeMouseArea::setEnabled(bool a) /*! \qmlproperty bool MouseArea::preventStealing - \since Quick 1.1 + \since QtQuick 1.1 This property holds whether the mouse events may be stolen from this MouseArea. diff --git a/src/declarative/graphicsitems/qdeclarativepositioners.cpp b/src/declarative/graphicsitems/qdeclarativepositioners.cpp index f3d1a68..483cad4 100644 --- a/src/declarative/graphicsitems/qdeclarativepositioners.cpp +++ b/src/declarative/graphicsitems/qdeclarativepositioners.cpp @@ -584,7 +584,7 @@ QDeclarativeRow::QDeclarativeRow(QDeclarativeItem *parent) /*! \qmlproperty enumeration Row::layoutDirection - \since Quick 1.1 + \since QtQuick 1.1 This property holds the layoutDirection of the row. @@ -878,7 +878,7 @@ void QDeclarativeGrid::setFlow(Flow flow) /*! \qmlproperty enumeration Grid::layoutDirection - \since Quick 1.1 + \since QtQuick 1.1 This property holds the layout direction of the layout. @@ -1236,7 +1236,7 @@ void QDeclarativeFlow::setFlow(Flow flow) /*! \qmlproperty enumeration Flow::layoutDirection - \since Quick 1.1 + \since QtQuick 1.1 This property holds the layout direction of the layout. diff --git a/src/declarative/graphicsitems/qdeclarativerepeater.cpp b/src/declarative/graphicsitems/qdeclarativerepeater.cpp index 813c255..e881b96 100644 --- a/src/declarative/graphicsitems/qdeclarativerepeater.cpp +++ b/src/declarative/graphicsitems/qdeclarativerepeater.cpp @@ -128,7 +128,7 @@ QDeclarativeRepeaterPrivate::~QDeclarativeRepeaterPrivate() /*! \qmlsignal Repeater::onItemAdded(int index, Item item) - \since Quick 1.1 + \since QtQuick 1.1 This handler is called when an item is added to the repeater. The \a index parameter holds the index at which the item has been inserted within the @@ -137,7 +137,7 @@ QDeclarativeRepeaterPrivate::~QDeclarativeRepeaterPrivate() /*! \qmlsignal Repeater::onItemRemoved(int index, Item item) - \since Quick 1.1 + \since QtQuick 1.1 This handler is called when an item is removed from the repeater. The \a index parameter holds the index at which the item was removed from the repeater, @@ -306,7 +306,7 @@ int QDeclarativeRepeater::count() const /*! \qmlmethod Item Repeater::itemAt(index) - \since Quick 1.1 + \since QtQuick 1.1 Returns the \l Item that has been created at the given \a index, or \c null if no item exists at \a index. diff --git a/src/declarative/graphicsitems/qdeclarativetext.cpp b/src/declarative/graphicsitems/qdeclarativetext.cpp index 91c12d2..6d1b15d 100644 --- a/src/declarative/graphicsitems/qdeclarativetext.cpp +++ b/src/declarative/graphicsitems/qdeclarativetext.cpp @@ -1213,7 +1213,7 @@ void QDeclarativeText::setWrapMode(WrapMode mode) /*! \qmlproperty int Text::lineCount - \since Quick 1.1 + \since QtQuick 1.1 Returns the number of lines visible in the text item. @@ -1229,7 +1229,7 @@ int QDeclarativeText::lineCount() const /*! \qmlproperty bool Text::truncated - \since Quick 1.1 + \since QtQuick 1.1 Returns true if the text has been truncated due to \l maximumLineCount or \l elide. @@ -1246,7 +1246,7 @@ bool QDeclarativeText::truncated() const /*! \qmlproperty int Text::maximumLineCount - \since Quick 1.1 + \since QtQuick 1.1 Set this property to limit the number of lines that the text item will show. If elide is set to Text.ElideRight, the text will be elided appropriately. @@ -1480,7 +1480,7 @@ qreal QDeclarativeText::paintedHeight() const /*! \qmlproperty real Text::lineHeight - \since Quick 1.1 + \since QtQuick 1.1 Sets the line height for the text. The value can be in pixels or a multiplier depending on lineHeightMode. diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp index 42c520c..15a3cae 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp @@ -107,7 +107,7 @@ TextEdit { /*! \qmlsignal TextEdit::onLinkActivated(string link) - \since Quick 1.1 + \since QtQuick 1.1 This handler is called when the user clicks on a link embedded in the text. The link must be in rich text or HTML format and the @@ -616,7 +616,7 @@ void QDeclarativeTextEdit::setWrapMode(WrapMode mode) /*! \qmlproperty int TextEdit::lineCount - \since Quick 1.1 + \since QtQuick 1.1 Returns the total number of lines in the textEdit item. */ @@ -710,7 +710,7 @@ void QDeclarativeTextEdit::moveCursorSelection(int pos) /*! \qmlmethod void TextEdit::moveCursorSelection(int position, SelectionMode mode = TextEdit.SelectCharacters) - \since Quick 1.1 + \since QtQuick 1.1 Moves the cursor to \a position and updates the selection according to the optional \a mode parameter. (To only move the cursor, set the \l cursorPosition property.) @@ -1075,7 +1075,7 @@ void QDeclarativeTextEdit::setSelectByMouse(bool on) /*! \qmlproperty enum TextEdit::mouseSelectionMode - \since Quick 1.1 + \since QtQuick 1.1 Specifies how text should be selected using a mouse. @@ -1221,7 +1221,7 @@ void QDeclarativeTextEditPrivate::focusChanged(bool hasFocus) /*! \qmlmethod void TextEdit::deselect() - \since Quick 1.1 + \since QtQuick 1.1 Removes active text selection. */ diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index c59c919..1c64464 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -1014,7 +1014,7 @@ int QDeclarativeTextInput::positionAt(int x) const /*! \qmlmethod int TextInput::positionAt(int x, CursorPosition position = CursorBetweenCharacters) - \since Quick 1.1 + \since QtQuick 1.1 This function returns the character position at x pixels from the left of the textInput. Position 0 is before the @@ -1402,7 +1402,7 @@ QVariant QDeclarativeTextInput::inputMethodQuery(Qt::InputMethodQuery property) /*! \qmlmethod void TextInput::deselect() - \since Quick 1.1 + \since QtQuick 1.1 Removes active text selection. */ @@ -1574,7 +1574,7 @@ void QDeclarativeTextInput::setSelectByMouse(bool on) /*! \qmlproperty enum TextInput::mouseSelectionMode - \since Quick 1.1 + \since QtQuick 1.1 Specifies how text should be selected using a mouse. @@ -1622,7 +1622,7 @@ void QDeclarativeTextInput::moveCursorSelection(int position) /*! \qmlmethod void TextInput::moveCursorSelection(int position, SelectionMode mode = TextInput.SelectCharacters) - \since Quick 1.1 + \since QtQuick 1.1 Moves the cursor to \a position and updates the selection according to the optional \a mode parameter. (To only move the cursor, set the \l cursorPosition property.) -- cgit v0.12 From 358e018dbb4b4dbdbfc702a6d462f113a1357e1e Mon Sep 17 00:00:00 2001 From: David Boddie Date: Thu, 30 Jun 2011 19:16:21 +0200 Subject: Doc: Fixed \since declarations. --- src/gui/kernel/qkeysequence.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index f8e4e57..8635bf2 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -934,7 +934,7 @@ QKeySequence::QKeySequence(const QString &key) } /*! - \since 4.x + \since 4.7 Creates a key sequence from the \a key string based on \a format. */ QKeySequence::QKeySequence(const QString &key, QKeySequence::SequenceFormat format) @@ -1131,7 +1131,7 @@ int QKeySequence::assign(const QString &ks) /*! \fn int QKeySequence::assign(const QString &keys, QKeySequence::SequenceFormat format) - \since 4.x + \since 4.7 Adds the given \a keys to the key sequence (based on \a format). \a keys may contain up to four key codes, provided they are -- cgit v0.12 From 86608d537eabc3cf7e1d1ddd1d0a2f90ccc2de2a Mon Sep 17 00:00:00 2001 From: David Boddie Date: Thu, 30 Jun 2011 20:48:32 +0200 Subject: Doc: Clarified the range of return values from QLineF::angle(). Task-number: QTBUG-20197 --- src/corelib/tools/qline.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qline.cpp b/src/corelib/tools/qline.cpp index af3b7d5..0f67652 100644 --- a/src/corelib/tools/qline.cpp +++ b/src/corelib/tools/qline.cpp @@ -564,8 +564,9 @@ qreal QLineF::length() const Returns the angle of the line in degrees. - Positive values for the angles mean counter-clockwise while negative values - mean the clockwise direction. Zero degrees is at the 3 o'clock position. + The return value will be in the range of values from 0.0 up to but not + including 360.0. The angles are measured counter-clockwise from a point + on the x-axis to the right of the origin (x > 0). \sa setAngle() */ -- cgit v0.12 From ea0cb7ad2066d9c3dc695ab2ebe724249b05ca0f Mon Sep 17 00:00:00 2001 From: Ademar de Souza Reis Jr Date: Tue, 9 Aug 2011 17:04:35 -0300 Subject: Updated WebKit to 66b76cdb8ef823f27a8229c5cae2d35e7f2d3c59 Signed-off-by: Ademar de Souza Reis Jr --- src/3rdparty/webkit/.tag | 2 +- src/3rdparty/webkit/ChangeLog | 13 + .../webkit/Source/JavaScriptCore/ChangeLog | 157 + .../Source/JavaScriptCore/JavaScriptCore.pri | 2 +- src/3rdparty/webkit/Source/JavaScriptCore/jsc.cpp | 2 +- .../Source/JavaScriptCore/parser/JSParser.cpp | 63 +- .../Source/JavaScriptCore/runtime/JSONObject.cpp | 53 + .../webkit/Source/JavaScriptCore/wtf/ByteArray.h | 2 +- .../webkit/Source/JavaScriptCore/wtf/DateMath.cpp | 2 +- .../webkit/Source/JavaScriptCore/wtf/NullPtr.h | 2 +- .../JavaScriptCore/wtf/PageAllocatorSymbian.h | 2 +- .../webkit/Source/JavaScriptCore/wtf/Platform.h | 12 +- .../Source/JavaScriptCore/wtf/StackBounds.cpp | 6 +- .../Source/JavaScriptCore/wtf/text/AtomicString.h | 31 + .../JavaScriptCore/wtf/text/StringStatics.cpp | 31 +- .../webkit/Source/JavaScriptCore/wtf/wtf.pri | 10 +- .../webkit/Source/JavaScriptCore/yarr/YarrJIT.cpp | 3112 ++++++++++---------- .../Source/ThirdParty/gtest/codegear/gtest.cbproj | 274 +- .../ThirdParty/gtest/codegear/gtest.groupproj | 106 +- .../Source/ThirdParty/gtest/codegear/gtest_all.cc | 76 +- .../Source/ThirdParty/gtest/codegear/gtest_link.cc | 80 +- .../ThirdParty/gtest/codegear/gtest_main.cbproj | 164 +- .../gtest/codegear/gtest_unittest.cbproj | 174 +- src/3rdparty/webkit/Source/ThirdParty/gyp/gyp.bat | 10 +- .../Source/ThirdParty/gyp/samples/samples.bat | 10 +- .../ThirdParty/gyp/test/actions/gyptest-errors.py | 40 +- .../gyp/test/actions/src/subdir1/program.c | 24 +- .../actions/subdir1/actions-out/README.txt | 8 +- .../generator-output/actions/subdir1/program.c | 24 +- .../actions/subdir2/actions-out/README.txt | 8 +- .../rules/subdir2/rules-out/README.txt | 8 +- .../Source/ThirdParty/gyp/tools/pretty_gyp.py | 284 +- src/3rdparty/webkit/Source/WebCore/ChangeLog | 746 ++++- src/3rdparty/webkit/Source/WebCore/WebCore.exp.in | 8 + src/3rdparty/webkit/Source/WebCore/WebCore.pri | 12 +- src/3rdparty/webkit/Source/WebCore/WebCore.pro | 34 +- .../WebCore/bindings/generic/ActiveDOMCallback.cpp | 46 +- .../Source/WebCore/bindings/js/JSExceptionBase.h | 86 +- .../webkit/Source/WebCore/css/CSSStyleSelector.h | 2 +- .../webkit/Source/WebCore/css/CSSStyleSheet.cpp | 4 +- src/3rdparty/webkit/Source/WebCore/dom/Document.h | 2 +- src/3rdparty/webkit/Source/WebCore/dom/Element.cpp | 6 + src/3rdparty/webkit/Source/WebCore/dom/Range.cpp | 37 +- .../WebCore/editing/ReplaceSelectionCommand.cpp | 2 +- .../webkit/Source/WebCore/editing/TextIterator.cpp | 3 + src/3rdparty/webkit/Source/WebCore/features.pri | 24 +- .../webkit/Source/WebCore/generated/CSSGrammar.cpp | 1413 +++++---- .../webkit/Source/WebCore/generated/CSSGrammar.h | 14 +- .../Source/WebCore/generated/CSSPropertyNames.cpp | 2 +- .../Source/WebCore/generated/CSSValueKeywords.cpp | 2 +- .../webkit/Source/WebCore/generated/ColorData.cpp | 2 +- .../Source/WebCore/generated/DocTypeStrings.cpp | 2 +- .../WebCore/generated/JSWebGLRenderingContext.cpp | 76 + .../Source/WebCore/generated/XPathGrammar.cpp | 637 ++-- .../webkit/Source/WebCore/generated/XPathGrammar.h | 14 +- .../Source/WebCore/html/HTMLSourceElement.cpp | 6 +- .../Source/WebCore/html/HTMLTrackElement.cpp | 6 +- .../WebCore/html/shadow/MediaControlElements.cpp | 2 +- .../Source/WebCore/inspector/InspectorValues.cpp | 13 +- .../webkit/Source/WebCore/loader/FrameLoader.cpp | 27 +- .../webkit/Source/WebCore/loader/FrameLoader.h | 2 +- .../Source/WebCore/loader/cache/CachedResource.cpp | 5 +- .../webkit/Source/WebCore/make-hash-tools.pl | 15 +- .../webkit/Source/WebCore/page/DOMWindow.cpp | 10 +- .../webkit/Source/WebCore/page/FrameView.cpp | 2 +- .../webkit/Source/WebCore/page/Geolocation.cpp | 3 + .../webkit/Source/WebCore/page/Geolocation.h | 2 +- .../webkit/Source/WebCore/page/PrintContext.cpp | 7 + .../webkit/Source/WebCore/page/PrintContext.h | 4 + .../graphics/gstreamer/PlatformVideoWindowQt.cpp | 4 +- .../WebCore/platform/graphics/mac/FontCacheMac.mm | 15 +- .../WebCore/platform/mac/WebCoreSystemInterface.h | 20 + .../WebCore/platform/mac/WebCoreSystemInterface.mm | 4 + .../platform/mac/WebVideoFullscreenController.h | 72 + .../platform/mac/WebVideoFullscreenController.mm | 617 ++++ .../mac/WebVideoFullscreenHUDWindowController.h | 66 + .../mac/WebVideoFullscreenHUDWindowController.mm | 679 +++++ .../WebCore/platform/mac/WebWindowAnimation.h | 59 + .../WebCore/platform/mac/WebWindowAnimation.mm | 234 ++ .../WebCore/platform/network/HTTPHeaderMap.cpp | 12 + .../WebCore/platform/qt/WebCoreSystemInterface.h | 10 + .../WebCore/platform/qt/WebCoreSystemInterface.mm | 4 + .../webkit/Source/WebCore/plugins/PluginView.cpp | 5 +- .../Source/WebCore/rendering/RenderBlock.cpp | 2 +- .../WebCore/rendering/RenderBlockLineLayout.cpp | 2 +- .../webkit/Source/WebCore/rendering/RenderBox.cpp | 2 +- .../webkit/Source/WebCore/rendering/RenderBox.h | 2 + .../Source/WebCore/rendering/RenderFlexibleBox.cpp | 4 +- .../Source/WebCore/rendering/RenderIFrame.cpp | 5 +- .../Source/WebCore/rendering/RenderInline.cpp | 19 +- .../Source/WebCore/rendering/RenderLineBoxList.cpp | 15 +- .../webkit/Source/WebCore/rendering/RenderObject.h | 3 + .../Source/WebCore/rendering/RenderReplaced.cpp | 8 + .../Source/WebCore/rendering/RenderReplaced.h | 2 + .../Source/WebCore/rendering/RenderThemeWinCE.cpp | 2 +- .../Source/WebCore/rendering/RenderWidget.cpp | 4 + .../WebCore/rendering/svg/RenderSVGInline.cpp | 3 + .../WebCore/rendering/svg/SVGInlineFlowBox.cpp | 5 +- .../svg/SVGTextLayoutAttributesBuilder.cpp | 8 +- .../webkit/Source/WebCore/storage/IDBRequest.cpp | 7 +- .../Source/WebCore/svg/SVGElementInstance.cpp | 9 +- .../webkit/Source/WebCore/svg/SVGElementInstance.h | 1 + .../Source/WebCore/svg/SVGTextContentElement.cpp | 12 + .../Source/WebCore/svg/SVGTextContentElement.h | 1 + .../WebCore/svg/SVGTextPositioningElement.cpp | 38 +- .../Source/WebCore/svg/SVGTextPositioningElement.h | 1 - .../webkit/Source/WebCore/svg/SVGUseElement.cpp | 1 + .../webkit/Source/WebCore/xml/XPathFunctions.cpp | 30 +- .../webkit/Source/WebCore/xml/XPathPredicate.cpp | 16 +- .../webkit/Source/WebCore/xml/XPathResult.cpp | 8 +- src/3rdparty/webkit/Source/WebKit.pri | 1 + src/3rdparty/webkit/Source/WebKit/ChangeLog | 26 + .../webkit/Source/WebKit/qt/Api/qwebframe.cpp | 6 +- .../webkit/Source/WebKit/qt/Api/qwebview.cpp | 2 +- src/3rdparty/webkit/Source/WebKit/qt/ChangeLog | 249 ++ src/3rdparty/webkit/Source/WebKit/qt/QtWebKit.pro | 26 +- .../WebKit/qt/WebCoreSupport/ChromeClientQt.cpp | 15 +- .../WebKit/qt/WebCoreSupport/ChromeClientQt.h | 5 +- .../qt/WebCoreSupport/FrameLoaderClientQt.cpp | 130 +- .../WebKit/qt/WebCoreSupport/FrameLoaderClientQt.h | 10 +- .../WebKit/qt/WebCoreSupport/FullScreenVideoQt.cpp | 25 +- .../WebKit/qt/WebCoreSupport/FullScreenVideoQt.h | 6 + .../WebCoreSupport/QTKitFullScreenVideoHandler.h | 44 + .../WebCoreSupport/QTKitFullScreenVideoHandler.mm | 68 + .../WebKit/qt/WebCoreSupport/WebSystemInterface.mm | 4 + .../WebKit/qt/declarative/qdeclarativewebview.cpp | 2 + .../Source/WebKit/qt/symbian/bwins/QtWebKitu.def | 178 +- .../Source/WebKit/qt/symbian/eabi/QtWebKitu.def | 1727 +++++------ .../symbian/platformplugin/qss/OverlayWidget.qss | 116 +- .../MIMESniffing/resources/application_postscript | 272 +- .../qt/tests/MIMESniffing/resources/text_xml | 38 +- .../qt/tests/qwebframe/resources/testiframe.html | 104 +- .../qt/tests/qwebframe/resources/testiframe2.html | 38 +- .../WebKit/qt/tests/qwebframe/tst_qwebframe.cpp | 190 +- .../WebKit/qt/tests/qwebpage/tst_qwebpage.cpp | 30 + src/3rdparty/webkit/Source/WebKit2/ChangeLog | 27 + src/3rdparty/webkit/Source/WebKit2/WebKit2.pri | 2 +- .../WebKit2/WebProcess/Plugins/PluginView.cpp | 5 +- src/3rdparty/webkit/VERSION | 2 +- 139 files changed, 8670 insertions(+), 4759 deletions(-) create mode 100644 src/3rdparty/webkit/Source/WebCore/platform/mac/WebVideoFullscreenController.h create mode 100644 src/3rdparty/webkit/Source/WebCore/platform/mac/WebVideoFullscreenController.mm create mode 100644 src/3rdparty/webkit/Source/WebCore/platform/mac/WebVideoFullscreenHUDWindowController.h create mode 100644 src/3rdparty/webkit/Source/WebCore/platform/mac/WebVideoFullscreenHUDWindowController.mm create mode 100644 src/3rdparty/webkit/Source/WebCore/platform/mac/WebWindowAnimation.h create mode 100644 src/3rdparty/webkit/Source/WebCore/platform/mac/WebWindowAnimation.mm create mode 100644 src/3rdparty/webkit/Source/WebKit/qt/WebCoreSupport/QTKitFullScreenVideoHandler.h create mode 100644 src/3rdparty/webkit/Source/WebKit/qt/WebCoreSupport/QTKitFullScreenVideoHandler.mm diff --git a/src/3rdparty/webkit/.tag b/src/3rdparty/webkit/.tag index f786b78..2b42a20 100644 --- a/src/3rdparty/webkit/.tag +++ b/src/3rdparty/webkit/.tag @@ -1 +1 @@ -a52dbae362a295e0adfb7ee4fdc21734ae4b7b45 +66b76cdb8ef823f27a8229c5cae2d35e7f2d3c59 diff --git a/src/3rdparty/webkit/ChangeLog b/src/3rdparty/webkit/ChangeLog index 96ef591..bc11b4d 100644 --- a/src/3rdparty/webkit/ChangeLog +++ b/src/3rdparty/webkit/ChangeLog @@ -1,3 +1,16 @@ +2011-08-06 Aron Rosenberg + + Reviewed by Benjamin Poulain. + + [Qt] Fix build with Intel compiler on Windows + https://bugs.webkit.org/show_bug.cgi?id=65088 + + Disable Intel Compiler warning 873 - function "" has no corresponding operator + delete (to be called if an exception is thrown during initialization of an + allocated object). + + * Source/WebKit.pri: + 2011-06-27 Alexis Menard Reviewed by Kenneth Rohde Christiansen. diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/ChangeLog b/src/3rdparty/webkit/Source/JavaScriptCore/ChangeLog index ae7ef60..3cc612a 100644 --- a/src/3rdparty/webkit/Source/JavaScriptCore/ChangeLog +++ b/src/3rdparty/webkit/Source/JavaScriptCore/ChangeLog @@ -1,3 +1,160 @@ +2011-08-06 Aron Rosenberg + + Reviewed by Benjamin Poulain. + + [Qt] Fix build with Intel compiler on Windows + https://bugs.webkit.org/show_bug.cgi?id=65088 + + Intel compiler needs .lib suffixes instead of .a + Intel compiler doesn't support nullptr + Intel compiler supports unsized arrays + + * JavaScriptCore.pri: + * jsc.cpp: + * wtf/ByteArray.h: + * wtf/NullPtr.h: + +2011-05-15 Gavin Barraclough + + Reviewed by Geoff Garen & Michael Saboff. + + https://bugs.webkit.org/show_bug.cgi?id=60860 + Simplify backtracking in YARR JIT + + YARR JIT currently performs a single pass of code generation over the pattern, + with special handling to allow the code generation for some backtracking code + out of line. We can simplify things by moving to a common mechanism whereby all + forwards matching code is generated in one pass, and all backtracking code is + generated in another. Backtracking code can be generated in reverse order, to + optimized the common fall-through case. + + To make it easier to walk over the pattern, we can first convert to a more + byte-code like format before JIT generating. In time we should unify this with + the YARR interpreter to more closely unify the two. + + * yarr/YarrJIT.cpp: + (JSC::Yarr::YarrGenerator::jumpIfNoAvailableInput): + (JSC::Yarr::YarrGenerator::YarrOp::YarrOp): + (JSC::Yarr::YarrGenerator::BacktrackingState::BacktrackingState): + (JSC::Yarr::YarrGenerator::BacktrackingState::append): + (JSC::Yarr::YarrGenerator::BacktrackingState::fallthrough): + (JSC::Yarr::YarrGenerator::BacktrackingState::link): + (JSC::Yarr::YarrGenerator::BacktrackingState::linkTo): + (JSC::Yarr::YarrGenerator::BacktrackingState::takeBacktracksToJumpList): + (JSC::Yarr::YarrGenerator::BacktrackingState::isEmpty): + (JSC::Yarr::YarrGenerator::BacktrackingState::linkDataLabels): + (JSC::Yarr::YarrGenerator::BacktrackingState::ReturnAddressRecord::ReturnAddressRecord): + (JSC::Yarr::YarrGenerator::generateAssertionBOL): + (JSC::Yarr::YarrGenerator::backtrackAssertionBOL): + (JSC::Yarr::YarrGenerator::generateAssertionEOL): + (JSC::Yarr::YarrGenerator::backtrackAssertionEOL): + (JSC::Yarr::YarrGenerator::matchAssertionWordchar): + (JSC::Yarr::YarrGenerator::generateAssertionWordBoundary): + (JSC::Yarr::YarrGenerator::backtrackAssertionWordBoundary): + (JSC::Yarr::YarrGenerator::generatePatternCharacterOnce): + (JSC::Yarr::YarrGenerator::backtrackPatternCharacterOnce): + (JSC::Yarr::YarrGenerator::generatePatternCharacterFixed): + (JSC::Yarr::YarrGenerator::backtrackPatternCharacterFixed): + (JSC::Yarr::YarrGenerator::generatePatternCharacterGreedy): + (JSC::Yarr::YarrGenerator::backtrackPatternCharacterGreedy): + (JSC::Yarr::YarrGenerator::generatePatternCharacterNonGreedy): + (JSC::Yarr::YarrGenerator::backtrackPatternCharacterNonGreedy): + (JSC::Yarr::YarrGenerator::generateCharacterClassOnce): + (JSC::Yarr::YarrGenerator::backtrackCharacterClassOnce): + (JSC::Yarr::YarrGenerator::generateCharacterClassFixed): + (JSC::Yarr::YarrGenerator::backtrackCharacterClassFixed): + (JSC::Yarr::YarrGenerator::generateCharacterClassGreedy): + (JSC::Yarr::YarrGenerator::backtrackCharacterClassGreedy): + (JSC::Yarr::YarrGenerator::generateCharacterClassNonGreedy): + (JSC::Yarr::YarrGenerator::backtrackCharacterClassNonGreedy): + (JSC::Yarr::YarrGenerator::generateTerm): + (JSC::Yarr::YarrGenerator::backtrackTerm): + (JSC::Yarr::YarrGenerator::generate): + (JSC::Yarr::YarrGenerator::backtrack): + (JSC::Yarr::YarrGenerator::opCompileParenthesesSubpattern): + (JSC::Yarr::YarrGenerator::opCompileParentheticalAssertion): + (JSC::Yarr::YarrGenerator::opCompileAlternative): + (JSC::Yarr::YarrGenerator::opCompileBody): + (JSC::Yarr::YarrGenerator::YarrGenerator): + (JSC::Yarr::YarrGenerator::compile): + +2011-06-08 Mikołaj Małecki + + Reviewed by Pavel Feldman. + + Web Inspector: Crash by buffer overrun crash when serializing inspector object tree. + https://bugs.webkit.org/show_bug.cgi?id=52791 + + No new tests. The problem can be reproduced by trying to create InspectorValue + from 1.0e-100 and call ->toJSONString() on this. + + * JavaScriptCore.exp: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + export 2 functions DecimalNumber::bufferLengthForStringExponential and + DecimalNumber::toStringExponential. + +2011-07-26 Alexis Menard + + Unreviewed build fix for Qt/Linux. + + On platforms with no glib and gstreamer we should not build javascriptcore + with the Glib support. This is related to http://trac.webkit.org/changeset/91752. + + * wtf/wtf.pri: + +2011-07-26 Alexis Menard + + Reviewed by Andreas Kling. + + [Qt] Change default backend to use GStreamer on Linux and QuickTime on Mac. + https://bugs.webkit.org/show_bug.cgi?id=63472 + + Enable the bits needed for GStreamer only when QtMultimedia is not used. + + * wtf/wtf.pri: + +2011-07-12 Hui Huang + + Reviewed by Laszlo Gombos. + + [Qt] Fix compiling errors with QtWebkit 2.2 WINSCW build. + https://bugs.webkit.org/show_bug.cgi?id=64391 + + (QtWebKit-2.2 only, patch not in webkit trunk) + + * parser/JSParser.cpp: + * runtime/JSONObject.cpp: + * wtf/PageAllocatorSymbian.h: + * wtf/Platform.h: + * wtf/text/AtomicString.h: + * wtf/text/StringStatics.cpp: + + +2011-07-13 Ademar de Souza Reis Jr. + + Reviewed by Andreas Kling. + + Broken build on QNX + https://bugs.webkit.org/show_bug.cgi?id=63717 + + QNX doesn't support pthread's SA_RESTART (required by + JSC_MULTIPLE_THREADS), JIT is broken at runtime and there a + few minor compilation errors here and there. + + Original patch by Ritt Konstantin , also + tested by him on QNX v6.5 (x86) + + * wtf/DateMath.cpp: fix usage of abs/labs + * wtf/Platform.h: Disable JIT and JSC_MULTIPLE_THREADS + * wtf/StackBounds.cpp: Add a couple of missing includes (and sort them) + +2011-07-09 Thouraya Andolsi + + Fix unaligned userspace access for SH4 platforms. + https://bugs.webkit.org/show_bug.cgi?id=62993 + + * wtf/Platform.h: + 2011-05-23 Matthew Delaney Reviewed by Simon Fraser. diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/JavaScriptCore.pri b/src/3rdparty/webkit/Source/JavaScriptCore/JavaScriptCore.pri index f6d064f..d8290cf 100644 --- a/src/3rdparty/webkit/Source/JavaScriptCore/JavaScriptCore.pri +++ b/src/3rdparty/webkit/Source/JavaScriptCore/JavaScriptCore.pri @@ -73,7 +73,7 @@ defineTest(prependJavaScriptCoreLib) { # Argument is the relative path to JavaScriptCore.pro's qmake output pathToJavaScriptCoreOutput = $$ARGS/$$JAVASCRIPTCORE_DESTDIR - win32-msvc*|wince* { + win32-msvc*|wince*|win32-icc { LIBS = -l$$JAVASCRIPTCORE_TARGET $$LIBS LIBS = -L$$pathToJavaScriptCoreOutput $$LIBS POST_TARGETDEPS += $${pathToJavaScriptCoreOutput}$${QMAKE_DIR_SEP}$${JAVASCRIPTCORE_TARGET}.lib diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/jsc.cpp b/src/3rdparty/webkit/Source/JavaScriptCore/jsc.cpp index 6ef8e18..5f63749 100644 --- a/src/3rdparty/webkit/Source/JavaScriptCore/jsc.cpp +++ b/src/3rdparty/webkit/Source/JavaScriptCore/jsc.cpp @@ -312,7 +312,7 @@ EncodedJSValue JSC_HOST_CALL functionQuit(ExecState* exec) // be in a separate main function because the jscmain function requires object // unwinding. -#if COMPILER(MSVC) && !defined(_DEBUG) && !OS(WINCE) +#if COMPILER(MSVC) && !COMPILER(INTEL) && !defined(_DEBUG) && !OS(WINCE) #define TRY __try { #define EXCEPT(x) } __except (EXCEPTION_EXECUTE_HANDLER) { x; } #else diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/parser/JSParser.cpp b/src/3rdparty/webkit/Source/JavaScriptCore/parser/JSParser.cpp index f36c668..5f6d8cf 100644 --- a/src/3rdparty/webkit/Source/JavaScriptCore/parser/JSParser.cpp +++ b/src/3rdparty/webkit/Source/JavaScriptCore/parser/JSParser.cpp @@ -215,13 +215,21 @@ private: template ALWAYS_INLINE TreeExpression parseObjectLiteral(TreeBuilder&); template ALWAYS_INLINE TreeExpression parseStrictObjectLiteral(TreeBuilder&); template ALWAYS_INLINE TreeArguments parseArguments(TreeBuilder&); +#if COMPILER(WINSCW) + template ALWAYS_INLINE TreeProperty parseProperty(bool, TreeBuilder&); +#else template ALWAYS_INLINE TreeProperty parseProperty(TreeBuilder&); +#endif template ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&); template ALWAYS_INLINE TreeFormalParameterList parseFormalParameters(TreeBuilder&); template ALWAYS_INLINE TreeExpression parseVarDeclarationList(TreeBuilder&, int& declarations, const Identifier*& lastIdent, TreeExpression& lastInitializer, int& identStart, int& initStart, int& initEnd); template ALWAYS_INLINE TreeConstDeclList parseConstDeclarationList(TreeBuilder& context); enum FunctionRequirements { FunctionNoRequirements, FunctionNeedsName }; +#if COMPILER(WINSCW) + template bool parseFunctionInfo(FunctionRequirements, bool, TreeBuilder&, const Identifier*&, TreeFormalParameterList&, TreeFunctionBody&, int& openBrace, int& closeBrace, int& bodyStartLine); +#else template bool parseFunctionInfo(TreeBuilder&, const Identifier*&, TreeFormalParameterList&, TreeFunctionBody&, int& openBrace, int& closeBrace, int& bodyStartLine); +#endif ALWAYS_INLINE int isBinaryOperator(JSTokenType token); bool allowAutomaticSemicolon(); @@ -1290,7 +1298,11 @@ template TreeFunctionBody JSParser::parseFunctionBody(TreeBu return context.createFunctionBody(strictMode()); } +#if COMPILER(WINSCW) +template bool JSParser::parseFunctionInfo(JSParser::FunctionRequirements requirements, bool nameIsInContainingScope, TreeBuilder& context, const Identifier*& name, TreeFormalParameterList& parameters, TreeFunctionBody& body, int& openBracePos, int& closeBracePos, int& bodyStartLine) +#else template bool JSParser::parseFunctionInfo(TreeBuilder& context, const Identifier*& name, TreeFormalParameterList& parameters, TreeFunctionBody& body, int& openBracePos, int& closeBracePos, int& bodyStartLine) +#endif { AutoPopScopeRef functionScope(this, pushScope()); functionScope->setIsFunction(); @@ -1371,7 +1383,11 @@ template TreeStatement JSParser::parseFunctionDeclaration(Tr int openBracePos = 0; int closeBracePos = 0; int bodyStartLine = 0; +#if COMPILER(WINSCW) + failIfFalse((parseFunctionInfo(FunctionNeedsName, true, context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine))); +#else failIfFalse((parseFunctionInfo(context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine))); +#endif failIfFalse(name); failIfFalseIfStrict(declareVariable(name)); return context.createFuncDeclStatement(name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine); @@ -1695,8 +1711,11 @@ template TreeExpression JSParser::parseBinaryExpression(Tree return context.popOperandStack(operandStackDepth); } - +#if COMPILER(WINSCW) +template TreeProperty JSParser::parseProperty(bool complete, TreeBuilder& context) +#else template TreeProperty JSParser::parseProperty(TreeBuilder& context) +#endif { bool wasIdent = false; switch (m_token.m_type) { @@ -1710,7 +1729,14 @@ template TreeProperty JSParser::parseProperty next(); TreeExpression node = parseAssignmentExpression(context); failIfFalse(node); +#if COMPILER(WINSCW) + if (complete) + return context.template createProperty(ident, node, PropertyNode::Constant); + else + return context.template createProperty(ident, node, PropertyNode::Constant); +#else return context.template createProperty(ident, node, PropertyNode::Constant); +#endif } failIfFalse(wasIdent); matchOrFail(IDENT); @@ -1727,8 +1753,16 @@ template TreeProperty JSParser::parseProperty type = PropertyNode::Setter; else fail(); +#if COMPILER(WINSCW) + failIfFalse((parseFunctionInfo(FunctionNeedsName, false, context, accessorName, parameters, body, openBracePos, closeBracePos, bodyStartLine))); + if (complete) + return context.template createGetterOrSetterProperty(type, accessorName, parameters, body, openBracePos, closeBracePos, bodyStartLine, m_lastLine); + else + return context.template createGetterOrSetterProperty(type, accessorName, parameters, body, openBracePos, closeBracePos, bodyStartLine, m_lastLine); +#else failIfFalse((parseFunctionInfo(context, accessorName, parameters, body, openBracePos, closeBracePos, bodyStartLine))); return context.template createGetterOrSetterProperty(type, accessorName, parameters, body, openBracePos, closeBracePos, bodyStartLine, m_lastLine); +#endif } case NUMBER: { double propertyName = m_token.m_data.doubleValue; @@ -1736,7 +1770,14 @@ template TreeProperty JSParser::parseProperty consumeOrFail(COLON); TreeExpression node = parseAssignmentExpression(context); failIfFalse(node); +#if COMPILER(WINSCW) + if (complete) + return context.template createProperty(m_globalData, propertyName, node, PropertyNode::Constant); + else + return context.template createProperty(m_globalData, propertyName, node, PropertyNode::Constant); +#else return context.template createProperty(m_globalData, propertyName, node, PropertyNode::Constant); +#endif } default: failIfFalse(m_token.m_type & KeywordTokenFlag); @@ -1754,7 +1795,11 @@ template TreeExpression JSParser::parseObjectLiteral(TreeBui return context.createObjectLiteral(); } +#if COMPILER(WINSCW) + TreeProperty property = parseProperty(false, context); +#else TreeProperty property = parseProperty(context); +#endif failIfFalse(property); if (!m_syntaxAlreadyValidated && context.getType(property) != PropertyNode::Constant) { m_lexer->setOffset(startOffset); @@ -1768,7 +1813,11 @@ template TreeExpression JSParser::parseObjectLiteral(TreeBui // allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939 if (match(CLOSEBRACE)) break; +#if COMPILER(WINSCW) + property = parseProperty(false, context); +#else property = parseProperty(context); +#endif failIfFalse(property); if (!m_syntaxAlreadyValidated && context.getType(property) != PropertyNode::Constant) { m_lexer->setOffset(startOffset); @@ -1792,7 +1841,11 @@ template TreeExpression JSParser::parseStrictObjectLiteral(T return context.createObjectLiteral(); } +#if COMPILER(WINSCW) + TreeProperty property = parseProperty(true, context); +#else TreeProperty property = parseProperty(context); +#endif failIfFalse(property); typedef HashMap, unsigned, IdentifierRepHash> ObjectValidationMap; @@ -1808,7 +1861,11 @@ template TreeExpression JSParser::parseStrictObjectLiteral(T // allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939 if (match(CLOSEBRACE)) break; +#if COMPILER(WINSCW) + property = parseProperty(true, context); +#else property = parseProperty(context); +#endif failIfFalse(property); if (!m_syntaxAlreadyValidated) { std::pair propertyEntryIter = objectValidator.add(context.getName(property).impl(), context.getType(property)); @@ -1987,7 +2044,11 @@ template TreeExpression JSParser::parseMemberExpression(Tree int closeBracePos = 0; int bodyStartLine = 0; next(); +#if COMPILER(WINSCW) + failIfFalse((parseFunctionInfo(FunctionNoRequirements, false, context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine))); +#else failIfFalse((parseFunctionInfo(context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine))); +#endif base = context.createFunctionExpr(name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine); } else base = parsePrimaryExpression(context); diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/runtime/JSONObject.cpp b/src/3rdparty/webkit/Source/JavaScriptCore/runtime/JSONObject.cpp index 8742fdc..27a508a 100644 --- a/src/3rdparty/webkit/Source/JavaScriptCore/runtime/JSONObject.cpp +++ b/src/3rdparty/webkit/Source/JavaScriptCore/runtime/JSONObject.cpp @@ -76,8 +76,13 @@ private: class Stringifier { WTF_MAKE_NONCOPYABLE(Stringifier); public: +#if COMPILER(WINSCW) + Stringifier(ExecState*, const Local* replacer, const Local* space); + Local stringify(Handle*); +#else Stringifier(ExecState*, const Local& replacer, const Local& space); Local stringify(Handle); +#endif void visitAggregate(SlotVisitor&); @@ -197,6 +202,15 @@ JSValue PropertyNameForFunctionCall::value(ExecState* exec) const // ------------------------------ Stringifier -------------------------------- +#if COMPILER(WINSCW) +Stringifier::Stringifier(ExecState* exec, const Local* replacer, const Local* space) + : m_exec(exec) + , m_replacer(*replacer) + , m_usingArrayReplacer(false) + , m_arrayReplacerPropertyNames(exec) + , m_replacerCallType(CallTypeNone) + , m_gap(gap(exec, space->get())) +#else Stringifier::Stringifier(ExecState* exec, const Local& replacer, const Local& space) : m_exec(exec) , m_replacer(replacer) @@ -204,6 +218,7 @@ Stringifier::Stringifier(ExecState* exec, const Local& replacer, const , m_arrayReplacerPropertyNames(exec) , m_replacerCallType(CallTypeNone) , m_gap(gap(exec, space.get())) +#endif { if (!m_replacer.isObject()) return; @@ -244,17 +259,29 @@ Stringifier::Stringifier(ExecState* exec, const Local& replacer, const m_replacerCallType = m_replacer.asObject()->getCallData(m_replacerCallData); } +#if COMPILER(WINSCW) +Local Stringifier::stringify(Handle* value) +#else Local Stringifier::stringify(Handle value) +#endif { JSObject* object = constructEmptyObject(m_exec); if (m_exec->hadException()) return Local(m_exec->globalData(), jsNull()); PropertyNameForFunctionCall emptyPropertyName(m_exec->globalData().propertyNames->emptyIdentifier); +#if COMPILER(WINSCW) + object->putDirect(m_exec->globalData(), m_exec->globalData().propertyNames->emptyIdentifier, value->get()); +#else object->putDirect(m_exec->globalData(), m_exec->globalData().propertyNames->emptyIdentifier, value.get()); +#endif UStringBuilder result; +#if COMPILER(WINSCW) + if (appendStringifiedValue(result, value->get(), object, emptyPropertyName) != StringifySucceeded) +#else if (appendStringifiedValue(result, value.get(), object, emptyPropertyName) != StringifySucceeded) +#endif return Local(m_exec->globalData(), jsUndefined()); if (m_exec->hadException()) return Local(m_exec->globalData(), jsNull()); @@ -606,6 +633,15 @@ bool JSONObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& pro class Walker { public: +#if COMPILER(WINSCW) + Walker(ExecState* exec, Handle* function, CallType callType, CallData callData) + : m_exec(exec) + , m_function(exec->globalData(), *function) + , m_callType(callType) + , m_callData(callData) + { + } +#else Walker(ExecState* exec, Handle function, CallType callType, CallData callData) : m_exec(exec) , m_function(exec->globalData(), function) @@ -613,6 +649,7 @@ public: , m_callData(callData) { } +#endif JSValue walk(JSValue unfiltered); private: JSValue callReviver(JSObject* thisObj, JSValue property, JSValue unfiltered) @@ -829,7 +866,12 @@ EncodedJSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState* exec) CallType callType = getCallData(function, callData); if (callType == CallTypeNone) return JSValue::encode(unfiltered); +#if COMPILER(WINSCW) + Local handle(exec->globalData(), asObject(function)); + return JSValue::encode(Walker(exec, &handle, callType, callData).walk(unfiltered)); +#else return JSValue::encode(Walker(exec, Local(exec->globalData(), asObject(function)), callType, callData).walk(unfiltered)); +#endif } // ECMA-262 v5 15.12.3 @@ -841,13 +883,24 @@ EncodedJSValue JSC_HOST_CALL JSONProtoFuncStringify(ExecState* exec) Local value(exec->globalData(), exec->argument(0)); Local replacer(exec->globalData(), exec->argument(1)); Local space(exec->globalData(), exec->argument(2)); +#if COMPILER(WINSCW) + return JSValue::encode(Stringifier(exec, &replacer, &space).stringify(&value).get()); +#else return JSValue::encode(Stringifier(exec, replacer, space).stringify(value).get()); +#endif } UString JSONStringify(ExecState* exec, JSValue value, unsigned indent) { LocalScope scope(exec->globalData()); +#if COMPILER(WINSCW) + Local replacer(exec->globalData(), jsNull()); + Local space(exec->globalData(), jsNumber(indent)); + Local valueHandle(exec->globalData(), value); + Local result = Stringifier(exec, &replacer, &space).stringify(&valueHandle); +#else Local result = Stringifier(exec, Local(exec->globalData(), jsNull()), Local(exec->globalData(), jsNumber(indent))).stringify(Local(exec->globalData(), value)); +#endif if (result.isUndefinedOrNull()) return UString(); return result.getString(exec); diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/wtf/ByteArray.h b/src/3rdparty/webkit/Source/JavaScriptCore/wtf/ByteArray.h index bdec630..47b1cff 100644 --- a/src/3rdparty/webkit/Source/JavaScriptCore/wtf/ByteArray.h +++ b/src/3rdparty/webkit/Source/JavaScriptCore/wtf/ByteArray.h @@ -91,7 +91,7 @@ namespace WTF { // MSVC can't handle correctly unsized array. // warning C4200: nonstandard extension used : zero-sized array in struct/union // Cannot generate copy-ctor or copy-assignment operator when UDT contains a zero-sized array -#if COMPILER(MSVC) +#if COMPILER(MSVC) && !COMPILER(INTEL) unsigned char m_data[INT_MAX]; #else unsigned char m_data[]; diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/wtf/DateMath.cpp b/src/3rdparty/webkit/Source/JavaScriptCore/wtf/DateMath.cpp index d414eae..b181ee2 100644 --- a/src/3rdparty/webkit/Source/JavaScriptCore/wtf/DateMath.cpp +++ b/src/3rdparty/webkit/Source/JavaScriptCore/wtf/DateMath.cpp @@ -692,7 +692,7 @@ double parseES5DateFromNullTerminatedCharacters(const char* dateString) return NaN; if (*postParsePosition != ':' || (postParsePosition - currentPosition) != 2) return NaN; - tzHoursAbs = abs(tzHours); + tzHoursAbs = labs(tzHours); currentPosition = postParsePosition + 1; if (!isASCIIDigit(*currentPosition)) diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/wtf/NullPtr.h b/src/3rdparty/webkit/Source/JavaScriptCore/wtf/NullPtr.h index c0e7bd3..9c4319d 100644 --- a/src/3rdparty/webkit/Source/JavaScriptCore/wtf/NullPtr.h +++ b/src/3rdparty/webkit/Source/JavaScriptCore/wtf/NullPtr.h @@ -35,7 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define __has_feature(feature) 0 #endif -#if __has_feature(cxx_nullptr) || (GCC_VERSION_AT_LEAST(4, 6, 0) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || (defined(_MSC_VER) && _MSC_VER >= 1600) +#if __has_feature(cxx_nullptr) || (GCC_VERSION_AT_LEAST(4, 6, 0) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || (defined(_MSC_VER) && _MSC_VER >= 1600 && !COMPILER(INTEL)) #define HAVE_NULLPTR 1 diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/wtf/PageAllocatorSymbian.h b/src/3rdparty/webkit/Source/JavaScriptCore/wtf/PageAllocatorSymbian.h index eba5b03..d396379 100644 --- a/src/3rdparty/webkit/Source/JavaScriptCore/wtf/PageAllocatorSymbian.h +++ b/src/3rdparty/webkit/Source/JavaScriptCore/wtf/PageAllocatorSymbian.h @@ -68,7 +68,7 @@ public: // Size of the large up-front reservation #if defined(__WINS__) // Emulator has limited virtual address space -const size_t largeReservationSize = 96*1024*1024; +const size_t largeReservationSize = 64*1024*1024; #else // HW has plenty of virtual addresses const size_t largeReservationSize = 256*1024*1024; diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/wtf/Platform.h b/src/3rdparty/webkit/Source/JavaScriptCore/wtf/Platform.h index 716d9e1..55f0b58 100644 --- a/src/3rdparty/webkit/Source/JavaScriptCore/wtf/Platform.h +++ b/src/3rdparty/webkit/Source/JavaScriptCore/wtf/Platform.h @@ -365,7 +365,7 @@ #endif /* ARM */ -#if CPU(ARM) || CPU(MIPS) +#if CPU(ARM) || CPU(MIPS) || CPU(SH4) #define WTF_CPU_NEEDS_ALIGNED_ACCESS 1 #endif @@ -581,7 +581,7 @@ #define WTF_USE_PTHREAD_BASED_QT 1 #endif -#if (PLATFORM(GTK) || PLATFORM(IOS) || PLATFORM(MAC) || PLATFORM(WIN) || (PLATFORM(QT) && (OS(DARWIN) || USE(PTHREAD_BASED_QT)) && !ENABLE(SINGLE_THREADED))) && !defined(ENABLE_JSC_MULTIPLE_THREADS) +#if (PLATFORM(GTK) || PLATFORM(IOS) || PLATFORM(MAC) || PLATFORM(WIN) || (PLATFORM(QT) && (OS(DARWIN) || USE(PTHREAD_BASED_QT)) && !ENABLE(SINGLE_THREADED))) && !OS(QNX) && !defined(ENABLE_JSC_MULTIPLE_THREADS) #define ENABLE_JSC_MULTIPLE_THREADS 1 #endif @@ -1019,11 +1019,17 @@ #define ENABLE_JIT 0 #endif +/* Disable JIT for WINSCW Symbian Emulator */ +#if !defined(ENABLE_JIT) && COMPILER(WINSCW) +#define ENABLE_JIT 0 +#endif + /* The JIT is enabled by default on all x86, x64-64, ARM & MIPS platforms. */ #if !defined(ENABLE_JIT) \ && (CPU(X86) || CPU(X86_64) || CPU(ARM) || CPU(MIPS)) \ && (OS(DARWIN) || !COMPILER(GCC) || GCC_VERSION_AT_LEAST(4, 1, 0)) \ - && !OS(WINCE) + && !OS(WINCE) \ + && !OS(QNX) #define ENABLE_JIT 1 #endif diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/wtf/StackBounds.cpp b/src/3rdparty/webkit/Source/JavaScriptCore/wtf/StackBounds.cpp index 41e0d60..6b61270 100644 --- a/src/3rdparty/webkit/Source/JavaScriptCore/wtf/StackBounds.cpp +++ b/src/3rdparty/webkit/Source/JavaScriptCore/wtf/StackBounds.cpp @@ -41,10 +41,12 @@ #elif OS(QNX) +#include #include -#include +#include #include -#include +#include +#include #elif OS(UNIX) diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/wtf/text/AtomicString.h b/src/3rdparty/webkit/Source/JavaScriptCore/wtf/text/AtomicString.h index 440700c..cc451e8 100644 --- a/src/3rdparty/webkit/Source/JavaScriptCore/wtf/text/AtomicString.h +++ b/src/3rdparty/webkit/Source/JavaScriptCore/wtf/text/AtomicString.h @@ -113,6 +113,16 @@ public: static AtomicString fromUTF8(const char*, size_t); static AtomicString fromUTF8(const char*); +#if COMPILER(WINSCW) + static const AtomicString& nullAtom2(); + static const AtomicString& emptyAtom2(); + static const AtomicString& textAtom2(); + static const AtomicString& commentAtom2(); + static const AtomicString& starAtom2(); + static const AtomicString& xmlAtom2(); + static const AtomicString& xmlnsAtom2(); +#endif + private: String m_string; @@ -155,6 +165,24 @@ inline bool equalIgnoringCase(const String& a, const AtomicString& b) { return e // Define external global variables for the commonly used atomic strings. // These are only usable from the main thread. #ifndef ATOMICSTRING_HIDE_GLOBALS + +#if COMPILER(WINSCW) +extern const JS_EXPORTDATA AtomicString nullAtom1; +extern const JS_EXPORTDATA AtomicString emptyAtom1; +extern const JS_EXPORTDATA AtomicString textAtom1; +extern const JS_EXPORTDATA AtomicString commentAtom1; +extern const JS_EXPORTDATA AtomicString starAtom1; +extern const JS_EXPORTDATA AtomicString xmlAtom1; +extern const JS_EXPORTDATA AtomicString xmlnsAtom1; + +#define nullAtom AtomicString::nullAtom2() +#define emptyAtom AtomicString::emptyAtom2() +#define textAtom AtomicString::textAtom2() +#define commentAtom AtomicString::commentAtom2() +#define starAtom AtomicString::starAtom2() +#define xmlAtom AtomicString::xmlAtom2() +#define xmlnsAtom AtomicString::xmlnsAtom2() +#else extern const JS_EXPORTDATA AtomicString nullAtom; extern const JS_EXPORTDATA AtomicString emptyAtom; extern const JS_EXPORTDATA AtomicString textAtom; @@ -162,6 +190,7 @@ extern const JS_EXPORTDATA AtomicString commentAtom; extern const JS_EXPORTDATA AtomicString starAtom; extern const JS_EXPORTDATA AtomicString xmlAtom; extern const JS_EXPORTDATA AtomicString xmlnsAtom; +#endif inline AtomicString AtomicString::fromUTF8(const char* characters, size_t length) { @@ -190,6 +219,7 @@ template<> struct DefaultHash { } // namespace WTF +#if !COMPILER(WINSCW) #ifndef ATOMICSTRING_HIDE_GLOBALS using WTF::AtomicString; using WTF::nullAtom; @@ -200,5 +230,6 @@ using WTF::starAtom; using WTF::xmlAtom; using WTF::xmlnsAtom; #endif +#endif #endif // AtomicString_h diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/wtf/text/StringStatics.cpp b/src/3rdparty/webkit/Source/JavaScriptCore/wtf/text/StringStatics.cpp index ce08728..c5a8b43 100644 --- a/src/3rdparty/webkit/Source/JavaScriptCore/wtf/text/StringStatics.cpp +++ b/src/3rdparty/webkit/Source/JavaScriptCore/wtf/text/StringStatics.cpp @@ -51,6 +51,15 @@ StringImpl* StringImpl::empty() return &emptyString; } +#if COMPILER(WINSCW) +static AtomicString nullAtom1; +static AtomicString emptyAtom1; +static AtomicString textAtom1; +static AtomicString commentAtom1; +static AtomicString starAtom1; +static AtomicString xmlAtom1; +static AtomicString xmlnsAtom1; +#else JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, nullAtom) JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, emptyAtom, "") JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, textAtom, "#text") @@ -58,6 +67,7 @@ JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, commentAtom, "#comment") JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, starAtom, "*") JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, xmlAtom, "xml") JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, xmlnsAtom, "xmlns") +#endif void AtomicString::init() { @@ -67,6 +77,15 @@ void AtomicString::init() ASSERT(isMainThread()); // Use placement new to initialize the globals. +#if COMPILER(WINSCW) + new ((void*)&nullAtom1) AtomicString; + new ((void*)&emptyAtom1) AtomicString(""); + new ((void*)&textAtom1) AtomicString("#text"); + new ((void*)&commentAtom1) AtomicString("#comment"); + new ((void*)&starAtom1) AtomicString("*"); + new ((void*)&xmlAtom1) AtomicString("xml"); + new ((void*)&xmlnsAtom1) AtomicString("xmlns"); +#else new ((void*)&nullAtom) AtomicString; new ((void*)&emptyAtom) AtomicString(""); new ((void*)&textAtom) AtomicString("#text"); @@ -74,9 +93,19 @@ void AtomicString::init() new ((void*)&starAtom) AtomicString("*"); new ((void*)&xmlAtom) AtomicString("xml"); new ((void*)&xmlnsAtom) AtomicString("xmlns"); - +#endif initialized = true; } } +#if COMPILER(WINSCW) +const AtomicString& AtomicString::nullAtom2() { return nullAtom1;} +const AtomicString& AtomicString::emptyAtom2() { return emptyAtom1;} +const AtomicString& AtomicString::textAtom2() { return textAtom1;} +const AtomicString& AtomicString::commentAtom2() { return commentAtom1;} +const AtomicString& AtomicString::starAtom2() { return starAtom1;} +const AtomicString& AtomicString::xmlAtom2() { return xmlAtom1;} +const AtomicString& AtomicString::xmlnsAtom2() { return xmlnsAtom1;} +#endif + } diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/wtf/wtf.pri b/src/3rdparty/webkit/Source/JavaScriptCore/wtf/wtf.pri index 10b41e4..5e48f9a 100644 --- a/src/3rdparty/webkit/Source/JavaScriptCore/wtf/wtf.pri +++ b/src/3rdparty/webkit/Source/JavaScriptCore/wtf/wtf.pri @@ -41,10 +41,12 @@ SOURCES += \ wtf/unicode/icu/CollatorICU.cpp \ wtf/unicode/UTF8.cpp -contains(DEFINES, USE_GSTREAMER=1) { - DEFINES += ENABLE_GLIB_SUPPORT=1 - PKGCONFIG += glib-2.0 gio-2.0 - CONFIG += link_pkgconfig +linux-*:!contains(DEFINES, USE_QTMULTIMEDIA=1) { + system(pkg-config --exists glib-2.0 gio-2.0 gstreamer-0.10): { + DEFINES += ENABLE_GLIB_SUPPORT=1 + PKGCONFIG += glib-2.0 gio-2.0 + CONFIG += link_pkgconfig + } } unix:!symbian: SOURCES += wtf/OSAllocatorPosix.cpp diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/yarr/YarrJIT.cpp b/src/3rdparty/webkit/Source/JavaScriptCore/yarr/YarrJIT.cpp index ece2379..f3356b1 100644 --- a/src/3rdparty/webkit/Source/JavaScriptCore/yarr/YarrJIT.cpp +++ b/src/3rdparty/webkit/Source/JavaScriptCore/yarr/YarrJIT.cpp @@ -228,9 +228,10 @@ class YarrGenerator : private MacroAssembler { } // Jumps if input not available; will have (incorrectly) incremented already! - Jump jumpIfNoAvailableInput(unsigned countToCheck) + Jump jumpIfNoAvailableInput(unsigned countToCheck = 0) { - add32(Imm32(countToCheck), index); + if (countToCheck) + add32(Imm32(countToCheck), index); return branch32(Above, index, length); } @@ -295,1056 +296,455 @@ class YarrGenerator : private MacroAssembler { jump(Address(stackPointerRegister, frameLocation * sizeof(void*))); } - struct IndirectJumpEntry { - IndirectJumpEntry(int32_t stackOffset) - : m_stackOffset(stackOffset) - { - } - - IndirectJumpEntry(int32_t stackOffset, Jump jump) - : m_stackOffset(stackOffset) - { - addJump(jump); - } - - IndirectJumpEntry(int32_t stackOffset, DataLabelPtr dataLabel) - : m_stackOffset(stackOffset) - { - addDataLabel(dataLabel); - } - - void addJump(Jump jump) - { - m_relJumps.append(jump); - } - - void addDataLabel(DataLabelPtr dataLabel) - { - m_dataLabelPtrVector.append(dataLabel); - } - - int32_t m_stackOffset; - JumpList m_relJumps; - Vector m_dataLabelPtrVector; + enum YarrOpCode { + // These nodes wrap body alternatives - those in the main disjunction, + // rather than subpatterns or assertions. These are chained together in + // a doubly linked list, with a 'begin' node for the first alternative, + // a 'next' node for each subsequent alternative, and an 'end' node at + // the end. In the case of repeating alternatives, the 'end' node also + // has a reference back to 'begin'. + OpBodyAlternativeBegin, + OpBodyAlternativeNext, + OpBodyAlternativeEnd, + // Similar to the body alternatives, but used for subpatterns with two + // or more alternatives. + OpNestedAlternativeBegin, + OpNestedAlternativeNext, + OpNestedAlternativeEnd, + // Used for alternatives in subpatterns where there is only a single + // alternative (backtrackingis easier in these cases), or for alternatives + // which never need to be backtracked (those in parenthetical assertions, + // terminal subpatterns). + OpSimpleNestedAlternativeBegin, + OpSimpleNestedAlternativeNext, + OpSimpleNestedAlternativeEnd, + // Used to wrap 'Once' subpattern matches (quantityCount == 1). + OpParenthesesSubpatternOnceBegin, + OpParenthesesSubpatternOnceEnd, + // Used to wrap 'Terminal' subpattern matches (at the end of the regexp). + OpParenthesesSubpatternTerminalBegin, + OpParenthesesSubpatternTerminalEnd, + // Used to wrap parenthetical assertions. + OpParentheticalAssertionBegin, + OpParentheticalAssertionEnd, + // Wraps all simple terms (pattern characters, character classes). + OpTerm, + // Where an expression contains only 'once through' body alternatives + // and no repeating ones, this op is used to return match failure. + OpMatchFailed }; - struct AlternativeBacktrackRecord { - DataLabelPtr dataLabel; - Label backtrackLocation; - - AlternativeBacktrackRecord(DataLabelPtr dataLabel, Label backtrackLocation) - : dataLabel(dataLabel) - , backtrackLocation(backtrackLocation) - { - } - }; - - struct ParenthesesTail; - struct TermGenerationState; - - struct GenerationState { - typedef HashMap, UnsignedWithZeroKeyHashTraits > IndirectJumpHashMap; - - GenerationState() - : m_parenNestingLevel(0) - { - } - - void addIndirectJumpEntry(int32_t stackOffset, Jump jump) - { - IndirectJumpHashMap::iterator result = m_indirectJumpMap.find(stackOffset); - - ASSERT(stackOffset >= 0); - - uint32_t offset = static_cast(stackOffset); - - if (result == m_indirectJumpMap.end()) - m_indirectJumpMap.add(offset, new IndirectJumpEntry(stackOffset, jump)); - else - result->second->addJump(jump); - } - - void addIndirectJumpEntry(int32_t stackOffset, JumpList jumps) - { - JumpList::JumpVector jumpVector = jumps.jumps(); - size_t size = jumpVector.size(); - for (size_t i = 0; i < size; ++i) - addIndirectJumpEntry(stackOffset, jumpVector[i]); - - jumps.empty(); - } - - void addIndirectJumpEntry(int32_t stackOffset, DataLabelPtr dataLabel) - { - IndirectJumpHashMap::iterator result = m_indirectJumpMap.find(stackOffset); - - ASSERT(stackOffset >= 0); - - uint32_t offset = static_cast(stackOffset); - - if (result == m_indirectJumpMap.end()) - m_indirectJumpMap.add(offset, new IndirectJumpEntry(stackOffset, dataLabel)); - else - result->second->addDataLabel(dataLabel); - } - - void emitIndirectJumpTable(MacroAssembler* masm) - { - for (IndirectJumpHashMap::iterator iter = m_indirectJumpMap.begin(); iter != m_indirectJumpMap.end(); ++iter) { - IndirectJumpEntry* indJumpEntry = iter->second; - size_t size = indJumpEntry->m_dataLabelPtrVector.size(); - if (size) { - // Link any associated DataLabelPtr's with indirect jump via label - Label hereLabel = masm->label(); - for (size_t i = 0; i < size; ++i) - m_backtrackRecords.append(AlternativeBacktrackRecord(indJumpEntry->m_dataLabelPtrVector[i], hereLabel)); - } - indJumpEntry->m_relJumps.link(masm); - masm->jump(Address(stackPointerRegister, indJumpEntry->m_stackOffset)); - delete indJumpEntry; - } - } - - void incrementParenNestingLevel() - { - ++m_parenNestingLevel; - } - - void decrementParenNestingLevel() - { - --m_parenNestingLevel; - } - - ParenthesesTail* addParenthesesTail(PatternTerm& term, JumpList* jumpListToPriorParen) - { - OwnPtr tail = adoptPtr(new ParenthesesTail(term, m_parenNestingLevel, jumpListToPriorParen)); - ParenthesesTail* rawTail = tail.get(); - - m_parenTails.append(tail.release()); - m_parenTailsForIteration.append(rawTail); - - return rawTail; - } - - void emitParenthesesTail(YarrGenerator* generator) - { - unsigned vectorSize = m_parenTails.size(); - bool priorBacktrackFallThrough = false; - - // Emit in reverse order so parentTail N can fall through to N-1 - for (unsigned index = vectorSize; index > 0; --index) { - JumpList jumpsToNext; - priorBacktrackFallThrough = m_parenTails[index-1].get()->generateCode(generator, jumpsToNext, priorBacktrackFallThrough, index > 1); - if (index > 1) - jumpsToNext.linkTo(generator->label(), generator); - else - addJumpsToNextInteration(jumpsToNext); - } - m_parenTails.clear(); - } - - void addJumpToNextInteration(Jump jump) + // This structure is used to hold the compiled opcode information, + // including reference back to the original PatternTerm/PatternAlternatives, + // and JIT compilation data structures. + struct YarrOp { + explicit YarrOp(PatternTerm* term) + : m_op(OpTerm) + , m_term(term) + , m_isDeadCode(false) { - m_jumpsToNextInteration.append(jump); } - void addJumpsToNextInteration(JumpList jumps) + explicit YarrOp(YarrOpCode op) + : m_op(op) + , m_isDeadCode(false) { - m_jumpsToNextInteration.append(jumps); } - void addDataLabelToNextIteration(DataLabelPtr dataLabel) - { - m_dataPtrsToNextIteration.append(dataLabel); - } - - void linkToNextIteration(Label label) - { - m_nextIteration = label; - - for (unsigned i = 0; i < m_dataPtrsToNextIteration.size(); ++i) - m_backtrackRecords.append(AlternativeBacktrackRecord(m_dataPtrsToNextIteration[i], m_nextIteration)); + // The operation, as a YarrOpCode, and also a reference to the PatternTerm. + YarrOpCode m_op; + PatternTerm* m_term; - m_dataPtrsToNextIteration.clear(); + // For alternatives, this holds the PatternAlternative and doubly linked + // references to this alternative's siblings. In the case of the + // OpBodyAlternativeEnd node at the end of a section of repeating nodes, + // m_nextOp will reference the OpBodyAlternativeBegin node of the first + // repeating alternative. + PatternAlternative* m_alternative; + size_t m_previousOp; + size_t m_nextOp; - for (unsigned i = 0; i < m_parenTailsForIteration.size(); ++i) - m_parenTailsForIteration[i]->setNextIteration(m_nextIteration); + // Used to record a set of Jumps out of the generated code, typically + // used for jumps out to backtracking code, and a single reentry back + // into the code for a node (likely where a backtrack will trigger + // rematching). + Label m_reentry; + JumpList m_jumps; - m_parenTailsForIteration.clear(); - } + // This flag is used to null out the second pattern character, when + // two are fused to match a pair together. + bool m_isDeadCode; - void linkToNextIteration(YarrGenerator* generator) - { - m_jumpsToNextInteration.linkTo(m_nextIteration, generator); - } + // Currently used in the case of some of the more complex management of + // 'm_checked', to cache the offset used in this alternative, to avoid + // recalculating it. + int m_checkAdjust; - int m_parenNestingLevel; - Vector m_backtrackRecords; - IndirectJumpHashMap m_indirectJumpMap; - Label m_nextIteration; - Vector > m_parenTails; - JumpList m_jumpsToNextInteration; - Vector m_dataPtrsToNextIteration; - Vector m_parenTailsForIteration; + // Used by OpNestedAlternativeNext/End to hold the pointer to the + // value that will be pushed into the pattern's frame to return to, + // upon backtracking back into the disjunction. + DataLabelPtr m_returnAddress; }; - struct BacktrackDestination { - typedef enum { - NoBacktrack, - BacktrackLabel, - BacktrackStackOffset, - BacktrackJumpList, - BacktrackLinked - } BacktrackType; - - BacktrackDestination() - : m_backtrackType(NoBacktrack) - , m_backtrackToLabel(0) - , m_subDataLabelPtr(0) - , m_nextBacktrack(0) - , m_backtrackSourceLabel(0) - , m_backtrackSourceJumps(0) - { - } - - BacktrackDestination(int32_t stackOffset) - : m_backtrackType(BacktrackStackOffset) - , m_backtrackStackOffset(stackOffset) - , m_backtrackToLabel(0) - , m_subDataLabelPtr(0) - , m_nextBacktrack(0) - , m_backtrackSourceLabel(0) - , m_backtrackSourceJumps(0) - { - } - - BacktrackDestination(Label label) - : m_backtrackType(BacktrackLabel) - , m_backtrackLabel(label) - , m_backtrackToLabel(0) - , m_subDataLabelPtr(0) - , m_nextBacktrack(0) - , m_backtrackSourceLabel(0) - , m_backtrackSourceJumps(0) - { - } - - void clear(bool doDataLabelClear = true) - { - m_backtrackType = NoBacktrack; - if (doDataLabelClear) - clearDataLabel(); - m_nextBacktrack = 0; - } - - void clearDataLabel() - { - m_dataLabelPtr = DataLabelPtr(); - } - - bool hasDestination() - { - return (m_backtrackType != NoBacktrack); - } - - bool isStackOffset() - { - return (m_backtrackType == BacktrackStackOffset); - } - - bool isLabel() - { - return (m_backtrackType == BacktrackLabel); - } - - bool isJumpList() - { - return (m_backtrackType == BacktrackJumpList); - } - - bool hasDataLabel() - { - return m_dataLabelPtr.isSet(); - } - - void copyTarget(BacktrackDestination& rhs, bool copyDataLabel = true) - { - m_backtrackType = rhs.m_backtrackType; - if (m_backtrackType == BacktrackStackOffset) - m_backtrackStackOffset = rhs.m_backtrackStackOffset; - else if (m_backtrackType == BacktrackLabel) - m_backtrackLabel = rhs.m_backtrackLabel; - if (copyDataLabel) - m_dataLabelPtr = rhs.m_dataLabelPtr; - m_backtrackSourceJumps = rhs.m_backtrackSourceJumps; - m_backtrackSourceLabel = rhs.m_backtrackSourceLabel; - } - - void copyTo(BacktrackDestination& lhs) - { - lhs.m_backtrackType = m_backtrackType; - if (m_backtrackType == BacktrackStackOffset) - lhs.m_backtrackStackOffset = m_backtrackStackOffset; - else if (m_backtrackType == BacktrackLabel) - lhs.m_backtrackLabel = m_backtrackLabel; - lhs.m_backtrackSourceJumps = m_backtrackSourceJumps; - lhs.m_backtrackSourceLabel = m_backtrackSourceLabel; - lhs.m_dataLabelPtr = m_dataLabelPtr; - lhs.m_backTrackJumps = m_backTrackJumps; - } - - void addBacktrackJump(Jump jump) - { - m_backTrackJumps.append(jump); - } - - void setStackOffset(int32_t stackOffset) - { - m_backtrackType = BacktrackStackOffset; - m_backtrackStackOffset = stackOffset; - } - - void setLabel(Label label) - { - m_backtrackType = BacktrackLabel; - m_backtrackLabel = label; - } - - void setNextBacktrackLabel(Label label) + // BacktrackingState + // This class encapsulates information about the state of code generation + // whilst generating the code for backtracking, when a term fails to match. + // Upon entry to code generation of the backtracking code for a given node, + // the Backtracking state will hold references to all control flow sources + // that are outputs in need of further backtracking from the prior node + // generated (which is the subsequent operation in the regular expression, + // and in the m_ops Vector, since we generated backtracking backwards). + // These references to control flow take the form of: + // - A jump list of jumps, to be linked to code that will backtrack them + // further. + // - A set of DataLabelPtr values, to be populated with values to be + // treated effectively as return addresses backtracking into complex + // subpatterns. + // - A flag indicating that the current sequence of generated code up to + // this point requires backtracking. + class BacktrackingState { + public: + BacktrackingState() + : m_pendingFallthrough(false) { - if (m_nextBacktrack) - m_nextBacktrack->setLabel(label); } - void propagateBacktrackToLabel(const BacktrackDestination& rhs) + // Add a jump or jumps, a return address, or set the flag indicating + // that the current 'fallthrough' control flow requires backtracking. + void append(const Jump& jump) { - if (!m_backtrackToLabel && rhs.m_backtrackToLabel) - m_backtrackToLabel = rhs.m_backtrackToLabel; + m_laterFailures.append(jump); } - - void setBacktrackToLabel(Label* backtrackToLabel) + void append(JumpList& jumpList) { - if (!m_backtrackToLabel) - m_backtrackToLabel = backtrackToLabel; + m_laterFailures.append(jumpList); } - - bool hasBacktrackToLabel() + void append(const DataLabelPtr& returnAddress) { - return m_backtrackToLabel; + m_pendingReturns.append(returnAddress); } - - void setBacktrackJumpList(JumpList* jumpList) + void fallthrough() { - m_backtrackType = BacktrackJumpList; - m_backtrackSourceJumps = jumpList; + ASSERT(!m_pendingFallthrough); + m_pendingFallthrough = true; } - void setBacktrackSourceLabel(Label* backtrackSourceLabel) + // These methods clear the backtracking state, either linking to the + // current location, a provided label, or copying the backtracking out + // to a JumpList. All actions may require code generation to take place, + // and as such are passed a pointer to the assembler. + void link(MacroAssembler* assembler) { - m_backtrackSourceLabel = backtrackSourceLabel; - } - - void setDataLabel(DataLabelPtr dp) - { - if (m_subDataLabelPtr) { - *m_subDataLabelPtr = dp; - m_subDataLabelPtr = 0; - } else { - ASSERT(!hasDataLabel()); - m_dataLabelPtr = dp; + if (m_pendingReturns.size()) { + Label here(assembler); + for (unsigned i = 0; i < m_pendingReturns.size(); ++i) + m_backtrackRecords.append(ReturnAddressRecord(m_pendingReturns[i], here)); + m_pendingReturns.clear(); } + m_laterFailures.link(assembler); + m_laterFailures.clear(); + m_pendingFallthrough = false; } - - void clearSubDataLabelPtr() - { - m_subDataLabelPtr = 0; - } - - void setSubDataLabelPtr(DataLabelPtr* subDataLabelPtr) - { - m_subDataLabelPtr = subDataLabelPtr; - } - - void linkToNextBacktrack(BacktrackDestination* nextBacktrack) - { - m_nextBacktrack = nextBacktrack; - } - - int32_t getStackOffset() + void linkTo(Label label, MacroAssembler* assembler) { - ASSERT(m_backtrackType == BacktrackStackOffset); - return m_backtrackStackOffset; - } - - Label getLabel() - { - ASSERT(m_backtrackType == BacktrackLabel); - return m_backtrackLabel; - } - - JumpList& getBacktrackJumps() - { - return m_backTrackJumps; - } - - DataLabelPtr& getDataLabel() - { - return m_dataLabelPtr; - } - - void jumpToBacktrack(MacroAssembler* masm) - { - if (isJumpList()) { - if (m_backtrackSourceLabel && (m_backtrackSourceLabel->isSet())) - masm->jump().linkTo(*m_backtrackSourceLabel, masm); - else - m_backtrackSourceJumps->append(masm->jump()); - } else if (isStackOffset()) - masm->jump(Address(stackPointerRegister, m_backtrackStackOffset)); - else if (isLabel()) - masm->jump().linkTo(m_backtrackLabel, masm); - else - m_backTrackJumps.append(masm->jump()); - } - - void jumpToBacktrack(YarrGenerator* generator, Jump jump) - { - if (isJumpList()) { - if (m_backtrackSourceLabel && (m_backtrackSourceLabel->isSet())) - jump.linkTo(*m_backtrackSourceLabel, generator); - else - m_backtrackSourceJumps->append(jump); - } else if (isStackOffset()) - generator->m_expressionState.addIndirectJumpEntry(getStackOffset(), jump); - else if (isLabel()) - jump.linkTo(getLabel(), generator); - else - m_backTrackJumps.append(jump); - } - - void jumpToBacktrack(YarrGenerator* generator, JumpList& jumps) - { - if (isJumpList()) { - if (m_backtrackSourceLabel && (m_backtrackSourceLabel->isSet())) - jumps.linkTo(*m_backtrackSourceLabel, generator); - else - m_backtrackSourceJumps->append(jumps); - } else if (isStackOffset()) - generator->m_expressionState.addIndirectJumpEntry(getStackOffset(), jumps); - else if (isLabel()) - jumps.linkTo(getLabel(), generator); - else - m_backTrackJumps.append(jumps); - } - - bool plantJumpToBacktrackIfExists(YarrGenerator* generator) - { - if (isJumpList()) { - if (m_backtrackSourceLabel && (m_backtrackSourceLabel->isSet())) - generator->jump(*m_backtrackSourceLabel); - else - m_backtrackSourceJumps->append(generator->jump()); - - return true; + if (m_pendingReturns.size()) { + for (unsigned i = 0; i < m_pendingReturns.size(); ++i) + m_backtrackRecords.append(ReturnAddressRecord(m_pendingReturns[i], label)); + m_pendingReturns.clear(); } - - if (isStackOffset()) { - generator->jump(Address(stackPointerRegister, getStackOffset())); - return true; - } - - if (isLabel()) { - generator->jump(getLabel()); - if (hasDataLabel()) { - generator->m_expressionState.m_backtrackRecords.append(AlternativeBacktrackRecord(getDataLabel(), getLabel())); - clearDataLabel(); - } - return true; + if (m_pendingFallthrough) + assembler->jump(label); + m_laterFailures.linkTo(label, assembler); + m_laterFailures.clear(); + m_pendingFallthrough = false; + } + void takeBacktracksToJumpList(JumpList& jumpList, MacroAssembler* assembler) + { + if (m_pendingReturns.size()) { + Label here(assembler); + for (unsigned i = 0; i < m_pendingReturns.size(); ++i) + m_backtrackRecords.append(ReturnAddressRecord(m_pendingReturns[i], here)); + m_pendingReturns.clear(); + m_pendingFallthrough = true; } - - return false; + if (m_pendingFallthrough) + jumpList.append(assembler->jump()); + jumpList.append(m_laterFailures); + m_laterFailures.clear(); + m_pendingFallthrough = false; } - void linkBacktrackToLabel(Label backtrackLabel) + bool isEmpty() { - if (m_backtrackToLabel) - *m_backtrackToLabel = backtrackLabel; - } - - void linkAlternativeBacktracks(YarrGenerator* generator, bool nextIteration = false) - { - Label hereLabel = generator->label(); - - if (m_backtrackToLabel) { - *m_backtrackToLabel = hereLabel; - m_backtrackToLabel = 0; - } - - m_backTrackJumps.link(generator); - - if (nextIteration) - generator->m_expressionState.linkToNextIteration(hereLabel); - - if (hasDataLabel()) { - generator->m_expressionState.m_backtrackRecords.append(AlternativeBacktrackRecord(getDataLabel(), hereLabel)); - // data label cleared as a result of the clear() below - } - - clear(); + return m_laterFailures.empty() && m_pendingReturns.isEmpty() && !m_pendingFallthrough; } - void linkAlternativeBacktracksTo(YarrGenerator* generator, Label label, bool nextIteration = false) + // Called at the end of code generation to link all return addresses. + void linkDataLabels(LinkBuffer& linkBuffer) { - m_backTrackJumps.linkTo(label, generator); - - if (nextIteration) - generator->m_expressionState.linkToNextIteration(label); - - if (hasDataLabel()) { - generator->m_expressionState.m_backtrackRecords.append(AlternativeBacktrackRecord(getDataLabel(), label)); - clearDataLabel(); - } + ASSERT(isEmpty()); + for (unsigned i = 0; i < m_backtrackRecords.size(); ++i) + linkBuffer.patch(m_backtrackRecords[i].m_dataLabel, linkBuffer.locationOf(m_backtrackRecords[i].m_backtrackLocation)); } private: - BacktrackType m_backtrackType; - int32_t m_backtrackStackOffset; - Label m_backtrackLabel; - DataLabelPtr m_dataLabelPtr; - Label* m_backtrackToLabel; - DataLabelPtr* m_subDataLabelPtr; - BacktrackDestination* m_nextBacktrack; - Label* m_backtrackSourceLabel; - JumpList* m_backtrackSourceJumps; - JumpList m_backTrackJumps; - }; - - struct TermGenerationState { - TermGenerationState(PatternDisjunction* disjunction, unsigned checkedTotal) - : disjunction(disjunction) - , checkedTotal(checkedTotal) - , m_subParenNum(0) - , m_linkedBacktrack(0) - , m_jumpList(0) - { - } - - void resetAlternative() - { - m_backtrack.clear(); - alt = 0; - } - bool alternativeValid() - { - return alt < disjunction->m_alternatives.size(); - } - void nextAlternative() - { - ++alt; - } - PatternAlternative* alternative() - { - return disjunction->m_alternatives[alt]; - } - bool isLastAlternative() - { - return (alt + 1) == disjunction->m_alternatives.size(); - } - - void resetTerm() - { - ASSERT(alternativeValid()); - t = 0; - m_subParenNum = 0; - } - bool termValid() - { - ASSERT(alternativeValid()); - return t < alternative()->m_terms.size(); - } - void nextTerm() - { - ASSERT(alternativeValid()); - ++t; - } - PatternTerm& term() - { - ASSERT(alternativeValid()); - return alternative()->m_terms[t]; - } - bool isLastTerm() - { - ASSERT(alternativeValid()); - return (t + 1) == alternative()->m_terms.size(); - } - unsigned getSubParenNum() - { - return m_subParenNum++; - } - bool isMainDisjunction() - { - return !disjunction->m_parent; - } - - void setJumpListToPriorParen(JumpList* jumpList) - { - m_jumpList = jumpList; - } - - JumpList* getJumpListToPriorParen() - { - return m_jumpList; - } - - PatternTerm& lookaheadTerm() - { - ASSERT(alternativeValid()); - ASSERT((t + 1) < alternative()->m_terms.size()); - return alternative()->m_terms[t + 1]; - } - bool isSinglePatternCharacterLookaheadTerm() - { - ASSERT(alternativeValid()); - return ((t + 1) < alternative()->m_terms.size()) - && (lookaheadTerm().type == PatternTerm::TypePatternCharacter) - && (lookaheadTerm().quantityType == QuantifierFixedCount) - && (lookaheadTerm().quantityCount == 1); - } - - int inputOffset() - { - return term().inputPosition - checkedTotal; - } - - void clearBacktrack() - { - m_backtrack.clear(false); - m_linkedBacktrack = 0; - } - - void jumpToBacktrack(MacroAssembler* masm) - { - m_backtrack.jumpToBacktrack(masm); - } - - void jumpToBacktrack(YarrGenerator* generator, Jump jump) - { - m_backtrack.jumpToBacktrack(generator, jump); - } - - void jumpToBacktrack(YarrGenerator* generator, JumpList& jumps) - { - m_backtrack.jumpToBacktrack(generator, jumps); - } - - bool plantJumpToBacktrackIfExists(YarrGenerator* generator) - { - return m_backtrack.plantJumpToBacktrackIfExists(generator); - } - - void linkDataLabelToBacktrackIfExists(YarrGenerator* generator, DataLabelPtr dataLabel) - { - // If we have a stack offset backtrack destination, use it directly - if (m_backtrack.isStackOffset()) { - generator->m_expressionState.addIndirectJumpEntry(m_backtrack.getStackOffset(), dataLabel); - m_backtrack.clearSubDataLabelPtr(); - } else { - // If we have a backtrack label, connect the datalabel to it directly. - if (m_backtrack.isLabel()) { - generator->m_expressionState.m_backtrackRecords.append(AlternativeBacktrackRecord(dataLabel, m_backtrack.getLabel())); - m_backtrack.clearSubDataLabelPtr(); - } else - setBacktrackDataLabel(dataLabel); + struct ReturnAddressRecord { + ReturnAddressRecord(DataLabelPtr dataLabel, Label backtrackLocation) + : m_dataLabel(dataLabel) + , m_backtrackLocation(backtrackLocation) + { } - } - void addBacktrackJump(Jump jump) - { - m_backtrack.addBacktrackJump(jump); - } - - void setBacktrackDataLabel(DataLabelPtr dp) - { - m_backtrack.setDataLabel(dp); - } - - void setBackTrackStackOffset(int32_t stackOffset) - { - m_backtrack.setStackOffset(stackOffset); - } - - void setBacktrackLabel(Label label) - { - m_backtrack.setLabel(label); - } - - void linkAlternativeBacktracks(YarrGenerator* generator, bool nextIteration = false) - { - m_backtrack.linkAlternativeBacktracks(generator, nextIteration); - m_linkedBacktrack = 0; - } - - void linkAlternativeBacktracksTo(YarrGenerator* generator, Label label, bool nextIteration = false) - { - m_backtrack.linkAlternativeBacktracksTo(generator, label, nextIteration); - } - - void setBacktrackLink(BacktrackDestination* linkedBacktrack) - { - m_linkedBacktrack = linkedBacktrack; - } - - void chainBacktracks(BacktrackDestination* followonBacktrack) - { - if (m_linkedBacktrack) - m_linkedBacktrack->linkToNextBacktrack(followonBacktrack); - } - - BacktrackDestination& getBacktrackDestination() - { - return m_backtrack; - } - - void propagateBacktrackingFrom(YarrGenerator* generator, BacktrackDestination& backtrack, bool doJump = true) - { - if (doJump) - m_backtrack.jumpToBacktrack(generator, backtrack.getBacktrackJumps()); - - if (m_backtrack.isLabel() && backtrack.hasBacktrackToLabel()) - backtrack.linkBacktrackToLabel(m_backtrack.getLabel()); - - if (backtrack.hasDestination()) { - if (m_backtrack.hasDataLabel()) - generator->m_expressionState.addDataLabelToNextIteration(m_backtrack.getDataLabel()); - - m_backtrack.copyTarget(backtrack, doJump); - } - } + DataLabelPtr m_dataLabel; + Label m_backtrackLocation; + }; - PatternDisjunction* disjunction; - int checkedTotal; - private: - unsigned alt; - unsigned t; - unsigned m_subParenNum; - BacktrackDestination m_backtrack; - BacktrackDestination* m_linkedBacktrack; - JumpList* m_jumpList; + JumpList m_laterFailures; + bool m_pendingFallthrough; + Vector m_pendingReturns; + Vector m_backtrackRecords; }; - struct ParenthesesTail { - ParenthesesTail(PatternTerm& term, int nestingLevel, JumpList* jumpListToPriorParen) - : m_term(term) - , m_nestingLevel(nestingLevel) - , m_subParenIndex(0) - , m_jumpListToPriorParen(jumpListToPriorParen) - { - } - - void processBacktracks(YarrGenerator* generator, TermGenerationState& state, TermGenerationState& parenthesesState, Label nonGreedyTryParentheses, Label fallThrough) - { - m_nonGreedyTryParentheses = nonGreedyTryParentheses; - m_fallThrough = fallThrough; - - m_subParenIndex = state.getSubParenNum(); - parenthesesState.getBacktrackDestination().copyTo(m_parenBacktrack); - state.chainBacktracks(&m_backtrack); - BacktrackDestination& stateBacktrack = state.getBacktrackDestination(); - stateBacktrack.copyTo(m_backtrack); - stateBacktrack.setBacktrackToLabel(&m_backtrackToLabel); - state.setBacktrackLink(&m_backtrack); - stateBacktrack.setSubDataLabelPtr(&m_dataAfterLabelPtr); - - m_doDirectBacktrack = m_parenBacktrack.hasDestination(); - - if ((m_term.quantityType == QuantifierGreedy) || (m_term.quantityType == QuantifierNonGreedy)) - m_doDirectBacktrack = false; - - if (m_doDirectBacktrack) - state.propagateBacktrackingFrom(generator, m_parenBacktrack, false); - else { - stateBacktrack.setBacktrackJumpList(&m_afterBacktrackJumps); - stateBacktrack.setBacktrackSourceLabel(&m_backtrackFromAfterParens); - } - } - - void setNextIteration(Label nextIteration) - { - if (!m_nestingLevel && !m_backtrackToLabel.isSet()) - m_backtrackToLabel = nextIteration; - } - - void addAfterParenJump(Jump jump) - { - m_afterBacktrackJumps.append(jump); - } - - bool generateCode(YarrGenerator* generator, JumpList& jumpsToNext, bool priorBackTrackFallThrough, bool nextBacktrackFallThrough) - { - const RegisterID indexTemporary = regT0; - unsigned parenthesesFrameLocation = m_term.frameLocation; - Jump fromPriorBacktrack; - bool needJumpForPriorParenTail = false; - - if (priorBackTrackFallThrough - && ((m_term.quantityType == QuantifierGreedy) - || (m_term.quantityType == QuantifierNonGreedy) - || (!m_doDirectBacktrack && m_parenBacktrack.hasDestination()))) { - // If the prior paren tail code assumed that it could fall through, - // but we need to generate after paren backtrack code, then provide - // a jump around that code for the prior paren tail code. - // A regular expressing like ((xxx)...)? needs this. - fromPriorBacktrack = generator->jump(); - needJumpForPriorParenTail = true; - } - - if (!m_backtrack.hasDestination()) { - if (m_backtrackToLabel.isSet()) { - m_backtrack.setLabel(m_backtrackToLabel); - nextBacktrackFallThrough = false; - } else if (m_jumpListToPriorParen) { - // If we don't have a destination, go back to either the prior paren or the next outer paren. - m_backtrack.setBacktrackJumpList(m_jumpListToPriorParen); - nextBacktrackFallThrough = false; - } else - m_backtrack.setBacktrackJumpList(&jumpsToNext); - } else - nextBacktrackFallThrough = false; - - // A failure AFTER the parens jumps here - Backtrack to this paren - m_backtrackFromAfterParens = generator->label(); - - if (m_dataAfterLabelPtr.isSet()) - generator->m_expressionState.m_backtrackRecords.append(AlternativeBacktrackRecord(m_dataAfterLabelPtr, m_backtrackFromAfterParens)); - - m_afterBacktrackJumps.link(generator); - - if (m_term.quantityType == QuantifierGreedy) { - // If this is -1 we have now tested with both with and without the parens. - generator->loadFromFrame(parenthesesFrameLocation, indexTemporary); - m_backtrack.jumpToBacktrack(generator, generator->branch32(Equal, indexTemporary, TrustedImm32(-1))); - } else if (m_term.quantityType == QuantifierNonGreedy) { - // If this is -1 we have now tested with both with and without the parens. - generator->loadFromFrame(parenthesesFrameLocation, indexTemporary); - generator->branch32(Equal, indexTemporary, TrustedImm32(-1)).linkTo(m_nonGreedyTryParentheses, generator); - } - - if (!m_doDirectBacktrack) - m_parenBacktrack.plantJumpToBacktrackIfExists(generator); - - // A failure WITHIN the parens jumps here - if (needJumpForPriorParenTail) - fromPriorBacktrack.link(generator); - m_parenBacktrack.linkAlternativeBacktracks(generator); - m_withinBacktrackJumps.link(generator); - - if (m_term.capture()) - generator->store32(TrustedImm32(-1), Address(output, (m_term.parentheses.subpatternId << 1) * sizeof(int))); + // Generation methods: + // =================== - if (m_term.quantityType == QuantifierGreedy) { - generator->storeToFrame(TrustedImm32(-1), parenthesesFrameLocation); - generator->jump().linkTo(m_fallThrough, generator); - nextBacktrackFallThrough = false; - } else if (!nextBacktrackFallThrough) - m_backtrack.jumpToBacktrack(generator); - - if (!m_doDirectBacktrack) - m_backtrack.setNextBacktrackLabel(m_backtrackFromAfterParens); - - return nextBacktrackFallThrough; - } - - PatternTerm& m_term; - int m_nestingLevel; - unsigned m_subParenIndex; - JumpList* m_jumpListToPriorParen; - Label m_nonGreedyTryParentheses; - Label m_fallThrough; - Label m_backtrackToLabel; - Label m_backtrackFromAfterParens; - DataLabelPtr m_dataAfterLabelPtr; - JumpList m_withinBacktrackJumps; - JumpList m_afterBacktrackJumps; - BacktrackDestination m_parenBacktrack; - BacktrackDestination m_backtrack; - bool m_doDirectBacktrack; - }; + // This method provides a default implementation of backtracking common + // to many terms; terms commonly jump out of the forwards matching path + // on any failed conditions, and add these jumps to the m_jumps list. If + // no special handling is required we can often just backtrack to m_jumps. + void backtrackTermDefault(size_t opIndex) + { + YarrOp& op = m_ops[opIndex]; + m_backtrackingState.append(op.m_jumps); + } - void generateAssertionBOL(TermGenerationState& state) + void generateAssertionBOL(size_t opIndex) { - PatternTerm& term = state.term(); + YarrOp& op = m_ops[opIndex]; + PatternTerm* term = op.m_term; if (m_pattern.m_multiline) { const RegisterID character = regT0; JumpList matchDest; - if (!term.inputPosition) - matchDest.append(branch32(Equal, index, Imm32(state.checkedTotal))); + if (!term->inputPosition) + matchDest.append(branch32(Equal, index, Imm32(m_checked))); - readCharacter(state.inputOffset() - 1, character); + readCharacter((term->inputPosition - m_checked) - 1, character); matchCharacterClass(character, matchDest, m_pattern.newlineCharacterClass()); - state.jumpToBacktrack(this); + op.m_jumps.append(jump()); matchDest.link(this); } else { // Erk, really should poison out these alternatives early. :-/ - if (term.inputPosition) - state.jumpToBacktrack(this); + if (term->inputPosition) + op.m_jumps.append(jump()); else - state.jumpToBacktrack(this, branch32(NotEqual, index, Imm32(state.checkedTotal))); + op.m_jumps.append(branch32(NotEqual, index, Imm32(m_checked))); } } + void backtrackAssertionBOL(size_t opIndex) + { + backtrackTermDefault(opIndex); + } - void generateAssertionEOL(TermGenerationState& state) + void generateAssertionEOL(size_t opIndex) { - PatternTerm& term = state.term(); + YarrOp& op = m_ops[opIndex]; + PatternTerm* term = op.m_term; if (m_pattern.m_multiline) { const RegisterID character = regT0; JumpList matchDest; - if (term.inputPosition == state.checkedTotal) + if (term->inputPosition == m_checked) matchDest.append(atEndOfInput()); - readCharacter(state.inputOffset(), character); + readCharacter((term->inputPosition - m_checked), character); matchCharacterClass(character, matchDest, m_pattern.newlineCharacterClass()); - state.jumpToBacktrack(this); + op.m_jumps.append(jump()); matchDest.link(this); } else { - if (term.inputPosition == state.checkedTotal) - state.jumpToBacktrack(this, notAtEndOfInput()); + if (term->inputPosition == m_checked) + op.m_jumps.append(notAtEndOfInput()); // Erk, really should poison out these alternatives early. :-/ else - state.jumpToBacktrack(this); + op.m_jumps.append(jump()); } } + void backtrackAssertionEOL(size_t opIndex) + { + backtrackTermDefault(opIndex); + } // Also falls though on nextIsNotWordChar. - void matchAssertionWordchar(TermGenerationState& state, JumpList& nextIsWordChar, JumpList& nextIsNotWordChar) + void matchAssertionWordchar(size_t opIndex, JumpList& nextIsWordChar, JumpList& nextIsNotWordChar) { + YarrOp& op = m_ops[opIndex]; + PatternTerm* term = op.m_term; + const RegisterID character = regT0; - PatternTerm& term = state.term(); - if (term.inputPosition == state.checkedTotal) + if (term->inputPosition == m_checked) nextIsNotWordChar.append(atEndOfInput()); - readCharacter(state.inputOffset(), character); + readCharacter((term->inputPosition - m_checked), character); matchCharacterClass(character, nextIsWordChar, m_pattern.wordcharCharacterClass()); } - void generateAssertionWordBoundary(TermGenerationState& state) + void generateAssertionWordBoundary(size_t opIndex) { + YarrOp& op = m_ops[opIndex]; + PatternTerm* term = op.m_term; + const RegisterID character = regT0; - PatternTerm& term = state.term(); Jump atBegin; JumpList matchDest; - if (!term.inputPosition) - atBegin = branch32(Equal, index, Imm32(state.checkedTotal)); - readCharacter(state.inputOffset() - 1, character); + if (!term->inputPosition) + atBegin = branch32(Equal, index, Imm32(m_checked)); + readCharacter((term->inputPosition - m_checked) - 1, character); matchCharacterClass(character, matchDest, m_pattern.wordcharCharacterClass()); - if (!term.inputPosition) + if (!term->inputPosition) atBegin.link(this); // We fall through to here if the last character was not a wordchar. JumpList nonWordCharThenWordChar; JumpList nonWordCharThenNonWordChar; - if (term.invert()) { - matchAssertionWordchar(state, nonWordCharThenNonWordChar, nonWordCharThenWordChar); + if (term->invert()) { + matchAssertionWordchar(opIndex, nonWordCharThenNonWordChar, nonWordCharThenWordChar); nonWordCharThenWordChar.append(jump()); } else { - matchAssertionWordchar(state, nonWordCharThenWordChar, nonWordCharThenNonWordChar); + matchAssertionWordchar(opIndex, nonWordCharThenWordChar, nonWordCharThenNonWordChar); nonWordCharThenNonWordChar.append(jump()); } - state.jumpToBacktrack(this, nonWordCharThenNonWordChar); + op.m_jumps.append(nonWordCharThenNonWordChar); // We jump here if the last character was a wordchar. matchDest.link(this); JumpList wordCharThenWordChar; JumpList wordCharThenNonWordChar; - if (term.invert()) { - matchAssertionWordchar(state, wordCharThenNonWordChar, wordCharThenWordChar); + if (term->invert()) { + matchAssertionWordchar(opIndex, wordCharThenNonWordChar, wordCharThenWordChar); wordCharThenWordChar.append(jump()); } else { - matchAssertionWordchar(state, wordCharThenWordChar, wordCharThenNonWordChar); + matchAssertionWordchar(opIndex, wordCharThenWordChar, wordCharThenNonWordChar); // This can fall-though! } - state.jumpToBacktrack(this, wordCharThenWordChar); + op.m_jumps.append(wordCharThenWordChar); nonWordCharThenWordChar.link(this); wordCharThenNonWordChar.link(this); } + void backtrackAssertionWordBoundary(size_t opIndex) + { + backtrackTermDefault(opIndex); + } - void generatePatternCharacterSingle(TermGenerationState& state) + void generatePatternCharacterOnce(size_t opIndex) { + YarrOp& op = m_ops[opIndex]; + + // m_ops always ends with a OpBodyAlternativeEnd or OpMatchFailed + // node, so there must always be at least one more node. + ASSERT(opIndex + 1 < m_ops.size()); + YarrOp& nextOp = m_ops[opIndex + 1]; + + if (op.m_isDeadCode) + return; + + PatternTerm* term = op.m_term; + UChar ch = term->patternCharacter; + const RegisterID character = regT0; - UChar ch = state.term().patternCharacter; + + if (nextOp.m_op == OpTerm) { + PatternTerm* nextTerm = nextOp.m_term; + if (nextTerm->type == PatternTerm::TypePatternCharacter + && nextTerm->quantityType == QuantifierFixedCount + && nextTerm->quantityCount == 1 + && nextTerm->inputPosition == (term->inputPosition + 1)) { + + UChar ch2 = nextTerm->patternCharacter; + + int mask = 0; + int chPair = ch | (ch2 << 16); + + if (m_pattern.m_ignoreCase) { + if (isASCIIAlpha(ch)) + mask |= 32; + if (isASCIIAlpha(ch2)) + mask |= 32 << 16; + } + + BaseIndex address(input, index, TimesTwo, (term->inputPosition - m_checked) * sizeof(UChar)); + if (mask) { + load32WithUnalignedHalfWords(address, character); + or32(Imm32(mask), character); + op.m_jumps.append(branch32(NotEqual, character, Imm32(chPair | mask))); + } else + op.m_jumps.append(branch32WithUnalignedHalfWords(NotEqual, address, Imm32(chPair))); + + nextOp.m_isDeadCode = true; + return; + } + } if (m_pattern.m_ignoreCase && isASCIIAlpha(ch)) { - readCharacter(state.inputOffset(), character); + readCharacter(term->inputPosition - m_checked, character); or32(TrustedImm32(32), character); - state.jumpToBacktrack(this, branch32(NotEqual, character, Imm32(Unicode::toLower(ch)))); + op.m_jumps.append(branch32(NotEqual, character, Imm32(Unicode::toLower(ch)))); } else { ASSERT(!m_pattern.m_ignoreCase || (Unicode::toLower(ch) == Unicode::toUpper(ch))); - state.jumpToBacktrack(this, jumpIfCharNotEquals(ch, state.inputOffset())); + op.m_jumps.append(jumpIfCharNotEquals(ch, term->inputPosition - m_checked)); } } - - void generatePatternCharacterPair(TermGenerationState& state) + void backtrackPatternCharacterOnce(size_t opIndex) { - const RegisterID character = regT0; - UChar ch1 = state.term().patternCharacter; - UChar ch2 = state.lookaheadTerm().patternCharacter; - - int mask = 0; - int chPair = ch1 | (ch2 << 16); - - if (m_pattern.m_ignoreCase) { - if (isASCIIAlpha(ch1)) - mask |= 32; - if (isASCIIAlpha(ch2)) - mask |= 32 << 16; - } - - if (mask) { - load32WithUnalignedHalfWords(BaseIndex(input, index, TimesTwo, state.inputOffset() * sizeof(UChar)), character); - or32(Imm32(mask), character); - state.jumpToBacktrack(this, branch32(NotEqual, character, Imm32(chPair | mask))); - } else - state.jumpToBacktrack(this, branch32WithUnalignedHalfWords(NotEqual, BaseIndex(input, index, TimesTwo, state.inputOffset() * sizeof(UChar)), Imm32(chPair))); + backtrackTermDefault(opIndex); } - void generatePatternCharacterFixed(TermGenerationState& state) + void generatePatternCharacterFixed(size_t opIndex) { + YarrOp& op = m_ops[opIndex]; + PatternTerm* term = op.m_term; + UChar ch = term->patternCharacter; + const RegisterID character = regT0; const RegisterID countRegister = regT1; - PatternTerm& term = state.term(); - UChar ch = term.patternCharacter; move(index, countRegister); - sub32(Imm32(term.quantityCount), countRegister); + sub32(Imm32(term->quantityCount), countRegister); Label loop(this); + BaseIndex address(input, countRegister, TimesTwo, (term->inputPosition - m_checked + term->quantityCount) * sizeof(UChar)); + if (m_pattern.m_ignoreCase && isASCIIAlpha(ch)) { - load16(BaseIndex(input, countRegister, TimesTwo, (state.inputOffset() + term.quantityCount) * sizeof(UChar)), character); + load16(address, character); or32(TrustedImm32(32), character); - state.jumpToBacktrack(this, branch32(NotEqual, character, Imm32(Unicode::toLower(ch)))); + op.m_jumps.append(branch32(NotEqual, character, Imm32(Unicode::toLower(ch)))); } else { ASSERT(!m_pattern.m_ignoreCase || (Unicode::toLower(ch) == Unicode::toUpper(ch))); - state.jumpToBacktrack(this, branch16(NotEqual, BaseIndex(input, countRegister, TimesTwo, (state.inputOffset() + term.quantityCount) * sizeof(UChar)), Imm32(ch))); + op.m_jumps.append(branch16(NotEqual, address, Imm32(ch))); } add32(TrustedImm32(1), countRegister); branch32(NotEqual, countRegister, index).linkTo(loop, this); } + void backtrackPatternCharacterFixed(size_t opIndex) + { + backtrackTermDefault(opIndex); + } - void generatePatternCharacterGreedy(TermGenerationState& state) + void generatePatternCharacterGreedy(size_t opIndex) { + YarrOp& op = m_ops[opIndex]; + PatternTerm* term = op.m_term; + UChar ch = term->patternCharacter; + const RegisterID character = regT0; const RegisterID countRegister = regT1; - PatternTerm& term = state.term(); - UChar ch = term.patternCharacter; move(TrustedImm32(0), countRegister); @@ -1352,121 +752,152 @@ class YarrGenerator : private MacroAssembler { Label loop(this); failures.append(atEndOfInput()); if (m_pattern.m_ignoreCase && isASCIIAlpha(ch)) { - readCharacter(state.inputOffset(), character); + readCharacter(term->inputPosition - m_checked, character); or32(TrustedImm32(32), character); failures.append(branch32(NotEqual, character, Imm32(Unicode::toLower(ch)))); } else { ASSERT(!m_pattern.m_ignoreCase || (Unicode::toLower(ch) == Unicode::toUpper(ch))); - failures.append(jumpIfCharNotEquals(ch, state.inputOffset())); + failures.append(jumpIfCharNotEquals(ch, term->inputPosition - m_checked)); } add32(TrustedImm32(1), countRegister); add32(TrustedImm32(1), index); - if (term.quantityCount != quantifyInfinite) { - branch32(NotEqual, countRegister, Imm32(term.quantityCount)).linkTo(loop, this); - failures.append(jump()); - } else + if (term->quantityCount == quantifyInfinite) jump(loop); - - Label backtrackBegin(this); - loadFromFrame(term.frameLocation, countRegister); - state.jumpToBacktrack(this, branchTest32(Zero, countRegister)); - sub32(TrustedImm32(1), countRegister); - sub32(TrustedImm32(1), index); + else + branch32(NotEqual, countRegister, Imm32(term->quantityCount)).linkTo(loop, this); failures.link(this); + op.m_reentry = label(); - storeToFrame(countRegister, term.frameLocation); + storeToFrame(countRegister, term->frameLocation); - state.setBacktrackLabel(backtrackBegin); } + void backtrackPatternCharacterGreedy(size_t opIndex) + { + YarrOp& op = m_ops[opIndex]; + PatternTerm* term = op.m_term; + + const RegisterID countRegister = regT1; - void generatePatternCharacterNonGreedy(TermGenerationState& state) + m_backtrackingState.link(this); + + loadFromFrame(term->frameLocation, countRegister); + m_backtrackingState.append(branchTest32(Zero, countRegister)); + sub32(TrustedImm32(1), countRegister); + sub32(TrustedImm32(1), index); + jump(op.m_reentry); + } + + void generatePatternCharacterNonGreedy(size_t opIndex) { - const RegisterID character = regT0; + YarrOp& op = m_ops[opIndex]; + PatternTerm* term = op.m_term; + const RegisterID countRegister = regT1; - PatternTerm& term = state.term(); - UChar ch = term.patternCharacter; move(TrustedImm32(0), countRegister); + op.m_reentry = label(); + storeToFrame(countRegister, term->frameLocation); + } + void backtrackPatternCharacterNonGreedy(size_t opIndex) + { + YarrOp& op = m_ops[opIndex]; + PatternTerm* term = op.m_term; + UChar ch = term->patternCharacter; + + const RegisterID character = regT0; + const RegisterID countRegister = regT1; - Jump firstTimeDoNothing = jump(); + JumpList nonGreedyFailures; - Label hardFail(this); - sub32(countRegister, index); - state.jumpToBacktrack(this); + m_backtrackingState.link(this); - Label backtrackBegin(this); - loadFromFrame(term.frameLocation, countRegister); + loadFromFrame(term->frameLocation, countRegister); - atEndOfInput().linkTo(hardFail, this); - if (term.quantityCount != quantifyInfinite) - branch32(Equal, countRegister, Imm32(term.quantityCount), hardFail); + nonGreedyFailures.append(atEndOfInput()); + if (term->quantityCount != quantifyInfinite) + nonGreedyFailures.append(branch32(Equal, countRegister, Imm32(term->quantityCount))); if (m_pattern.m_ignoreCase && isASCIIAlpha(ch)) { - readCharacter(state.inputOffset(), character); + readCharacter(term->inputPosition - m_checked, character); or32(TrustedImm32(32), character); - branch32(NotEqual, character, Imm32(Unicode::toLower(ch))).linkTo(hardFail, this); + nonGreedyFailures.append(branch32(NotEqual, character, Imm32(Unicode::toLower(ch)))); } else { ASSERT(!m_pattern.m_ignoreCase || (Unicode::toLower(ch) == Unicode::toUpper(ch))); - jumpIfCharNotEquals(ch, state.inputOffset()).linkTo(hardFail, this); + nonGreedyFailures.append(jumpIfCharNotEquals(ch, term->inputPosition - m_checked)); } add32(TrustedImm32(1), countRegister); add32(TrustedImm32(1), index); - firstTimeDoNothing.link(this); - storeToFrame(countRegister, term.frameLocation); + jump(op.m_reentry); - state.setBacktrackLabel(backtrackBegin); + nonGreedyFailures.link(this); + sub32(countRegister, index); + m_backtrackingState.fallthrough(); } - void generateCharacterClassSingle(TermGenerationState& state) + void generateCharacterClassOnce(size_t opIndex) { + YarrOp& op = m_ops[opIndex]; + PatternTerm* term = op.m_term; + const RegisterID character = regT0; - PatternTerm& term = state.term(); JumpList matchDest; - readCharacter(state.inputOffset(), character); - matchCharacterClass(character, matchDest, term.characterClass); + readCharacter((term->inputPosition - m_checked), character); + matchCharacterClass(character, matchDest, term->characterClass); - if (term.invert()) - state.jumpToBacktrack(this, matchDest); + if (term->invert()) + op.m_jumps.append(matchDest); else { - state.jumpToBacktrack(this); + op.m_jumps.append(jump()); matchDest.link(this); } } + void backtrackCharacterClassOnce(size_t opIndex) + { + backtrackTermDefault(opIndex); + } - void generateCharacterClassFixed(TermGenerationState& state) + void generateCharacterClassFixed(size_t opIndex) { + YarrOp& op = m_ops[opIndex]; + PatternTerm* term = op.m_term; + const RegisterID character = regT0; const RegisterID countRegister = regT1; - PatternTerm& term = state.term(); move(index, countRegister); - sub32(Imm32(term.quantityCount), countRegister); + sub32(Imm32(term->quantityCount), countRegister); Label loop(this); JumpList matchDest; - load16(BaseIndex(input, countRegister, TimesTwo, (state.inputOffset() + term.quantityCount) * sizeof(UChar)), character); - matchCharacterClass(character, matchDest, term.characterClass); + load16(BaseIndex(input, countRegister, TimesTwo, (term->inputPosition - m_checked + term->quantityCount) * sizeof(UChar)), character); + matchCharacterClass(character, matchDest, term->characterClass); - if (term.invert()) - state.jumpToBacktrack(this, matchDest); + if (term->invert()) + op.m_jumps.append(matchDest); else { - state.jumpToBacktrack(this); + op.m_jumps.append(jump()); matchDest.link(this); } add32(TrustedImm32(1), countRegister); branch32(NotEqual, countRegister, index).linkTo(loop, this); } + void backtrackCharacterClassFixed(size_t opIndex) + { + backtrackTermDefault(opIndex); + } - void generateCharacterClassGreedy(TermGenerationState& state) + void generateCharacterClassGreedy(size_t opIndex) { + YarrOp& op = m_ops[opIndex]; + PatternTerm* term = op.m_term; + const RegisterID character = regT0; const RegisterID countRegister = regT1; - PatternTerm& term = state.term(); move(TrustedImm32(0), countRegister); @@ -1474,692 +905,1356 @@ class YarrGenerator : private MacroAssembler { Label loop(this); failures.append(atEndOfInput()); - if (term.invert()) { - readCharacter(state.inputOffset(), character); - matchCharacterClass(character, failures, term.characterClass); + if (term->invert()) { + readCharacter(term->inputPosition - m_checked, character); + matchCharacterClass(character, failures, term->characterClass); } else { JumpList matchDest; - readCharacter(state.inputOffset(), character); - matchCharacterClass(character, matchDest, term.characterClass); + readCharacter(term->inputPosition - m_checked, character); + matchCharacterClass(character, matchDest, term->characterClass); failures.append(jump()); matchDest.link(this); } add32(TrustedImm32(1), countRegister); add32(TrustedImm32(1), index); - if (term.quantityCount != quantifyInfinite) { - branch32(NotEqual, countRegister, Imm32(term.quantityCount)).linkTo(loop, this); + if (term->quantityCount != quantifyInfinite) { + branch32(NotEqual, countRegister, Imm32(term->quantityCount)).linkTo(loop, this); failures.append(jump()); } else jump(loop); - Label backtrackBegin(this); - loadFromFrame(term.frameLocation, countRegister); - state.jumpToBacktrack(this, branchTest32(Zero, countRegister)); - sub32(TrustedImm32(1), countRegister); - sub32(TrustedImm32(1), index); - failures.link(this); + op.m_reentry = label(); + + storeToFrame(countRegister, term->frameLocation); + } + void backtrackCharacterClassGreedy(size_t opIndex) + { + YarrOp& op = m_ops[opIndex]; + PatternTerm* term = op.m_term; + + const RegisterID countRegister = regT1; - storeToFrame(countRegister, term.frameLocation); + m_backtrackingState.link(this); - state.setBacktrackLabel(backtrackBegin); + loadFromFrame(term->frameLocation, countRegister); + m_backtrackingState.append(branchTest32(Zero, countRegister)); + sub32(TrustedImm32(1), countRegister); + sub32(TrustedImm32(1), index); + jump(op.m_reentry); } - void generateCharacterClassNonGreedy(TermGenerationState& state) + void generateCharacterClassNonGreedy(size_t opIndex) { - const RegisterID character = regT0; + YarrOp& op = m_ops[opIndex]; + PatternTerm* term = op.m_term; + const RegisterID countRegister = regT1; - PatternTerm& term = state.term(); move(TrustedImm32(0), countRegister); + op.m_reentry = label(); + storeToFrame(countRegister, term->frameLocation); + } + void backtrackCharacterClassNonGreedy(size_t opIndex) + { + YarrOp& op = m_ops[opIndex]; + PatternTerm* term = op.m_term; - Jump firstTimeDoNothing = jump(); + const RegisterID character = regT0; + const RegisterID countRegister = regT1; - Label hardFail(this); - sub32(countRegister, index); - state.jumpToBacktrack(this); + JumpList nonGreedyFailures; + + m_backtrackingState.link(this); Label backtrackBegin(this); - loadFromFrame(term.frameLocation, countRegister); + loadFromFrame(term->frameLocation, countRegister); - atEndOfInput().linkTo(hardFail, this); - branch32(Equal, countRegister, Imm32(term.quantityCount), hardFail); + nonGreedyFailures.append(atEndOfInput()); + nonGreedyFailures.append(branch32(Equal, countRegister, Imm32(term->quantityCount))); JumpList matchDest; - readCharacter(state.inputOffset(), character); - matchCharacterClass(character, matchDest, term.characterClass); + readCharacter(term->inputPosition - m_checked, character); + matchCharacterClass(character, matchDest, term->characterClass); - if (term.invert()) - matchDest.linkTo(hardFail, this); + if (term->invert()) + nonGreedyFailures.append(matchDest); else { - jump(hardFail); + nonGreedyFailures.append(jump()); matchDest.link(this); } add32(TrustedImm32(1), countRegister); add32(TrustedImm32(1), index); - firstTimeDoNothing.link(this); - storeToFrame(countRegister, term.frameLocation); + jump(op.m_reentry); + + nonGreedyFailures.link(this); + sub32(countRegister, index); + m_backtrackingState.fallthrough(); + } + + // Code generation/backtracking for simple terms + // (pattern characters, character classes, and assertions). + // These methods farm out work to the set of functions above. + void generateTerm(size_t opIndex) + { + YarrOp& op = m_ops[opIndex]; + PatternTerm* term = op.m_term; + + switch (term->type) { + case PatternTerm::TypePatternCharacter: + switch (term->quantityType) { + case QuantifierFixedCount: + if (term->quantityCount == 1) + generatePatternCharacterOnce(opIndex); + else + generatePatternCharacterFixed(opIndex); + break; + case QuantifierGreedy: + generatePatternCharacterGreedy(opIndex); + break; + case QuantifierNonGreedy: + generatePatternCharacterNonGreedy(opIndex); + break; + } + break; - state.setBacktrackLabel(backtrackBegin); + case PatternTerm::TypeCharacterClass: + switch (term->quantityType) { + case QuantifierFixedCount: + if (term->quantityCount == 1) + generateCharacterClassOnce(opIndex); + else + generateCharacterClassFixed(opIndex); + break; + case QuantifierGreedy: + generateCharacterClassGreedy(opIndex); + break; + case QuantifierNonGreedy: + generateCharacterClassNonGreedy(opIndex); + break; + } + break; + + case PatternTerm::TypeAssertionBOL: + generateAssertionBOL(opIndex); + break; + + case PatternTerm::TypeAssertionEOL: + generateAssertionEOL(opIndex); + break; + + case PatternTerm::TypeAssertionWordBoundary: + generateAssertionWordBoundary(opIndex); + break; + + case PatternTerm::TypeForwardReference: + break; + + case PatternTerm::TypeParenthesesSubpattern: + case PatternTerm::TypeParentheticalAssertion: + ASSERT_NOT_REACHED(); + case PatternTerm::TypeBackReference: + m_shouldFallBack = true; + break; + } } - - void generateParenthesesDisjunction(PatternTerm& parenthesesTerm, TermGenerationState& state, unsigned alternativeFrameLocation) + void backtrackTerm(size_t opIndex) { - ASSERT((parenthesesTerm.type == PatternTerm::TypeParenthesesSubpattern) || (parenthesesTerm.type == PatternTerm::TypeParentheticalAssertion)); - ASSERT(parenthesesTerm.quantityCount == 1); - - PatternDisjunction* disjunction = parenthesesTerm.parentheses.disjunction; - unsigned preCheckedCount = ((parenthesesTerm.quantityType == QuantifierFixedCount) && (parenthesesTerm.type != PatternTerm::TypeParentheticalAssertion)) ? disjunction->m_minimumSize : 0; - - if (disjunction->m_alternatives.size() == 1) { - state.resetAlternative(); - ASSERT(state.alternativeValid()); - PatternAlternative* alternative = state.alternative(); - optimizeAlternative(alternative); + YarrOp& op = m_ops[opIndex]; + PatternTerm* term = op.m_term; - int countToCheck = alternative->m_minimumSize - preCheckedCount; - if (countToCheck) { - ASSERT((parenthesesTerm.type == PatternTerm::TypeParentheticalAssertion) || (parenthesesTerm.quantityType != QuantifierFixedCount)); + switch (term->type) { + case PatternTerm::TypePatternCharacter: + switch (term->quantityType) { + case QuantifierFixedCount: + if (term->quantityCount == 1) + backtrackPatternCharacterOnce(opIndex); + else + backtrackPatternCharacterFixed(opIndex); + break; + case QuantifierGreedy: + backtrackPatternCharacterGreedy(opIndex); + break; + case QuantifierNonGreedy: + backtrackPatternCharacterNonGreedy(opIndex); + break; + } + break; - // FIXME: This is quite horrible. The call to 'plantJumpToBacktrackIfExists' - // will be forced to always trampoline into here, just to decrement the index. - // Ick. - Jump skip = jump(); + case PatternTerm::TypeCharacterClass: + switch (term->quantityType) { + case QuantifierFixedCount: + if (term->quantityCount == 1) + backtrackCharacterClassOnce(opIndex); + else + backtrackCharacterClassFixed(opIndex); + break; + case QuantifierGreedy: + backtrackCharacterClassGreedy(opIndex); + break; + case QuantifierNonGreedy: + backtrackCharacterClassNonGreedy(opIndex); + break; + } + break; - Label backtrackBegin(this); - sub32(Imm32(countToCheck), index); - state.addBacktrackJump(jump()); + case PatternTerm::TypeAssertionBOL: + backtrackAssertionBOL(opIndex); + break; - skip.link(this); + case PatternTerm::TypeAssertionEOL: + backtrackAssertionEOL(opIndex); + break; - state.setBacktrackLabel(backtrackBegin); + case PatternTerm::TypeAssertionWordBoundary: + backtrackAssertionWordBoundary(opIndex); + break; - state.jumpToBacktrack(this, jumpIfNoAvailableInput(countToCheck)); - state.checkedTotal += countToCheck; - } + case PatternTerm::TypeForwardReference: + break; - for (state.resetTerm(); state.termValid(); state.nextTerm()) - generateTerm(state); + case PatternTerm::TypeParenthesesSubpattern: + case PatternTerm::TypeParentheticalAssertion: + ASSERT_NOT_REACHED(); + case PatternTerm::TypeBackReference: + m_shouldFallBack = true; + break; + } + } - state.checkedTotal -= countToCheck; - } else { - JumpList successes; - bool propogateBacktrack = false; + void generate() + { + // Forwards generate the matching code. + ASSERT(m_ops.size()); + size_t opIndex = 0; - // Save current state's paren jump list for use with each alternative - JumpList* outerJumpList = state.getJumpListToPriorParen(); + do { + YarrOp& op = m_ops[opIndex]; + switch (op.m_op) { - for (state.resetAlternative(); state.alternativeValid(); state.nextAlternative(), state.setJumpListToPriorParen(outerJumpList)) { - PatternAlternative* alternative = state.alternative(); - optimizeAlternative(alternative); + case OpTerm: + generateTerm(opIndex); + break; - ASSERT(alternative->m_minimumSize >= preCheckedCount); - int countToCheck = alternative->m_minimumSize - preCheckedCount; - if (countToCheck) { - state.addBacktrackJump(jumpIfNoAvailableInput(countToCheck)); - state.checkedTotal += countToCheck; + // OpBodyAlternativeBegin/Next/End + // + // These nodes wrap the set of alternatives in the body of the regular expression. + // There may be either one or two chains of OpBodyAlternative nodes, one representing + // the 'once through' sequence of alternatives (if any exist), and one representing + // the repeating alternatives (again, if any exist). + // + // Upon normal entry to the Begin alternative, we will check that input is available. + // Reentry to the Begin alternative will take place after the check has taken place, + // and will assume that the input position has already been progressed as appropriate. + // + // Entry to subsequent Next/End alternatives occurs when the prior alternative has + // successfully completed a match - return a success state from JIT code. + // + // Next alternatives allow for reentry optimized to suit backtracking from its + // preceding alternative. It expects the input position to still be set to a position + // appropriate to its predecessor, and it will only perform an input check if the + // predecessor had a minimum size less than its own. + // + // In the case 'once through' expressions, the End node will also have a reentry + // point to jump to when the last alternative fails. Again, this expects the input + // position to still reflect that expected by the prior alternative. + case OpBodyAlternativeBegin: { + PatternAlternative* alternative = op.m_alternative; + + // Upon entry at the head of the set of alternatives, check if input is available + // to run the first alternative. (This progresses the input position). + op.m_jumps.append(jumpIfNoAvailableInput(alternative->m_minimumSize)); + // We will reenter after the check, and assume the input position to have been + // set as appropriate to this alternative. + op.m_reentry = label(); + + m_checked += alternative->m_minimumSize; + break; + } + case OpBodyAlternativeNext: + case OpBodyAlternativeEnd: { + PatternAlternative* priorAlternative = m_ops[op.m_previousOp].m_alternative; + PatternAlternative* alternative = op.m_alternative; + + // If we get here, the prior alternative matched - return success. + + // Adjust the stack pointer to remove the pattern's frame. + if (m_pattern.m_body->m_callFrameSize) + addPtr(Imm32(m_pattern.m_body->m_callFrameSize * sizeof(void*)), stackPointerRegister); + + // Load appropriate values into the return register and the first output + // slot, and return. In the case of pattern with a fixed size, we will + // not have yet set the value in the first + ASSERT(index != returnRegister); + if (m_pattern.m_body->m_hasFixedSize) { + move(index, returnRegister); + if (priorAlternative->m_minimumSize) + sub32(Imm32(priorAlternative->m_minimumSize), returnRegister); + store32(returnRegister, output); + } else + load32(Address(output), returnRegister); + store32(index, Address(output, 4)); + generateReturn(); + + // This is the divide between the tail of the prior alternative, above, and + // the head of the subsequent alternative, below. + + if (op.m_op == OpBodyAlternativeNext) { + // This is the reentry point for the Next alternative. We expect any code + // that jumps here to do so with the input position matching that of the + // PRIOR alteranative, and we will only check input availability if we + // need to progress it forwards. + op.m_reentry = label(); + if (int delta = alternative->m_minimumSize - priorAlternative->m_minimumSize) { + add32(Imm32(delta), index); + if (delta > 0) + op.m_jumps.append(jumpIfNoAvailableInput()); + } + } else if (op.m_nextOp == notFound) { + // This is the reentry point for the End of 'once through' alternatives, + // jumped to when the las alternative fails to match. + op.m_reentry = label(); + sub32(Imm32(priorAlternative->m_minimumSize), index); } - for (state.resetTerm(); state.termValid(); state.nextTerm()) - generateTerm(state); + if (op.m_op == OpBodyAlternativeNext) + m_checked += alternative->m_minimumSize; + m_checked -= priorAlternative->m_minimumSize; + break; + } - // Matched an alternative. - DataLabelPtr dataLabel = storeToFrameWithPatch(alternativeFrameLocation); + // OpSimpleNestedAlternativeBegin/Next/End + // OpNestedAlternativeBegin/Next/End + // + // These nodes are used to handle sets of alternatives that are nested within + // subpatterns and parenthetical assertions. The 'simple' forms are used where + // we do not need to be able to backtrack back into any alternative other than + // the last, the normal forms allow backtracking into any alternative. + // + // Each Begin/Next node is responsible for planting an input check to ensure + // sufficient input is available on entry. Next nodes additionally need to + // jump to the end - Next nodes use the End node's m_jumps list to hold this + // set of jumps. + // + // In the non-simple forms, successful alternative matches must store a + // 'return address' using a DataLabelPtr, used to store the address to jump + // to when backtracking, to get to the code for the appropriate alternative. + case OpSimpleNestedAlternativeBegin: + case OpNestedAlternativeBegin: { + PatternTerm* term = op.m_term; + PatternAlternative* alternative = op.m_alternative; + PatternDisjunction* disjunction = term->parentheses.disjunction; + + // Calculate how much input we need to check for, and if non-zero check. + op.m_checkAdjust = alternative->m_minimumSize; + if ((term->quantityType == QuantifierFixedCount) && (term->type != PatternTerm::TypeParentheticalAssertion)) + op.m_checkAdjust -= disjunction->m_minimumSize; + if (op.m_checkAdjust) + op.m_jumps.append(jumpIfNoAvailableInput(op.m_checkAdjust)); + + m_checked += op.m_checkAdjust; + break; + } + case OpSimpleNestedAlternativeNext: + case OpNestedAlternativeNext: { + PatternTerm* term = op.m_term; + PatternAlternative* alternative = op.m_alternative; + PatternDisjunction* disjunction = term->parentheses.disjunction; + + // In the non-simple case, store a 'return address' so we can backtrack correctly. + if (op.m_op == OpNestedAlternativeNext) { + unsigned parenthesesFrameLocation = term->frameLocation; + unsigned alternativeFrameLocation = parenthesesFrameLocation; + if (term->quantityType != QuantifierFixedCount) + alternativeFrameLocation += YarrStackSpaceForBackTrackInfoParenthesesOnce; + op.m_returnAddress = storeToFrameWithPatch(alternativeFrameLocation); + } - if (!state.isLastAlternative() || countToCheck) - successes.append(jump()); + // If we reach here then the last alternative has matched - jump to the + // End node, to skip over any further alternatives. + // + // FIXME: this is logically O(N^2) (though N can be expected to be very + // small). We could avoid this either by adding an extra jump to the JIT + // data structures, or by making backtracking code that jumps to Next + // alternatives are responsible for checking that input is available (if + // we didn't need to plant the input checks, then m_jumps would be free). + YarrOp* endOp = &m_ops[op.m_nextOp]; + while (endOp->m_nextOp != notFound) { + ASSERT(endOp->m_op == OpSimpleNestedAlternativeNext || endOp->m_op == OpNestedAlternativeNext); + endOp = &m_ops[endOp->m_nextOp]; + } + ASSERT(endOp->m_op == OpSimpleNestedAlternativeEnd || endOp->m_op == OpNestedAlternativeEnd); + endOp->m_jumps.append(jump()); + + // This is the entry point for the next alternative. + op.m_reentry = label(); + + // Calculate how much input we need to check for, and if non-zero check. + op.m_checkAdjust = alternative->m_minimumSize; + if ((term->quantityType == QuantifierFixedCount) && (term->type != PatternTerm::TypeParentheticalAssertion)) + op.m_checkAdjust -= disjunction->m_minimumSize; + if (op.m_checkAdjust) + op.m_jumps.append(jumpIfNoAvailableInput(op.m_checkAdjust)); + + YarrOp& lastOp = m_ops[op.m_previousOp]; + m_checked -= lastOp.m_checkAdjust; + m_checked += op.m_checkAdjust; + break; + } + case OpSimpleNestedAlternativeEnd: + case OpNestedAlternativeEnd: { + PatternTerm* term = op.m_term; + + // In the non-simple case, store a 'return address' so we can backtrack correctly. + if (op.m_op == OpNestedAlternativeEnd) { + unsigned parenthesesFrameLocation = term->frameLocation; + unsigned alternativeFrameLocation = parenthesesFrameLocation; + if (term->quantityType != QuantifierFixedCount) + alternativeFrameLocation += YarrStackSpaceForBackTrackInfoParenthesesOnce; + op.m_returnAddress = storeToFrameWithPatch(alternativeFrameLocation); + } - // Alternative did not match. + // If this set of alternatives contains more than one alternative, + // then the Next nodes will have planted jumps to the End, and added + // them to this node's m_jumps list. + op.m_jumps.link(this); + op.m_jumps.clear(); - // Do we have a backtrack destination? - // if so, link the data label to it. - state.linkDataLabelToBacktrackIfExists(this, dataLabel); + YarrOp& lastOp = m_ops[op.m_previousOp]; + m_checked -= lastOp.m_checkAdjust; + break; + } - if (!state.isLastAlternative() || countToCheck) - state.linkAlternativeBacktracks(this); + // OpParenthesesSubpatternOnceBegin/End + // + // These nodes support (optionally) capturing subpatterns, that have a + // quantity count of 1 (this covers fixed once, and ?/?? quantifiers). + case OpParenthesesSubpatternOnceBegin: { + PatternTerm* term = op.m_term; + unsigned parenthesesFrameLocation = term->frameLocation; + const RegisterID indexTemporary = regT0; + ASSERT(term->quantityCount == 1); + + // Upon entry to a Greedy quantified set of parenthese store the index. + // We'll use this for two purposes: + // - To indicate which iteration we are on of mathing the remainder of + // the expression after the parentheses - the first, including the + // match within the parentheses, or the second having skipped over them. + // - To check for empty matches, which must be rejected. + // + // At the head of a NonGreedy set of parentheses we'll immediately set the + // value on the stack to -1 (indicating a match skipping the subpattern), + // and plant a jump to the end. We'll also plant a label to backtrack to + // to reenter the subpattern later, with a store to set up index on the + // second iteration. + // + // FIXME: for capturing parens, could use the index in the capture array? + if (term->quantityType == QuantifierGreedy) + storeToFrame(index, parenthesesFrameLocation); + else if (term->quantityType == QuantifierNonGreedy) { + storeToFrame(TrustedImm32(-1), parenthesesFrameLocation); + op.m_jumps.append(jump()); + op.m_reentry = label(); + storeToFrame(index, parenthesesFrameLocation); + } - if (countToCheck) { - sub32(Imm32(countToCheck), index); - state.checkedTotal -= countToCheck; - } else if (state.isLastAlternative()) - propogateBacktrack = true; + // If the parenthese are capturing, store the starting index value to the + // captures array, offsetting as necessary. + // + // FIXME: could avoid offsetting this value in JIT code, apply + // offsets only afterwards, at the point the results array is + // being accessed. + if (term->capture()) { + int offsetId = term->parentheses.subpatternId << 1; + int inputOffset = term->inputPosition - m_checked; + if (term->quantityType == QuantifierFixedCount) + inputOffset -= term->parentheses.disjunction->m_minimumSize; + if (inputOffset) { + move(index, indexTemporary); + add32(Imm32(inputOffset), indexTemporary); + store32(indexTemporary, Address(output, offsetId * sizeof(int))); + } else + store32(index, Address(output, offsetId * sizeof(int))); + } + break; } - // We fall through to here when the last alternative fails. - // Add a backtrack out of here for the parenthese handling code to link up. - if (!propogateBacktrack) - state.addBacktrackJump(jump()); - - // Save address on stack for the parens code to backtrack to, to retry the - // next alternative. - state.setBackTrackStackOffset(alternativeFrameLocation * sizeof(void*)); + case OpParenthesesSubpatternOnceEnd: { + PatternTerm* term = op.m_term; + unsigned parenthesesFrameLocation = term->frameLocation; + const RegisterID indexTemporary = regT0; + ASSERT(term->quantityCount == 1); + + // For Greedy/NonGreedy quantified parentheses, we must reject zero length + // matches. If the minimum size is know to be non-zero we need not check. + if (term->quantityType != QuantifierFixedCount && !term->parentheses.disjunction->m_minimumSize) + op.m_jumps.append(branch32(Equal, index, Address(stackPointerRegister, parenthesesFrameLocation * sizeof(void*)))); + + // If the parenthese are capturing, store the ending index value to the + // captures array, offsetting as necessary. + // + // FIXME: could avoid offsetting this value in JIT code, apply + // offsets only afterwards, at the point the results array is + // being accessed. + if (term->capture()) { + int offsetId = (term->parentheses.subpatternId << 1) + 1; + int inputOffset = term->inputPosition - m_checked; + if (inputOffset) { + move(index, indexTemporary); + add32(Imm32(inputOffset), indexTemporary); + store32(indexTemporary, Address(output, offsetId * sizeof(int))); + } else + store32(index, Address(output, offsetId * sizeof(int))); + } - successes.link(this); - } - } + // If the parentheses are quantified Greedy then add a label to jump back + // to if get a failed match from after the parentheses. For NonGreedy + // parentheses, link the jump from before the subpattern to here. + if (term->quantityType == QuantifierGreedy) + op.m_reentry = label(); + else if (term->quantityType == QuantifierNonGreedy) { + YarrOp& beginOp = m_ops[op.m_previousOp]; + beginOp.m_jumps.link(this); + } + break; + } - void generateParenthesesSingle(TermGenerationState& state) - { - const RegisterID indexTemporary = regT0; - PatternTerm& term = state.term(); - PatternDisjunction* disjunction = term.parentheses.disjunction; - ASSERT(term.quantityCount == 1); + // OpParenthesesSubpatternTerminalBegin/End + case OpParenthesesSubpatternTerminalBegin: { + PatternTerm* term = op.m_term; + ASSERT(term->quantityType == QuantifierGreedy); + ASSERT(term->quantityCount == quantifyInfinite); + ASSERT(!term->capture()); - unsigned preCheckedCount = (term.quantityType == QuantifierFixedCount) ? disjunction->m_minimumSize : 0; + // Upon entry set a label to loop back to. + op.m_reentry = label(); - unsigned parenthesesFrameLocation = term.frameLocation; - unsigned alternativeFrameLocation = parenthesesFrameLocation; - if (term.quantityType != QuantifierFixedCount) - alternativeFrameLocation += YarrStackSpaceForBackTrackInfoParenthesesOnce; + // Store the start index of the current match; we need to reject zero + // length matches. + storeToFrame(index, term->frameLocation); + break; + } + case OpParenthesesSubpatternTerminalEnd: { + PatternTerm* term = op.m_term; - // optimized case - no capture & no quantifier can be handled in a light-weight manner. - if (!term.capture() && (term.quantityType == QuantifierFixedCount)) { - m_expressionState.incrementParenNestingLevel(); + // Check for zero length matches - if the match is non-zero, then we + // can accept it & loop back up to the head of the subpattern. + YarrOp& beginOp = m_ops[op.m_previousOp]; + branch32(NotEqual, index, Address(stackPointerRegister, term->frameLocation * sizeof(void*)), beginOp.m_reentry); - TermGenerationState parenthesesState(disjunction, state.checkedTotal); + // Reject the match - backtrack back into the subpattern. + op.m_jumps.append(jump()); - // Use the current state's jump list for the nested parentheses. - parenthesesState.setJumpListToPriorParen(state.getJumpListToPriorParen()); + // This is the entry point to jump to when we stop matching - we will + // do so once the subpattern cannot match any more. + op.m_reentry = label(); + break; + } - generateParenthesesDisjunction(state.term(), parenthesesState, alternativeFrameLocation); - // this expects that any backtracks back out of the parentheses will be in the - // parenthesesState's m_backTrackJumps vector, and that if they need backtracking - // they will have set an entry point on the parenthesesState's m_backtrackLabel. - BacktrackDestination& parenthesesBacktrack = parenthesesState.getBacktrackDestination(); - BacktrackDestination& stateBacktrack = state.getBacktrackDestination(); + // OpParentheticalAssertionBegin/End + case OpParentheticalAssertionBegin: { + PatternTerm* term = op.m_term; - state.propagateBacktrackingFrom(this, parenthesesBacktrack); - stateBacktrack.propagateBacktrackToLabel(parenthesesBacktrack); + // Store the current index - assertions should not update index, so + // we will need to restore it upon a successful match. + unsigned parenthesesFrameLocation = term->frameLocation; + storeToFrame(index, parenthesesFrameLocation); - state.setJumpListToPriorParen(parenthesesState.getJumpListToPriorParen()); + // Check + op.m_checkAdjust = m_checked - term->inputPosition; + if (op.m_checkAdjust) + sub32(Imm32(op.m_checkAdjust), index); - m_expressionState.decrementParenNestingLevel(); - } else { - Jump nonGreedySkipParentheses; - Label nonGreedyTryParentheses; - if (term.quantityType == QuantifierGreedy) - storeToFrame(index, parenthesesFrameLocation); - else if (term.quantityType == QuantifierNonGreedy) { - storeToFrame(TrustedImm32(-1), parenthesesFrameLocation); - nonGreedySkipParentheses = jump(); - nonGreedyTryParentheses = label(); - storeToFrame(index, parenthesesFrameLocation); + m_checked -= op.m_checkAdjust; + break; } + case OpParentheticalAssertionEnd: { + PatternTerm* term = op.m_term; + + // Restore the input index value. + unsigned parenthesesFrameLocation = term->frameLocation; + loadFromFrame(parenthesesFrameLocation, index); + + // If inverted, a successful match of the assertion must be treated + // as a failure, so jump to backtracking. + if (term->invert()) { + op.m_jumps.append(jump()); + op.m_reentry = label(); + } - // store the match start index - if (term.capture()) { - int inputOffset = state.inputOffset() - preCheckedCount; - if (inputOffset) { - move(index, indexTemporary); - add32(Imm32(inputOffset), indexTemporary); - store32(indexTemporary, Address(output, (term.parentheses.subpatternId << 1) * sizeof(int))); - } else - store32(index, Address(output, (term.parentheses.subpatternId << 1) * sizeof(int))); + YarrOp& lastOp = m_ops[op.m_previousOp]; + m_checked += lastOp.m_checkAdjust; + break; } - ParenthesesTail* parenthesesTail = m_expressionState.addParenthesesTail(term, state.getJumpListToPriorParen()); - - m_expressionState.incrementParenNestingLevel(); - - TermGenerationState parenthesesState(disjunction, state.checkedTotal); - - // Save the parenthesesTail for backtracking from nested parens to this one. - parenthesesState.setJumpListToPriorParen(&parenthesesTail->m_withinBacktrackJumps); - - // generate the body of the parentheses - generateParenthesesDisjunction(state.term(), parenthesesState, alternativeFrameLocation); - - // For non-fixed counts, backtrack if we didn't match anything. - if (term.quantityType != QuantifierFixedCount) - parenthesesTail->addAfterParenJump(branch32(Equal, index, Address(stackPointerRegister, (parenthesesFrameLocation * sizeof(void*))))); - - // store the match end index - if (term.capture()) { - int inputOffset = state.inputOffset(); - if (inputOffset) { - move(index, indexTemporary); - add32(Imm32(state.inputOffset()), indexTemporary); - store32(indexTemporary, Address(output, ((term.parentheses.subpatternId << 1) + 1) * sizeof(int))); - } else - store32(index, Address(output, ((term.parentheses.subpatternId << 1) + 1) * sizeof(int))); + case OpMatchFailed: + if (m_pattern.m_body->m_callFrameSize) + addPtr(Imm32(m_pattern.m_body->m_callFrameSize * sizeof(void*)), stackPointerRegister); + move(TrustedImm32(-1), returnRegister); + generateReturn(); + break; } - m_expressionState.decrementParenNestingLevel(); - - parenthesesTail->processBacktracks(this, state, parenthesesState, nonGreedyTryParentheses, label()); - - state.setJumpListToPriorParen(&parenthesesTail->m_afterBacktrackJumps); - - parenthesesState.getBacktrackDestination().clear(); - - if (term.quantityType == QuantifierNonGreedy) - nonGreedySkipParentheses.link(this); - } + ++opIndex; + } while (opIndex < m_ops.size()); } - void generateParenthesesGreedyNoBacktrack(TermGenerationState& state) + void backtrack() { - PatternTerm& parenthesesTerm = state.term(); - PatternDisjunction* disjunction = parenthesesTerm.parentheses.disjunction; - ASSERT(parenthesesTerm.type == PatternTerm::TypeParenthesesSubpattern); - ASSERT(parenthesesTerm.quantityCount != 1); // Handled by generateParenthesesSingle. + // Backwards generate the backtracking code. + size_t opIndex = m_ops.size(); + ASSERT(opIndex); - TermGenerationState parenthesesState(disjunction, state.checkedTotal); + do { + --opIndex; + YarrOp& op = m_ops[opIndex]; + switch (op.m_op) { - Label matchAgain(this); + case OpTerm: + backtrackTerm(opIndex); + break; - storeToFrame(index, parenthesesTerm.frameLocation); // Save the current index to check for zero len matches later. + // OpBodyAlternativeBegin/Next/End + // + // For each Begin/Next node representing an alternative, we need to decide what to do + // in two circumstances: + // - If we backtrack back into this node, from within the alternative. + // - If the input check at the head of the alternative fails (if this exists). + // + // We treat these two cases differently since in the former case we have slightly + // more information - since we are backtracking out of a prior alternative we know + // that at least enough input was available to run it. For example, given the regular + // expression /a|b/, if we backtrack out of the first alternative (a failed pattern + // character match of 'a'), then we need not perform an additional input availability + // check before running the second alternative. + // + // Backtracking required differs for the last alternative, which in the case of the + // repeating set of alternatives must loop. The code generated for the last alternative + // will also be used to handle all input check failures from any prior alternatives - + // these require similar functionality, in seeking the next available alternative for + // which there is sufficient input. + // + // Since backtracking of all other alternatives simply requires us to link backtracks + // to the reentry point for the subsequent alternative, we will only be generating any + // code when backtracking the last alternative. + case OpBodyAlternativeBegin: + case OpBodyAlternativeNext: { + PatternAlternative* alternative = op.m_alternative; + + if (op.m_op == OpBodyAlternativeNext) { + PatternAlternative* priorAlternative = m_ops[op.m_previousOp].m_alternative; + m_checked += priorAlternative->m_minimumSize; + } + m_checked -= alternative->m_minimumSize; - for (parenthesesState.resetAlternative(); parenthesesState.alternativeValid(); parenthesesState.nextAlternative()) { + // Is this the last alternative? If not, then if we backtrack to this point we just + // need to jump to try to match the next alternative. + if (m_ops[op.m_nextOp].m_op != OpBodyAlternativeEnd) { + m_backtrackingState.linkTo(m_ops[op.m_nextOp].m_reentry, this); + break; + } + YarrOp& endOp = m_ops[op.m_nextOp]; - PatternAlternative* alternative = parenthesesState.alternative(); - optimizeAlternative(alternative); + YarrOp* beginOp = &op; + while (beginOp->m_op != OpBodyAlternativeBegin) { + ASSERT(beginOp->m_op == OpBodyAlternativeNext); + beginOp = &m_ops[beginOp->m_previousOp]; + } - int countToCheck = alternative->m_minimumSize; - if (countToCheck) { - parenthesesState.addBacktrackJump(jumpIfNoAvailableInput(countToCheck)); - parenthesesState.checkedTotal += countToCheck; - } + bool onceThrough = endOp.m_nextOp == notFound; + + // First, generate code to handle cases where we backtrack out of an attempted match + // of the last alternative. If this is a 'once through' set of alternatives then we + // have nothing to do - link this straight through to the End. + if (onceThrough) + m_backtrackingState.linkTo(endOp.m_reentry, this); + else { + // Okay, we're going to need to loop. Calculate the delta between where the input + // position was, and where we want it to be allowing for the fact that we need to + // increment by 1. E.g. for the regexp /a|x/ we need to increment the position by + // 1 between loop iterations, but for /abcd|xyz/ we need to increment by two when + // looping from the last alternative to the first, for /a|xyz/ we need to decrement + // by 1, and for /a|xy/ we don't need to move the input position at all. + int deltaLastAlternativeToFirstAlternativePlusOne = (beginOp->m_alternative->m_minimumSize - alternative->m_minimumSize) + 1; + + // If we don't need to move the input poistion, and the pattern has a fixed size + // (in which case we omit the store of the start index until the pattern has matched) + // then we can just link the backtrack out of the last alternative straight to the + // head of the first alternative. + if (!deltaLastAlternativeToFirstAlternativePlusOne && m_pattern.m_body->m_hasFixedSize) + m_backtrackingState.linkTo(beginOp->m_reentry, this); + else { + // We need to generate a trampoline of code to execute before looping back + // around to the first alternative. + m_backtrackingState.link(this); + + // If the pattern size is not fixed, then store the start index, for use if we match. + if (!m_pattern.m_body->m_hasFixedSize) { + if (alternative->m_minimumSize == 1) + store32(index, Address(output)); + else { + move(index, regT0); + if (alternative->m_minimumSize) + sub32(Imm32(alternative->m_minimumSize - 1), regT0); + else + add32(Imm32(1), regT0); + store32(regT0, Address(output)); + } + } + + if (deltaLastAlternativeToFirstAlternativePlusOne) + add32(Imm32(deltaLastAlternativeToFirstAlternativePlusOne), index); + + // Loop. Since this code is only reached when we backtrack out of the last + // alternative (and NOT linked to from the input check upon entry to the + // last alternative) we know that there must be at least enough input as + // required by the last alternative. As such, we only need to check if the + // first will require more to run - if the same or less is required we can + // unconditionally jump. + if (deltaLastAlternativeToFirstAlternativePlusOne > 0) + checkInput().linkTo(beginOp->m_reentry, this); + else + jump(beginOp->m_reentry); + } + } - for (parenthesesState.resetTerm(); parenthesesState.termValid(); parenthesesState.nextTerm()) - generateTerm(parenthesesState); + // We can reach this point in the code in two ways: + // - Fallthrough from the code above (a repeating alternative backtracked out of its + // last alternative, and did not have sufficent input to run the first). + // - We will loop back up to the following label when a releating alternative loops, + // following a failed input check. + // + // Either way, we have just failed the input check for the first alternative. + Label firstInputCheckFailed(this); + + // Generate code to handle input check failures from alternatives except the last. + // prevOp is the alternative we're handling a bail out from (initially Begin), and + // nextOp is the alternative we will be attempting to reenter into. + // + // We will link input check failures from the forwards matching path back to the code + // that can handle them. + YarrOp* prevOp = beginOp; + YarrOp* nextOp = &m_ops[beginOp->m_nextOp]; + while (nextOp->m_op != OpBodyAlternativeEnd) { + prevOp->m_jumps.link(this); + + int delta = nextOp->m_alternative->m_minimumSize - prevOp->m_alternative->m_minimumSize; + if (delta) + add32(Imm32(delta), index); + + // We only get here if an input check fails, it is only worth checking again + // if the next alternative has a minimum size less than the last. + if (delta < 0) { + // FIXME: if we added an extra label to YarrOp, we could avoid needing to + // subtract delta back out, and reduce this code. Should performance test + // the benefit of this. + Jump fail = jumpIfNoAvailableInput(); + sub32(Imm32(delta), index); + jump(nextOp->m_reentry); + fail.link(this); + } + prevOp = nextOp; + nextOp = &m_ops[nextOp->m_nextOp]; + } - // If we get here, we matched! If the index advanced then try to match more since limit isn't supported yet. - branch32(NotEqual, index, Address(stackPointerRegister, (parenthesesTerm.frameLocation * sizeof(void*))), matchAgain); + // We fall through to here if there is insufficient input to run the last alternative. - // If we get here we matched, but we matched "" - cannot accept this alternative as is, so either backtrack, - // or fall through to try the next alternative if no backtrack is available. - parenthesesState.plantJumpToBacktrackIfExists(this); + // If there is insufficient input to run the last alternative, then for 'once through' + // alternatives we are done - just jump back up into the forwards matching path at the End. + if (onceThrough) { + op.m_jumps.linkTo(endOp.m_reentry, this); + jump(endOp.m_reentry); + break; + } - parenthesesState.linkAlternativeBacktracks(this); + // For repeating alternatives, link any input check failure from the last alternative to + // this point. + op.m_jumps.link(this); - // We get here if the alternative fails to match - fall through to the next iteration, or out of the loop. + bool needsToUpdateMatchStart = !m_pattern.m_body->m_hasFixedSize; - if (countToCheck) { - sub32(Imm32(countToCheck), index); - parenthesesState.checkedTotal -= countToCheck; - } - } + // Check for cases where input position is already incremented by 1 for the last + // alternative (this is particularly useful where the minimum size of the body + // disjunction is 0, e.g. /a*|b/). + if (needsToUpdateMatchStart && alternative->m_minimumSize == 1) { + // index is already incremented by 1, so just store it now! + store32(index, Address(output)); + needsToUpdateMatchStart = false; + } - // If the last alternative falls through to here, we have a failed match... - // Which means that we match whatever we have matched up to this point (even if nothing). - } + // Check whether there is sufficient input to loop. Increment the input position by + // one, and check. Also add in the minimum disjunction size before checking - there + // is no point in looping if we're just going to fail all the input checks around + // the next iteration. + int deltaLastAlternativeToBodyMinimumPlusOne = (m_pattern.m_body->m_minimumSize + 1) - alternative->m_minimumSize; + if (deltaLastAlternativeToBodyMinimumPlusOne) + add32(Imm32(deltaLastAlternativeToBodyMinimumPlusOne), index); + Jump matchFailed = jumpIfNoAvailableInput(); + + if (needsToUpdateMatchStart) { + if (!m_pattern.m_body->m_minimumSize) + store32(index, Address(output)); + else { + move(index, regT0); + sub32(Imm32(m_pattern.m_body->m_minimumSize), regT0); + store32(regT0, Address(output)); + } + } - void generateParentheticalAssertion(TermGenerationState& state) - { - PatternTerm& term = state.term(); - PatternDisjunction* disjunction = term.parentheses.disjunction; - ASSERT(term.quantityCount == 1); - ASSERT(term.quantityType == QuantifierFixedCount); + // Calculate how much more input the first alternative requires than the minimum + // for the body as a whole. If no more is needed then we dont need an additional + // input check here - jump straight back up to the start of the first alternative. + int deltaBodyMinimumToFirstAlternative = beginOp->m_alternative->m_minimumSize - m_pattern.m_body->m_minimumSize; + if (!deltaBodyMinimumToFirstAlternative) + jump(beginOp->m_reentry); + else { + add32(Imm32(deltaBodyMinimumToFirstAlternative), index); + checkInput().linkTo(beginOp->m_reentry, this); + jump(firstInputCheckFailed); + } - unsigned parenthesesFrameLocation = term.frameLocation; - unsigned alternativeFrameLocation = parenthesesFrameLocation + YarrStackSpaceForBackTrackInfoParentheticalAssertion; + // We jump to here if we iterate to the point that there is insufficient input to + // run any matches, and need to return a failure state from JIT code. + matchFailed.link(this); - int countCheckedAfterAssertion = state.checkedTotal - term.inputPosition; + if (m_pattern.m_body->m_callFrameSize) + addPtr(Imm32(m_pattern.m_body->m_callFrameSize * sizeof(void*)), stackPointerRegister); + move(TrustedImm32(-1), returnRegister); + generateReturn(); + break; + } + case OpBodyAlternativeEnd: { + // We should never backtrack back into a body disjunction. + ASSERT(m_backtrackingState.isEmpty()); - if (term.invert()) { - // Inverted case - storeToFrame(index, parenthesesFrameLocation); + PatternAlternative* priorAlternative = m_ops[op.m_previousOp].m_alternative; + m_checked += priorAlternative->m_minimumSize; + break; + } - state.checkedTotal -= countCheckedAfterAssertion; - if (countCheckedAfterAssertion) - sub32(Imm32(countCheckedAfterAssertion), index); + // OpSimpleNestedAlternativeBegin/Next/End + // OpNestedAlternativeBegin/Next/End + // + // Generate code for when we backtrack back out of an alternative into + // a Begin or Next node, or when the entry input count check fails. If + // there are more alternatives we need to jump to the next alternative, + // if not we backtrack back out of the current set of parentheses. + // + // In the case of non-simple nested assertions we need to also link the + // 'return address' appropriately to backtrack back out into the correct + // alternative. + case OpSimpleNestedAlternativeBegin: + case OpSimpleNestedAlternativeNext: + case OpNestedAlternativeBegin: + case OpNestedAlternativeNext: { + YarrOp& nextOp = m_ops[op.m_nextOp]; + bool isBegin = op.m_previousOp == notFound; + bool isLastAlternative = nextOp.m_nextOp == notFound; + ASSERT(isBegin == (op.m_op == OpSimpleNestedAlternativeBegin || op.m_op == OpNestedAlternativeBegin)); + ASSERT(isLastAlternative == (nextOp.m_op == OpSimpleNestedAlternativeEnd || nextOp.m_op == OpNestedAlternativeEnd)); + + // Treat an input check failure the same as a failed match. + m_backtrackingState.append(op.m_jumps); + + // Set the backtracks to jump to the appropriate place. We may need + // to link the backtracks in one of three different way depending on + // the type of alternative we are dealing with: + // - A single alternative, with no simplings. + // - The last alternative of a set of two or more. + // - An alternative other than the last of a set of two or more. + // + // In the case of a single alternative on its own, we don't need to + // jump anywhere - if the alternative fails to match we can just + // continue to backtrack out of the parentheses without jumping. + // + // In the case of the last alternative in a set of more than one, we + // need to jump to return back out to the beginning. We'll do so by + // adding a jump to the End node's m_jumps list, and linking this + // when we come to generate the Begin node. For alternatives other + // than the last, we need to jump to the next alternative. + // + // If the alternative had adjusted the input position we must link + // backtracking to here, correct, and then jump on. If not we can + // link the backtracks directly to their destination. + if (op.m_checkAdjust) { + // Handle the cases where we need to link the backtracks here. + m_backtrackingState.link(this); + sub32(Imm32(op.m_checkAdjust), index); + if (!isLastAlternative) { + // An alternative that is not the last should jump to its successor. + jump(nextOp.m_reentry); + } else if (!isBegin) { + // The last of more than one alternatives must jump back to the begnning. + nextOp.m_jumps.append(jump()); + } else { + // A single alternative on its own can fall through. + m_backtrackingState.fallthrough(); + } + } else { + // Handle the cases where we can link the backtracks directly to their destinations. + if (!isLastAlternative) { + // An alternative that is not the last should jump to its successor. + m_backtrackingState.linkTo(nextOp.m_reentry, this); + } else if (!isBegin) { + // The last of more than one alternatives must jump back to the begnning. + m_backtrackingState.takeBacktracksToJumpList(nextOp.m_jumps, this); + } + // In the case of a single alternative on its own do nothing - it can fall through. + } - TermGenerationState parenthesesState(disjunction, state.checkedTotal); - generateParenthesesDisjunction(state.term(), parenthesesState, alternativeFrameLocation); - // Success! - which means - Fail! - loadFromFrame(parenthesesFrameLocation, index); - state.jumpToBacktrack(this); + // At this point we've handled the backtracking back into this node. + // Now link any backtracks that need to jump to here. + + // For non-simple alternatives, link the alternative's 'return address' + // so that we backtrack back out into the previous alternative. + if (op.m_op == OpNestedAlternativeNext) + m_backtrackingState.append(op.m_returnAddress); + + // If there is more than one alternative, then the last alternative will + // have planted a jump to be linked to the end. This jump was added to the + // End node's m_jumps list. If we are back at the beginning, link it here. + if (isBegin) { + YarrOp* endOp = &m_ops[op.m_nextOp]; + while (endOp->m_nextOp != notFound) { + ASSERT(endOp->m_op == OpSimpleNestedAlternativeNext || endOp->m_op == OpNestedAlternativeNext); + endOp = &m_ops[endOp->m_nextOp]; + } + ASSERT(endOp->m_op == OpSimpleNestedAlternativeEnd || endOp->m_op == OpNestedAlternativeEnd); + m_backtrackingState.append(endOp->m_jumps); + } - // And fail means success. - parenthesesState.linkAlternativeBacktracks(this); + if (!isBegin) { + YarrOp& lastOp = m_ops[op.m_previousOp]; + m_checked += lastOp.m_checkAdjust; + } + m_checked -= op.m_checkAdjust; + break; + } + case OpSimpleNestedAlternativeEnd: + case OpNestedAlternativeEnd: { + PatternTerm* term = op.m_term; + + // If we backtrack into the end of a simple subpattern do nothing; + // just continue through into the last alternative. If we backtrack + // into the end of a non-simple set of alterntives we need to jump + // to the backtracking return address set up during generation. + if (op.m_op == OpNestedAlternativeEnd) { + m_backtrackingState.link(this); + + // Plant a jump to the return address. + unsigned parenthesesFrameLocation = term->frameLocation; + unsigned alternativeFrameLocation = parenthesesFrameLocation; + if (term->quantityType != QuantifierFixedCount) + alternativeFrameLocation += YarrStackSpaceForBackTrackInfoParenthesesOnce; + loadFromFrameAndJump(alternativeFrameLocation); + + // Link the DataLabelPtr associated with the end of the last + // alternative to this point. + m_backtrackingState.append(op.m_returnAddress); + } - loadFromFrame(parenthesesFrameLocation, index); + YarrOp& lastOp = m_ops[op.m_previousOp]; + m_checked += lastOp.m_checkAdjust; + break; + } - state.checkedTotal += countCheckedAfterAssertion; - } else { - // Normal case - storeToFrame(index, parenthesesFrameLocation); + // OpParenthesesSubpatternOnceBegin/End + // + // When we are backtracking back out of a capturing subpattern we need + // to clear the start index in the matches output array, to record that + // this subpattern has not been captured. + // + // When backtracking back out of a Greedy quantified subpattern we need + // to catch this, and try running the remainder of the alternative after + // the subpattern again, skipping the parentheses. + // + // Upon backtracking back into a quantified set of parentheses we need to + // check whether we were currently skipping the subpattern. If not, we + // can backtrack into them, if we were we need to either backtrack back + // out of the start of the parentheses, or jump back to the forwards + // matching start, depending of whether the match is Greedy or NonGreedy. + case OpParenthesesSubpatternOnceBegin: { + PatternTerm* term = op.m_term; + ASSERT(term->quantityCount == 1); + + // We only need to backtrack to thispoint if capturing or greedy. + if (term->capture() || term->quantityType == QuantifierGreedy) { + m_backtrackingState.link(this); + + // If capturing, clear the capture (we only need to reset start). + if (term->capture()) + store32(TrustedImm32(-1), Address(output, (term->parentheses.subpatternId << 1) * sizeof(int))); + + // If Greedy, jump to the end. + if (term->quantityType == QuantifierGreedy) { + // Clear the flag in the stackframe indicating we ran through the subpattern. + unsigned parenthesesFrameLocation = term->frameLocation; + storeToFrame(TrustedImm32(-1), parenthesesFrameLocation); + // Jump to after the parentheses, skipping the subpattern. + jump(m_ops[op.m_nextOp].m_reentry); + // A backtrack from after the parentheses, when skipping the subpattern, + // will jump back to here. + op.m_jumps.link(this); + } - state.checkedTotal -= countCheckedAfterAssertion; - if (countCheckedAfterAssertion) - sub32(Imm32(countCheckedAfterAssertion), index); + m_backtrackingState.fallthrough(); + } + break; + } + case OpParenthesesSubpatternOnceEnd: { + PatternTerm* term = op.m_term; + + if (term->quantityType != QuantifierFixedCount) { + m_backtrackingState.link(this); + + // Check whether we should backtrack back into the parentheses, or if we + // are currently in a state where we had skipped over the subpattern + // (in which case the flag value on the stack will be -1). + unsigned parenthesesFrameLocation = term->frameLocation; + Jump hadSkipped = branch32(Equal, Address(stackPointerRegister, parenthesesFrameLocation * sizeof(void*)), TrustedImm32(-1)); + + if (term->quantityType == QuantifierGreedy) { + // For Greedy parentheses, we skip after having already tried going + // through the subpattern, so if we get here we're done. + YarrOp& beginOp = m_ops[op.m_previousOp]; + beginOp.m_jumps.append(hadSkipped); + } else { + // For NonGreedy parentheses, we try skipping the subpattern first, + // so if we get here we need to try running through the subpattern + // next. Jump back to the start of the parentheses in the forwards + // matching path. + ASSERT(term->quantityType == QuantifierNonGreedy); + YarrOp& beginOp = m_ops[op.m_previousOp]; + hadSkipped.linkTo(beginOp.m_reentry, this); + } - TermGenerationState parenthesesState(disjunction, state.checkedTotal); - generateParenthesesDisjunction(state.term(), parenthesesState, alternativeFrameLocation); - // Success! - which means - Success! - loadFromFrame(parenthesesFrameLocation, index); - Jump success = jump(); + m_backtrackingState.fallthrough(); + } - parenthesesState.linkAlternativeBacktracks(this); + m_backtrackingState.append(op.m_jumps); + break; + } - loadFromFrame(parenthesesFrameLocation, index); - state.jumpToBacktrack(this); + // OpParenthesesSubpatternTerminalBegin/End + // + // Terminal subpatterns will always match - there is nothing after them to + // force a backtrack, and they have a minimum count of 0, and as such will + // always produce an acceptable result. + case OpParenthesesSubpatternTerminalBegin: { + // We will backtrack to this point once the subpattern cannot match any + // more. Since no match is accepted as a successful match (we are Greedy + // quantified with a minimum of zero) jump back to the forwards matching + // path at the end. + YarrOp& endOp = m_ops[op.m_nextOp]; + m_backtrackingState.linkTo(endOp.m_reentry, this); + break; + } + case OpParenthesesSubpatternTerminalEnd: + // We should never be backtracking to here (hence the 'terminal' in the name). + ASSERT(m_backtrackingState.isEmpty()); + m_backtrackingState.append(op.m_jumps); + break; - success.link(this); + // OpParentheticalAssertionBegin/End + case OpParentheticalAssertionBegin: { + PatternTerm* term = op.m_term; + YarrOp& endOp = m_ops[op.m_nextOp]; - state.checkedTotal += countCheckedAfterAssertion; - } - } + // We need to handle the backtracks upon backtracking back out + // of a parenthetical assertion if either we need to correct + // the input index, or the assertion was inverted. + if (op.m_checkAdjust || term->invert()) { + m_backtrackingState.link(this); - void generateTerm(TermGenerationState& state) - { - PatternTerm& term = state.term(); + if (op.m_checkAdjust) + add32(Imm32(op.m_checkAdjust), index); - switch (term.type) { - case PatternTerm::TypeAssertionBOL: - generateAssertionBOL(state); - break; + // In an inverted assertion failure to match the subpattern + // is treated as a successful match - jump to the end of the + // subpattern. We already have adjusted the input position + // back to that before the assertion, which is correct. + if (term->invert()) + jump(endOp.m_reentry); - case PatternTerm::TypeAssertionEOL: - generateAssertionEOL(state); - break; + m_backtrackingState.fallthrough(); + } - case PatternTerm::TypeAssertionWordBoundary: - generateAssertionWordBoundary(state); - break; + // The End node's jump list will contain any backtracks into + // the end of the assertion. Also, if inverted, we will have + // added the failure caused by a successful match to this. + m_backtrackingState.append(endOp.m_jumps); - case PatternTerm::TypePatternCharacter: - switch (term.quantityType) { - case QuantifierFixedCount: - if (term.quantityCount == 1) { - if (state.isSinglePatternCharacterLookaheadTerm() && (state.lookaheadTerm().inputPosition == (term.inputPosition + 1))) { - generatePatternCharacterPair(state); - state.nextTerm(); - } else - generatePatternCharacterSingle(state); - } else - generatePatternCharacterFixed(state); - break; - case QuantifierGreedy: - generatePatternCharacterGreedy(state); - break; - case QuantifierNonGreedy: - generatePatternCharacterNonGreedy(state); + m_checked += op.m_checkAdjust; break; } - break; + case OpParentheticalAssertionEnd: { + // FIXME: We should really be clearing any nested subpattern + // matches on bailing out from after the pattern. Firefox has + // this bug too (presumably because they use YARR!) - case PatternTerm::TypeCharacterClass: - switch (term.quantityType) { - case QuantifierFixedCount: - if (term.quantityCount == 1) - generateCharacterClassSingle(state); - else - generateCharacterClassFixed(state); - break; - case QuantifierGreedy: - generateCharacterClassGreedy(state); - break; - case QuantifierNonGreedy: - generateCharacterClassNonGreedy(state); + // Never backtrack into an assertion; later failures bail to before the begin. + m_backtrackingState.takeBacktracksToJumpList(op.m_jumps, this); + + YarrOp& lastOp = m_ops[op.m_previousOp]; + m_checked -= lastOp.m_checkAdjust; break; } - break; - - case PatternTerm::TypeBackReference: - m_shouldFallBack = true; - break; - - case PatternTerm::TypeForwardReference: - break; - case PatternTerm::TypeParenthesesSubpattern: - if (term.quantityCount == 1 && !term.parentheses.isCopy) - generateParenthesesSingle(state); - else if (term.parentheses.isTerminal) - generateParenthesesGreedyNoBacktrack(state); - else - m_shouldFallBack = true; - break; + case OpMatchFailed: + break; + } - case PatternTerm::TypeParentheticalAssertion: - generateParentheticalAssertion(state); - break; - } + } while (opIndex); } - void generateDisjunction(PatternDisjunction* disjunction) + // Compilation methods: + // ==================== + + // opCompileParenthesesSubpattern + // Emits ops for a subpattern (set of parentheses). These consist + // of a set of alternatives wrapped in an outer set of nodes for + // the parentheses. + // Supported types of parentheses are 'Once' (quantityCount == 1) + // and 'Terminal' (non-capturing parentheses quantified as greedy + // and infinite). + // Alternatives will use the 'Simple' set of ops if either the + // subpattern is terminal (in which case we will never need to + // backtrack), or if the subpattern only contains one alternative. + void opCompileParenthesesSubpattern(PatternTerm* term) { - TermGenerationState state(disjunction, 0); - state.resetAlternative(); - - // check availability for the next alternative - int countCheckedForCurrentAlternative = 0; - int countToCheckForFirstAlternative = 0; - bool hasShorterAlternatives = false; - bool setRepeatAlternativeLabels = false; - JumpList notEnoughInputForPreviousAlternative; - Label firstAlternative; - Label firstAlternativeInputChecked; - - // The label 'firstAlternative' is used to plant a check to see if there is - // sufficient input available to run the first repeating alternative. - // The label 'firstAlternativeInputChecked' will jump directly to matching - // the first repeating alternative having skipped this check. - - if (state.alternativeValid()) { - PatternAlternative* alternative = state.alternative(); - if (!alternative->onceThrough()) { - firstAlternative = Label(this); - setRepeatAlternativeLabels = true; + YarrOpCode parenthesesBeginOpCode; + YarrOpCode parenthesesEndOpCode; + YarrOpCode alternativeBeginOpCode = OpSimpleNestedAlternativeBegin; + YarrOpCode alternativeNextOpCode = OpSimpleNestedAlternativeNext; + YarrOpCode alternativeEndOpCode = OpSimpleNestedAlternativeEnd; + + // We can currently only compile quantity 1 subpatterns that are + // not copies. We generate a copy in the case of a range quantifier, + // e.g. /(?:x){3,9}/, or /(?:x)+/ (These are effectively expanded to + // /(?:x){3,3}(?:x){0,6}/ and /(?:x)(?:x)*/ repectively). The problem + // comes where the subpattern is capturing, in which case we would + // need to restore the capture from the first subpattern upon a + // failure in the second. + if (term->quantityCount == 1 && !term->parentheses.isCopy) { + // Select the 'Once' nodes. + parenthesesBeginOpCode = OpParenthesesSubpatternOnceBegin; + parenthesesEndOpCode = OpParenthesesSubpatternOnceEnd; + + // If there is more than one alternative we cannot use the 'simple' nodes. + if (term->parentheses.disjunction->m_alternatives.size() != 1) { + alternativeBeginOpCode = OpNestedAlternativeBegin; + alternativeNextOpCode = OpNestedAlternativeNext; + alternativeEndOpCode = OpNestedAlternativeEnd; } - countToCheckForFirstAlternative = alternative->m_minimumSize; - state.checkedTotal += countToCheckForFirstAlternative; - if (countToCheckForFirstAlternative) - notEnoughInputForPreviousAlternative.append(jumpIfNoAvailableInput(countToCheckForFirstAlternative)); - countCheckedForCurrentAlternative = countToCheckForFirstAlternative; + } else if (term->parentheses.isTerminal) { + // Select the 'Terminal' nodes. + parenthesesBeginOpCode = OpParenthesesSubpatternTerminalBegin; + parenthesesEndOpCode = OpParenthesesSubpatternTerminalEnd; + } else { + // This subpattern is not supported by the JIT. + m_shouldFallBack = true; + return; } - if (setRepeatAlternativeLabels) - firstAlternativeInputChecked = Label(this); - - while (state.alternativeValid()) { - PatternAlternative* alternative = state.alternative(); - optimizeAlternative(alternative); - - // Track whether any alternatives are shorter than the first one. - if (!alternative->onceThrough()) - hasShorterAlternatives = hasShorterAlternatives || (countCheckedForCurrentAlternative < countToCheckForFirstAlternative); - - for (state.resetTerm(); state.termValid(); state.nextTerm()) - generateTerm(state); - - // If we get here, the alternative matched. - if (m_pattern.m_body->m_callFrameSize) - addPtr(Imm32(m_pattern.m_body->m_callFrameSize * sizeof(void*)), stackPointerRegister); - - ASSERT(index != returnRegister); - if (m_pattern.m_body->m_hasFixedSize) { - move(index, returnRegister); - if (alternative->m_minimumSize) - sub32(Imm32(alternative->m_minimumSize), returnRegister); + size_t parenBegin = m_ops.size(); + m_ops.append(parenthesesBeginOpCode); - store32(returnRegister, output); - } else - load32(Address(output), returnRegister); - - store32(index, Address(output, 4)); + m_ops.append(alternativeBeginOpCode); + m_ops.last().m_previousOp = notFound; + m_ops.last().m_term = term; + Vector& alternatives = term->parentheses.disjunction->m_alternatives; + for (unsigned i = 0; i < alternatives.size(); ++i) { + size_t lastOpIndex = m_ops.size() - 1; - generateReturn(); + PatternAlternative* nestedAlternative = alternatives[i]; + opCompileAlternative(nestedAlternative); - state.nextAlternative(); - if (alternative->onceThrough() && state.alternativeValid()) - state.clearBacktrack(); + size_t thisOpIndex = m_ops.size(); + m_ops.append(YarrOp(alternativeNextOpCode)); - // if there are any more alternatives, plant the check for input before looping. - if (state.alternativeValid()) { - state.setJumpListToPriorParen(0); - PatternAlternative* nextAlternative = state.alternative(); - if (!setRepeatAlternativeLabels && !nextAlternative->onceThrough()) { - // We have handled non-repeating alternatives, jump to next iteration - // and loop over repeating alternatives. - state.jumpToBacktrack(this); + YarrOp& lastOp = m_ops[lastOpIndex]; + YarrOp& thisOp = m_ops[thisOpIndex]; - countToCheckForFirstAlternative = nextAlternative->m_minimumSize; + lastOp.m_alternative = nestedAlternative; + lastOp.m_nextOp = thisOpIndex; + thisOp.m_previousOp = lastOpIndex; + thisOp.m_term = term; + } + YarrOp& lastOp = m_ops.last(); + ASSERT(lastOp.m_op == alternativeNextOpCode); + lastOp.m_op = alternativeEndOpCode; + lastOp.m_alternative = 0; + lastOp.m_nextOp = notFound; - // If we get here, there the last input checked failed. - notEnoughInputForPreviousAlternative.link(this); + size_t parenEnd = m_ops.size(); + m_ops.append(parenthesesEndOpCode); - state.linkAlternativeBacktracks(this); + m_ops[parenBegin].m_term = term; + m_ops[parenBegin].m_previousOp = notFound; + m_ops[parenBegin].m_nextOp = parenEnd; + m_ops[parenEnd].m_term = term; + m_ops[parenEnd].m_previousOp = parenBegin; + m_ops[parenEnd].m_nextOp = notFound; + } - // Back up to start the looping alternatives. - if (countCheckedForCurrentAlternative) - sub32(Imm32(countCheckedForCurrentAlternative), index); + // opCompileParentheticalAssertion + // Emits ops for a parenthetical assertion. These consist of an + // OpSimpleNestedAlternativeBegin/Next/End set of nodes wrapping + // the alternatives, with these wrapped by an outer pair of + // OpParentheticalAssertionBegin/End nodes. + // We can always use the OpSimpleNestedAlternative nodes in the + // case of parenthetical assertions since these only ever match + // once, and will never backtrack back into the assertion. + void opCompileParentheticalAssertion(PatternTerm* term) + { + size_t parenBegin = m_ops.size(); + m_ops.append(OpParentheticalAssertionBegin); + + m_ops.append(OpSimpleNestedAlternativeBegin); + m_ops.last().m_previousOp = notFound; + m_ops.last().m_term = term; + Vector& alternatives = term->parentheses.disjunction->m_alternatives; + for (unsigned i = 0; i < alternatives.size(); ++i) { + size_t lastOpIndex = m_ops.size() - 1; + + PatternAlternative* nestedAlternative = alternatives[i]; + opCompileAlternative(nestedAlternative); + + size_t thisOpIndex = m_ops.size(); + m_ops.append(YarrOp(OpSimpleNestedAlternativeNext)); + + YarrOp& lastOp = m_ops[lastOpIndex]; + YarrOp& thisOp = m_ops[thisOpIndex]; + + lastOp.m_alternative = nestedAlternative; + lastOp.m_nextOp = thisOpIndex; + thisOp.m_previousOp = lastOpIndex; + thisOp.m_term = term; + } + YarrOp& lastOp = m_ops.last(); + ASSERT(lastOp.m_op == OpSimpleNestedAlternativeNext); + lastOp.m_op = OpSimpleNestedAlternativeEnd; + lastOp.m_alternative = 0; + lastOp.m_nextOp = notFound; + + size_t parenEnd = m_ops.size(); + m_ops.append(OpParentheticalAssertionEnd); + + m_ops[parenBegin].m_term = term; + m_ops[parenBegin].m_previousOp = notFound; + m_ops[parenBegin].m_nextOp = parenEnd; + m_ops[parenEnd].m_term = term; + m_ops[parenEnd].m_previousOp = parenBegin; + m_ops[parenEnd].m_nextOp = notFound; + } - firstAlternative = Label(this); + // opCompileAlternative + // Called to emit nodes for all terms in an alternative. + void opCompileAlternative(PatternAlternative* alternative) + { + optimizeAlternative(alternative); - state.checkedTotal = countToCheckForFirstAlternative; - if (countToCheckForFirstAlternative) - notEnoughInputForPreviousAlternative.append(jumpIfNoAvailableInput(countToCheckForFirstAlternative)); + for (unsigned i = 0; i < alternative->m_terms.size(); ++i) { + PatternTerm* term = &alternative->m_terms[i]; - countCheckedForCurrentAlternative = countToCheckForFirstAlternative; + switch (term->type) { + case PatternTerm::TypeParenthesesSubpattern: + opCompileParenthesesSubpattern(term); + break; - firstAlternativeInputChecked = Label(this); + case PatternTerm::TypeParentheticalAssertion: + opCompileParentheticalAssertion(term); + break; - setRepeatAlternativeLabels = true; - } else { - int countToCheckForNextAlternative = nextAlternative->m_minimumSize; - - if (countCheckedForCurrentAlternative > countToCheckForNextAlternative) { // CASE 1: current alternative was longer than the next one. - // If we get here, then the last input checked failed. - notEnoughInputForPreviousAlternative.link(this); - - // Check if sufficent input available to run the next alternative - notEnoughInputForPreviousAlternative.append(jumpIfNoAvailableInput(countToCheckForNextAlternative - countCheckedForCurrentAlternative)); - // We are now in the correct state to enter the next alternative; this add is only required - // to mirror and revert operation of the sub32, just below. - add32(Imm32(countCheckedForCurrentAlternative - countToCheckForNextAlternative), index); - - // If we get here, then the last input checked passed. - state.linkAlternativeBacktracks(this); - - // No need to check if we can run the next alternative, since it is shorter - - // just update index. - sub32(Imm32(countCheckedForCurrentAlternative - countToCheckForNextAlternative), index); - } else if (countCheckedForCurrentAlternative < countToCheckForNextAlternative) { // CASE 2: next alternative is longer than the current one. - // If we get here, then the last input checked failed. - // If there is insufficient input to run the current alternative, and the next alternative is longer, - // then there is definitely not enough input to run it - don't even check. Just adjust index, as if - // we had checked. - notEnoughInputForPreviousAlternative.link(this); - add32(Imm32(countToCheckForNextAlternative - countCheckedForCurrentAlternative), index); - notEnoughInputForPreviousAlternative.append(jump()); - - // The next alternative is longer than the current one; check the difference. - state.linkAlternativeBacktracks(this); - - notEnoughInputForPreviousAlternative.append(jumpIfNoAvailableInput(countToCheckForNextAlternative - countCheckedForCurrentAlternative)); - } else { // CASE 3: Both alternatives are the same length. - ASSERT(countCheckedForCurrentAlternative == countToCheckForNextAlternative); - - // If the next alterative is the same length as this one, then no need to check the input - - // if there was sufficent input to run the current alternative then there is sufficient - // input to run the next one; if not, there isn't. - state.linkAlternativeBacktracks(this); - } - state.checkedTotal -= countCheckedForCurrentAlternative; - countCheckedForCurrentAlternative = countToCheckForNextAlternative; - state.checkedTotal += countCheckedForCurrentAlternative; - } + default: + m_ops.append(term); } } + } - // If we get here, all Alternatives failed... + // opCompileBody + // This method compiles the body disjunction of the regular expression. + // The body consists of two sets of alternatives - zero or more 'once + // through' (BOL anchored) alternatives, followed by zero or more + // repeated alternatives. + // For each of these two sets of alteratives, if not empty they will be + // wrapped in a set of OpBodyAlternativeBegin/Next/End nodes (with the + // 'begin' node referencing the first alternative, and 'next' nodes + // referencing any further alternatives. The begin/next/end nodes are + // linked together in a doubly linked list. In the case of repeating + // alternatives, the end node is also linked back to the beginning. + // If no repeating alternatives exist, then a OpMatchFailed node exists + // to return the failing result. + void opCompileBody(PatternDisjunction* disjunction) + { + Vector& alternatives = disjunction->m_alternatives; + size_t currentAlternativeIndex = 0; - state.checkedTotal -= countCheckedForCurrentAlternative; + // Emit the 'once through' alternatives. + if (alternatives.size() && alternatives[0]->onceThrough()) { + m_ops.append(YarrOp(OpBodyAlternativeBegin)); + m_ops.last().m_previousOp = notFound; - if (!setRepeatAlternativeLabels) { - // If there are no alternatives that need repeating (all are marked 'onceThrough') then just link - // the match failures to this point, and fall through to the return below. - state.linkAlternativeBacktracks(this, true); + do { + size_t lastOpIndex = m_ops.size() - 1; + PatternAlternative* alternative = alternatives[currentAlternativeIndex]; + opCompileAlternative(alternative); - notEnoughInputForPreviousAlternative.link(this); - } else { - // How much more input need there be to be able to retry from the first alternative? - // examples: - // /yarr_jit/ or /wrec|pcre/ - // In these examples we need check for one more input before looping. - // /yarr_jit|pcre/ - // In this case we need check for 5 more input to loop (+4 to allow for the first alterative - // being four longer than the last alternative checked, and another +1 to effectively move - // the start position along by one). - // /yarr|rules/ or /wrec|notsomuch/ - // In these examples, provided that there was sufficient input to have just been matching for - // the second alternative we can loop without checking for available input (since the second - // alternative is longer than the first). In the latter example we need to decrement index - // (by 4) so the start position is only progressed by 1 from the last iteration. - int incrementForNextIter = (countToCheckForFirstAlternative - countCheckedForCurrentAlternative) + 1; - - // First, deal with the cases where there was sufficient input to try the last alternative. - if (incrementForNextIter > 0) // We need to check for more input anyway, fall through to the checking below. - state.linkAlternativeBacktracks(this, true); - else if (m_pattern.m_body->m_hasFixedSize && !incrementForNextIter) // No need to update anything, link these backtracks straight to the to pof the loop! - state.linkAlternativeBacktracksTo(this, firstAlternativeInputChecked, true); - else { // no need to check the input, but we do have some bookkeeping to do first. - state.linkAlternativeBacktracks(this, true); - - // Where necessary update our preserved start position. - if (!m_pattern.m_body->m_hasFixedSize) { - move(index, regT0); - sub32(Imm32(countCheckedForCurrentAlternative - 1), regT0); - store32(regT0, Address(output)); - } + size_t thisOpIndex = m_ops.size(); + m_ops.append(YarrOp(OpBodyAlternativeNext)); - // Update index if necessary, and loop (without checking). - if (incrementForNextIter) - add32(Imm32(incrementForNextIter), index); - jump().linkTo(firstAlternativeInputChecked, this); - } + YarrOp& lastOp = m_ops[lastOpIndex]; + YarrOp& thisOp = m_ops[thisOpIndex]; - notEnoughInputForPreviousAlternative.link(this); - // Update our idea of the start position, if we're tracking this. - if (!m_pattern.m_body->m_hasFixedSize) { - if (countCheckedForCurrentAlternative - 1) { - move(index, regT0); - sub32(Imm32(countCheckedForCurrentAlternative - 1), regT0); - store32(regT0, Address(output)); - } else - store32(index, Address(output)); - } + lastOp.m_alternative = alternative; + lastOp.m_nextOp = thisOpIndex; + thisOp.m_previousOp = lastOpIndex; + + ++currentAlternativeIndex; + } while (currentAlternativeIndex < alternatives.size() && alternatives[currentAlternativeIndex]->onceThrough()); - // Check if there is sufficent input to run the first alternative again. - jumpIfAvailableInput(incrementForNextIter).linkTo(firstAlternativeInputChecked, this); - // No - insufficent input to run the first alteranative, are there any other alternatives we - // might need to check? If so, the last check will have left the index incremented by - // (countToCheckForFirstAlternative + 1), so we need test whether countToCheckForFirstAlternative - // LESS input is available, to have the effect of just progressing the start position by 1 - // from the last iteration. If this check passes we can just jump up to the check associated - // with the first alternative in the loop. This is a bit sad, since we'll end up trying the - // first alternative again, and this check will fail (otherwise the check planted just above - // here would have passed). This is a bit sad, however it saves trying to do something more - // complex here in compilation, and in the common case we should end up coallescing the checks. - // - // FIXME: a nice improvement here may be to stop trying to match sooner, based on the least - // of the minimum-alternative-lengths. E.g. if I have two alternatives of length 200 and 150, - // and a string of length 100, we'll end up looping index from 0 to 100, checking whether there - // is sufficient input to run either alternative (constantly failing). If there had been only - // one alternative, or if the shorter alternative had come first, we would have terminated - // immediately. :-/ - if (hasShorterAlternatives) - jumpIfAvailableInput(-countToCheckForFirstAlternative).linkTo(firstAlternative, this); - // index will now be a bit garbled (depending on whether 'hasShorterAlternatives' is true, - // it has either been incremented by 1 or by (countToCheckForFirstAlternative + 1) ... - // but since we're about to return a failure this doesn't really matter!) + YarrOp& lastOp = m_ops.last(); + + ASSERT(lastOp.m_op == OpBodyAlternativeNext); + lastOp.m_op = OpBodyAlternativeEnd; + lastOp.m_alternative = 0; + lastOp.m_nextOp = notFound; } - if (m_pattern.m_body->m_callFrameSize) - addPtr(Imm32(m_pattern.m_body->m_callFrameSize * sizeof(void*)), stackPointerRegister); + if (currentAlternativeIndex == alternatives.size()) { + m_ops.append(YarrOp(OpMatchFailed)); + return; + } + + // Emit the repeated alternatives. + size_t repeatLoop = m_ops.size(); + m_ops.append(YarrOp(OpBodyAlternativeBegin)); + m_ops.last().m_previousOp = notFound; + do { + size_t lastOpIndex = m_ops.size() - 1; + PatternAlternative* alternative = alternatives[currentAlternativeIndex]; + ASSERT(!alternative->onceThrough()); + opCompileAlternative(alternative); - move(TrustedImm32(-1), returnRegister); + size_t thisOpIndex = m_ops.size(); + m_ops.append(YarrOp(OpBodyAlternativeNext)); - generateReturn(); + YarrOp& lastOp = m_ops[lastOpIndex]; + YarrOp& thisOp = m_ops[thisOpIndex]; - m_expressionState.emitParenthesesTail(this); - m_expressionState.emitIndirectJumpTable(this); - m_expressionState.linkToNextIteration(this); + lastOp.m_alternative = alternative; + lastOp.m_nextOp = thisOpIndex; + thisOp.m_previousOp = lastOpIndex; + + ++currentAlternativeIndex; + } while (currentAlternativeIndex < alternatives.size()); + YarrOp& lastOp = m_ops.last(); + ASSERT(lastOp.m_op == OpBodyAlternativeNext); + lastOp.m_op = OpBodyAlternativeEnd; + lastOp.m_alternative = 0; + lastOp.m_nextOp = repeatLoop; } void generateEnter() @@ -2230,10 +2325,11 @@ public: YarrGenerator(YarrPattern& pattern) : m_pattern(pattern) , m_shouldFallBack(false) + , m_checked(0) { } - void generate() + void compile(JSGlobalData* globalData, YarrCodeBlock& jitObject) { generateEnter(); @@ -2243,26 +2339,50 @@ public: if (m_pattern.m_body->m_callFrameSize) subPtr(Imm32(m_pattern.m_body->m_callFrameSize * sizeof(void*)), stackPointerRegister); - generateDisjunction(m_pattern.m_body); - } - - void compile(JSGlobalData* globalData, YarrCodeBlock& jitObject) - { - generate(); + // Compile the pattern to the internal 'YarrOp' representation. + opCompileBody(m_pattern.m_body); - LinkBuffer patchBuffer(this, globalData->regexAllocator); + // If we encountered anything we can't handle in the JIT code + // (e.g. backreferences) then return early. + if (m_shouldFallBack) { + jitObject.setFallBack(true); + return; + } - for (unsigned i = 0; i < m_expressionState.m_backtrackRecords.size(); ++i) - patchBuffer.patch(m_expressionState.m_backtrackRecords[i].dataLabel, patchBuffer.locationOf(m_expressionState.m_backtrackRecords[i].backtrackLocation)); + generate(); + backtrack(); - jitObject.set(patchBuffer.finalizeCode()); + // Link & finalize the code. + LinkBuffer linkBuffer(this, globalData->regexAllocator); + m_backtrackingState.linkDataLabels(linkBuffer); + jitObject.set(linkBuffer.finalizeCode()); jitObject.setFallBack(m_shouldFallBack); } private: YarrPattern& m_pattern; + + // Used to detect regular expression constructs that are not currently + // supported in the JIT; fall back to the interpreter when this is detected. bool m_shouldFallBack; - GenerationState m_expressionState; + + // The regular expression expressed as a linear sequence of operations. + Vector m_ops; + + // This records the current input offset being applied due to the current + // set of alternatives we are nested within. E.g. when matching the + // character 'b' within the regular expression /abc/, we will know that + // the minimum size for the alternative is 3, checked upon entry to the + // alternative, and that 'b' is at offset 1 from the start, and as such + // when matching 'b' we need to apply an offset of -2 to the load. + // + // FIXME: This should go away. Rather than tracking this value throughout + // code generation, we should gather this information up front & store it + // on the YarrOp structure. + int m_checked; + + // This class records state whilst generating the backtracking path of code. + BacktrackingState m_backtrackingState; }; void jitCompile(YarrPattern& pattern, JSGlobalData* globalData, YarrCodeBlock& jitObject) diff --git a/src/3rdparty/webkit/Source/ThirdParty/gtest/codegear/gtest.cbproj b/src/3rdparty/webkit/Source/ThirdParty/gtest/codegear/gtest.cbproj index 285bb2a..95c3054 100644 --- a/src/3rdparty/webkit/Source/ThirdParty/gtest/codegear/gtest.cbproj +++ b/src/3rdparty/webkit/Source/ThirdParty/gtest/codegear/gtest.cbproj @@ -1,138 +1,138 @@ - - - - {bca37a72-5b07-46cf-b44e-89f8e06451a2} - Release - - - true - - - true - true - Base - - - true - true - Base - - - true - lib - JPHNE - NO_STRICT - true - true - CppStaticLibrary - true - rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;dclZipForged11.bpi;vclZipForged11.bpi;GR32_BDS2006.bpi;GR32_DSGN_BDS2006.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi;CExceptionExpert11.bpi - false - $(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;.. - rtl.lib;vcl.lib - 32 - $(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk - - - false - false - true - _DEBUG;$(Defines) - true - false - true - None - DEBUG - true - Debug - true - true - true - $(BDS)\lib\debug;$(ILINK_LibraryPath) - Full - true - - - NDEBUG;$(Defines) - Release - $(BDS)\lib\release;$(ILINK_LibraryPath) - None - - - CPlusPlusBuilder.Personality - CppStaticLibrary - -FalseFalse1000FalseFalseFalseFalseFalse103312521.0.0.01.0.0.0FalseFalseFalseTrueFalse - - - CodeGear C++Builder Office 2000 Servers Package - CodeGear C++Builder Office XP Servers Package - FalseTrueTrue3$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\src;..\include1$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk1NO_STRICT13216 - - - - - 3 - - - 4 - - - 5 - - - 6 - - - 7 - - - 8 - - - 0 - - - 1 - - - 2 - - - 9 - - - 10 - - - 11 - - - 12 - - - 14 - - - 13 - - - 15 - - - 16 - - - 17 - - - 18 - - - Cfg_1 - - - Cfg_2 - - + + + + {bca37a72-5b07-46cf-b44e-89f8e06451a2} + Release + + + true + + + true + true + Base + + + true + true + Base + + + true + lib + JPHNE + NO_STRICT + true + true + CppStaticLibrary + true + rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;dclZipForged11.bpi;vclZipForged11.bpi;GR32_BDS2006.bpi;GR32_DSGN_BDS2006.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi;CExceptionExpert11.bpi + false + $(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;.. + rtl.lib;vcl.lib + 32 + $(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk + + + false + false + true + _DEBUG;$(Defines) + true + false + true + None + DEBUG + true + Debug + true + true + true + $(BDS)\lib\debug;$(ILINK_LibraryPath) + Full + true + + + NDEBUG;$(Defines) + Release + $(BDS)\lib\release;$(ILINK_LibraryPath) + None + + + CPlusPlusBuilder.Personality + CppStaticLibrary + +FalseFalse1000FalseFalseFalseFalseFalse103312521.0.0.01.0.0.0FalseFalseFalseTrueFalse + + + CodeGear C++Builder Office 2000 Servers Package + CodeGear C++Builder Office XP Servers Package + FalseTrueTrue3$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\src;..\include1$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk1NO_STRICT13216 + + + + + 3 + + + 4 + + + 5 + + + 6 + + + 7 + + + 8 + + + 0 + + + 1 + + + 2 + + + 9 + + + 10 + + + 11 + + + 12 + + + 14 + + + 13 + + + 15 + + + 16 + + + 17 + + + 18 + + + Cfg_1 + + + Cfg_2 + + \ No newline at end of file diff --git a/src/3rdparty/webkit/Source/ThirdParty/gtest/codegear/gtest.groupproj b/src/3rdparty/webkit/Source/ThirdParty/gtest/codegear/gtest.groupproj index 849f4c4..faf31ca 100644 --- a/src/3rdparty/webkit/Source/ThirdParty/gtest/codegear/gtest.groupproj +++ b/src/3rdparty/webkit/Source/ThirdParty/gtest/codegear/gtest.groupproj @@ -1,54 +1,54 @@ - - - {c1d923e0-6cba-4332-9b6f-3420acbf5091} - - - - - - - - - Default.Personality - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + {c1d923e0-6cba-4332-9b6f-3420acbf5091} + + + + + + + + + Default.Personality + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/3rdparty/webkit/Source/ThirdParty/gtest/codegear/gtest_all.cc b/src/3rdparty/webkit/Source/ThirdParty/gtest/codegear/gtest_all.cc index ba7ad68..121b2d8 100644 --- a/src/3rdparty/webkit/Source/ThirdParty/gtest/codegear/gtest_all.cc +++ b/src/3rdparty/webkit/Source/ThirdParty/gtest/codegear/gtest_all.cc @@ -1,38 +1,38 @@ -// Copyright 2009, Google 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: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "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 THE COPYRIGHT -// OWNER 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. -// -// Author: Josh Kelley (joshkel@gmail.com) -// -// Google C++ Testing Framework (Google Test) -// -// C++Builder's IDE cannot build a static library from files with hyphens -// in their name. See http://qc.codegear.com/wc/qcmain.aspx?d=70977 . -// This file serves as a workaround. - -#include "src/gtest-all.cc" +// Copyright 2009, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 THE COPYRIGHT +// OWNER 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. +// +// Author: Josh Kelley (joshkel@gmail.com) +// +// Google C++ Testing Framework (Google Test) +// +// C++Builder's IDE cannot build a static library from files with hyphens +// in their name. See http://qc.codegear.com/wc/qcmain.aspx?d=70977 . +// This file serves as a workaround. + +#include "src/gtest-all.cc" diff --git a/src/3rdparty/webkit/Source/ThirdParty/gtest/codegear/gtest_link.cc b/src/3rdparty/webkit/Source/ThirdParty/gtest/codegear/gtest_link.cc index b955ebf..918eccd 100644 --- a/src/3rdparty/webkit/Source/ThirdParty/gtest/codegear/gtest_link.cc +++ b/src/3rdparty/webkit/Source/ThirdParty/gtest/codegear/gtest_link.cc @@ -1,40 +1,40 @@ -// Copyright 2009, Google 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: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "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 THE COPYRIGHT -// OWNER 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. -// -// Author: Josh Kelley (joshkel@gmail.com) -// -// Google C++ Testing Framework (Google Test) -// -// Links gtest.lib and gtest_main.lib into the current project in C++Builder. -// This means that these libraries can't be renamed, but it's the only way to -// ensure that Debug versus Release test builds are linked against the -// appropriate Debug or Release build of the libraries. - -#pragma link "gtest.lib" -#pragma link "gtest_main.lib" +// Copyright 2009, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 THE COPYRIGHT +// OWNER 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. +// +// Author: Josh Kelley (joshkel@gmail.com) +// +// Google C++ Testing Framework (Google Test) +// +// Links gtest.lib and gtest_main.lib into the current project in C++Builder. +// This means that these libraries can't be renamed, but it's the only way to +// ensure that Debug versus Release test builds are linked against the +// appropriate Debug or Release build of the libraries. + +#pragma link "gtest.lib" +#pragma link "gtest_main.lib" diff --git a/src/3rdparty/webkit/Source/ThirdParty/gtest/codegear/gtest_main.cbproj b/src/3rdparty/webkit/Source/ThirdParty/gtest/codegear/gtest_main.cbproj index fae32cb..d76ce13 100644 --- a/src/3rdparty/webkit/Source/ThirdParty/gtest/codegear/gtest_main.cbproj +++ b/src/3rdparty/webkit/Source/ThirdParty/gtest/codegear/gtest_main.cbproj @@ -1,82 +1,82 @@ - - - - {bca37a72-5b07-46cf-b44e-89f8e06451a2} - Release - - - true - - - true - true - Base - - - true - true - Base - - - true - lib - JPHNE - NO_STRICT - true - true - CppStaticLibrary - true - rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;dclZipForged11.bpi;vclZipForged11.bpi;GR32_BDS2006.bpi;GR32_DSGN_BDS2006.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi;CExceptionExpert11.bpi - false - $(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;.. - rtl.lib;vcl.lib - 32 - $(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk - - - false - false - true - _DEBUG;$(Defines) - true - false - true - None - DEBUG - true - Debug - true - true - true - $(BDS)\lib\debug;$(ILINK_LibraryPath) - Full - true - - - NDEBUG;$(Defines) - Release - $(BDS)\lib\release;$(ILINK_LibraryPath) - None - - - CPlusPlusBuilder.Personality - CppStaticLibrary - -FalseFalse1000FalseFalseFalseFalseFalse103312521.0.0.01.0.0.0FalseFalseFalseTrueFalse - CodeGear C++Builder Office 2000 Servers Package - CodeGear C++Builder Office XP Servers Package - FalseTrueTrue3$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\src;..\include1$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk1NO_STRICT13216 - - - - - 0 - - - Cfg_1 - - - Cfg_2 - - - + + + + {bca37a72-5b07-46cf-b44e-89f8e06451a2} + Release + + + true + + + true + true + Base + + + true + true + Base + + + true + lib + JPHNE + NO_STRICT + true + true + CppStaticLibrary + true + rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;dclZipForged11.bpi;vclZipForged11.bpi;GR32_BDS2006.bpi;GR32_DSGN_BDS2006.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi;CExceptionExpert11.bpi + false + $(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;.. + rtl.lib;vcl.lib + 32 + $(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk + + + false + false + true + _DEBUG;$(Defines) + true + false + true + None + DEBUG + true + Debug + true + true + true + $(BDS)\lib\debug;$(ILINK_LibraryPath) + Full + true + + + NDEBUG;$(Defines) + Release + $(BDS)\lib\release;$(ILINK_LibraryPath) + None + + + CPlusPlusBuilder.Personality + CppStaticLibrary + +FalseFalse1000FalseFalseFalseFalseFalse103312521.0.0.01.0.0.0FalseFalseFalseTrueFalse + CodeGear C++Builder Office 2000 Servers Package + CodeGear C++Builder Office XP Servers Package + FalseTrueTrue3$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\src;..\include1$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk1NO_STRICT13216 + + + + + 0 + + + Cfg_1 + + + Cfg_2 + + + diff --git a/src/3rdparty/webkit/Source/ThirdParty/gtest/codegear/gtest_unittest.cbproj b/src/3rdparty/webkit/Source/ThirdParty/gtest/codegear/gtest_unittest.cbproj index 33f7056..dc5db8e 100644 --- a/src/3rdparty/webkit/Source/ThirdParty/gtest/codegear/gtest_unittest.cbproj +++ b/src/3rdparty/webkit/Source/ThirdParty/gtest/codegear/gtest_unittest.cbproj @@ -1,88 +1,88 @@ - - - - {eea63393-5ac5-4b9c-8909-d75fef2daa41} - Release - - - true - - - true - true - Base - - - true - true - Base - - - exe - true - NO_STRICT - JPHNE - true - ..\test - true - CppConsoleApplication - true - true - rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi - false - $(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test;.. - $(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test - true - - - false - false - true - _DEBUG;$(Defines) - true - false - true - None - DEBUG - true - Debug - true - true - true - $(BDS)\lib\debug;$(ILINK_LibraryPath) - Full - true - - - NDEBUG;$(Defines) - Release - $(BDS)\lib\release;$(ILINK_LibraryPath) - None - - - CPlusPlusBuilder.Personality - CppConsoleApplication - -FalseFalse1000FalseFalseFalseFalseFalse103312521.0.0.01.0.0.0FalseFalseFalseTrueFalse - - - CodeGear C++Builder Office 2000 Servers Package - CodeGear C++Builder Office XP Servers Package - FalseTrueTrue3$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include1$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;$(OUTPUTDIR);..\test2NO_STRICTSTRICT - - - - - 0 - - - 1 - - - Cfg_1 - - - Cfg_2 - - + + + + {eea63393-5ac5-4b9c-8909-d75fef2daa41} + Release + + + true + + + true + true + Base + + + true + true + Base + + + exe + true + NO_STRICT + JPHNE + true + ..\test + true + CppConsoleApplication + true + true + rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi + false + $(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test;.. + $(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test + true + + + false + false + true + _DEBUG;$(Defines) + true + false + true + None + DEBUG + true + Debug + true + true + true + $(BDS)\lib\debug;$(ILINK_LibraryPath) + Full + true + + + NDEBUG;$(Defines) + Release + $(BDS)\lib\release;$(ILINK_LibraryPath) + None + + + CPlusPlusBuilder.Personality + CppConsoleApplication + +FalseFalse1000FalseFalseFalseFalseFalse103312521.0.0.01.0.0.0FalseFalseFalseTrueFalse + + + CodeGear C++Builder Office 2000 Servers Package + CodeGear C++Builder Office XP Servers Package + FalseTrueTrue3$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include1$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;$(OUTPUTDIR);..\test2NO_STRICTSTRICT + + + + + 0 + + + 1 + + + Cfg_1 + + + Cfg_2 + + \ No newline at end of file diff --git a/src/3rdparty/webkit/Source/ThirdParty/gyp/gyp.bat b/src/3rdparty/webkit/Source/ThirdParty/gyp/gyp.bat index 91ebf1e..90fbc6d 100755 --- a/src/3rdparty/webkit/Source/ThirdParty/gyp/gyp.bat +++ b/src/3rdparty/webkit/Source/ThirdParty/gyp/gyp.bat @@ -1,5 +1,5 @@ -@rem Copyright (c) 2009 Google Inc. All rights reserved. -@rem Use of this source code is governed by a BSD-style license that can be -@rem found in the LICENSE file. - -@python "%~dp0/gyp" %* +@rem Copyright (c) 2009 Google Inc. All rights reserved. +@rem Use of this source code is governed by a BSD-style license that can be +@rem found in the LICENSE file. + +@python "%~dp0/gyp" %* diff --git a/src/3rdparty/webkit/Source/ThirdParty/gyp/samples/samples.bat b/src/3rdparty/webkit/Source/ThirdParty/gyp/samples/samples.bat index 5683255..778d9c9 100644 --- a/src/3rdparty/webkit/Source/ThirdParty/gyp/samples/samples.bat +++ b/src/3rdparty/webkit/Source/ThirdParty/gyp/samples/samples.bat @@ -1,5 +1,5 @@ -@rem Copyright (c) 2009 Google Inc. All rights reserved. -@rem Use of this source code is governed by a BSD-style license that can be -@rem found in the LICENSE file. - -@python %~dp0/samples %* +@rem Copyright (c) 2009 Google Inc. All rights reserved. +@rem Use of this source code is governed by a BSD-style license that can be +@rem found in the LICENSE file. + +@python %~dp0/samples %* diff --git a/src/3rdparty/webkit/Source/ThirdParty/gyp/test/actions/gyptest-errors.py b/src/3rdparty/webkit/Source/ThirdParty/gyp/test/actions/gyptest-errors.py index 4a2aa07..ca41487 100644 --- a/src/3rdparty/webkit/Source/ThirdParty/gyp/test/actions/gyptest-errors.py +++ b/src/3rdparty/webkit/Source/ThirdParty/gyp/test/actions/gyptest-errors.py @@ -1,24 +1,24 @@ -#!/usr/bin/env python +#!/usr/bin/env python # Copyright (c) 2009 Google Inc. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. - -""" -Verifies behavior for different action configuration errors: -exit status of 1, and the expected error message must be in stderr. -""" - -import TestGyp - -test = TestGyp.TestGyp() - - -test.run_gyp('action_missing_name.gyp', chdir='src', status=1, stderr=None) -expect = [ - "Anonymous action in target broken_actions2. An action must have an 'action_name' field.", -] -test.must_contain_all_lines(test.stderr(), expect) - - -test.pass_test() + +""" +Verifies behavior for different action configuration errors: +exit status of 1, and the expected error message must be in stderr. +""" + +import TestGyp + +test = TestGyp.TestGyp() + + +test.run_gyp('action_missing_name.gyp', chdir='src', status=1, stderr=None) +expect = [ + "Anonymous action in target broken_actions2. An action must have an 'action_name' field.", +] +test.must_contain_all_lines(test.stderr(), expect) + + +test.pass_test() diff --git a/src/3rdparty/webkit/Source/ThirdParty/gyp/test/actions/src/subdir1/program.c b/src/3rdparty/webkit/Source/ThirdParty/gyp/test/actions/src/subdir1/program.c index f155939..d5f661d 100644 --- a/src/3rdparty/webkit/Source/ThirdParty/gyp/test/actions/src/subdir1/program.c +++ b/src/3rdparty/webkit/Source/ThirdParty/gyp/test/actions/src/subdir1/program.c @@ -1,12 +1,12 @@ -#include - -extern void prog1(void); -extern void prog2(void); - -int main(int argc, char *argv[]) -{ - printf("Hello from program.c\n"); - prog1(); - prog2(); - return 0; -} +#include + +extern void prog1(void); +extern void prog2(void); + +int main(int argc, char *argv[]) +{ + printf("Hello from program.c\n"); + prog1(); + prog2(); + return 0; +} diff --git a/src/3rdparty/webkit/Source/ThirdParty/gyp/test/generator-output/actions/subdir1/actions-out/README.txt b/src/3rdparty/webkit/Source/ThirdParty/gyp/test/generator-output/actions/subdir1/actions-out/README.txt index 90ef886..1b052c9 100644 --- a/src/3rdparty/webkit/Source/ThirdParty/gyp/test/generator-output/actions/subdir1/actions-out/README.txt +++ b/src/3rdparty/webkit/Source/ThirdParty/gyp/test/generator-output/actions/subdir1/actions-out/README.txt @@ -1,4 +1,4 @@ -A place-holder for this Xcode build output directory, so that the -test script can verify that .xcodeproj files are not created in -their normal location by making the src/ read-only, and then -selectively making this build directory writable. +A place-holder for this Xcode build output directory, so that the +test script can verify that .xcodeproj files are not created in +their normal location by making the src/ read-only, and then +selectively making this build directory writable. diff --git a/src/3rdparty/webkit/Source/ThirdParty/gyp/test/generator-output/actions/subdir1/program.c b/src/3rdparty/webkit/Source/ThirdParty/gyp/test/generator-output/actions/subdir1/program.c index f155939..d5f661d 100644 --- a/src/3rdparty/webkit/Source/ThirdParty/gyp/test/generator-output/actions/subdir1/program.c +++ b/src/3rdparty/webkit/Source/ThirdParty/gyp/test/generator-output/actions/subdir1/program.c @@ -1,12 +1,12 @@ -#include - -extern void prog1(void); -extern void prog2(void); - -int main(int argc, char *argv[]) -{ - printf("Hello from program.c\n"); - prog1(); - prog2(); - return 0; -} +#include + +extern void prog1(void); +extern void prog2(void); + +int main(int argc, char *argv[]) +{ + printf("Hello from program.c\n"); + prog1(); + prog2(); + return 0; +} diff --git a/src/3rdparty/webkit/Source/ThirdParty/gyp/test/generator-output/actions/subdir2/actions-out/README.txt b/src/3rdparty/webkit/Source/ThirdParty/gyp/test/generator-output/actions/subdir2/actions-out/README.txt index 90ef886..1b052c9 100644 --- a/src/3rdparty/webkit/Source/ThirdParty/gyp/test/generator-output/actions/subdir2/actions-out/README.txt +++ b/src/3rdparty/webkit/Source/ThirdParty/gyp/test/generator-output/actions/subdir2/actions-out/README.txt @@ -1,4 +1,4 @@ -A place-holder for this Xcode build output directory, so that the -test script can verify that .xcodeproj files are not created in -their normal location by making the src/ read-only, and then -selectively making this build directory writable. +A place-holder for this Xcode build output directory, so that the +test script can verify that .xcodeproj files are not created in +their normal location by making the src/ read-only, and then +selectively making this build directory writable. diff --git a/src/3rdparty/webkit/Source/ThirdParty/gyp/test/generator-output/rules/subdir2/rules-out/README.txt b/src/3rdparty/webkit/Source/ThirdParty/gyp/test/generator-output/rules/subdir2/rules-out/README.txt index 90ef886..1b052c9 100644 --- a/src/3rdparty/webkit/Source/ThirdParty/gyp/test/generator-output/rules/subdir2/rules-out/README.txt +++ b/src/3rdparty/webkit/Source/ThirdParty/gyp/test/generator-output/rules/subdir2/rules-out/README.txt @@ -1,4 +1,4 @@ -A place-holder for this Xcode build output directory, so that the -test script can verify that .xcodeproj files are not created in -their normal location by making the src/ read-only, and then -selectively making this build directory writable. +A place-holder for this Xcode build output directory, so that the +test script can verify that .xcodeproj files are not created in +their normal location by making the src/ read-only, and then +selectively making this build directory writable. diff --git a/src/3rdparty/webkit/Source/ThirdParty/gyp/tools/pretty_gyp.py b/src/3rdparty/webkit/Source/ThirdParty/gyp/tools/pretty_gyp.py index 128c2e3..04c7901 100644 --- a/src/3rdparty/webkit/Source/ThirdParty/gyp/tools/pretty_gyp.py +++ b/src/3rdparty/webkit/Source/ThirdParty/gyp/tools/pretty_gyp.py @@ -1,142 +1,142 @@ -#!/usr/bin/env python -# Copyright (c) 2009 The Chromium Authors. 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 pretty-prints the contents of a GYP file. - -import sys -import re - -input = [] -if len(sys.argv) > 1: - input_file = open(sys.argv[1]) - input = input_file.read().splitlines() - input_file.close() -else: - input = sys.stdin.read().splitlines() - -# This is used to remove comments when we're counting braces. -comment_re = re.compile(r'\s*#.*') - -# This is used to remove quoted strings when we're counting braces. -# It takes into account quoted quotes, and makes sure that the quotes -# match. -# NOTE: It does not handle quotes that span more than one line, or -# cases where an escaped quote is preceeded by an escaped backslash. -quote_re_str = r'(?P[\'"])(.*?)(? 0: - after = True - - # This catches the special case of a closing brace having something - # other than just whitespace ahead of it -- we don't want to - # unindent that until after this line is printed so it stays with - # the previous indentation level. - if cnt < 0 and closing_prefix_re.match(stripline): - after = True - return (cnt, after) - -# This does the main work of indenting the input based on the brace counts. -def prettyprint_input(lines): - indent = 0 - basic_offset = 2 - last_line = "" - for line in lines: - if comment_re.match(line): - print line - else: - line = line.strip('\r\n\t ') # Otherwise doesn't strip \r on Unix. - if len(line) > 0: - (brace_diff, after) = count_braces(line) - if brace_diff != 0: - if after: - print " " * (basic_offset * indent) + line - indent += brace_diff - else: - indent += brace_diff - print " " * (basic_offset * indent) + line - else: - print " " * (basic_offset * indent) + line - else: - print "" - last_line = line - -# Split up the double braces. -lines = split_double_braces(input) - -# Indent and print the output. -prettyprint_input(lines) +#!/usr/bin/env python +# Copyright (c) 2009 The Chromium Authors. 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 pretty-prints the contents of a GYP file. + +import sys +import re + +input = [] +if len(sys.argv) > 1: + input_file = open(sys.argv[1]) + input = input_file.read().splitlines() + input_file.close() +else: + input = sys.stdin.read().splitlines() + +# This is used to remove comments when we're counting braces. +comment_re = re.compile(r'\s*#.*') + +# This is used to remove quoted strings when we're counting braces. +# It takes into account quoted quotes, and makes sure that the quotes +# match. +# NOTE: It does not handle quotes that span more than one line, or +# cases where an escaped quote is preceeded by an escaped backslash. +quote_re_str = r'(?P[\'"])(.*?)(? 0: + after = True + + # This catches the special case of a closing brace having something + # other than just whitespace ahead of it -- we don't want to + # unindent that until after this line is printed so it stays with + # the previous indentation level. + if cnt < 0 and closing_prefix_re.match(stripline): + after = True + return (cnt, after) + +# This does the main work of indenting the input based on the brace counts. +def prettyprint_input(lines): + indent = 0 + basic_offset = 2 + last_line = "" + for line in lines: + if comment_re.match(line): + print line + else: + line = line.strip('\r\n\t ') # Otherwise doesn't strip \r on Unix. + if len(line) > 0: + (brace_diff, after) = count_braces(line) + if brace_diff != 0: + if after: + print " " * (basic_offset * indent) + line + indent += brace_diff + else: + indent += brace_diff + print " " * (basic_offset * indent) + line + else: + print " " * (basic_offset * indent) + line + else: + print "" + last_line = line + +# Split up the double braces. +lines = split_double_braces(input) + +# Indent and print the output. +prettyprint_input(lines) diff --git a/src/3rdparty/webkit/Source/WebCore/ChangeLog b/src/3rdparty/webkit/Source/WebCore/ChangeLog index f112cba..2e34c2e 100644 --- a/src/3rdparty/webkit/Source/WebCore/ChangeLog +++ b/src/3rdparty/webkit/Source/WebCore/ChangeLog @@ -1,3 +1,738 @@ +2011-08-06 Aron Rosenberg + + Reviewed by Benjamin Poulain. + + [Qt] Fix build with Intel compiler on Windows + https://bugs.webkit.org/show_bug.cgi?id=65088 + + Intel compiler needs .lib suffixes instead of .a + + * WebCore.pri: + +2011-08-03 Kent Tamura + + Fix incorrect checks for HTMLMediaElement + https://bugs.webkit.org/show_bug.cgi?id=65590 + + Reviewed by Dimitri Glazkov. + +